1a5a4af3bSchristos /* SPU ELF support for BFD. 2a5a4af3bSchristos 3*8b657b07Schristos Copyright (C) 2006-2022 Free Software Foundation, Inc. 4a5a4af3bSchristos 5a5a4af3bSchristos This file is part of GDB, GAS, and the GNU binutils. 6a5a4af3bSchristos 7a5a4af3bSchristos This program is free software; you can redistribute it and/or modify 8a5a4af3bSchristos it under the terms of the GNU General Public License as published by 9a5a4af3bSchristos the Free Software Foundation; either version 3 of the License, or 10a5a4af3bSchristos (at your option) any later version. 11a5a4af3bSchristos 12a5a4af3bSchristos This program is distributed in the hope that it will be useful, 13a5a4af3bSchristos but WITHOUT ANY WARRANTY; without even the implied warranty of 14a5a4af3bSchristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15a5a4af3bSchristos GNU General Public License for more details. 16a5a4af3bSchristos 17a5a4af3bSchristos You should have received a copy of the GNU General Public License 18a5a4af3bSchristos along with this program; if not, write to the Free Software Foundation, 19a5a4af3bSchristos Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ 20a5a4af3bSchristos 21a5a4af3bSchristos /* These two enums are from rel_apu/common/spu_asm_format.h */ 22a5a4af3bSchristos /* definition of instruction format */ 23a5a4af3bSchristos typedef enum { 24a5a4af3bSchristos RRR, 25a5a4af3bSchristos RI18, 26a5a4af3bSchristos RI16, 27a5a4af3bSchristos RI10, 28a5a4af3bSchristos RI8, 29a5a4af3bSchristos RI7, 30a5a4af3bSchristos RR, 31a5a4af3bSchristos LBT, 32a5a4af3bSchristos LBTI, 33a5a4af3bSchristos IDATA, 34a5a4af3bSchristos UNKNOWN_IFORMAT 35a5a4af3bSchristos } spu_iformat; 36a5a4af3bSchristos 37a5a4af3bSchristos /* These values describe assembly instruction arguments. They indicate 38a5a4af3bSchristos * how to encode, range checking and which relocation to use. */ 39a5a4af3bSchristos typedef enum { 40a5a4af3bSchristos A_T, /* register at pos 0 */ 41a5a4af3bSchristos A_A, /* register at pos 7 */ 42a5a4af3bSchristos A_B, /* register at pos 14 */ 43a5a4af3bSchristos A_C, /* register at pos 21 */ 44a5a4af3bSchristos A_S, /* special purpose register at pos 7 */ 45a5a4af3bSchristos A_H, /* channel register at pos 7 */ 46a5a4af3bSchristos A_P, /* parenthesis, this has to separate regs from immediates */ 47a5a4af3bSchristos A_S3, 48a5a4af3bSchristos A_S6, 49a5a4af3bSchristos A_S7N, 50a5a4af3bSchristos A_S7, 51a5a4af3bSchristos A_U7A, 52a5a4af3bSchristos A_U7B, 53a5a4af3bSchristos A_S10B, 54a5a4af3bSchristos A_S10, 55a5a4af3bSchristos A_S11, 56a5a4af3bSchristos A_S11I, 57a5a4af3bSchristos A_S14, 58a5a4af3bSchristos A_S16, 59a5a4af3bSchristos A_S18, 60a5a4af3bSchristos A_R18, 61a5a4af3bSchristos A_U3, 62a5a4af3bSchristos A_U5, 63a5a4af3bSchristos A_U6, 64a5a4af3bSchristos A_U7, 65a5a4af3bSchristos A_U14, 66a5a4af3bSchristos A_X16, 67a5a4af3bSchristos A_U18, 68a5a4af3bSchristos A_MAX 69a5a4af3bSchristos } spu_aformat; 70a5a4af3bSchristos 71a5a4af3bSchristos enum spu_insns { 72a5a4af3bSchristos #define APUOP(TAG,MACFORMAT,OPCODE,MNEMONIC,ASMFORMAT,DEP,PIPE) \ 73a5a4af3bSchristos TAG, 74a5a4af3bSchristos #define APUOPFB(TAG,MACFORMAT,OPCODE,FB,MNEMONIC,ASMFORMAT,DEP,PIPE) \ 75a5a4af3bSchristos TAG, 76a5a4af3bSchristos #include "opcode/spu-insns.h" 77a5a4af3bSchristos #undef APUOP 78a5a4af3bSchristos #undef APUOPFB 79a5a4af3bSchristos M_SPU_MAX 80a5a4af3bSchristos }; 81a5a4af3bSchristos 82a5a4af3bSchristos struct spu_opcode 83a5a4af3bSchristos { 84a5a4af3bSchristos spu_iformat insn_type; 85a5a4af3bSchristos unsigned int opcode; 86e5cb852cSchristos const char *mnemonic; 87a5a4af3bSchristos int arg[5]; 88a5a4af3bSchristos }; 89a5a4af3bSchristos 9082650ea5Schristos #define UNSIGNED_EXTRACT(insn, size, pos) \ 9182650ea5Schristos (((insn) >> (pos)) & ((1u << (size)) - 1)) 9282650ea5Schristos #define SIGNED_EXTRACT(insn, size, pos) \ 9382650ea5Schristos (((int) UNSIGNED_EXTRACT(insn, size, pos) \ 9482650ea5Schristos ^ (1 << ((size) - 1))) - (1 << ((size) - 1))) 95a5a4af3bSchristos 96a5a4af3bSchristos #define DECODE_INSN_RT(insn) (insn & 0x7f) 97a5a4af3bSchristos #define DECODE_INSN_RA(insn) ((insn >> 7) & 0x7f) 98a5a4af3bSchristos #define DECODE_INSN_RB(insn) ((insn >> 14) & 0x7f) 99a5a4af3bSchristos #define DECODE_INSN_RC(insn) ((insn >> 21) & 0x7f) 100a5a4af3bSchristos 101a5a4af3bSchristos #define DECODE_INSN_I10(insn) SIGNED_EXTRACT (insn, 10, 14) 102a5a4af3bSchristos #define DECODE_INSN_U10(insn) UNSIGNED_EXTRACT (insn, 10, 14) 103a5a4af3bSchristos 104a5a4af3bSchristos /* For branching, immediate loads, hbr and lqa/stqa. */ 105a5a4af3bSchristos #define DECODE_INSN_I16(insn) SIGNED_EXTRACT (insn, 16, 7) 106a5a4af3bSchristos #define DECODE_INSN_U16(insn) UNSIGNED_EXTRACT (insn, 16, 7) 107a5a4af3bSchristos 108a5a4af3bSchristos /* for stop */ 109a5a4af3bSchristos #define DECODE_INSN_U14(insn) UNSIGNED_EXTRACT (insn, 14, 0) 110a5a4af3bSchristos 111a5a4af3bSchristos /* For ila */ 112a5a4af3bSchristos #define DECODE_INSN_I18(insn) SIGNED_EXTRACT (insn, 18, 7) 113a5a4af3bSchristos #define DECODE_INSN_U18(insn) UNSIGNED_EXTRACT (insn, 18, 7) 114a5a4af3bSchristos 115a5a4af3bSchristos /* For rotate and shift and generate control mask */ 116a5a4af3bSchristos #define DECODE_INSN_I7(insn) SIGNED_EXTRACT (insn, 7, 14) 117a5a4af3bSchristos #define DECODE_INSN_U7(insn) UNSIGNED_EXTRACT (insn, 7, 14) 118a5a4af3bSchristos 119a5a4af3bSchristos /* For float <-> int conversion */ 120a5a4af3bSchristos #define DECODE_INSN_I8(insn) SIGNED_EXTRACT (insn, 8, 14) 121a5a4af3bSchristos #define DECODE_INSN_U8(insn) UNSIGNED_EXTRACT (insn, 8, 14) 122a5a4af3bSchristos 123a5a4af3bSchristos /* For hbr */ 12482650ea5Schristos #define DECODE_INSN_I9a(insn) \ 12582650ea5Schristos ((SIGNED_EXTRACT (insn, 2, 23) * 128) | (int) UNSIGNED_EXTRACT (insn, 7, 0)) 12682650ea5Schristos #define DECODE_INSN_I9b(insn) \ 12782650ea5Schristos ((SIGNED_EXTRACT (insn, 2, 14) * 128) | (int) UNSIGNED_EXTRACT (insn, 7, 0)) 128a5a4af3bSchristos 129