1 /* NDS32-specific support for 32-bit ELF. 2 Copyright (C) 2012-2013 Free Software Foundation, Inc. 3 Contributed by Andes Technology Corporation. 4 5 This file is part of BFD, the Binary File Descriptor library. 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 3 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 19 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 20 02110-1301, USA.*/ 21 22 23 #include <config.h> 24 25 #include <stdlib.h> 26 #include <stdint.h> 27 #include <string.h> 28 #include <assert.h> 29 30 #include "safe-ctype.h" 31 #include "libiberty.h" 32 #include "hashtab.h" 33 #include "bfd.h" 34 35 #include "opcode/nds32.h" 36 #include "nds32-asm.h" 37 38 /* There at at most MAX_LEX_NUM lexical elements in a syntax. */ 39 #define MAX_LEX_NUM 32 40 /* A operand in syntax string should be at most this long. */ 41 #define MAX_LEX_LEN 32 42 /* The max length of a keyword can be. */ 43 #define MAX_KEYWORD_LEN 32 44 /* This LEX is a plain char or operand. */ 45 #define IS_LEX_CHAR(c) (((c) >> 7) == 0) 46 #define LEX_SET_FIELD(c) ((c) | SYN_FIELD) 47 #define LEX_GET_FIELD(c) operand_fields[((c) & 0xff)] 48 /* Get the char in this lexical element. */ 49 #define LEX_CHAR(c) ((c) & 0xff) 50 51 #define USRIDX(group, usr) ((group) | ((usr) << 5)) 52 #define SRIDX(major, minor, ext) \ 53 (((major) << 7) | ((minor) << 3) | (ext)) 54 55 static int parse_re2 (struct nds32_asm_desc *, struct nds32_asm_insn *, 56 char **, int64_t *); 57 static int parse_fe5 (struct nds32_asm_desc *, struct nds32_asm_insn *, 58 char **, int64_t *); 59 static int parse_pi5 (struct nds32_asm_desc *, struct nds32_asm_insn *, 60 char **, int64_t *); 61 62 63 enum 64 { 65 /* This is a field (operand) of just a separator char. */ 66 SYN_FIELD = 0x100, 67 68 /* This operand is used for input or output. (define or use) */ 69 SYN_INPUT = 0x1000, 70 SYN_OUTPUT = 0x2000, 71 SYN_LOPT = 0x4000, 72 SYN_ROPT = 0x8000, 73 74 /* Hardware resources. */ 75 HW_GPR = 0, 76 HW_USR, 77 HW_DXR, 78 HW_SR, 79 HW_FSR, 80 HW_FDR, 81 HW_CP, /* Co-processor ID. */ 82 HW_CPR, /* Co-processor registers. */ 83 HW_ABDIM, /* [ab][di]m? flag for LSMWA?. */ 84 HW_ABM, /* [ab]m? flag for LSMWZB. */ 85 HW_DTITON, 86 HW_DTITOFF, 87 HW_DPREF_ST, 88 HW_CCTL_ST0, 89 HW_CCTL_ST1, 90 HW_CCTL_ST2, 91 HW_CCTL_ST3, 92 HW_CCTL_ST4, 93 HW_CCTL_ST5, 94 HW_CCTL_LV, 95 HW_TLBOP_ST, 96 HW_STANDBY_ST, 97 HW_MSYNC_ST, 98 _HW_LAST, 99 /* TODO: Maybe we should add a new type to distinguish address and 100 const int. Only the former allows symbols and relocations. */ 101 HW_INT, 102 HW_UINT 103 }; 104 105 106 /* These are operand prefixes for input/output semantic. 107 108 % input 109 = output 110 & both 111 {} optional operand 112 113 Field table for operands and bit-fields. */ 114 115 static const field_t operand_fields[] = 116 { 117 {"rt", 20, 5, 0, HW_GPR, NULL}, 118 {"ra", 15, 5, 0, HW_GPR, NULL}, 119 {"rb", 10, 5, 0, HW_GPR, NULL}, 120 {"rd", 5, 5, 0, HW_GPR, NULL}, 121 {"fst", 20, 5, 0, HW_FSR, NULL}, 122 {"fsa", 15, 5, 0, HW_FSR, NULL}, 123 {"fsb", 10, 5, 0, HW_FSR, NULL}, 124 {"fdt", 20, 5, 0, HW_FDR, NULL}, 125 {"fda", 15, 5, 0, HW_FDR, NULL}, 126 {"fdb", 10, 5, 0, HW_FDR, NULL}, 127 {"cprt", 20, 5, 0, HW_CPR, NULL}, 128 {"cp", 13, 2, 0, HW_CP, NULL}, 129 {"sh", 5, 5, 0, HW_UINT, NULL}, /* sh in ALU instructions. */ 130 {"sv", 8, 2, 0, HW_UINT, NULL}, /* sv in MEM instructions. */ 131 {"dt", 21, 1, 0, HW_DXR, NULL}, 132 {"usr", 10, 10, 0, HW_USR, NULL}, /* User Special Registers. */ 133 {"sr", 10, 10, 0, HW_SR, NULL}, /* System Registers. */ 134 {"ridx", 10, 10, 0, HW_UINT, NULL}, /* Raw value for mfusr/mfsr. */ 135 {"enb4", 6, 9, 0, HW_UINT, NULL}, /* Enable4 for LSMW. */ 136 {"swid", 5, 15, 0, HW_UINT, NULL}, 137 {"stdby_st", 5, 2, 0, HW_STANDBY_ST, NULL}, 138 {"tlbop_st", 5, 5, 0, HW_TLBOP_ST, NULL}, 139 {"tlbop_stx", 5, 5, 0, HW_UINT, NULL}, 140 {"cctl_st0", 5, 5, 0, HW_CCTL_ST0, NULL}, 141 {"cctl_st1", 5, 5, 0, HW_CCTL_ST1, NULL}, 142 {"cctl_st2", 5, 5, 0, HW_CCTL_ST2, NULL}, 143 {"cctl_st3", 5, 5, 0, HW_CCTL_ST3, NULL}, 144 {"cctl_st4", 5, 5, 0, HW_CCTL_ST4, NULL}, 145 {"cctl_st5", 5, 5, 0, HW_CCTL_ST5, NULL}, 146 {"cctl_stx", 5, 5, 0, HW_UINT, NULL}, 147 {"cctl_lv", 10, 1, 0, HW_CCTL_LV, NULL}, 148 {"msync_st", 5, 3, 0, HW_MSYNC_ST, NULL}, 149 {"msync_stx", 5, 3, 0, HW_UINT, NULL}, 150 {"dpref_st", 20, 5, 0, HW_DPREF_ST, NULL}, 151 {"rt5", 5, 5, 0, HW_GPR, NULL}, 152 {"ra5", 0, 5, 0, HW_GPR, NULL}, 153 {"rt4", 5, 4, 0, HW_GPR, NULL}, 154 {"rt3", 6, 3, 0, HW_GPR, NULL}, 155 {"rt38", 8, 3, 0, HW_GPR, NULL}, /* rt3 used in 38 form. */ 156 {"ra3", 3, 3, 0, HW_GPR, NULL}, 157 {"rb3", 0, 3, 0, HW_GPR, NULL}, 158 {"rt5e", 4, 4, 1, HW_GPR, NULL}, /* movd44 */ 159 {"ra5e", 0, 4, 1, HW_GPR, NULL}, /* movd44 */ 160 {"re2", 5, 2, 0, HW_GPR, parse_re2}, /* re in push25/pop25. */ 161 {"fe5", 0, 5, 2, HW_UINT, parse_fe5}, /* imm5u in lwi45.fe. */ 162 {"pi5", 0, 5, 0, HW_UINT, parse_pi5}, /* imm5u in movpi45. */ 163 {"abdim", 2, 3, 0, HW_ABDIM, NULL}, /* Flags for LSMW. */ 164 {"abm", 2, 3, 0, HW_ABM, NULL}, /* Flags for LSMWZB. */ 165 {"dtiton", 8, 2, 0, HW_DTITON, NULL}, 166 {"dtitoff", 8, 2, 0, HW_DTITOFF, NULL}, 167 168 {"i5s", 0, 5, 0, HW_INT, NULL}, 169 {"i10s", 0, 10, 0, HW_INT, NULL}, 170 {"i15s", 0, 15, 0, HW_INT, NULL}, 171 {"i19s", 0, 19, 0, HW_INT, NULL}, 172 {"i20s", 0, 20, 0, HW_INT, NULL}, 173 {"i8s1", 0, 8, 1, HW_INT, NULL}, 174 {"i11br3", 8, 11, 0, HW_INT, NULL}, 175 {"i14s1", 0, 14, 1, HW_INT, NULL}, 176 {"i15s1", 0, 15, 1, HW_INT, NULL}, 177 {"i16s1", 0, 16, 1, HW_INT, NULL}, 178 {"i18s1", 0, 18, 1, HW_INT, NULL}, 179 {"i24s1", 0, 24, 1, HW_INT, NULL}, 180 {"i8s2", 0, 8, 2, HW_INT, NULL}, 181 {"i12s2", 0, 12, 2, HW_INT, NULL}, 182 {"i15s2", 0, 15, 2, HW_INT, NULL}, 183 {"i17s2", 0, 17, 2, HW_INT, NULL}, 184 {"i19s2", 0, 19, 2, HW_INT, NULL}, 185 {"i3u", 0, 3, 0, HW_UINT, NULL}, 186 {"i5u", 0, 5, 0, HW_UINT, NULL}, 187 {"ib5u", 10, 5, 0, HW_UINT, NULL}, /* imm5 field in ALU. */ 188 {"ib5s", 10, 5, 0, HW_INT, NULL}, /* imm5 field in ALU. */ 189 {"i9u", 0, 9, 0, HW_UINT, NULL}, /* break16/ex9.it */ 190 {"ia3u", 3, 3, 0, HW_UINT, NULL}, /* bmski33, fexti33 */ 191 {"i8u", 0, 8, 0, HW_UINT, NULL}, 192 {"i15u", 0, 15, 0, HW_UINT, NULL}, 193 {"i20u", 0, 20, 0, HW_UINT, NULL}, 194 {"i3u1", 0, 3, 1, HW_UINT, NULL}, 195 {"i9u1", 0, 9, 1, HW_UINT, NULL}, 196 {"i3u2", 0, 3, 2, HW_UINT, NULL}, 197 {"i6u2", 0, 6, 2, HW_UINT, NULL}, 198 {"i7u2", 0, 7, 2, HW_UINT, NULL}, 199 {"i5u3", 0, 5, 3, HW_UINT, NULL}, /* pop25/pop25 */ 200 {"i15s3", 0, 15, 3, HW_UINT, NULL}, /* dprefi.d */ 201 202 {NULL, 0, 0, 0, 0, NULL} 203 }; 204 205 206 #define OP6(op6) (N32_OP6_ ## op6 << 25) 207 #define DEF_REG(r) (__BIT (r)) 208 #define USE_REG(r) (__BIT (r)) 209 #define RT(r) (r << 20) 210 #define RA(r) (r << 15) 211 #define RB(r) (r << 10) 212 #define RA5(r) (r) 213 214 static struct nds32_opcode nds32_opcodes[] = 215 { 216 /* ALU1 */ 217 #define ALU1(sub) (OP6 (ALU1) | N32_ALU1_ ## sub) 218 {"add", "=rt,%ra,%rb", ALU1 (ADD), 4, ATTR_ALL, 0, NULL, 0, NULL}, 219 {"sub", "=rt,%ra,%rb", ALU1 (SUB), 4, ATTR_ALL, 0, NULL, 0, NULL}, 220 {"and", "=rt,%ra,%rb", ALU1 (AND), 4, ATTR_ALL, 0, NULL, 0, NULL}, 221 {"xor", "=rt,%ra,%rb", ALU1 (XOR), 4, ATTR_ALL, 0, NULL, 0, NULL}, 222 {"or", "=rt,%ra,%rb", ALU1 (OR), 4, ATTR_ALL, 0, NULL, 0, NULL}, 223 {"nor", "=rt,%ra,%rb", ALU1 (NOR), 4, ATTR_ALL, 0, NULL, 0, NULL}, 224 {"slt", "=rt,%ra,%rb", ALU1 (SLT), 4, ATTR_ALL, 0, NULL, 0, NULL}, 225 {"slts", "=rt,%ra,%rb", ALU1 (SLTS), 4, ATTR_ALL, 0, NULL, 0, NULL}, 226 {"slli", "=rt,%ra,%ib5u", ALU1 (SLLI), 4, ATTR_ALL, 0, NULL, 0, NULL}, 227 {"srli", "=rt,%ra,%ib5u", ALU1 (SRLI), 4, ATTR_ALL, 0, NULL, 0, NULL}, 228 {"srai", "=rt,%ra,%ib5u", ALU1 (SRAI), 4, ATTR_ALL, 0, NULL, 0, NULL}, 229 {"rotri", "=rt,%ra,%ib5u", ALU1 (ROTRI), 4, ATTR_ALL, 0, NULL, 0, NULL}, 230 {"sll", "=rt,%ra,%rb", ALU1 (SLL), 4, ATTR_ALL, 0, NULL, 0, NULL}, 231 {"srl", "=rt,%ra,%rb", ALU1 (SRL), 4, ATTR_ALL, 0, NULL, 0, NULL}, 232 {"sra", "=rt,%ra,%rb", ALU1 (SRA), 4, ATTR_ALL, 0, NULL, 0, NULL}, 233 {"rotr", "=rt,%ra,%rb", ALU1 (ROTR), 4, ATTR_ALL, 0, NULL, 0, NULL}, 234 {"seb", "=rt,%ra", ALU1 (SEB), 4, ATTR_ALL, 0, NULL, 0, NULL}, 235 {"seh", "=rt,%ra", ALU1 (SEH), 4, ATTR_ALL, 0, NULL, 0, NULL}, 236 {"bitc", "=rt,%ra,%rb", ALU1 (BITC), 4, ATTR_V3, 0, NULL, 0, NULL}, 237 {"zeh", "=rt,%ra", ALU1 (ZEH), 4, ATTR_ALL, 0, NULL, 0, NULL}, 238 {"wsbh", "=rt,%ra", ALU1 (WSBH), 4, ATTR_ALL, 0, NULL, 0, NULL}, 239 {"divsr", "=rt,=rd,%ra,%rb", ALU1 (DIVSR), 4, ATTR (DIV) | ATTR_V2UP, 0, NULL, 0, NULL}, 240 {"divr", "=rt,=rd,%ra,%rb", ALU1 (DIVR), 4, ATTR (DIV) | ATTR_V2UP, 0, NULL, 0, NULL}, 241 {"sva", "=rt,%ra,%rb", ALU1 (SVA), 4, ATTR_ALL, 0, NULL, 0, NULL}, 242 {"svs", "=rt,%ra,%rb", ALU1 (SVS), 4, ATTR_ALL, 0, NULL, 0, NULL}, 243 {"cmovz", "=rt,%ra,%rb", ALU1 (CMOVZ), 4, ATTR_ALL, 0, NULL, 0, NULL}, 244 {"cmovn", "=rt,%ra,%rb", ALU1 (CMOVN), 4, ATTR_ALL, 0, NULL, 0, NULL}, 245 {"add_slli", "=rt,%ra,%rb,%sh", ALU1 (ADD), 4, ATTR_V3, 0, NULL, 0, NULL}, 246 {"sub_slli", "=rt,%ra,%rb,%sh", ALU1 (SUB), 4, ATTR_V3, 0, NULL, 0, NULL}, 247 {"and_slli", "=rt,%ra,%rb,%sh", ALU1 (AND), 4, ATTR_V3, 0, NULL, 0, NULL}, 248 {"xor_slli", "=rt,%ra,%rb,%sh", ALU1 (XOR), 4, ATTR_V3, 0, NULL, 0, NULL}, 249 {"or_slli", "=rt,%ra,%rb,%sh", ALU1 (OR), 4, ATTR_V3, 0, NULL, 0, NULL}, 250 {"or_srli", "=rt,%ra,%rb,%sh", ALU1 (OR_SRLI), 4, ATTR_V3, 0, NULL, 0, NULL}, 251 {"add_srli", "=rt,%ra,%rb,%sh", ALU1 (ADD_SRLI), 4, ATTR_V3, 0, NULL, 0, NULL}, 252 {"sub_srli", "=rt,%ra,%rb,%sh", ALU1 (SUB_SRLI), 4, ATTR_V3, 0, NULL, 0, NULL}, 253 {"and_srli", "=rt,%ra,%rb,%sh", ALU1 (AND_SRLI), 4, ATTR_V3, 0, NULL, 0, NULL}, 254 {"xor_srli", "=rt,%ra,%rb,%sh", ALU1 (XOR_SRLI), 4, ATTR_V3, 0, NULL, 0, NULL}, 255 256 /* ALU2 */ 257 #define ALU2(sub) (OP6 (ALU2) | N32_ALU2_ ## sub) 258 {"max", "=rt,%ra,%rb", ALU2 (MAX), 4, ATTR (PERF_EXT), 0, NULL, 0, NULL}, 259 {"min", "=rt,%ra,%rb", ALU2 (MIN), 4, ATTR (PERF_EXT), 0, NULL, 0, NULL}, 260 {"ave", "=rt,%ra,%rb", ALU2 (AVE), 4, ATTR (PERF_EXT), 0, NULL, 0, NULL}, 261 {"abs", "=rt,%ra", ALU2 (ABS), 4, ATTR (PERF_EXT), 0, NULL, 0, NULL}, 262 {"clips", "=rt,%ra,%ib5s", ALU2 (CLIPS), 4, ATTR (PERF_EXT), 0, NULL, 0, NULL}, 263 {"clip", "=rt,%ra,%ib5u", ALU2 (CLIP), 4, ATTR (PERF_EXT), 0, NULL, 0, NULL}, 264 {"clo", "=rt,%ra", ALU2 (CLO), 4, ATTR (PERF_EXT), 0, NULL, 0, NULL}, 265 {"clz", "=rt,%ra", ALU2 (CLZ), 4, ATTR (PERF_EXT), 0, NULL, 0, NULL}, 266 {"bset", "=rt,%ra,%ib5u", ALU2 (BSET), 4, ATTR (PERF_EXT), 0, NULL, 0, NULL}, 267 {"bclr", "=rt,%ra,%ib5u", ALU2 (BCLR), 4, ATTR (PERF_EXT), 0, NULL, 0, NULL}, 268 {"btgl", "=rt,%ra,%ib5u", ALU2 (BTGL), 4, ATTR (PERF_EXT), 0, NULL, 0, NULL}, 269 {"btst", "=rt,%ra,%ib5u", ALU2 (BTST), 4, ATTR (PERF_EXT), 0, NULL, 0, NULL}, 270 {"bse", "=rt,%ra,=rb", ALU2 (BSE), 4, ATTR (PERF2_EXT), 0, NULL, 0, NULL}, 271 {"bsp", "=rt,%ra,=rb", ALU2 (BSP), 4, ATTR (PERF2_EXT), 0, NULL, 0, NULL}, 272 {"ffb", "=rt,%ra,%rb", ALU2 (FFB), 4, ATTR (STR_EXT), 0, NULL, 0, NULL}, 273 {"ffmism", "=rt,%ra,%rb", ALU2 (FFMISM), 4, ATTR (STR_EXT), 0, NULL, 0, NULL}, 274 {"ffzmism", "=rt,%ra,%rb", ALU2 (FFZMISM), 4, ATTR (STR_EXT), 0, NULL, 0, NULL}, 275 {"mfusr", "=rt,%usr", ALU2 (MFUSR), 4, ATTR_V3MEX_V1, 0, NULL, 0, NULL}, 276 {"mtusr", "%rt,%usr", ALU2 (MTUSR), 4, ATTR_V3MEX_V1, 0, NULL, 0, NULL}, 277 {"mfusr", "=rt,%ridx", ALU2 (MFUSR), 4, ATTR_V3MEX_V1, 0, NULL, 0, NULL}, 278 {"mtusr", "%rt,%ridx", ALU2 (MTUSR), 4, ATTR_V3MEX_V1, 0, NULL, 0, NULL}, 279 {"mul", "=rt,%ra,%rb", ALU2 (MUL), 4, ATTR_ALL, 0, NULL, 0, NULL}, 280 {"mults64", "=dt,%ra,%rb", ALU2 (MULTS64), 4, ATTR_ALL, 0, NULL, 0, NULL}, 281 {"mult64", "=dt,%ra,%rb", ALU2 (MULT64), 4, ATTR_ALL, 0, NULL, 0, NULL}, 282 {"madds64", "=dt,%ra,%rb", ALU2 (MADDS64), 4, ATTR (MAC) | ATTR_ALL, 0, NULL, 0, NULL}, 283 {"madd64", "=dt,%ra,%rb", ALU2 (MADD64), 4, ATTR (MAC) | ATTR_ALL, 0, NULL, 0, NULL}, 284 {"msubs64", "=dt,%ra,%rb", ALU2 (MSUBS64), 4, ATTR (MAC) | ATTR_ALL, 0, NULL, 0, NULL}, 285 {"msub64", "=dt,%ra,%rb", ALU2 (MSUB64), 4, ATTR (MAC) | ATTR_ALL, 0, NULL, 0, NULL}, 286 {"divs", "=dt,%ra,%rb", ALU2 (DIVS), 4, ATTR (DIV) | ATTR (DXREG), 0, NULL, 0, NULL}, 287 {"div", "=dt,%ra,%rb", ALU2 (DIV), 4, ATTR (DIV) | ATTR (DXREG), 0, NULL, 0, NULL}, 288 {"mult32", "=dt,%ra,%rb", ALU2 (MULT32), 4, ATTR (DXREG) | ATTR_ALL, 0, NULL, 0, NULL}, 289 {"madd32", "=dt,%ra,%rb", ALU2 (MADD32), 4, ATTR (MAC) | ATTR (DXREG) | ATTR_ALL, 0, NULL, 0, NULL}, 290 {"msub32", "=dt,%ra,%rb", ALU2 (MSUB32), 4, ATTR (MAC) | ATTR (DXREG) | ATTR_ALL, 0, NULL, 0, NULL}, 291 {"ffbi", "=rt,%ra,%ib5u", ALU2 (FFBI) | __BIT (6), 4, ATTR (STR_EXT), 0, NULL, 0, NULL}, 292 {"flmism", "=rt,%ra,%rb", ALU2 (FLMISM) | __BIT (6), 4, ATTR (STR_EXT), 0, NULL, 0, NULL}, 293 {"mulsr64", "=rt,%ra,%rb", ALU2 (MULSR64)| __BIT (6), 4, ATTR_V3MEX_V2, 0, NULL, 0, NULL}, 294 {"mulr64", "=rt,%ra,%rb", ALU2 (MULR64) | __BIT (6), 4, ATTR_V3MEX_V2, 0, NULL, 0, NULL}, 295 {"maddr32", "=rt,%ra,%rb", ALU2 (MADDR32) | __BIT (6), 4, ATTR (MAC) | ATTR_V2UP, 0, NULL, 0, NULL}, 296 {"msubr32", "=rt,%ra,%rb", ALU2 (MSUBR32) | __BIT (6), 4, ATTR (MAC) | ATTR_V2UP, 0, NULL, 0, NULL}, 297 298 /* MISC */ 299 #define MISC(sub) (OP6 (MISC) | N32_MISC_ ## sub) 300 {"standby", "%stdby_st", MISC (STANDBY), 4, ATTR_ALL, 0, NULL, 0, NULL}, 301 {"cctl", "%ra,%cctl_st0", MISC (CCTL), 4, ATTR_V3MEX_V1, 0, NULL, 0, NULL}, 302 {"cctl", "%ra,%cctl_st1{,%cctl_lv}", MISC (CCTL), 4, ATTR_V3MEX_V1, 0, NULL, 0, NULL}, 303 {"cctl", "=rt,%ra,%cctl_st2", MISC (CCTL), 4, ATTR_V3MEX_V1, 0, NULL, 0, NULL}, 304 {"cctl", "%rt,%ra,%cctl_st3", MISC (CCTL), 4, ATTR_V3MEX_V1, 0, NULL, 0, NULL}, 305 {"cctl", "%cctl_st4", MISC (CCTL), 4, ATTR_V3MEX_V1, 0, NULL, 0, NULL}, 306 {"cctl", "%cctl_st5{,%cctl_lv}", MISC (CCTL), 4, ATTR_V3, 0, NULL, 0, NULL}, 307 {"cctl", "=rt,%ra,%cctl_stx,%cctl_lv", MISC (CCTL), 4, ATTR_V3MEX_V1, 0, NULL, 0, NULL}, 308 {"mfsr", "=rt,%sr", MISC (MFSR), 4, ATTR_ALL, 0, NULL, 0, NULL}, 309 {"mtsr", "%rt,%sr", MISC (MTSR), 4, ATTR_ALL, 0, NULL, 0, NULL}, 310 {"mfsr", "=rt,%ridx", MISC (MFSR), 4, ATTR_ALL, 0, NULL, 0, NULL}, 311 {"mtsr", "%rt,%ridx", MISC (MTSR), 4, ATTR_ALL, 0, NULL, 0, NULL}, 312 {"iret", "", MISC (IRET), 4, ATTR_ALL, 0, NULL, 0, NULL}, 313 {"trap", "%swid", MISC (TRAP), 4, ATTR_V3MEX_V1, 0, NULL, 0, NULL}, 314 {"trap", "", MISC (TRAP), 4, ATTR_V3MEX_V1, 0, NULL, 0, NULL}, 315 {"teqz", "%rt,%swid", MISC (TEQZ), 4, ATTR_V3MEX_V1, 0, NULL, 0, NULL}, 316 {"tnez", "%rt,%swid", MISC (TNEZ), 4, ATTR_V3MEX_V1, 0, NULL, 0, NULL}, 317 {"dsb", "", MISC (DSB), 4, ATTR_ALL, 0, NULL, 0, NULL}, 318 {"isb", "", MISC (ISB), 4, ATTR_ALL, 0, NULL, 0, NULL}, 319 {"break", "%swid", MISC (BREAK), 4, ATTR_ALL, 0, NULL, 0, NULL}, 320 {"break", "", MISC (BREAK), 4, ATTR_ALL, 0, NULL, 0, NULL}, 321 {"syscall", "%swid", MISC (SYSCALL), 4, ATTR_ALL, 0, NULL, 0, NULL}, 322 {"msync", "%msync_st", MISC (MSYNC), 4, ATTR_ALL, 0, NULL, 0, NULL}, 323 {"msync", "%msync_stx", MISC (MSYNC), 4, ATTR_ALL, 0, NULL, 0, NULL}, 324 {"isync", "%rt", MISC (ISYNC), 4, ATTR_ALL, 0, NULL, 0, NULL}, 325 {"tlbop", "%ra,%tlbop_st", MISC (TLBOP), 4, ATTR_V3MEX_V1, 0, NULL, 0, NULL}, 326 {"tlbop", "%ra,%tlbop_stx", MISC (TLBOP), 4, ATTR_V3MEX_V1, 0, NULL, 0, NULL}, 327 {"tlbop", "%rt,%ra,pb", MISC (TLBOP) | (5 << 5), 4, ATTR_V3MEX_V1, 0, NULL, 0, NULL}, 328 {"tlbop", "flua", MISC (TLBOP) | (7 << 5), 4, ATTR_V3MEX_V1, 0, NULL, 0, NULL}, 329 330 {"setend.l", "", MISC (MTSR) 331 | (SRIDX (1, 0, 0) << 10) | __BIT (5), 4, ATTR_ALL, 0, NULL, 0, NULL}, 332 {"setend.b", "", MISC (MTSR) 333 | (SRIDX (1, 0, 0) << 10) | __BIT (5) | __BIT (20), 4, ATTR_ALL, 0, NULL, 0, NULL}, 334 {"setgie.d", "", MISC (MTSR) 335 | (SRIDX (1, 0, 0) << 10) | __BIT (6), 4, ATTR_ALL, 0, NULL, 0, NULL}, 336 {"setgie.e", "", MISC (MTSR) 337 | (SRIDX (1, 0, 0) << 10) | __BIT (6) | __BIT (20), 4, ATTR_ALL, 0, NULL, 0, NULL}, 338 339 /* JI */ 340 {"jal", "%i24s1", OP6 (JI) | __BIT (24), 4, ATTR_PCREL | ATTR_ALL, 0, NULL, 0, NULL}, 341 {"j", "%i24s1", OP6 (JI), 4, ATTR_PCREL | ATTR_ALL, 0, NULL, 0, NULL}, 342 343 /* BR1 */ 344 {"beq", "%rt,%ra,%i14s1", OP6 (BR1), 4, ATTR_PCREL | ATTR_ALL, 0, NULL, 0, NULL}, 345 {"bne", "%rt,%ra,%i14s1", OP6 (BR1) | __BIT (14), 4, ATTR_PCREL | ATTR_ALL, 0, NULL, 0, NULL}, 346 347 /* BR2 */ 348 #define BR2(sub) (OP6 (BR2) | (N32_BR2_ ## sub << 16)) 349 {"beqz", "%rt,%i16s1", BR2 (BEQZ), 4, ATTR_PCREL | ATTR_ALL, 0, NULL, 0, NULL}, 350 {"bnez", "%rt,%i16s1", BR2 (BNEZ), 4, ATTR_PCREL | ATTR_ALL, 0, NULL, 0, NULL}, 351 {"bgez", "%rt,%i16s1", BR2 (BGEZ), 4, ATTR_PCREL | ATTR_ALL, 0, NULL, 0, NULL}, 352 {"bltz", "%rt,%i16s1", BR2 (BLTZ), 4, ATTR_PCREL | ATTR_ALL, 0, NULL, 0, NULL}, 353 {"bgtz", "%rt,%i16s1", BR2 (BGTZ), 4, ATTR_PCREL | ATTR_ALL, 0, NULL, 0, NULL}, 354 {"blez", "%rt,%i16s1", BR2 (BLEZ), 4, ATTR_PCREL | ATTR_ALL, 0, NULL, 0, NULL}, 355 {"bgezal", "%rt,%i16s1", BR2 (BGEZAL), 4, ATTR_PCREL | ATTR_ALL, 0, NULL, 0, NULL}, 356 {"bltzal", "%rt,%i16s1", BR2 (BLTZAL), 4, ATTR_PCREL | ATTR_ALL, 0, NULL, 0, NULL}, 357 358 /* BR3 */ 359 {"beqc", "%rt,%i11br3,%i8s1", OP6 (BR3), 4, ATTR_PCREL | ATTR_V3MUP, 0, NULL, 0, NULL}, 360 {"bnec", "%rt,%i11br3,%i8s1", OP6 (BR3) | __BIT (19), 4, ATTR_PCREL | ATTR_V3MUP, 0, NULL, 0, NULL}, 361 362 #define JREG(sub) (OP6 (JREG) | N32_JREG_ ## sub) 363 /* JREG */ 364 {"jr", "%rb", JREG (JR), 4, ATTR (BRANCH) | ATTR_ALL, 0, NULL, 0, NULL}, 365 {"jral", "%rt,%rb", JREG (JRAL), 4, ATTR (BRANCH) | ATTR_ALL, 0, NULL, 0, NULL}, 366 {"jral", "%rb", JREG (JRAL) | RT (30), 4, ATTR (BRANCH) | ATTR_ALL, 0, NULL, 0, NULL}, 367 {"jrnez", "%rb", JREG (JRNEZ), 4, ATTR (BRANCH) | ATTR_V3, 0, NULL, 0, NULL}, 368 {"jralnez", "%rt,%rb", JREG (JRALNEZ), 4, ATTR (BRANCH) | ATTR_V3, 0, NULL, 0, NULL}, 369 {"jralnez", "%rb", JREG (JRALNEZ) | RT (30), 4, ATTR (BRANCH) | ATTR_V3, 0, NULL, 0, NULL}, 370 371 #define JREG_RET (1 << 5) 372 #define JREG_IFC (1 << 6) 373 {"ret", "%rb", JREG (JR) | JREG_RET, 4, ATTR (BRANCH) | ATTR_ALL, 0, NULL, 0, NULL}, 374 {"ret", "", JREG (JR) | JREG_RET | RB (30), 4, ATTR (BRANCH) | ATTR_ALL, 0, NULL, 0, NULL}, 375 {"jral", "%dtiton %rt,%rb", JREG (JRAL), 4, ATTR (BRANCH) | ATTR_ALL, 0, NULL, 0, NULL}, 376 {"jral", "%dtiton %rb", JREG (JRAL) | RT (30), 4, ATTR (BRANCH) | ATTR_ALL, 0, NULL, 0, NULL}, 377 {"jr", "%dtitoff %rb", JREG (JR), 4, ATTR (BRANCH) | ATTR_V3MEX_V1, 0, NULL, 0, NULL}, 378 {"ret", "%dtitoff %rb", JREG (JR) | JREG_RET, 4, ATTR (BRANCH) | ATTR_V3MEX_V1, 0, NULL, 0, NULL}, 379 {"ifret", "", JREG (JR) | JREG_IFC | JREG_RET, 4, ATTR (BRANCH) | ATTR (IFC_EXT), 0, NULL, 0, NULL}, 380 381 /* MEM */ 382 #define MEM(sub) (OP6 (MEM) | N32_MEM_ ## sub) 383 {"lb", "=rt,[%ra+(%rb<<%sv)]", MEM (LB), 4, ATTR_ALL, 0, NULL, 0, NULL}, 384 {"lb", "=rt,[%ra+%rb{<<%sv}]", MEM (LB), 4, ATTR_ALL, 0, NULL, 0, NULL}, 385 {"lh", "=rt,[%ra+(%rb<<%sv)]", MEM (LH), 4, ATTR_ALL, 0, NULL, 0, NULL}, 386 {"lh", "=rt,[%ra+%rb{<<%sv}]", MEM (LH), 4, ATTR_ALL, 0, NULL, 0, NULL}, 387 {"lw", "=rt,[%ra+(%rb<<%sv)]", MEM (LW), 4, ATTR_ALL, 0, NULL, 0, NULL}, 388 {"lw", "=rt,[%ra+%rb{<<%sv}]", MEM (LW), 4, ATTR_ALL, 0, NULL, 0, NULL}, 389 {"sb", "=rt,[%ra+(%rb<<%sv)]", MEM (SB), 4, ATTR_ALL, 0, NULL, 0, NULL}, 390 {"sb", "%rt,[%ra+%rb{<<%sv}]", MEM (SB), 4, ATTR_ALL, 0, NULL, 0, NULL}, 391 {"sh", "=rt,[%ra+(%rb<<%sv)]", MEM (SH), 4, ATTR_ALL, 0, NULL, 0, NULL}, 392 {"sh", "%rt,[%ra+%rb{<<%sv}]", MEM (SH), 4, ATTR_ALL, 0, NULL, 0, NULL}, 393 {"sw", "=rt,[%ra+(%rb<<%sv)]", MEM (SW), 4, ATTR_ALL, 0, NULL, 0, NULL}, 394 {"sw", "%rt,[%ra+%rb{<<%sv}]", MEM (SW), 4, ATTR_ALL, 0, NULL, 0, NULL}, 395 {"lb.bi", "=rt,[%ra],(%rb<<%sv)", MEM (LB_BI), 4, ATTR_ALL, 0, NULL, 0, NULL}, 396 {"lb.bi", "=rt,[%ra],%rb{<<%sv}", MEM (LB_BI), 4, ATTR_ALL, 0, NULL, 0, NULL}, 397 {"lh.bi", "=rt,[%ra],(%rb<<%sv)", MEM (LH_BI), 4, ATTR_ALL, 0, NULL, 0, NULL}, 398 {"lh.bi", "=rt,[%ra],%rb{<<%sv}", MEM (LH_BI), 4, ATTR_ALL, 0, NULL, 0, NULL}, 399 {"lw.bi", "=rt,[%ra],(%rb<<%sv)", MEM (LW_BI), 4, ATTR_ALL, 0, NULL, 0, NULL}, 400 {"lw.bi", "=rt,[%ra],%rb{<<%sv}", MEM (LW_BI), 4, ATTR_ALL, 0, NULL, 0, NULL}, 401 {"sb.bi", "=rt,[%ra],(%rb<<%sv)", MEM (SB_BI), 4, ATTR_ALL, 0, NULL, 0, NULL}, 402 {"sb.bi", "%rt,[%ra],%rb{<<%sv}", MEM (SB_BI), 4, ATTR_ALL, 0, NULL, 0, NULL}, 403 {"sh.bi", "=rt,[%ra],(%rb<<%sv)", MEM (SH_BI), 4, ATTR_ALL, 0, NULL, 0, NULL}, 404 {"sh.bi", "%rt,[%ra],%rb{<<%sv}", MEM (SH_BI), 4, ATTR_ALL, 0, NULL, 0, NULL}, 405 {"sw.bi", "=rt,[%ra],(%rb<<%sv)", MEM (SW_BI), 4, ATTR_ALL, 0, NULL, 0, NULL}, 406 {"sw.bi", "%rt,[%ra],%rb{<<%sv}", MEM (SW_BI), 4, ATTR_ALL, 0, NULL, 0, NULL}, 407 {"lbs", "=rt,[%ra+(%rb<<%sv)]", MEM (LBS), 4, ATTR_ALL, 0, NULL, 0, NULL}, 408 {"lbs", "=rt,[%ra+%rb{<<%sv}]", MEM (LBS), 4, ATTR_ALL, 0, NULL, 0, NULL}, 409 {"lhs", "=rt,[%ra+(%rb<<%sv)]", MEM (LHS), 4, ATTR_ALL, 0, NULL, 0, NULL}, 410 {"lhs", "=rt,[%ra+%rb{<<%sv}]", MEM (LHS), 4, ATTR_ALL, 0, NULL, 0, NULL}, 411 {"lbs.bi", "=rt,[%ra],(%rb<<%sv)", MEM (LBS_BI), 4, ATTR_ALL, 0, NULL, 0, NULL}, 412 {"lbs.bi", "=rt,[%ra],%rb{<<%sv}", MEM (LBS_BI), 4, ATTR_ALL, 0, NULL, 0, NULL}, 413 {"lhs.bi", "=rt,[%ra],(%rb<<%sv)", MEM (LHS_BI), 4, ATTR_ALL, 0, NULL, 0, NULL}, 414 {"lhs.bi", "=rt,[%ra],%rb{<<%sv}", MEM (LHS_BI), 4, ATTR_ALL, 0, NULL, 0, NULL}, 415 {"llw", "=rt,[%ra+(%rb<<%sv)]", MEM (LLW), 4, ATTR_V3MEX_V1, 0, NULL, 0, NULL}, 416 {"llw", "=rt,[%ra+%rb{<<%sv}]", MEM (LLW), 4, ATTR_V3MEX_V1, 0, NULL, 0, NULL}, 417 {"scw", "%rt,[%ra+(%rb<<%sv)]", MEM (SCW), 4, ATTR_V3MEX_V1, 0, NULL, 0, NULL}, 418 {"scw", "%rt,[%ra+%rb{<<%sv}]", MEM (SCW), 4, ATTR_V3MEX_V1, 0, NULL, 0, NULL}, 419 {"lbup", "=rt,[%ra+(%rb<<%sv)]", MEM (LBUP), 4, ATTR_V3MEX_V2, 0, NULL, 0, NULL}, 420 {"lbup", "=rt,[%ra+%rb{<<%sv}]", MEM (LBUP), 4, ATTR_V3MEX_V2, 0, NULL, 0, NULL}, 421 {"lwup", "=rt,[%ra+(%rb<<%sv)]", MEM (LWUP), 4, ATTR_V3MEX_V1, 0, NULL, 0, NULL}, 422 {"lwup", "=rt,[%ra+%rb{<<%sv}]", MEM (LWUP), 4, ATTR_V3MEX_V1, 0, NULL, 0, NULL}, 423 {"sbup", "%rt,[%ra+(%rb<<%sv)]", MEM (SBUP), 4, ATTR_V3MEX_V2, 0, NULL, 0, NULL}, 424 {"sbup", "%rt,[%ra+%rb{<<%sv}]", MEM (SBUP), 4, ATTR_V3MEX_V2, 0, NULL, 0, NULL}, 425 {"swup", "%rt,[%ra+(%rb<<%sv)]", MEM (SWUP), 4, ATTR_V3MEX_V1, 0, NULL, 0, NULL}, 426 {"swup", "%rt,[%ra+%rb{<<%sv}]", MEM (SWUP), 4, ATTR_V3MEX_V1, 0, NULL, 0, NULL}, 427 {"dpref", "%dpref_st,[%ra+(%rb<<%sv)]", MEM (DPREF), 4, ATTR_V3MEX_V1, 0, NULL, 0, NULL}, 428 {"dpref", "%dpref_st,[%ra+%rb{<<%sv}]", MEM (DPREF), 4, ATTR_V3MEX_V1, 0, NULL, 0, NULL}, 429 430 /* LBGP */ 431 {"lbi.gp", "=rt,[+%i19s]", OP6 (LBGP), 4, ATTR (GPREL) | ATTR_V2UP, USE_REG (29), NULL, 0, NULL}, 432 {"lbsi.gp", "=rt,[+%i19s]", OP6 (LBGP) | __BIT (19), 4, ATTR (GPREL) | ATTR_V2UP, USE_REG (29), NULL, 0, NULL}, 433 434 /* SBGP */ 435 {"sbi.gp", "%rt,[+%i19s]", OP6 (SBGP), 4, ATTR (GPREL) | ATTR_V2UP, USE_REG (29), NULL, 0, NULL}, 436 {"addi.gp", "=rt,%i19s", OP6 (SBGP) | __BIT (19), 4, ATTR (GPREL) | ATTR_V2UP, USE_REG (29), NULL, 0, NULL}, 437 438 /* HWGP */ 439 {"lhi.gp", "=rt,[+%i18s1]", OP6 (HWGP), 4, ATTR (GPREL) | ATTR_V2UP, USE_REG (29), NULL, 0, NULL}, 440 {"lhsi.gp", "=rt,[+%i18s1]", OP6 (HWGP) | (2 << 17), 4, ATTR (GPREL) | ATTR_V2UP, USE_REG (29), NULL, 0, NULL}, 441 {"shi.gp", "%rt,[+%i18s1]", OP6 (HWGP) | (4 << 17), 4, ATTR (GPREL) | ATTR_V2UP, USE_REG (29), NULL, 0, NULL}, 442 {"lwi.gp", "=rt,[+%i17s2]", OP6 (HWGP) | (6 << 17), 4, ATTR (GPREL) | ATTR_V2UP, USE_REG (29), NULL, 0, NULL}, 443 {"swi.gp", "%rt,[+%i17s2]", OP6 (HWGP) | (7 << 17), 4, ATTR (GPREL) | ATTR_V2UP, USE_REG (29), NULL, 0, NULL}, 444 445 #define LSMW(sub) (OP6 (LSMW) | N32_LSMW_ ## sub) 446 {"lmw", "%abdim %rt,[%ra],%rb{,%enb4}", LSMW (LSMW), 4, ATTR_ALL, 0, NULL, 0, NULL}, 447 {"smw", "%abdim %rt,[%ra],%rb{,%enb4}", LSMW (LSMW) | __BIT (5), 4, ATTR_ALL, 0, NULL, 0, NULL}, 448 {"lmwa", "%abdim %rt,[%ra],%rb{,%enb4}", LSMW (LSMWA), 4, ATTR_V3MEX_V2, 0, NULL, 0, NULL}, 449 {"smwa", "%abdim %rt,[%ra],%rb{,%enb4}", LSMW (LSMWA) | __BIT (5), 4, ATTR_V3MEX_V2, 0, NULL, 0, NULL}, 450 {"lmwzb", "%abm %rt,[%ra],%rb{,%enb4}", LSMW (LSMWZB), 4, ATTR (STR_EXT), 0, NULL, 0, NULL}, 451 {"smwzb", "%abm %rt,[%ra],%rb{,%enb4}", LSMW (LSMWZB) | __BIT (5), 4, ATTR (STR_EXT), 0, NULL, 0, NULL}, 452 453 454 #define SIMD(sub) (OP6 (SIMD) | N32_SIMD_ ## sub) 455 {"pbsad", "%rt,%rb,%ra", SIMD (PBSAD), 4, ATTR (PERF2_EXT), 0, NULL, 0, NULL}, 456 {"pbsada", "%rt,%rb,%ra", SIMD (PBSADA), 4, ATTR (PERF2_EXT), 0, NULL, 0, NULL}, 457 458 /* COP */ 459 #if 0 460 {"cpe1", 0, 0, NULL, 0, NULL}, 461 {"mfcp", 0, 0, NULL, 0, NULL}, 462 {"cplw", 0, 0, NULL, 0, NULL}, 463 {"cplw.bi", 0, 0, NULL, 0, NULL}, 464 {"cpld", 0, 0, NULL, 0, NULL}, 465 {"cpld.bi", 0, 0, NULL, 0, NULL}, 466 {"cpe2", 0, 0, NULL, 0, NULL}, 467 468 {"cpe3", 0, 0, NULL, 0, NULL}, 469 {"mtcp", 0, 0, NULL, 0, NULL}, 470 {"cpsw", 0, 0, NULL, 0, NULL}, 471 {"cpsw.bi", 0, 0, NULL, 0, NULL}, 472 {"cpsd", 0, 0, NULL, 0, NULL}, 473 {"cpsd.bi", 0, 0, NULL, 0, NULL}, 474 {"cpe4", 0, 0, NULL, 0, NULL}, 475 #endif 476 477 /* FPU */ 478 #define FS1(sub) (OP6 (COP) | N32_FPU_FS1 | (N32_FPU_FS1_ ## sub << 6)) 479 {"fadds", "=fst,%fsa,%fsb", FS1 (FADDS), 4, ATTR (FPU) | ATTR (FPU_SP_EXT), 0, NULL, 0, NULL}, 480 {"fsubs", "=fst,%fsa,%fsb", FS1 (FSUBS), 4, ATTR (FPU) | ATTR (FPU_SP_EXT), 0, NULL, 0, NULL}, 481 {"fcpynss", "=fst,%fsa,%fsb", FS1 (FCPYNSS), 4, ATTR (FPU) | ATTR (FPU_SP_EXT), 0, NULL, 0, NULL}, 482 {"fcpyss", "=fst,%fsa,%fsb", FS1 (FCPYSS), 4, ATTR (FPU) | ATTR (FPU_SP_EXT), 0, NULL, 0, NULL}, 483 {"fmadds", "=fst,%fsa,%fsb", FS1 (FMADDS), 4, ATTR (FPU) | ATTR (FPU_SP_EXT), 0, NULL, 0, NULL}, 484 {"fmsubs", "=fst,%fsa,%fsb", FS1 (FMSUBS), 4, ATTR (FPU) | ATTR (FPU_SP_EXT), 0, NULL, 0, NULL}, 485 {"fcmovns", "=fst,%fsa,%fsb", FS1 (FCMOVNS), 4, ATTR (FPU) | ATTR (FPU_SP_EXT), 0, NULL, 0, NULL}, 486 {"fcmovzs", "=fst,%fsa,%fsb", FS1 (FCMOVZS), 4, ATTR (FPU) | ATTR (FPU_SP_EXT), 0, NULL, 0, NULL}, 487 {"fnmadds", "=fst,%fsa,%fsb", FS1 (FNMADDS), 4, ATTR (FPU) | ATTR (FPU_SP_EXT), 0, NULL, 0, NULL}, 488 {"fnmsubs", "=fst,%fsa,%fsb", FS1 (FNMSUBS), 4, ATTR (FPU) | ATTR (FPU_SP_EXT), 0, NULL, 0, NULL}, 489 {"fmuls", "=fst,%fsa,%fsb", FS1 (FMULS), 4, ATTR (FPU) | ATTR (FPU_SP_EXT), 0, NULL, 0, NULL}, 490 {"fdivs", "=fst,%fsa,%fsb", FS1 (FDIVS), 4, ATTR (FPU) | ATTR (FPU_SP_EXT), 0, NULL, 0, NULL}, 491 492 #define FS1_F2OP(sub) (OP6 (COP) | N32_FPU_FS1 | (N32_FPU_FS1_F2OP << 6) \ 493 | (N32_FPU_FS1_F2OP_ ## sub << 10)) 494 {"fs2d", "=fdt,%fsa", FS1_F2OP (FS2D), 4, ATTR (FPU) | ATTR (FPU_SP_EXT) | ATTR (FPU_DP_EXT), 0, NULL, 0, NULL}, 495 {"fsqrts", "=fst,%fsa", FS1_F2OP (FSQRTS), 4, ATTR (FPU) | ATTR (FPU_SP_EXT), 0, NULL, 0, NULL}, 496 {"fabss", "=fst,%fsa", FS1_F2OP (FABSS), 4, ATTR (FPU) | ATTR (FPU_SP_EXT), 0, NULL, 0, NULL}, 497 {"fui2s", "=fst,%fsa", FS1_F2OP (FUI2S), 4, ATTR (FPU) | ATTR (FPU_SP_EXT), 0, NULL, 0, NULL}, 498 {"fsi2s", "=fst,%fsa", FS1_F2OP (FSI2S), 4, ATTR (FPU) | ATTR (FPU_SP_EXT), 0, NULL, 0, NULL}, 499 {"fs2ui", "=fst,%fsa", FS1_F2OP (FS2UI), 4, ATTR (FPU) | ATTR (FPU_SP_EXT), 0, NULL, 0, NULL}, 500 {"fs2ui.z", "=fst,%fsa", FS1_F2OP (FS2UI_Z), 4, ATTR (FPU) | ATTR (FPU_SP_EXT), 0, NULL, 0, NULL}, 501 {"fs2si", "=fst,%fsa", FS1_F2OP (FS2SI), 4, ATTR (FPU) | ATTR (FPU_SP_EXT), 0, NULL, 0, NULL}, 502 {"fs2si.z", "=fst,%fsa", FS1_F2OP (FS2SI_Z), 4, ATTR (FPU) | ATTR (FPU_SP_EXT), 0, NULL, 0, NULL}, 503 504 #define FS2(sub) (OP6 (COP) | N32_FPU_FS2 | (N32_FPU_FS2_ ## sub << 6)) 505 {"fcmpeqs", "=fst,%fsa,%fsb", FS2 (FCMPEQS), 4, ATTR (FPU) | ATTR (FPU_SP_EXT), 0, NULL, 0, NULL}, 506 {"fcmplts", "=fst,%fsa,%fsb", FS2 (FCMPLTS), 4, ATTR (FPU) | ATTR (FPU_SP_EXT), 0, NULL, 0, NULL}, 507 {"fcmples", "=fst,%fsa,%fsb", FS2 (FCMPLES), 4, ATTR (FPU) | ATTR (FPU_SP_EXT), 0, NULL, 0, NULL}, 508 {"fcmpuns", "=fst,%fsa,%fsb", FS2 (FCMPUNS), 4, ATTR (FPU) | ATTR (FPU_SP_EXT), 0, NULL, 0, NULL}, 509 {"fcmpeqs.e", "=fst,%fsa,%fsb", FS2 (FCMPEQS_E), 4, ATTR (FPU) | ATTR (FPU_SP_EXT), 0, NULL, 0, NULL}, 510 {"fcmplts.e", "=fst,%fsa,%fsb", FS2 (FCMPLTS_E), 4, ATTR (FPU) | ATTR (FPU_SP_EXT), 0, NULL, 0, NULL}, 511 {"fcmples.e", "=fst,%fsa,%fsb", FS2 (FCMPLES_E), 4, ATTR (FPU) | ATTR (FPU_SP_EXT), 0, NULL, 0, NULL}, 512 {"fcmpuns.e", "=fst,%fsa,%fsb", FS2 (FCMPUNS_E), 4, ATTR (FPU) | ATTR (FPU_SP_EXT), 0, NULL, 0, NULL}, 513 514 #define FD1(sub) (OP6 (COP) | N32_FPU_FD1 | (N32_FPU_FD1_ ## sub << 6)) 515 {"faddd", "=fdt,%fda,%fdb", FD1 (FADDD), 4, ATTR (FPU) | ATTR (FPU_DP_EXT), 0, NULL, 0, NULL}, 516 {"fsubd", "=fdt,%fda,%fdb", FD1 (FSUBD), 4, ATTR (FPU) | ATTR (FPU_DP_EXT), 0, NULL, 0, NULL}, 517 {"fcpynsd", "=fdt,%fda,%fdb", FD1 (FCPYNSD), 4, ATTR (FPU) | ATTR (FPU_DP_EXT), 0, NULL, 0, NULL}, 518 {"fcpysd", "=fdt,%fda,%fdb", FD1 (FCPYSD), 4, ATTR (FPU), 0, NULL, 0, NULL}, 519 {"fmaddd", "=fdt,%fda,%fdb", FD1 (FMADDD), 4, ATTR (FPU) | ATTR (FPU_DP_EXT), 0, NULL, 0, NULL}, 520 {"fmsubd", "=fdt,%fda,%fdb", FD1 (FMSUBD), 4, ATTR (FPU) | ATTR (FPU_DP_EXT), 0, NULL, 0, NULL}, 521 {"fcmovnd", "=fdt,%fda,%fsb", FD1 (FCMOVND), 4, ATTR (FPU) | ATTR (FPU_DP_EXT), 0, NULL, 0, NULL}, 522 {"fcmovzd", "=fdt,%fda,%fsb", FD1 (FCMOVZD), 4, ATTR (FPU) | ATTR (FPU_DP_EXT), 0, NULL, 0, NULL}, 523 {"fnmaddd", "=fdt,%fda,%fdb", FD1 (FNMADDD), 4, ATTR (FPU) | ATTR (FPU_DP_EXT), 0, NULL, 0, NULL}, 524 {"fnmsubd", "=fdt,%fda,%fdb", FD1 (FNMSUBD), 4, ATTR (FPU) | ATTR (FPU_DP_EXT), 0, NULL, 0, NULL}, 525 {"fmuld", "=fdt,%fda,%fdb", FD1 (FMULD), 4, ATTR (FPU) | ATTR (FPU_DP_EXT), 0, NULL, 0, NULL}, 526 {"fdivd", "=fdt,%fda,%fdb", FD1 (FDIVD), 4, ATTR (FPU) | ATTR (FPU_DP_EXT), 0, NULL, 0, NULL}, 527 528 #define FD1_F2OP(sub) (OP6 (COP) | N32_FPU_FD1 | (N32_FPU_FD1_F2OP << 6) \ 529 | (N32_FPU_FD1_F2OP_ ## sub << 10)) 530 {"fd2s", "=fst,%fda", FD1_F2OP (FD2S), 4, ATTR (FPU) | ATTR (FPU_SP_EXT) | ATTR (FPU_DP_EXT), 0, NULL, 0, NULL}, 531 {"fsqrtd", "=fdt,%fda", FD1_F2OP (FSQRTD), 4, ATTR (FPU) | ATTR (FPU_DP_EXT), 0, NULL, 0, NULL}, 532 {"fabsd", "=fdt,%fda", FD1_F2OP (FABSD), 4, ATTR (FPU) | ATTR (FPU_DP_EXT), 0, NULL, 0, NULL}, 533 {"fui2d", "=fdt,%fsa", FD1_F2OP (FUI2D), 4, ATTR (FPU) | ATTR (FPU_DP_EXT), 0, NULL, 0, NULL}, 534 {"fsi2d", "=fdt,%fsa", FD1_F2OP (FSI2D), 4, ATTR (FPU) | ATTR (FPU_DP_EXT), 0, NULL, 0, NULL}, 535 {"fd2ui", "=fst,%fda", FD1_F2OP (FD2UI), 4, ATTR (FPU) | ATTR (FPU_DP_EXT), 0, NULL, 0, NULL}, 536 {"fd2ui.z", "=fst,%fda", FD1_F2OP (FD2UI_Z), 4, ATTR (FPU) | ATTR (FPU_DP_EXT), 0, NULL, 0, NULL}, 537 {"fd2si", "=fst,%fda", FD1_F2OP (FD2SI), 4, ATTR (FPU) | ATTR (FPU_DP_EXT), 0, NULL, 0, NULL}, 538 {"fd2si.z", "=fst,%fda", FD1_F2OP (FD2SI_Z), 4, ATTR (FPU) | ATTR (FPU_DP_EXT), 0, NULL, 0, NULL}, 539 540 #define FD2(sub) (OP6 (COP) | N32_FPU_FD2 | (N32_FPU_FD2_ ## sub << 6)) 541 {"fcmpeqd", "=fst,%fda,%fdb", FD2 (FCMPEQD), 4, ATTR (FPU) | ATTR (FPU_DP_EXT), 0, NULL, 0, NULL}, 542 {"fcmpltd", "=fst,%fda,%fdb", FD2 (FCMPLTD), 4, ATTR (FPU) | ATTR (FPU_DP_EXT), 0, NULL, 0, NULL}, 543 {"fcmpled", "=fst,%fda,%fdb", FD2 (FCMPLED), 4, ATTR (FPU) | ATTR (FPU_DP_EXT), 0, NULL, 0, NULL}, 544 {"fcmpund", "=fst,%fda,%fdb", FD2 (FCMPUND), 4, ATTR (FPU) | ATTR (FPU_DP_EXT), 0, NULL, 0, NULL}, 545 {"fcmpeqd.e", "=fst,%fda,%fdb", FD2 (FCMPEQD_E), 4, ATTR (FPU) | ATTR (FPU_DP_EXT), 0, NULL, 0, NULL}, 546 {"fcmpltd.e", "=fst,%fda,%fdb", FD2 (FCMPLTD_E), 4, ATTR (FPU) | ATTR (FPU_DP_EXT), 0, NULL, 0, NULL}, 547 {"fcmpled.e", "=fst,%fda,%fdb", FD2 (FCMPLED_E), 4, ATTR (FPU) | ATTR (FPU_DP_EXT), 0, NULL, 0, NULL}, 548 {"fcmpund.e", "=fst,%fda,%fdb", FD2 (FCMPUND_E), 4, ATTR (FPU) | ATTR (FPU_DP_EXT), 0, NULL, 0, NULL}, 549 550 #define MFCP(sub) (OP6 (COP) | N32_FPU_MFCP | (N32_FPU_MFCP_ ## sub << 6)) 551 {"fmfsr", "=rt,%fsa", MFCP (FMFSR), 4, ATTR (FPU), 0, NULL, 0, NULL}, 552 {"fmfdr", "=rt,%fda", MFCP (FMFDR), 4, ATTR (FPU), 0, NULL, 0, NULL}, 553 554 #define MFCP_XR(sub) (OP6 (COP) | N32_FPU_MFCP | (N32_FPU_MFCP_XR << 6) \ 555 | (N32_FPU_MFCP_XR_ ## sub << 10)) 556 {"fmfcfg", "=rt" , MFCP_XR(FMFCFG), 4, ATTR (FPU), 0, NULL, 0, NULL}, 557 {"fmfcsr", "=rt" , MFCP_XR(FMFCSR), 4, ATTR (FPU), 0, NULL, 0, NULL}, 558 559 #define MTCP(sub) (OP6 (COP) | N32_FPU_MTCP | (N32_FPU_MTCP_ ## sub << 6)) 560 {"fmtsr", "%rt,=fsa", MTCP (FMTSR), 4, ATTR (FPU), 0, NULL, 0, NULL}, 561 {"fmtdr", "%rt,=fda", MTCP (FMTDR), 4, ATTR (FPU), 0, NULL, 0, NULL}, 562 563 #define MTCP_XR(sub) (OP6 (COP) | N32_FPU_MTCP | (N32_FPU_MTCP_XR << 6) \ 564 | (N32_FPU_MTCP_XR_ ## sub << 10)) 565 {"fmtcsr", "%rt" , MTCP_XR(FMTCSR), 4, ATTR (FPU), 0, NULL, 0, NULL}, 566 567 #define FPU_MEM(sub) (OP6 (COP) | N32_FPU_ ## sub) 568 #define FPU_MEMBI(sub) (OP6 (COP) | N32_FPU_ ## sub | 0x2 << 6) 569 #define FPU_RA_IMMBI(sub) (OP6 (sub) | __BIT (12)) 570 {"fls", "=fst,[%ra+(%rb<<%sv)]", FPU_MEM (FLS), 4, ATTR (FPU), 0, NULL, 0, NULL}, 571 {"fls", "=fst,[%ra+%rb{<<%sv}]", FPU_MEM (FLS), 4, ATTR (FPU), 0, NULL, 0, NULL}, 572 {"fls.bi", "=fst,[%ra],(%rb<<%sv)", FPU_MEMBI (FLS), 4, ATTR (FPU), 0, NULL, 0, NULL}, 573 {"fls.bi", "=fst,[%ra],%rb{<<%sv}", FPU_MEMBI (FLS), 4, ATTR (FPU), 0, NULL, 0, NULL}, 574 {"fss", "=fst,[%ra+(%rb<<%sv)]", FPU_MEM (FSS), 4, ATTR (FPU), 0, NULL, 0, NULL}, 575 {"fss", "=fst,[%ra+%rb{<<%sv}]", FPU_MEM (FSS), 4, ATTR (FPU), 0, NULL, 0, NULL}, 576 {"fss.bi", "=fst,[%ra],(%rb<<%sv)", FPU_MEMBI (FSS), 4, ATTR (FPU), 0, NULL, 0, NULL}, 577 {"fss.bi", "=fst,[%ra],%rb{<<%sv}", FPU_MEMBI (FSS), 4, ATTR (FPU), 0, NULL, 0, NULL}, 578 {"fld", "=fdt,[%ra+(%rb<<%sv)]", FPU_MEM (FLD), 4, ATTR (FPU), 0, NULL, 0, NULL}, 579 {"fld", "=fdt,[%ra+%rb{<<%sv}]", FPU_MEM (FLD), 4, ATTR (FPU), 0, NULL, 0, NULL}, 580 {"fld.bi", "=fdt,[%ra],(%rb<<%sv)", FPU_MEMBI (FLD), 4, ATTR (FPU), 0, NULL, 0, NULL}, 581 {"fld.bi", "=fdt,[%ra],%rb{<<%sv}", FPU_MEMBI (FLD), 4, ATTR (FPU), 0, NULL, 0, NULL}, 582 {"fsd", "=fdt,[%ra+(%rb<<%sv)]", FPU_MEM (FSD), 4, ATTR (FPU), 0, NULL, 0, NULL}, 583 {"fsd", "=fdt,[%ra+%rb{<<%sv}]", FPU_MEM (FSD), 4, ATTR (FPU), 0, NULL, 0, NULL}, 584 {"fsd.bi", "=fdt,[%ra],(%rb<<%sv)", FPU_MEMBI (FSD), 4, ATTR (FPU), 0, NULL, 0, NULL}, 585 {"fsd.bi", "=fdt,[%ra],%rb{<<%sv}", FPU_MEMBI (FSD), 4, ATTR (FPU), 0, NULL, 0, NULL}, 586 {"flsi", "=fst,[%ra{+%i12s2}]", OP6 (LWC), 4, ATTR (FPU), 0, NULL, 0, NULL}, 587 {"flsi.bi", "=fst,[%ra],%i12s2", FPU_RA_IMMBI (LWC),4, ATTR (FPU), 0, NULL, 0, NULL}, 588 {"fssi", "=fst,[%ra{+%i12s2}]", OP6 (SWC), 4, ATTR (FPU), 0, NULL, 0, NULL}, 589 {"fssi.bi", "=fst,[%ra],%i12s2", FPU_RA_IMMBI (SWC),4, ATTR (FPU), 0, NULL, 0, NULL}, 590 {"fldi", "=fdt,[%ra{+%i12s2}]", OP6 (LDC), 4, ATTR (FPU), 0, NULL, 0, NULL}, 591 {"fldi.bi", "=fdt,[%ra],%i12s2", FPU_RA_IMMBI (LDC),4, ATTR (FPU), 0, NULL, 0, NULL}, 592 {"fsdi", "=fdt,[%ra{+%i12s2}]", OP6 (SDC), 4, ATTR (FPU), 0, NULL, 0, NULL}, 593 {"fsdi.bi", "=fdt,[%ra],%i12s2", FPU_RA_IMMBI (SDC),4, ATTR (FPU), 0, NULL, 0, NULL}, 594 595 /* AEXT */ 596 597 {"lbi", "=rt,[%ra{+%i15s}]", OP6 (LBI), 4, ATTR_ALL, 0, NULL, 0, NULL}, 598 {"lhi", "=rt,[%ra{+%i15s1}]", OP6 (LHI), 4, ATTR_ALL, 0, NULL, 0, NULL}, 599 {"lwi", "=rt,[%ra{+%i15s2}]", OP6 (LWI), 4, ATTR_ALL, 0, NULL, 0, NULL}, 600 {"lbi.bi", "=rt,[%ra],%i15s", OP6 (LBI_BI), 4, ATTR_ALL, 0, NULL, 0, NULL}, 601 {"lhi.bi", "=rt,[%ra],%i15s1", OP6 (LHI_BI), 4, ATTR_ALL, 0, NULL, 0, NULL}, 602 {"lwi.bi", "=rt,[%ra],%i15s2", OP6 (LWI_BI), 4, ATTR_ALL, 0, NULL, 0, NULL}, 603 {"sbi", "%rt,[%ra{+%i15s}]", OP6 (SBI), 4, ATTR_ALL, 0, NULL, 0, NULL}, 604 {"shi", "%rt,[%ra{+%i15s1}]", OP6 (SHI), 4, ATTR_ALL, 0, NULL, 0, NULL}, 605 {"swi", "%rt,[%ra{+%i15s2}]", OP6 (SWI), 4, ATTR_ALL, 0, NULL, 0, NULL}, 606 {"sbi.bi", "%rt,[%ra],%i15s", OP6 (SBI_BI), 4, ATTR_ALL, 0, NULL, 0, NULL}, 607 {"shi.bi", "%rt,[%ra],%i15s1", OP6 (SHI_BI), 4, ATTR_ALL, 0, NULL, 0, NULL}, 608 {"swi.bi", "%rt,[%ra],%i15s2", OP6 (SWI_BI), 4, ATTR_ALL, 0, NULL, 0, NULL}, 609 {"lbsi", "=rt,[%ra{+%i15s}]", OP6 (LBSI), 4, ATTR_ALL, 0, NULL, 0, NULL}, 610 {"lhsi", "=rt,[%ra{+%i15s1}]", OP6 (LHSI), 4, ATTR_ALL, 0, NULL, 0, NULL}, 611 {"lwsi", "=rt,[%ra{+%i15s2}]", OP6 (LWSI), 4, ATTR_ALL, 0, NULL, 0, NULL}, 612 {"lbsi.bi", "=rt,[%ra],%i15s", OP6 (LBSI_BI), 4, ATTR_ALL, 0, NULL, 0, NULL}, 613 {"lhsi.bi", "=rt,[%ra],%i15s1", OP6 (LHSI_BI), 4, ATTR_ALL, 0, NULL, 0, NULL}, 614 {"lwsi.bi", "=rt,[%ra],%i15s2", OP6 (LWSI_BI), 4, ATTR_ALL, 0, NULL, 0, NULL}, 615 {"cplwi", "%cp,=cprt,[%ra{+%i12s2}]", OP6 (LWC), 4, 0, 0, NULL, 0, NULL}, 616 {"cpswi", "%cp,=cprt,[%ra{+%i12s2}]", OP6 (SWC), 4, 0, 0, NULL, 0, NULL}, 617 {"cpldi", "%cp,%cprt,[%ra{+%i12s2}]", OP6 (LDC), 4, 0, 0, NULL, 0, NULL}, 618 {"cpsdi", "%cp,%cprt,[%ra{+%i12s2}]", OP6 (SDC), 4, 0, 0, NULL, 0, NULL}, 619 {"cplwi.bi", "%cp,=cprt,[%ra],%i12s2", OP6 (LWC) | __BIT (12), 4, 0, 0, NULL, 0, NULL}, 620 {"cpswi.bi", "%cp,=cprt,[%ra],%i12s2", OP6 (SWC) | __BIT (12), 4, 0, 0, NULL, 0, NULL}, 621 {"cpldi.bi", "%cp,%cprt,[%ra],%i12s2", OP6 (LDC) | __BIT (12), 4, 0, 0, NULL, 0, NULL}, 622 {"cpsdi.bi", "%cp,%cprt,[%ra],%i12s2", OP6 (SDC) | __BIT (12), 4, 0, 0, NULL, 0, NULL}, 623 {"movi", "=rt,%i20s", OP6 (MOVI), 4, ATTR_ALL, 0, NULL, 0, NULL}, 624 {"sethi", "=rt,%i20u", OP6 (SETHI), 4, ATTR_ALL, 0, NULL, 0, NULL}, 625 {"addi", "=rt,%ra,%i15s", OP6 (ADDI), 4, ATTR_ALL, 0, NULL, 0, NULL}, 626 {"subri", "=rt,%ra,%i15s", OP6 (SUBRI), 4, ATTR_ALL, 0, NULL, 0, NULL}, 627 {"andi", "=rt,%ra,%i15u", OP6 (ANDI), 4, ATTR_ALL, 0, NULL, 0, NULL}, 628 {"xori", "=rt,%ra,%i15u", OP6 (XORI), 4, ATTR_ALL, 0, NULL, 0, NULL}, 629 {"ori", "=rt,%ra,%i15u", OP6 (ORI), 4, ATTR_ALL, 0, NULL, 0, NULL}, 630 {"slti", "=rt,%ra,%i15s", OP6 (SLTI), 4, ATTR_ALL, 0, NULL, 0, NULL}, 631 {"sltsi", "=rt,%ra,%i15s", OP6 (SLTSI), 4, ATTR_ALL, 0, NULL, 0, NULL}, 632 {"bitci", "=rt,%ra,%i15u", OP6 (BITCI), 4, ATTR_V3, 0, NULL, 0, NULL}, 633 {"dprefi.w", "%dpref_st,[%ra{+%i15s2]}", OP6 (DPREFI), 4, ATTR_V3MEX_V1, 0, NULL, 0, NULL}, 634 {"dprefi.d", "%dpref_st,[%ra{+%i15s3]}", OP6 (DPREFI) | __BIT (24), 4, ATTR_V3MEX_V1, 0, NULL, 0, NULL}, 635 636 /* 16-bit instructions. */ 637 {"mov55", "=rt5,%ra5", 0x8000, 2, ATTR_ALL, 0, NULL, 0, NULL}, /* mov55, $sp, $sp == ifret */ 638 {"ifret16", "", 0x83ff, 2, ATTR (IFC_EXT), 0, NULL, 0, NULL}, 639 {"movi55", "=rt5,%i5s", 0x8400, 2, ATTR_ALL, 0, NULL, 0, NULL}, 640 {"add45", "=rt4,%ra5", 0x8800, 2, ATTR_ALL, 0, NULL, 0, NULL}, 641 {"sub45", "=rt4,%ra5", 0x8a00, 2, ATTR_ALL, 0, NULL, 0, NULL}, 642 {"addi45", "=rt4,%i5u", 0x8c00, 2, ATTR_ALL, 0, NULL, 0, NULL}, 643 {"subi45", "=rt4,%i5u", 0x8e00, 2, ATTR_ALL, 0, NULL, 0, NULL}, 644 {"srai45", "=rt4,%i5u", 0x9000, 2, ATTR_ALL, 0, NULL, 0, NULL}, 645 {"srli45", "=rt4,%i5u", 0x9200, 2, ATTR_ALL, 0, NULL, 0, NULL}, 646 {"slli333", "=rt3,%ra3,%i3u", 0x9400, 2, ATTR_ALL, 0, NULL, 0, NULL}, 647 {"zeb33", "=rt3,%ra3", 0x9600, 2, ATTR_ALL, 0, NULL, 0, NULL}, 648 {"zeh33", "=rt3,%ra3", 0x9601, 2, ATTR_ALL, 0, NULL, 0, NULL}, 649 {"seb33", "=rt3,%ra3", 0x9602, 2, ATTR_ALL, 0, NULL, 0, NULL}, 650 {"seh33", "=rt3,%ra3", 0x9603, 2, ATTR_ALL, 0, NULL, 0, NULL}, 651 {"xlsb33", "=rt3,%ra3", 0x9604, 2, ATTR_ALL, 0, NULL, 0, NULL}, 652 {"x11b33", "=rt3,%ra3", 0x9605, 2, ATTR_ALL, 0, NULL, 0, NULL}, 653 {"bmski33", "=rt3,%ia3u", 0x9606, 2, ATTR_V3MUP, 0, NULL, 0, NULL}, 654 {"fexti33", "=rt3,%ia3u", 0x9607, 2, ATTR_V3MUP, 0, NULL, 0, NULL}, 655 {"add333", "=rt3,%ra3,%rb3", 0x9800, 2, ATTR_ALL, 0, NULL, 0, NULL}, 656 {"sub333", "=rt3,%ra3,%rb3", 0x9a00, 2, ATTR_ALL, 0, NULL, 0, NULL}, 657 {"addi333", "=rt3,%ra3,%i3u", 0x9c00, 2, ATTR_ALL, 0, NULL, 0, NULL}, 658 {"subi333", "=rt3,%ra3,%i3u", 0x9e00, 2, ATTR_ALL, 0, NULL, 0, NULL}, 659 {"lwi333", "=rt3,[%ra3{+%i3u2}]", 0xa000, 2, ATTR_ALL, 0, NULL, 0, NULL}, 660 {"lwi333.bi", "=rt3,[%ra3],%i3u2", 0xa200, 2, ATTR_ALL, 0, NULL, 0, NULL}, 661 {"lhi333", "=rt3,[%ra3{+%i3u1}]", 0xa400, 2, ATTR_ALL, 0, NULL, 0, NULL}, 662 {"lbi333", "=rt3,[%ra3{+%i3u}]", 0xa600, 2, ATTR_ALL, 0, NULL, 0, NULL}, 663 {"swi333", "%rt3,[%ra3{+%i3u2}]", 0xa800, 2, ATTR_ALL, 0, NULL, 0, NULL}, 664 {"swi333.bi", "%rt3,[%ra3],%i3u2", 0xaa00, 2, ATTR_ALL, 0, NULL, 0, NULL}, 665 {"shi333", "%rt3,[%ra3{+%i3u1}]", 0xac00, 2, ATTR_ALL, 0, NULL, 0, NULL}, 666 {"sbi333", "%rt3,[%ra3{+%i3u}]", 0xae00, 2, ATTR_ALL, 0, NULL, 0, NULL}, 667 {"addri36.sp", "%rt3,%i6u2", 0xb000, 2, ATTR_V3MUP, USE_REG (31), NULL, 0, NULL}, 668 {"lwi45.fe", "=rt4,%fe5", 0xb200, 2, ATTR_V3MUP, USE_REG (8), NULL, 0, NULL}, 669 {"lwi450", "=rt4,[%ra5]", 0xb400, 2, ATTR_ALL, 0, NULL, 0, NULL}, 670 {"swi450", "%rt4,[%ra5]", 0xb600, 2, ATTR_ALL, 0, NULL, 0, NULL}, 671 {"lwi37", "=rt38,[$fp{+%i7u2}]", 0xb800, 2, ATTR_ALL, USE_REG (28), NULL, 0, NULL}, 672 {"swi37", "%rt38,[$fp{+%i7u2}]", 0xb880, 2, ATTR_ALL, USE_REG (28), NULL, 0, NULL}, 673 {"beqz38", "%rt38,%i8s1", 0xc000, 2, ATTR_PCREL | ATTR_ALL, 0, NULL, 0, NULL}, 674 {"bnez38", "%rt38,%i8s1", 0xc800, 2, ATTR_PCREL | ATTR_ALL, 0, NULL, 0, NULL}, 675 {"beqs38", "%rt38,%i8s1", 0xd000, 2, ATTR_PCREL | ATTR_ALL, USE_REG (5), NULL, 0, NULL}, 676 {"j8", "%i8s1", 0xd500, 2, ATTR_PCREL | ATTR_ALL, 0, NULL, 0, NULL}, 677 {"bnes38", "%rt38,%i8s1", 0xd800, 2, ATTR_PCREL | ATTR_ALL, USE_REG (5), NULL, 0, NULL}, 678 {"jr5", "%ra5", 0xdd00, 2, ATTR_ALL, 0, NULL, 0, NULL}, 679 {"ex9.it", "%i5u", 0xdd40, 2, ATTR (EX9_EXT), 0, NULL, 0, NULL}, 680 {"ret5", "%ra5", 0xdd80, 2, ATTR_ALL, 0, NULL, 0, NULL}, 681 {"ret5", "", 0xdd80 | RA5 (30), 2, ATTR_ALL, 0, NULL, 0, NULL}, 682 {"jral5", "%ra5", 0xdd20, 2, ATTR_ALL, 0, NULL, 0, NULL}, 683 {"add5.pc", "%ra5", 0xdda0, 2, ATTR_V3, 0, NULL, 0, NULL}, 684 {"slts45", "%rt4,%ra5", 0xe000, 2, ATTR_ALL, DEF_REG (15), NULL, 0, NULL}, 685 {"slt45", "%rt4,%ra5", 0xe200, 2, ATTR_ALL, DEF_REG (15), NULL, 0, NULL}, 686 {"sltsi45", "%rt4,%i5u", 0xe400, 2, ATTR_ALL, DEF_REG (15), NULL, 0, NULL}, 687 {"slti45", "%rt4,%i5u", 0xe600, 2, ATTR_ALL, DEF_REG (15), NULL, 0, NULL}, 688 {"beqzs8", "%i8s1", 0xe800, 2, ATTR_PCREL | ATTR_ALL, USE_REG (5), NULL, 0, NULL}, 689 {"bnezs8", "%i8s1", 0xe900, 2, ATTR_PCREL | ATTR_ALL, USE_REG (5), NULL, 0, NULL}, 690 {"ex9.it", "%i9u", 0xea00, 2, ATTR (EX9_EXT), 0, NULL, 0, NULL}, 691 {"break16", "%i9u", 0xea00, 2, ATTR_ALL, 0, NULL, 0, NULL}, 692 {"addi10.sp", "%i10s", 0xec00, 2, ATTR_V2UP, USE_REG (31) | DEF_REG (31), NULL, 0, NULL}, 693 {"lwi37.sp", "=rt38,[+%i7u2]", 0xf000, 2, ATTR_V2UP, USE_REG (31), NULL, 0, NULL}, 694 {"swi37.sp", "%rt38,[+%i7u2]", 0xf080, 2, ATTR_V2UP, USE_REG (31), NULL, 0, NULL}, 695 {"ifcall9", "%i9u1", 0xf800, 2, ATTR (IFC_EXT), 0, NULL, 0, NULL}, 696 {"movpi45", "=rt4,%pi5", 0xfa00, 2, ATTR_V3MUP, 0, NULL, 0, NULL}, 697 {"push25", "%re2,%i5u3", 0xfc00, 2, ATTR_V3MUP, USE_REG (31) | DEF_REG (31), NULL, 0, NULL}, 698 {"pop25", "%re2,%i5u3", 0xfc80, 2, ATTR_V3MUP, USE_REG (31) | DEF_REG (31), NULL, 0, NULL}, 699 {"movd44", "=rt5e,%ra5e", 0xfd00, 2, ATTR_V3MUP, 0, NULL, 0, NULL}, 700 {"neg33", "=rt3,%ra3", 0xfe02, 2, ATTR_V3MUP, 0, NULL, 0, NULL}, 701 {"not33", "=rt3,%ra3", 0xfe03, 2, ATTR_V3MUP, 0, NULL, 0, NULL}, 702 {"mul33", "=rt3,%ra3", 0xfe04, 2, ATTR_V3MUP, 0, NULL, 0, NULL}, 703 {"xor33", "=rt3,%ra3", 0xfe05, 2, ATTR_V3MUP, 0, NULL, 0, NULL}, 704 {"and33", "=rt3,%ra3", 0xfe06, 2, ATTR_V3MUP, 0, NULL, 0, NULL}, 705 {"or33", "=rt3,%ra3", 0xfe07, 2, ATTR_V3MUP, 0, NULL, 0, NULL}, 706 707 /* Alias instructions. */ 708 {"neg", "=rt,%ra", OP6 (SUBRI), 4, ATTR_ALL, 0, NULL, 0, NULL}, 709 {"zeb", "=rt,%ra", OP6 (ANDI) | 0xff, 4, ATTR_ALL, 0, NULL, 0, NULL}, 710 {"nop", "", ALU1 (SRLI), 4, ATTR_ALL, 0, NULL, 0, NULL}, 711 {"nop16", "", 0x9200, 2, ATTR_ALL, 0, NULL, 0, NULL}, 712 713 /* TODO: For some instruction, an operand may refer to a pair of 714 register, e.g., mulsr64 or movd44. 715 716 Some instruction need special constrain, e.g., movpi45, 717 break16, ex9.it. */ 718 }; 719 720 static const keyword_t keyword_gpr[] = 721 { 722 {"r0", 0, ATTR (RDREG)}, {"r1", 1, ATTR (RDREG)}, {"r2", 2, ATTR (RDREG)}, 723 {"r3", 3, ATTR (RDREG)}, {"r4", 4, ATTR (RDREG)}, {"r5", 5, ATTR (RDREG)}, 724 {"r6", 6, ATTR (RDREG)}, {"r7", 7, ATTR (RDREG)}, {"r8", 8, ATTR (RDREG)}, 725 {"r9", 9, ATTR (RDREG)}, {"r10", 10, ATTR (RDREG)}, 726 {"r11", 11, 0}, {"r12", 12, 0}, {"r13", 13, 0}, {"r14", 14, 0}, 727 {"r15", 15, ATTR (RDREG)}, 728 {"r16", 16, 0}, {"r17", 17, 0}, {"r18", 18, 0}, {"r19", 19, 0}, {"r20", 20, 0}, 729 {"r21", 21, 0}, {"r22", 22, 0}, {"r23", 23, 0}, {"r24", 24, 0}, {"r25", 25, 0}, 730 {"r26", 26, 0}, {"r27", 27, 0}, 731 {"r28", 28, ATTR (RDREG)}, {"r29", 29, ATTR (RDREG)}, 732 {"r30", 30, ATTR (RDREG)}, {"r31", 31, ATTR (RDREG)}, 733 734 {"ta", 15, ATTR (RDREG)}, {"p0", 26, 0}, {"p1", 27, 0}, 735 {"fp", 28, ATTR (RDREG)}, {"gp", 29, ATTR (RDREG)}, 736 {"lp", 30, ATTR (RDREG)}, {"sp", 31, ATTR (RDREG)}, 737 738 {NULL, 0, 0} 739 }; 740 741 static const keyword_t keyword_usr[] = 742 { 743 {"d0.lo", USRIDX (0, 0), 0}, 744 {"d0.hi", USRIDX (0, 1), 0}, 745 {"d1.lo", USRIDX (0, 2), 0}, 746 {"d1.hi", USRIDX (0, 3), 0}, 747 {"itb", USRIDX (0, 28), 0}, 748 {"ifc_lp", USRIDX (0, 29), 0}, 749 {"pc", USRIDX (0, 31), 0}, 750 751 {"dma_cfg", USRIDX (1, 0), 0}, 752 {"dma_gcsw", USRIDX (1, 1), 0}, 753 {"dma_chnsel", USRIDX (1, 2), 0}, 754 {"dma_act", USRIDX (1, 3), 0}, 755 {"dma_setup", USRIDX (1, 4), 0}, 756 {"dma_isaddr", USRIDX (1, 5), 0}, 757 {"dma_esaddr", USRIDX (1, 6), 0}, 758 {"dma_tcnt", USRIDX (1, 7), 0}, 759 {"dma_status", USRIDX (1, 8), 0}, 760 {"dma_2dset", USRIDX (1, 9), 0}, 761 {"dma_rcnt", USRIDX (1, 23), 0}, 762 {"dma_hstatus", USRIDX (1, 24), 0}, 763 {"dma_2dsctl", USRIDX (1, 25), 0}, 764 765 {"pfmc0", USRIDX (2, 0), 0}, 766 {"pfmc1", USRIDX (2, 1), 0}, 767 {"pfmc2", USRIDX (2, 2), 0}, 768 {"pfm_ctl", USRIDX (2, 4), 0}, 769 770 {NULL, 0, 0} 771 }; 772 773 static const keyword_t keyword_dxr[] = 774 { 775 {"d0", 0, 0}, {"d1", 1, 0}, {NULL, 0, 0} 776 }; 777 778 static const keyword_t keyword_sr[] = 779 { 780 {"cr0", SRIDX (0, 0, 0), 0}, {"cpu_ver", SRIDX (0, 0, 0), 0}, 781 {"cr1", SRIDX (0, 1, 0), 0}, {"icm_cfg", SRIDX (0, 1, 0), 0}, 782 {"cr2", SRIDX (0, 2, 0), 0}, {"dcm_cfg", SRIDX (0, 2, 0), 0}, 783 {"cr3", SRIDX (0, 3, 0), 0}, {"mmu_cfg", SRIDX (0, 3, 0), 0}, 784 {"cr4", SRIDX (0, 4, 0), 0}, {"msc_cfg", SRIDX (0, 4, 0), 0}, 785 {"cr5", SRIDX (0, 0, 1), 0}, {"core_id", SRIDX (0, 0, 1), 0}, 786 {"cr6", SRIDX (0, 5, 0), 0}, {"fucop_exist", SRIDX (0, 5, 0), 0}, 787 788 {"ir0", SRIDX (1, 0, 0), 0}, {"psw", SRIDX (1, 0, 0), 0}, 789 {"ir1", SRIDX (1, 0, 1), 0}, {"ipsw", SRIDX (1, 0, 1), 0}, 790 {"ir2", SRIDX (1, 0, 2), 0}, {"p_ipsw", SRIDX (1, 0, 2), 0}, 791 {"ir3", SRIDX (1, 1, 1), 0}, {"ivb", SRIDX (1, 1, 1), 0}, 792 {"ir4", SRIDX (1, 2, 1), 0}, {"p_eva", SRIDX (1, 2, 2), 0}, 793 {"ir5", SRIDX (1, 2, 2), 0}, {"eva", SRIDX (1, 2, 1), 0}, 794 {"ir6", SRIDX (1, 3, 1), 0}, {"itype", SRIDX (1, 3, 1), 0}, 795 {"ir7", SRIDX (1, 3, 2), 0}, {"p_itype", SRIDX (1, 3, 2), 0}, 796 {"ir8", SRIDX (1, 4, 1), 0}, {"merr", SRIDX (1, 4, 1), 0}, 797 {"ir9", SRIDX (1, 5, 1), 0}, {"ipc", SRIDX (1, 5, 1), 0}, 798 {"ir10", SRIDX (1, 5, 2), 0}, {"p_ipc", SRIDX (1, 5, 2), 0}, 799 {"ir11", SRIDX (1, 5, 3), 0}, {"oipc", SRIDX (1, 5, 3), 0}, 800 {"ir12", SRIDX (1, 6, 2), 0}, {"p_p0", SRIDX (1, 6, 2), 0}, 801 {"ir13", SRIDX (1, 7, 2), 0}, {"p_p1", SRIDX (1, 7, 2), 0}, 802 {"ir14", SRIDX (1, 8, 0), 0}, {"int_mask", SRIDX (1, 8, 0), 0}, 803 {"ir15", SRIDX (1, 9, 0), 0}, {"int_pend", SRIDX (1, 9, 0), 0}, 804 {"ir16", SRIDX (1, 10, 0), 0}, {"sp_usr", SRIDX (1, 10, 0), 0}, 805 {"ir17", SRIDX (1, 10, 1), 0}, {"sp_priv", SRIDX (1, 10, 1), 0}, 806 {"ir18", SRIDX (1, 11, 0), 0}, {"int_pri", SRIDX (1, 11, 0), 0}, 807 {"ir19", SRIDX (1, 1, 2), 0}, {"int_ctrl", SRIDX (1, 1, 2), 0}, 808 {"ir20", SRIDX (1, 10, 2), 0}, {"sp_usr1", SRIDX (1, 10, 2), 0}, 809 {"ir21", SRIDX (1, 10, 3), 0}, {"sp_priv1", SRIDX (1, 10, 3), 0}, 810 {"ir22", SRIDX (1, 10, 4), 0}, {"sp_usr2", SRIDX (1, 10, 4), 0}, 811 {"ir23", SRIDX (1, 10, 5), 0}, {"sp_priv2", SRIDX (1, 10, 5), 0}, 812 {"ir24", SRIDX (1, 10, 6), 0}, {"sp_usr3", SRIDX (1, 10, 6), 0}, 813 {"ir25", SRIDX (1, 10, 7), 0}, {"sp_priv3", SRIDX (1, 10, 7), 0}, 814 {"ir26", SRIDX (1, 8, 1), 0}, {"int_mask2", SRIDX (1, 8, 1), 0}, 815 {"ir27", SRIDX (1, 9, 1), 0}, {"int_pend2", SRIDX (1, 9, 1), 0}, 816 {"ir28", SRIDX (1, 11, 1), 0}, {"int_pri2", SRIDX (1, 11, 1), 0}, 817 {"ir29", SRIDX (1, 9, 4), 0}, {"int_trigger", SRIDX (1, 9, 4), 0}, 818 {"ir30", SRIDX (1, 1, 3), 0}, 819 820 {"mr0", SRIDX (2, 0, 0), 0}, {"mmu_ctl", SRIDX (2, 0, 0), 0}, 821 {"mr1", SRIDX (2, 1, 0), 0}, {"l1_pptb", SRIDX (2, 1, 0), 0}, 822 {"mr2", SRIDX (2, 2, 0), 0}, {"tlb_vpn", SRIDX (2, 2, 0), 0}, 823 {"mr3", SRIDX (2, 3, 0), 0}, {"tlb_data", SRIDX (2, 3, 0), 0}, 824 {"mr4", SRIDX (2, 4, 0), 0}, {"tlb_misc", SRIDX (2, 4, 0), 0}, 825 {"mr5", SRIDX (2, 5, 0), 0}, {"vlpt_idx", SRIDX (2, 5, 0), 0}, 826 {"mr6", SRIDX (2, 6, 0), 0}, {"ilmb", SRIDX (2, 6, 0), 0}, 827 {"mr7", SRIDX (2, 7, 0), 0}, {"dlmb", SRIDX (2, 7, 0), 0}, 828 {"mr8", SRIDX (2, 8, 0), 0}, {"cache_ctl", SRIDX (2, 8, 0), 0}, 829 {"mr9", SRIDX (2, 9, 0), 0}, {"hsmp_saddr", SRIDX (2, 9, 0), 0}, 830 {"mr10", SRIDX (2, 9, 1), 0}, {"hsmp_eaddr", SRIDX (2, 9, 1), 0}, 831 {"mr11", SRIDX (2, 0, 1), 0}, {"bg_region", SRIDX (2, 0, 1), 0}, 832 833 {"pfr0", SRIDX (4, 0, 0), 0}, {"pfmc0", SRIDX (4, 0, 0), 0}, 834 {"pfr1", SRIDX (4, 0, 1), 0}, {"pfmc1", SRIDX (4, 0, 1), 0}, 835 {"pfr2", SRIDX (4, 0, 2), 0}, {"pfmc2", SRIDX (4, 0, 2), 0}, 836 {"pfr3", SRIDX (4, 1, 0), 0}, {"pfm_ctl", SRIDX (4, 1, 0), 0}, 837 838 {"dmar0", SRIDX (5, 0, 0), 0}, {"dma_cfg", SRIDX (5, 0, 0), 0}, 839 {"dmar1", SRIDX (5, 1, 0), 0}, {"dma_gcsw", SRIDX (5, 1, 0), 0}, 840 {"dmar2", SRIDX (5, 2, 0), 0}, {"dma_chnsel", SRIDX (5, 2, 0), 0}, 841 {"dmar3", SRIDX (5, 3, 0), 0}, {"dma_act", SRIDX (5, 3, 0), 0}, 842 {"dmar4", SRIDX (5, 4, 0), 0}, {"dma_setup", SRIDX (5, 4, 0), 0}, 843 {"dmar5", SRIDX (5, 5, 0), 0}, {"dma_isaddr", SRIDX (5, 5, 0), 0}, 844 {"dmar6", SRIDX (5, 6, 0), 0}, {"dma_esaddr", SRIDX (5, 6, 0), 0}, 845 {"dmar7", SRIDX (5, 7, 0), 0}, {"dma_tcnt", SRIDX (5, 7, 0), 0}, 846 {"dmar8", SRIDX (5, 8, 0), 0}, {"dma_status", SRIDX (5, 8, 0), 0}, 847 {"dmar9", SRIDX (5, 9, 0), 0}, {"dma_2dset", SRIDX (5, 9, 0), 0}, 848 {"dmar10", SRIDX (5, 9, 1), 0}, {"dma_2dsctl", SRIDX (5, 9, 1), 0}, 849 {"dmar11", SRIDX (5, 7, 1), 0}, {"dma_rcnt", SRIDX (5, 7, 1), 0}, 850 {"dmar12", SRIDX (5, 8, 1), 0}, {"dma_hstatus", SRIDX (5, 8, 1), 0}, 851 852 {"idr0", SRIDX (2, 15, 0), 0}, {"sdz_ctl", SRIDX (2, 15, 0), 0}, 853 {"idr1", SRIDX (2, 15, 1), 0}, {"n12misc_ctl", SRIDX (2, 15, 1), 0}, 854 {"misc_ctl", SRIDX (2, 15, 1), 0}, 855 856 {"secur0", SRIDX (6, 0, 0), 0}, {"sfcr", SRIDX (6, 0, 0), 0}, 857 858 {"prusr_acc_ctl", SRIDX (4, 4, 0), 0}, 859 {"fucpr", SRIDX (4, 5, 0), 0}, {"fucop_ctl", SRIDX (4, 5, 0), 0}, 860 861 {"dr0", SRIDX (3, 0, 0), 0}, {"bpc0", SRIDX (3, 0, 0), 0}, 862 {"dr1", SRIDX (3, 0, 1), 0}, {"bpc1", SRIDX (3, 0, 1), 0}, 863 {"dr2", SRIDX (3, 0, 2), 0}, {"bpc2", SRIDX (3, 0, 2), 0}, 864 {"dr3", SRIDX (3, 0, 3), 0}, {"bpc3", SRIDX (3, 0, 3), 0}, 865 {"dr4", SRIDX (3, 0, 4), 0}, {"bpc4", SRIDX (3, 0, 4), 0}, 866 {"dr5", SRIDX (3, 0, 5), 0}, {"bpc5", SRIDX (3, 0, 5), 0}, 867 {"dr6", SRIDX (3, 0, 6), 0}, {"bpc6", SRIDX (3, 0, 6), 0}, 868 {"dr7", SRIDX (3, 0, 7), 0}, {"bpc7", SRIDX (3, 0, 7), 0}, 869 {"dr8", SRIDX (3, 1, 0), 0}, {"bpa0", SRIDX (3, 1, 0), 0}, 870 {"dr9", SRIDX (3, 1, 1), 0}, {"bpa1", SRIDX (3, 1, 1), 0}, 871 {"dr10", SRIDX (3, 1, 2), 0}, {"bpa2", SRIDX (3, 1, 2), 0}, 872 {"dr11", SRIDX (3, 1, 3), 0}, {"bpa3", SRIDX (3, 1, 3), 0}, 873 {"dr12", SRIDX (3, 1, 4), 0}, {"bpa4", SRIDX (3, 1, 4), 0}, 874 {"dr13", SRIDX (3, 1, 5), 0}, {"bpa5", SRIDX (3, 1, 5), 0}, 875 {"dr14", SRIDX (3, 1, 6), 0}, {"bpa6", SRIDX (3, 1, 6), 0}, 876 {"dr15", SRIDX (3, 1, 7), 0}, {"bpa7", SRIDX (3, 1, 7), 0}, 877 {"dr16", SRIDX (3, 2, 0), 0}, {"bpam0", SRIDX (3, 2, 0), 0}, 878 {"dr17", SRIDX (3, 2, 1), 0}, {"bpam1", SRIDX (3, 2, 1), 0}, 879 {"dr18", SRIDX (3, 2, 2), 0}, {"bpam2", SRIDX (3, 2, 2), 0}, 880 {"dr19", SRIDX (3, 2, 3), 0}, {"bpam3", SRIDX (3, 2, 3), 0}, 881 {"dr20", SRIDX (3, 2, 4), 0}, {"bpam4", SRIDX (3, 2, 4), 0}, 882 {"dr21", SRIDX (3, 2, 5), 0}, {"bpam5", SRIDX (3, 2, 5), 0}, 883 {"dr22", SRIDX (3, 2, 6), 0}, {"bpam6", SRIDX (3, 2, 6), 0}, 884 {"dr23", SRIDX (3, 2, 7), 0}, {"bpam7", SRIDX (3, 2, 7), 0}, 885 {"dr24", SRIDX (3, 3, 0), 0}, {"bpv0", SRIDX (3, 3, 0), 0}, 886 {"dr25", SRIDX (3, 3, 1), 0}, {"bpv1", SRIDX (3, 3, 1), 0}, 887 {"dr26", SRIDX (3, 3, 2), 0}, {"bpv2", SRIDX (3, 3, 2), 0}, 888 {"dr27", SRIDX (3, 3, 3), 0}, {"bpv3", SRIDX (3, 3, 3), 0}, 889 {"dr28", SRIDX (3, 3, 4), 0}, {"bpv4", SRIDX (3, 3, 4), 0}, 890 {"dr29", SRIDX (3, 3, 5), 0}, {"bpv5", SRIDX (3, 3, 5), 0}, 891 {"dr30", SRIDX (3, 3, 6), 0}, {"bpv6", SRIDX (3, 3, 6), 0}, 892 {"dr31", SRIDX (3, 3, 7), 0}, {"bpv7", SRIDX (3, 3, 7), 0}, 893 {"dr32", SRIDX (3, 4, 0), 0}, {"bpcid0", SRIDX (3, 4, 0), 0}, 894 {"dr33", SRIDX (3, 4, 1), 0}, {"bpcid1", SRIDX (3, 4, 1), 0}, 895 {"dr34", SRIDX (3, 4, 2), 0}, {"bpcid2", SRIDX (3, 4, 2), 0}, 896 {"dr35", SRIDX (3, 4, 3), 0}, {"bpcid3", SRIDX (3, 4, 3), 0}, 897 {"dr36", SRIDX (3, 4, 4), 0}, {"bpcid4", SRIDX (3, 4, 4), 0}, 898 {"dr37", SRIDX (3, 4, 5), 0}, {"bpcid5", SRIDX (3, 4, 5), 0}, 899 {"dr38", SRIDX (3, 4, 6), 0}, {"bpcid6", SRIDX (3, 4, 6), 0}, 900 {"dr39", SRIDX (3, 4, 7), 0}, {"bpcid7", SRIDX (3, 4, 7), 0}, 901 {"dr40", SRIDX (3, 5, 0), 0}, {"edm_cfg", SRIDX (3, 5, 0), 0}, 902 {"dr41", SRIDX (3, 6, 0), 0}, {"edmsw", SRIDX (3, 6, 0), 0}, 903 {"dr42", SRIDX (3, 7, 0), 0}, {"edm_ctl", SRIDX (3, 7, 0), 0}, 904 {"dr43", SRIDX (3, 8, 0), 0}, {"edm_dtr", SRIDX (3, 8, 0), 0}, 905 {"dr44", SRIDX (3, 9, 0), 0}, {"bpmtc", SRIDX (3, 9, 0), 0}, 906 {"dr45", SRIDX (3, 10, 0), 0}, {"dimbr", SRIDX (3, 10, 0), 0}, 907 {"dr46", SRIDX (3, 14, 0), 0}, {"tecr0", SRIDX (3, 14, 0), 0}, 908 {"dr47", SRIDX (3, 14, 1), 0}, {"tecr1", SRIDX (3, 14, 1), 0}, 909 {NULL,0 ,0} 910 }; 911 912 static const keyword_t keyword_cp[] = 913 { 914 {"cp0", 0, 0}, {"cp1", 1, 0}, {"cp2", 2, 0}, {"cp3", 3, 0}, {NULL, 0, 0} 915 }; 916 917 static const keyword_t keyword_cpr[] = 918 { 919 {"cpr0", 0, 0}, {"cpr1", 1, 0}, {"cpr2", 2, 0}, {"cpr3", 3, 0}, {"cpr4", 4, 0}, 920 {"cpr5", 5, 0}, {"cpr6", 6, 0}, {"cpr7", 7, 0}, {"cpr8", 8, 0}, {"cpr9", 9, 0}, 921 {"cpr10", 10, 0}, {"cpr11", 11, 0}, {"cpr12", 12, 0}, {"cpr13", 13, 0}, 922 {"cpr14", 14, 0}, {"cpr15", 15, 0}, {"cpr16", 16, 0}, {"cpr17", 17, 0}, 923 {"cpr18", 18, 0}, {"cpr19", 19, 0}, {"cpr20", 20, 0}, {"cpr21", 21, 0}, 924 {"cpr22", 22, 0}, {"cpr23", 23, 0}, {"cpr24", 24, 0}, {"cpr25", 25, 0}, 925 {"cpr26", 26, 0}, {"cpr27", 27, 0}, {"cpr28", 28, 0}, {"cpr29", 29, 0}, 926 {"cpr30", 30, 0}, {"cpr31", 31, 0}, {NULL, 0, 0} 927 }; 928 929 static const keyword_t keyword_fsr[] = 930 { 931 {"fs0", 0, 0}, {"fs1", 1, 0}, {"fs2", 2, 0}, {"fs3", 3, 0}, {"fs4", 4, 0}, 932 {"fs5", 5, 0}, {"fs6", 6, 0}, {"fs7", 7, 0}, {"fs8", 8, 0}, {"fs9", 9, 0}, 933 {"fs10", 10, 0}, {"fs11", 11, 0}, {"fs12", 12, 0}, {"fs13", 13, 0}, 934 {"fs14", 14, 0}, {"fs15", 15, 0}, {"fs16", 16, 0}, {"fs17", 17, 0}, 935 {"fs18", 18, 0}, {"fs19", 19, 0}, {"fs20", 20, 0}, {"fs21", 21, 0}, 936 {"fs22", 22, 0}, {"fs23", 23, 0}, {"fs24", 24, 0}, {"fs25", 25, 0}, 937 {"fs26", 26, 0}, {"fs27", 27, 0}, {"fs28", 28, 0}, {"fs29", 29, 0}, 938 {"fs30", 30, 0}, {"fs31", 31, 0}, {NULL, 0 ,0} 939 }; 940 941 static const keyword_t keyword_fdr[] = 942 { 943 {"fd0", 0, 0}, {"fd1", 1, 0}, {"fd2", 2, 0}, {"fd3", 3, 0}, {"fd4", 4, 0}, 944 {"fd5", 5, 0}, {"fd6", 6, 0}, {"fd7", 7, 0}, {"fd8", 8, 0}, {"fd9", 9, 0}, 945 {"fd10", 10, 0}, {"fd11", 11, 0}, {"fd12", 12, 0}, {"fd13", 13, 0}, 946 {"fd14", 14, 0}, {"fd15", 15, 0}, {"fd16", 16, 0}, {"fd17", 17, 0}, 947 {"fd18", 18, 0}, {"fd19", 19, 0}, {"fd20", 20, 0}, {"fd21", 21, 0}, 948 {"fd22", 22, 0}, {"fd23", 23, 0}, {"fd24", 24, 0}, {"fd25", 25, 0}, 949 {"fd26", 26, 0}, {"fd27", 27, 0}, {"fd28", 28, 0}, {"fd29", 29, 0}, 950 {"fd30", 30, 0}, {"fd31", 31, 0}, {NULL, 0, 0} 951 }; 952 953 static const keyword_t keyword_abdim[] = 954 { 955 {"bi", 0, 0}, {"bim", 1, 0}, {"bd", 2, 0}, {"bdm", 3, 0}, 956 {"ai", 4, 0}, {"aim", 5, 0}, {"ad", 6, 0}, {"adm", 7, 0}, 957 {NULL, 0, 0} 958 }; 959 960 static const keyword_t keyword_abm[] = 961 { 962 {"b", 0, 0}, {"bm", 1, 0}, {"a", 4, 0}, {"am", 5, 0}, {NULL, 0, 0} 963 }; 964 965 static const keyword_t keyword_dtiton[] = 966 { 967 {"iton", 1, 0}, {"ton", 3, 0}, {NULL, 0, 0} 968 }; 969 970 static const keyword_t keyword_dtitoff[] = 971 { 972 {"itoff", 1, 0}, {"toff", 3, 0}, {NULL, 0, 0} 973 }; 974 975 static const keyword_t keyword_dpref_st[] = 976 { 977 {"srd", 0, 0}, {"mrd", 1, 0}, {"swr", 2, 0}, {"mwr", 3, 0}, 978 {"pte", 4, 0}, {"clwr", 5, 0}, {NULL, 0, 0} 979 }; 980 981 /* CCTL Ra, SubType */ 982 static const keyword_t keyword_cctl_st0[] = 983 { 984 {"l1d_ix_inval", 0X0, 0}, {"l1d_ix_wb", 0X1, 0}, {"l1d_ix_wbinval", 0X2, 0}, 985 {"l1d_va_fillck", 0XB, 0}, {"l1d_va_ulck", 0XC, 0}, {"l1i_ix_inval", 0X10, 0}, 986 {"l1i_va_fillck", 0X1B, 0}, {"l1i_va_ulck", 0X1C, 0}, 987 {NULL, 0, 0} 988 }; 989 990 /* CCTL Ra, SubType, level */ 991 static const keyword_t keyword_cctl_st1[] = 992 { 993 {"l1d_va_inval", 0X8, 0}, {"l1d_va_wb", 0X9, 0}, 994 {"l1d_va_wbinval", 0XA, 0}, {"l1i_va_inval", 0X18, 0}, 995 {NULL, 0, 0} 996 }; 997 998 /* CCTL Rt, Ra, SubType */ 999 static const keyword_t keyword_cctl_st2[] = 1000 { 1001 {"l1d_ix_rtag", 0X3, 0}, {"l1d_ix_rwd", 0X4, 0}, 1002 {"l1i_ix_rtag", 0X13, 0}, {"l1i_ix_rwd", 0X14, 0}, 1003 {NULL, 0, 0} 1004 }; 1005 1006 /* CCTL Rb, Ra, SubType */ 1007 static const keyword_t keyword_cctl_st3[] = 1008 { 1009 {"l1d_ix_wtag", 0X5, 0}, {"l1d_ix_wwd", 0X6, 0}, 1010 {"l1i_ix_wtag", 0X15, 0}, {"l1i_ix_wwd", 0X16, 0}, 1011 {NULL, 0, 0} 1012 }; 1013 1014 /* CCTL L1D_INVALALL */ 1015 static const keyword_t keyword_cctl_st4[] = 1016 { 1017 {"l1d_invalall", 0x7, 0}, {NULL, 0, 0} 1018 }; 1019 1020 /* CCTL L1D_WBALL, level */ 1021 static const keyword_t keyword_cctl_st5[] = 1022 { 1023 {"l1d_wball", 0xf, 0}, {NULL, 0, 0} 1024 }; 1025 1026 static const keyword_t keyword_cctl_lv[] = 1027 { 1028 {"1level", 0, 0}, {"alevel", 1, 0}, {"0", 0, 0}, {"1", 1, 0}, 1029 {NULL, 0, 0}, 1030 }; 1031 1032 static const keyword_t keyword_tlbop_st[] = 1033 { 1034 {"trd", 0, 0}, {"targetread", 0, 0}, 1035 {"twr", 1, 0}, {"targetwrite", 1, 0}, 1036 {"rwr", 2, 0}, {"rwrite", 2, 0}, 1037 {"rwlk", 3, 0}, {"rwritelock", 3, 0}, 1038 {"unlk", 4, 0}, {"unlock", 4, 0}, 1039 {"inv", 6, 0}, {"invalidate", 6, 0}, 1040 {NULL, 0, 0}, 1041 /* "pb" requries two operand and "flua" requires none. */ 1042 /* {"pb", 5, 0}, {"probe", 5, 0}, 1043 {"flua", 7, 0}, {"flushall", 0}, */ 1044 }; 1045 1046 static const keyword_t keyword_standby_st[] = 1047 { 1048 {"no_wake_grant", 0, 0}, 1049 {"wake_grant", 1, 0}, 1050 {"wait_done", 2, 0}, 1051 {"0", 0, 0}, 1052 {"1", 1, 0}, 1053 {"2", 2, 0}, 1054 {"3", 3, 0}, 1055 {NULL, 0, 0}, 1056 }; 1057 1058 static const keyword_t keyword_msync_st[] = 1059 { 1060 {"all", 0, 0}, {"store", 1, 0}, 1061 {NULL, 0, 0} 1062 }; 1063 1064 1065 /* Hash table for syntax lex. */ 1066 static htab_t field_htab; 1067 /* Hash table for opcodes. */ 1068 static htab_t opcode_htab; 1069 /* Hash table for hardware resources. */ 1070 static htab_t hw_ktabs[_HW_LAST]; 1071 1072 static hashval_t 1073 htab_hash_hash (const void *p) 1074 { 1075 struct nds32_hash_entry *h = (struct nds32_hash_entry *) p; 1076 1077 return htab_hash_string (h->name); 1078 } 1079 1080 static int 1081 htab_hash_eq (const void *p, const void *q) 1082 { 1083 struct nds32_hash_entry *h = (struct nds32_hash_entry *) p; 1084 const char *name = (const char *) q; 1085 1086 return strcmp (name, h->name) == 0; 1087 } 1088 1089 1090 /* Build a hash table for array BASE. Each element is in size of SIZE, 1091 and it's first element is a pointer to the key of string. 1092 It stops inserting elements until reach an NULL key. */ 1093 1094 static htab_t 1095 build_hash_table (const void *base, size_t size) 1096 { 1097 htab_t htab; 1098 hashval_t hash; 1099 const char *p; 1100 1101 htab = htab_create_alloc (128, htab_hash_hash, htab_hash_eq, 1102 NULL, xcalloc, free); 1103 1104 p = base; 1105 while (1) 1106 { 1107 struct nds32_hash_entry **slot; 1108 struct nds32_hash_entry *h; 1109 1110 h = (struct nds32_hash_entry *) p; 1111 1112 if (h->name == NULL) 1113 break; 1114 1115 hash = htab_hash_string (h->name); 1116 slot = (struct nds32_hash_entry **) 1117 htab_find_slot_with_hash (htab, h->name, hash, INSERT); 1118 1119 assert (slot != NULL && *slot == NULL); 1120 1121 *slot = h; 1122 1123 p = p + size; 1124 } 1125 1126 return htab; 1127 } 1128 1129 /* Build the syntax for a given opcode OPC. It parses the string 1130 pointed by INSTRUCTION and store the result on SYNTAX, so 1131 when we assemble an instruction, we don't have to parse the syntax 1132 again. */ 1133 1134 static void 1135 build_opcode_syntax (struct nds32_opcode *opc) 1136 { 1137 char odstr[MAX_LEX_LEN]; 1138 const char *str; 1139 const char *end; 1140 lex_t *plex; 1141 int len; 1142 hashval_t hash; 1143 field_t *fd; 1144 int opt = 0; 1145 1146 /* Check whether it has been initialized. */ 1147 if (opc->syntax) 1148 return; 1149 1150 opc->syntax = xmalloc (MAX_LEX_NUM * sizeof (lex_t)); 1151 1152 str = opc->instruction; 1153 plex = opc->syntax; 1154 while (*str) 1155 { 1156 int fidx; 1157 1158 switch (*str) 1159 { 1160 case '%': *plex = SYN_INPUT; break; 1161 case '=': *plex = SYN_OUTPUT; break; 1162 case '&': *plex = SYN_INPUT | SYN_OUTPUT; break; 1163 case '{': 1164 *plex++ = SYN_LOPT; 1165 opt++; 1166 str++; 1167 continue; 1168 case '}': 1169 *plex++ = SYN_ROPT; 1170 str++; 1171 continue; 1172 default: 1173 *plex++ = *str++; 1174 continue; 1175 } 1176 str++; 1177 1178 /* Extract operand. */ 1179 end = str; 1180 while (ISALNUM (*end) || *end == '_') 1181 end++; 1182 len = end - str; 1183 memcpy (odstr, str, len); 1184 odstr[len] = '\0'; 1185 1186 hash = htab_hash_string (odstr); 1187 fd = (field_t *) htab_find_with_hash (field_htab, odstr, hash); 1188 fidx = fd - operand_fields; 1189 1190 if (fd == NULL) 1191 { 1192 fprintf (stderr, "Internal error: Unknown operand, %s\n", str); 1193 } 1194 assert (fd && fidx >= 0 && fidx < (int) ARRAY_SIZE (operand_fields)); 1195 *plex |= LEX_SET_FIELD (fidx); 1196 1197 str += len; 1198 plex++; 1199 } 1200 1201 *plex = 0; 1202 opc->variant = opt; 1203 return; 1204 1205 fprintf (stderr, "Unknown lex in assembly syntax, %s.\n", str); 1206 abort (); 1207 } 1208 1209 /* Initialize the assembler. It must be called before assembling. */ 1210 1211 void 1212 nds32_asm_init (nds32_asm_desc_t *pdesc, int flags) 1213 { 1214 int i; 1215 hashval_t hash; 1216 const keyword_t *keywords[_HW_LAST] = 1217 { 1218 keyword_gpr, keyword_usr, keyword_dxr, keyword_sr, keyword_fsr, 1219 keyword_fdr, keyword_cp, keyword_cpr, keyword_abdim, keyword_abm, 1220 keyword_dtiton, keyword_dtitoff, keyword_dpref_st, 1221 keyword_cctl_st0, keyword_cctl_st1, keyword_cctl_st2, 1222 keyword_cctl_st3, keyword_cctl_st4, keyword_cctl_st5, 1223 keyword_cctl_lv, keyword_tlbop_st, keyword_standby_st, 1224 keyword_msync_st, 1225 }; 1226 1227 pdesc->flags = flags; 1228 pdesc->mach = flags & NASM_OPEN_ARCH_MASK; 1229 1230 /* Build keyword tables. */ 1231 field_htab = build_hash_table (operand_fields, 1232 sizeof (operand_fields[0])); 1233 1234 for (i = 0; i < _HW_LAST; i++) 1235 hw_ktabs[i] = build_hash_table (keywords[i], sizeof (keyword_t)); 1236 1237 /* Build opcode table. */ 1238 opcode_htab = htab_create_alloc (128, htab_hash_hash, htab_hash_eq, 1239 NULL, xcalloc, free); 1240 1241 for (i = 0; i < (int) ARRAY_SIZE (nds32_opcodes); i++) 1242 { 1243 struct nds32_opcode **slot; 1244 struct nds32_opcode *opc; 1245 1246 opc = &nds32_opcodes[i]; 1247 1248 hash = htab_hash_string (opc->opcode); 1249 slot = (struct nds32_opcode **) 1250 htab_find_slot_with_hash (opcode_htab, opc->opcode, hash, INSERT); 1251 1252 #define NDS32_PREINIT_SYNTAX 1253 #if defined (NDS32_PREINIT_SYNTAX) 1254 /* Initial SYNTAX when build opcode table, so bug in syntax can be 1255 found when initialized rather than used. */ 1256 build_opcode_syntax (opc); 1257 #endif 1258 1259 if (*slot == NULL) 1260 { 1261 /* This is the new one. */ 1262 *slot = opc; 1263 } 1264 else 1265 { 1266 /* Already exists. Append to the list. */ 1267 opc = *slot; 1268 while (opc->next) 1269 opc = opc->next; 1270 opc->next = &nds32_opcodes[i]; 1271 } 1272 } 1273 } 1274 1275 /* Parse the input and store operand keyword string in ODSTR. 1276 This function is only used for parsing keywords, 1277 HW_INT/HW_UINT are parsed parse_operand callback handler. */ 1278 1279 static char * 1280 parse_to_delimiter (char *str, char odstr[MAX_KEYWORD_LEN]) 1281 { 1282 char *outp = odstr; 1283 1284 while (ISALNUM (*str) || *str == '.' || *str == '_') 1285 *outp++ = TOLOWER (*str++); 1286 1287 *outp = '\0'; 1288 return str; 1289 } 1290 1291 /* Parse the operand of push25/pop25. */ 1292 1293 static int 1294 parse_re2 (struct nds32_asm_desc *pdesc ATTRIBUTE_UNUSED, 1295 struct nds32_asm_insn *pinsn ATTRIBUTE_UNUSED, 1296 char **pstr, int64_t *value) 1297 { 1298 char *end = *pstr; 1299 char odstr[MAX_KEYWORD_LEN]; 1300 keyword_t *k; 1301 hashval_t hash; 1302 1303 if (*end == '$') 1304 end++; 1305 end = parse_to_delimiter (end, odstr); 1306 1307 hash = htab_hash_string (odstr); 1308 k = htab_find_with_hash (hw_ktabs[HW_GPR], odstr, hash); 1309 1310 if (k == NULL) 1311 return NASM_ERR_OPERAND; 1312 1313 if (k->value == 6) 1314 *value = 0; 1315 else if (k->value == 8) 1316 *value = 1; 1317 else if (k->value == 10) 1318 *value = 2; 1319 else if (k->value == 14) 1320 *value = 3; 1321 else 1322 return NASM_ERR_OPERAND; 1323 1324 *pstr = end; 1325 return NASM_R_CONST; 1326 } 1327 1328 /* Parse the operand of lwi45.fe. */ 1329 1330 static int 1331 parse_fe5 (struct nds32_asm_desc *pdesc, struct nds32_asm_insn *pinsn, 1332 char **pstr, int64_t *value) 1333 { 1334 int r; 1335 1336 r = pdesc->parse_operand (pdesc, pinsn, pstr, value); 1337 if (r != NASM_R_CONST) 1338 return r; 1339 1340 /* 128 == 32 << 2. Leave the shift to parse_opreand, 1341 so it can check whether it is a multiple of 4. */ 1342 *value = 128 + *value; 1343 return r; 1344 } 1345 1346 /* Parse the operand of movpi45. */ 1347 1348 static int 1349 parse_pi5 (struct nds32_asm_desc *pdesc, struct nds32_asm_insn *pinsn, 1350 char **pstr, int64_t *value) 1351 { 1352 int r; 1353 1354 r = pdesc->parse_operand (pdesc, pinsn, pstr, value); 1355 if (r != NASM_R_CONST) 1356 return r; 1357 1358 *value -= 16; 1359 return r; 1360 } 1361 1362 /* Generic operand parse base on the information provided by the field. */ 1363 1364 static int 1365 parse_operand (nds32_asm_desc_t *pdesc, nds32_asm_insn_t *pinsn, 1366 char **str, int syn) 1367 { 1368 char odstr[MAX_KEYWORD_LEN]; 1369 char *end; 1370 hashval_t hash; 1371 const field_t *fld = &LEX_GET_FIELD (syn); 1372 keyword_t *k; 1373 int64_t value; 1374 int r; 1375 uint64_t modifier = 0; 1376 1377 end = *str; 1378 1379 if (fld->parse) 1380 { 1381 r = fld->parse (pdesc, pinsn, &end, &value); 1382 goto done; 1383 } 1384 1385 if (fld->hw_res < _HW_LAST) 1386 { 1387 /* Parse the operand in assembly code. */ 1388 if (*end == '$') 1389 end++; 1390 end = parse_to_delimiter (end, odstr); 1391 1392 hash = htab_hash_string (odstr); 1393 k = htab_find_with_hash (hw_ktabs[fld->hw_res], odstr, hash); 1394 1395 if (k == NULL) 1396 { 1397 pdesc->result = NASM_ERR_OPERAND; 1398 return 0; 1399 } 1400 1401 if (fld->hw_res == HW_GPR && (pdesc->flags & NASM_OPEN_REDUCED_REG) 1402 && (k->attr & ATTR (RDREG)) == 0) 1403 { 1404 /* Register not allowed in reduced register. */ 1405 pdesc->result = NASM_ERR_REG_REDUCED; 1406 return 0; 1407 } 1408 1409 if (fld->hw_res == HW_GPR) 1410 { 1411 if (syn & SYN_INPUT) 1412 pinsn->defuse |= USE_REG (k->value); 1413 if (syn & SYN_OUTPUT) 1414 pinsn->defuse |= DEF_REG (k->value); 1415 } 1416 1417 value = k->value; 1418 if (fld->hw_res == HW_GPR && (fld->bitsize + fld->shift) == 4) 1419 value = nds32_r54map[value]; 1420 } 1421 else if (fld->hw_res == HW_INT || fld->hw_res == HW_UINT) 1422 { 1423 if (*end == '#') 1424 end++; 1425 1426 /* Handle modifiers. Do we need to make a table for modifiers? 1427 Do we need to check unknown modifier? */ 1428 if (strncasecmp (end, "hi20(", 5) == 0) 1429 { 1430 modifier |= NASM_ATTR_HI20; 1431 end += 5; 1432 } 1433 else if (strncasecmp (end, "lo12(", 5) == 0) 1434 { 1435 modifier |= NASM_ATTR_LO12; 1436 end += 5; 1437 } 1438 else if (strncasecmp (end, "lo20(", 5) == 0) 1439 { 1440 /* e.g., movi */ 1441 modifier |= NASM_ATTR_LO20; 1442 end += 5; 1443 } 1444 1445 r = pdesc->parse_operand (pdesc, pinsn, &end, &value); 1446 if (modifier) 1447 { 1448 /* Consume the ')' of modifier. */ 1449 end++; 1450 pinsn->attr |= modifier; 1451 } 1452 1453 switch (r) 1454 { 1455 case NASM_R_ILLEGAL: 1456 pdesc->result = NASM_ERR_OPERAND; 1457 return 0; 1458 case NASM_R_SYMBOL: 1459 /* This field needs special fix-up. */ 1460 pinsn->field = fld; 1461 break; 1462 case NASM_R_CONST: 1463 if (modifier & NASM_ATTR_HI20) 1464 value = (value >> 12) & 0xfffff; 1465 else if (modifier & NASM_ATTR_LO12) 1466 value = value & 0xfff; 1467 else if (modifier & NASM_ATTR_LO20) 1468 value = value & 0xfffff; 1469 break; 1470 default: 1471 fprintf (stderr, "Internal error: Don't know how to handle " 1472 "parsing results.\n"); 1473 abort (); 1474 } 1475 } 1476 else 1477 { 1478 fprintf (stderr, "Internal error: Unknown hardware resource.\n"); 1479 abort (); 1480 } 1481 1482 done: 1483 /* Don't silently discarding bits. */ 1484 if (value & __MASK (fld->shift)) 1485 { 1486 pdesc->result = NASM_ERR_OUT_OF_RANGE; 1487 return 0; 1488 } 1489 1490 /* Check the range of signed or unsigned result. */ 1491 if (fld->hw_res != HW_INT && (value >> (fld->bitsize + fld->shift))) 1492 { 1493 pdesc->result = NASM_ERR_OUT_OF_RANGE; 1494 return 0; 1495 } 1496 else if (fld->hw_res == HW_INT) 1497 { 1498 /* Sign-ext the value. */ 1499 if (((value >> 32) == 0) && (value & 0x80000000)) 1500 value |= (int64_t) -1 << 31; 1501 1502 1503 /* Shift the value to positive domain. */ 1504 if ((value + (1 << (fld->bitsize + fld->shift - 1))) 1505 >> (fld->bitsize + fld->shift)) 1506 { 1507 pdesc->result = NASM_ERR_OUT_OF_RANGE; 1508 return 0; 1509 } 1510 } 1511 1512 pinsn->insn |= (((value >> fld->shift) & __MASK (fld->bitsize)) << fld->bitpos); 1513 *str = end; 1514 return 1; 1515 } 1516 1517 /* Try to parse an instruction string based on opcode syntax. */ 1518 1519 static int 1520 parse_insn (nds32_asm_desc_t *pdesc, nds32_asm_insn_t *pinsn, 1521 char *str, struct nds32_opcode *opc) 1522 { 1523 int variant = 0; 1524 char *p = NULL; 1525 1526 /* A syntax may has optional operands, so we have to try each possible 1527 combination to see if the input is accepted. In order to do so, 1528 bit-N represent whether optional-operand-N is used in this combination. 1529 That is, if bit-N is set, optional-operand-N is not used. 1530 1531 For example, there are 2 optional operands in this syntax, 1532 1533 "a{,b}{,c}" 1534 1535 we can try it 4 times (i.e., 1 << 2) 1536 1537 0 (b00): "a,b,c" 1538 1 (b01): "a,c" 1539 2 (b10): "a,b" 1540 3 (b11): "a" 1541 */ 1542 1543 /* The outer do-while loop is used to try each possible optional 1544 operand combination, and VARIANT is the bit mask. The inner loop 1545 iterates each lexeme in the syntax. */ 1546 1547 do 1548 { 1549 /* OPT is the number of optional operands we've seen. */ 1550 int opt = 0; 1551 lex_t *plex; 1552 1553 /* PLEX is the syntax iterator and P is the iterator for input 1554 string. */ 1555 plex = opc->syntax; 1556 p = str; 1557 /* Initial the base value. */ 1558 pinsn->insn = opc->value; 1559 1560 while (*plex) 1561 { 1562 if (IS_LEX_CHAR (*plex)) 1563 { 1564 /* If it's a plain char, just compare it. */ 1565 if (LEX_CHAR (*plex) != *p) 1566 { 1567 pdesc->result = NASM_ERR_SYNTAX; 1568 goto reject; 1569 } 1570 p++; 1571 } 1572 else if (*plex & SYN_LOPT) 1573 { 1574 /* If it's '{' and it's not used in this iteration, 1575 just skip the whole optional operand. */ 1576 if ((1 << (opt++)) & variant) 1577 { 1578 while ((*plex & SYN_ROPT) == 0) 1579 plex++; 1580 } 1581 } 1582 else if (*plex & SYN_ROPT) 1583 { 1584 /* ignore */ 1585 } 1586 else 1587 { 1588 /* If it's a operand, parse the input operand from input. */ 1589 if (!parse_operand (pdesc, pinsn, &p, *plex)) 1590 goto reject; 1591 } 1592 plex++; 1593 } 1594 1595 /* Check whether this syntax is accepted. */ 1596 if (*plex == 0 && (*p == '\0' || *p == '!' || *p == '#')) 1597 return 1; 1598 1599 reject: 1600 /* If not accepted, try another combination. */ 1601 variant++; 1602 } 1603 while (variant < (1 << opc->variant)); 1604 1605 return 0; 1606 } 1607 1608 void 1609 nds32_assemble (nds32_asm_desc_t *pdesc, nds32_asm_insn_t *pinsn, 1610 char *str) 1611 { 1612 struct nds32_opcode *opc; 1613 char *s; 1614 char *mnemoic; 1615 char *dot; 1616 hashval_t hash; 1617 1618 /* Duplicate the string, so we can modify it for convenience. */ 1619 s = strdup (str); 1620 mnemoic = s; 1621 str = s; 1622 1623 /* Find opcode mnemoic. */ 1624 while (*s != ' ' && *s != '\t' && *s != '\0') 1625 s++; 1626 if (*s != '\0') 1627 *s++ = '\0'; 1628 dot = strchr (mnemoic, '.'); 1629 1630 retry_dot: 1631 /* Lookup the opcode syntax. */ 1632 hash = htab_hash_string (mnemoic); 1633 opc = (struct nds32_opcode *) 1634 htab_find_with_hash (opcode_htab, mnemoic, hash); 1635 1636 /* If we cannot find a match syntax, try it again without `.'. 1637 For example, try "lmw.adm" first and then try "lmw" again. */ 1638 if (opc == NULL && dot != NULL) 1639 { 1640 *dot = '\0'; 1641 s[-1] = ' '; 1642 s = dot + 1; 1643 dot = NULL; 1644 goto retry_dot; 1645 } 1646 else if (opc == NULL) 1647 { 1648 pdesc->result = NASM_ERR_UNKNOWN_OP; 1649 goto out; 1650 } 1651 1652 /* There may be multiple syntaxes for a given opcode. 1653 Try each one until a match is found. */ 1654 for (; opc; opc = opc->next) 1655 { 1656 /* Build opcode syntax, if it's not been initialized yet. */ 1657 if (opc->syntax == NULL) 1658 build_opcode_syntax (opc); 1659 1660 /* Reset status before assemble. */ 1661 pinsn->defuse = opc->defuse; 1662 pinsn->insn = 0; 1663 pinsn->field = NULL; 1664 /* Use opcode attributes to initial instruction attributes. */ 1665 pinsn->attr = opc->attr; 1666 if (parse_insn (pdesc, pinsn, s, opc)) 1667 break; 1668 } 1669 1670 pinsn->opcode = opc; 1671 if (opc == NULL) 1672 { 1673 pdesc->result = NASM_ERR_SYNTAX; 1674 goto out; 1675 } 1676 1677 /* A matched opcode is found. Write the result to instruction buffer. */ 1678 pdesc->result = NASM_OK; 1679 1680 out: 1681 free (str); 1682 } 1683