1 1.1 matt /* OpenRISC 1000 opcode support. -*- C -*- 2 1.1 matt Copyright 2000-2014 Free Software Foundation, Inc. 3 1.1 matt 4 1.1 matt Originally ontributed for OR32 by Red Hat Inc; 5 1.1 matt 6 1.1 matt This file is part of the GNU Binutils. 7 1.1 matt 8 1.1 matt This program is free software; you can redistribute it and/or modify 9 1.1 matt it under the terms of the GNU General Public License as published by 10 1.1 matt the Free Software Foundation; either version 3 of the License, or 11 1.1 matt (at your option) any later version. 12 1.1 matt 13 1.1 matt This program is distributed in the hope that it will be useful, 14 1.1 matt but WITHOUT ANY WARRANTY; without even the implied warranty of 15 1.1 matt MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 1.1 matt GNU General Public License for more details. 17 1.1 matt 18 1.1 matt You should have received a copy of the GNU General Public License 19 1.1 matt along with this program; if not, see <http://www.gnu.org/licenses/>. */ 20 1.1 matt 21 1.1 matt /* This file is an addendum to or1k.cpu. Heavy use of C code isn't 22 1.1 matt appropriate in .cpu files, so it resides here. This especially applies 23 1.1 matt to assembly/disassembly where parsing/printing can be quite involved. 24 1.1 matt Such things aren't really part of the specification of the cpu, per se, 25 1.1 matt so .cpu files provide the general framework and .opc files handle the 26 1.1 matt nitty-gritty details as necessary. 27 1.1 matt 28 1.1 matt Each section is delimited with start and end markers. 29 1.1 matt 30 1.1 matt <arch>-opc.h additions use: "-- opc.h" 31 1.1 matt <arch>-opc.c additions use: "-- opc.c" 32 1.1 matt <arch>-asm.c additions use: "-- asm.c" 33 1.1 matt <arch>-dis.c additions use: "-- dis.c" 34 1.1 matt <arch>-ibd.h additions use: "-- ibd.h" */ 35 1.1 matt 36 1.1 matt /* -- opc.h */ 37 1.1 matt 38 1.1 matt #undef CGEN_DIS_HASH_SIZE 39 1.1 matt #define CGEN_DIS_HASH_SIZE 256 40 1.1 matt #undef CGEN_DIS_HASH 41 1.4 christos #define CGEN_DIS_HASH(buffer, value) ((value >> 26) & 0xff) 42 1.1 matt 43 1.2 christos /* Check applicability of instructions against machines. */ 44 1.2 christos #define CGEN_VALIDATE_INSN_SUPPORTED 45 1.2 christos 46 1.2 christos extern int or1k_cgen_insn_supported (CGEN_CPU_DESC, const CGEN_INSN *); 47 1.2 christos 48 1.1 matt /* -- */ 49 1.1 matt 50 1.1 matt /* -- opc.c */ 51 1.2 christos 52 1.2 christos /* Special check to ensure that instruction exists for given machine. */ 53 1.2 christos 54 1.2 christos int 55 1.2 christos or1k_cgen_insn_supported (CGEN_CPU_DESC cd, const CGEN_INSN *insn) 56 1.2 christos { 57 1.2 christos int machs = CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_MACH); 58 1.2 christos 59 1.2 christos /* No mach attribute? Assume it's supported for all machs. */ 60 1.2 christos if (machs == 0) 61 1.2 christos return 1; 62 1.2 christos 63 1.2 christos return ((machs & cd->machs) != 0); 64 1.2 christos } 65 1.2 christos 66 1.1 matt /* -- */ 67 1.1 matt 68 1.1 matt /* -- asm.c */ 69 1.1 matt 70 1.1 matt static const char * MISSING_CLOSING_PARENTHESIS = N_("missing `)'"); 71 1.2 christos static const char * INVALID_STORE_RELOC = N_("relocation invalid for store"); 72 1.2 christos static const char * INVALID_RELOC_TYPE = N_("internal relocation type invalid"); 73 1.1 matt 74 1.1 matt #define CGEN_VERBOSE_ASSEMBLER_ERRORS 75 1.1 matt 76 1.1 matt static const char * 77 1.1 matt parse_disp26 (CGEN_CPU_DESC cd, 78 1.1 matt const char ** strp, 79 1.1 matt int opindex, 80 1.2 christos int opinfo ATTRIBUTE_UNUSED, 81 1.1 matt enum cgen_parse_operand_result * resultp, 82 1.1 matt bfd_vma * valuep) 83 1.1 matt { 84 1.2 christos const char *str = *strp; 85 1.1 matt const char *errmsg = NULL; 86 1.2 christos bfd_reloc_code_real_type reloc = BFD_RELOC_OR1K_REL_26; 87 1.1 matt 88 1.2 christos if (strncasecmp (str, "plta(", 5) == 0) 89 1.2 christos { 90 1.2 christos *strp = str + 5; 91 1.2 christos reloc = BFD_RELOC_OR1K_PLTA26; 92 1.2 christos } 93 1.2 christos else if (strncasecmp (str, "plt(", 4) == 0) 94 1.1 matt { 95 1.2 christos *strp = str + 4; 96 1.2 christos reloc = BFD_RELOC_OR1K_PLT26; 97 1.1 matt } 98 1.1 matt 99 1.2 christos errmsg = cgen_parse_address (cd, strp, opindex, reloc, resultp, valuep); 100 1.1 matt 101 1.2 christos if (reloc != BFD_RELOC_OR1K_REL_26) 102 1.1 matt { 103 1.1 matt if (**strp != ')') 104 1.1 matt errmsg = MISSING_CLOSING_PARENTHESIS; 105 1.2 christos else 106 1.2 christos ++*strp; 107 1.1 matt } 108 1.1 matt 109 1.2 christos return errmsg; 110 1.2 christos } 111 1.1 matt 112 1.2 christos static const char * 113 1.2 christos parse_disp21 (CGEN_CPU_DESC cd, 114 1.2 christos const char ** strp, 115 1.2 christos int opindex, 116 1.2 christos int opinfo ATTRIBUTE_UNUSED, 117 1.2 christos enum cgen_parse_operand_result * resultp, 118 1.2 christos bfd_vma * valuep) 119 1.2 christos { 120 1.2 christos const char *str = *strp; 121 1.2 christos const char *errmsg = NULL; 122 1.2 christos bfd_reloc_code_real_type reloc = BFD_RELOC_OR1K_PCREL_PG21; 123 1.1 matt 124 1.2 christos if (strncasecmp (str, "got(", 4) == 0) 125 1.2 christos { 126 1.2 christos *strp = str + 4; 127 1.2 christos reloc = BFD_RELOC_OR1K_GOT_PG21; 128 1.1 matt } 129 1.2 christos else if (strncasecmp (str, "tlsgd(", 6) == 0) 130 1.1 matt { 131 1.2 christos *strp = str + 6; 132 1.2 christos reloc = BFD_RELOC_OR1K_TLS_GD_PG21; 133 1.1 matt } 134 1.2 christos else if (strncasecmp (str, "tlsldm(", 7) == 0) 135 1.1 matt { 136 1.2 christos *strp = str + 7; 137 1.2 christos reloc = BFD_RELOC_OR1K_TLS_LDM_PG21; 138 1.1 matt } 139 1.2 christos else if (strncasecmp (str, "gottp(", 6) == 0) 140 1.1 matt { 141 1.2 christos *strp = str + 6; 142 1.2 christos reloc = BFD_RELOC_OR1K_TLS_IE_PG21; 143 1.1 matt } 144 1.1 matt 145 1.2 christos errmsg = cgen_parse_address (cd, strp, opindex, reloc, resultp, valuep); 146 1.1 matt 147 1.2 christos if (reloc != BFD_RELOC_OR1K_PCREL_PG21) 148 1.1 matt { 149 1.1 matt if (**strp != ')') 150 1.2 christos errmsg = MISSING_CLOSING_PARENTHESIS; 151 1.2 christos else 152 1.2 christos ++*strp; 153 1.1 matt } 154 1.1 matt 155 1.2 christos return errmsg; 156 1.2 christos } 157 1.1 matt 158 1.2 christos enum or1k_rclass 159 1.2 christos { 160 1.2 christos RCLASS_DIRECT = 0, 161 1.2 christos RCLASS_GOT = 1, 162 1.2 christos RCLASS_GOTPC = 2, 163 1.2 christos RCLASS_GOTOFF = 3, 164 1.2 christos RCLASS_TLSGD = 4, 165 1.2 christos RCLASS_TLSLDM = 5, 166 1.2 christos RCLASS_DTPOFF = 6, 167 1.2 christos RCLASS_GOTTPOFF = 7, 168 1.2 christos RCLASS_TPOFF = 8, 169 1.2 christos }; 170 1.1 matt 171 1.2 christos enum or1k_rtype 172 1.2 christos { 173 1.2 christos RTYPE_LO = 0, 174 1.2 christos RTYPE_SLO = 1, 175 1.2 christos RTYPE_PO = 2, 176 1.2 christos RTYPE_SPO = 3, 177 1.2 christos RTYPE_HI = 4, 178 1.2 christos RTYPE_AHI = 5, 179 1.2 christos }; 180 1.2 christos 181 1.2 christos #define RCLASS_SHIFT 3 182 1.2 christos #define RTYPE_MASK 7 183 1.2 christos 184 1.2 christos static const bfd_reloc_code_real_type or1k_imm16_relocs[][6] = { 185 1.2 christos { BFD_RELOC_LO16, 186 1.2 christos BFD_RELOC_OR1K_SLO16, 187 1.2 christos BFD_RELOC_OR1K_LO13, 188 1.2 christos BFD_RELOC_OR1K_SLO13, 189 1.2 christos BFD_RELOC_HI16, 190 1.2 christos BFD_RELOC_HI16_S, }, 191 1.2 christos { BFD_RELOC_OR1K_GOT16, 192 1.2 christos BFD_RELOC_UNUSED, 193 1.2 christos BFD_RELOC_OR1K_GOT_LO13, 194 1.2 christos BFD_RELOC_UNUSED, 195 1.2 christos BFD_RELOC_UNUSED, 196 1.3 christos BFD_RELOC_OR1K_GOT_AHI16 }, 197 1.2 christos { BFD_RELOC_OR1K_GOTPC_LO16, 198 1.2 christos BFD_RELOC_UNUSED, 199 1.2 christos BFD_RELOC_UNUSED, 200 1.2 christos BFD_RELOC_UNUSED, 201 1.2 christos BFD_RELOC_OR1K_GOTPC_HI16, 202 1.2 christos BFD_RELOC_UNUSED }, 203 1.2 christos { BFD_RELOC_LO16_GOTOFF, 204 1.2 christos BFD_RELOC_OR1K_GOTOFF_SLO16, 205 1.2 christos BFD_RELOC_UNUSED, 206 1.2 christos BFD_RELOC_UNUSED, 207 1.2 christos BFD_RELOC_HI16_GOTOFF, 208 1.2 christos BFD_RELOC_HI16_S_GOTOFF }, 209 1.2 christos { BFD_RELOC_OR1K_TLS_GD_LO16, 210 1.2 christos BFD_RELOC_UNUSED, 211 1.2 christos BFD_RELOC_OR1K_TLS_GD_LO13, 212 1.2 christos BFD_RELOC_UNUSED, 213 1.2 christos BFD_RELOC_OR1K_TLS_GD_HI16, 214 1.2 christos BFD_RELOC_UNUSED }, 215 1.2 christos { BFD_RELOC_OR1K_TLS_LDM_LO16, 216 1.2 christos BFD_RELOC_UNUSED, 217 1.2 christos BFD_RELOC_OR1K_TLS_LDM_LO13, 218 1.2 christos BFD_RELOC_UNUSED, 219 1.2 christos BFD_RELOC_OR1K_TLS_LDM_HI16, 220 1.2 christos BFD_RELOC_UNUSED }, 221 1.2 christos { BFD_RELOC_OR1K_TLS_LDO_LO16, 222 1.2 christos BFD_RELOC_UNUSED, 223 1.2 christos BFD_RELOC_UNUSED, 224 1.2 christos BFD_RELOC_UNUSED, 225 1.2 christos BFD_RELOC_OR1K_TLS_LDO_HI16, 226 1.2 christos BFD_RELOC_UNUSED }, 227 1.2 christos { BFD_RELOC_OR1K_TLS_IE_LO16, 228 1.2 christos BFD_RELOC_UNUSED, 229 1.2 christos BFD_RELOC_OR1K_TLS_IE_LO13, 230 1.2 christos BFD_RELOC_UNUSED, 231 1.2 christos BFD_RELOC_OR1K_TLS_IE_HI16, 232 1.2 christos BFD_RELOC_OR1K_TLS_IE_AHI16 }, 233 1.2 christos { BFD_RELOC_OR1K_TLS_LE_LO16, 234 1.2 christos BFD_RELOC_OR1K_TLS_LE_SLO16, 235 1.2 christos BFD_RELOC_UNUSED, 236 1.2 christos BFD_RELOC_UNUSED, 237 1.2 christos BFD_RELOC_OR1K_TLS_LE_HI16, 238 1.2 christos BFD_RELOC_OR1K_TLS_LE_AHI16 }, 239 1.2 christos }; 240 1.1 matt 241 1.2 christos static int 242 1.2 christos parse_reloc (const char **strp) 243 1.2 christos { 244 1.2 christos const char *str = *strp; 245 1.2 christos enum or1k_rclass cls = RCLASS_DIRECT; 246 1.2 christos enum or1k_rtype typ; 247 1.2 christos 248 1.2 christos if (strncasecmp (str, "got(", 4) == 0) 249 1.2 christos { 250 1.2 christos *strp = str + 4; 251 1.2 christos return (RCLASS_GOT << RCLASS_SHIFT) | RTYPE_LO; 252 1.2 christos } 253 1.2 christos if (strncasecmp (str, "gotpo(", 6) == 0) 254 1.2 christos { 255 1.2 christos *strp = str + 6; 256 1.2 christos return (RCLASS_GOT << RCLASS_SHIFT) | RTYPE_PO; 257 1.2 christos } 258 1.2 christos if (strncasecmp (str, "gottppo(", 8) == 0) 259 1.2 christos { 260 1.2 christos *strp = str + 8; 261 1.2 christos return (RCLASS_GOTTPOFF << RCLASS_SHIFT) | RTYPE_PO; 262 1.2 christos } 263 1.2 christos 264 1.2 christos if (strncasecmp (str, "gotpc", 5) == 0) 265 1.2 christos { 266 1.2 christos str += 5; 267 1.2 christos cls = RCLASS_GOTPC; 268 1.2 christos } 269 1.2 christos else if (strncasecmp (str, "gotoff", 6) == 0) 270 1.2 christos { 271 1.2 christos str += 6; 272 1.2 christos cls = RCLASS_GOTOFF; 273 1.2 christos } 274 1.2 christos else if (strncasecmp (str, "tlsgd", 5) == 0) 275 1.2 christos { 276 1.2 christos str += 5; 277 1.2 christos cls = RCLASS_TLSGD; 278 1.2 christos } 279 1.2 christos else if (strncasecmp (str, "tlsldm", 6) == 0) 280 1.2 christos { 281 1.2 christos str += 6; 282 1.2 christos cls = RCLASS_TLSLDM; 283 1.2 christos } 284 1.2 christos else if (strncasecmp (str, "dtpoff", 6) == 0) 285 1.2 christos { 286 1.2 christos str += 6; 287 1.2 christos cls = RCLASS_DTPOFF; 288 1.2 christos } 289 1.2 christos else if (strncasecmp (str, "gottpoff", 8) == 0) 290 1.2 christos { 291 1.2 christos str += 8; 292 1.2 christos cls = RCLASS_GOTTPOFF; 293 1.2 christos } 294 1.2 christos else if (strncasecmp (str, "tpoff", 5) == 0) 295 1.2 christos { 296 1.2 christos str += 5; 297 1.2 christos cls = RCLASS_TPOFF; 298 1.2 christos } 299 1.3 christos else if (strncasecmp (str, "got", 3) == 0) 300 1.3 christos { 301 1.3 christos str += 3; 302 1.3 christos cls = RCLASS_GOT; 303 1.3 christos } 304 1.2 christos 305 1.2 christos if (strncasecmp (str, "hi(", 3) == 0) 306 1.2 christos { 307 1.2 christos str += 3; 308 1.2 christos typ = RTYPE_HI; 309 1.2 christos } 310 1.2 christos else if (strncasecmp (str, "lo(", 3) == 0) 311 1.2 christos { 312 1.2 christos str += 3; 313 1.2 christos typ = RTYPE_LO; 314 1.2 christos } 315 1.2 christos else if (strncasecmp (str, "ha(", 3) == 0) 316 1.2 christos { 317 1.2 christos str += 3; 318 1.2 christos typ = RTYPE_AHI; 319 1.2 christos } 320 1.2 christos else if (strncasecmp (str, "po(", 3) == 0 && cls != RCLASS_GOTTPOFF) 321 1.2 christos { 322 1.2 christos str += 3; 323 1.2 christos typ = RTYPE_PO; 324 1.2 christos } 325 1.2 christos else 326 1.2 christos return -1; 327 1.1 matt 328 1.2 christos *strp = str; 329 1.2 christos return (cls << RCLASS_SHIFT) | typ; 330 1.2 christos } 331 1.1 matt 332 1.2 christos static const char * 333 1.2 christos parse_imm16 (CGEN_CPU_DESC cd, const char **strp, int opindex, 334 1.2 christos long *valuep, int splitp) 335 1.2 christos { 336 1.2 christos const char *errmsg; 337 1.2 christos enum cgen_parse_operand_result result_type; 338 1.2 christos bfd_reloc_code_real_type reloc = BFD_RELOC_UNUSED; 339 1.2 christos enum or1k_rtype reloc_type; 340 1.2 christos int reloc_code; 341 1.2 christos bfd_vma ret; 342 1.1 matt 343 1.2 christos if (**strp == '#') 344 1.2 christos ++*strp; 345 1.1 matt 346 1.2 christos reloc_code = parse_reloc (strp); 347 1.2 christos reloc_type = reloc_code & RTYPE_MASK; 348 1.2 christos if (reloc_code >= 0) 349 1.1 matt { 350 1.2 christos enum or1k_rclass reloc_class = reloc_code >> RCLASS_SHIFT; 351 1.2 christos if (splitp) 352 1.2 christos { 353 1.2 christos if ((reloc_type == RTYPE_LO || reloc_type == RTYPE_PO) 354 1.2 christos && reloc_class != RCLASS_GOT) 355 1.2 christos /* If split we or up the type to RTYPE_SLO or RTYPE_SPO. */ 356 1.2 christos reloc_type |= 1; 357 1.2 christos else 358 1.2 christos return INVALID_STORE_RELOC; 359 1.2 christos } 360 1.2 christos reloc = or1k_imm16_relocs[reloc_class][reloc_type]; 361 1.1 matt } 362 1.1 matt 363 1.2 christos if (reloc != BFD_RELOC_UNUSED) 364 1.1 matt { 365 1.1 matt bfd_vma value; 366 1.1 matt 367 1.2 christos errmsg = cgen_parse_address (cd, strp, opindex, reloc, 368 1.1 matt &result_type, &value); 369 1.1 matt if (**strp != ')') 370 1.2 christos errmsg = MISSING_CLOSING_PARENTHESIS; 371 1.1 matt ++*strp; 372 1.1 matt 373 1.2 christos ret = value; 374 1.1 matt 375 1.2 christos if (errmsg == NULL && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) 376 1.2 christos switch (reloc_type) 377 1.2 christos { 378 1.2 christos case RTYPE_AHI: 379 1.2 christos ret += 0x8000; 380 1.2 christos /* FALLTHRU */ 381 1.2 christos case RTYPE_HI: 382 1.2 christos ret >>= 16; 383 1.2 christos /* FALLTHRU */ 384 1.2 christos case RTYPE_LO: 385 1.2 christos case RTYPE_SLO: 386 1.2 christos ret &= 0xffff; 387 1.2 christos ret = (ret ^ 0x8000) - 0x8000; 388 1.2 christos break; 389 1.2 christos case RTYPE_PO: 390 1.2 christos case RTYPE_SPO: 391 1.2 christos ret &= 0x1fff; 392 1.2 christos break; 393 1.2 christos default: 394 1.2 christos errmsg = INVALID_RELOC_TYPE; 395 1.2 christos } 396 1.1 matt } 397 1.1 matt else 398 1.1 matt { 399 1.1 matt long value; 400 1.1 matt errmsg = cgen_parse_signed_integer (cd, strp, opindex, &value); 401 1.1 matt ret = value; 402 1.1 matt } 403 1.1 matt 404 1.1 matt if (errmsg == NULL) 405 1.1 matt *valuep = ret; 406 1.1 matt 407 1.1 matt return errmsg; 408 1.1 matt } 409 1.1 matt 410 1.1 matt static const char * 411 1.2 christos parse_simm16 (CGEN_CPU_DESC cd, const char **strp, int opindex, long *valuep) 412 1.1 matt { 413 1.2 christos return parse_imm16(cd, strp, opindex, (long *) valuep, 0); 414 1.2 christos } 415 1.2 christos 416 1.2 christos static const char * 417 1.2 christos parse_simm16_split (CGEN_CPU_DESC cd, const char **strp, int opindex, 418 1.2 christos long *valuep) 419 1.2 christos { 420 1.2 christos return parse_imm16(cd, strp, opindex, (long *) valuep, 1); 421 1.2 christos } 422 1.1 matt 423 1.2 christos static const char * 424 1.2 christos parse_uimm16 (CGEN_CPU_DESC cd, const char **strp, int opindex, 425 1.2 christos unsigned long *valuep) 426 1.2 christos { 427 1.2 christos const char *errmsg = parse_imm16(cd, strp, opindex, (long *) valuep, 0); 428 1.1 matt if (errmsg == NULL) 429 1.1 matt *valuep &= 0xffff; 430 1.1 matt return errmsg; 431 1.1 matt } 432 1.1 matt 433 1.2 christos static const char * 434 1.2 christos parse_uimm16_split (CGEN_CPU_DESC cd, const char **strp, int opindex, 435 1.2 christos unsigned long *valuep) 436 1.2 christos { 437 1.2 christos const char *errmsg = parse_imm16(cd, strp, opindex, (long *) valuep, 1); 438 1.2 christos if (errmsg == NULL) 439 1.2 christos *valuep &= 0xffff; 440 1.2 christos return errmsg; 441 1.2 christos } 442 1.2 christos 443 1.2 christos /* Parse register pairs with syntax rA,rB to a flag + rA value. */ 444 1.2 christos 445 1.2 christos static const char * 446 1.2 christos parse_regpair (CGEN_CPU_DESC cd, const char **strp, 447 1.2 christos int opindex ATTRIBUTE_UNUSED, unsigned long *valuep) 448 1.2 christos { 449 1.2 christos long reg1_index; 450 1.2 christos long reg2_index; 451 1.2 christos const char *errmsg; 452 1.2 christos 453 1.2 christos /* The first part should just be a register. */ 454 1.2 christos errmsg = cgen_parse_keyword (cd, strp, &or1k_cgen_opval_h_gpr, 455 1.2 christos ®1_index); 456 1.2 christos 457 1.2 christos /* If that worked skip the comma separator. */ 458 1.2 christos if (errmsg == NULL) 459 1.2 christos { 460 1.2 christos if (**strp == ',') 461 1.2 christos ++*strp; 462 1.2 christos else 463 1.2 christos errmsg = "Unexpected character, expected ','"; 464 1.2 christos } 465 1.2 christos 466 1.2 christos /* If that worked the next part is just another register. */ 467 1.2 christos if (errmsg == NULL) 468 1.2 christos errmsg = cgen_parse_keyword (cd, strp, &or1k_cgen_opval_h_gpr, 469 1.2 christos ®2_index); 470 1.2 christos 471 1.2 christos /* Validate the register pair is valid and create the output value. */ 472 1.2 christos if (errmsg == NULL) 473 1.2 christos { 474 1.2 christos int regoffset = reg2_index - reg1_index; 475 1.2 christos 476 1.2 christos if (regoffset == 1 || regoffset == 2) 477 1.2 christos { 478 1.2 christos unsigned short offsetmask; 479 1.2 christos unsigned short value; 480 1.2 christos 481 1.2 christos offsetmask = ((regoffset == 2 ? 1 : 0) << 5); 482 1.2 christos value = offsetmask | reg1_index; 483 1.2 christos 484 1.2 christos *valuep = value; 485 1.2 christos } 486 1.2 christos else 487 1.2 christos errmsg = "Invalid register pair, offset not 1 or 2."; 488 1.2 christos } 489 1.2 christos 490 1.2 christos return errmsg; 491 1.2 christos } 492 1.2 christos 493 1.2 christos /* -- */ 494 1.2 christos 495 1.2 christos /* -- dis.c */ 496 1.2 christos 497 1.2 christos static void 498 1.2 christos print_regpair (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, 499 1.2 christos void * dis_info, 500 1.2 christos long value, 501 1.2 christos unsigned int attrs ATTRIBUTE_UNUSED, 502 1.2 christos bfd_vma pc ATTRIBUTE_UNUSED, 503 1.2 christos int length ATTRIBUTE_UNUSED) 504 1.2 christos { 505 1.2 christos disassemble_info *info = dis_info; 506 1.2 christos char reg1_index; 507 1.2 christos char reg2_index; 508 1.2 christos 509 1.2 christos reg1_index = value & 0x1f; 510 1.2 christos reg2_index = reg1_index + ((value & (1 << 5)) ? 2 : 1); 511 1.2 christos 512 1.2 christos (*info->fprintf_func) (info->stream, "r%d,r%d", reg1_index, reg2_index); 513 1.2 christos } 514 1.2 christos 515 1.1 matt /* -- */ 516 1.1 matt 517 1.1 matt /* -- ibd.h */ 518 1.1 matt 519 1.1 matt /* -- */ 520