1 1.10 christos /* Copyright (C) 1998-2025 Free Software Foundation, Inc. 2 1.1 christos Contributed by David Mosberger-Tang <davidm (at) hpl.hp.com> 3 1.1 christos 4 1.1 christos This file is part of BFD, the Binary File Descriptor library. 5 1.1 christos 6 1.1 christos This program is free software; you can redistribute it and/or modify 7 1.1 christos it under the terms of the GNU General Public License as published by 8 1.1 christos the Free Software Foundation; either version 3 of the License, or 9 1.1 christos (at your option) any later version. 10 1.1 christos 11 1.1 christos This program is distributed in the hope that it will be useful, 12 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of 13 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 1.1 christos GNU General Public License for more details. 15 1.1 christos 16 1.1 christos You should have received a copy of the GNU General Public License 17 1.1 christos along with this program; if not, write to the Free Software 18 1.1 christos Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, 19 1.1 christos MA 02110-1301, USA. */ 20 1.1 christos 21 1.1 christos /* Logically, this code should be part of libopcode but since some of 22 1.1 christos the operand insertion/extraction functions help bfd to implement 23 1.1 christos relocations, this code is included as part of cpu-ia64.c. This 24 1.1 christos avoids circular dependencies between libopcode and libbfd and also 25 1.1 christos obviates the need for applications to link in libopcode when all 26 1.1 christos they really want is libbfd. 27 1.1 christos 28 1.1 christos --davidm Mon Apr 13 22:14:02 1998 */ 29 1.1 christos 30 1.1 christos #include "../opcodes/ia64-opc.h" 31 1.1 christos 32 1.1 christos #define NELEMS(a) ((int) (sizeof (a) / sizeof ((a)[0]))) 33 1.1 christos 34 1.1 christos static const char* 35 1.1 christos ins_rsvd (const struct ia64_operand *self ATTRIBUTE_UNUSED, 36 1.1 christos ia64_insn value ATTRIBUTE_UNUSED, ia64_insn *code ATTRIBUTE_UNUSED) 37 1.1 christos { 38 1.1 christos return "internal error---this shouldn't happen"; 39 1.1 christos } 40 1.1 christos 41 1.1 christos static const char* 42 1.1 christos ext_rsvd (const struct ia64_operand *self ATTRIBUTE_UNUSED, 43 1.1 christos ia64_insn code ATTRIBUTE_UNUSED, ia64_insn *valuep ATTRIBUTE_UNUSED) 44 1.1 christos { 45 1.1 christos return "internal error---this shouldn't happen"; 46 1.1 christos } 47 1.1 christos 48 1.1 christos static const char* 49 1.1 christos ins_const (const struct ia64_operand *self ATTRIBUTE_UNUSED, 50 1.1 christos ia64_insn value ATTRIBUTE_UNUSED, ia64_insn *code ATTRIBUTE_UNUSED) 51 1.1 christos { 52 1.1 christos return 0; 53 1.1 christos } 54 1.1 christos 55 1.1 christos static const char* 56 1.1 christos ext_const (const struct ia64_operand *self ATTRIBUTE_UNUSED, 57 1.1 christos ia64_insn code ATTRIBUTE_UNUSED, ia64_insn *valuep ATTRIBUTE_UNUSED) 58 1.1 christos { 59 1.1 christos return 0; 60 1.1 christos } 61 1.1 christos 62 1.1 christos static const char* 63 1.1 christos ins_reg (const struct ia64_operand *self, ia64_insn value, ia64_insn *code) 64 1.1 christos { 65 1.1 christos if (value >= 1u << self->field[0].bits) 66 1.1 christos return "register number out of range"; 67 1.1 christos 68 1.1 christos *code |= value << self->field[0].shift; 69 1.1 christos return 0; 70 1.1 christos } 71 1.1 christos 72 1.1 christos static const char* 73 1.1 christos ext_reg (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep) 74 1.1 christos { 75 1.1 christos *valuep = ((code >> self->field[0].shift) 76 1.1 christos & ((1u << self->field[0].bits) - 1)); 77 1.1 christos return 0; 78 1.1 christos } 79 1.1 christos 80 1.1 christos static const char* 81 1.1 christos ins_immu (const struct ia64_operand *self, ia64_insn value, ia64_insn *code) 82 1.1 christos { 83 1.1 christos ia64_insn new_insn = 0; 84 1.1 christos int i; 85 1.1 christos 86 1.1 christos for (i = 0; i < NELEMS (self->field) && self->field[i].bits; ++i) 87 1.1 christos { 88 1.1 christos new_insn |= ((value & ((((ia64_insn) 1) << self->field[i].bits) - 1)) 89 1.6 christos << self->field[i].shift); 90 1.1 christos value >>= self->field[i].bits; 91 1.1 christos } 92 1.1 christos if (value) 93 1.1 christos return "integer operand out of range"; 94 1.1 christos 95 1.1 christos *code |= new_insn; 96 1.1 christos return 0; 97 1.1 christos } 98 1.1 christos 99 1.1 christos static const char* 100 1.1 christos ext_immu (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep) 101 1.1 christos { 102 1.8 christos uint64_t value = 0; 103 1.1 christos int i, bits = 0, total = 0; 104 1.1 christos 105 1.1 christos for (i = 0; i < NELEMS (self->field) && self->field[i].bits; ++i) 106 1.1 christos { 107 1.1 christos bits = self->field[i].bits; 108 1.1 christos value |= ((code >> self->field[i].shift) 109 1.8 christos & (((uint64_t) 1 << bits) - 1)) << total; 110 1.1 christos total += bits; 111 1.1 christos } 112 1.1 christos *valuep = value; 113 1.1 christos return 0; 114 1.1 christos } 115 1.1 christos 116 1.1 christos static const char* 117 1.1 christos ins_immu5b (const struct ia64_operand *self, ia64_insn value, 118 1.1 christos ia64_insn *code) 119 1.1 christos { 120 1.1 christos if (value < 32 || value > 63) 121 1.1 christos return "value must be between 32 and 63"; 122 1.1 christos return ins_immu (self, value - 32, code); 123 1.1 christos } 124 1.1 christos 125 1.1 christos static const char* 126 1.1 christos ext_immu5b (const struct ia64_operand *self, ia64_insn code, 127 1.1 christos ia64_insn *valuep) 128 1.1 christos { 129 1.1 christos const char *result; 130 1.1 christos 131 1.1 christos result = ext_immu (self, code, valuep); 132 1.1 christos if (result) 133 1.1 christos return result; 134 1.1 christos 135 1.1 christos *valuep = *valuep + 32; 136 1.1 christos return 0; 137 1.1 christos } 138 1.1 christos 139 1.1 christos static const char* 140 1.1 christos ins_immus8 (const struct ia64_operand *self, ia64_insn value, ia64_insn *code) 141 1.1 christos { 142 1.1 christos if (value & 0x7) 143 1.1 christos return "value not an integer multiple of 8"; 144 1.1 christos return ins_immu (self, value >> 3, code); 145 1.1 christos } 146 1.1 christos 147 1.1 christos static const char* 148 1.1 christos ext_immus8 (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep) 149 1.1 christos { 150 1.1 christos const char *result; 151 1.1 christos 152 1.1 christos result = ext_immu (self, code, valuep); 153 1.1 christos if (result) 154 1.1 christos return result; 155 1.1 christos 156 1.1 christos *valuep = *valuep << 3; 157 1.1 christos return 0; 158 1.1 christos } 159 1.1 christos 160 1.1 christos static const char* 161 1.1 christos ins_imms_scaled (const struct ia64_operand *self, ia64_insn value, 162 1.1 christos ia64_insn *code, int scale) 163 1.1 christos { 164 1.8 christos int64_t svalue = value, sign_bit = 0; 165 1.1 christos ia64_insn new_insn = 0; 166 1.1 christos int i; 167 1.1 christos 168 1.1 christos svalue >>= scale; 169 1.1 christos 170 1.1 christos for (i = 0; i < NELEMS (self->field) && self->field[i].bits; ++i) 171 1.1 christos { 172 1.1 christos new_insn |= ((svalue & ((((ia64_insn) 1) << self->field[i].bits) - 1)) 173 1.6 christos << self->field[i].shift); 174 1.1 christos sign_bit = (svalue >> (self->field[i].bits - 1)) & 1; 175 1.1 christos svalue >>= self->field[i].bits; 176 1.1 christos } 177 1.1 christos if ((!sign_bit && svalue != 0) || (sign_bit && svalue != -1)) 178 1.1 christos return "integer operand out of range"; 179 1.1 christos 180 1.1 christos *code |= new_insn; 181 1.1 christos return 0; 182 1.1 christos } 183 1.1 christos 184 1.1 christos static const char* 185 1.1 christos ext_imms_scaled (const struct ia64_operand *self, ia64_insn code, 186 1.1 christos ia64_insn *valuep, int scale) 187 1.1 christos { 188 1.1 christos int i, bits = 0, total = 0; 189 1.8 christos uint64_t val = 0, sign; 190 1.1 christos 191 1.1 christos for (i = 0; i < NELEMS (self->field) && self->field[i].bits; ++i) 192 1.1 christos { 193 1.1 christos bits = self->field[i].bits; 194 1.1 christos val |= ((code >> self->field[i].shift) 195 1.8 christos & (((uint64_t) 1 << bits) - 1)) << total; 196 1.1 christos total += bits; 197 1.1 christos } 198 1.1 christos /* sign extend: */ 199 1.8 christos sign = (uint64_t) 1 << (total - 1); 200 1.1 christos val = (val ^ sign) - sign; 201 1.1 christos 202 1.7 christos *valuep = val << scale; 203 1.1 christos return 0; 204 1.1 christos } 205 1.1 christos 206 1.1 christos static const char* 207 1.1 christos ins_imms (const struct ia64_operand *self, ia64_insn value, ia64_insn *code) 208 1.1 christos { 209 1.1 christos return ins_imms_scaled (self, value, code, 0); 210 1.1 christos } 211 1.1 christos 212 1.1 christos static const char* 213 1.1 christos ins_immsu4 (const struct ia64_operand *self, ia64_insn value, ia64_insn *code) 214 1.1 christos { 215 1.1 christos value = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000; 216 1.1 christos 217 1.1 christos return ins_imms_scaled (self, value, code, 0); 218 1.1 christos } 219 1.1 christos 220 1.1 christos static const char* 221 1.1 christos ext_imms (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep) 222 1.1 christos { 223 1.1 christos return ext_imms_scaled (self, code, valuep, 0); 224 1.1 christos } 225 1.1 christos 226 1.1 christos static const char* 227 1.1 christos ins_immsm1 (const struct ia64_operand *self, ia64_insn value, ia64_insn *code) 228 1.1 christos { 229 1.1 christos --value; 230 1.1 christos return ins_imms_scaled (self, value, code, 0); 231 1.1 christos } 232 1.1 christos 233 1.1 christos static const char* 234 1.1 christos ins_immsm1u4 (const struct ia64_operand *self, ia64_insn value, 235 1.1 christos ia64_insn *code) 236 1.1 christos { 237 1.1 christos value = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000; 238 1.1 christos 239 1.1 christos --value; 240 1.1 christos return ins_imms_scaled (self, value, code, 0); 241 1.1 christos } 242 1.1 christos 243 1.1 christos static const char* 244 1.1 christos ext_immsm1 (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep) 245 1.1 christos { 246 1.1 christos const char *res = ext_imms_scaled (self, code, valuep, 0); 247 1.1 christos 248 1.1 christos ++*valuep; 249 1.1 christos return res; 250 1.1 christos } 251 1.1 christos 252 1.1 christos static const char* 253 1.1 christos ins_imms1 (const struct ia64_operand *self, ia64_insn value, ia64_insn *code) 254 1.1 christos { 255 1.1 christos return ins_imms_scaled (self, value, code, 1); 256 1.1 christos } 257 1.1 christos 258 1.1 christos static const char* 259 1.1 christos ext_imms1 (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep) 260 1.1 christos { 261 1.1 christos return ext_imms_scaled (self, code, valuep, 1); 262 1.1 christos } 263 1.1 christos 264 1.1 christos static const char* 265 1.1 christos ins_imms4 (const struct ia64_operand *self, ia64_insn value, ia64_insn *code) 266 1.1 christos { 267 1.1 christos return ins_imms_scaled (self, value, code, 4); 268 1.1 christos } 269 1.1 christos 270 1.1 christos static const char* 271 1.1 christos ext_imms4 (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep) 272 1.1 christos { 273 1.1 christos return ext_imms_scaled (self, code, valuep, 4); 274 1.1 christos } 275 1.1 christos 276 1.1 christos static const char* 277 1.1 christos ins_imms16 (const struct ia64_operand *self, ia64_insn value, ia64_insn *code) 278 1.1 christos { 279 1.1 christos return ins_imms_scaled (self, value, code, 16); 280 1.1 christos } 281 1.1 christos 282 1.1 christos static const char* 283 1.1 christos ext_imms16 (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep) 284 1.1 christos { 285 1.1 christos return ext_imms_scaled (self, code, valuep, 16); 286 1.1 christos } 287 1.1 christos 288 1.1 christos static const char* 289 1.1 christos ins_cimmu (const struct ia64_operand *self, ia64_insn value, ia64_insn *code) 290 1.1 christos { 291 1.1 christos ia64_insn mask = (((ia64_insn) 1) << self->field[0].bits) - 1; 292 1.1 christos return ins_immu (self, value ^ mask, code); 293 1.1 christos } 294 1.1 christos 295 1.1 christos static const char* 296 1.1 christos ext_cimmu (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep) 297 1.1 christos { 298 1.1 christos const char *result; 299 1.1 christos ia64_insn mask; 300 1.1 christos 301 1.1 christos mask = (((ia64_insn) 1) << self->field[0].bits) - 1; 302 1.1 christos result = ext_immu (self, code, valuep); 303 1.1 christos if (!result) 304 1.1 christos { 305 1.1 christos mask = (((ia64_insn) 1) << self->field[0].bits) - 1; 306 1.1 christos *valuep ^= mask; 307 1.1 christos } 308 1.1 christos return result; 309 1.1 christos } 310 1.1 christos 311 1.1 christos static const char* 312 1.1 christos ins_cnt (const struct ia64_operand *self, ia64_insn value, ia64_insn *code) 313 1.1 christos { 314 1.1 christos --value; 315 1.8 christos if (value >= (uint64_t) 1 << self->field[0].bits) 316 1.1 christos return "count out of range"; 317 1.1 christos 318 1.1 christos *code |= value << self->field[0].shift; 319 1.1 christos return 0; 320 1.1 christos } 321 1.1 christos 322 1.1 christos static const char* 323 1.1 christos ext_cnt (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep) 324 1.1 christos { 325 1.1 christos *valuep = ((code >> self->field[0].shift) 326 1.8 christos & (((uint64_t) 1 << self->field[0].bits) - 1)) + 1; 327 1.1 christos return 0; 328 1.1 christos } 329 1.1 christos 330 1.1 christos static const char* 331 1.1 christos ins_cnt2b (const struct ia64_operand *self, ia64_insn value, ia64_insn *code) 332 1.1 christos { 333 1.1 christos --value; 334 1.1 christos 335 1.1 christos if (value > 2) 336 1.1 christos return "count must be in range 1..3"; 337 1.1 christos 338 1.1 christos *code |= value << self->field[0].shift; 339 1.1 christos return 0; 340 1.1 christos } 341 1.1 christos 342 1.1 christos static const char* 343 1.1 christos ext_cnt2b (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep) 344 1.1 christos { 345 1.1 christos *valuep = ((code >> self->field[0].shift) & 0x3) + 1; 346 1.1 christos return 0; 347 1.1 christos } 348 1.1 christos 349 1.1 christos static const char* 350 1.1 christos ins_cnt2c (const struct ia64_operand *self, ia64_insn value, ia64_insn *code) 351 1.1 christos { 352 1.1 christos switch (value) 353 1.1 christos { 354 1.1 christos case 0: value = 0; break; 355 1.1 christos case 7: value = 1; break; 356 1.1 christos case 15: value = 2; break; 357 1.1 christos case 16: value = 3; break; 358 1.1 christos default: return "count must be 0, 7, 15, or 16"; 359 1.1 christos } 360 1.1 christos *code |= value << self->field[0].shift; 361 1.1 christos return 0; 362 1.1 christos } 363 1.1 christos 364 1.1 christos static const char* 365 1.1 christos ext_cnt2c (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep) 366 1.1 christos { 367 1.1 christos ia64_insn value; 368 1.1 christos 369 1.1 christos value = (code >> self->field[0].shift) & 0x3; 370 1.1 christos switch (value) 371 1.1 christos { 372 1.1 christos case 0: value = 0; break; 373 1.1 christos case 1: value = 7; break; 374 1.1 christos case 2: value = 15; break; 375 1.1 christos case 3: value = 16; break; 376 1.1 christos } 377 1.1 christos *valuep = value; 378 1.1 christos return 0; 379 1.1 christos } 380 1.1 christos 381 1.1 christos static const char* 382 1.1 christos ins_cnt6a (const struct ia64_operand *self, ia64_insn value, 383 1.1 christos ia64_insn *code) 384 1.1 christos { 385 1.1 christos if (value < 1 || value > 64) 386 1.1 christos return "value must be between 1 and 64"; 387 1.1 christos return ins_immu (self, value - 1, code); 388 1.1 christos } 389 1.1 christos 390 1.1 christos static const char* 391 1.1 christos ext_cnt6a (const struct ia64_operand *self, ia64_insn code, 392 1.1 christos ia64_insn *valuep) 393 1.1 christos { 394 1.1 christos const char *result; 395 1.1 christos 396 1.1 christos result = ext_immu (self, code, valuep); 397 1.1 christos if (result) 398 1.1 christos return result; 399 1.1 christos 400 1.1 christos *valuep = *valuep + 1; 401 1.1 christos return 0; 402 1.1 christos } 403 1.1 christos 404 1.1 christos static const char* 405 1.1 christos ins_strd5b (const struct ia64_operand *self, ia64_insn value, 406 1.1 christos ia64_insn *code) 407 1.1 christos { 408 1.1 christos if ( value & 0x3f ) 409 1.1 christos return "value must be a multiple of 64"; 410 1.1 christos return ins_imms_scaled (self, value, code, 6); 411 1.1 christos } 412 1.1 christos 413 1.1 christos static const char* 414 1.1 christos ext_strd5b (const struct ia64_operand *self, ia64_insn code, 415 1.1 christos ia64_insn *valuep) 416 1.1 christos { 417 1.1 christos return ext_imms_scaled (self, code, valuep, 6); 418 1.1 christos } 419 1.1 christos 420 1.1 christos 421 1.1 christos static const char* 422 1.1 christos ins_inc3 (const struct ia64_operand *self, ia64_insn value, ia64_insn *code) 423 1.1 christos { 424 1.8 christos int64_t val = value; 425 1.8 christos uint64_t sign = 0; 426 1.1 christos 427 1.1 christos if (val < 0) 428 1.1 christos { 429 1.1 christos sign = 0x4; 430 1.1 christos value = -value; 431 1.1 christos } 432 1.1 christos switch (value) 433 1.1 christos { 434 1.1 christos case 1: value = 3; break; 435 1.1 christos case 4: value = 2; break; 436 1.1 christos case 8: value = 1; break; 437 1.1 christos case 16: value = 0; break; 438 1.1 christos default: return "count must be +/- 1, 4, 8, or 16"; 439 1.1 christos } 440 1.1 christos *code |= (sign | value) << self->field[0].shift; 441 1.1 christos return 0; 442 1.1 christos } 443 1.1 christos 444 1.1 christos static const char* 445 1.1 christos ext_inc3 (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep) 446 1.1 christos { 447 1.8 christos int64_t val; 448 1.1 christos int negate; 449 1.1 christos 450 1.1 christos val = (code >> self->field[0].shift) & 0x7; 451 1.1 christos negate = val & 0x4; 452 1.1 christos switch (val & 0x3) 453 1.1 christos { 454 1.1 christos case 0: val = 16; break; 455 1.1 christos case 1: val = 8; break; 456 1.1 christos case 2: val = 4; break; 457 1.1 christos case 3: val = 1; break; 458 1.1 christos } 459 1.1 christos if (negate) 460 1.1 christos val = -val; 461 1.1 christos 462 1.1 christos *valuep = val; 463 1.1 christos return 0; 464 1.1 christos } 465 1.1 christos 466 1.1 christos #define CST IA64_OPND_CLASS_CST 467 1.1 christos #define REG IA64_OPND_CLASS_REG 468 1.1 christos #define IND IA64_OPND_CLASS_IND 469 1.1 christos #define ABS IA64_OPND_CLASS_ABS 470 1.1 christos #define REL IA64_OPND_CLASS_REL 471 1.1 christos 472 1.1 christos #define SDEC IA64_OPND_FLAG_DECIMAL_SIGNED 473 1.1 christos #define UDEC IA64_OPND_FLAG_DECIMAL_UNSIGNED 474 1.1 christos 475 1.1 christos const struct ia64_operand elf64_ia64_operands[IA64_OPND_COUNT] = 476 1.1 christos { 477 1.1 christos /* constants: */ 478 1.1 christos { CST, ins_const, ext_const, "NIL", {{ 0, 0}}, 0, "<none>" }, 479 1.1 christos { CST, ins_const, ext_const, "ar.csd", {{ 0, 0}}, 0, "ar.csd" }, 480 1.1 christos { CST, ins_const, ext_const, "ar.ccv", {{ 0, 0}}, 0, "ar.ccv" }, 481 1.1 christos { CST, ins_const, ext_const, "ar.pfs", {{ 0, 0}}, 0, "ar.pfs" }, 482 1.1 christos { CST, ins_const, ext_const, "1", {{ 0, 0}}, 0, "1" }, 483 1.1 christos { CST, ins_const, ext_const, "8", {{ 0, 0}}, 0, "8" }, 484 1.1 christos { CST, ins_const, ext_const, "16", {{ 0, 0}}, 0, "16" }, 485 1.1 christos { CST, ins_const, ext_const, "r0", {{ 0, 0}}, 0, "r0" }, 486 1.1 christos { CST, ins_const, ext_const, "ip", {{ 0, 0}}, 0, "ip" }, 487 1.1 christos { CST, ins_const, ext_const, "pr", {{ 0, 0}}, 0, "pr" }, 488 1.1 christos { CST, ins_const, ext_const, "pr.rot", {{ 0, 0}}, 0, "pr.rot" }, 489 1.1 christos { CST, ins_const, ext_const, "psr", {{ 0, 0}}, 0, "psr" }, 490 1.1 christos { CST, ins_const, ext_const, "psr.l", {{ 0, 0}}, 0, "psr.l" }, 491 1.1 christos { CST, ins_const, ext_const, "psr.um", {{ 0, 0}}, 0, "psr.um" }, 492 1.1 christos 493 1.1 christos /* register operands: */ 494 1.1 christos { REG, ins_reg, ext_reg, "ar", {{ 7, 20}}, 0, /* AR3 */ 495 1.1 christos "an application register" }, 496 1.1 christos { REG, ins_reg, ext_reg, "b", {{ 3, 6}}, 0, /* B1 */ 497 1.1 christos "a branch register" }, 498 1.1 christos { REG, ins_reg, ext_reg, "b", {{ 3, 13}}, 0, /* B2 */ 499 1.1 christos "a branch register"}, 500 1.1 christos { REG, ins_reg, ext_reg, "cr", {{ 7, 20}}, 0, /* CR */ 501 1.1 christos "a control register"}, 502 1.1 christos { REG, ins_reg, ext_reg, "f", {{ 7, 6}}, 0, /* F1 */ 503 1.1 christos "a floating-point register" }, 504 1.1 christos { REG, ins_reg, ext_reg, "f", {{ 7, 13}}, 0, /* F2 */ 505 1.1 christos "a floating-point register" }, 506 1.1 christos { REG, ins_reg, ext_reg, "f", {{ 7, 20}}, 0, /* F3 */ 507 1.1 christos "a floating-point register" }, 508 1.1 christos { REG, ins_reg, ext_reg, "f", {{ 7, 27}}, 0, /* F4 */ 509 1.1 christos "a floating-point register" }, 510 1.1 christos { REG, ins_reg, ext_reg, "p", {{ 6, 6}}, 0, /* P1 */ 511 1.1 christos "a predicate register" }, 512 1.1 christos { REG, ins_reg, ext_reg, "p", {{ 6, 27}}, 0, /* P2 */ 513 1.1 christos "a predicate register" }, 514 1.1 christos { REG, ins_reg, ext_reg, "r", {{ 7, 6}}, 0, /* R1 */ 515 1.1 christos "a general register" }, 516 1.1 christos { REG, ins_reg, ext_reg, "r", {{ 7, 13}}, 0, /* R2 */ 517 1.1 christos "a general register" }, 518 1.1 christos { REG, ins_reg, ext_reg, "r", {{ 7, 20}}, 0, /* R3 */ 519 1.1 christos "a general register" }, 520 1.1 christos { REG, ins_reg, ext_reg, "r", {{ 2, 20}}, 0, /* R3_2 */ 521 1.1 christos "a general register r0-r3" }, 522 1.1 christos { REG, ins_reg, ext_reg, "dahr", {{ 3, 23}}, 0, /* DAHR */ 523 1.1 christos "a dahr register dahr0-7" }, 524 1.1 christos 525 1.1 christos /* memory operands: */ 526 1.1 christos { IND, ins_reg, ext_reg, "", {{7, 20}}, 0, /* MR3 */ 527 1.1 christos "a memory address" }, 528 1.1 christos 529 1.1 christos /* indirect operands: */ 530 1.1 christos { IND, ins_reg, ext_reg, "cpuid", {{7, 20}}, 0, /* CPUID_R3 */ 531 1.1 christos "a cpuid register" }, 532 1.1 christos { IND, ins_reg, ext_reg, "dbr", {{7, 20}}, 0, /* DBR_R3 */ 533 1.1 christos "a dbr register" }, 534 1.1 christos { IND, ins_reg, ext_reg, "dtr", {{7, 20}}, 0, /* DTR_R3 */ 535 1.1 christos "a dtr register" }, 536 1.1 christos { IND, ins_reg, ext_reg, "itr", {{7, 20}}, 0, /* ITR_R3 */ 537 1.1 christos "an itr register" }, 538 1.1 christos { IND, ins_reg, ext_reg, "ibr", {{7, 20}}, 0, /* IBR_R3 */ 539 1.1 christos "an ibr register" }, 540 1.1 christos { IND, ins_reg, ext_reg, "msr", {{7, 20}}, 0, /* MSR_R3 */ 541 1.1 christos "an msr register" }, 542 1.1 christos { IND, ins_reg, ext_reg, "pkr", {{7, 20}}, 0, /* PKR_R3 */ 543 1.1 christos "a pkr register" }, 544 1.1 christos { IND, ins_reg, ext_reg, "pmc", {{7, 20}}, 0, /* PMC_R3 */ 545 1.1 christos "a pmc register" }, 546 1.1 christos { IND, ins_reg, ext_reg, "pmd", {{7, 20}}, 0, /* PMD_R3 */ 547 1.1 christos "a pmd register" }, 548 1.1 christos { IND, ins_reg, ext_reg, "dahr", {{7, 20}}, 0, /* DAHR_R3 */ 549 1.1 christos "a dahr register" }, 550 1.1 christos { IND, ins_reg, ext_reg, "rr", {{7, 20}}, 0, /* RR_R3 */ 551 1.1 christos "an rr register" }, 552 1.1 christos 553 1.1 christos /* immediate operands: */ 554 1.1 christos { ABS, ins_cimmu, ext_cimmu, 0, {{ 5, 20 }}, UDEC, /* CCNT5 */ 555 1.1 christos "a 5-bit count (0-31)" }, 556 1.1 christos { ABS, ins_cnt, ext_cnt, 0, {{ 2, 27 }}, UDEC, /* CNT2a */ 557 1.1 christos "a 2-bit count (1-4)" }, 558 1.1 christos { ABS, ins_cnt2b, ext_cnt2b, 0, {{ 2, 27 }}, UDEC, /* CNT2b */ 559 1.1 christos "a 2-bit count (1-3)" }, 560 1.1 christos { ABS, ins_cnt2c, ext_cnt2c, 0, {{ 2, 30 }}, UDEC, /* CNT2c */ 561 1.1 christos "a count (0, 7, 15, or 16)" }, 562 1.1 christos { ABS, ins_immu, ext_immu, 0, {{ 5, 14}}, UDEC, /* CNT5 */ 563 1.1 christos "a 5-bit count (0-31)" }, 564 1.1 christos { ABS, ins_immu, ext_immu, 0, {{ 6, 27}}, UDEC, /* CNT6 */ 565 1.1 christos "a 6-bit count (0-63)" }, 566 1.1 christos { ABS, ins_cimmu, ext_cimmu, 0, {{ 6, 20}}, UDEC, /* CPOS6a */ 567 1.1 christos "a 6-bit bit pos (0-63)" }, 568 1.1 christos { ABS, ins_cimmu, ext_cimmu, 0, {{ 6, 14}}, UDEC, /* CPOS6b */ 569 1.1 christos "a 6-bit bit pos (0-63)" }, 570 1.1 christos { ABS, ins_cimmu, ext_cimmu, 0, {{ 6, 31}}, UDEC, /* CPOS6c */ 571 1.1 christos "a 6-bit bit pos (0-63)" }, 572 1.1 christos { ABS, ins_imms, ext_imms, 0, {{ 1, 36}}, SDEC, /* IMM1 */ 573 1.1 christos "a 1-bit integer (-1, 0)" }, 574 1.1 christos { ABS, ins_immu, ext_immu, 0, {{ 2, 13}}, UDEC, /* IMMU2 */ 575 1.1 christos "a 2-bit unsigned (0-3)" }, 576 1.1 christos { ABS, ins_immu5b, ext_immu5b, 0, {{ 5, 14}}, UDEC, /* IMMU5b */ 577 1.1 christos "a 5-bit unsigned (32 + (0-31))" }, 578 1.1 christos { ABS, ins_immu, ext_immu, 0, {{ 7, 13}}, 0, /* IMMU7a */ 579 1.1 christos "a 7-bit unsigned (0-127)" }, 580 1.1 christos { ABS, ins_immu, ext_immu, 0, {{ 7, 20}}, 0, /* IMMU7b */ 581 1.1 christos "a 7-bit unsigned (0-127)" }, 582 1.1 christos { ABS, ins_immu, ext_immu, 0, {{ 7, 13}}, UDEC, /* SOF */ 583 1.1 christos "a frame size (register count)" }, 584 1.1 christos { ABS, ins_immu, ext_immu, 0, {{ 7, 20}}, UDEC, /* SOL */ 585 1.1 christos "a local register count" }, 586 1.1 christos { ABS, ins_immus8,ext_immus8,0, {{ 4, 27}}, UDEC, /* SOR */ 587 1.1 christos "a rotating register count (integer multiple of 8)" }, 588 1.1 christos { ABS, ins_imms, ext_imms, 0, /* IMM8 */ 589 1.1 christos {{ 7, 13}, { 1, 36}}, SDEC, 590 1.1 christos "an 8-bit integer (-128-127)" }, 591 1.1 christos { ABS, ins_immsu4, ext_imms, 0, /* IMM8U4 */ 592 1.1 christos {{ 7, 13}, { 1, 36}}, SDEC, 593 1.1 christos "an 8-bit signed integer for 32-bit unsigned compare (-128-127)" }, 594 1.1 christos { ABS, ins_immsm1, ext_immsm1, 0, /* IMM8M1 */ 595 1.1 christos {{ 7, 13}, { 1, 36}}, SDEC, 596 1.1 christos "an 8-bit integer (-127-128)" }, 597 1.1 christos { ABS, ins_immsm1u4, ext_immsm1, 0, /* IMM8M1U4 */ 598 1.1 christos {{ 7, 13}, { 1, 36}}, SDEC, 599 1.1 christos "an 8-bit integer for 32-bit unsigned compare (-127-(-1),1-128,0x100000000)" }, 600 1.1 christos { ABS, ins_immsm1, ext_immsm1, 0, /* IMM8M1U8 */ 601 1.1 christos {{ 7, 13}, { 1, 36}}, SDEC, 602 1.1 christos "an 8-bit integer for 64-bit unsigned compare (-127-(-1),1-128,0x10000000000000000)" }, 603 1.1 christos { ABS, ins_immu, ext_immu, 0, {{ 2, 33}, { 7, 20}}, 0, /* IMMU9 */ 604 1.1 christos "a 9-bit unsigned (0-511)" }, 605 1.1 christos { ABS, ins_imms, ext_imms, 0, /* IMM9a */ 606 1.1 christos {{ 7, 6}, { 1, 27}, { 1, 36}}, SDEC, 607 1.1 christos "a 9-bit integer (-256-255)" }, 608 1.1 christos { ABS, ins_imms, ext_imms, 0, /* IMM9b */ 609 1.1 christos {{ 7, 13}, { 1, 27}, { 1, 36}}, SDEC, 610 1.1 christos "a 9-bit integer (-256-255)" }, 611 1.1 christos { ABS, ins_imms, ext_imms, 0, /* IMM14 */ 612 1.1 christos {{ 7, 13}, { 6, 27}, { 1, 36}}, SDEC, 613 1.1 christos "a 14-bit integer (-8192-8191)" }, 614 1.1 christos { ABS, ins_immu, ext_immu, 0, /* IMMU16 */ 615 1.1 christos {{4, 6}, {11, 12}, { 1, 36}}, UDEC, 616 1.1 christos "a 16-bit unsigned" }, 617 1.1 christos { ABS, ins_imms1, ext_imms1, 0, /* IMM17 */ 618 1.1 christos {{ 7, 6}, { 8, 24}, { 1, 36}}, 0, 619 1.1 christos "a 17-bit integer (-65536-65535)" }, 620 1.1 christos { ABS, ins_immu, ext_immu, 0, /* IMMU19 */ 621 1.1 christos {{4, 6}, {14, 12}, { 1, 36}}, UDEC, 622 1.1 christos "a 19-bit unsigned" }, 623 1.1 christos { ABS, ins_immu, ext_immu, 0, {{20, 6}, { 1, 36}}, 0, /* IMMU21 */ 624 1.1 christos "a 21-bit unsigned" }, 625 1.1 christos { ABS, ins_imms, ext_imms, 0, /* IMM22 */ 626 1.1 christos {{ 7, 13}, { 9, 27}, { 5, 22}, { 1, 36}}, SDEC, 627 1.1 christos "a 22-bit signed integer" }, 628 1.1 christos { ABS, ins_immu, ext_immu, 0, /* IMMU24 */ 629 1.1 christos {{21, 6}, { 2, 31}, { 1, 36}}, 0, 630 1.1 christos "a 24-bit unsigned" }, 631 1.1 christos { ABS, ins_imms16,ext_imms16,0, {{27, 6}, { 1, 36}}, 0, /* IMM44 */ 632 1.1 christos "a 44-bit unsigned (least 16 bits ignored/zeroes)" }, 633 1.1 christos { ABS, ins_rsvd, ext_rsvd, 0, {{0, 0}}, 0, /* IMMU62 */ 634 1.1 christos "a 62-bit unsigned" }, 635 1.1 christos { ABS, ins_rsvd, ext_rsvd, 0, {{0, 0}}, 0, /* IMMU64 */ 636 1.1 christos "a 64-bit unsigned" }, 637 1.1 christos { ABS, ins_inc3, ext_inc3, 0, {{ 3, 13}}, SDEC, /* INC3 */ 638 1.1 christos "an increment (+/- 1, 4, 8, or 16)" }, 639 1.1 christos { ABS, ins_cnt, ext_cnt, 0, {{ 4, 27}}, UDEC, /* LEN4 */ 640 1.1 christos "a 4-bit length (1-16)" }, 641 1.1 christos { ABS, ins_cnt, ext_cnt, 0, {{ 6, 27}}, UDEC, /* LEN6 */ 642 1.1 christos "a 6-bit length (1-64)" }, 643 1.1 christos { ABS, ins_immu, ext_immu, 0, {{ 4, 20}}, 0, /* MBTYPE4 */ 644 1.1 christos "a mix type (@rev, @mix, @shuf, @alt, or @brcst)" }, 645 1.1 christos { ABS, ins_immu, ext_immu, 0, {{ 8, 20}}, 0, /* MBTYPE8 */ 646 1.1 christos "an 8-bit mix type" }, 647 1.1 christos { ABS, ins_immu, ext_immu, 0, {{ 6, 14}}, UDEC, /* POS6 */ 648 1.1 christos "a 6-bit bit pos (0-63)" }, 649 1.1 christos { REL, ins_imms4, ext_imms4, 0, {{ 7, 6}, { 2, 33}}, 0, /* TAG13 */ 650 1.1 christos "a branch tag" }, 651 1.1 christos { REL, ins_imms4, ext_imms4, 0, {{ 9, 24}}, 0, /* TAG13b */ 652 1.1 christos "a branch tag" }, 653 1.1 christos { REL, ins_imms4, ext_imms4, 0, {{20, 6}, { 1, 36}}, 0, /* TGT25 */ 654 1.1 christos "a branch target" }, 655 1.1 christos { REL, ins_imms4, ext_imms4, 0, /* TGT25b */ 656 1.1 christos {{ 7, 6}, {13, 20}, { 1, 36}}, 0, 657 1.1 christos "a branch target" }, 658 1.1 christos { REL, ins_imms4, ext_imms4, 0, {{20, 13}, { 1, 36}}, 0, /* TGT25c */ 659 1.1 christos "a branch target" }, 660 1.6 christos { REL, ins_rsvd, ext_rsvd, 0, {{0, 0}}, 0, /* TGT64 */ 661 1.1 christos "a branch target" }, 662 1.1 christos 663 1.1 christos { ABS, ins_const, ext_const, 0, {{0, 0}}, 0, /* LDXMOV */ 664 1.1 christos "ldxmov target" }, 665 1.1 christos { ABS, ins_cnt6a, ext_cnt6a, 0, {{6, 6}}, UDEC, /* CNT6a */ 666 1.1 christos "lfetch count" }, 667 1.1 christos { ABS, ins_strd5b, ext_strd5b, 0, {{5, 13}}, SDEC, /* STRD5b*/ 668 1.1 christos "lfetch stride" }, 669 1.1 christos }; 670