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