116dce513Schristos/* OpenRISC 1000 opcode support. -*- C -*- 216dce513Schristos Copyright 2000-2014 Free Software Foundation, Inc. 316dce513Schristos 416dce513Schristos Originally ontributed for OR32 by Red Hat Inc; 516dce513Schristos 616dce513Schristos This file is part of the GNU Binutils. 716dce513Schristos 816dce513Schristos This program is free software; you can redistribute it and/or modify 916dce513Schristos it under the terms of the GNU General Public License as published by 1016dce513Schristos the Free Software Foundation; either version 3 of the License, or 1116dce513Schristos (at your option) any later version. 1216dce513Schristos 1316dce513Schristos This program is distributed in the hope that it will be useful, 1416dce513Schristos but WITHOUT ANY WARRANTY; without even the implied warranty of 1516dce513Schristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1616dce513Schristos GNU General Public License for more details. 1716dce513Schristos 1816dce513Schristos You should have received a copy of the GNU General Public License 1916dce513Schristos along with this program; if not, see <http://www.gnu.org/licenses/>. */ 2016dce513Schristos 2116dce513Schristos/* This file is an addendum to or1k.cpu. Heavy use of C code isn't 2216dce513Schristos appropriate in .cpu files, so it resides here. This especially applies 2316dce513Schristos to assembly/disassembly where parsing/printing can be quite involved. 2416dce513Schristos Such things aren't really part of the specification of the cpu, per se, 2516dce513Schristos so .cpu files provide the general framework and .opc files handle the 2616dce513Schristos nitty-gritty details as necessary. 2716dce513Schristos 2816dce513Schristos Each section is delimited with start and end markers. 2916dce513Schristos 3016dce513Schristos <arch>-opc.h additions use: "-- opc.h" 3116dce513Schristos <arch>-opc.c additions use: "-- opc.c" 3216dce513Schristos <arch>-asm.c additions use: "-- asm.c" 3316dce513Schristos <arch>-dis.c additions use: "-- dis.c" 3416dce513Schristos <arch>-ibd.h additions use: "-- ibd.h" */ 3516dce513Schristos 3616dce513Schristos/* -- opc.h */ 3716dce513Schristos 3816dce513Schristos#undef CGEN_DIS_HASH_SIZE 3916dce513Schristos#define CGEN_DIS_HASH_SIZE 256 4016dce513Schristos#undef CGEN_DIS_HASH 4116dce513Schristos#define CGEN_DIS_HASH(buffer, value) (((unsigned char *) (buffer))[0] >> 2) 4216dce513Schristos 43012573ebSchristos/* Check applicability of instructions against machines. */ 44012573ebSchristos#define CGEN_VALIDATE_INSN_SUPPORTED 45012573ebSchristos 46012573ebSchristosextern int or1k_cgen_insn_supported (CGEN_CPU_DESC, const CGEN_INSN *); 47012573ebSchristos 4816dce513Schristos/* -- */ 4916dce513Schristos 5016dce513Schristos/* -- opc.c */ 51012573ebSchristos 52012573ebSchristos/* Special check to ensure that instruction exists for given machine. */ 53012573ebSchristos 54012573ebSchristosint 55012573ebSchristosor1k_cgen_insn_supported (CGEN_CPU_DESC cd, const CGEN_INSN *insn) 56012573ebSchristos{ 57012573ebSchristos int machs = CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_MACH); 58012573ebSchristos 59012573ebSchristos /* No mach attribute? Assume it's supported for all machs. */ 60012573ebSchristos if (machs == 0) 61012573ebSchristos return 1; 62012573ebSchristos 63012573ebSchristos return ((machs & cd->machs) != 0); 64012573ebSchristos} 65012573ebSchristos 6616dce513Schristos/* -- */ 6716dce513Schristos 6816dce513Schristos/* -- asm.c */ 6916dce513Schristos 7016dce513Schristosstatic const char * MISSING_CLOSING_PARENTHESIS = N_("missing `)'"); 71012573ebSchristosstatic const char * INVALID_STORE_RELOC = N_("relocation invalid for store"); 72012573ebSchristosstatic const char * INVALID_RELOC_TYPE = N_("internal relocation type invalid"); 7316dce513Schristos 7416dce513Schristos#define CGEN_VERBOSE_ASSEMBLER_ERRORS 7516dce513Schristos 7616dce513Schristosstatic const char * 7716dce513Schristosparse_disp26 (CGEN_CPU_DESC cd, 7816dce513Schristos const char ** strp, 7916dce513Schristos int opindex, 80012573ebSchristos int opinfo ATTRIBUTE_UNUSED, 8116dce513Schristos enum cgen_parse_operand_result * resultp, 8216dce513Schristos bfd_vma * valuep) 8316dce513Schristos{ 84012573ebSchristos const char *str = *strp; 8516dce513Schristos const char *errmsg = NULL; 86012573ebSchristos bfd_reloc_code_real_type reloc = BFD_RELOC_OR1K_REL_26; 8716dce513Schristos 88012573ebSchristos if (strncasecmp (str, "plta(", 5) == 0) 8916dce513Schristos { 90012573ebSchristos *strp = str + 5; 91012573ebSchristos reloc = BFD_RELOC_OR1K_PLTA26; 9216dce513Schristos } 93012573ebSchristos else if (strncasecmp (str, "plt(", 4) == 0) 94012573ebSchristos { 95012573ebSchristos *strp = str + 4; 96012573ebSchristos reloc = BFD_RELOC_OR1K_PLT26; 97012573ebSchristos } 98012573ebSchristos 99012573ebSchristos errmsg = cgen_parse_address (cd, strp, opindex, reloc, resultp, valuep); 100012573ebSchristos 101012573ebSchristos if (reloc != BFD_RELOC_OR1K_REL_26) 102012573ebSchristos { 103012573ebSchristos if (**strp != ')') 104012573ebSchristos errmsg = MISSING_CLOSING_PARENTHESIS; 105012573ebSchristos else 106012573ebSchristos ++*strp; 107012573ebSchristos } 108012573ebSchristos 109012573ebSchristos return errmsg; 11016dce513Schristos} 11116dce513Schristos 11216dce513Schristosstatic const char * 113012573ebSchristosparse_disp21 (CGEN_CPU_DESC cd, 114012573ebSchristos const char ** strp, 115012573ebSchristos int opindex, 116012573ebSchristos int opinfo ATTRIBUTE_UNUSED, 117012573ebSchristos enum cgen_parse_operand_result * resultp, 118012573ebSchristos bfd_vma * valuep) 119012573ebSchristos{ 120012573ebSchristos const char *str = *strp; 121012573ebSchristos const char *errmsg = NULL; 122012573ebSchristos bfd_reloc_code_real_type reloc = BFD_RELOC_OR1K_PCREL_PG21; 123012573ebSchristos 124012573ebSchristos if (strncasecmp (str, "got(", 4) == 0) 125012573ebSchristos { 126012573ebSchristos *strp = str + 4; 127012573ebSchristos reloc = BFD_RELOC_OR1K_GOT_PG21; 128012573ebSchristos } 129012573ebSchristos else if (strncasecmp (str, "tlsgd(", 6) == 0) 130012573ebSchristos { 131012573ebSchristos *strp = str + 6; 132012573ebSchristos reloc = BFD_RELOC_OR1K_TLS_GD_PG21; 133012573ebSchristos } 134012573ebSchristos else if (strncasecmp (str, "tlsldm(", 7) == 0) 135012573ebSchristos { 136012573ebSchristos *strp = str + 7; 137012573ebSchristos reloc = BFD_RELOC_OR1K_TLS_LDM_PG21; 138012573ebSchristos } 139012573ebSchristos else if (strncasecmp (str, "gottp(", 6) == 0) 140012573ebSchristos { 141012573ebSchristos *strp = str + 6; 142012573ebSchristos reloc = BFD_RELOC_OR1K_TLS_IE_PG21; 143012573ebSchristos } 144012573ebSchristos 145012573ebSchristos errmsg = cgen_parse_address (cd, strp, opindex, reloc, resultp, valuep); 146012573ebSchristos 147012573ebSchristos if (reloc != BFD_RELOC_OR1K_PCREL_PG21) 148012573ebSchristos { 149012573ebSchristos if (**strp != ')') 150012573ebSchristos errmsg = MISSING_CLOSING_PARENTHESIS; 151012573ebSchristos else 152012573ebSchristos ++*strp; 153012573ebSchristos } 154012573ebSchristos 155012573ebSchristos return errmsg; 156012573ebSchristos} 157012573ebSchristos 158012573ebSchristosenum or1k_rclass 159012573ebSchristos{ 160012573ebSchristos RCLASS_DIRECT = 0, 161012573ebSchristos RCLASS_GOT = 1, 162012573ebSchristos RCLASS_GOTPC = 2, 163012573ebSchristos RCLASS_GOTOFF = 3, 164012573ebSchristos RCLASS_TLSGD = 4, 165012573ebSchristos RCLASS_TLSLDM = 5, 166012573ebSchristos RCLASS_DTPOFF = 6, 167012573ebSchristos RCLASS_GOTTPOFF = 7, 168012573ebSchristos RCLASS_TPOFF = 8, 169012573ebSchristos}; 170012573ebSchristos 171012573ebSchristosenum or1k_rtype 172012573ebSchristos{ 173012573ebSchristos RTYPE_LO = 0, 174012573ebSchristos RTYPE_SLO = 1, 175012573ebSchristos RTYPE_PO = 2, 176012573ebSchristos RTYPE_SPO = 3, 177012573ebSchristos RTYPE_HI = 4, 178012573ebSchristos RTYPE_AHI = 5, 179012573ebSchristos}; 180012573ebSchristos 181012573ebSchristos#define RCLASS_SHIFT 3 182012573ebSchristos#define RTYPE_MASK 7 183012573ebSchristos 184012573ebSchristosstatic const bfd_reloc_code_real_type or1k_imm16_relocs[][6] = { 185012573ebSchristos { BFD_RELOC_LO16, 186012573ebSchristos BFD_RELOC_OR1K_SLO16, 187012573ebSchristos BFD_RELOC_OR1K_LO13, 188012573ebSchristos BFD_RELOC_OR1K_SLO13, 189012573ebSchristos BFD_RELOC_HI16, 190012573ebSchristos BFD_RELOC_HI16_S, }, 191012573ebSchristos { BFD_RELOC_OR1K_GOT16, 192012573ebSchristos BFD_RELOC_UNUSED, 193012573ebSchristos BFD_RELOC_OR1K_GOT_LO13, 194012573ebSchristos BFD_RELOC_UNUSED, 195012573ebSchristos BFD_RELOC_UNUSED, 196*e992f068Schristos BFD_RELOC_OR1K_GOT_AHI16 }, 197012573ebSchristos { BFD_RELOC_OR1K_GOTPC_LO16, 198012573ebSchristos BFD_RELOC_UNUSED, 199012573ebSchristos BFD_RELOC_UNUSED, 200012573ebSchristos BFD_RELOC_UNUSED, 201012573ebSchristos BFD_RELOC_OR1K_GOTPC_HI16, 202012573ebSchristos BFD_RELOC_UNUSED }, 203012573ebSchristos { BFD_RELOC_LO16_GOTOFF, 204012573ebSchristos BFD_RELOC_OR1K_GOTOFF_SLO16, 205012573ebSchristos BFD_RELOC_UNUSED, 206012573ebSchristos BFD_RELOC_UNUSED, 207012573ebSchristos BFD_RELOC_HI16_GOTOFF, 208012573ebSchristos BFD_RELOC_HI16_S_GOTOFF }, 209012573ebSchristos { BFD_RELOC_OR1K_TLS_GD_LO16, 210012573ebSchristos BFD_RELOC_UNUSED, 211012573ebSchristos BFD_RELOC_OR1K_TLS_GD_LO13, 212012573ebSchristos BFD_RELOC_UNUSED, 213012573ebSchristos BFD_RELOC_OR1K_TLS_GD_HI16, 214012573ebSchristos BFD_RELOC_UNUSED }, 215012573ebSchristos { BFD_RELOC_OR1K_TLS_LDM_LO16, 216012573ebSchristos BFD_RELOC_UNUSED, 217012573ebSchristos BFD_RELOC_OR1K_TLS_LDM_LO13, 218012573ebSchristos BFD_RELOC_UNUSED, 219012573ebSchristos BFD_RELOC_OR1K_TLS_LDM_HI16, 220012573ebSchristos BFD_RELOC_UNUSED }, 221012573ebSchristos { BFD_RELOC_OR1K_TLS_LDO_LO16, 222012573ebSchristos BFD_RELOC_UNUSED, 223012573ebSchristos BFD_RELOC_UNUSED, 224012573ebSchristos BFD_RELOC_UNUSED, 225012573ebSchristos BFD_RELOC_OR1K_TLS_LDO_HI16, 226012573ebSchristos BFD_RELOC_UNUSED }, 227012573ebSchristos { BFD_RELOC_OR1K_TLS_IE_LO16, 228012573ebSchristos BFD_RELOC_UNUSED, 229012573ebSchristos BFD_RELOC_OR1K_TLS_IE_LO13, 230012573ebSchristos BFD_RELOC_UNUSED, 231012573ebSchristos BFD_RELOC_OR1K_TLS_IE_HI16, 232012573ebSchristos BFD_RELOC_OR1K_TLS_IE_AHI16 }, 233012573ebSchristos { BFD_RELOC_OR1K_TLS_LE_LO16, 234012573ebSchristos BFD_RELOC_OR1K_TLS_LE_SLO16, 235012573ebSchristos BFD_RELOC_UNUSED, 236012573ebSchristos BFD_RELOC_UNUSED, 237012573ebSchristos BFD_RELOC_OR1K_TLS_LE_HI16, 238012573ebSchristos BFD_RELOC_OR1K_TLS_LE_AHI16 }, 239012573ebSchristos}; 240012573ebSchristos 241012573ebSchristosstatic int 242012573ebSchristosparse_reloc (const char **strp) 243012573ebSchristos{ 244012573ebSchristos const char *str = *strp; 245012573ebSchristos enum or1k_rclass cls = RCLASS_DIRECT; 246012573ebSchristos enum or1k_rtype typ; 247012573ebSchristos 248012573ebSchristos if (strncasecmp (str, "got(", 4) == 0) 249012573ebSchristos { 250012573ebSchristos *strp = str + 4; 251012573ebSchristos return (RCLASS_GOT << RCLASS_SHIFT) | RTYPE_LO; 252012573ebSchristos } 253012573ebSchristos if (strncasecmp (str, "gotpo(", 6) == 0) 254012573ebSchristos { 255012573ebSchristos *strp = str + 6; 256012573ebSchristos return (RCLASS_GOT << RCLASS_SHIFT) | RTYPE_PO; 257012573ebSchristos } 258012573ebSchristos if (strncasecmp (str, "gottppo(", 8) == 0) 259012573ebSchristos { 260012573ebSchristos *strp = str + 8; 261012573ebSchristos return (RCLASS_GOTTPOFF << RCLASS_SHIFT) | RTYPE_PO; 262012573ebSchristos } 263012573ebSchristos 264012573ebSchristos if (strncasecmp (str, "gotpc", 5) == 0) 265012573ebSchristos { 266012573ebSchristos str += 5; 267012573ebSchristos cls = RCLASS_GOTPC; 268012573ebSchristos } 269012573ebSchristos else if (strncasecmp (str, "gotoff", 6) == 0) 270012573ebSchristos { 271012573ebSchristos str += 6; 272012573ebSchristos cls = RCLASS_GOTOFF; 273012573ebSchristos } 274012573ebSchristos else if (strncasecmp (str, "tlsgd", 5) == 0) 275012573ebSchristos { 276012573ebSchristos str += 5; 277012573ebSchristos cls = RCLASS_TLSGD; 278012573ebSchristos } 279012573ebSchristos else if (strncasecmp (str, "tlsldm", 6) == 0) 280012573ebSchristos { 281012573ebSchristos str += 6; 282012573ebSchristos cls = RCLASS_TLSLDM; 283012573ebSchristos } 284012573ebSchristos else if (strncasecmp (str, "dtpoff", 6) == 0) 285012573ebSchristos { 286012573ebSchristos str += 6; 287012573ebSchristos cls = RCLASS_DTPOFF; 288012573ebSchristos } 289012573ebSchristos else if (strncasecmp (str, "gottpoff", 8) == 0) 290012573ebSchristos { 291012573ebSchristos str += 8; 292012573ebSchristos cls = RCLASS_GOTTPOFF; 293012573ebSchristos } 294012573ebSchristos else if (strncasecmp (str, "tpoff", 5) == 0) 295012573ebSchristos { 296012573ebSchristos str += 5; 297012573ebSchristos cls = RCLASS_TPOFF; 298012573ebSchristos } 299*e992f068Schristos else if (strncasecmp (str, "got", 3) == 0) 300*e992f068Schristos { 301*e992f068Schristos str += 3; 302*e992f068Schristos cls = RCLASS_GOT; 303*e992f068Schristos } 304012573ebSchristos 305012573ebSchristos if (strncasecmp (str, "hi(", 3) == 0) 306012573ebSchristos { 307012573ebSchristos str += 3; 308012573ebSchristos typ = RTYPE_HI; 309012573ebSchristos } 310012573ebSchristos else if (strncasecmp (str, "lo(", 3) == 0) 311012573ebSchristos { 312012573ebSchristos str += 3; 313012573ebSchristos typ = RTYPE_LO; 314012573ebSchristos } 315012573ebSchristos else if (strncasecmp (str, "ha(", 3) == 0) 316012573ebSchristos { 317012573ebSchristos str += 3; 318012573ebSchristos typ = RTYPE_AHI; 319012573ebSchristos } 320012573ebSchristos else if (strncasecmp (str, "po(", 3) == 0 && cls != RCLASS_GOTTPOFF) 321012573ebSchristos { 322012573ebSchristos str += 3; 323012573ebSchristos typ = RTYPE_PO; 324012573ebSchristos } 325012573ebSchristos else 326012573ebSchristos return -1; 327012573ebSchristos 328012573ebSchristos *strp = str; 329012573ebSchristos return (cls << RCLASS_SHIFT) | typ; 330012573ebSchristos} 331012573ebSchristos 332012573ebSchristosstatic const char * 333012573ebSchristosparse_imm16 (CGEN_CPU_DESC cd, const char **strp, int opindex, 334012573ebSchristos long *valuep, int splitp) 33516dce513Schristos{ 33616dce513Schristos const char *errmsg; 33716dce513Schristos enum cgen_parse_operand_result result_type; 338012573ebSchristos bfd_reloc_code_real_type reloc = BFD_RELOC_UNUSED; 339012573ebSchristos enum or1k_rtype reloc_type; 340012573ebSchristos int reloc_code; 341012573ebSchristos bfd_vma ret; 34216dce513Schristos 34316dce513Schristos if (**strp == '#') 34416dce513Schristos ++*strp; 34516dce513Schristos 346012573ebSchristos reloc_code = parse_reloc (strp); 347012573ebSchristos reloc_type = reloc_code & RTYPE_MASK; 348012573ebSchristos if (reloc_code >= 0) 349012573ebSchristos { 350012573ebSchristos enum or1k_rclass reloc_class = reloc_code >> RCLASS_SHIFT; 351012573ebSchristos if (splitp) 352012573ebSchristos { 353012573ebSchristos if ((reloc_type == RTYPE_LO || reloc_type == RTYPE_PO) 354012573ebSchristos && reloc_class != RCLASS_GOT) 355012573ebSchristos /* If split we or up the type to RTYPE_SLO or RTYPE_SPO. */ 356012573ebSchristos reloc_type |= 1; 357012573ebSchristos else 358012573ebSchristos return INVALID_STORE_RELOC; 359012573ebSchristos } 360012573ebSchristos reloc = or1k_imm16_relocs[reloc_class][reloc_type]; 361012573ebSchristos } 362012573ebSchristos 363012573ebSchristos if (reloc != BFD_RELOC_UNUSED) 36416dce513Schristos { 36516dce513Schristos bfd_vma value; 36616dce513Schristos 367012573ebSchristos errmsg = cgen_parse_address (cd, strp, opindex, reloc, 36816dce513Schristos &result_type, &value); 36916dce513Schristos if (**strp != ')') 37016dce513Schristos errmsg = MISSING_CLOSING_PARENTHESIS; 37116dce513Schristos ++*strp; 37216dce513Schristos 37316dce513Schristos ret = value; 37416dce513Schristos 375012573ebSchristos if (errmsg == NULL && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) 376012573ebSchristos switch (reloc_type) 37716dce513Schristos { 378012573ebSchristos case RTYPE_AHI: 379012573ebSchristos ret += 0x8000; 380012573ebSchristos /* FALLTHRU */ 381012573ebSchristos case RTYPE_HI: 38216dce513Schristos ret >>= 16; 383012573ebSchristos /* FALLTHRU */ 384012573ebSchristos case RTYPE_LO: 385012573ebSchristos case RTYPE_SLO: 38616dce513Schristos ret &= 0xffff; 38716dce513Schristos ret = (ret ^ 0x8000) - 0x8000; 388012573ebSchristos break; 389012573ebSchristos case RTYPE_PO: 390012573ebSchristos case RTYPE_SPO: 391012573ebSchristos ret &= 0x1fff; 392012573ebSchristos break; 393012573ebSchristos default: 394012573ebSchristos errmsg = INVALID_RELOC_TYPE; 39516dce513Schristos } 39616dce513Schristos } 39716dce513Schristos else 39816dce513Schristos { 39916dce513Schristos long value; 40016dce513Schristos errmsg = cgen_parse_signed_integer (cd, strp, opindex, &value); 40116dce513Schristos ret = value; 40216dce513Schristos } 40316dce513Schristos 40416dce513Schristos if (errmsg == NULL) 40516dce513Schristos *valuep = ret; 40616dce513Schristos 40716dce513Schristos return errmsg; 40816dce513Schristos} 40916dce513Schristos 41016dce513Schristosstatic const char * 411012573ebSchristosparse_simm16 (CGEN_CPU_DESC cd, const char **strp, int opindex, long *valuep) 41216dce513Schristos{ 413012573ebSchristos return parse_imm16(cd, strp, opindex, (long *) valuep, 0); 414012573ebSchristos} 41516dce513Schristos 416012573ebSchristosstatic const char * 417012573ebSchristosparse_simm16_split (CGEN_CPU_DESC cd, const char **strp, int opindex, 418012573ebSchristos long *valuep) 419012573ebSchristos{ 420012573ebSchristos return parse_imm16(cd, strp, opindex, (long *) valuep, 1); 421012573ebSchristos} 422012573ebSchristos 423012573ebSchristosstatic const char * 424012573ebSchristosparse_uimm16 (CGEN_CPU_DESC cd, const char **strp, int opindex, 425012573ebSchristos unsigned long *valuep) 426012573ebSchristos{ 427012573ebSchristos const char *errmsg = parse_imm16(cd, strp, opindex, (long *) valuep, 0); 42816dce513Schristos if (errmsg == NULL) 42916dce513Schristos *valuep &= 0xffff; 43016dce513Schristos return errmsg; 43116dce513Schristos} 43216dce513Schristos 433012573ebSchristosstatic const char * 434012573ebSchristosparse_uimm16_split (CGEN_CPU_DESC cd, const char **strp, int opindex, 435012573ebSchristos unsigned long *valuep) 436012573ebSchristos{ 437012573ebSchristos const char *errmsg = parse_imm16(cd, strp, opindex, (long *) valuep, 1); 438012573ebSchristos if (errmsg == NULL) 439012573ebSchristos *valuep &= 0xffff; 440012573ebSchristos return errmsg; 441012573ebSchristos} 442012573ebSchristos 443012573ebSchristos/* Parse register pairs with syntax rA,rB to a flag + rA value. */ 444012573ebSchristos 445012573ebSchristosstatic const char * 446012573ebSchristosparse_regpair (CGEN_CPU_DESC cd, const char **strp, 447012573ebSchristos int opindex ATTRIBUTE_UNUSED, unsigned long *valuep) 448012573ebSchristos{ 449012573ebSchristos long reg1_index; 450012573ebSchristos long reg2_index; 451012573ebSchristos const char *errmsg; 452012573ebSchristos 453012573ebSchristos /* The first part should just be a register. */ 454012573ebSchristos errmsg = cgen_parse_keyword (cd, strp, &or1k_cgen_opval_h_gpr, 455012573ebSchristos ®1_index); 456012573ebSchristos 457012573ebSchristos /* If that worked skip the comma separator. */ 458012573ebSchristos if (errmsg == NULL) 459012573ebSchristos { 460012573ebSchristos if (**strp == ',') 461012573ebSchristos ++*strp; 462012573ebSchristos else 463012573ebSchristos errmsg = "Unexpected character, expected ','"; 464012573ebSchristos } 465012573ebSchristos 466012573ebSchristos /* If that worked the next part is just another register. */ 467012573ebSchristos if (errmsg == NULL) 468012573ebSchristos errmsg = cgen_parse_keyword (cd, strp, &or1k_cgen_opval_h_gpr, 469012573ebSchristos ®2_index); 470012573ebSchristos 471012573ebSchristos /* Validate the register pair is valid and create the output value. */ 472012573ebSchristos if (errmsg == NULL) 473012573ebSchristos { 474012573ebSchristos int regoffset = reg2_index - reg1_index; 475012573ebSchristos 476012573ebSchristos if (regoffset == 1 || regoffset == 2) 477012573ebSchristos { 478012573ebSchristos unsigned short offsetmask; 479012573ebSchristos unsigned short value; 480012573ebSchristos 481012573ebSchristos offsetmask = ((regoffset == 2 ? 1 : 0) << 5); 482012573ebSchristos value = offsetmask | reg1_index; 483012573ebSchristos 484012573ebSchristos *valuep = value; 485012573ebSchristos } 486012573ebSchristos else 487012573ebSchristos errmsg = "Invalid register pair, offset not 1 or 2."; 488012573ebSchristos } 489012573ebSchristos 490012573ebSchristos return errmsg; 491012573ebSchristos} 492012573ebSchristos 493012573ebSchristos/* -- */ 494012573ebSchristos 495012573ebSchristos/* -- dis.c */ 496012573ebSchristos 497012573ebSchristosstatic void 498012573ebSchristosprint_regpair (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, 499012573ebSchristos void * dis_info, 500012573ebSchristos long value, 501012573ebSchristos unsigned int attrs ATTRIBUTE_UNUSED, 502012573ebSchristos bfd_vma pc ATTRIBUTE_UNUSED, 503012573ebSchristos int length ATTRIBUTE_UNUSED) 504012573ebSchristos{ 505012573ebSchristos disassemble_info *info = dis_info; 506012573ebSchristos char reg1_index; 507012573ebSchristos char reg2_index; 508012573ebSchristos 509012573ebSchristos reg1_index = value & 0x1f; 510012573ebSchristos reg2_index = reg1_index + ((value & (1 << 5)) ? 2 : 1); 511012573ebSchristos 512012573ebSchristos (*info->fprintf_func) (info->stream, "r%d,r%d", reg1_index, reg2_index); 513012573ebSchristos} 514012573ebSchristos 51516dce513Schristos/* -- */ 51616dce513Schristos 51716dce513Schristos/* -- ibd.h */ 51816dce513Schristos 51916dce513Schristos/* -- */ 520