162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */ 262306a36Sopenharmony_ci/* SPU ELF support for BFD. 362306a36Sopenharmony_ci 462306a36Sopenharmony_ci Copyright 2006 Free Software Foundation, Inc. 562306a36Sopenharmony_ci 662306a36Sopenharmony_ci This file is part of GDB, GAS, and the GNU binutils. 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci */ 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_ci/* These two enums are from rel_apu/common/spu_asm_format.h */ 1262306a36Sopenharmony_ci/* definition of instruction format */ 1362306a36Sopenharmony_citypedef enum { 1462306a36Sopenharmony_ci RRR, 1562306a36Sopenharmony_ci RI18, 1662306a36Sopenharmony_ci RI16, 1762306a36Sopenharmony_ci RI10, 1862306a36Sopenharmony_ci RI8, 1962306a36Sopenharmony_ci RI7, 2062306a36Sopenharmony_ci RR, 2162306a36Sopenharmony_ci LBT, 2262306a36Sopenharmony_ci LBTI, 2362306a36Sopenharmony_ci IDATA, 2462306a36Sopenharmony_ci UNKNOWN_IFORMAT 2562306a36Sopenharmony_ci} spu_iformat; 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_ci/* These values describe assembly instruction arguments. They indicate 2862306a36Sopenharmony_ci * how to encode, range checking and which relocation to use. */ 2962306a36Sopenharmony_citypedef enum { 3062306a36Sopenharmony_ci A_T, /* register at pos 0 */ 3162306a36Sopenharmony_ci A_A, /* register at pos 7 */ 3262306a36Sopenharmony_ci A_B, /* register at pos 14 */ 3362306a36Sopenharmony_ci A_C, /* register at pos 21 */ 3462306a36Sopenharmony_ci A_S, /* special purpose register at pos 7 */ 3562306a36Sopenharmony_ci A_H, /* channel register at pos 7 */ 3662306a36Sopenharmony_ci A_P, /* parenthesis, this has to separate regs from immediates */ 3762306a36Sopenharmony_ci A_S3, 3862306a36Sopenharmony_ci A_S6, 3962306a36Sopenharmony_ci A_S7N, 4062306a36Sopenharmony_ci A_S7, 4162306a36Sopenharmony_ci A_U7A, 4262306a36Sopenharmony_ci A_U7B, 4362306a36Sopenharmony_ci A_S10B, 4462306a36Sopenharmony_ci A_S10, 4562306a36Sopenharmony_ci A_S11, 4662306a36Sopenharmony_ci A_S11I, 4762306a36Sopenharmony_ci A_S14, 4862306a36Sopenharmony_ci A_S16, 4962306a36Sopenharmony_ci A_S18, 5062306a36Sopenharmony_ci A_R18, 5162306a36Sopenharmony_ci A_U3, 5262306a36Sopenharmony_ci A_U5, 5362306a36Sopenharmony_ci A_U6, 5462306a36Sopenharmony_ci A_U7, 5562306a36Sopenharmony_ci A_U14, 5662306a36Sopenharmony_ci A_X16, 5762306a36Sopenharmony_ci A_U18, 5862306a36Sopenharmony_ci A_MAX 5962306a36Sopenharmony_ci} spu_aformat; 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_cienum spu_insns { 6262306a36Sopenharmony_ci#define APUOP(TAG,MACFORMAT,OPCODE,MNEMONIC,ASMFORMAT,DEP,PIPE) \ 6362306a36Sopenharmony_ci TAG, 6462306a36Sopenharmony_ci#define APUOPFB(TAG,MACFORMAT,OPCODE,FB,MNEMONIC,ASMFORMAT,DEP,PIPE) \ 6562306a36Sopenharmony_ci TAG, 6662306a36Sopenharmony_ci#include "spu-insns.h" 6762306a36Sopenharmony_ci#undef APUOP 6862306a36Sopenharmony_ci#undef APUOPFB 6962306a36Sopenharmony_ci M_SPU_MAX 7062306a36Sopenharmony_ci}; 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_cistruct spu_opcode 7362306a36Sopenharmony_ci{ 7462306a36Sopenharmony_ci spu_iformat insn_type; 7562306a36Sopenharmony_ci unsigned int opcode; 7662306a36Sopenharmony_ci char *mnemonic; 7762306a36Sopenharmony_ci int arg[5]; 7862306a36Sopenharmony_ci}; 7962306a36Sopenharmony_ci 8062306a36Sopenharmony_ci#define SIGNED_EXTRACT(insn,size,pos) (((int)((insn) << (32-size-pos))) >> (32-size)) 8162306a36Sopenharmony_ci#define UNSIGNED_EXTRACT(insn,size,pos) (((insn) >> pos) & ((1 << size)-1)) 8262306a36Sopenharmony_ci 8362306a36Sopenharmony_ci#define DECODE_INSN_RT(insn) (insn & 0x7f) 8462306a36Sopenharmony_ci#define DECODE_INSN_RA(insn) ((insn >> 7) & 0x7f) 8562306a36Sopenharmony_ci#define DECODE_INSN_RB(insn) ((insn >> 14) & 0x7f) 8662306a36Sopenharmony_ci#define DECODE_INSN_RC(insn) ((insn >> 21) & 0x7f) 8762306a36Sopenharmony_ci 8862306a36Sopenharmony_ci#define DECODE_INSN_I10(insn) SIGNED_EXTRACT(insn,10,14) 8962306a36Sopenharmony_ci#define DECODE_INSN_U10(insn) UNSIGNED_EXTRACT(insn,10,14) 9062306a36Sopenharmony_ci 9162306a36Sopenharmony_ci/* For branching, immediate loads, hbr and lqa/stqa. */ 9262306a36Sopenharmony_ci#define DECODE_INSN_I16(insn) SIGNED_EXTRACT(insn,16,7) 9362306a36Sopenharmony_ci#define DECODE_INSN_U16(insn) UNSIGNED_EXTRACT(insn,16,7) 9462306a36Sopenharmony_ci 9562306a36Sopenharmony_ci/* for stop */ 9662306a36Sopenharmony_ci#define DECODE_INSN_U14(insn) UNSIGNED_EXTRACT(insn,14,0) 9762306a36Sopenharmony_ci 9862306a36Sopenharmony_ci/* For ila */ 9962306a36Sopenharmony_ci#define DECODE_INSN_I18(insn) SIGNED_EXTRACT(insn,18,7) 10062306a36Sopenharmony_ci#define DECODE_INSN_U18(insn) UNSIGNED_EXTRACT(insn,18,7) 10162306a36Sopenharmony_ci 10262306a36Sopenharmony_ci/* For rotate and shift and generate control mask */ 10362306a36Sopenharmony_ci#define DECODE_INSN_I7(insn) SIGNED_EXTRACT(insn,7,14) 10462306a36Sopenharmony_ci#define DECODE_INSN_U7(insn) UNSIGNED_EXTRACT(insn,7,14) 10562306a36Sopenharmony_ci 10662306a36Sopenharmony_ci/* For float <-> int conversion */ 10762306a36Sopenharmony_ci#define DECODE_INSN_I8(insn) SIGNED_EXTRACT(insn,8,14) 10862306a36Sopenharmony_ci#define DECODE_INSN_U8(insn) UNSIGNED_EXTRACT(insn,8,14) 10962306a36Sopenharmony_ci 11062306a36Sopenharmony_ci/* For hbr */ 11162306a36Sopenharmony_ci#define DECODE_INSN_I9a(insn) ((SIGNED_EXTRACT(insn,2,23) << 7) | UNSIGNED_EXTRACT(insn,7,0)) 11262306a36Sopenharmony_ci#define DECODE_INSN_I9b(insn) ((SIGNED_EXTRACT(insn,2,14) << 7) | UNSIGNED_EXTRACT(insn,7,0)) 11362306a36Sopenharmony_ci#define DECODE_INSN_U9a(insn) ((UNSIGNED_EXTRACT(insn,2,23) << 7) | UNSIGNED_EXTRACT(insn,7,0)) 11462306a36Sopenharmony_ci#define DECODE_INSN_U9b(insn) ((UNSIGNED_EXTRACT(insn,2,14) << 7) | UNSIGNED_EXTRACT(insn,7,0)) 11562306a36Sopenharmony_ci 116