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