1440a403fSchristos/* OpenRISC 1000 opcode support. -*- C -*- 2440a403fSchristos Copyright 2000-2014 Free Software Foundation, Inc. 3440a403fSchristos 4440a403fSchristos Originally ontributed for OR32 by Red Hat Inc; 5440a403fSchristos 6440a403fSchristos This file is part of the GNU Binutils. 7440a403fSchristos 8440a403fSchristos This program is free software; you can redistribute it and/or modify 9440a403fSchristos it under the terms of the GNU General Public License as published by 10440a403fSchristos the Free Software Foundation; either version 3 of the License, or 11440a403fSchristos (at your option) any later version. 12440a403fSchristos 13440a403fSchristos This program is distributed in the hope that it will be useful, 14440a403fSchristos but WITHOUT ANY WARRANTY; without even the implied warranty of 15440a403fSchristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16440a403fSchristos GNU General Public License for more details. 17440a403fSchristos 18440a403fSchristos You should have received a copy of the GNU General Public License 19440a403fSchristos along with this program; if not, see <http://www.gnu.org/licenses/>. */ 20440a403fSchristos 21440a403fSchristos/* This file is an addendum to or1k.cpu. Heavy use of C code isn't 22440a403fSchristos appropriate in .cpu files, so it resides here. This especially applies 23440a403fSchristos to assembly/disassembly where parsing/printing can be quite involved. 24440a403fSchristos Such things aren't really part of the specification of the cpu, per se, 25440a403fSchristos so .cpu files provide the general framework and .opc files handle the 26440a403fSchristos nitty-gritty details as necessary. 27440a403fSchristos 28440a403fSchristos Each section is delimited with start and end markers. 29440a403fSchristos 30440a403fSchristos <arch>-opc.h additions use: "-- opc.h" 31440a403fSchristos <arch>-opc.c additions use: "-- opc.c" 32440a403fSchristos <arch>-asm.c additions use: "-- asm.c" 33440a403fSchristos <arch>-dis.c additions use: "-- dis.c" 34440a403fSchristos <arch>-ibd.h additions use: "-- ibd.h" */ 35440a403fSchristos 36440a403fSchristos/* -- opc.h */ 37440a403fSchristos 38440a403fSchristos#undef CGEN_DIS_HASH_SIZE 39440a403fSchristos#define CGEN_DIS_HASH_SIZE 256 40440a403fSchristos#undef CGEN_DIS_HASH 41440a403fSchristos#define CGEN_DIS_HASH(buffer, value) (((unsigned char *) (buffer))[0] >> 2) 42440a403fSchristos 43*b88e3e88Schristos/* Check applicability of instructions against machines. */ 44*b88e3e88Schristos#define CGEN_VALIDATE_INSN_SUPPORTED 45*b88e3e88Schristos 46*b88e3e88Schristosextern int or1k_cgen_insn_supported (CGEN_CPU_DESC, const CGEN_INSN *); 47*b88e3e88Schristos 48440a403fSchristos/* -- */ 49440a403fSchristos 50440a403fSchristos/* -- opc.c */ 51*b88e3e88Schristos 52*b88e3e88Schristos/* Special check to ensure that instruction exists for given machine. */ 53*b88e3e88Schristos 54*b88e3e88Schristosint 55*b88e3e88Schristosor1k_cgen_insn_supported (CGEN_CPU_DESC cd, const CGEN_INSN *insn) 56*b88e3e88Schristos{ 57*b88e3e88Schristos int machs = CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_MACH); 58*b88e3e88Schristos 59*b88e3e88Schristos /* No mach attribute? Assume it's supported for all machs. */ 60*b88e3e88Schristos if (machs == 0) 61*b88e3e88Schristos return 1; 62*b88e3e88Schristos 63*b88e3e88Schristos return ((machs & cd->machs) != 0); 64*b88e3e88Schristos} 65*b88e3e88Schristos 66440a403fSchristos/* -- */ 67440a403fSchristos 68440a403fSchristos/* -- asm.c */ 69440a403fSchristos 70440a403fSchristosstatic const char * MISSING_CLOSING_PARENTHESIS = N_("missing `)'"); 71*b88e3e88Schristosstatic const char * INVALID_STORE_RELOC = N_("relocation invalid for store"); 72*b88e3e88Schristosstatic const char * INVALID_RELOC_TYPE = N_("internal relocation type invalid"); 73440a403fSchristos 74440a403fSchristos#define CGEN_VERBOSE_ASSEMBLER_ERRORS 75440a403fSchristos 76440a403fSchristosstatic const char * 77440a403fSchristosparse_disp26 (CGEN_CPU_DESC cd, 78440a403fSchristos const char ** strp, 79440a403fSchristos int opindex, 80*b88e3e88Schristos int opinfo ATTRIBUTE_UNUSED, 81440a403fSchristos enum cgen_parse_operand_result * resultp, 82440a403fSchristos bfd_vma * valuep) 83440a403fSchristos{ 84*b88e3e88Schristos const char *str = *strp; 85440a403fSchristos const char *errmsg = NULL; 86*b88e3e88Schristos bfd_reloc_code_real_type reloc = BFD_RELOC_OR1K_REL_26; 87440a403fSchristos 88*b88e3e88Schristos if (strncasecmp (str, "plta(", 5) == 0) 89440a403fSchristos { 90*b88e3e88Schristos *strp = str + 5; 91*b88e3e88Schristos reloc = BFD_RELOC_OR1K_PLTA26; 92440a403fSchristos } 93*b88e3e88Schristos else if (strncasecmp (str, "plt(", 4) == 0) 94*b88e3e88Schristos { 95*b88e3e88Schristos *strp = str + 4; 96*b88e3e88Schristos reloc = BFD_RELOC_OR1K_PLT26; 97*b88e3e88Schristos } 98*b88e3e88Schristos 99*b88e3e88Schristos errmsg = cgen_parse_address (cd, strp, opindex, reloc, resultp, valuep); 100*b88e3e88Schristos 101*b88e3e88Schristos if (reloc != BFD_RELOC_OR1K_REL_26) 102*b88e3e88Schristos { 103*b88e3e88Schristos if (**strp != ')') 104*b88e3e88Schristos errmsg = MISSING_CLOSING_PARENTHESIS; 105*b88e3e88Schristos else 106*b88e3e88Schristos ++*strp; 107*b88e3e88Schristos } 108*b88e3e88Schristos 109*b88e3e88Schristos return errmsg; 110440a403fSchristos} 111440a403fSchristos 112440a403fSchristosstatic const char * 113*b88e3e88Schristosparse_disp21 (CGEN_CPU_DESC cd, 114*b88e3e88Schristos const char ** strp, 115*b88e3e88Schristos int opindex, 116*b88e3e88Schristos int opinfo ATTRIBUTE_UNUSED, 117*b88e3e88Schristos enum cgen_parse_operand_result * resultp, 118*b88e3e88Schristos bfd_vma * valuep) 119*b88e3e88Schristos{ 120*b88e3e88Schristos const char *str = *strp; 121*b88e3e88Schristos const char *errmsg = NULL; 122*b88e3e88Schristos bfd_reloc_code_real_type reloc = BFD_RELOC_OR1K_PCREL_PG21; 123*b88e3e88Schristos 124*b88e3e88Schristos if (strncasecmp (str, "got(", 4) == 0) 125*b88e3e88Schristos { 126*b88e3e88Schristos *strp = str + 4; 127*b88e3e88Schristos reloc = BFD_RELOC_OR1K_GOT_PG21; 128*b88e3e88Schristos } 129*b88e3e88Schristos else if (strncasecmp (str, "tlsgd(", 6) == 0) 130*b88e3e88Schristos { 131*b88e3e88Schristos *strp = str + 6; 132*b88e3e88Schristos reloc = BFD_RELOC_OR1K_TLS_GD_PG21; 133*b88e3e88Schristos } 134*b88e3e88Schristos else if (strncasecmp (str, "tlsldm(", 7) == 0) 135*b88e3e88Schristos { 136*b88e3e88Schristos *strp = str + 7; 137*b88e3e88Schristos reloc = BFD_RELOC_OR1K_TLS_LDM_PG21; 138*b88e3e88Schristos } 139*b88e3e88Schristos else if (strncasecmp (str, "gottp(", 6) == 0) 140*b88e3e88Schristos { 141*b88e3e88Schristos *strp = str + 6; 142*b88e3e88Schristos reloc = BFD_RELOC_OR1K_TLS_IE_PG21; 143*b88e3e88Schristos } 144*b88e3e88Schristos 145*b88e3e88Schristos errmsg = cgen_parse_address (cd, strp, opindex, reloc, resultp, valuep); 146*b88e3e88Schristos 147*b88e3e88Schristos if (reloc != BFD_RELOC_OR1K_PCREL_PG21) 148*b88e3e88Schristos { 149*b88e3e88Schristos if (**strp != ')') 150*b88e3e88Schristos errmsg = MISSING_CLOSING_PARENTHESIS; 151*b88e3e88Schristos else 152*b88e3e88Schristos ++*strp; 153*b88e3e88Schristos } 154*b88e3e88Schristos 155*b88e3e88Schristos return errmsg; 156*b88e3e88Schristos} 157*b88e3e88Schristos 158*b88e3e88Schristosenum or1k_rclass 159*b88e3e88Schristos{ 160*b88e3e88Schristos RCLASS_DIRECT = 0, 161*b88e3e88Schristos RCLASS_GOT = 1, 162*b88e3e88Schristos RCLASS_GOTPC = 2, 163*b88e3e88Schristos RCLASS_GOTOFF = 3, 164*b88e3e88Schristos RCLASS_TLSGD = 4, 165*b88e3e88Schristos RCLASS_TLSLDM = 5, 166*b88e3e88Schristos RCLASS_DTPOFF = 6, 167*b88e3e88Schristos RCLASS_GOTTPOFF = 7, 168*b88e3e88Schristos RCLASS_TPOFF = 8, 169*b88e3e88Schristos}; 170*b88e3e88Schristos 171*b88e3e88Schristosenum or1k_rtype 172*b88e3e88Schristos{ 173*b88e3e88Schristos RTYPE_LO = 0, 174*b88e3e88Schristos RTYPE_SLO = 1, 175*b88e3e88Schristos RTYPE_PO = 2, 176*b88e3e88Schristos RTYPE_SPO = 3, 177*b88e3e88Schristos RTYPE_HI = 4, 178*b88e3e88Schristos RTYPE_AHI = 5, 179*b88e3e88Schristos}; 180*b88e3e88Schristos 181*b88e3e88Schristos#define RCLASS_SHIFT 3 182*b88e3e88Schristos#define RTYPE_MASK 7 183*b88e3e88Schristos 184*b88e3e88Schristosstatic const bfd_reloc_code_real_type or1k_imm16_relocs[][6] = { 185*b88e3e88Schristos { BFD_RELOC_LO16, 186*b88e3e88Schristos BFD_RELOC_OR1K_SLO16, 187*b88e3e88Schristos BFD_RELOC_OR1K_LO13, 188*b88e3e88Schristos BFD_RELOC_OR1K_SLO13, 189*b88e3e88Schristos BFD_RELOC_HI16, 190*b88e3e88Schristos BFD_RELOC_HI16_S, }, 191*b88e3e88Schristos { BFD_RELOC_OR1K_GOT16, 192*b88e3e88Schristos BFD_RELOC_UNUSED, 193*b88e3e88Schristos BFD_RELOC_OR1K_GOT_LO13, 194*b88e3e88Schristos BFD_RELOC_UNUSED, 195*b88e3e88Schristos BFD_RELOC_UNUSED, 196*b88e3e88Schristos BFD_RELOC_UNUSED }, 197*b88e3e88Schristos { BFD_RELOC_OR1K_GOTPC_LO16, 198*b88e3e88Schristos BFD_RELOC_UNUSED, 199*b88e3e88Schristos BFD_RELOC_UNUSED, 200*b88e3e88Schristos BFD_RELOC_UNUSED, 201*b88e3e88Schristos BFD_RELOC_OR1K_GOTPC_HI16, 202*b88e3e88Schristos BFD_RELOC_UNUSED }, 203*b88e3e88Schristos { BFD_RELOC_LO16_GOTOFF, 204*b88e3e88Schristos BFD_RELOC_OR1K_GOTOFF_SLO16, 205*b88e3e88Schristos BFD_RELOC_UNUSED, 206*b88e3e88Schristos BFD_RELOC_UNUSED, 207*b88e3e88Schristos BFD_RELOC_HI16_GOTOFF, 208*b88e3e88Schristos BFD_RELOC_HI16_S_GOTOFF }, 209*b88e3e88Schristos { BFD_RELOC_OR1K_TLS_GD_LO16, 210*b88e3e88Schristos BFD_RELOC_UNUSED, 211*b88e3e88Schristos BFD_RELOC_OR1K_TLS_GD_LO13, 212*b88e3e88Schristos BFD_RELOC_UNUSED, 213*b88e3e88Schristos BFD_RELOC_OR1K_TLS_GD_HI16, 214*b88e3e88Schristos BFD_RELOC_UNUSED }, 215*b88e3e88Schristos { BFD_RELOC_OR1K_TLS_LDM_LO16, 216*b88e3e88Schristos BFD_RELOC_UNUSED, 217*b88e3e88Schristos BFD_RELOC_OR1K_TLS_LDM_LO13, 218*b88e3e88Schristos BFD_RELOC_UNUSED, 219*b88e3e88Schristos BFD_RELOC_OR1K_TLS_LDM_HI16, 220*b88e3e88Schristos BFD_RELOC_UNUSED }, 221*b88e3e88Schristos { BFD_RELOC_OR1K_TLS_LDO_LO16, 222*b88e3e88Schristos BFD_RELOC_UNUSED, 223*b88e3e88Schristos BFD_RELOC_UNUSED, 224*b88e3e88Schristos BFD_RELOC_UNUSED, 225*b88e3e88Schristos BFD_RELOC_OR1K_TLS_LDO_HI16, 226*b88e3e88Schristos BFD_RELOC_UNUSED }, 227*b88e3e88Schristos { BFD_RELOC_OR1K_TLS_IE_LO16, 228*b88e3e88Schristos BFD_RELOC_UNUSED, 229*b88e3e88Schristos BFD_RELOC_OR1K_TLS_IE_LO13, 230*b88e3e88Schristos BFD_RELOC_UNUSED, 231*b88e3e88Schristos BFD_RELOC_OR1K_TLS_IE_HI16, 232*b88e3e88Schristos BFD_RELOC_OR1K_TLS_IE_AHI16 }, 233*b88e3e88Schristos { BFD_RELOC_OR1K_TLS_LE_LO16, 234*b88e3e88Schristos BFD_RELOC_OR1K_TLS_LE_SLO16, 235*b88e3e88Schristos BFD_RELOC_UNUSED, 236*b88e3e88Schristos BFD_RELOC_UNUSED, 237*b88e3e88Schristos BFD_RELOC_OR1K_TLS_LE_HI16, 238*b88e3e88Schristos BFD_RELOC_OR1K_TLS_LE_AHI16 }, 239*b88e3e88Schristos}; 240*b88e3e88Schristos 241*b88e3e88Schristosstatic int 242*b88e3e88Schristosparse_reloc (const char **strp) 243*b88e3e88Schristos{ 244*b88e3e88Schristos const char *str = *strp; 245*b88e3e88Schristos enum or1k_rclass cls = RCLASS_DIRECT; 246*b88e3e88Schristos enum or1k_rtype typ; 247*b88e3e88Schristos 248*b88e3e88Schristos if (strncasecmp (str, "got(", 4) == 0) 249*b88e3e88Schristos { 250*b88e3e88Schristos *strp = str + 4; 251*b88e3e88Schristos return (RCLASS_GOT << RCLASS_SHIFT) | RTYPE_LO; 252*b88e3e88Schristos } 253*b88e3e88Schristos if (strncasecmp (str, "gotpo(", 6) == 0) 254*b88e3e88Schristos { 255*b88e3e88Schristos *strp = str + 6; 256*b88e3e88Schristos return (RCLASS_GOT << RCLASS_SHIFT) | RTYPE_PO; 257*b88e3e88Schristos } 258*b88e3e88Schristos if (strncasecmp (str, "gottppo(", 8) == 0) 259*b88e3e88Schristos { 260*b88e3e88Schristos *strp = str + 8; 261*b88e3e88Schristos return (RCLASS_GOTTPOFF << RCLASS_SHIFT) | RTYPE_PO; 262*b88e3e88Schristos } 263*b88e3e88Schristos 264*b88e3e88Schristos if (strncasecmp (str, "gotpc", 5) == 0) 265*b88e3e88Schristos { 266*b88e3e88Schristos str += 5; 267*b88e3e88Schristos cls = RCLASS_GOTPC; 268*b88e3e88Schristos } 269*b88e3e88Schristos else if (strncasecmp (str, "gotoff", 6) == 0) 270*b88e3e88Schristos { 271*b88e3e88Schristos str += 6; 272*b88e3e88Schristos cls = RCLASS_GOTOFF; 273*b88e3e88Schristos } 274*b88e3e88Schristos else if (strncasecmp (str, "tlsgd", 5) == 0) 275*b88e3e88Schristos { 276*b88e3e88Schristos str += 5; 277*b88e3e88Schristos cls = RCLASS_TLSGD; 278*b88e3e88Schristos } 279*b88e3e88Schristos else if (strncasecmp (str, "tlsldm", 6) == 0) 280*b88e3e88Schristos { 281*b88e3e88Schristos str += 6; 282*b88e3e88Schristos cls = RCLASS_TLSLDM; 283*b88e3e88Schristos } 284*b88e3e88Schristos else if (strncasecmp (str, "dtpoff", 6) == 0) 285*b88e3e88Schristos { 286*b88e3e88Schristos str += 6; 287*b88e3e88Schristos cls = RCLASS_DTPOFF; 288*b88e3e88Schristos } 289*b88e3e88Schristos else if (strncasecmp (str, "gottpoff", 8) == 0) 290*b88e3e88Schristos { 291*b88e3e88Schristos str += 8; 292*b88e3e88Schristos cls = RCLASS_GOTTPOFF; 293*b88e3e88Schristos } 294*b88e3e88Schristos else if (strncasecmp (str, "tpoff", 5) == 0) 295*b88e3e88Schristos { 296*b88e3e88Schristos str += 5; 297*b88e3e88Schristos cls = RCLASS_TPOFF; 298*b88e3e88Schristos } 299*b88e3e88Schristos 300*b88e3e88Schristos if (strncasecmp (str, "hi(", 3) == 0) 301*b88e3e88Schristos { 302*b88e3e88Schristos str += 3; 303*b88e3e88Schristos typ = RTYPE_HI; 304*b88e3e88Schristos } 305*b88e3e88Schristos else if (strncasecmp (str, "lo(", 3) == 0) 306*b88e3e88Schristos { 307*b88e3e88Schristos str += 3; 308*b88e3e88Schristos typ = RTYPE_LO; 309*b88e3e88Schristos } 310*b88e3e88Schristos else if (strncasecmp (str, "ha(", 3) == 0) 311*b88e3e88Schristos { 312*b88e3e88Schristos str += 3; 313*b88e3e88Schristos typ = RTYPE_AHI; 314*b88e3e88Schristos } 315*b88e3e88Schristos else if (strncasecmp (str, "po(", 3) == 0 && cls != RCLASS_GOTTPOFF) 316*b88e3e88Schristos { 317*b88e3e88Schristos str += 3; 318*b88e3e88Schristos typ = RTYPE_PO; 319*b88e3e88Schristos } 320*b88e3e88Schristos else 321*b88e3e88Schristos return -1; 322*b88e3e88Schristos 323*b88e3e88Schristos *strp = str; 324*b88e3e88Schristos return (cls << RCLASS_SHIFT) | typ; 325*b88e3e88Schristos} 326*b88e3e88Schristos 327*b88e3e88Schristosstatic const char * 328*b88e3e88Schristosparse_imm16 (CGEN_CPU_DESC cd, const char **strp, int opindex, 329*b88e3e88Schristos long *valuep, int splitp) 330440a403fSchristos{ 331440a403fSchristos const char *errmsg; 332440a403fSchristos enum cgen_parse_operand_result result_type; 333*b88e3e88Schristos bfd_reloc_code_real_type reloc = BFD_RELOC_UNUSED; 334*b88e3e88Schristos enum or1k_rtype reloc_type; 335*b88e3e88Schristos int reloc_code; 336*b88e3e88Schristos bfd_vma ret; 337440a403fSchristos 338440a403fSchristos if (**strp == '#') 339440a403fSchristos ++*strp; 340440a403fSchristos 341*b88e3e88Schristos reloc_code = parse_reloc (strp); 342*b88e3e88Schristos reloc_type = reloc_code & RTYPE_MASK; 343*b88e3e88Schristos if (reloc_code >= 0) 344*b88e3e88Schristos { 345*b88e3e88Schristos enum or1k_rclass reloc_class = reloc_code >> RCLASS_SHIFT; 346*b88e3e88Schristos if (splitp) 347*b88e3e88Schristos { 348*b88e3e88Schristos if ((reloc_type == RTYPE_LO || reloc_type == RTYPE_PO) 349*b88e3e88Schristos && reloc_class != RCLASS_GOT) 350*b88e3e88Schristos /* If split we or up the type to RTYPE_SLO or RTYPE_SPO. */ 351*b88e3e88Schristos reloc_type |= 1; 352*b88e3e88Schristos else 353*b88e3e88Schristos return INVALID_STORE_RELOC; 354*b88e3e88Schristos } 355*b88e3e88Schristos reloc = or1k_imm16_relocs[reloc_class][reloc_type]; 356*b88e3e88Schristos } 357*b88e3e88Schristos 358*b88e3e88Schristos if (reloc != BFD_RELOC_UNUSED) 359440a403fSchristos { 360440a403fSchristos bfd_vma value; 361440a403fSchristos 362*b88e3e88Schristos errmsg = cgen_parse_address (cd, strp, opindex, reloc, 363440a403fSchristos &result_type, &value); 364440a403fSchristos if (**strp != ')') 365440a403fSchristos errmsg = MISSING_CLOSING_PARENTHESIS; 366440a403fSchristos ++*strp; 367440a403fSchristos 368440a403fSchristos ret = value; 369440a403fSchristos 370*b88e3e88Schristos if (errmsg == NULL && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) 371*b88e3e88Schristos switch (reloc_type) 372440a403fSchristos { 373*b88e3e88Schristos case RTYPE_AHI: 374*b88e3e88Schristos ret += 0x8000; 375*b88e3e88Schristos /* FALLTHRU */ 376*b88e3e88Schristos case RTYPE_HI: 377440a403fSchristos ret >>= 16; 378*b88e3e88Schristos /* FALLTHRU */ 379*b88e3e88Schristos case RTYPE_LO: 380*b88e3e88Schristos case RTYPE_SLO: 381440a403fSchristos ret &= 0xffff; 382440a403fSchristos ret = (ret ^ 0x8000) - 0x8000; 383*b88e3e88Schristos break; 384*b88e3e88Schristos case RTYPE_PO: 385*b88e3e88Schristos case RTYPE_SPO: 386*b88e3e88Schristos ret &= 0x1fff; 387*b88e3e88Schristos break; 388*b88e3e88Schristos default: 389*b88e3e88Schristos errmsg = INVALID_RELOC_TYPE; 390440a403fSchristos } 391440a403fSchristos } 392440a403fSchristos else 393440a403fSchristos { 394440a403fSchristos long value; 395440a403fSchristos errmsg = cgen_parse_signed_integer (cd, strp, opindex, &value); 396440a403fSchristos ret = value; 397440a403fSchristos } 398440a403fSchristos 399440a403fSchristos if (errmsg == NULL) 400440a403fSchristos *valuep = ret; 401440a403fSchristos 402440a403fSchristos return errmsg; 403440a403fSchristos} 404440a403fSchristos 405440a403fSchristosstatic const char * 406*b88e3e88Schristosparse_simm16 (CGEN_CPU_DESC cd, const char **strp, int opindex, long *valuep) 407440a403fSchristos{ 408*b88e3e88Schristos return parse_imm16(cd, strp, opindex, (long *) valuep, 0); 409*b88e3e88Schristos} 410440a403fSchristos 411*b88e3e88Schristosstatic const char * 412*b88e3e88Schristosparse_simm16_split (CGEN_CPU_DESC cd, const char **strp, int opindex, 413*b88e3e88Schristos long *valuep) 414*b88e3e88Schristos{ 415*b88e3e88Schristos return parse_imm16(cd, strp, opindex, (long *) valuep, 1); 416*b88e3e88Schristos} 417*b88e3e88Schristos 418*b88e3e88Schristosstatic const char * 419*b88e3e88Schristosparse_uimm16 (CGEN_CPU_DESC cd, const char **strp, int opindex, 420*b88e3e88Schristos unsigned long *valuep) 421*b88e3e88Schristos{ 422*b88e3e88Schristos const char *errmsg = parse_imm16(cd, strp, opindex, (long *) valuep, 0); 423440a403fSchristos if (errmsg == NULL) 424440a403fSchristos *valuep &= 0xffff; 425440a403fSchristos return errmsg; 426440a403fSchristos} 427440a403fSchristos 428*b88e3e88Schristosstatic const char * 429*b88e3e88Schristosparse_uimm16_split (CGEN_CPU_DESC cd, const char **strp, int opindex, 430*b88e3e88Schristos unsigned long *valuep) 431*b88e3e88Schristos{ 432*b88e3e88Schristos const char *errmsg = parse_imm16(cd, strp, opindex, (long *) valuep, 1); 433*b88e3e88Schristos if (errmsg == NULL) 434*b88e3e88Schristos *valuep &= 0xffff; 435*b88e3e88Schristos return errmsg; 436*b88e3e88Schristos} 437*b88e3e88Schristos 438*b88e3e88Schristos/* Parse register pairs with syntax rA,rB to a flag + rA value. */ 439*b88e3e88Schristos 440*b88e3e88Schristosstatic const char * 441*b88e3e88Schristosparse_regpair (CGEN_CPU_DESC cd, const char **strp, 442*b88e3e88Schristos int opindex ATTRIBUTE_UNUSED, unsigned long *valuep) 443*b88e3e88Schristos{ 444*b88e3e88Schristos long reg1_index; 445*b88e3e88Schristos long reg2_index; 446*b88e3e88Schristos const char *errmsg; 447*b88e3e88Schristos 448*b88e3e88Schristos /* The first part should just be a register. */ 449*b88e3e88Schristos errmsg = cgen_parse_keyword (cd, strp, &or1k_cgen_opval_h_gpr, 450*b88e3e88Schristos ®1_index); 451*b88e3e88Schristos 452*b88e3e88Schristos /* If that worked skip the comma separator. */ 453*b88e3e88Schristos if (errmsg == NULL) 454*b88e3e88Schristos { 455*b88e3e88Schristos if (**strp == ',') 456*b88e3e88Schristos ++*strp; 457*b88e3e88Schristos else 458*b88e3e88Schristos errmsg = "Unexpected character, expected ','"; 459*b88e3e88Schristos } 460*b88e3e88Schristos 461*b88e3e88Schristos /* If that worked the next part is just another register. */ 462*b88e3e88Schristos if (errmsg == NULL) 463*b88e3e88Schristos errmsg = cgen_parse_keyword (cd, strp, &or1k_cgen_opval_h_gpr, 464*b88e3e88Schristos ®2_index); 465*b88e3e88Schristos 466*b88e3e88Schristos /* Validate the register pair is valid and create the output value. */ 467*b88e3e88Schristos if (errmsg == NULL) 468*b88e3e88Schristos { 469*b88e3e88Schristos int regoffset = reg2_index - reg1_index; 470*b88e3e88Schristos 471*b88e3e88Schristos if (regoffset == 1 || regoffset == 2) 472*b88e3e88Schristos { 473*b88e3e88Schristos unsigned short offsetmask; 474*b88e3e88Schristos unsigned short value; 475*b88e3e88Schristos 476*b88e3e88Schristos offsetmask = ((regoffset == 2 ? 1 : 0) << 5); 477*b88e3e88Schristos value = offsetmask | reg1_index; 478*b88e3e88Schristos 479*b88e3e88Schristos *valuep = value; 480*b88e3e88Schristos } 481*b88e3e88Schristos else 482*b88e3e88Schristos errmsg = "Invalid register pair, offset not 1 or 2."; 483*b88e3e88Schristos } 484*b88e3e88Schristos 485*b88e3e88Schristos return errmsg; 486*b88e3e88Schristos} 487*b88e3e88Schristos 488*b88e3e88Schristos/* -- */ 489*b88e3e88Schristos 490*b88e3e88Schristos/* -- dis.c */ 491*b88e3e88Schristos 492*b88e3e88Schristosstatic void 493*b88e3e88Schristosprint_regpair (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, 494*b88e3e88Schristos void * dis_info, 495*b88e3e88Schristos long value, 496*b88e3e88Schristos unsigned int attrs ATTRIBUTE_UNUSED, 497*b88e3e88Schristos bfd_vma pc ATTRIBUTE_UNUSED, 498*b88e3e88Schristos int length ATTRIBUTE_UNUSED) 499*b88e3e88Schristos{ 500*b88e3e88Schristos disassemble_info *info = dis_info; 501*b88e3e88Schristos char reg1_index; 502*b88e3e88Schristos char reg2_index; 503*b88e3e88Schristos 504*b88e3e88Schristos reg1_index = value & 0x1f; 505*b88e3e88Schristos reg2_index = reg1_index + ((value & (1 << 5)) ? 2 : 1); 506*b88e3e88Schristos 507*b88e3e88Schristos (*info->fprintf_func) (info->stream, "r%d,r%d", reg1_index, reg2_index); 508*b88e3e88Schristos} 509*b88e3e88Schristos 510440a403fSchristos/* -- */ 511440a403fSchristos 512440a403fSchristos/* -- ibd.h */ 513440a403fSchristos 514440a403fSchristos/* -- */ 515