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