1*16dce513Schristos/* IQ2000 opcode support. -*- C -*- 2*16dce513Schristos 3*16dce513Schristos Copyright 2000, 2001, 2002, 2005, 2007, 2009 Free Software Foundation, Inc. 4*16dce513Schristos 5*16dce513Schristos Contributed by Red Hat Inc; developed under contract from Fujitsu. 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/* This file is an addendum to iq2000.cpu. Heavy use of C code isn't 25*16dce513Schristos appropriate in .cpu files, so it resides here. This especially applies 26*16dce513Schristos to assembly/disassembly where parsing/printing can be quite involved. 27*16dce513Schristos Such things aren't really part of the specification of the cpu, per se, 28*16dce513Schristos so .cpu files provide the general framework and .opc files handle the 29*16dce513Schristos nitty-gritty details as necessary. 30*16dce513Schristos 31*16dce513Schristos Each section is delimited with start and end markers. 32*16dce513Schristos 33*16dce513Schristos <arch>-opc.h additions use: "-- opc.h" 34*16dce513Schristos <arch>-opc.c additions use: "-- opc.c" 35*16dce513Schristos <arch>-asm.c additions use: "-- asm.c" 36*16dce513Schristos <arch>-dis.c additions use: "-- dis.c" 37*16dce513Schristos <arch>-ibd.h additions use: "-- ibd.h". */ 38*16dce513Schristos 39*16dce513Schristos/* -- opc.h */ 40*16dce513Schristos 41*16dce513Schristos/* Allows reason codes to be output when assembler errors occur. */ 42*16dce513Schristos#define CGEN_VERBOSE_ASSEMBLER_ERRORS 43*16dce513Schristos 44*16dce513Schristos/* Override disassembly hashing - there are variable bits in the top 45*16dce513Schristos byte of these instructions. */ 46*16dce513Schristos#define CGEN_DIS_HASH_SIZE 8 47*16dce513Schristos#define CGEN_DIS_HASH(buf,value) (((* (unsigned char*) (buf)) >> 6) % CGEN_DIS_HASH_SIZE) 48*16dce513Schristos 49*16dce513Schristos/* following activates check beyond hashing since some iq2000 and iq10 50*16dce513Schristos instructions have same mnemonics but different functionality. */ 51*16dce513Schristos#define CGEN_VALIDATE_INSN_SUPPORTED 52*16dce513Schristos 53*16dce513Schristosextern int iq2000_cgen_insn_supported (CGEN_CPU_DESC, const CGEN_INSN *); 54*16dce513Schristos 55*16dce513Schristos/* -- asm.c */ 56*16dce513Schristos 57*16dce513Schristos#include "safe-ctype.h" 58*16dce513Schristos 59*16dce513Schristosstatic const char * MISSING_CLOSING_PARENTHESIS = N_("missing `)'"); 60*16dce513Schristos 61*16dce513Schristos/* Special check to ensure that instruction exists for given machine. */ 62*16dce513Schristos 63*16dce513Schristosint 64*16dce513Schristosiq2000_cgen_insn_supported (CGEN_CPU_DESC cd, const CGEN_INSN *insn) 65*16dce513Schristos{ 66*16dce513Schristos int machs = cd->machs; 67*16dce513Schristos 68*16dce513Schristos return (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_MACH) & machs) != 0; 69*16dce513Schristos} 70*16dce513Schristos 71*16dce513Schristosstatic int 72*16dce513Schristosiq2000_cgen_isa_register (const char **strp) 73*16dce513Schristos{ 74*16dce513Schristos int len; 75*16dce513Schristos int ch1, ch2; 76*16dce513Schristos 77*16dce513Schristos if (**strp == 'r' || **strp == 'R') 78*16dce513Schristos { 79*16dce513Schristos len = strlen (*strp); 80*16dce513Schristos if (len == 2) 81*16dce513Schristos { 82*16dce513Schristos ch1 = (*strp)[1]; 83*16dce513Schristos if ('0' <= ch1 && ch1 <= '9') 84*16dce513Schristos return 1; 85*16dce513Schristos } 86*16dce513Schristos else if (len == 3) 87*16dce513Schristos { 88*16dce513Schristos ch1 = (*strp)[1]; 89*16dce513Schristos ch2 = (*strp)[2]; 90*16dce513Schristos if (('1' <= ch1 && ch1 <= '2') && ('0' <= ch2 && ch2 <= '9')) 91*16dce513Schristos return 1; 92*16dce513Schristos if ('3' == ch1 && (ch2 == '0' || ch2 == '1')) 93*16dce513Schristos return 1; 94*16dce513Schristos } 95*16dce513Schristos } 96*16dce513Schristos if (**strp == '%' 97*16dce513Schristos && TOLOWER ((*strp)[1]) != 'l' 98*16dce513Schristos && TOLOWER ((*strp)[1]) != 'h') 99*16dce513Schristos return 1; 100*16dce513Schristos return 0; 101*16dce513Schristos} 102*16dce513Schristos 103*16dce513Schristos/* Handle negated literal. */ 104*16dce513Schristos 105*16dce513Schristosstatic const char * 106*16dce513Schristosparse_mimm (CGEN_CPU_DESC cd, 107*16dce513Schristos const char **strp, 108*16dce513Schristos int opindex, 109*16dce513Schristos unsigned long *valuep) 110*16dce513Schristos{ 111*16dce513Schristos const char *errmsg; 112*16dce513Schristos 113*16dce513Schristos /* Verify this isn't a register. */ 114*16dce513Schristos if (iq2000_cgen_isa_register (strp)) 115*16dce513Schristos errmsg = _("immediate value cannot be register"); 116*16dce513Schristos else 117*16dce513Schristos { 118*16dce513Schristos long value; 119*16dce513Schristos 120*16dce513Schristos errmsg = cgen_parse_signed_integer (cd, strp, opindex, & value); 121*16dce513Schristos if (errmsg == NULL) 122*16dce513Schristos { 123*16dce513Schristos long x = (-value) & 0xFFFF0000; 124*16dce513Schristos 125*16dce513Schristos if (x != 0 && x != (long) 0xFFFF0000) 126*16dce513Schristos errmsg = _("immediate value out of range"); 127*16dce513Schristos else 128*16dce513Schristos *valuep = (-value & 0xFFFF); 129*16dce513Schristos } 130*16dce513Schristos } 131*16dce513Schristos return errmsg; 132*16dce513Schristos} 133*16dce513Schristos 134*16dce513Schristos/* Handle signed/unsigned literal. */ 135*16dce513Schristos 136*16dce513Schristosstatic const char * 137*16dce513Schristosparse_imm (CGEN_CPU_DESC cd, 138*16dce513Schristos const char **strp, 139*16dce513Schristos int opindex, 140*16dce513Schristos unsigned long *valuep) 141*16dce513Schristos{ 142*16dce513Schristos const char *errmsg; 143*16dce513Schristos 144*16dce513Schristos if (iq2000_cgen_isa_register (strp)) 145*16dce513Schristos errmsg = _("immediate value cannot be register"); 146*16dce513Schristos else 147*16dce513Schristos { 148*16dce513Schristos long value; 149*16dce513Schristos 150*16dce513Schristos errmsg = cgen_parse_signed_integer (cd, strp, opindex, & value); 151*16dce513Schristos if (errmsg == NULL) 152*16dce513Schristos { 153*16dce513Schristos long x = value & 0xFFFF0000; 154*16dce513Schristos 155*16dce513Schristos if (x != 0 && x != (long) 0xFFFF0000) 156*16dce513Schristos errmsg = _("immediate value out of range"); 157*16dce513Schristos else 158*16dce513Schristos *valuep = (value & 0xFFFF); 159*16dce513Schristos } 160*16dce513Schristos } 161*16dce513Schristos return errmsg; 162*16dce513Schristos} 163*16dce513Schristos 164*16dce513Schristos/* Handle iq10 21-bit jmp offset. */ 165*16dce513Schristos 166*16dce513Schristosstatic const char * 167*16dce513Schristosparse_jtargq10 (CGEN_CPU_DESC cd, 168*16dce513Schristos const char **strp, 169*16dce513Schristos int opindex, 170*16dce513Schristos int reloc ATTRIBUTE_UNUSED, 171*16dce513Schristos enum cgen_parse_operand_result *type_addr ATTRIBUTE_UNUSED, 172*16dce513Schristos bfd_vma *valuep) 173*16dce513Schristos{ 174*16dce513Schristos const char *errmsg; 175*16dce513Schristos bfd_vma value; 176*16dce513Schristos enum cgen_parse_operand_result result_type = CGEN_PARSE_OPERAND_RESULT_NUMBER; 177*16dce513Schristos 178*16dce513Schristos errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_IQ2000_OFFSET_21, 179*16dce513Schristos & result_type, & value); 180*16dce513Schristos if (errmsg == NULL && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) 181*16dce513Schristos { 182*16dce513Schristos /* Check value is within 23-bits 183*16dce513Schristos (remembering that 2-bit shift right will occur). */ 184*16dce513Schristos if (value > 0x7fffff) 185*16dce513Schristos return _("21-bit offset out of range"); 186*16dce513Schristos } 187*16dce513Schristos *valuep = (value & 0x7FFFFF); 188*16dce513Schristos return errmsg; 189*16dce513Schristos} 190*16dce513Schristos 191*16dce513Schristos/* Handle high(). */ 192*16dce513Schristos 193*16dce513Schristosstatic const char * 194*16dce513Schristosparse_hi16 (CGEN_CPU_DESC cd, 195*16dce513Schristos const char **strp, 196*16dce513Schristos int opindex, 197*16dce513Schristos unsigned long *valuep) 198*16dce513Schristos{ 199*16dce513Schristos if (strncasecmp (*strp, "%hi(", 4) == 0) 200*16dce513Schristos { 201*16dce513Schristos enum cgen_parse_operand_result result_type; 202*16dce513Schristos bfd_vma value; 203*16dce513Schristos const char *errmsg; 204*16dce513Schristos 205*16dce513Schristos *strp += 4; 206*16dce513Schristos errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_HI16, 207*16dce513Schristos & result_type, & value); 208*16dce513Schristos if (**strp != ')') 209*16dce513Schristos return MISSING_CLOSING_PARENTHESIS; 210*16dce513Schristos 211*16dce513Schristos ++*strp; 212*16dce513Schristos if (errmsg == NULL 213*16dce513Schristos && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) 214*16dce513Schristos { 215*16dce513Schristos /* If value has top-bit of %lo on, then it will 216*16dce513Schristos sign-propagate and so we compensate by adding 217*16dce513Schristos 1 to the resultant %hi value. */ 218*16dce513Schristos if (value & 0x8000) 219*16dce513Schristos value += 0x10000; 220*16dce513Schristos value >>= 16; 221*16dce513Schristos value &= 0xffff; 222*16dce513Schristos } 223*16dce513Schristos *valuep = value; 224*16dce513Schristos 225*16dce513Schristos return errmsg; 226*16dce513Schristos } 227*16dce513Schristos 228*16dce513Schristos /* We add %uhi in case a user just wants the high 16-bits or is using 229*16dce513Schristos an insn like ori for %lo which does not sign-propagate. */ 230*16dce513Schristos if (strncasecmp (*strp, "%uhi(", 5) == 0) 231*16dce513Schristos { 232*16dce513Schristos enum cgen_parse_operand_result result_type; 233*16dce513Schristos bfd_vma value; 234*16dce513Schristos const char *errmsg; 235*16dce513Schristos 236*16dce513Schristos *strp += 5; 237*16dce513Schristos errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_IQ2000_UHI16, 238*16dce513Schristos & result_type, & value); 239*16dce513Schristos if (**strp != ')') 240*16dce513Schristos return MISSING_CLOSING_PARENTHESIS; 241*16dce513Schristos 242*16dce513Schristos ++*strp; 243*16dce513Schristos if (errmsg == NULL 244*16dce513Schristos && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) 245*16dce513Schristos value >>= 16; 246*16dce513Schristos 247*16dce513Schristos value &= 0xffff; 248*16dce513Schristos *valuep = value; 249*16dce513Schristos 250*16dce513Schristos return errmsg; 251*16dce513Schristos } 252*16dce513Schristos 253*16dce513Schristos return parse_imm (cd, strp, opindex, valuep); 254*16dce513Schristos} 255*16dce513Schristos 256*16dce513Schristos/* Handle %lo in a signed context. 257*16dce513Schristos The signedness of the value doesn't matter to %lo(), but this also 258*16dce513Schristos handles the case where %lo() isn't present. */ 259*16dce513Schristos 260*16dce513Schristosstatic const char * 261*16dce513Schristosparse_lo16 (CGEN_CPU_DESC cd, 262*16dce513Schristos const char **strp, 263*16dce513Schristos int opindex, 264*16dce513Schristos unsigned long *valuep) 265*16dce513Schristos{ 266*16dce513Schristos if (strncasecmp (*strp, "%lo(", 4) == 0) 267*16dce513Schristos { 268*16dce513Schristos const char *errmsg; 269*16dce513Schristos enum cgen_parse_operand_result result_type; 270*16dce513Schristos bfd_vma value; 271*16dce513Schristos 272*16dce513Schristos *strp += 4; 273*16dce513Schristos errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_LO16, 274*16dce513Schristos & result_type, & value); 275*16dce513Schristos if (**strp != ')') 276*16dce513Schristos return MISSING_CLOSING_PARENTHESIS; 277*16dce513Schristos ++*strp; 278*16dce513Schristos if (errmsg == NULL 279*16dce513Schristos && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) 280*16dce513Schristos value &= 0xffff; 281*16dce513Schristos *valuep = value; 282*16dce513Schristos return errmsg; 283*16dce513Schristos } 284*16dce513Schristos 285*16dce513Schristos return parse_imm (cd, strp, opindex, valuep); 286*16dce513Schristos} 287*16dce513Schristos 288*16dce513Schristos/* Handle %lo in a negated signed context. 289*16dce513Schristos The signedness of the value doesn't matter to %lo(), but this also 290*16dce513Schristos handles the case where %lo() isn't present. */ 291*16dce513Schristos 292*16dce513Schristosstatic const char * 293*16dce513Schristosparse_mlo16 (CGEN_CPU_DESC cd, 294*16dce513Schristos const char **strp, 295*16dce513Schristos int opindex, 296*16dce513Schristos unsigned long *valuep) 297*16dce513Schristos{ 298*16dce513Schristos if (strncasecmp (*strp, "%lo(", 4) == 0) 299*16dce513Schristos { 300*16dce513Schristos const char *errmsg; 301*16dce513Schristos enum cgen_parse_operand_result result_type; 302*16dce513Schristos bfd_vma value; 303*16dce513Schristos 304*16dce513Schristos *strp += 4; 305*16dce513Schristos errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_LO16, 306*16dce513Schristos & result_type, & value); 307*16dce513Schristos if (**strp != ')') 308*16dce513Schristos return MISSING_CLOSING_PARENTHESIS; 309*16dce513Schristos ++*strp; 310*16dce513Schristos if (errmsg == NULL 311*16dce513Schristos && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) 312*16dce513Schristos value = (-value) & 0xffff; 313*16dce513Schristos *valuep = value; 314*16dce513Schristos return errmsg; 315*16dce513Schristos } 316*16dce513Schristos 317*16dce513Schristos return parse_mimm (cd, strp, opindex, valuep); 318*16dce513Schristos} 319*16dce513Schristos 320*16dce513Schristos/* -- */ 321