]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - cpu/lm32.opc
ubsan: xstormy16: left shift of negative value
[thirdparty/binutils-gdb.git] / cpu / lm32.opc
CommitLineData
84e94c90 1/* Lattice Mico32 opcode support. -*- C -*-
aa820537 2 Copyright 2008, 2009 Free Software Foundation, Inc.
84e94c90
NC
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}