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