static const char * parse_mem8 (CGEN_CPU_DESC cd, const char **strp, int opindex, unsigned long *valuep) { if (**strp == '(') { const char *s = *strp; if (s[1] == '-' && s[2] == '-') return _("Bad register in preincrement"); while (ISALNUM (*++s)) ; if (s[0] == '+' && s[1] == '+' && (s[2] == ')' || s[2] == ',')) return _("Bad register in postincrement"); if (s[0] == ',' || s[0] == ')') return _("Bad register name"); } else if (cgen_parse_keyword (cd, strp, & xstormy16_cgen_opval_gr_names, (long *) valuep) == NULL) return _("Label conflicts with register name"); else if (strncasecmp (*strp, "rx,", 3) == 0 || strncasecmp (*strp, "rxl,", 3) == 0 || strncasecmp (*strp, "rxh,", 3) == 0) return _("Label conflicts with `Rx'"); else if (**strp == '#') return _("Bad immediate expression"); return cgen_parse_unsigned_integer (cd, strp, opindex, valuep); }
const char * parse_csrn (CGEN_CPU_DESC cd, const char **strp, CGEN_KEYWORD *keyword_table, long *field) { const char *err; unsigned long value; err = cgen_parse_keyword (cd, strp, keyword_table, field); if (!err) return NULL; err = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_CSRN_IDX, & value); if (err) return err; *field = value; return NULL; }
static const char * parse_immediate16 (CGEN_CPU_DESC cd, const char **strp, int opindex, unsigned long *valuep) { const char *errmsg; enum cgen_parse_operand_result result; bfd_reloc_code_real_type code = BFD_RELOC_NONE; bfd_vma value; if (strncmp (*strp, "@hi(", 4) == 0) { *strp += 4; code = BFD_RELOC_HI16; } else if (strncmp (*strp, "@lo(", 4) == 0) { *strp += 4; code = BFD_RELOC_LO16; } if (code == BFD_RELOC_NONE) errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep); else { errmsg = cgen_parse_address (cd, strp, opindex, code, &result, &value); if ((errmsg == NULL) && (result != CGEN_PARSE_OPERAND_RESULT_QUEUED)) errmsg = _("Operand is not a symbol"); *valuep = value; if ((code == BFD_RELOC_HI16 || code == BFD_RELOC_LO16) && **strp == ')') *strp += 1; else { errmsg = _("Syntax error: No trailing ')'"); return errmsg; } } return errmsg; }
static const char * parse_simm_not_reg (CGEN_CPU_DESC cd, const char ** strp, int opindex, long * valuep) { const char * errmsg; int sign = 0; int bits = 0; switch (opindex) { case EPIPHANY_OPERAND_SIMM3: sign = 1; bits = 3; break; case EPIPHANY_OPERAND_SIMM11: sign = 1; bits = 11; break; case EPIPHANY_OPERAND_DISP3: sign = 0; bits = 3; break; case EPIPHANY_OPERAND_DISP11: /* Load/store displacement is a sign-magnitude 12 bit value. */ sign = 0; bits = 11; break; } /* First try to parse as a register name and reject the operand. */ errmsg = cgen_parse_keyword (cd, strp, & epiphany_cgen_opval_gr_names,valuep); if (!errmsg) return _("register name used as immediate value"); errmsg = (sign ? cgen_parse_signed_integer (cd, strp, opindex, valuep) : cgen_parse_unsigned_integer (cd, strp, opindex, (unsigned long *) valuep)); if (errmsg) return errmsg; if (sign) errmsg = cgen_validate_signed_integer (*valuep, -((1L << bits) - 1), (1 << (bits - 1)) - 1); else errmsg = cgen_validate_unsigned_integer (*valuep, 0, (1L << bits) - 1); return errmsg; }
const char * xstormy16_cgen_parse_operand (CGEN_CPU_DESC cd, int opindex, const char ** strp, CGEN_FIELDS * fields) { const char * errmsg = NULL; /* Used by scalar operands that still need to be parsed. */ long junk ATTRIBUTE_UNUSED; switch (opindex) { case XSTORMY16_OPERAND_RB : errmsg = cgen_parse_keyword (cd, strp, & xstormy16_cgen_opval_gr_Rb_names, & fields->f_Rb); break; case XSTORMY16_OPERAND_RBJ : errmsg = cgen_parse_keyword (cd, strp, & xstormy16_cgen_opval_gr_Rb_names, & fields->f_Rbj); break; case XSTORMY16_OPERAND_RD : errmsg = cgen_parse_keyword (cd, strp, & xstormy16_cgen_opval_gr_names, & fields->f_Rd); break; case XSTORMY16_OPERAND_RDM : errmsg = cgen_parse_keyword (cd, strp, & xstormy16_cgen_opval_gr_names, & fields->f_Rdm); break; case XSTORMY16_OPERAND_RM : errmsg = cgen_parse_keyword (cd, strp, & xstormy16_cgen_opval_gr_names, & fields->f_Rm); break; case XSTORMY16_OPERAND_RS : errmsg = cgen_parse_keyword (cd, strp, & xstormy16_cgen_opval_gr_names, & fields->f_Rs); break; case XSTORMY16_OPERAND_ABS24 : errmsg = cgen_parse_unsigned_integer (cd, strp, XSTORMY16_OPERAND_ABS24, (unsigned long *) (& fields->f_abs24)); break; case XSTORMY16_OPERAND_BCOND2 : errmsg = cgen_parse_keyword (cd, strp, & xstormy16_cgen_opval_h_branchcond, & fields->f_op2); break; case XSTORMY16_OPERAND_BCOND5 : errmsg = cgen_parse_keyword (cd, strp, & xstormy16_cgen_opval_h_branchcond, & fields->f_op5); break; case XSTORMY16_OPERAND_HMEM8 : errmsg = parse_mem8 (cd, strp, XSTORMY16_OPERAND_HMEM8, (unsigned long *) (& fields->f_hmem8)); break; case XSTORMY16_OPERAND_IMM12 : errmsg = cgen_parse_signed_integer (cd, strp, XSTORMY16_OPERAND_IMM12, (long *) (& fields->f_imm12)); break; case XSTORMY16_OPERAND_IMM16 : errmsg = parse_immediate16 (cd, strp, XSTORMY16_OPERAND_IMM16, (unsigned long *) (& fields->f_imm16)); break; case XSTORMY16_OPERAND_IMM2 : errmsg = cgen_parse_unsigned_integer (cd, strp, XSTORMY16_OPERAND_IMM2, (unsigned long *) (& fields->f_imm2)); break; case XSTORMY16_OPERAND_IMM3 : errmsg = cgen_parse_unsigned_integer (cd, strp, XSTORMY16_OPERAND_IMM3, (unsigned long *) (& fields->f_imm3)); break; case XSTORMY16_OPERAND_IMM3B : errmsg = cgen_parse_unsigned_integer (cd, strp, XSTORMY16_OPERAND_IMM3B, (unsigned long *) (& fields->f_imm3b)); break; case XSTORMY16_OPERAND_IMM4 : errmsg = parse_small_immediate (cd, strp, XSTORMY16_OPERAND_IMM4, (unsigned long *) (& fields->f_imm4)); break; case XSTORMY16_OPERAND_IMM8 : errmsg = cgen_parse_unsigned_integer (cd, strp, XSTORMY16_OPERAND_IMM8, (unsigned long *) (& fields->f_imm8)); break; case XSTORMY16_OPERAND_IMM8SMALL : errmsg = parse_small_immediate (cd, strp, XSTORMY16_OPERAND_IMM8SMALL, (unsigned long *) (& fields->f_imm8)); break; case XSTORMY16_OPERAND_LMEM8 : errmsg = parse_mem8 (cd, strp, XSTORMY16_OPERAND_LMEM8, (unsigned long *) (& fields->f_lmem8)); break; case XSTORMY16_OPERAND_REL12 : errmsg = cgen_parse_unsigned_integer (cd, strp, XSTORMY16_OPERAND_REL12, (unsigned long *) (& fields->f_rel12)); break; case XSTORMY16_OPERAND_REL12A : errmsg = cgen_parse_unsigned_integer (cd, strp, XSTORMY16_OPERAND_REL12A, (unsigned long *) (& fields->f_rel12a)); break; case XSTORMY16_OPERAND_REL8_2 : errmsg = cgen_parse_unsigned_integer (cd, strp, XSTORMY16_OPERAND_REL8_2, (unsigned long *) (& fields->f_rel8_2)); break; case XSTORMY16_OPERAND_REL8_4 : errmsg = cgen_parse_unsigned_integer (cd, strp, XSTORMY16_OPERAND_REL8_4, (unsigned long *) (& fields->f_rel8_4)); break; case XSTORMY16_OPERAND_WS2 : errmsg = cgen_parse_keyword (cd, strp, & xstormy16_cgen_opval_h_wordsize, & fields->f_op2m); break; default : /* xgettext:c-format */ fprintf (stderr, _("Unrecognized field %d while parsing.\n"), opindex); abort (); } return errmsg; }
static const char * parse_ulo16 (CGEN_CPU_DESC cd, const char **strp, int opindex, unsigned long *valuep) { const char *errmsg; enum cgen_parse_operand_result result_type; bfd_vma value; if (**strp == '#' || **strp == '%') { if (strncasecmp (*strp + 1, "lo(", 3) == 0) { *strp += 4; errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_LO16, & result_type, & value); if (**strp != ')') return "missing `)'"; ++*strp; if (errmsg == NULL && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) value &= 0xffff; *valuep = value; return errmsg; } if (strncasecmp (*strp + 1, "gprello(", 8) == 0) { *strp += 9; errmsg = parse_symbolic_address (cd, strp, opindex, BFD_RELOC_FRV_GPRELLO, & result_type, & value); if (**strp != ')') return "missing ')'"; ++*strp; *valuep = value; return errmsg; } else if (strncasecmp (*strp + 1, "gotlo(", 6) == 0) { *strp += 7; errmsg = parse_symbolic_address (cd, strp, opindex, BFD_RELOC_FRV_GOTLO, & result_type, & value); if (**strp != ')') return "missing ')'"; ++*strp; *valuep = value; return errmsg; } else if (strncasecmp (*strp + 1, "gotfuncdesclo(", 14) == 0) { *strp += 15; errmsg = parse_symbolic_address (cd, strp, opindex, BFD_RELOC_FRV_FUNCDESC_GOTLO, & result_type, & value); if (**strp != ')') return "missing ')'"; ++*strp; *valuep = value; return errmsg; } else if (strncasecmp (*strp + 1, "gotofflo(", 9) == 0) { *strp += 10; errmsg = parse_symbolic_address (cd, strp, opindex, BFD_RELOC_FRV_GOTOFFLO, & result_type, & value); if (**strp != ')') return "missing ')'"; ++*strp; *valuep = value; return errmsg; } else if (strncasecmp (*strp + 1, "gotofffuncdesclo(", 17) == 0) { *strp += 18; errmsg = parse_symbolic_address (cd, strp, opindex, BFD_RELOC_FRV_FUNCDESC_GOTOFFLO, & result_type, & value); if (**strp != ')') return "missing ')'"; ++*strp; *valuep = value; return errmsg; } else if (strncasecmp (*strp + 1, "gottlsdesclo(", 13) == 0) { *strp += 14; errmsg = parse_symbolic_address (cd, strp, opindex, BFD_RELOC_FRV_GOTTLSDESCLO, & result_type, & value); if (**strp != ')') return "missing ')'"; ++*strp; *valuep = value; return errmsg; } else if (strncasecmp (*strp + 1, "tlsmofflo(", 10) == 0) { *strp += 11; errmsg = parse_symbolic_address (cd, strp, opindex, BFD_RELOC_FRV_TLSMOFFLO, & result_type, & value); if (**strp != ')') return "missing ')'"; ++*strp; *valuep = value; return errmsg; } else if (strncasecmp (*strp + 1, "gottlsofflo(", 12) == 0) { *strp += 13; errmsg = parse_symbolic_address (cd, strp, opindex, BFD_RELOC_FRV_GOTTLSOFFLO, & result_type, & value); if (**strp != ')') return "missing ')'"; ++*strp; *valuep = value; return errmsg; } } return cgen_parse_unsigned_integer (cd, strp, opindex, valuep); }
const char * lm32_cgen_parse_operand (CGEN_CPU_DESC cd, int opindex, const char ** strp, CGEN_FIELDS * fields) { const char * errmsg = NULL; /* Used by scalar operands that still need to be parsed. */ long junk ATTRIBUTE_UNUSED; switch (opindex) { case LM32_OPERAND_BRANCH : { bfd_vma value = 0; errmsg = cgen_parse_address (cd, strp, LM32_OPERAND_BRANCH, 0, NULL, & value); fields->f_branch = value; } break; case LM32_OPERAND_CALL : { bfd_vma value = 0; errmsg = cgen_parse_address (cd, strp, LM32_OPERAND_CALL, 0, NULL, & value); fields->f_call = value; } break; case LM32_OPERAND_CSR : errmsg = cgen_parse_keyword (cd, strp, & lm32_cgen_opval_h_csr, & fields->f_csr); break; case LM32_OPERAND_EXCEPTION : errmsg = cgen_parse_unsigned_integer (cd, strp, LM32_OPERAND_EXCEPTION, (unsigned long *) (& fields->f_exception)); break; case LM32_OPERAND_GOT16 : errmsg = parse_got16 (cd, strp, LM32_OPERAND_GOT16, (long *) (& fields->f_imm)); break; case LM32_OPERAND_GOTOFFHI16 : errmsg = parse_gotoff_hi16 (cd, strp, LM32_OPERAND_GOTOFFHI16, (long *) (& fields->f_imm)); break; case LM32_OPERAND_GOTOFFLO16 : errmsg = parse_gotoff_lo16 (cd, strp, LM32_OPERAND_GOTOFFLO16, (long *) (& fields->f_imm)); break; case LM32_OPERAND_GP16 : errmsg = parse_gp16 (cd, strp, LM32_OPERAND_GP16, (long *) (& fields->f_imm)); break; case LM32_OPERAND_HI16 : errmsg = parse_hi16 (cd, strp, LM32_OPERAND_HI16, (unsigned long *) (& fields->f_uimm)); break; case LM32_OPERAND_IMM : errmsg = cgen_parse_signed_integer (cd, strp, LM32_OPERAND_IMM, (long *) (& fields->f_imm)); break; case LM32_OPERAND_LO16 : errmsg = parse_lo16 (cd, strp, LM32_OPERAND_LO16, (unsigned long *) (& fields->f_uimm)); break; case LM32_OPERAND_R0 : errmsg = cgen_parse_keyword (cd, strp, & lm32_cgen_opval_h_gr, & fields->f_r0); break; case LM32_OPERAND_R1 : errmsg = cgen_parse_keyword (cd, strp, & lm32_cgen_opval_h_gr, & fields->f_r1); break; case LM32_OPERAND_R2 : errmsg = cgen_parse_keyword (cd, strp, & lm32_cgen_opval_h_gr, & fields->f_r2); break; case LM32_OPERAND_SHIFT : errmsg = cgen_parse_unsigned_integer (cd, strp, LM32_OPERAND_SHIFT, (unsigned long *) (& fields->f_shift)); break; case LM32_OPERAND_UIMM : errmsg = cgen_parse_unsigned_integer (cd, strp, LM32_OPERAND_UIMM, (unsigned long *) (& fields->f_uimm)); break; case LM32_OPERAND_USER : errmsg = cgen_parse_unsigned_integer (cd, strp, LM32_OPERAND_USER, (unsigned long *) (& fields->f_user)); break; default : /* xgettext:c-format */ fprintf (stderr, _("Unrecognized field %d while parsing.\n"), opindex); abort (); } return errmsg; }