18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */
28c2ecf20Sopenharmony_ci/* SPU ELF support for BFD.
38c2ecf20Sopenharmony_ci
48c2ecf20Sopenharmony_ci   Copyright 2006 Free Software Foundation, Inc.
58c2ecf20Sopenharmony_ci
68c2ecf20Sopenharmony_ci   This file is part of GDB, GAS, and the GNU binutils.
78c2ecf20Sopenharmony_ci
88c2ecf20Sopenharmony_ci */
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_ci
118c2ecf20Sopenharmony_ci/* These two enums are from rel_apu/common/spu_asm_format.h */
128c2ecf20Sopenharmony_ci/* definition of instruction format */
138c2ecf20Sopenharmony_citypedef enum {
148c2ecf20Sopenharmony_ci  RRR,
158c2ecf20Sopenharmony_ci  RI18,
168c2ecf20Sopenharmony_ci  RI16,
178c2ecf20Sopenharmony_ci  RI10,
188c2ecf20Sopenharmony_ci  RI8,
198c2ecf20Sopenharmony_ci  RI7,
208c2ecf20Sopenharmony_ci  RR,
218c2ecf20Sopenharmony_ci  LBT,
228c2ecf20Sopenharmony_ci  LBTI,
238c2ecf20Sopenharmony_ci  IDATA,
248c2ecf20Sopenharmony_ci  UNKNOWN_IFORMAT
258c2ecf20Sopenharmony_ci} spu_iformat;
268c2ecf20Sopenharmony_ci
278c2ecf20Sopenharmony_ci/* These values describe assembly instruction arguments.  They indicate
288c2ecf20Sopenharmony_ci * how to encode, range checking and which relocation to use. */
298c2ecf20Sopenharmony_citypedef enum {
308c2ecf20Sopenharmony_ci  A_T,  /* register at pos 0 */
318c2ecf20Sopenharmony_ci  A_A,  /* register at pos 7 */
328c2ecf20Sopenharmony_ci  A_B,  /* register at pos 14 */
338c2ecf20Sopenharmony_ci  A_C,  /* register at pos 21 */
348c2ecf20Sopenharmony_ci  A_S,  /* special purpose register at pos 7 */
358c2ecf20Sopenharmony_ci  A_H,  /* channel register at pos 7 */
368c2ecf20Sopenharmony_ci  A_P,  /* parenthesis, this has to separate regs from immediates */
378c2ecf20Sopenharmony_ci  A_S3,
388c2ecf20Sopenharmony_ci  A_S6,
398c2ecf20Sopenharmony_ci  A_S7N,
408c2ecf20Sopenharmony_ci  A_S7,
418c2ecf20Sopenharmony_ci  A_U7A,
428c2ecf20Sopenharmony_ci  A_U7B,
438c2ecf20Sopenharmony_ci  A_S10B,
448c2ecf20Sopenharmony_ci  A_S10,
458c2ecf20Sopenharmony_ci  A_S11,
468c2ecf20Sopenharmony_ci  A_S11I,
478c2ecf20Sopenharmony_ci  A_S14,
488c2ecf20Sopenharmony_ci  A_S16,
498c2ecf20Sopenharmony_ci  A_S18,
508c2ecf20Sopenharmony_ci  A_R18,
518c2ecf20Sopenharmony_ci  A_U3,
528c2ecf20Sopenharmony_ci  A_U5,
538c2ecf20Sopenharmony_ci  A_U6,
548c2ecf20Sopenharmony_ci  A_U7,
558c2ecf20Sopenharmony_ci  A_U14,
568c2ecf20Sopenharmony_ci  A_X16,
578c2ecf20Sopenharmony_ci  A_U18,
588c2ecf20Sopenharmony_ci  A_MAX
598c2ecf20Sopenharmony_ci} spu_aformat;
608c2ecf20Sopenharmony_ci
618c2ecf20Sopenharmony_cienum spu_insns {
628c2ecf20Sopenharmony_ci#define APUOP(TAG,MACFORMAT,OPCODE,MNEMONIC,ASMFORMAT,DEP,PIPE) \
638c2ecf20Sopenharmony_ci	TAG,
648c2ecf20Sopenharmony_ci#define APUOPFB(TAG,MACFORMAT,OPCODE,FB,MNEMONIC,ASMFORMAT,DEP,PIPE) \
658c2ecf20Sopenharmony_ci	TAG,
668c2ecf20Sopenharmony_ci#include "spu-insns.h"
678c2ecf20Sopenharmony_ci#undef APUOP
688c2ecf20Sopenharmony_ci#undef APUOPFB
698c2ecf20Sopenharmony_ci        M_SPU_MAX
708c2ecf20Sopenharmony_ci};
718c2ecf20Sopenharmony_ci
728c2ecf20Sopenharmony_cistruct spu_opcode
738c2ecf20Sopenharmony_ci{
748c2ecf20Sopenharmony_ci   spu_iformat insn_type;
758c2ecf20Sopenharmony_ci   unsigned int opcode;
768c2ecf20Sopenharmony_ci   char *mnemonic;
778c2ecf20Sopenharmony_ci   int arg[5];
788c2ecf20Sopenharmony_ci};
798c2ecf20Sopenharmony_ci
808c2ecf20Sopenharmony_ci#define SIGNED_EXTRACT(insn,size,pos) (((int)((insn) << (32-size-pos))) >> (32-size))
818c2ecf20Sopenharmony_ci#define UNSIGNED_EXTRACT(insn,size,pos) (((insn) >> pos) & ((1 << size)-1))
828c2ecf20Sopenharmony_ci
838c2ecf20Sopenharmony_ci#define DECODE_INSN_RT(insn) (insn & 0x7f)
848c2ecf20Sopenharmony_ci#define DECODE_INSN_RA(insn) ((insn >> 7) & 0x7f)
858c2ecf20Sopenharmony_ci#define DECODE_INSN_RB(insn) ((insn >> 14) & 0x7f)
868c2ecf20Sopenharmony_ci#define DECODE_INSN_RC(insn) ((insn >> 21) & 0x7f)
878c2ecf20Sopenharmony_ci
888c2ecf20Sopenharmony_ci#define DECODE_INSN_I10(insn) SIGNED_EXTRACT(insn,10,14)
898c2ecf20Sopenharmony_ci#define DECODE_INSN_U10(insn) UNSIGNED_EXTRACT(insn,10,14)
908c2ecf20Sopenharmony_ci
918c2ecf20Sopenharmony_ci/* For branching, immediate loads, hbr and  lqa/stqa. */
928c2ecf20Sopenharmony_ci#define DECODE_INSN_I16(insn) SIGNED_EXTRACT(insn,16,7)
938c2ecf20Sopenharmony_ci#define DECODE_INSN_U16(insn) UNSIGNED_EXTRACT(insn,16,7)
948c2ecf20Sopenharmony_ci
958c2ecf20Sopenharmony_ci/* for stop */
968c2ecf20Sopenharmony_ci#define DECODE_INSN_U14(insn) UNSIGNED_EXTRACT(insn,14,0)
978c2ecf20Sopenharmony_ci
988c2ecf20Sopenharmony_ci/* For ila */
998c2ecf20Sopenharmony_ci#define DECODE_INSN_I18(insn) SIGNED_EXTRACT(insn,18,7)
1008c2ecf20Sopenharmony_ci#define DECODE_INSN_U18(insn) UNSIGNED_EXTRACT(insn,18,7)
1018c2ecf20Sopenharmony_ci
1028c2ecf20Sopenharmony_ci/* For rotate and shift and generate control mask */
1038c2ecf20Sopenharmony_ci#define DECODE_INSN_I7(insn) SIGNED_EXTRACT(insn,7,14)
1048c2ecf20Sopenharmony_ci#define DECODE_INSN_U7(insn) UNSIGNED_EXTRACT(insn,7,14)
1058c2ecf20Sopenharmony_ci
1068c2ecf20Sopenharmony_ci/* For float <-> int conversion */
1078c2ecf20Sopenharmony_ci#define DECODE_INSN_I8(insn)  SIGNED_EXTRACT(insn,8,14)
1088c2ecf20Sopenharmony_ci#define DECODE_INSN_U8(insn) UNSIGNED_EXTRACT(insn,8,14)
1098c2ecf20Sopenharmony_ci
1108c2ecf20Sopenharmony_ci/* For hbr  */
1118c2ecf20Sopenharmony_ci#define DECODE_INSN_I9a(insn) ((SIGNED_EXTRACT(insn,2,23) << 7) | UNSIGNED_EXTRACT(insn,7,0))
1128c2ecf20Sopenharmony_ci#define DECODE_INSN_I9b(insn) ((SIGNED_EXTRACT(insn,2,14) << 7) | UNSIGNED_EXTRACT(insn,7,0))
1138c2ecf20Sopenharmony_ci#define DECODE_INSN_U9a(insn) ((UNSIGNED_EXTRACT(insn,2,23) << 7) | UNSIGNED_EXTRACT(insn,7,0))
1148c2ecf20Sopenharmony_ci#define DECODE_INSN_U9b(insn) ((UNSIGNED_EXTRACT(insn,2,14) << 7) | UNSIGNED_EXTRACT(insn,7,0))
1158c2ecf20Sopenharmony_ci
116