1*75fd0b74Schristos /* Assembler interface for targets using CGEN. -*- C -*- 2*75fd0b74Schristos CGEN: Cpu tools GENerator 3*75fd0b74Schristos 4*75fd0b74Schristos THIS FILE IS MACHINE GENERATED WITH CGEN. 5*75fd0b74Schristos - the resultant file is machine generated, cgen-asm.in isn't 6*75fd0b74Schristos 7*75fd0b74Schristos Copyright (C) 1996-2016 Free Software Foundation, Inc. 8*75fd0b74Schristos 9*75fd0b74Schristos This file is part of libopcodes. 10*75fd0b74Schristos 11*75fd0b74Schristos This library is free software; you can redistribute it and/or modify 12*75fd0b74Schristos it under the terms of the GNU General Public License as published by 13*75fd0b74Schristos the Free Software Foundation; either version 3, or (at your option) 14*75fd0b74Schristos any later version. 15*75fd0b74Schristos 16*75fd0b74Schristos It is distributed in the hope that it will be useful, but WITHOUT 17*75fd0b74Schristos ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 18*75fd0b74Schristos or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 19*75fd0b74Schristos License for more details. 20*75fd0b74Schristos 21*75fd0b74Schristos You should have received a copy of the GNU General Public License 22*75fd0b74Schristos along with this program; if not, write to the Free Software Foundation, Inc., 23*75fd0b74Schristos 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ 24*75fd0b74Schristos 25*75fd0b74Schristos 26*75fd0b74Schristos /* ??? Eventually more and more of this stuff can go to cpu-independent files. 27*75fd0b74Schristos Keep that in mind. */ 28*75fd0b74Schristos 29*75fd0b74Schristos #include "sysdep.h" 30*75fd0b74Schristos #include <stdio.h> 31*75fd0b74Schristos #include "ansidecl.h" 32*75fd0b74Schristos #include "bfd.h" 33*75fd0b74Schristos #include "symcat.h" 34*75fd0b74Schristos #include "m32r-desc.h" 35*75fd0b74Schristos #include "m32r-opc.h" 36*75fd0b74Schristos #include "opintl.h" 37*75fd0b74Schristos #include "xregex.h" 38*75fd0b74Schristos #include "libiberty.h" 39*75fd0b74Schristos #include "safe-ctype.h" 40*75fd0b74Schristos 41*75fd0b74Schristos #undef min 42*75fd0b74Schristos #define min(a,b) ((a) < (b) ? (a) : (b)) 43*75fd0b74Schristos #undef max 44*75fd0b74Schristos #define max(a,b) ((a) > (b) ? (a) : (b)) 45*75fd0b74Schristos 46*75fd0b74Schristos static const char * parse_insn_normal 47*75fd0b74Schristos (CGEN_CPU_DESC, const CGEN_INSN *, const char **, CGEN_FIELDS *); 48*75fd0b74Schristos 49*75fd0b74Schristos /* -- assembler routines inserted here. */ 50*75fd0b74Schristos 51*75fd0b74Schristos /* -- asm.c */ 52*75fd0b74Schristos static const char * MISSING_CLOSING_PARENTHESIS = N_("missing `)'"); 53*75fd0b74Schristos 54*75fd0b74Schristos /* Handle '#' prefixes (i.e. skip over them). */ 55*75fd0b74Schristos 56*75fd0b74Schristos static const char * 57*75fd0b74Schristos parse_hash (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, 58*75fd0b74Schristos const char **strp, 59*75fd0b74Schristos int opindex ATTRIBUTE_UNUSED, 60*75fd0b74Schristos long *valuep ATTRIBUTE_UNUSED) 61*75fd0b74Schristos { 62*75fd0b74Schristos if (**strp == '#') 63*75fd0b74Schristos ++*strp; 64*75fd0b74Schristos return NULL; 65*75fd0b74Schristos } 66*75fd0b74Schristos 67*75fd0b74Schristos /* Handle shigh(), high(). */ 68*75fd0b74Schristos 69*75fd0b74Schristos static const char * 70*75fd0b74Schristos parse_hi16 (CGEN_CPU_DESC cd, 71*75fd0b74Schristos const char **strp, 72*75fd0b74Schristos int opindex, 73*75fd0b74Schristos unsigned long *valuep) 74*75fd0b74Schristos { 75*75fd0b74Schristos const char *errmsg; 76*75fd0b74Schristos enum cgen_parse_operand_result result_type; 77*75fd0b74Schristos bfd_vma value; 78*75fd0b74Schristos 79*75fd0b74Schristos if (**strp == '#') 80*75fd0b74Schristos ++*strp; 81*75fd0b74Schristos 82*75fd0b74Schristos if (strncasecmp (*strp, "high(", 5) == 0) 83*75fd0b74Schristos { 84*75fd0b74Schristos *strp += 5; 85*75fd0b74Schristos errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_M32R_HI16_ULO, 86*75fd0b74Schristos & result_type, & value); 87*75fd0b74Schristos if (**strp != ')') 88*75fd0b74Schristos return MISSING_CLOSING_PARENTHESIS; 89*75fd0b74Schristos ++*strp; 90*75fd0b74Schristos if (errmsg == NULL 91*75fd0b74Schristos && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) 92*75fd0b74Schristos { 93*75fd0b74Schristos value >>= 16; 94*75fd0b74Schristos value &= 0xffff; 95*75fd0b74Schristos } 96*75fd0b74Schristos *valuep = value; 97*75fd0b74Schristos return errmsg; 98*75fd0b74Schristos } 99*75fd0b74Schristos else if (strncasecmp (*strp, "shigh(", 6) == 0) 100*75fd0b74Schristos { 101*75fd0b74Schristos *strp += 6; 102*75fd0b74Schristos errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_M32R_HI16_SLO, 103*75fd0b74Schristos & result_type, & value); 104*75fd0b74Schristos if (**strp != ')') 105*75fd0b74Schristos return MISSING_CLOSING_PARENTHESIS; 106*75fd0b74Schristos ++*strp; 107*75fd0b74Schristos if (errmsg == NULL 108*75fd0b74Schristos && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) 109*75fd0b74Schristos { 110*75fd0b74Schristos value += 0x8000; 111*75fd0b74Schristos value >>= 16; 112*75fd0b74Schristos value &= 0xffff; 113*75fd0b74Schristos } 114*75fd0b74Schristos *valuep = value; 115*75fd0b74Schristos return errmsg; 116*75fd0b74Schristos } 117*75fd0b74Schristos 118*75fd0b74Schristos return cgen_parse_unsigned_integer (cd, strp, opindex, valuep); 119*75fd0b74Schristos } 120*75fd0b74Schristos 121*75fd0b74Schristos /* Handle low() in a signed context. Also handle sda(). 122*75fd0b74Schristos The signedness of the value doesn't matter to low(), but this also 123*75fd0b74Schristos handles the case where low() isn't present. */ 124*75fd0b74Schristos 125*75fd0b74Schristos static const char * 126*75fd0b74Schristos parse_slo16 (CGEN_CPU_DESC cd, 127*75fd0b74Schristos const char ** strp, 128*75fd0b74Schristos int opindex, 129*75fd0b74Schristos long * valuep) 130*75fd0b74Schristos { 131*75fd0b74Schristos const char *errmsg; 132*75fd0b74Schristos enum cgen_parse_operand_result result_type; 133*75fd0b74Schristos bfd_vma value; 134*75fd0b74Schristos 135*75fd0b74Schristos if (**strp == '#') 136*75fd0b74Schristos ++*strp; 137*75fd0b74Schristos 138*75fd0b74Schristos if (strncasecmp (*strp, "low(", 4) == 0) 139*75fd0b74Schristos { 140*75fd0b74Schristos *strp += 4; 141*75fd0b74Schristos errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_M32R_LO16, 142*75fd0b74Schristos & result_type, & value); 143*75fd0b74Schristos if (**strp != ')') 144*75fd0b74Schristos return MISSING_CLOSING_PARENTHESIS; 145*75fd0b74Schristos ++*strp; 146*75fd0b74Schristos if (errmsg == NULL 147*75fd0b74Schristos && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) 148*75fd0b74Schristos value = ((value & 0xffff) ^ 0x8000) - 0x8000; 149*75fd0b74Schristos *valuep = value; 150*75fd0b74Schristos return errmsg; 151*75fd0b74Schristos } 152*75fd0b74Schristos 153*75fd0b74Schristos if (strncasecmp (*strp, "sda(", 4) == 0) 154*75fd0b74Schristos { 155*75fd0b74Schristos *strp += 4; 156*75fd0b74Schristos errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_M32R_SDA16, 157*75fd0b74Schristos NULL, & value); 158*75fd0b74Schristos if (**strp != ')') 159*75fd0b74Schristos return MISSING_CLOSING_PARENTHESIS; 160*75fd0b74Schristos ++*strp; 161*75fd0b74Schristos *valuep = value; 162*75fd0b74Schristos return errmsg; 163*75fd0b74Schristos } 164*75fd0b74Schristos 165*75fd0b74Schristos return cgen_parse_signed_integer (cd, strp, opindex, valuep); 166*75fd0b74Schristos } 167*75fd0b74Schristos 168*75fd0b74Schristos /* Handle low() in an unsigned context. 169*75fd0b74Schristos The signedness of the value doesn't matter to low(), but this also 170*75fd0b74Schristos handles the case where low() isn't present. */ 171*75fd0b74Schristos 172*75fd0b74Schristos static const char * 173*75fd0b74Schristos parse_ulo16 (CGEN_CPU_DESC cd, 174*75fd0b74Schristos const char **strp, 175*75fd0b74Schristos int opindex, 176*75fd0b74Schristos unsigned long *valuep) 177*75fd0b74Schristos { 178*75fd0b74Schristos const char *errmsg; 179*75fd0b74Schristos enum cgen_parse_operand_result result_type; 180*75fd0b74Schristos bfd_vma value; 181*75fd0b74Schristos 182*75fd0b74Schristos if (**strp == '#') 183*75fd0b74Schristos ++*strp; 184*75fd0b74Schristos 185*75fd0b74Schristos if (strncasecmp (*strp, "low(", 4) == 0) 186*75fd0b74Schristos { 187*75fd0b74Schristos *strp += 4; 188*75fd0b74Schristos errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_M32R_LO16, 189*75fd0b74Schristos & result_type, & value); 190*75fd0b74Schristos if (**strp != ')') 191*75fd0b74Schristos return MISSING_CLOSING_PARENTHESIS; 192*75fd0b74Schristos ++*strp; 193*75fd0b74Schristos if (errmsg == NULL 194*75fd0b74Schristos && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) 195*75fd0b74Schristos value &= 0xffff; 196*75fd0b74Schristos *valuep = value; 197*75fd0b74Schristos return errmsg; 198*75fd0b74Schristos } 199*75fd0b74Schristos 200*75fd0b74Schristos return cgen_parse_unsigned_integer (cd, strp, opindex, valuep); 201*75fd0b74Schristos } 202*75fd0b74Schristos 203*75fd0b74Schristos /* -- */ 204*75fd0b74Schristos 205*75fd0b74Schristos const char * m32r_cgen_parse_operand 206*75fd0b74Schristos (CGEN_CPU_DESC, int, const char **, CGEN_FIELDS *); 207*75fd0b74Schristos 208*75fd0b74Schristos /* Main entry point for operand parsing. 209*75fd0b74Schristos 210*75fd0b74Schristos This function is basically just a big switch statement. Earlier versions 211*75fd0b74Schristos used tables to look up the function to use, but 212*75fd0b74Schristos - if the table contains both assembler and disassembler functions then 213*75fd0b74Schristos the disassembler contains much of the assembler and vice-versa, 214*75fd0b74Schristos - there's a lot of inlining possibilities as things grow, 215*75fd0b74Schristos - using a switch statement avoids the function call overhead. 216*75fd0b74Schristos 217*75fd0b74Schristos This function could be moved into `parse_insn_normal', but keeping it 218*75fd0b74Schristos separate makes clear the interface between `parse_insn_normal' and each of 219*75fd0b74Schristos the handlers. */ 220*75fd0b74Schristos 221*75fd0b74Schristos const char * 222*75fd0b74Schristos m32r_cgen_parse_operand (CGEN_CPU_DESC cd, 223*75fd0b74Schristos int opindex, 224*75fd0b74Schristos const char ** strp, 225*75fd0b74Schristos CGEN_FIELDS * fields) 226*75fd0b74Schristos { 227*75fd0b74Schristos const char * errmsg = NULL; 228*75fd0b74Schristos /* Used by scalar operands that still need to be parsed. */ 229*75fd0b74Schristos long junk ATTRIBUTE_UNUSED; 230*75fd0b74Schristos 231*75fd0b74Schristos switch (opindex) 232*75fd0b74Schristos { 233*75fd0b74Schristos case M32R_OPERAND_ACC : 234*75fd0b74Schristos errmsg = cgen_parse_keyword (cd, strp, & m32r_cgen_opval_h_accums, & fields->f_acc); 235*75fd0b74Schristos break; 236*75fd0b74Schristos case M32R_OPERAND_ACCD : 237*75fd0b74Schristos errmsg = cgen_parse_keyword (cd, strp, & m32r_cgen_opval_h_accums, & fields->f_accd); 238*75fd0b74Schristos break; 239*75fd0b74Schristos case M32R_OPERAND_ACCS : 240*75fd0b74Schristos errmsg = cgen_parse_keyword (cd, strp, & m32r_cgen_opval_h_accums, & fields->f_accs); 241*75fd0b74Schristos break; 242*75fd0b74Schristos case M32R_OPERAND_DCR : 243*75fd0b74Schristos errmsg = cgen_parse_keyword (cd, strp, & m32r_cgen_opval_cr_names, & fields->f_r1); 244*75fd0b74Schristos break; 245*75fd0b74Schristos case M32R_OPERAND_DISP16 : 246*75fd0b74Schristos { 247*75fd0b74Schristos bfd_vma value = 0; 248*75fd0b74Schristos errmsg = cgen_parse_address (cd, strp, M32R_OPERAND_DISP16, 0, NULL, & value); 249*75fd0b74Schristos fields->f_disp16 = value; 250*75fd0b74Schristos } 251*75fd0b74Schristos break; 252*75fd0b74Schristos case M32R_OPERAND_DISP24 : 253*75fd0b74Schristos { 254*75fd0b74Schristos bfd_vma value = 0; 255*75fd0b74Schristos errmsg = cgen_parse_address (cd, strp, M32R_OPERAND_DISP24, 0, NULL, & value); 256*75fd0b74Schristos fields->f_disp24 = value; 257*75fd0b74Schristos } 258*75fd0b74Schristos break; 259*75fd0b74Schristos case M32R_OPERAND_DISP8 : 260*75fd0b74Schristos { 261*75fd0b74Schristos bfd_vma value = 0; 262*75fd0b74Schristos errmsg = cgen_parse_address (cd, strp, M32R_OPERAND_DISP8, 0, NULL, & value); 263*75fd0b74Schristos fields->f_disp8 = value; 264*75fd0b74Schristos } 265*75fd0b74Schristos break; 266*75fd0b74Schristos case M32R_OPERAND_DR : 267*75fd0b74Schristos errmsg = cgen_parse_keyword (cd, strp, & m32r_cgen_opval_gr_names, & fields->f_r1); 268*75fd0b74Schristos break; 269*75fd0b74Schristos case M32R_OPERAND_HASH : 270*75fd0b74Schristos errmsg = parse_hash (cd, strp, M32R_OPERAND_HASH, (long *) (& junk)); 271*75fd0b74Schristos break; 272*75fd0b74Schristos case M32R_OPERAND_HI16 : 273*75fd0b74Schristos errmsg = parse_hi16 (cd, strp, M32R_OPERAND_HI16, (unsigned long *) (& fields->f_hi16)); 274*75fd0b74Schristos break; 275*75fd0b74Schristos case M32R_OPERAND_IMM1 : 276*75fd0b74Schristos errmsg = cgen_parse_unsigned_integer (cd, strp, M32R_OPERAND_IMM1, (unsigned long *) (& fields->f_imm1)); 277*75fd0b74Schristos break; 278*75fd0b74Schristos case M32R_OPERAND_SCR : 279*75fd0b74Schristos errmsg = cgen_parse_keyword (cd, strp, & m32r_cgen_opval_cr_names, & fields->f_r2); 280*75fd0b74Schristos break; 281*75fd0b74Schristos case M32R_OPERAND_SIMM16 : 282*75fd0b74Schristos errmsg = cgen_parse_signed_integer (cd, strp, M32R_OPERAND_SIMM16, (long *) (& fields->f_simm16)); 283*75fd0b74Schristos break; 284*75fd0b74Schristos case M32R_OPERAND_SIMM8 : 285*75fd0b74Schristos errmsg = cgen_parse_signed_integer (cd, strp, M32R_OPERAND_SIMM8, (long *) (& fields->f_simm8)); 286*75fd0b74Schristos break; 287*75fd0b74Schristos case M32R_OPERAND_SLO16 : 288*75fd0b74Schristos errmsg = parse_slo16 (cd, strp, M32R_OPERAND_SLO16, (long *) (& fields->f_simm16)); 289*75fd0b74Schristos break; 290*75fd0b74Schristos case M32R_OPERAND_SR : 291*75fd0b74Schristos errmsg = cgen_parse_keyword (cd, strp, & m32r_cgen_opval_gr_names, & fields->f_r2); 292*75fd0b74Schristos break; 293*75fd0b74Schristos case M32R_OPERAND_SRC1 : 294*75fd0b74Schristos errmsg = cgen_parse_keyword (cd, strp, & m32r_cgen_opval_gr_names, & fields->f_r1); 295*75fd0b74Schristos break; 296*75fd0b74Schristos case M32R_OPERAND_SRC2 : 297*75fd0b74Schristos errmsg = cgen_parse_keyword (cd, strp, & m32r_cgen_opval_gr_names, & fields->f_r2); 298*75fd0b74Schristos break; 299*75fd0b74Schristos case M32R_OPERAND_UIMM16 : 300*75fd0b74Schristos errmsg = cgen_parse_unsigned_integer (cd, strp, M32R_OPERAND_UIMM16, (unsigned long *) (& fields->f_uimm16)); 301*75fd0b74Schristos break; 302*75fd0b74Schristos case M32R_OPERAND_UIMM24 : 303*75fd0b74Schristos { 304*75fd0b74Schristos bfd_vma value = 0; 305*75fd0b74Schristos errmsg = cgen_parse_address (cd, strp, M32R_OPERAND_UIMM24, 0, NULL, & value); 306*75fd0b74Schristos fields->f_uimm24 = value; 307*75fd0b74Schristos } 308*75fd0b74Schristos break; 309*75fd0b74Schristos case M32R_OPERAND_UIMM3 : 310*75fd0b74Schristos errmsg = cgen_parse_unsigned_integer (cd, strp, M32R_OPERAND_UIMM3, (unsigned long *) (& fields->f_uimm3)); 311*75fd0b74Schristos break; 312*75fd0b74Schristos case M32R_OPERAND_UIMM4 : 313*75fd0b74Schristos errmsg = cgen_parse_unsigned_integer (cd, strp, M32R_OPERAND_UIMM4, (unsigned long *) (& fields->f_uimm4)); 314*75fd0b74Schristos break; 315*75fd0b74Schristos case M32R_OPERAND_UIMM5 : 316*75fd0b74Schristos errmsg = cgen_parse_unsigned_integer (cd, strp, M32R_OPERAND_UIMM5, (unsigned long *) (& fields->f_uimm5)); 317*75fd0b74Schristos break; 318*75fd0b74Schristos case M32R_OPERAND_UIMM8 : 319*75fd0b74Schristos errmsg = cgen_parse_unsigned_integer (cd, strp, M32R_OPERAND_UIMM8, (unsigned long *) (& fields->f_uimm8)); 320*75fd0b74Schristos break; 321*75fd0b74Schristos case M32R_OPERAND_ULO16 : 322*75fd0b74Schristos errmsg = parse_ulo16 (cd, strp, M32R_OPERAND_ULO16, (unsigned long *) (& fields->f_uimm16)); 323*75fd0b74Schristos break; 324*75fd0b74Schristos 325*75fd0b74Schristos default : 326*75fd0b74Schristos /* xgettext:c-format */ 327*75fd0b74Schristos fprintf (stderr, _("Unrecognized field %d while parsing.\n"), opindex); 328*75fd0b74Schristos abort (); 329*75fd0b74Schristos } 330*75fd0b74Schristos 331*75fd0b74Schristos return errmsg; 332*75fd0b74Schristos } 333*75fd0b74Schristos 334*75fd0b74Schristos cgen_parse_fn * const m32r_cgen_parse_handlers[] = 335*75fd0b74Schristos { 336*75fd0b74Schristos parse_insn_normal, 337*75fd0b74Schristos }; 338*75fd0b74Schristos 339*75fd0b74Schristos void 340*75fd0b74Schristos m32r_cgen_init_asm (CGEN_CPU_DESC cd) 341*75fd0b74Schristos { 342*75fd0b74Schristos m32r_cgen_init_opcode_table (cd); 343*75fd0b74Schristos m32r_cgen_init_ibld_table (cd); 344*75fd0b74Schristos cd->parse_handlers = & m32r_cgen_parse_handlers[0]; 345*75fd0b74Schristos cd->parse_operand = m32r_cgen_parse_operand; 346*75fd0b74Schristos #ifdef CGEN_ASM_INIT_HOOK 347*75fd0b74Schristos CGEN_ASM_INIT_HOOK 348*75fd0b74Schristos #endif 349*75fd0b74Schristos } 350*75fd0b74Schristos 351*75fd0b74Schristos 352*75fd0b74Schristos 353*75fd0b74Schristos /* Regex construction routine. 354*75fd0b74Schristos 355*75fd0b74Schristos This translates an opcode syntax string into a regex string, 356*75fd0b74Schristos by replacing any non-character syntax element (such as an 357*75fd0b74Schristos opcode) with the pattern '.*' 358*75fd0b74Schristos 359*75fd0b74Schristos It then compiles the regex and stores it in the opcode, for 360*75fd0b74Schristos later use by m32r_cgen_assemble_insn 361*75fd0b74Schristos 362*75fd0b74Schristos Returns NULL for success, an error message for failure. */ 363*75fd0b74Schristos 364*75fd0b74Schristos char * 365*75fd0b74Schristos m32r_cgen_build_insn_regex (CGEN_INSN *insn) 366*75fd0b74Schristos { 367*75fd0b74Schristos CGEN_OPCODE *opc = (CGEN_OPCODE *) CGEN_INSN_OPCODE (insn); 368*75fd0b74Schristos const char *mnem = CGEN_INSN_MNEMONIC (insn); 369*75fd0b74Schristos char rxbuf[CGEN_MAX_RX_ELEMENTS]; 370*75fd0b74Schristos char *rx = rxbuf; 371*75fd0b74Schristos const CGEN_SYNTAX_CHAR_TYPE *syn; 372*75fd0b74Schristos int reg_err; 373*75fd0b74Schristos 374*75fd0b74Schristos syn = CGEN_SYNTAX_STRING (CGEN_OPCODE_SYNTAX (opc)); 375*75fd0b74Schristos 376*75fd0b74Schristos /* Mnemonics come first in the syntax string. */ 377*75fd0b74Schristos if (! CGEN_SYNTAX_MNEMONIC_P (* syn)) 378*75fd0b74Schristos return _("missing mnemonic in syntax string"); 379*75fd0b74Schristos ++syn; 380*75fd0b74Schristos 381*75fd0b74Schristos /* Generate a case sensitive regular expression that emulates case 382*75fd0b74Schristos insensitive matching in the "C" locale. We cannot generate a case 383*75fd0b74Schristos insensitive regular expression because in Turkish locales, 'i' and 'I' 384*75fd0b74Schristos are not equal modulo case conversion. */ 385*75fd0b74Schristos 386*75fd0b74Schristos /* Copy the literal mnemonic out of the insn. */ 387*75fd0b74Schristos for (; *mnem; mnem++) 388*75fd0b74Schristos { 389*75fd0b74Schristos char c = *mnem; 390*75fd0b74Schristos 391*75fd0b74Schristos if (ISALPHA (c)) 392*75fd0b74Schristos { 393*75fd0b74Schristos *rx++ = '['; 394*75fd0b74Schristos *rx++ = TOLOWER (c); 395*75fd0b74Schristos *rx++ = TOUPPER (c); 396*75fd0b74Schristos *rx++ = ']'; 397*75fd0b74Schristos } 398*75fd0b74Schristos else 399*75fd0b74Schristos *rx++ = c; 400*75fd0b74Schristos } 401*75fd0b74Schristos 402*75fd0b74Schristos /* Copy any remaining literals from the syntax string into the rx. */ 403*75fd0b74Schristos for(; * syn != 0 && rx <= rxbuf + (CGEN_MAX_RX_ELEMENTS - 7 - 4); ++syn) 404*75fd0b74Schristos { 405*75fd0b74Schristos if (CGEN_SYNTAX_CHAR_P (* syn)) 406*75fd0b74Schristos { 407*75fd0b74Schristos char c = CGEN_SYNTAX_CHAR (* syn); 408*75fd0b74Schristos 409*75fd0b74Schristos switch (c) 410*75fd0b74Schristos { 411*75fd0b74Schristos /* Escape any regex metacharacters in the syntax. */ 412*75fd0b74Schristos case '.': case '[': case '\\': 413*75fd0b74Schristos case '*': case '^': case '$': 414*75fd0b74Schristos 415*75fd0b74Schristos #ifdef CGEN_ESCAPE_EXTENDED_REGEX 416*75fd0b74Schristos case '?': case '{': case '}': 417*75fd0b74Schristos case '(': case ')': case '*': 418*75fd0b74Schristos case '|': case '+': case ']': 419*75fd0b74Schristos #endif 420*75fd0b74Schristos *rx++ = '\\'; 421*75fd0b74Schristos *rx++ = c; 422*75fd0b74Schristos break; 423*75fd0b74Schristos 424*75fd0b74Schristos default: 425*75fd0b74Schristos if (ISALPHA (c)) 426*75fd0b74Schristos { 427*75fd0b74Schristos *rx++ = '['; 428*75fd0b74Schristos *rx++ = TOLOWER (c); 429*75fd0b74Schristos *rx++ = TOUPPER (c); 430*75fd0b74Schristos *rx++ = ']'; 431*75fd0b74Schristos } 432*75fd0b74Schristos else 433*75fd0b74Schristos *rx++ = c; 434*75fd0b74Schristos break; 435*75fd0b74Schristos } 436*75fd0b74Schristos } 437*75fd0b74Schristos else 438*75fd0b74Schristos { 439*75fd0b74Schristos /* Replace non-syntax fields with globs. */ 440*75fd0b74Schristos *rx++ = '.'; 441*75fd0b74Schristos *rx++ = '*'; 442*75fd0b74Schristos } 443*75fd0b74Schristos } 444*75fd0b74Schristos 445*75fd0b74Schristos /* Trailing whitespace ok. */ 446*75fd0b74Schristos * rx++ = '['; 447*75fd0b74Schristos * rx++ = ' '; 448*75fd0b74Schristos * rx++ = '\t'; 449*75fd0b74Schristos * rx++ = ']'; 450*75fd0b74Schristos * rx++ = '*'; 451*75fd0b74Schristos 452*75fd0b74Schristos /* But anchor it after that. */ 453*75fd0b74Schristos * rx++ = '$'; 454*75fd0b74Schristos * rx = '\0'; 455*75fd0b74Schristos 456*75fd0b74Schristos CGEN_INSN_RX (insn) = xmalloc (sizeof (regex_t)); 457*75fd0b74Schristos reg_err = regcomp ((regex_t *) CGEN_INSN_RX (insn), rxbuf, REG_NOSUB); 458*75fd0b74Schristos 459*75fd0b74Schristos if (reg_err == 0) 460*75fd0b74Schristos return NULL; 461*75fd0b74Schristos else 462*75fd0b74Schristos { 463*75fd0b74Schristos static char msg[80]; 464*75fd0b74Schristos 465*75fd0b74Schristos regerror (reg_err, (regex_t *) CGEN_INSN_RX (insn), msg, 80); 466*75fd0b74Schristos regfree ((regex_t *) CGEN_INSN_RX (insn)); 467*75fd0b74Schristos free (CGEN_INSN_RX (insn)); 468*75fd0b74Schristos (CGEN_INSN_RX (insn)) = NULL; 469*75fd0b74Schristos return msg; 470*75fd0b74Schristos } 471*75fd0b74Schristos } 472*75fd0b74Schristos 473*75fd0b74Schristos 474*75fd0b74Schristos /* Default insn parser. 475*75fd0b74Schristos 476*75fd0b74Schristos The syntax string is scanned and operands are parsed and stored in FIELDS. 477*75fd0b74Schristos Relocs are queued as we go via other callbacks. 478*75fd0b74Schristos 479*75fd0b74Schristos ??? Note that this is currently an all-or-nothing parser. If we fail to 480*75fd0b74Schristos parse the instruction, we return 0 and the caller will start over from 481*75fd0b74Schristos the beginning. Backtracking will be necessary in parsing subexpressions, 482*75fd0b74Schristos but that can be handled there. Not handling backtracking here may get 483*75fd0b74Schristos expensive in the case of the m68k. Deal with later. 484*75fd0b74Schristos 485*75fd0b74Schristos Returns NULL for success, an error message for failure. */ 486*75fd0b74Schristos 487*75fd0b74Schristos static const char * 488*75fd0b74Schristos parse_insn_normal (CGEN_CPU_DESC cd, 489*75fd0b74Schristos const CGEN_INSN *insn, 490*75fd0b74Schristos const char **strp, 491*75fd0b74Schristos CGEN_FIELDS *fields) 492*75fd0b74Schristos { 493*75fd0b74Schristos /* ??? Runtime added insns not handled yet. */ 494*75fd0b74Schristos const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn); 495*75fd0b74Schristos const char *str = *strp; 496*75fd0b74Schristos const char *errmsg; 497*75fd0b74Schristos const char *p; 498*75fd0b74Schristos const CGEN_SYNTAX_CHAR_TYPE * syn; 499*75fd0b74Schristos #ifdef CGEN_MNEMONIC_OPERANDS 500*75fd0b74Schristos /* FIXME: wip */ 501*75fd0b74Schristos int past_opcode_p; 502*75fd0b74Schristos #endif 503*75fd0b74Schristos 504*75fd0b74Schristos /* For now we assume the mnemonic is first (there are no leading operands). 505*75fd0b74Schristos We can parse it without needing to set up operand parsing. 506*75fd0b74Schristos GAS's input scrubber will ensure mnemonics are lowercase, but we may 507*75fd0b74Schristos not be called from GAS. */ 508*75fd0b74Schristos p = CGEN_INSN_MNEMONIC (insn); 509*75fd0b74Schristos while (*p && TOLOWER (*p) == TOLOWER (*str)) 510*75fd0b74Schristos ++p, ++str; 511*75fd0b74Schristos 512*75fd0b74Schristos if (* p) 513*75fd0b74Schristos return _("unrecognized instruction"); 514*75fd0b74Schristos 515*75fd0b74Schristos #ifndef CGEN_MNEMONIC_OPERANDS 516*75fd0b74Schristos if (* str && ! ISSPACE (* str)) 517*75fd0b74Schristos return _("unrecognized instruction"); 518*75fd0b74Schristos #endif 519*75fd0b74Schristos 520*75fd0b74Schristos CGEN_INIT_PARSE (cd); 521*75fd0b74Schristos cgen_init_parse_operand (cd); 522*75fd0b74Schristos #ifdef CGEN_MNEMONIC_OPERANDS 523*75fd0b74Schristos past_opcode_p = 0; 524*75fd0b74Schristos #endif 525*75fd0b74Schristos 526*75fd0b74Schristos /* We don't check for (*str != '\0') here because we want to parse 527*75fd0b74Schristos any trailing fake arguments in the syntax string. */ 528*75fd0b74Schristos syn = CGEN_SYNTAX_STRING (syntax); 529*75fd0b74Schristos 530*75fd0b74Schristos /* Mnemonics come first for now, ensure valid string. */ 531*75fd0b74Schristos if (! CGEN_SYNTAX_MNEMONIC_P (* syn)) 532*75fd0b74Schristos abort (); 533*75fd0b74Schristos 534*75fd0b74Schristos ++syn; 535*75fd0b74Schristos 536*75fd0b74Schristos while (* syn != 0) 537*75fd0b74Schristos { 538*75fd0b74Schristos /* Non operand chars must match exactly. */ 539*75fd0b74Schristos if (CGEN_SYNTAX_CHAR_P (* syn)) 540*75fd0b74Schristos { 541*75fd0b74Schristos /* FIXME: While we allow for non-GAS callers above, we assume the 542*75fd0b74Schristos first char after the mnemonic part is a space. */ 543*75fd0b74Schristos /* FIXME: We also take inappropriate advantage of the fact that 544*75fd0b74Schristos GAS's input scrubber will remove extraneous blanks. */ 545*75fd0b74Schristos if (TOLOWER (*str) == TOLOWER (CGEN_SYNTAX_CHAR (* syn))) 546*75fd0b74Schristos { 547*75fd0b74Schristos #ifdef CGEN_MNEMONIC_OPERANDS 548*75fd0b74Schristos if (CGEN_SYNTAX_CHAR(* syn) == ' ') 549*75fd0b74Schristos past_opcode_p = 1; 550*75fd0b74Schristos #endif 551*75fd0b74Schristos ++ syn; 552*75fd0b74Schristos ++ str; 553*75fd0b74Schristos } 554*75fd0b74Schristos else if (*str) 555*75fd0b74Schristos { 556*75fd0b74Schristos /* Syntax char didn't match. Can't be this insn. */ 557*75fd0b74Schristos static char msg [80]; 558*75fd0b74Schristos 559*75fd0b74Schristos /* xgettext:c-format */ 560*75fd0b74Schristos sprintf (msg, _("syntax error (expected char `%c', found `%c')"), 561*75fd0b74Schristos CGEN_SYNTAX_CHAR(*syn), *str); 562*75fd0b74Schristos return msg; 563*75fd0b74Schristos } 564*75fd0b74Schristos else 565*75fd0b74Schristos { 566*75fd0b74Schristos /* Ran out of input. */ 567*75fd0b74Schristos static char msg [80]; 568*75fd0b74Schristos 569*75fd0b74Schristos /* xgettext:c-format */ 570*75fd0b74Schristos sprintf (msg, _("syntax error (expected char `%c', found end of instruction)"), 571*75fd0b74Schristos CGEN_SYNTAX_CHAR(*syn)); 572*75fd0b74Schristos return msg; 573*75fd0b74Schristos } 574*75fd0b74Schristos continue; 575*75fd0b74Schristos } 576*75fd0b74Schristos 577*75fd0b74Schristos #ifdef CGEN_MNEMONIC_OPERANDS 578*75fd0b74Schristos (void) past_opcode_p; 579*75fd0b74Schristos #endif 580*75fd0b74Schristos /* We have an operand of some sort. */ 581*75fd0b74Schristos errmsg = cd->parse_operand (cd, CGEN_SYNTAX_FIELD (*syn), &str, fields); 582*75fd0b74Schristos if (errmsg) 583*75fd0b74Schristos return errmsg; 584*75fd0b74Schristos 585*75fd0b74Schristos /* Done with this operand, continue with next one. */ 586*75fd0b74Schristos ++ syn; 587*75fd0b74Schristos } 588*75fd0b74Schristos 589*75fd0b74Schristos /* If we're at the end of the syntax string, we're done. */ 590*75fd0b74Schristos if (* syn == 0) 591*75fd0b74Schristos { 592*75fd0b74Schristos /* FIXME: For the moment we assume a valid `str' can only contain 593*75fd0b74Schristos blanks now. IE: We needn't try again with a longer version of 594*75fd0b74Schristos the insn and it is assumed that longer versions of insns appear 595*75fd0b74Schristos before shorter ones (eg: lsr r2,r3,1 vs lsr r2,r3). */ 596*75fd0b74Schristos while (ISSPACE (* str)) 597*75fd0b74Schristos ++ str; 598*75fd0b74Schristos 599*75fd0b74Schristos if (* str != '\0') 600*75fd0b74Schristos return _("junk at end of line"); /* FIXME: would like to include `str' */ 601*75fd0b74Schristos 602*75fd0b74Schristos return NULL; 603*75fd0b74Schristos } 604*75fd0b74Schristos 605*75fd0b74Schristos /* We couldn't parse it. */ 606*75fd0b74Schristos return _("unrecognized instruction"); 607*75fd0b74Schristos } 608*75fd0b74Schristos 609*75fd0b74Schristos /* Main entry point. 610*75fd0b74Schristos This routine is called for each instruction to be assembled. 611*75fd0b74Schristos STR points to the insn to be assembled. 612*75fd0b74Schristos We assume all necessary tables have been initialized. 613*75fd0b74Schristos The assembled instruction, less any fixups, is stored in BUF. 614*75fd0b74Schristos Remember that if CGEN_INT_INSN_P then BUF is an int and thus the value 615*75fd0b74Schristos still needs to be converted to target byte order, otherwise BUF is an array 616*75fd0b74Schristos of bytes in target byte order. 617*75fd0b74Schristos The result is a pointer to the insn's entry in the opcode table, 618*75fd0b74Schristos or NULL if an error occured (an error message will have already been 619*75fd0b74Schristos printed). 620*75fd0b74Schristos 621*75fd0b74Schristos Note that when processing (non-alias) macro-insns, 622*75fd0b74Schristos this function recurses. 623*75fd0b74Schristos 624*75fd0b74Schristos ??? It's possible to make this cpu-independent. 625*75fd0b74Schristos One would have to deal with a few minor things. 626*75fd0b74Schristos At this point in time doing so would be more of a curiosity than useful 627*75fd0b74Schristos [for example this file isn't _that_ big], but keeping the possibility in 628*75fd0b74Schristos mind helps keep the design clean. */ 629*75fd0b74Schristos 630*75fd0b74Schristos const CGEN_INSN * 631*75fd0b74Schristos m32r_cgen_assemble_insn (CGEN_CPU_DESC cd, 632*75fd0b74Schristos const char *str, 633*75fd0b74Schristos CGEN_FIELDS *fields, 634*75fd0b74Schristos CGEN_INSN_BYTES_PTR buf, 635*75fd0b74Schristos char **errmsg) 636*75fd0b74Schristos { 637*75fd0b74Schristos const char *start; 638*75fd0b74Schristos CGEN_INSN_LIST *ilist; 639*75fd0b74Schristos const char *parse_errmsg = NULL; 640*75fd0b74Schristos const char *insert_errmsg = NULL; 641*75fd0b74Schristos int recognized_mnemonic = 0; 642*75fd0b74Schristos 643*75fd0b74Schristos /* Skip leading white space. */ 644*75fd0b74Schristos while (ISSPACE (* str)) 645*75fd0b74Schristos ++ str; 646*75fd0b74Schristos 647*75fd0b74Schristos /* The instructions are stored in hashed lists. 648*75fd0b74Schristos Get the first in the list. */ 649*75fd0b74Schristos ilist = CGEN_ASM_LOOKUP_INSN (cd, str); 650*75fd0b74Schristos 651*75fd0b74Schristos /* Keep looking until we find a match. */ 652*75fd0b74Schristos start = str; 653*75fd0b74Schristos for ( ; ilist != NULL ; ilist = CGEN_ASM_NEXT_INSN (ilist)) 654*75fd0b74Schristos { 655*75fd0b74Schristos const CGEN_INSN *insn = ilist->insn; 656*75fd0b74Schristos recognized_mnemonic = 1; 657*75fd0b74Schristos 658*75fd0b74Schristos #ifdef CGEN_VALIDATE_INSN_SUPPORTED 659*75fd0b74Schristos /* Not usually needed as unsupported opcodes 660*75fd0b74Schristos shouldn't be in the hash lists. */ 661*75fd0b74Schristos /* Is this insn supported by the selected cpu? */ 662*75fd0b74Schristos if (! m32r_cgen_insn_supported (cd, insn)) 663*75fd0b74Schristos continue; 664*75fd0b74Schristos #endif 665*75fd0b74Schristos /* If the RELAXED attribute is set, this is an insn that shouldn't be 666*75fd0b74Schristos chosen immediately. Instead, it is used during assembler/linker 667*75fd0b74Schristos relaxation if possible. */ 668*75fd0b74Schristos if (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_RELAXED) != 0) 669*75fd0b74Schristos continue; 670*75fd0b74Schristos 671*75fd0b74Schristos str = start; 672*75fd0b74Schristos 673*75fd0b74Schristos /* Skip this insn if str doesn't look right lexically. */ 674*75fd0b74Schristos if (CGEN_INSN_RX (insn) != NULL && 675*75fd0b74Schristos regexec ((regex_t *) CGEN_INSN_RX (insn), str, 0, NULL, 0) == REG_NOMATCH) 676*75fd0b74Schristos continue; 677*75fd0b74Schristos 678*75fd0b74Schristos /* Allow parse/insert handlers to obtain length of insn. */ 679*75fd0b74Schristos CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn); 680*75fd0b74Schristos 681*75fd0b74Schristos parse_errmsg = CGEN_PARSE_FN (cd, insn) (cd, insn, & str, fields); 682*75fd0b74Schristos if (parse_errmsg != NULL) 683*75fd0b74Schristos continue; 684*75fd0b74Schristos 685*75fd0b74Schristos /* ??? 0 is passed for `pc'. */ 686*75fd0b74Schristos insert_errmsg = CGEN_INSERT_FN (cd, insn) (cd, insn, fields, buf, 687*75fd0b74Schristos (bfd_vma) 0); 688*75fd0b74Schristos if (insert_errmsg != NULL) 689*75fd0b74Schristos continue; 690*75fd0b74Schristos 691*75fd0b74Schristos /* It is up to the caller to actually output the insn and any 692*75fd0b74Schristos queued relocs. */ 693*75fd0b74Schristos return insn; 694*75fd0b74Schristos } 695*75fd0b74Schristos 696*75fd0b74Schristos { 697*75fd0b74Schristos static char errbuf[150]; 698*75fd0b74Schristos const char *tmp_errmsg; 699*75fd0b74Schristos #ifdef CGEN_VERBOSE_ASSEMBLER_ERRORS 700*75fd0b74Schristos #define be_verbose 1 701*75fd0b74Schristos #else 702*75fd0b74Schristos #define be_verbose 0 703*75fd0b74Schristos #endif 704*75fd0b74Schristos 705*75fd0b74Schristos if (be_verbose) 706*75fd0b74Schristos { 707*75fd0b74Schristos /* If requesting verbose error messages, use insert_errmsg. 708*75fd0b74Schristos Failing that, use parse_errmsg. */ 709*75fd0b74Schristos tmp_errmsg = (insert_errmsg ? insert_errmsg : 710*75fd0b74Schristos parse_errmsg ? parse_errmsg : 711*75fd0b74Schristos recognized_mnemonic ? 712*75fd0b74Schristos _("unrecognized form of instruction") : 713*75fd0b74Schristos _("unrecognized instruction")); 714*75fd0b74Schristos 715*75fd0b74Schristos if (strlen (start) > 50) 716*75fd0b74Schristos /* xgettext:c-format */ 717*75fd0b74Schristos sprintf (errbuf, "%s `%.50s...'", tmp_errmsg, start); 718*75fd0b74Schristos else 719*75fd0b74Schristos /* xgettext:c-format */ 720*75fd0b74Schristos sprintf (errbuf, "%s `%.50s'", tmp_errmsg, start); 721*75fd0b74Schristos } 722*75fd0b74Schristos else 723*75fd0b74Schristos { 724*75fd0b74Schristos if (strlen (start) > 50) 725*75fd0b74Schristos /* xgettext:c-format */ 726*75fd0b74Schristos sprintf (errbuf, _("bad instruction `%.50s...'"), start); 727*75fd0b74Schristos else 728*75fd0b74Schristos /* xgettext:c-format */ 729*75fd0b74Schristos sprintf (errbuf, _("bad instruction `%.50s'"), start); 730*75fd0b74Schristos } 731*75fd0b74Schristos 732*75fd0b74Schristos *errmsg = errbuf; 733*75fd0b74Schristos return NULL; 734*75fd0b74Schristos } 735*75fd0b74Schristos } 736