URL
https://opencores.org/ocsvn/open8_urisc/open8_urisc/trunk
Subversion Repositories open8_urisc
[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [cpu/] [iq2000.opc] - Rev 24
Compare with Previous | Blame | View Log
/* IQ2000 opcode support. -*- C -*-Copyright 2000, 2001, 2002, 2005, 2007, 2009 Free Software Foundation, Inc.Contributed by Red Hat Inc; developed under contract from Fujitsu.This file is part of the GNU Binutils.This program is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 3 of the License, or(at your option) any later version.This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free SoftwareFoundation, Inc., 51 Franklin Street - Fifth Floor, Boston,MA 02110-1301, USA. *//* This file is an addendum to iq2000.cpu. Heavy use of C code isn'tappropriate in .cpu files, so it resides here. This especially appliesto assembly/disassembly where parsing/printing can be quite involved.Such things aren't really part of the specification of the cpu, per se,so .cpu files provide the general framework and .opc files handle thenitty-gritty details as necessary.Each section is delimited with start and end markers.<arch>-opc.h additions use: "-- opc.h"<arch>-opc.c additions use: "-- opc.c"<arch>-asm.c additions use: "-- asm.c"<arch>-dis.c additions use: "-- dis.c"<arch>-ibd.h additions use: "-- ibd.h". *//* -- opc.h *//* Allows reason codes to be output when assembler errors occur. */#define CGEN_VERBOSE_ASSEMBLER_ERRORS/* Override disassembly hashing - there are variable bits in the topbyte of these instructions. */#define CGEN_DIS_HASH_SIZE 8#define CGEN_DIS_HASH(buf,value) (((* (unsigned char*) (buf)) >> 6) % CGEN_DIS_HASH_SIZE)/* following activates check beyond hashing since some iq2000 and iq10instructions have same mnemonics but different functionality. */#define CGEN_VALIDATE_INSN_SUPPORTEDextern int iq2000_cgen_insn_supported (CGEN_CPU_DESC, const CGEN_INSN *);/* -- asm.c */#include "safe-ctype.h"static const char * MISSING_CLOSING_PARENTHESIS = N_("missing `)'");/* Special check to ensure that instruction exists for given machine. */intiq2000_cgen_insn_supported (CGEN_CPU_DESC cd, const CGEN_INSN *insn){int machs = cd->machs;return (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_MACH) & machs) != 0;}static intiq2000_cgen_isa_register (const char **strp){int len;int ch1, ch2;if (**strp == 'r' || **strp == 'R'){len = strlen (*strp);if (len == 2){ch1 = (*strp)[1];if ('0' <= ch1 && ch1 <= '9')return 1;}else if (len == 3){ch1 = (*strp)[1];ch2 = (*strp)[2];if (('1' <= ch1 && ch1 <= '2') && ('0' <= ch2 && ch2 <= '9'))return 1;if ('3' == ch1 && (ch2 == '0' || ch2 == '1'))return 1;}}if (**strp == '%'&& TOLOWER ((*strp)[1]) != 'l'&& TOLOWER ((*strp)[1]) != 'h')return 1;return 0;}/* Handle negated literal. */static const char *parse_mimm (CGEN_CPU_DESC cd,const char **strp,int opindex,unsigned long *valuep){const char *errmsg;/* Verify this isn't a register. */if (iq2000_cgen_isa_register (strp))errmsg = _("immediate value cannot be register");else{long value;errmsg = cgen_parse_signed_integer (cd, strp, opindex, & value);if (errmsg == NULL){long x = (-value) & 0xFFFF0000;if (x != 0 && x != (long) 0xFFFF0000)errmsg = _("immediate value out of range");else*valuep = (-value & 0xFFFF);}}return errmsg;}/* Handle signed/unsigned literal. */static const char *parse_imm (CGEN_CPU_DESC cd,const char **strp,int opindex,unsigned long *valuep){const char *errmsg;if (iq2000_cgen_isa_register (strp))errmsg = _("immediate value cannot be register");else{long value;errmsg = cgen_parse_signed_integer (cd, strp, opindex, & value);if (errmsg == NULL){long x = value & 0xFFFF0000;if (x != 0 && x != (long) 0xFFFF0000)errmsg = _("immediate value out of range");else*valuep = (value & 0xFFFF);}}return errmsg;}/* Handle iq10 21-bit jmp offset. */static const char *parse_jtargq10 (CGEN_CPU_DESC cd,const char **strp,int opindex,int reloc ATTRIBUTE_UNUSED,enum cgen_parse_operand_result *type_addr ATTRIBUTE_UNUSED,bfd_vma *valuep){const char *errmsg;bfd_vma value;enum cgen_parse_operand_result result_type = CGEN_PARSE_OPERAND_RESULT_NUMBER;errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_IQ2000_OFFSET_21,& result_type, & value);if (errmsg == NULL && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER){/* Check value is within 23-bits(remembering that 2-bit shift right will occur). */if (value > 0x7fffff)return _("21-bit offset out of range");}*valuep = (value & 0x7FFFFF);return errmsg;}/* Handle high(). */static const char *parse_hi16 (CGEN_CPU_DESC cd,const char **strp,int opindex,unsigned long *valuep){if (strncasecmp (*strp, "%hi(", 4) == 0){enum cgen_parse_operand_result result_type;bfd_vma value;const char *errmsg;*strp += 4;errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_HI16,& result_type, & value);if (**strp != ')')return MISSING_CLOSING_PARENTHESIS;++*strp;if (errmsg == NULL&& result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER){/* If value has top-bit of %lo on, then it willsign-propagate and so we compensate by adding1 to the resultant %hi value. */if (value & 0x8000)value += 0x10000;value >>= 16;value &= 0xffff;}*valuep = value;return errmsg;}/* We add %uhi in case a user just wants the high 16-bits or is usingan insn like ori for %lo which does not sign-propagate. */if (strncasecmp (*strp, "%uhi(", 5) == 0){enum cgen_parse_operand_result result_type;bfd_vma value;const char *errmsg;*strp += 5;errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_IQ2000_UHI16,& result_type, & value);if (**strp != ')')return MISSING_CLOSING_PARENTHESIS;++*strp;if (errmsg == NULL&& result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)value >>= 16;value &= 0xffff;*valuep = value;return errmsg;}return parse_imm (cd, strp, opindex, valuep);}/* Handle %lo in a signed context.The signedness of the value doesn't matter to %lo(), but this alsohandles the case where %lo() isn't present. */static const char *parse_lo16 (CGEN_CPU_DESC cd,const char **strp,int opindex,unsigned long *valuep){if (strncasecmp (*strp, "%lo(", 4) == 0){const char *errmsg;enum cgen_parse_operand_result result_type;bfd_vma value;*strp += 4;errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_LO16,& result_type, & value);if (**strp != ')')return MISSING_CLOSING_PARENTHESIS;++*strp;if (errmsg == NULL&& result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)value &= 0xffff;*valuep = value;return errmsg;}return parse_imm (cd, strp, opindex, valuep);}/* Handle %lo in a negated signed context.The signedness of the value doesn't matter to %lo(), but this alsohandles the case where %lo() isn't present. */static const char *parse_mlo16 (CGEN_CPU_DESC cd,const char **strp,int opindex,unsigned long *valuep){if (strncasecmp (*strp, "%lo(", 4) == 0){const char *errmsg;enum cgen_parse_operand_result result_type;bfd_vma value;*strp += 4;errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_LO16,& result_type, & value);if (**strp != ')')return MISSING_CLOSING_PARENTHESIS;++*strp;if (errmsg == NULL&& result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)value = (-value) & 0xffff;*valuep = value;return errmsg;}return parse_mimm (cd, strp, opindex, valuep);}/* -- */
