167754Smsmith/* SPU ELF support for BFD.
267754Smsmith
377424Smsmith   Copyright 2006 Free Software Foundation, Inc.
467754Smsmith
567754Smsmith   This file is part of GDB, GAS, and the GNU binutils.
667754Smsmith
7217365Sjkim   This program is free software; you can redistribute it and/or modify
8217365Sjkim   it under the terms of the GNU General Public License as published by
970243Smsmith   the Free Software Foundation; either version 2 of the License, or
1067754Smsmith   (at your option) any later version.
11217365Sjkim
12217365Sjkim   This program is distributed in the hope that it will be useful,
13217365Sjkim   but WITHOUT ANY WARRANTY; without even the implied warranty of
14217365Sjkim   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15217365Sjkim   GNU General Public License for more details.
16217365Sjkim
17217365Sjkim   You should have received a copy of the GNU General Public License
18217365Sjkim   along with this program; if not, write to the Free Software Foundation,
19217365Sjkim   Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
20217365Sjkim
21217365Sjkim
22217365Sjkim/* These two enums are from rel_apu/common/spu_asm_format.h */
23217365Sjkim/* definition of instruction format */
24217365Sjkimtypedef enum {
2567754Smsmith  RRR,
26217365Sjkim  RI18,
27217365Sjkim  RI16,
28217365Sjkim  RI10,
2967754Smsmith  RI8,
30217365Sjkim  RI7,
31217365Sjkim  RR,
32217365Sjkim  LBT,
33217365Sjkim  LBTI,
34217365Sjkim  IDATA,
35217365Sjkim  UNKNOWN_IFORMAT
36217365Sjkim} spu_iformat;
37217365Sjkim
38217365Sjkim/* These values describe assembly instruction arguments.  They indicate
39217365Sjkim * how to encode, range checking and which relocation to use. */
40217365Sjkimtypedef enum {
41217365Sjkim  A_T,  /* register at pos 0 */
42217365Sjkim  A_A,  /* register at pos 7 */
4367754Smsmith  A_B,  /* register at pos 14 */
4467754Smsmith  A_C,  /* register at pos 21 */
4567754Smsmith  A_S,  /* special purpose register at pos 7 */
46193341Sjkim  A_H,  /* channel register at pos 7 */
47193341Sjkim  A_P,  /* parenthesis, this has to separate regs from immediates */
48193341Sjkim  A_S3,
4967754Smsmith  A_S6,
5077424Smsmith  A_S7N,
5191116Smsmith  A_S7,
5267754Smsmith  A_U7A,
5367754Smsmith  A_U7B,
5467754Smsmith  A_S10B,
5567754Smsmith  A_S10,
56151937Sjkim  A_S11,
57151937Sjkim  A_S11I,
58167802Sjkim  A_S14,
59167802Sjkim  A_S16,
60167802Sjkim  A_S18,
61151937Sjkim  A_R18,
62151937Sjkim  A_U3,
63151937Sjkim  A_U5,
64167802Sjkim  A_U6,
65167802Sjkim  A_U7,
66151937Sjkim  A_U14,
67151937Sjkim  A_X16,
6867754Smsmith  A_U18,
69151937Sjkim  A_MAX
70151937Sjkim} spu_aformat;
71167802Sjkim
72167802Sjkimenum spu_insns {
73167802Sjkim#define APUOP(TAG,MACFORMAT,OPCODE,MNEMONIC,ASMFORMAT,DEP,PIPE) \
74167802Sjkim	TAG,
75167802Sjkim#define APUOPFB(TAG,MACFORMAT,OPCODE,FB,MNEMONIC,ASMFORMAT,DEP,PIPE) \
76151937Sjkim	TAG,
77167802Sjkim#include "opcode/spu-insns.h"
78167802Sjkim#undef APUOP
79167802Sjkim#undef APUOPFB
80151937Sjkim        M_SPU_MAX
8167754Smsmith};
8267754Smsmith
83167802Sjkimstruct spu_opcode
8467754Smsmith{
8567754Smsmith   spu_iformat insn_type;
86167802Sjkim   unsigned int opcode;
87167802Sjkim   char *mnemonic;
88167802Sjkim   int arg[5];
89167802Sjkim};
90167802Sjkim
91167802Sjkim#define SIGNED_EXTRACT(insn,size,pos) (((int)((insn) << (32-size-pos))) >> (32-size))
92151937Sjkim#define UNSIGNED_EXTRACT(insn,size,pos) (((insn) >> pos) & ((1 << size)-1))
93167802Sjkim
94167802Sjkim#define DECODE_INSN_RT(insn) (insn & 0x7f)
95167802Sjkim#define DECODE_INSN_RA(insn) ((insn >> 7) & 0x7f)
9667754Smsmith#define DECODE_INSN_RB(insn) ((insn >> 14) & 0x7f)
97167802Sjkim#define DECODE_INSN_RC(insn) ((insn >> 21) & 0x7f)
9867754Smsmith
99167802Sjkim#define DECODE_INSN_I10(insn) SIGNED_EXTRACT(insn,10,14)
100167802Sjkim#define DECODE_INSN_U10(insn) UNSIGNED_EXTRACT(insn,10,14)
101167802Sjkim
102167802Sjkim/* For branching, immediate loads, hbr and  lqa/stqa. */
103167802Sjkim#define DECODE_INSN_I16(insn) SIGNED_EXTRACT(insn,16,7)
104167802Sjkim#define DECODE_INSN_U16(insn) UNSIGNED_EXTRACT(insn,16,7)
105204773Sjkim
106167802Sjkim/* for stop */
107167802Sjkim#define DECODE_INSN_U14(insn) UNSIGNED_EXTRACT(insn,14,0)
10867754Smsmith
109167802Sjkim/* For ila */
110167802Sjkim#define DECODE_INSN_I18(insn) SIGNED_EXTRACT(insn,18,7)
111167802Sjkim#define DECODE_INSN_U18(insn) UNSIGNED_EXTRACT(insn,18,7)
112167802Sjkim
11367754Smsmith/* For rotate and shift and generate control mask */
114167802Sjkim#define DECODE_INSN_I7(insn) SIGNED_EXTRACT(insn,7,14)
11567754Smsmith#define DECODE_INSN_U7(insn) UNSIGNED_EXTRACT(insn,7,14)
116167802Sjkim
117167802Sjkim/* For float <-> int conversion */
11867754Smsmith#define DECODE_INSN_I8(insn)  SIGNED_EXTRACT(insn,8,14)
11967754Smsmith#define DECODE_INSN_U8(insn) UNSIGNED_EXTRACT(insn,8,14)
12067754Smsmith
12167754Smsmith/* For hbr  */
12267754Smsmith#define DECODE_INSN_I9a(insn) ((SIGNED_EXTRACT(insn,2,23) << 7) | UNSIGNED_EXTRACT(insn,7,0))
123151937Sjkim#define DECODE_INSN_I9b(insn) ((SIGNED_EXTRACT(insn,2,14) << 7) | UNSIGNED_EXTRACT(insn,7,0))
12467754Smsmith#define DECODE_INSN_U9a(insn) ((UNSIGNED_EXTRACT(insn,2,23) << 7) | UNSIGNED_EXTRACT(insn,7,0))
125151937Sjkim#define DECODE_INSN_U9b(insn) ((UNSIGNED_EXTRACT(insn,2,14) << 7) | UNSIGNED_EXTRACT(insn,7,0))
126151937Sjkim
127151937Sjkim