1*440a403fSchristos/* OpenRISC 1000 opcode support. -*- C -*- 2*440a403fSchristos Copyright 2000-2014 Free Software Foundation, Inc. 3*440a403fSchristos 4*440a403fSchristos Originally ontributed for OR32 by Red Hat Inc; 5*440a403fSchristos 6*440a403fSchristos This file is part of the GNU Binutils. 7*440a403fSchristos 8*440a403fSchristos This program is free software; you can redistribute it and/or modify 9*440a403fSchristos it under the terms of the GNU General Public License as published by 10*440a403fSchristos the Free Software Foundation; either version 3 of the License, or 11*440a403fSchristos (at your option) any later version. 12*440a403fSchristos 13*440a403fSchristos This program is distributed in the hope that it will be useful, 14*440a403fSchristos but WITHOUT ANY WARRANTY; without even the implied warranty of 15*440a403fSchristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16*440a403fSchristos GNU General Public License for more details. 17*440a403fSchristos 18*440a403fSchristos You should have received a copy of the GNU General Public License 19*440a403fSchristos along with this program; if not, see <http://www.gnu.org/licenses/>. */ 20*440a403fSchristos 21*440a403fSchristos/* This file is an addendum to or1k.cpu. Heavy use of C code isn't 22*440a403fSchristos appropriate in .cpu files, so it resides here. This especially applies 23*440a403fSchristos to assembly/disassembly where parsing/printing can be quite involved. 24*440a403fSchristos Such things aren't really part of the specification of the cpu, per se, 25*440a403fSchristos so .cpu files provide the general framework and .opc files handle the 26*440a403fSchristos nitty-gritty details as necessary. 27*440a403fSchristos 28*440a403fSchristos Each section is delimited with start and end markers. 29*440a403fSchristos 30*440a403fSchristos <arch>-opc.h additions use: "-- opc.h" 31*440a403fSchristos <arch>-opc.c additions use: "-- opc.c" 32*440a403fSchristos <arch>-asm.c additions use: "-- asm.c" 33*440a403fSchristos <arch>-dis.c additions use: "-- dis.c" 34*440a403fSchristos <arch>-ibd.h additions use: "-- ibd.h" */ 35*440a403fSchristos 36*440a403fSchristos/* -- opc.h */ 37*440a403fSchristos 38*440a403fSchristos#undef CGEN_DIS_HASH_SIZE 39*440a403fSchristos#define CGEN_DIS_HASH_SIZE 256 40*440a403fSchristos#undef CGEN_DIS_HASH 41*440a403fSchristos#define CGEN_DIS_HASH(buffer, value) (((unsigned char *) (buffer))[0] >> 2) 42*440a403fSchristos 43*440a403fSchristos/* -- */ 44*440a403fSchristos 45*440a403fSchristos/* -- opc.c */ 46*440a403fSchristos/* -- */ 47*440a403fSchristos 48*440a403fSchristos/* -- asm.c */ 49*440a403fSchristos 50*440a403fSchristosstatic const char * MISSING_CLOSING_PARENTHESIS = N_("missing `)'"); 51*440a403fSchristos 52*440a403fSchristos#define CGEN_VERBOSE_ASSEMBLER_ERRORS 53*440a403fSchristos 54*440a403fSchristosstatic const char * 55*440a403fSchristosparse_disp26 (CGEN_CPU_DESC cd, 56*440a403fSchristos const char ** strp, 57*440a403fSchristos int opindex, 58*440a403fSchristos int opinfo, 59*440a403fSchristos enum cgen_parse_operand_result * resultp, 60*440a403fSchristos bfd_vma * valuep) 61*440a403fSchristos{ 62*440a403fSchristos const char *errmsg = NULL; 63*440a403fSchristos enum cgen_parse_operand_result result_type; 64*440a403fSchristos 65*440a403fSchristos if (strncasecmp (*strp, "plt(", 4) == 0) 66*440a403fSchristos { 67*440a403fSchristos bfd_vma value; 68*440a403fSchristos 69*440a403fSchristos *strp += 4; 70*440a403fSchristos errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_OR1K_PLT26, 71*440a403fSchristos & result_type, & value); 72*440a403fSchristos if (**strp != ')') 73*440a403fSchristos return MISSING_CLOSING_PARENTHESIS; 74*440a403fSchristos ++*strp; 75*440a403fSchristos if (errmsg == NULL 76*440a403fSchristos && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) 77*440a403fSchristos value = (value >> 2) & 0xffff; 78*440a403fSchristos *valuep = value; 79*440a403fSchristos return errmsg; 80*440a403fSchristos } 81*440a403fSchristos return cgen_parse_address (cd, strp, opindex, opinfo, resultp, valuep); 82*440a403fSchristos} 83*440a403fSchristos 84*440a403fSchristosstatic const char * 85*440a403fSchristosparse_simm16 (CGEN_CPU_DESC cd, const char ** strp, int opindex, long * valuep) 86*440a403fSchristos{ 87*440a403fSchristos const char *errmsg; 88*440a403fSchristos enum cgen_parse_operand_result result_type; 89*440a403fSchristos long ret; 90*440a403fSchristos 91*440a403fSchristos if (**strp == '#') 92*440a403fSchristos ++*strp; 93*440a403fSchristos 94*440a403fSchristos if (strncasecmp (*strp, "hi(", 3) == 0) 95*440a403fSchristos { 96*440a403fSchristos bfd_vma value; 97*440a403fSchristos 98*440a403fSchristos *strp += 3; 99*440a403fSchristos errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_HI16, 100*440a403fSchristos & result_type, & value); 101*440a403fSchristos if (**strp != ')') 102*440a403fSchristos errmsg = MISSING_CLOSING_PARENTHESIS; 103*440a403fSchristos ++*strp; 104*440a403fSchristos 105*440a403fSchristos ret = value; 106*440a403fSchristos 107*440a403fSchristos if (errmsg == NULL 108*440a403fSchristos && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) 109*440a403fSchristos { 110*440a403fSchristos ret >>= 16; 111*440a403fSchristos ret &= 0xffff; 112*440a403fSchristos ret = (ret ^ 0x8000) - 0x8000; 113*440a403fSchristos } 114*440a403fSchristos } 115*440a403fSchristos else if (strncasecmp (*strp, "lo(", 3) == 0) 116*440a403fSchristos { 117*440a403fSchristos bfd_vma value; 118*440a403fSchristos 119*440a403fSchristos *strp += 3; 120*440a403fSchristos errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_LO16, 121*440a403fSchristos & result_type, & value); 122*440a403fSchristos if (**strp != ')') 123*440a403fSchristos return MISSING_CLOSING_PARENTHESIS; 124*440a403fSchristos ++*strp; 125*440a403fSchristos 126*440a403fSchristos ret = value; 127*440a403fSchristos 128*440a403fSchristos if (result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) 129*440a403fSchristos { 130*440a403fSchristos ret &= 0xffff; 131*440a403fSchristos ret = (ret ^ 0x8000) - 0x8000; 132*440a403fSchristos } 133*440a403fSchristos } 134*440a403fSchristos else if (strncasecmp (*strp, "got(", 4) == 0) 135*440a403fSchristos { 136*440a403fSchristos bfd_vma value; 137*440a403fSchristos 138*440a403fSchristos *strp += 4; 139*440a403fSchristos errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_OR1K_GOT16, 140*440a403fSchristos & result_type, & value); 141*440a403fSchristos if (**strp != ')') 142*440a403fSchristos return MISSING_CLOSING_PARENTHESIS; 143*440a403fSchristos ++*strp; 144*440a403fSchristos if (errmsg == NULL 145*440a403fSchristos && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) 146*440a403fSchristos value &= 0xffff; 147*440a403fSchristos *valuep = value; 148*440a403fSchristos return errmsg; 149*440a403fSchristos } 150*440a403fSchristos else if (strncasecmp (*strp, "gotpchi(", 8) == 0) 151*440a403fSchristos { 152*440a403fSchristos bfd_vma value; 153*440a403fSchristos 154*440a403fSchristos *strp += 8; 155*440a403fSchristos errmsg = cgen_parse_address (cd, strp, opindex, 156*440a403fSchristos BFD_RELOC_OR1K_GOTPC_HI16, 157*440a403fSchristos & result_type, & value); 158*440a403fSchristos if (**strp != ')') 159*440a403fSchristos return MISSING_CLOSING_PARENTHESIS; 160*440a403fSchristos ++*strp; 161*440a403fSchristos if (errmsg == NULL 162*440a403fSchristos && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) 163*440a403fSchristos value = (value >> 16) & 0xffff; 164*440a403fSchristos *valuep = value; 165*440a403fSchristos return errmsg; 166*440a403fSchristos } 167*440a403fSchristos else if (strncasecmp (*strp, "gotpclo(", 8) == 0) 168*440a403fSchristos { 169*440a403fSchristos bfd_vma value; 170*440a403fSchristos 171*440a403fSchristos *strp += 8; 172*440a403fSchristos errmsg = cgen_parse_address (cd, strp, opindex, 173*440a403fSchristos BFD_RELOC_OR1K_GOTPC_LO16, 174*440a403fSchristos &result_type, &value); 175*440a403fSchristos if (**strp != ')') 176*440a403fSchristos return MISSING_CLOSING_PARENTHESIS; 177*440a403fSchristos ++*strp; 178*440a403fSchristos if (errmsg == NULL 179*440a403fSchristos && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) 180*440a403fSchristos value &= 0xffff; 181*440a403fSchristos *valuep = value; 182*440a403fSchristos return errmsg; 183*440a403fSchristos } 184*440a403fSchristos else if (strncasecmp (*strp, "gotoffhi(", 9) == 0) 185*440a403fSchristos { 186*440a403fSchristos bfd_vma value; 187*440a403fSchristos 188*440a403fSchristos *strp += 9; 189*440a403fSchristos errmsg = cgen_parse_address (cd, strp, opindex, 190*440a403fSchristos BFD_RELOC_OR1K_GOTOFF_HI16, 191*440a403fSchristos & result_type, & value); 192*440a403fSchristos 193*440a403fSchristos if (**strp != ')') 194*440a403fSchristos return MISSING_CLOSING_PARENTHESIS; 195*440a403fSchristos ++*strp; 196*440a403fSchristos if (errmsg == NULL 197*440a403fSchristos && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) 198*440a403fSchristos value = (value >> 16) & 0xffff; 199*440a403fSchristos *valuep = value; 200*440a403fSchristos return errmsg; 201*440a403fSchristos } 202*440a403fSchristos else if (strncasecmp (*strp, "gotofflo(", 9) == 0) 203*440a403fSchristos { 204*440a403fSchristos bfd_vma value; 205*440a403fSchristos 206*440a403fSchristos *strp += 9; 207*440a403fSchristos errmsg = cgen_parse_address (cd, strp, opindex, 208*440a403fSchristos BFD_RELOC_OR1K_GOTOFF_LO16, 209*440a403fSchristos &result_type, &value); 210*440a403fSchristos if (**strp != ')') 211*440a403fSchristos return MISSING_CLOSING_PARENTHESIS; 212*440a403fSchristos ++*strp; 213*440a403fSchristos if (errmsg == NULL 214*440a403fSchristos && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) 215*440a403fSchristos value &= 0xffff; 216*440a403fSchristos *valuep = value; 217*440a403fSchristos return errmsg; 218*440a403fSchristos } 219*440a403fSchristos else if (strncasecmp (*strp, "tlsgdhi(", 8) == 0) 220*440a403fSchristos { 221*440a403fSchristos bfd_vma value; 222*440a403fSchristos 223*440a403fSchristos *strp += 8; 224*440a403fSchristos errmsg = cgen_parse_address (cd, strp, opindex, 225*440a403fSchristos BFD_RELOC_OR1K_TLS_GD_HI16, 226*440a403fSchristos & result_type, & value); 227*440a403fSchristos 228*440a403fSchristos if (**strp != ')') 229*440a403fSchristos return MISSING_CLOSING_PARENTHESIS; 230*440a403fSchristos ++*strp; 231*440a403fSchristos if (errmsg == NULL 232*440a403fSchristos && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) 233*440a403fSchristos value = (value >> 16) & 0xffff; 234*440a403fSchristos *valuep = value; 235*440a403fSchristos return errmsg; 236*440a403fSchristos } 237*440a403fSchristos else if (strncasecmp (*strp, "tlsgdlo(", 8) == 0) 238*440a403fSchristos { 239*440a403fSchristos bfd_vma value; 240*440a403fSchristos 241*440a403fSchristos *strp += 8; 242*440a403fSchristos errmsg = cgen_parse_address (cd, strp, opindex, 243*440a403fSchristos BFD_RELOC_OR1K_TLS_GD_LO16, 244*440a403fSchristos &result_type, &value); 245*440a403fSchristos if (**strp != ')') 246*440a403fSchristos return MISSING_CLOSING_PARENTHESIS; 247*440a403fSchristos ++*strp; 248*440a403fSchristos if (errmsg == NULL 249*440a403fSchristos && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) 250*440a403fSchristos value &= 0xffff; 251*440a403fSchristos *valuep = value; 252*440a403fSchristos return errmsg; 253*440a403fSchristos } 254*440a403fSchristos else if (strncasecmp (*strp, "tlsldmhi(", 9) == 0) 255*440a403fSchristos { 256*440a403fSchristos bfd_vma value; 257*440a403fSchristos 258*440a403fSchristos *strp += 9; 259*440a403fSchristos errmsg = cgen_parse_address (cd, strp, opindex, 260*440a403fSchristos BFD_RELOC_OR1K_TLS_LDM_HI16, 261*440a403fSchristos & result_type, & value); 262*440a403fSchristos 263*440a403fSchristos if (**strp != ')') 264*440a403fSchristos return MISSING_CLOSING_PARENTHESIS; 265*440a403fSchristos ++*strp; 266*440a403fSchristos if (errmsg == NULL 267*440a403fSchristos && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) 268*440a403fSchristos value = (value >> 16) & 0xffff; 269*440a403fSchristos *valuep = value; 270*440a403fSchristos return errmsg; 271*440a403fSchristos } 272*440a403fSchristos else if (strncasecmp (*strp, "tlsldmlo(", 9) == 0) 273*440a403fSchristos { 274*440a403fSchristos bfd_vma value; 275*440a403fSchristos 276*440a403fSchristos *strp += 9; 277*440a403fSchristos errmsg = cgen_parse_address (cd, strp, opindex, 278*440a403fSchristos BFD_RELOC_OR1K_TLS_LDM_LO16, 279*440a403fSchristos &result_type, &value); 280*440a403fSchristos if (**strp != ')') 281*440a403fSchristos return MISSING_CLOSING_PARENTHESIS; 282*440a403fSchristos ++*strp; 283*440a403fSchristos if (errmsg == NULL 284*440a403fSchristos && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) 285*440a403fSchristos value &= 0xffff; 286*440a403fSchristos *valuep = value; 287*440a403fSchristos return errmsg; 288*440a403fSchristos } 289*440a403fSchristos else if (strncasecmp (*strp, "dtpoffhi(", 9) == 0) 290*440a403fSchristos { 291*440a403fSchristos bfd_vma value; 292*440a403fSchristos 293*440a403fSchristos *strp += 9; 294*440a403fSchristos errmsg = cgen_parse_address (cd, strp, opindex, 295*440a403fSchristos BFD_RELOC_OR1K_TLS_LDO_HI16, 296*440a403fSchristos & result_type, & value); 297*440a403fSchristos 298*440a403fSchristos if (**strp != ')') 299*440a403fSchristos return MISSING_CLOSING_PARENTHESIS; 300*440a403fSchristos ++*strp; 301*440a403fSchristos if (errmsg == NULL 302*440a403fSchristos && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) 303*440a403fSchristos value = (value >> 16) & 0xffff; 304*440a403fSchristos *valuep = value; 305*440a403fSchristos return errmsg; 306*440a403fSchristos } 307*440a403fSchristos else if (strncasecmp (*strp, "dtpofflo(", 9) == 0) 308*440a403fSchristos { 309*440a403fSchristos bfd_vma value; 310*440a403fSchristos 311*440a403fSchristos *strp += 9; 312*440a403fSchristos errmsg = cgen_parse_address (cd, strp, opindex, 313*440a403fSchristos BFD_RELOC_OR1K_TLS_LDO_LO16, 314*440a403fSchristos &result_type, &value); 315*440a403fSchristos if (**strp != ')') 316*440a403fSchristos return MISSING_CLOSING_PARENTHESIS; 317*440a403fSchristos ++*strp; 318*440a403fSchristos if (errmsg == NULL 319*440a403fSchristos && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) 320*440a403fSchristos value &= 0xffff; 321*440a403fSchristos *valuep = value; 322*440a403fSchristos return errmsg; 323*440a403fSchristos } 324*440a403fSchristos else if (strncasecmp (*strp, "gottpoffhi(", 11) == 0) 325*440a403fSchristos { 326*440a403fSchristos bfd_vma value; 327*440a403fSchristos 328*440a403fSchristos *strp += 11; 329*440a403fSchristos errmsg = cgen_parse_address (cd, strp, opindex, 330*440a403fSchristos BFD_RELOC_OR1K_TLS_IE_HI16, 331*440a403fSchristos & result_type, & value); 332*440a403fSchristos 333*440a403fSchristos if (**strp != ')') 334*440a403fSchristos return MISSING_CLOSING_PARENTHESIS; 335*440a403fSchristos ++*strp; 336*440a403fSchristos if (errmsg == NULL 337*440a403fSchristos && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) 338*440a403fSchristos value = (value >> 16) & 0xffff; 339*440a403fSchristos *valuep = value; 340*440a403fSchristos return errmsg; 341*440a403fSchristos } 342*440a403fSchristos else if (strncasecmp (*strp, "gottpofflo(", 11) == 0) 343*440a403fSchristos { 344*440a403fSchristos bfd_vma value; 345*440a403fSchristos 346*440a403fSchristos *strp += 11; 347*440a403fSchristos errmsg = cgen_parse_address (cd, strp, opindex, 348*440a403fSchristos BFD_RELOC_OR1K_TLS_IE_LO16, 349*440a403fSchristos &result_type, &value); 350*440a403fSchristos if (**strp != ')') 351*440a403fSchristos return MISSING_CLOSING_PARENTHESIS; 352*440a403fSchristos ++*strp; 353*440a403fSchristos if (errmsg == NULL 354*440a403fSchristos && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) 355*440a403fSchristos value &= 0xffff; 356*440a403fSchristos *valuep = value; 357*440a403fSchristos return errmsg; 358*440a403fSchristos } 359*440a403fSchristos else if (strncasecmp (*strp, "tpoffhi(", 8) == 0) 360*440a403fSchristos { 361*440a403fSchristos bfd_vma value; 362*440a403fSchristos 363*440a403fSchristos *strp += 8; 364*440a403fSchristos errmsg = cgen_parse_address (cd, strp, opindex, 365*440a403fSchristos BFD_RELOC_OR1K_TLS_LE_HI16, 366*440a403fSchristos & result_type, & value); 367*440a403fSchristos 368*440a403fSchristos if (**strp != ')') 369*440a403fSchristos return MISSING_CLOSING_PARENTHESIS; 370*440a403fSchristos ++*strp; 371*440a403fSchristos if (errmsg == NULL 372*440a403fSchristos && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) 373*440a403fSchristos value = (value >> 16) & 0xffff; 374*440a403fSchristos *valuep = value; 375*440a403fSchristos return errmsg; 376*440a403fSchristos } 377*440a403fSchristos else if (strncasecmp (*strp, "tpofflo(", 8) == 0) 378*440a403fSchristos { 379*440a403fSchristos bfd_vma value; 380*440a403fSchristos 381*440a403fSchristos *strp += 8; 382*440a403fSchristos errmsg = cgen_parse_address (cd, strp, opindex, 383*440a403fSchristos BFD_RELOC_OR1K_TLS_LE_LO16, 384*440a403fSchristos &result_type, &value); 385*440a403fSchristos if (**strp != ')') 386*440a403fSchristos return MISSING_CLOSING_PARENTHESIS; 387*440a403fSchristos ++*strp; 388*440a403fSchristos if (errmsg == NULL 389*440a403fSchristos && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) 390*440a403fSchristos value &= 0xffff; 391*440a403fSchristos *valuep = value; 392*440a403fSchristos return errmsg; 393*440a403fSchristos } 394*440a403fSchristos else 395*440a403fSchristos { 396*440a403fSchristos long value; 397*440a403fSchristos errmsg = cgen_parse_signed_integer (cd, strp, opindex, &value); 398*440a403fSchristos ret = value; 399*440a403fSchristos } 400*440a403fSchristos 401*440a403fSchristos if (errmsg == NULL) 402*440a403fSchristos *valuep = ret; 403*440a403fSchristos 404*440a403fSchristos return errmsg; 405*440a403fSchristos} 406*440a403fSchristos 407*440a403fSchristosstatic const char * 408*440a403fSchristosparse_uimm16 (CGEN_CPU_DESC cd, const char ** strp, int opindex, unsigned long * valuep) 409*440a403fSchristos{ 410*440a403fSchristos const char *errmsg = parse_simm16(cd, strp, opindex, (long *) valuep); 411*440a403fSchristos 412*440a403fSchristos if (errmsg == NULL) 413*440a403fSchristos *valuep &= 0xffff; 414*440a403fSchristos return errmsg; 415*440a403fSchristos} 416*440a403fSchristos 417*440a403fSchristos/* -- */ 418*440a403fSchristos 419*440a403fSchristos/* -- ibd.h */ 420*440a403fSchristos 421*440a403fSchristos/* -- */ 422