xref: /OK3568_Linux_fs/kernel/arch/powerpc/xmon/spu.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-or-later */
2*4882a593Smuzhiyun /* SPU ELF support for BFD.
3*4882a593Smuzhiyun 
4*4882a593Smuzhiyun    Copyright 2006 Free Software Foundation, Inc.
5*4882a593Smuzhiyun 
6*4882a593Smuzhiyun    This file is part of GDB, GAS, and the GNU binutils.
7*4882a593Smuzhiyun 
8*4882a593Smuzhiyun  */
9*4882a593Smuzhiyun 
10*4882a593Smuzhiyun 
11*4882a593Smuzhiyun /* These two enums are from rel_apu/common/spu_asm_format.h */
12*4882a593Smuzhiyun /* definition of instruction format */
13*4882a593Smuzhiyun typedef enum {
14*4882a593Smuzhiyun   RRR,
15*4882a593Smuzhiyun   RI18,
16*4882a593Smuzhiyun   RI16,
17*4882a593Smuzhiyun   RI10,
18*4882a593Smuzhiyun   RI8,
19*4882a593Smuzhiyun   RI7,
20*4882a593Smuzhiyun   RR,
21*4882a593Smuzhiyun   LBT,
22*4882a593Smuzhiyun   LBTI,
23*4882a593Smuzhiyun   IDATA,
24*4882a593Smuzhiyun   UNKNOWN_IFORMAT
25*4882a593Smuzhiyun } spu_iformat;
26*4882a593Smuzhiyun 
27*4882a593Smuzhiyun /* These values describe assembly instruction arguments.  They indicate
28*4882a593Smuzhiyun  * how to encode, range checking and which relocation to use. */
29*4882a593Smuzhiyun typedef enum {
30*4882a593Smuzhiyun   A_T,  /* register at pos 0 */
31*4882a593Smuzhiyun   A_A,  /* register at pos 7 */
32*4882a593Smuzhiyun   A_B,  /* register at pos 14 */
33*4882a593Smuzhiyun   A_C,  /* register at pos 21 */
34*4882a593Smuzhiyun   A_S,  /* special purpose register at pos 7 */
35*4882a593Smuzhiyun   A_H,  /* channel register at pos 7 */
36*4882a593Smuzhiyun   A_P,  /* parenthesis, this has to separate regs from immediates */
37*4882a593Smuzhiyun   A_S3,
38*4882a593Smuzhiyun   A_S6,
39*4882a593Smuzhiyun   A_S7N,
40*4882a593Smuzhiyun   A_S7,
41*4882a593Smuzhiyun   A_U7A,
42*4882a593Smuzhiyun   A_U7B,
43*4882a593Smuzhiyun   A_S10B,
44*4882a593Smuzhiyun   A_S10,
45*4882a593Smuzhiyun   A_S11,
46*4882a593Smuzhiyun   A_S11I,
47*4882a593Smuzhiyun   A_S14,
48*4882a593Smuzhiyun   A_S16,
49*4882a593Smuzhiyun   A_S18,
50*4882a593Smuzhiyun   A_R18,
51*4882a593Smuzhiyun   A_U3,
52*4882a593Smuzhiyun   A_U5,
53*4882a593Smuzhiyun   A_U6,
54*4882a593Smuzhiyun   A_U7,
55*4882a593Smuzhiyun   A_U14,
56*4882a593Smuzhiyun   A_X16,
57*4882a593Smuzhiyun   A_U18,
58*4882a593Smuzhiyun   A_MAX
59*4882a593Smuzhiyun } spu_aformat;
60*4882a593Smuzhiyun 
61*4882a593Smuzhiyun enum spu_insns {
62*4882a593Smuzhiyun #define APUOP(TAG,MACFORMAT,OPCODE,MNEMONIC,ASMFORMAT,DEP,PIPE) \
63*4882a593Smuzhiyun 	TAG,
64*4882a593Smuzhiyun #define APUOPFB(TAG,MACFORMAT,OPCODE,FB,MNEMONIC,ASMFORMAT,DEP,PIPE) \
65*4882a593Smuzhiyun 	TAG,
66*4882a593Smuzhiyun #include "spu-insns.h"
67*4882a593Smuzhiyun #undef APUOP
68*4882a593Smuzhiyun #undef APUOPFB
69*4882a593Smuzhiyun         M_SPU_MAX
70*4882a593Smuzhiyun };
71*4882a593Smuzhiyun 
72*4882a593Smuzhiyun struct spu_opcode
73*4882a593Smuzhiyun {
74*4882a593Smuzhiyun    spu_iformat insn_type;
75*4882a593Smuzhiyun    unsigned int opcode;
76*4882a593Smuzhiyun    char *mnemonic;
77*4882a593Smuzhiyun    int arg[5];
78*4882a593Smuzhiyun };
79*4882a593Smuzhiyun 
80*4882a593Smuzhiyun #define SIGNED_EXTRACT(insn,size,pos) (((int)((insn) << (32-size-pos))) >> (32-size))
81*4882a593Smuzhiyun #define UNSIGNED_EXTRACT(insn,size,pos) (((insn) >> pos) & ((1 << size)-1))
82*4882a593Smuzhiyun 
83*4882a593Smuzhiyun #define DECODE_INSN_RT(insn) (insn & 0x7f)
84*4882a593Smuzhiyun #define DECODE_INSN_RA(insn) ((insn >> 7) & 0x7f)
85*4882a593Smuzhiyun #define DECODE_INSN_RB(insn) ((insn >> 14) & 0x7f)
86*4882a593Smuzhiyun #define DECODE_INSN_RC(insn) ((insn >> 21) & 0x7f)
87*4882a593Smuzhiyun 
88*4882a593Smuzhiyun #define DECODE_INSN_I10(insn) SIGNED_EXTRACT(insn,10,14)
89*4882a593Smuzhiyun #define DECODE_INSN_U10(insn) UNSIGNED_EXTRACT(insn,10,14)
90*4882a593Smuzhiyun 
91*4882a593Smuzhiyun /* For branching, immediate loads, hbr and  lqa/stqa. */
92*4882a593Smuzhiyun #define DECODE_INSN_I16(insn) SIGNED_EXTRACT(insn,16,7)
93*4882a593Smuzhiyun #define DECODE_INSN_U16(insn) UNSIGNED_EXTRACT(insn,16,7)
94*4882a593Smuzhiyun 
95*4882a593Smuzhiyun /* for stop */
96*4882a593Smuzhiyun #define DECODE_INSN_U14(insn) UNSIGNED_EXTRACT(insn,14,0)
97*4882a593Smuzhiyun 
98*4882a593Smuzhiyun /* For ila */
99*4882a593Smuzhiyun #define DECODE_INSN_I18(insn) SIGNED_EXTRACT(insn,18,7)
100*4882a593Smuzhiyun #define DECODE_INSN_U18(insn) UNSIGNED_EXTRACT(insn,18,7)
101*4882a593Smuzhiyun 
102*4882a593Smuzhiyun /* For rotate and shift and generate control mask */
103*4882a593Smuzhiyun #define DECODE_INSN_I7(insn) SIGNED_EXTRACT(insn,7,14)
104*4882a593Smuzhiyun #define DECODE_INSN_U7(insn) UNSIGNED_EXTRACT(insn,7,14)
105*4882a593Smuzhiyun 
106*4882a593Smuzhiyun /* For float <-> int conversion */
107*4882a593Smuzhiyun #define DECODE_INSN_I8(insn)  SIGNED_EXTRACT(insn,8,14)
108*4882a593Smuzhiyun #define DECODE_INSN_U8(insn) UNSIGNED_EXTRACT(insn,8,14)
109*4882a593Smuzhiyun 
110*4882a593Smuzhiyun /* For hbr  */
111*4882a593Smuzhiyun #define DECODE_INSN_I9a(insn) ((SIGNED_EXTRACT(insn,2,23) << 7) | UNSIGNED_EXTRACT(insn,7,0))
112*4882a593Smuzhiyun #define DECODE_INSN_I9b(insn) ((SIGNED_EXTRACT(insn,2,14) << 7) | UNSIGNED_EXTRACT(insn,7,0))
113*4882a593Smuzhiyun #define DECODE_INSN_U9a(insn) ((UNSIGNED_EXTRACT(insn,2,23) << 7) | UNSIGNED_EXTRACT(insn,7,0))
114*4882a593Smuzhiyun #define DECODE_INSN_U9b(insn) ((UNSIGNED_EXTRACT(insn,2,14) << 7) | UNSIGNED_EXTRACT(insn,7,0))
115*4882a593Smuzhiyun 
116