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