1/* Lattice Mico32 opcode support. -*- C -*- 2 Copyright 2008, 2009 Free Software Foundation, Inc. 3 Contributed by Jon Beniston <jon@beniston.com> 4 5 This file is part of the GNU Binutils. 6 7 This program is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 3 of the License, or 10 (at your option) any later version. 11 12 This program is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program; if not, write to the Free Software 19 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, 20 MA 02110-1301, USA. */ 21 22/* -- opc.h */ 23 24/* Allows reason codes to be output when assembler errors occur. */ 25#define CGEN_VERBOSE_ASSEMBLER_ERRORS 26 27#define CGEN_DIS_HASH_SIZE 64 28#define CGEN_DIS_HASH(buf,value) ((value >> 26) & 0x3f) 29 30/* -- asm.c */ 31 32/* Handle signed/unsigned literal. */ 33 34static const char * 35parse_imm (CGEN_CPU_DESC cd, 36 const char **strp, 37 int opindex, 38 unsigned long *valuep) 39{ 40 const char *errmsg; 41 signed long value; 42 43 errmsg = cgen_parse_signed_integer (cd, strp, opindex, & value); 44 if (errmsg == NULL) 45 { 46 unsigned long x = value & 0xFFFF0000; 47 if (x != 0 && x != 0xFFFF0000) 48 errmsg = _("immediate value out of range"); 49 else 50 *valuep = (value & 0xFFFF); 51 } 52 return errmsg; 53} 54 55/* Handle hi() */ 56 57static const char * 58parse_hi16 (CGEN_CPU_DESC cd, 59 const char **strp, 60 int opindex, 61 unsigned long *valuep) 62{ 63 if (strncasecmp (*strp, "hi(", 3) == 0) 64 { 65 enum cgen_parse_operand_result result_type; 66 bfd_vma value; 67 const char *errmsg; 68 69 *strp += 3; 70 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_HI16, 71 &result_type, &value); 72 if (**strp != ')') 73 return _("missing `)'"); 74 75 ++*strp; 76 if (errmsg == NULL 77 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) 78 value = (value >> 16) & 0xffff; 79 *valuep = value; 80 81 return errmsg; 82 } 83 84 return parse_imm (cd, strp, opindex, valuep); 85} 86 87/* Handle lo() */ 88 89static const char * 90parse_lo16 (CGEN_CPU_DESC cd, 91 const char **strp, 92 int opindex, 93 unsigned long *valuep) 94{ 95 if (strncasecmp (*strp, "lo(", 3) == 0) 96 { 97 const char *errmsg; 98 enum cgen_parse_operand_result result_type; 99 bfd_vma value; 100 101 *strp += 3; 102 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_LO16, 103 &result_type, &value); 104 if (**strp != ')') 105 return _("missing `)'"); 106 ++*strp; 107 if (errmsg == NULL 108 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) 109 value &= 0xffff; 110 *valuep = value; 111 return errmsg; 112 } 113 114 return parse_imm (cd, strp, opindex, valuep); 115} 116 117/* Handle gp() */ 118 119static const char * 120parse_gp16 (CGEN_CPU_DESC cd, 121 const char **strp, 122 int opindex, 123 long *valuep) 124{ 125 if (strncasecmp (*strp, "gp(", 3) == 0) 126 { 127 const char *errmsg; 128 enum cgen_parse_operand_result result_type; 129 bfd_vma value; 130 131 *strp += 3; 132 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_GPREL16, 133 & result_type, & value); 134 if (**strp != ')') 135 return _("missing `)'"); 136 ++*strp; 137 if (errmsg == NULL 138 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) 139 value &= 0xffff; 140 *valuep = value; 141 return errmsg; 142 } 143 144 return _("expecting gp relative address: gp(symbol)"); 145} 146 147/* Handle got() */ 148 149static const char * 150parse_got16 (CGEN_CPU_DESC cd, 151 const char **strp, 152 int opindex, 153 long *valuep) 154{ 155 if (strncasecmp (*strp, "got(", 4) == 0) 156 { 157 const char *errmsg; 158 enum cgen_parse_operand_result result_type; 159 bfd_vma value; 160 161 *strp += 4; 162 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_LM32_16_GOT, 163 & result_type, & value); 164 if (**strp != ')') 165 return _("missing `)'"); 166 ++*strp; 167 if (errmsg == NULL 168 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) 169 value &= 0xffff; 170 *valuep = value; 171 return errmsg; 172 } 173 174 return _("expecting got relative address: got(symbol)"); 175} 176 177/* Handle gotoffhi16() */ 178 179static const char * 180parse_gotoff_hi16 (CGEN_CPU_DESC cd, 181 const char **strp, 182 int opindex, 183 long *valuep) 184{ 185 if (strncasecmp (*strp, "gotoffhi16(", 11) == 0) 186 { 187 const char *errmsg; 188 enum cgen_parse_operand_result result_type; 189 bfd_vma value; 190 191 *strp += 11; 192 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_LM32_GOTOFF_HI16, 193 & result_type, & value); 194 if (**strp != ')') 195 return _("missing `)'"); 196 ++*strp; 197 if (errmsg == NULL 198 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) 199 value &= 0xffff; 200 *valuep = value; 201 return errmsg; 202 } 203 204 return _("expecting got relative address: gotoffhi16(symbol)"); 205} 206 207/* Handle gotofflo16() */ 208 209static const char * 210parse_gotoff_lo16 (CGEN_CPU_DESC cd, 211 const char **strp, 212 int opindex, 213 long *valuep) 214{ 215 if (strncasecmp (*strp, "gotofflo16(", 11) == 0) 216 { 217 const char *errmsg; 218 enum cgen_parse_operand_result result_type; 219 bfd_vma value; 220 221 *strp += 11; 222 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_LM32_GOTOFF_LO16, 223 &result_type, &value); 224 if (**strp != ')') 225 return _("missing `)'"); 226 ++*strp; 227 if (errmsg == NULL 228 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) 229 value &= 0xffff; 230 *valuep = value; 231 return errmsg; 232 } 233 234 return _("expecting got relative address: gotofflo16(symbol)"); 235} 236