1*16dce513Schristos/* Morpho Technologies mRISC opcode support, for GNU Binutils. -*- C -*- 2*16dce513Schristos Copyright 2001, 2007, 2008, 2009, 2012 Free Software Foundation, Inc. 3*16dce513Schristos 4*16dce513Schristos Contributed by Red Hat Inc; developed under contract from 5*16dce513Schristos Morpho Technologies. 6*16dce513Schristos 7*16dce513Schristos This file is part of the GNU Binutils. 8*16dce513Schristos 9*16dce513Schristos This program is free software; you can redistribute it and/or modify 10*16dce513Schristos it under the terms of the GNU General Public License as published by 11*16dce513Schristos the Free Software Foundation; either version 3 of the License, or 12*16dce513Schristos (at your option) any later version. 13*16dce513Schristos 14*16dce513Schristos This program is distributed in the hope that it will be useful, 15*16dce513Schristos but WITHOUT ANY WARRANTY; without even the implied warranty of 16*16dce513Schristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17*16dce513Schristos GNU General Public License for more details. 18*16dce513Schristos 19*16dce513Schristos You should have received a copy of the GNU General Public License 20*16dce513Schristos along with this program; if not, write to the Free Software 21*16dce513Schristos Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, 22*16dce513Schristos MA 02110-1301, USA. */ 23*16dce513Schristos 24*16dce513Schristos 25*16dce513Schristos/* Each section is delimited with start and end markers. 26*16dce513Schristos 27*16dce513Schristos <arch>-opc.h additions use: "-- opc.h" 28*16dce513Schristos <arch>-opc.c additions use: "-- opc.c" 29*16dce513Schristos <arch>-asm.c additions use: "-- asm.c" 30*16dce513Schristos <arch>-dis.c additions use: "-- dis.c" 31*16dce513Schristos <arch>-ibd.h additions use: "-- ibd.h" */ 32*16dce513Schristos 33*16dce513Schristos/* -- opc.h */ 34*16dce513Schristos 35*16dce513Schristos/* Check applicability of instructions against machines. */ 36*16dce513Schristos#define CGEN_VALIDATE_INSN_SUPPORTED 37*16dce513Schristos 38*16dce513Schristos/* Allows reason codes to be output when assembler errors occur. */ 39*16dce513Schristos#define CGEN_VERBOSE_ASSEMBLER_ERRORS 40*16dce513Schristos 41*16dce513Schristos/* Override disassembly hashing - there are variable bits in the top 42*16dce513Schristos byte of these instructions. */ 43*16dce513Schristos#define CGEN_DIS_HASH_SIZE 8 44*16dce513Schristos#define CGEN_DIS_HASH(buf, value) (((* (unsigned char *) (buf)) >> 5) % CGEN_DIS_HASH_SIZE) 45*16dce513Schristos 46*16dce513Schristos#define CGEN_ASM_HASH_SIZE 127 47*16dce513Schristos#define CGEN_ASM_HASH(insn) mt_asm_hash (insn) 48*16dce513Schristos 49*16dce513Schristosextern unsigned int mt_asm_hash (const char *); 50*16dce513Schristos 51*16dce513Schristosextern int mt_cgen_insn_supported (CGEN_CPU_DESC, const CGEN_INSN *); 52*16dce513Schristos 53*16dce513Schristos 54*16dce513Schristos/* -- opc.c */ 55*16dce513Schristos#include "safe-ctype.h" 56*16dce513Schristos 57*16dce513Schristos/* Special check to ensure that instruction exists for given machine. */ 58*16dce513Schristos 59*16dce513Schristosint 60*16dce513Schristosmt_cgen_insn_supported (CGEN_CPU_DESC cd, const CGEN_INSN *insn) 61*16dce513Schristos{ 62*16dce513Schristos int machs = CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_MACH); 63*16dce513Schristos 64*16dce513Schristos /* No mach attribute? Assume it's supported for all machs. */ 65*16dce513Schristos if (machs == 0) 66*16dce513Schristos return 1; 67*16dce513Schristos 68*16dce513Schristos return ((machs & cd->machs) != 0); 69*16dce513Schristos} 70*16dce513Schristos 71*16dce513Schristos/* A better hash function for instruction mnemonics. */ 72*16dce513Schristos 73*16dce513Schristosunsigned int 74*16dce513Schristosmt_asm_hash (const char* insn) 75*16dce513Schristos{ 76*16dce513Schristos unsigned int hash; 77*16dce513Schristos const char* m = insn; 78*16dce513Schristos 79*16dce513Schristos for (hash = 0; *m && ! ISSPACE (*m); m++) 80*16dce513Schristos hash = (hash * 23) ^ (0x1F & TOLOWER (*m)); 81*16dce513Schristos 82*16dce513Schristos /* printf ("%s %d\n", insn, (hash % CGEN_ASM_HASH_SIZE)); */ 83*16dce513Schristos 84*16dce513Schristos return hash % CGEN_ASM_HASH_SIZE; 85*16dce513Schristos} 86*16dce513Schristos 87*16dce513Schristos 88*16dce513Schristos/* -- asm.c */ 89*16dce513Schristos/* Range checking for signed numbers. Returns 0 if acceptable 90*16dce513Schristos and 1 if the value is out of bounds for a signed quantity. */ 91*16dce513Schristos 92*16dce513Schristosstatic int 93*16dce513Schristossigned_out_of_bounds (long val) 94*16dce513Schristos{ 95*16dce513Schristos if ((val < -32768) || (val > 32767)) 96*16dce513Schristos return 1; 97*16dce513Schristos return 0; 98*16dce513Schristos} 99*16dce513Schristos 100*16dce513Schristosstatic const char * 101*16dce513Schristosparse_loopsize (CGEN_CPU_DESC cd, 102*16dce513Schristos const char **strp, 103*16dce513Schristos int opindex, 104*16dce513Schristos void *arg) 105*16dce513Schristos{ 106*16dce513Schristos signed long * valuep = (signed long *) arg; 107*16dce513Schristos const char *errmsg; 108*16dce513Schristos bfd_reloc_code_real_type code = BFD_RELOC_NONE; 109*16dce513Schristos enum cgen_parse_operand_result result_type; 110*16dce513Schristos bfd_vma value; 111*16dce513Schristos 112*16dce513Schristos /* Is it a control transfer instructions? */ 113*16dce513Schristos if (opindex == (CGEN_OPERAND_TYPE) MT_OPERAND_LOOPSIZE) 114*16dce513Schristos { 115*16dce513Schristos code = BFD_RELOC_MT_PCINSN8; 116*16dce513Schristos errmsg = cgen_parse_address (cd, strp, opindex, code, 117*16dce513Schristos & result_type, & value); 118*16dce513Schristos *valuep = value; 119*16dce513Schristos return errmsg; 120*16dce513Schristos } 121*16dce513Schristos 122*16dce513Schristos abort (); 123*16dce513Schristos} 124*16dce513Schristos 125*16dce513Schristosstatic const char * 126*16dce513Schristosparse_imm16 (CGEN_CPU_DESC cd, 127*16dce513Schristos const char **strp, 128*16dce513Schristos int opindex, 129*16dce513Schristos void *arg) 130*16dce513Schristos{ 131*16dce513Schristos signed long * valuep = (signed long *) arg; 132*16dce513Schristos const char *errmsg; 133*16dce513Schristos enum cgen_parse_operand_result result_type; 134*16dce513Schristos bfd_reloc_code_real_type code = BFD_RELOC_NONE; 135*16dce513Schristos bfd_vma value; 136*16dce513Schristos 137*16dce513Schristos /* Is it a control transfer instructions? */ 138*16dce513Schristos if (opindex == (CGEN_OPERAND_TYPE) MT_OPERAND_IMM16O) 139*16dce513Schristos { 140*16dce513Schristos code = BFD_RELOC_16_PCREL; 141*16dce513Schristos errmsg = cgen_parse_address (cd, strp, opindex, code, 142*16dce513Schristos & result_type, & value); 143*16dce513Schristos if (errmsg == NULL) 144*16dce513Schristos { 145*16dce513Schristos if (signed_out_of_bounds (value)) 146*16dce513Schristos errmsg = _("Operand out of range. Must be between -32768 and 32767."); 147*16dce513Schristos } 148*16dce513Schristos *valuep = value; 149*16dce513Schristos return errmsg; 150*16dce513Schristos } 151*16dce513Schristos 152*16dce513Schristos /* If it's not a control transfer instruction, then 153*16dce513Schristos we have to check for %OP relocating operators. */ 154*16dce513Schristos if (opindex == (CGEN_OPERAND_TYPE) MT_OPERAND_IMM16L) 155*16dce513Schristos ; 156*16dce513Schristos else if (strncmp (*strp, "%hi16", 5) == 0) 157*16dce513Schristos { 158*16dce513Schristos *strp += 5; 159*16dce513Schristos code = BFD_RELOC_HI16; 160*16dce513Schristos } 161*16dce513Schristos else if (strncmp (*strp, "%lo16", 5) == 0) 162*16dce513Schristos { 163*16dce513Schristos *strp += 5; 164*16dce513Schristos code = BFD_RELOC_LO16; 165*16dce513Schristos } 166*16dce513Schristos 167*16dce513Schristos /* If we found a %OP relocating operator, then parse it as an address. 168*16dce513Schristos If not, we need to parse it as an integer, either signed or unsigned 169*16dce513Schristos depending on which operand type we have. */ 170*16dce513Schristos if (code != BFD_RELOC_NONE) 171*16dce513Schristos { 172*16dce513Schristos /* %OP relocating operator found. */ 173*16dce513Schristos errmsg = cgen_parse_address (cd, strp, opindex, code, 174*16dce513Schristos & result_type, & value); 175*16dce513Schristos if (errmsg == NULL) 176*16dce513Schristos { 177*16dce513Schristos switch (result_type) 178*16dce513Schristos { 179*16dce513Schristos case (CGEN_PARSE_OPERAND_RESULT_NUMBER): 180*16dce513Schristos if (code == BFD_RELOC_HI16) 181*16dce513Schristos value = (value >> 16) & 0xFFFF; 182*16dce513Schristos else if (code == BFD_RELOC_LO16) 183*16dce513Schristos value = value & 0xFFFF; 184*16dce513Schristos else 185*16dce513Schristos errmsg = _("Biiiig Trouble in parse_imm16!"); 186*16dce513Schristos break; 187*16dce513Schristos 188*16dce513Schristos case (CGEN_PARSE_OPERAND_RESULT_QUEUED): 189*16dce513Schristos /* No special processing for this case. */ 190*16dce513Schristos break; 191*16dce513Schristos 192*16dce513Schristos default: 193*16dce513Schristos errmsg = _("The percent-operator's operand is not a symbol"); 194*16dce513Schristos break; 195*16dce513Schristos } 196*16dce513Schristos } 197*16dce513Schristos *valuep = value; 198*16dce513Schristos } 199*16dce513Schristos else 200*16dce513Schristos { 201*16dce513Schristos /* Parse hex values like 0xffff as unsigned, and sign extend 202*16dce513Schristos them manually. */ 203*16dce513Schristos int parse_signed = (opindex == (CGEN_OPERAND_TYPE)MT_OPERAND_IMM16); 204*16dce513Schristos 205*16dce513Schristos if ((*strp)[0] == '0' 206*16dce513Schristos && ((*strp)[1] == 'x' || (*strp)[1] == 'X')) 207*16dce513Schristos parse_signed = 0; 208*16dce513Schristos 209*16dce513Schristos /* No relocating operator. Parse as an number. */ 210*16dce513Schristos if (parse_signed) 211*16dce513Schristos { 212*16dce513Schristos /* Parse as as signed integer. */ 213*16dce513Schristos 214*16dce513Schristos errmsg = cgen_parse_signed_integer (cd, strp, opindex, valuep); 215*16dce513Schristos 216*16dce513Schristos if (errmsg == NULL) 217*16dce513Schristos { 218*16dce513Schristos#if 0 219*16dce513Schristos /* Manual range checking is needed for the signed case. */ 220*16dce513Schristos if (*valuep & 0x8000) 221*16dce513Schristos value = 0xffff0000 | *valuep; 222*16dce513Schristos else 223*16dce513Schristos value = *valuep; 224*16dce513Schristos 225*16dce513Schristos if (signed_out_of_bounds (value)) 226*16dce513Schristos errmsg = _("Operand out of range. Must be between -32768 and 32767."); 227*16dce513Schristos /* Truncate to 16 bits. This is necessary 228*16dce513Schristos because cgen will have sign extended *valuep. */ 229*16dce513Schristos *valuep &= 0xFFFF; 230*16dce513Schristos#endif 231*16dce513Schristos } 232*16dce513Schristos } 233*16dce513Schristos else 234*16dce513Schristos { 235*16dce513Schristos /* MT_OPERAND_IMM16Z. Parse as an unsigned integer. */ 236*16dce513Schristos errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, (unsigned long *) valuep); 237*16dce513Schristos 238*16dce513Schristos if (opindex == (CGEN_OPERAND_TYPE) MT_OPERAND_IMM16 239*16dce513Schristos && *valuep >= 0x8000 240*16dce513Schristos && *valuep <= 0xffff) 241*16dce513Schristos *valuep -= 0x10000; 242*16dce513Schristos } 243*16dce513Schristos } 244*16dce513Schristos 245*16dce513Schristos return errmsg; 246*16dce513Schristos} 247*16dce513Schristos 248*16dce513Schristos 249*16dce513Schristosstatic const char * 250*16dce513Schristosparse_dup (CGEN_CPU_DESC cd, 251*16dce513Schristos const char **strp, 252*16dce513Schristos int opindex, 253*16dce513Schristos unsigned long *valuep) 254*16dce513Schristos{ 255*16dce513Schristos const char *errmsg = NULL; 256*16dce513Schristos 257*16dce513Schristos if (strncmp (*strp, "dup", 3) == 0 || strncmp (*strp, "DUP", 3) == 0) 258*16dce513Schristos { 259*16dce513Schristos *strp += 3; 260*16dce513Schristos *valuep = 1; 261*16dce513Schristos } 262*16dce513Schristos else if (strncmp (*strp, "xx", 2) == 0 || strncmp (*strp, "XX", 2) == 0) 263*16dce513Schristos { 264*16dce513Schristos *strp += 2; 265*16dce513Schristos *valuep = 0; 266*16dce513Schristos } 267*16dce513Schristos else 268*16dce513Schristos errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep); 269*16dce513Schristos 270*16dce513Schristos return errmsg; 271*16dce513Schristos} 272*16dce513Schristos 273*16dce513Schristos 274*16dce513Schristosstatic const char * 275*16dce513Schristosparse_ball (CGEN_CPU_DESC cd, 276*16dce513Schristos const char **strp, 277*16dce513Schristos int opindex, 278*16dce513Schristos unsigned long *valuep) 279*16dce513Schristos{ 280*16dce513Schristos const char *errmsg = NULL; 281*16dce513Schristos 282*16dce513Schristos if (strncmp (*strp, "all", 3) == 0 || strncmp (*strp, "ALL", 3) == 0) 283*16dce513Schristos { 284*16dce513Schristos *strp += 3; 285*16dce513Schristos *valuep = 1; 286*16dce513Schristos } 287*16dce513Schristos else if (strncmp (*strp, "one", 3) == 0 || strncmp (*strp, "ONE", 3) == 0) 288*16dce513Schristos { 289*16dce513Schristos *strp += 3; 290*16dce513Schristos *valuep = 0; 291*16dce513Schristos } 292*16dce513Schristos else 293*16dce513Schristos errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep); 294*16dce513Schristos 295*16dce513Schristos return errmsg; 296*16dce513Schristos} 297*16dce513Schristos 298*16dce513Schristosstatic const char * 299*16dce513Schristosparse_xmode (CGEN_CPU_DESC cd, 300*16dce513Schristos const char **strp, 301*16dce513Schristos int opindex, 302*16dce513Schristos unsigned long *valuep) 303*16dce513Schristos{ 304*16dce513Schristos const char *errmsg = NULL; 305*16dce513Schristos 306*16dce513Schristos if (strncmp (*strp, "pm", 2) == 0 || strncmp (*strp, "PM", 2) == 0) 307*16dce513Schristos { 308*16dce513Schristos *strp += 2; 309*16dce513Schristos *valuep = 1; 310*16dce513Schristos } 311*16dce513Schristos else if (strncmp (*strp, "xm", 2) == 0 || strncmp (*strp, "XM", 2) == 0) 312*16dce513Schristos { 313*16dce513Schristos *strp += 2; 314*16dce513Schristos *valuep = 0; 315*16dce513Schristos } 316*16dce513Schristos else 317*16dce513Schristos errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep); 318*16dce513Schristos 319*16dce513Schristos return errmsg; 320*16dce513Schristos} 321*16dce513Schristos 322*16dce513Schristosstatic const char * 323*16dce513Schristosparse_rc (CGEN_CPU_DESC cd, 324*16dce513Schristos const char **strp, 325*16dce513Schristos int opindex, 326*16dce513Schristos unsigned long *valuep) 327*16dce513Schristos{ 328*16dce513Schristos const char *errmsg = NULL; 329*16dce513Schristos 330*16dce513Schristos if (strncmp (*strp, "r", 1) == 0 || strncmp (*strp, "R", 1) == 0) 331*16dce513Schristos { 332*16dce513Schristos *strp += 1; 333*16dce513Schristos *valuep = 1; 334*16dce513Schristos } 335*16dce513Schristos else if (strncmp (*strp, "c", 1) == 0 || strncmp (*strp, "C", 1) == 0) 336*16dce513Schristos { 337*16dce513Schristos *strp += 1; 338*16dce513Schristos *valuep = 0; 339*16dce513Schristos } 340*16dce513Schristos else 341*16dce513Schristos errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep); 342*16dce513Schristos 343*16dce513Schristos return errmsg; 344*16dce513Schristos} 345*16dce513Schristos 346*16dce513Schristosstatic const char * 347*16dce513Schristosparse_cbrb (CGEN_CPU_DESC cd, 348*16dce513Schristos const char **strp, 349*16dce513Schristos int opindex, 350*16dce513Schristos unsigned long *valuep) 351*16dce513Schristos{ 352*16dce513Schristos const char *errmsg = NULL; 353*16dce513Schristos 354*16dce513Schristos if (strncmp (*strp, "rb", 2) == 0 || strncmp (*strp, "RB", 2) == 0) 355*16dce513Schristos { 356*16dce513Schristos *strp += 2; 357*16dce513Schristos *valuep = 1; 358*16dce513Schristos } 359*16dce513Schristos else if (strncmp (*strp, "cb", 2) == 0 || strncmp (*strp, "CB", 2) == 0) 360*16dce513Schristos { 361*16dce513Schristos *strp += 2; 362*16dce513Schristos *valuep = 0; 363*16dce513Schristos } 364*16dce513Schristos else 365*16dce513Schristos errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep); 366*16dce513Schristos 367*16dce513Schristos return errmsg; 368*16dce513Schristos} 369*16dce513Schristos 370*16dce513Schristosstatic const char * 371*16dce513Schristosparse_rbbc (CGEN_CPU_DESC cd, 372*16dce513Schristos const char **strp, 373*16dce513Schristos int opindex, 374*16dce513Schristos unsigned long *valuep) 375*16dce513Schristos{ 376*16dce513Schristos const char *errmsg = NULL; 377*16dce513Schristos 378*16dce513Schristos if (strncmp (*strp, "rt", 2) == 0 || strncmp (*strp, "RT", 2) == 0) 379*16dce513Schristos { 380*16dce513Schristos *strp += 2; 381*16dce513Schristos *valuep = 0; 382*16dce513Schristos } 383*16dce513Schristos else if (strncmp (*strp, "br1", 3) == 0 || strncmp (*strp, "BR1", 3) == 0) 384*16dce513Schristos { 385*16dce513Schristos *strp += 3; 386*16dce513Schristos *valuep = 1; 387*16dce513Schristos } 388*16dce513Schristos else if (strncmp (*strp, "br2", 3) == 0 || strncmp (*strp, "BR2", 3) == 0) 389*16dce513Schristos { 390*16dce513Schristos *strp += 3; 391*16dce513Schristos *valuep = 2; 392*16dce513Schristos } 393*16dce513Schristos else if (strncmp (*strp, "cs", 2) == 0 || strncmp (*strp, "CS", 2) == 0) 394*16dce513Schristos { 395*16dce513Schristos *strp += 2; 396*16dce513Schristos *valuep = 3; 397*16dce513Schristos } 398*16dce513Schristos else 399*16dce513Schristos errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep); 400*16dce513Schristos 401*16dce513Schristos return errmsg; 402*16dce513Schristos} 403*16dce513Schristos 404*16dce513Schristosstatic const char * 405*16dce513Schristosparse_type (CGEN_CPU_DESC cd, 406*16dce513Schristos const char **strp, 407*16dce513Schristos int opindex, 408*16dce513Schristos unsigned long *valuep) 409*16dce513Schristos{ 410*16dce513Schristos const char *errmsg = NULL; 411*16dce513Schristos 412*16dce513Schristos if (strncmp (*strp, "odd", 3) == 0 || strncmp (*strp, "ODD", 3) == 0) 413*16dce513Schristos { 414*16dce513Schristos *strp += 3; 415*16dce513Schristos *valuep = 0; 416*16dce513Schristos } 417*16dce513Schristos else if (strncmp (*strp, "even", 4) == 0 || strncmp (*strp, "EVEN", 4) == 0) 418*16dce513Schristos { 419*16dce513Schristos *strp += 4; 420*16dce513Schristos *valuep = 1; 421*16dce513Schristos } 422*16dce513Schristos else if (strncmp (*strp, "oe", 2) == 0 || strncmp (*strp, "OE", 2) == 0) 423*16dce513Schristos { 424*16dce513Schristos *strp += 2; 425*16dce513Schristos *valuep = 2; 426*16dce513Schristos } 427*16dce513Schristos else 428*16dce513Schristos errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep); 429*16dce513Schristos 430*16dce513Schristos if ((errmsg == NULL) && (*valuep == 3)) 431*16dce513Schristos errmsg = _("invalid operand. type may have values 0,1,2 only."); 432*16dce513Schristos 433*16dce513Schristos return errmsg; 434*16dce513Schristos} 435*16dce513Schristos 436*16dce513Schristos/* -- dis.c */ 437*16dce513Schristosstatic void 438*16dce513Schristosprint_dollarhex (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, 439*16dce513Schristos void * dis_info, 440*16dce513Schristos long value, 441*16dce513Schristos unsigned int attrs ATTRIBUTE_UNUSED, 442*16dce513Schristos bfd_vma pc ATTRIBUTE_UNUSED, 443*16dce513Schristos int length ATTRIBUTE_UNUSED) 444*16dce513Schristos{ 445*16dce513Schristos disassemble_info *info = (disassemble_info *) dis_info; 446*16dce513Schristos 447*16dce513Schristos info->fprintf_func (info->stream, "$%lx", value & 0xffffffff); 448*16dce513Schristos 449*16dce513Schristos if (0) 450*16dce513Schristos print_normal (cd, dis_info, value, attrs, pc, length); 451*16dce513Schristos} 452*16dce513Schristos 453*16dce513Schristosstatic void 454*16dce513Schristosprint_pcrel (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, 455*16dce513Schristos void * dis_info, 456*16dce513Schristos long value, 457*16dce513Schristos unsigned int attrs ATTRIBUTE_UNUSED, 458*16dce513Schristos bfd_vma pc ATTRIBUTE_UNUSED, 459*16dce513Schristos int length ATTRIBUTE_UNUSED) 460*16dce513Schristos{ 461*16dce513Schristos print_address (cd, dis_info, value + pc, attrs, pc, length); 462*16dce513Schristos} 463*16dce513Schristos 464*16dce513Schristos/* -- */ 465*16dce513Schristos 466*16dce513Schristos 467*16dce513Schristos 468*16dce513Schristos 469*16dce513Schristos 470