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