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