/gas:
[deliverable/binutils-gdb.git] / gas / config / tc-avr.c
CommitLineData
adde6300
AM
1/* tc-avr.c -- Assembler code for the ATMEL AVR
2
d669d37f 3 Copyright 1999, 2000, 2001, 2002, 2004, 2005, 2006, 2007, 2008
2132e3a3 4 Free Software Foundation, Inc.
adde6300
AM
5 Contributed by Denis Chertykov <denisc@overta.ru>
6
7 This file is part of GAS, the GNU Assembler.
8
9 GAS is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
ec2655a6 11 the Free Software Foundation; either version 3, or (at your option)
adde6300
AM
12 any later version.
13
14 GAS is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with GAS; see the file COPYING. If not, write to
4b4da160
NC
21 the Free Software Foundation, 51 Franklin Street - Fifth Floor,
22 Boston, MA 02110-1301, USA. */
adde6300 23
adde6300 24#include "as.h"
3882b010 25#include "safe-ctype.h"
adde6300
AM
26#include "subsegs.h"
27
1188e082
DC
28struct avr_opcodes_s
29{
dc191a8f
NC
30 char * name;
31 char * constraints;
32 int insn_size; /* In words. */
33 int isa;
34 unsigned int bin_opcode;
1188e082
DC
35};
36
37#define AVR_INSN(NAME, CONSTR, OPCODE, SIZE, ISA, BIN) \
38{#NAME, CONSTR, SIZE, ISA, BIN},
39
40struct avr_opcodes_s avr_opcodes[] =
41{
42 #include "opcode/avr.h"
43 {NULL, NULL, 0, 0, 0}
44};
45
adde6300
AM
46const char comment_chars[] = ";";
47const char line_comment_chars[] = "#";
48const char line_separator_chars[] = "$";
49
adde6300
AM
50const char *md_shortopts = "m:";
51struct mcu_type_s
52{
53 char *name;
54 int isa;
55 int mach;
56};
57
1f8ae5e6 58/* XXX - devices that don't seem to exist (renamed, replaced with larger
7b21ac3f 59 ones, or planned but never produced), left here for compatibility. */
1f8ae5e6 60
adde6300
AM
61static struct mcu_type_s mcu_types[] =
62{
7b21ac3f
EW
63 {"avr1", AVR_ISA_AVR1, bfd_mach_avr1},
64/* TODO: insruction set for avr2 architecture should be AVR_ISA_AVR2,
65 but set to AVR_ISA_AVR25 for some following version
66 of GCC (from 4.3) for backward compatibility. */
67 {"avr2", AVR_ISA_AVR25, bfd_mach_avr2},
68 {"avr25", AVR_ISA_AVR25, bfd_mach_avr25},
69/* TODO: insruction set for avr3 architecture should be AVR_ISA_AVR3,
70 but set to AVR_ISA_AVR3_ALL for some following version
71 of GCC (from 4.3) for backward compatibility. */
72 {"avr3", AVR_ISA_AVR3_ALL, bfd_mach_avr3},
73 {"avr31", AVR_ISA_AVR31, bfd_mach_avr31},
74 {"avr35", AVR_ISA_AVR35, bfd_mach_avr35},
75 {"avr4", AVR_ISA_AVR4, bfd_mach_avr4},
76/* TODO: insruction set for avr5 architecture should be AVR_ISA_AVR5,
77 but set to AVR_ISA_AVR51 for some following version
78 of GCC (from 4.3) for backward compatibility. */
79 {"avr5", AVR_ISA_AVR51, bfd_mach_avr5},
80 {"avr51", AVR_ISA_AVR51, bfd_mach_avr51},
81 {"avr6", AVR_ISA_AVR6, bfd_mach_avr6},
28c9d252 82 {"at90s1200", AVR_ISA_1200, bfd_mach_avr1},
7b21ac3f
EW
83 {"attiny11", AVR_ISA_AVR1, bfd_mach_avr1},
84 {"attiny12", AVR_ISA_AVR1, bfd_mach_avr1},
85 {"attiny15", AVR_ISA_AVR1, bfd_mach_avr1},
86 {"attiny28", AVR_ISA_AVR1, bfd_mach_avr1},
87 {"at90s2313", AVR_ISA_AVR2, bfd_mach_avr2},
88 {"at90s2323", AVR_ISA_AVR2, bfd_mach_avr2},
89 {"at90s2333", AVR_ISA_AVR2, bfd_mach_avr2}, /* XXX -> 4433 */
90 {"at90s2343", AVR_ISA_AVR2, bfd_mach_avr2},
91 {"attiny22", AVR_ISA_AVR2, bfd_mach_avr2}, /* XXX -> 2343 */
d669d37f 92 {"attiny26", AVR_ISA_2xxe, bfd_mach_avr2},
7b21ac3f
EW
93 {"at90s4414", AVR_ISA_AVR2, bfd_mach_avr2}, /* XXX -> 8515 */
94 {"at90s4433", AVR_ISA_AVR2, bfd_mach_avr2},
95 {"at90s4434", AVR_ISA_AVR2, bfd_mach_avr2}, /* XXX -> 8535 */
96 {"at90s8515", AVR_ISA_AVR2, bfd_mach_avr2},
97 {"at90c8534", AVR_ISA_AVR2, bfd_mach_avr2},
98 {"at90s8535", AVR_ISA_AVR2, bfd_mach_avr2},
99 {"attiny13", AVR_ISA_AVR25, bfd_mach_avr25},
100 {"attiny13a", AVR_ISA_AVR25, bfd_mach_avr25},
101 {"attiny2313", AVR_ISA_AVR25, bfd_mach_avr25},
102 {"attiny24", AVR_ISA_AVR25, bfd_mach_avr25},
103 {"attiny44", AVR_ISA_AVR25, bfd_mach_avr25},
104 {"attiny84", AVR_ISA_AVR25, bfd_mach_avr25},
105 {"attiny25", AVR_ISA_AVR25, bfd_mach_avr25},
106 {"attiny45", AVR_ISA_AVR25, bfd_mach_avr25},
107 {"attiny85", AVR_ISA_AVR25, bfd_mach_avr25},
108 {"attiny261", AVR_ISA_AVR25, bfd_mach_avr25},
109 {"attiny461", AVR_ISA_AVR25, bfd_mach_avr25},
110 {"attiny861", AVR_ISA_AVR25, bfd_mach_avr25},
2b02f87c 111 {"attiny87", AVR_ISA_AVR25, bfd_mach_avr25},
7b21ac3f
EW
112 {"attiny43u", AVR_ISA_AVR25, bfd_mach_avr25},
113 {"attiny48", AVR_ISA_AVR25, bfd_mach_avr25},
114 {"attiny88", AVR_ISA_AVR25, bfd_mach_avr25},
115 {"at86rf401", AVR_ISA_RF401, bfd_mach_avr25},
a53fddce 116 {"ata6289", AVR_ISA_AVR25, bfd_mach_avr25},
7b21ac3f
EW
117 {"at43usb355", AVR_ISA_AVR3, bfd_mach_avr3},
118 {"at76c711", AVR_ISA_AVR3, bfd_mach_avr3},
119 {"atmega103", AVR_ISA_AVR31, bfd_mach_avr31},
120 {"at43usb320", AVR_ISA_AVR31, bfd_mach_avr31},
121 {"attiny167", AVR_ISA_AVR35, bfd_mach_avr35},
2b02f87c 122 {"attiny327", AVR_ISA_AVR35, bfd_mach_avr35},
7b21ac3f
EW
123 {"at90usb82", AVR_ISA_AVR35, bfd_mach_avr35},
124 {"at90usb162", AVR_ISA_AVR35, bfd_mach_avr35},
28c9d252 125 {"atmega8", AVR_ISA_M8, bfd_mach_avr4},
7b21ac3f
EW
126 {"atmega48", AVR_ISA_AVR4, bfd_mach_avr4},
127 {"atmega48p", AVR_ISA_AVR4, bfd_mach_avr4},
128 {"atmega88", AVR_ISA_AVR4, bfd_mach_avr4},
129 {"atmega88p", AVR_ISA_AVR4, bfd_mach_avr4},
28c9d252
NC
130 {"atmega8515", AVR_ISA_M8, bfd_mach_avr4},
131 {"atmega8535", AVR_ISA_M8, bfd_mach_avr4},
7b21ac3f 132 {"atmega8hva", AVR_ISA_AVR4, bfd_mach_avr4},
2b02f87c
NC
133 {"atmega4hvd", AVR_ISA_AVR4, bfd_mach_avr4},
134 {"atmega8hvd", AVR_ISA_AVR4, bfd_mach_avr4},
7b21ac3f
EW
135 {"at90pwm1", AVR_ISA_AVR4, bfd_mach_avr4},
136 {"at90pwm2", AVR_ISA_AVR4, bfd_mach_avr4},
137 {"at90pwm2b", AVR_ISA_AVR4, bfd_mach_avr4},
138 {"at90pwm3", AVR_ISA_AVR4, bfd_mach_avr4},
139 {"at90pwm3b", AVR_ISA_AVR4, bfd_mach_avr4},
2b02f87c 140 {"at90pwm81", AVR_ISA_AVR4, bfd_mach_avr4},
7b21ac3f 141 {"atmega16", AVR_ISA_AVR5, bfd_mach_avr5},
28c9d252 142 {"atmega161", AVR_ISA_M161, bfd_mach_avr5},
7b21ac3f 143 {"atmega162", AVR_ISA_AVR5, bfd_mach_avr5},
28c9d252 144 {"atmega163", AVR_ISA_M161, bfd_mach_avr5},
7b21ac3f
EW
145 {"atmega164p", AVR_ISA_AVR5, bfd_mach_avr5},
146 {"atmega165", AVR_ISA_AVR5, bfd_mach_avr5},
147 {"atmega165p", AVR_ISA_AVR5, bfd_mach_avr5},
148 {"atmega168", AVR_ISA_AVR5, bfd_mach_avr5},
149 {"atmega168p", AVR_ISA_AVR5, bfd_mach_avr5},
150 {"atmega169", AVR_ISA_AVR5, bfd_mach_avr5},
151 {"atmega169p", AVR_ISA_AVR5, bfd_mach_avr5},
152 {"atmega32", AVR_ISA_AVR5, bfd_mach_avr5},
153 {"atmega323", AVR_ISA_AVR5, bfd_mach_avr5},
154 {"atmega324p", AVR_ISA_AVR5, bfd_mach_avr5},
155 {"atmega325", AVR_ISA_AVR5, bfd_mach_avr5},
156 {"atmega325p", AVR_ISA_AVR5, bfd_mach_avr5},
157 {"atmega3250", AVR_ISA_AVR5, bfd_mach_avr5},
158 {"atmega3250p",AVR_ISA_AVR5, bfd_mach_avr5},
159 {"atmega328p", AVR_ISA_AVR5, bfd_mach_avr5},
160 {"atmega329", AVR_ISA_AVR5, bfd_mach_avr5},
161 {"atmega329p", AVR_ISA_AVR5, bfd_mach_avr5},
162 {"atmega3290", AVR_ISA_AVR5, bfd_mach_avr5},
163 {"atmega3290p",AVR_ISA_AVR5, bfd_mach_avr5},
164 {"atmega406", AVR_ISA_AVR5, bfd_mach_avr5},
165 {"atmega64", AVR_ISA_AVR5, bfd_mach_avr5},
166 {"atmega640", AVR_ISA_AVR5, bfd_mach_avr5},
167 {"atmega644", AVR_ISA_AVR5, bfd_mach_avr5},
168 {"atmega644p", AVR_ISA_AVR5, bfd_mach_avr5},
169 {"atmega645", AVR_ISA_AVR5, bfd_mach_avr5},
170 {"atmega649", AVR_ISA_AVR5, bfd_mach_avr5},
171 {"atmega6450", AVR_ISA_AVR5, bfd_mach_avr5},
172 {"atmega6490", AVR_ISA_AVR5, bfd_mach_avr5},
173 {"atmega16hva",AVR_ISA_AVR5, bfd_mach_avr5},
2b02f87c
NC
174 {"atmega16hvb",AVR_ISA_AVR5, bfd_mach_avr5},
175 {"atmega32hvb",AVR_ISA_AVR5, bfd_mach_avr5},
7b21ac3f
EW
176 {"at90can32" , AVR_ISA_AVR5, bfd_mach_avr5},
177 {"at90can64" , AVR_ISA_AVR5, bfd_mach_avr5},
178 {"at90pwm216", AVR_ISA_AVR5, bfd_mach_avr5},
179 {"at90pwm316", AVR_ISA_AVR5, bfd_mach_avr5},
180 {"atmega32c1", AVR_ISA_AVR5, bfd_mach_avr5},
2b02f87c
NC
181 {"atmega64c1", AVR_ISA_AVR5, bfd_mach_avr5},
182 {"atmega16m1", AVR_ISA_AVR5, bfd_mach_avr5},
7b21ac3f 183 {"atmega32m1", AVR_ISA_AVR5, bfd_mach_avr5},
2b02f87c
NC
184 {"atmega64m1", AVR_ISA_AVR5, bfd_mach_avr5},
185 {"atmega16u4", AVR_ISA_AVR5, bfd_mach_avr5},
7b21ac3f 186 {"atmega32u4", AVR_ISA_AVR5, bfd_mach_avr5},
2b02f87c 187 {"atmega32u6", AVR_ISA_AVR5, bfd_mach_avr5},
7b21ac3f
EW
188 {"at90usb646", AVR_ISA_AVR5, bfd_mach_avr5},
189 {"at90usb647", AVR_ISA_AVR5, bfd_mach_avr5},
2b02f87c 190 {"at90scr100", AVR_ISA_AVR5, bfd_mach_avr5},
28c9d252 191 {"at94k", AVR_ISA_94K, bfd_mach_avr5},
7b21ac3f
EW
192 {"atmega128", AVR_ISA_AVR51, bfd_mach_avr51},
193 {"atmega1280", AVR_ISA_AVR51, bfd_mach_avr51},
194 {"atmega1281", AVR_ISA_AVR51, bfd_mach_avr51},
195 {"atmega1284p",AVR_ISA_AVR51, bfd_mach_avr51},
17f4880d 196 {"atmega128rfa1",AVR_ISA_AVR51, bfd_mach_avr51},
7b21ac3f
EW
197 {"at90can128", AVR_ISA_AVR51, bfd_mach_avr51},
198 {"at90usb1286",AVR_ISA_AVR51, bfd_mach_avr51},
199 {"at90usb1287",AVR_ISA_AVR51, bfd_mach_avr51},
2b02f87c
NC
200 {"m3000f", AVR_ISA_AVR51, bfd_mach_avr51},
201 {"m3000s", AVR_ISA_AVR51, bfd_mach_avr51},
202 {"m3001b", AVR_ISA_AVR51, bfd_mach_avr51},
7b21ac3f
EW
203 {"atmega2560", AVR_ISA_AVR6, bfd_mach_avr6},
204 {"atmega2561", AVR_ISA_AVR6, bfd_mach_avr6},
adde6300
AM
205 {NULL, 0, 0}
206};
207
adde6300 208/* Current MCU type. */
7b21ac3f 209static struct mcu_type_s default_mcu = {"avr2", AVR_ISA_AVR2, bfd_mach_avr2};
dc191a8f 210static struct mcu_type_s * avr_mcu = & default_mcu;
adde6300 211
00d2865b
NC
212/* AVR target-specific switches. */
213struct avr_opt_s
214{
dc191a8f
NC
215 int all_opcodes; /* -mall-opcodes: accept all known AVR opcodes. */
216 int no_skip_bug; /* -mno-skip-bug: no warnings for skipping 2-word insns. */
217 int no_wrap; /* -mno-wrap: reject rjmp/rcall with 8K wrap-around. */
00d2865b
NC
218};
219
220static struct avr_opt_s avr_opt = { 0, 0, 0 };
221
adde6300
AM
222const char EXP_CHARS[] = "eE";
223const char FLT_CHARS[] = "dD";
dc191a8f
NC
224
225static void avr_set_arch (int);
adde6300
AM
226
227/* The target specific pseudo-ops which we support. */
228const pseudo_typeS md_pseudo_table[] =
229{
230 {"arch", avr_set_arch, 0},
231 { NULL, NULL, 0}
232};
233
234#define LDI_IMMEDIATE(x) (((x) & 0xf) | (((x) << 4) & 0xf00))
adde6300 235
dc191a8f
NC
236#define EXP_MOD_NAME(i) exp_mod[i].name
237#define EXP_MOD_RELOC(i) exp_mod[i].reloc
238#define EXP_MOD_NEG_RELOC(i) exp_mod[i].neg_reloc
239#define HAVE_PM_P(i) exp_mod[i].have_pm
adde6300
AM
240
241struct exp_mod_s
242{
dc191a8f
NC
243 char * name;
244 bfd_reloc_code_real_type reloc;
245 bfd_reloc_code_real_type neg_reloc;
246 int have_pm;
adde6300
AM
247};
248
c6a7ab1f
NC
249static struct exp_mod_s exp_mod[] =
250{
adde6300
AM
251 {"hh8", BFD_RELOC_AVR_HH8_LDI, BFD_RELOC_AVR_HH8_LDI_NEG, 1},
252 {"pm_hh8", BFD_RELOC_AVR_HH8_LDI_PM, BFD_RELOC_AVR_HH8_LDI_PM_NEG, 0},
253 {"hi8", BFD_RELOC_AVR_HI8_LDI, BFD_RELOC_AVR_HI8_LDI_NEG, 1},
254 {"pm_hi8", BFD_RELOC_AVR_HI8_LDI_PM, BFD_RELOC_AVR_HI8_LDI_PM_NEG, 0},
255 {"lo8", BFD_RELOC_AVR_LO8_LDI, BFD_RELOC_AVR_LO8_LDI_NEG, 1},
256 {"pm_lo8", BFD_RELOC_AVR_LO8_LDI_PM, BFD_RELOC_AVR_LO8_LDI_PM_NEG, 0},
df406460
NC
257 {"hlo8", BFD_RELOC_AVR_HH8_LDI, BFD_RELOC_AVR_HH8_LDI_NEG, 0},
258 {"hhi8", BFD_RELOC_AVR_MS8_LDI, BFD_RELOC_AVR_MS8_LDI_NEG, 0},
adde6300
AM
259};
260
8ad7c533
NC
261/* A union used to store indicies into the exp_mod[] array
262 in a hash table which expects void * data types. */
263typedef union
264{
265 void * ptr;
266 int index;
267} mod_index;
268
adde6300
AM
269/* Opcode hash table. */
270static struct hash_control *avr_hash;
271
272/* Reloc modifiers hash control (hh8,hi8,lo8,pm_xx). */
273static struct hash_control *avr_mod_hash;
274
00d2865b 275#define OPTION_MMCU 'm'
dc191a8f
NC
276enum options
277{
278 OPTION_ALL_OPCODES = OPTION_MD_BASE + 1,
279 OPTION_NO_SKIP_BUG,
280 OPTION_NO_WRAP
281};
adde6300 282
c6a7ab1f
NC
283struct option md_longopts[] =
284{
00d2865b
NC
285 { "mmcu", required_argument, NULL, OPTION_MMCU },
286 { "mall-opcodes", no_argument, NULL, OPTION_ALL_OPCODES },
287 { "mno-skip-bug", no_argument, NULL, OPTION_NO_SKIP_BUG },
288 { "mno-wrap", no_argument, NULL, OPTION_NO_WRAP },
289 { NULL, no_argument, NULL, 0 }
adde6300 290};
adde6300 291
c6a7ab1f 292size_t md_longopts_size = sizeof (md_longopts);
00d2865b
NC
293
294/* Display nicely formatted list of known MCU names. */
c6a7ab1f 295
00d2865b 296static void
dc191a8f 297show_mcu_list (FILE *stream)
00d2865b
NC
298{
299 int i, x;
300
301 fprintf (stream, _("Known MCU names:"));
302 x = 1000;
1dab94dd 303
00d2865b
NC
304 for (i = 0; mcu_types[i].name; i++)
305 {
306 int len = strlen (mcu_types[i].name);
1dab94dd 307
00d2865b 308 x += len + 1;
1dab94dd 309
00d2865b 310 if (x < 75)
c6a7ab1f 311 fprintf (stream, " %s", mcu_types[i].name);
00d2865b
NC
312 else
313 {
314 fprintf (stream, "\n %s", mcu_types[i].name);
315 x = len + 2;
316 }
317 }
1dab94dd 318
c6a7ab1f 319 fprintf (stream, "\n");
00d2865b
NC
320}
321
adde6300 322static inline char *
dc191a8f 323skip_space (char *s)
adde6300
AM
324{
325 while (*s == ' ' || *s == '\t')
326 ++s;
327 return s;
328}
329
330/* Extract one word from FROM and copy it to TO. */
c6a7ab1f 331
adde6300
AM
332static char *
333extract_word (char *from, char *to, int limit)
334{
335 char *op_start;
336 char *op_end;
337 int size = 0;
338
339 /* Drop leading whitespace. */
340 from = skip_space (from);
341 *to = 0;
c6a7ab1f 342
adde6300 343 /* Find the op code end. */
c6a7ab1f 344 for (op_start = op_end = from; *op_end != 0 && is_part_of_name (*op_end);)
adde6300
AM
345 {
346 to[size++] = *op_end++;
347 if (size + 1 >= limit)
348 break;
349 }
1dab94dd 350
adde6300
AM
351 to[size] = 0;
352 return op_end;
353}
354
355int
dc191a8f
NC
356md_estimate_size_before_relax (fragS *fragp ATTRIBUTE_UNUSED,
357 asection *seg ATTRIBUTE_UNUSED)
adde6300
AM
358{
359 abort ();
360 return 0;
361}
362
363void
dc191a8f 364md_show_usage (FILE *stream)
adde6300 365{
00d2865b
NC
366 fprintf (stream,
367 _("AVR options:\n"
adde6300
AM
368 " -mmcu=[avr-name] select microcontroller variant\n"
369 " [avr-name] can be:\n"
7b21ac3f
EW
370 " avr1 - classic AVR core without data RAM\n"
371 " avr2 - classic AVR core with up to 8K program memory\n"
372 " avr25 - classic AVR core with up to 8K program memory\n"
373 " plus the MOVW instruction\n"
374 " avr3 - classic AVR core with up to 64K program memory\n"
375 " avr31 - classic AVR core with up to 128K program memory\n"
376 " avr35 - classic AVR core with up to 64K program memory\n"
377 " plus the MOVW instruction\n"
378 " avr4 - enhanced AVR core with up to 8K program memory\n"
379 " avr5 - enhanced AVR core with up to 64K program memory\n"
380 " avr51 - enhanced AVR core with up to 128K program memory\n"
381 " avr6 - enhanced AVR core with up to 256K program memory\n"
adde6300 382 " or immediate microcontroller name.\n"));
00d2865b
NC
383 fprintf (stream,
384 _(" -mall-opcodes accept all AVR opcodes, even if not supported by MCU\n"
385 " -mno-skip-bug disable warnings for skipping two-word instructions\n"
386 " (default for avr4, avr5)\n"
387 " -mno-wrap reject rjmp/rcall instructions with 8K wrap-around\n"
388 " (default for avr3, avr5)\n"));
389 show_mcu_list (stream);
adde6300
AM
390}
391
392static void
dc191a8f 393avr_set_arch (int dummy ATTRIBUTE_UNUSED)
adde6300 394{
dc191a8f 395 char str[20];
1dab94dd 396
adde6300 397 input_line_pointer = extract_word (input_line_pointer, str, 20);
00d2865b 398 md_parse_option (OPTION_MMCU, str);
adde6300
AM
399 bfd_set_arch_mach (stdoutput, TARGET_ARCH, avr_mcu->mach);
400}
401
402int
dc191a8f 403md_parse_option (int c, char *arg)
adde6300 404{
00d2865b 405 switch (c)
adde6300 406 {
00d2865b
NC
407 case OPTION_MMCU:
408 {
409 int i;
410 char *s = alloca (strlen (arg) + 1);
adde6300 411
00d2865b
NC
412 {
413 char *t = s;
414 char *arg1 = arg;
415
416 do
3882b010 417 *t = TOLOWER (*arg1++);
00d2865b
NC
418 while (*t++);
419 }
420
421 for (i = 0; mcu_types[i].name; ++i)
422 if (strcmp (mcu_types[i].name, s) == 0)
423 break;
adde6300 424
00d2865b
NC
425 if (!mcu_types[i].name)
426 {
427 show_mcu_list (stderr);
428 as_fatal (_("unknown MCU: %s\n"), arg);
429 }
65aa24b6 430
00d2865b
NC
431 /* It is OK to redefine mcu type within the same avr[1-5] bfd machine
432 type - this for allows passing -mmcu=... via gcc ASM_SPEC as well
433 as .arch ... in the asm output at the same time. */
00d2865b
NC
434 if (avr_mcu == &default_mcu || avr_mcu->mach == mcu_types[i].mach)
435 avr_mcu = &mcu_types[i];
436 else
437 as_fatal (_("redefinition of mcu type `%s' to `%s'"),
438 avr_mcu->name, mcu_types[i].name);
439 return 1;
440 }
441 case OPTION_ALL_OPCODES:
442 avr_opt.all_opcodes = 1;
443 return 1;
444 case OPTION_NO_SKIP_BUG:
445 avr_opt.no_skip_bug = 1;
446 return 1;
447 case OPTION_NO_WRAP:
448 avr_opt.no_wrap = 1;
adde6300
AM
449 return 1;
450 }
1dab94dd 451
adde6300
AM
452 return 0;
453}
454
455symbolS *
dc191a8f 456md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
adde6300 457{
dc191a8f 458 return NULL;
adde6300
AM
459}
460
adde6300 461char *
dc191a8f 462md_atof (int type, char *litP, int *sizeP)
adde6300 463{
499ac353 464 return ieee_md_atof (type, litP, sizeP, FALSE);
adde6300
AM
465}
466
467void
dc191a8f
NC
468md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
469 asection *sec ATTRIBUTE_UNUSED,
470 fragS *fragP ATTRIBUTE_UNUSED)
adde6300
AM
471{
472 abort ();
473}
474
adde6300 475void
dc191a8f 476md_begin (void)
adde6300 477{
df136245 478 unsigned int i;
adde6300 479 struct avr_opcodes_s *opcode;
dc191a8f 480
c6a7ab1f 481 avr_hash = hash_new ();
adde6300
AM
482
483 /* Insert unique names into hash table. This hash table then provides a
484 quick index to the first opcode with a particular name in the opcode
485 table. */
adde6300
AM
486 for (opcode = avr_opcodes; opcode->name; opcode++)
487 hash_insert (avr_hash, opcode->name, (char *) opcode);
488
489 avr_mod_hash = hash_new ();
490
dc191a8f 491 for (i = 0; i < ARRAY_SIZE (exp_mod); ++i)
8ad7c533
NC
492 {
493 mod_index m;
494
495 m.index = i + 10;
496 hash_insert (avr_mod_hash, EXP_MOD_NAME (i), m.ptr);
497 }
c6a7ab1f 498
adde6300
AM
499 bfd_set_arch_mach (stdoutput, TARGET_ARCH, avr_mcu->mach);
500}
501
df136245 502/* Resolve STR as a constant expression and return the result.
c6a7ab1f 503 If result greater than MAX then error. */
df136245
DC
504
505static unsigned int
dc191a8f 506avr_get_constant (char *str, int max)
df136245
DC
507{
508 expressionS ex;
dc191a8f 509
df136245
DC
510 str = skip_space (str);
511 input_line_pointer = str;
dc191a8f 512 expression (& ex);
df136245
DC
513
514 if (ex.X_op != O_constant)
515 as_bad (_("constant value required"));
516
517 if (ex.X_add_number > max || ex.X_add_number < 0)
73f4d86e 518 as_bad (_("number must be positive and less than %d"), max + 1);
1dab94dd 519
df136245
DC
520 return ex.X_add_number;
521}
522
dc191a8f 523/* Parse for ldd/std offset. */
df136245 524
dc191a8f
NC
525static void
526avr_offset_expression (expressionS *exp)
adde6300 527{
dc191a8f
NC
528 char *str = input_line_pointer;
529 char *tmp;
530 char op[8];
adde6300 531
dc191a8f
NC
532 tmp = str;
533 str = extract_word (str, op, sizeof (op));
534
535 input_line_pointer = tmp;
536 expression (exp);
537
538 /* Warn about expressions that fail to use lo8 (). */
539 if (exp->X_op == O_constant)
adde6300 540 {
dc191a8f 541 int x = exp->X_add_number;
28c9d252 542
dc191a8f
NC
543 if (x < -255 || x > 255)
544 as_warn (_("constant out of 8-bit range: %d"), x);
545 }
546}
adde6300 547
dc191a8f 548/* Parse ordinary expression. */
adde6300 549
dc191a8f
NC
550static char *
551parse_exp (char *s, expressionS *op)
552{
553 input_line_pointer = s;
554 expression (op);
555 if (op->X_op == O_absent)
556 as_bad (_("missing operand"));
557 return input_line_pointer;
558}
1dab94dd 559
dc191a8f
NC
560/* Parse special expressions (needed for LDI command):
561 xx8 (address)
562 xx8 (-address)
563 pm_xx8 (address)
564 pm_xx8 (-address)
565 where xx is: hh, hi, lo. */
adde6300 566
dc191a8f
NC
567static bfd_reloc_code_real_type
568avr_ldi_expression (expressionS *exp)
569{
570 char *str = input_line_pointer;
571 char *tmp;
572 char op[8];
573 int mod;
28c9d252
NC
574 int linker_stubs_should_be_generated = 0;
575
dc191a8f 576 tmp = str;
adde6300 577
dc191a8f 578 str = extract_word (str, op, sizeof (op));
adde6300 579
dc191a8f
NC
580 if (op[0])
581 {
8ad7c533 582 mod_index m;
28c9d252 583
8ad7c533
NC
584 m.ptr = hash_find (avr_mod_hash, op);
585 mod = m.index;
1dab94dd 586
dc191a8f
NC
587 if (mod)
588 {
589 int closes = 0;
b170af93 590
dc191a8f
NC
591 mod -= 10;
592 str = skip_space (str);
00d2865b 593
dc191a8f
NC
594 if (*str == '(')
595 {
28c9d252 596 bfd_reloc_code_real_type reloc_to_return;
dc191a8f 597 int neg_p = 0;
00d2865b 598
dc191a8f 599 ++str;
00d2865b 600
dc191a8f 601 if (strncmp ("pm(", str, 3) == 0
28c9d252
NC
602 || strncmp ("gs(",str,3) == 0
603 || strncmp ("-(gs(",str,5) == 0
dc191a8f
NC
604 || strncmp ("-(pm(", str, 5) == 0)
605 {
606 if (HAVE_PM_P (mod))
607 {
608 ++mod;
609 ++closes;
610 }
611 else
612 as_bad (_("illegal expression"));
b170af93 613
28c9d252
NC
614 if (str[0] == 'g' || str[2] == 'g')
615 linker_stubs_should_be_generated = 1;
616
dc191a8f
NC
617 if (*str == '-')
618 {
619 neg_p = 1;
620 ++closes;
621 str += 5;
622 }
623 else
624 str += 3;
625 }
adde6300 626
dc191a8f
NC
627 if (*str == '-' && *(str + 1) == '(')
628 {
629 neg_p ^= 1;
630 ++closes;
631 str += 2;
632 }
750bce0e 633
dc191a8f
NC
634 input_line_pointer = str;
635 expression (exp);
750bce0e 636
dc191a8f
NC
637 do
638 {
639 if (*input_line_pointer != ')')
640 {
641 as_bad (_("`)' required"));
642 break;
643 }
644 input_line_pointer++;
645 }
646 while (closes--);
647
28c9d252
NC
648 reloc_to_return =
649 neg_p ? EXP_MOD_NEG_RELOC (mod) : EXP_MOD_RELOC (mod);
650 if (linker_stubs_should_be_generated)
651 {
652 switch (reloc_to_return)
653 {
654 case BFD_RELOC_AVR_LO8_LDI_PM:
655 reloc_to_return = BFD_RELOC_AVR_LO8_LDI_GS;
656 break;
657 case BFD_RELOC_AVR_HI8_LDI_PM:
658 reloc_to_return = BFD_RELOC_AVR_HI8_LDI_GS;
659 break;
660
661 default:
0a903bab
NC
662 /* PR 5523: Do not generate a warning here,
663 legitimate code can trigger this case. */
664 break;
28c9d252
NC
665 }
666 }
667 return reloc_to_return;
dc191a8f
NC
668 }
669 }
670 }
750bce0e
NC
671
672 input_line_pointer = tmp;
673 expression (exp);
674
675 /* Warn about expressions that fail to use lo8 (). */
676 if (exp->X_op == O_constant)
677 {
678 int x = exp->X_add_number;
dc191a8f 679
750bce0e
NC
680 if (x < -255 || x > 255)
681 as_warn (_("constant out of 8-bit range: %d"), x);
682 }
dc191a8f
NC
683
684 return BFD_RELOC_AVR_LDI;
750bce0e
NC
685}
686
df136245 687/* Parse one instruction operand.
c6a7ab1f
NC
688 Return operand bitmask. Also fixups can be generated. */
689
adde6300 690static unsigned int
dc191a8f
NC
691avr_operand (struct avr_opcodes_s *opcode,
692 int where,
693 char *op,
694 char **line)
adde6300 695{
adde6300 696 expressionS op_expr;
df136245
DC
697 unsigned int op_mask = 0;
698 char *str = skip_space (*line);
adde6300 699
adde6300
AM
700 switch (*op)
701 {
702 /* Any register operand. */
703 case 'w':
704 case 'd':
705 case 'r':
b170af93
DC
706 case 'a':
707 case 'v':
c6a7ab1f
NC
708 if (*str == 'r' || *str == 'R')
709 {
710 char r_name[20];
1dab94dd 711
c6a7ab1f 712 str = extract_word (str, r_name, sizeof (r_name));
65b1d096 713 op_mask = 0xff;
3882b010 714 if (ISDIGIT (r_name[1]))
c6a7ab1f
NC
715 {
716 if (r_name[2] == '\0')
717 op_mask = r_name[1] - '0';
718 else if (r_name[1] != '0'
3882b010 719 && ISDIGIT (r_name[2])
c6a7ab1f
NC
720 && r_name[3] == '\0')
721 op_mask = (r_name[1] - '0') * 10 + r_name[2] - '0';
722 }
723 }
724 else
725 {
726 op_mask = avr_get_constant (str, 31);
727 str = input_line_pointer;
728 }
1dab94dd 729
c6a7ab1f
NC
730 if (op_mask <= 31)
731 {
732 switch (*op)
733 {
734 case 'a':
735 if (op_mask < 16 || op_mask > 23)
736 as_bad (_("register r16-r23 required"));
737 op_mask -= 16;
738 break;
1dab94dd 739
c6a7ab1f
NC
740 case 'd':
741 if (op_mask < 16)
742 as_bad (_("register number above 15 required"));
743 op_mask -= 16;
744 break;
1dab94dd 745
c6a7ab1f
NC
746 case 'v':
747 if (op_mask & 1)
748 as_bad (_("even register number required"));
749 op_mask >>= 1;
750 break;
1dab94dd 751
c6a7ab1f 752 case 'w':
65b1d096 753 if ((op_mask & 1) || op_mask < 24)
c6a7ab1f 754 as_bad (_("register r24, r26, r28 or r30 required"));
65b1d096 755 op_mask = (op_mask - 24) >> 1;
c6a7ab1f
NC
756 break;
757 }
758 break;
759 }
760 as_bad (_("register name or number from 0 to 31 required"));
adde6300
AM
761 break;
762
763 case 'e':
764 {
765 char c;
1dab94dd 766
adde6300
AM
767 if (*str == '-')
768 {
c6a7ab1f 769 str = skip_space (str + 1);
adde6300
AM
770 op_mask = 0x1002;
771 }
3882b010 772 c = TOLOWER (*str);
adde6300
AM
773 if (c == 'x')
774 op_mask |= 0x100c;
775 else if (c == 'y')
776 op_mask |= 0x8;
777 else if (c != 'z')
00d2865b 778 as_bad (_("pointer register (X, Y or Z) required"));
adde6300 779
c6a7ab1f 780 str = skip_space (str + 1);
adde6300
AM
781 if (*str == '+')
782 {
783 ++str;
784 if (op_mask & 2)
00d2865b 785 as_bad (_("cannot both predecrement and postincrement"));
adde6300
AM
786 op_mask |= 0x1001;
787 }
e38c9cc2 788
1188e082 789 /* avr1 can do "ld r,Z" and "st Z,r" but no other pointer
e38c9cc2 790 registers, no predecrement, no postincrement. */
00d2865b
NC
791 if (!avr_opt.all_opcodes && (op_mask & 0x100F)
792 && !(avr_mcu->isa & AVR_ISA_SRAM))
793 as_bad (_("addressing mode not supported"));
adde6300
AM
794 }
795 break;
796
b170af93 797 case 'z':
c6a7ab1f
NC
798 if (*str == '-')
799 as_bad (_("can't predecrement"));
1dab94dd 800
c6a7ab1f
NC
801 if (! (*str == 'z' || *str == 'Z'))
802 as_bad (_("pointer register Z required"));
1dab94dd 803
c6a7ab1f
NC
804 str = skip_space (str + 1);
805
806 if (*str == '+')
807 {
808 ++str;
809 op_mask |= 1;
810 }
d669d37f
NC
811
812 /* attiny26 can do "lpm" and "lpm r,Z" but not "lpm r,Z+". */
813 if (!avr_opt.all_opcodes
814 && (op_mask & 0x0001)
815 && !(avr_mcu->isa & AVR_ISA_MOVW))
816 as_bad (_("postincrement not supported"));
b170af93
DC
817 break;
818
adde6300
AM
819 case 'b':
820 {
3882b010 821 char c = TOLOWER (*str++);
1dab94dd 822
adde6300
AM
823 if (c == 'y')
824 op_mask |= 0x8;
825 else if (c != 'z')
00d2865b 826 as_bad (_("pointer register (Y or Z) required"));
adde6300
AM
827 str = skip_space (str);
828 if (*str++ == '+')
829 {
750bce0e
NC
830 input_line_pointer = str;
831 avr_offset_expression (& op_expr);
adde6300 832 str = input_line_pointer;
750bce0e
NC
833 fix_new_exp (frag_now, where, 3,
834 &op_expr, FALSE, BFD_RELOC_AVR_6);
adde6300
AM
835 }
836 }
837 break;
838
839 case 'h':
c6a7ab1f
NC
840 str = parse_exp (str, &op_expr);
841 fix_new_exp (frag_now, where, opcode->insn_size * 2,
b34976b6 842 &op_expr, FALSE, BFD_RELOC_AVR_CALL);
adde6300
AM
843 break;
844
845 case 'L':
c6a7ab1f
NC
846 str = parse_exp (str, &op_expr);
847 fix_new_exp (frag_now, where, opcode->insn_size * 2,
b34976b6 848 &op_expr, TRUE, BFD_RELOC_AVR_13_PCREL);
adde6300
AM
849 break;
850
851 case 'l':
c6a7ab1f
NC
852 str = parse_exp (str, &op_expr);
853 fix_new_exp (frag_now, where, opcode->insn_size * 2,
b34976b6 854 &op_expr, TRUE, BFD_RELOC_AVR_7_PCREL);
adde6300
AM
855 break;
856
857 case 'i':
c6a7ab1f
NC
858 str = parse_exp (str, &op_expr);
859 fix_new_exp (frag_now, where + 2, opcode->insn_size * 2,
b34976b6 860 &op_expr, FALSE, BFD_RELOC_16);
adde6300
AM
861 break;
862
863 case 'M':
864 {
865 bfd_reloc_code_real_type r_type;
1dab94dd 866
c6a7ab1f
NC
867 input_line_pointer = str;
868 r_type = avr_ldi_expression (&op_expr);
869 str = input_line_pointer;
adde6300 870 fix_new_exp (frag_now, where, 3,
b34976b6 871 &op_expr, FALSE, r_type);
adde6300
AM
872 }
873 break;
874
875 case 'n':
876 {
877 unsigned int x;
1dab94dd 878
adde6300
AM
879 x = ~avr_get_constant (str, 255);
880 str = input_line_pointer;
881 op_mask |= (x & 0xf) | ((x << 4) & 0xf00);
882 }
883 break;
884
885 case 'K':
750bce0e
NC
886 input_line_pointer = str;
887 avr_offset_expression (& op_expr);
888 str = input_line_pointer;
889 fix_new_exp (frag_now, where, 3,
890 & op_expr, FALSE, BFD_RELOC_AVR_6_ADIW);
adde6300
AM
891 break;
892
893 case 'S':
894 case 's':
895 {
896 unsigned int x;
1dab94dd 897
adde6300
AM
898 x = avr_get_constant (str, 7);
899 str = input_line_pointer;
900 if (*op == 'S')
901 x <<= 4;
902 op_mask |= x;
903 }
904 break;
905
906 case 'P':
907 {
908 unsigned int x;
1dab94dd 909
adde6300
AM
910 x = avr_get_constant (str, 63);
911 str = input_line_pointer;
912 op_mask |= (x & 0xf) | ((x & 0x30) << 5);
913 }
914 break;
915
916 case 'p':
917 {
918 unsigned int x;
1dab94dd 919
adde6300
AM
920 x = avr_get_constant (str, 31);
921 str = input_line_pointer;
922 op_mask |= x << 3;
923 }
924 break;
1dab94dd 925
1188e082
DC
926 case '?':
927 break;
1dab94dd 928
adde6300 929 default:
00d2865b 930 as_bad (_("unknown constraint `%c'"), *op);
adde6300 931 }
1dab94dd 932
adde6300
AM
933 *line = str;
934 return op_mask;
935}
936
dc191a8f
NC
937/* Parse instruction operands.
938 Return binary opcode. */
939
940static unsigned int
941avr_operands (struct avr_opcodes_s *opcode, char **line)
942{
943 char *op = opcode->constraints;
944 unsigned int bin = opcode->bin_opcode;
945 char *frag = frag_more (opcode->insn_size * 2);
946 char *str = *line;
947 int where = frag - frag_now->fr_literal;
948 static unsigned int prev = 0; /* Previous opcode. */
949
950 /* Opcode have operands. */
951 if (*op)
952 {
953 unsigned int reg1 = 0;
954 unsigned int reg2 = 0;
955 int reg1_present = 0;
956 int reg2_present = 0;
957
958 /* Parse first operand. */
959 if (REGISTER_P (*op))
960 reg1_present = 1;
961 reg1 = avr_operand (opcode, where, op, &str);
962 ++op;
963
964 /* Parse second operand. */
965 if (*op)
966 {
967 if (*op == ',')
968 ++op;
969
970 if (*op == '=')
971 {
972 reg2 = reg1;
973 reg2_present = 1;
974 }
975 else
976 {
977 if (REGISTER_P (*op))
978 reg2_present = 1;
979
980 str = skip_space (str);
981 if (*str++ != ',')
982 as_bad (_("`,' required"));
983 str = skip_space (str);
984
985 reg2 = avr_operand (opcode, where, op, &str);
986 }
987
988 if (reg1_present && reg2_present)
989 reg2 = (reg2 & 0xf) | ((reg2 << 5) & 0x200);
990 else if (reg2_present)
991 reg2 <<= 4;
992 }
993 if (reg1_present)
994 reg1 <<= 4;
995 bin |= reg1 | reg2;
996 }
997
998 /* Detect undefined combinations (like ld r31,Z+). */
999 if (!avr_opt.all_opcodes && AVR_UNDEF_P (bin))
1000 as_warn (_("undefined combination of operands"));
1001
1002 if (opcode->insn_size == 2)
1003 {
1004 /* Warn if the previous opcode was cpse/sbic/sbis/sbrc/sbrs
1005 (AVR core bug, fixed in the newer devices). */
1006 if (!(avr_opt.no_skip_bug ||
1007 (avr_mcu->isa & (AVR_ISA_MUL | AVR_ISA_MOVW)))
1008 && AVR_SKIP_P (prev))
1009 as_warn (_("skipping two-word instruction"));
1010
1011 bfd_putl32 ((bfd_vma) bin, frag);
1012 }
1013 else
1014 bfd_putl16 ((bfd_vma) bin, frag);
1015
1016 prev = bin;
1017 *line = str;
1018 return bin;
1019}
1020
adde6300
AM
1021/* GAS will call this function for each section at the end of the assembly,
1022 to permit the CPU backend to adjust the alignment of a section. */
c6a7ab1f 1023
adde6300 1024valueT
dc191a8f 1025md_section_align (asection *seg, valueT addr)
adde6300
AM
1026{
1027 int align = bfd_get_section_alignment (stdoutput, seg);
1028 return ((addr + (1 << align) - 1) & (-1 << align));
1029}
1030
1031/* If you define this macro, it should return the offset between the
1032 address of a PC relative fixup and the position from which the PC
1033 relative adjustment should be made. On many processors, the base
1034 of a PC relative instruction is the next instruction, so this
1035 macro would return the length of an instruction. */
c6a7ab1f 1036
adde6300 1037long
dc191a8f 1038md_pcrel_from_section (fixS *fixp, segT sec)
adde6300 1039{
c6a7ab1f 1040 if (fixp->fx_addsy != (symbolS *) NULL
adde6300
AM
1041 && (!S_IS_DEFINED (fixp->fx_addsy)
1042 || (S_GET_SEGMENT (fixp->fx_addsy) != sec)))
1043 return 0;
1dab94dd 1044
adde6300
AM
1045 return fixp->fx_frag->fr_address + fixp->fx_where;
1046}
1047
1048/* GAS will call this for each fixup. It should store the correct
c6a7ab1f
NC
1049 value in the object file. */
1050
94f592af 1051void
dc191a8f 1052md_apply_fix (fixS *fixP, valueT * valP, segT seg)
adde6300
AM
1053{
1054 unsigned char *where;
1055 unsigned long insn;
a161fe53 1056 long value = *valP;
adde6300 1057
94f592af
NC
1058 if (fixP->fx_addsy == (symbolS *) NULL)
1059 fixP->fx_done = 1;
1060
87733541
AM
1061 else if (fixP->fx_pcrel)
1062 {
1063 segT s = S_GET_SEGMENT (fixP->fx_addsy);
1064
1065 if (s == seg || s == absolute_section)
1066 {
1067 value += S_GET_VALUE (fixP->fx_addsy);
1068 fixP->fx_done = 1;
1069 }
1070 }
1071
a161fe53
AM
1072 /* We don't actually support subtracting a symbol. */
1073 if (fixP->fx_subsy != (symbolS *) NULL)
1074 as_bad_where (fixP->fx_file, fixP->fx_line, _("expression too complex"));
1dab94dd 1075
94f592af 1076 switch (fixP->fx_r_type)
adde6300
AM
1077 {
1078 default:
94f592af 1079 fixP->fx_no_overflow = 1;
adde6300
AM
1080 break;
1081 case BFD_RELOC_AVR_7_PCREL:
1082 case BFD_RELOC_AVR_13_PCREL:
1083 case BFD_RELOC_32:
1084 case BFD_RELOC_16:
1085 case BFD_RELOC_AVR_CALL:
1086 break;
1087 }
1088
94f592af 1089 if (fixP->fx_done)
adde6300
AM
1090 {
1091 /* Fetch the instruction, insert the fully resolved operand
1092 value, and stuff the instruction back again. */
2132e3a3 1093 where = (unsigned char *) fixP->fx_frag->fr_literal + fixP->fx_where;
adde6300
AM
1094 insn = bfd_getl16 (where);
1095
94f592af 1096 switch (fixP->fx_r_type)
adde6300
AM
1097 {
1098 case BFD_RELOC_AVR_7_PCREL:
1099 if (value & 1)
94f592af 1100 as_bad_where (fixP->fx_file, fixP->fx_line,
adde6300 1101 _("odd address operand: %ld"), value);
1dab94dd 1102
adde6300
AM
1103 /* Instruction addresses are always right-shifted by 1. */
1104 value >>= 1;
1105 --value; /* Correct PC. */
1dab94dd 1106
adde6300 1107 if (value < -64 || value > 63)
94f592af 1108 as_bad_where (fixP->fx_file, fixP->fx_line,
adde6300
AM
1109 _("operand out of range: %ld"), value);
1110 value = (value << 3) & 0x3f8;
1111 bfd_putl16 ((bfd_vma) (value | insn), where);
1112 break;
1113
1114 case BFD_RELOC_AVR_13_PCREL:
1115 if (value & 1)
94f592af 1116 as_bad_where (fixP->fx_file, fixP->fx_line,
adde6300 1117 _("odd address operand: %ld"), value);
1dab94dd 1118
adde6300
AM
1119 /* Instruction addresses are always right-shifted by 1. */
1120 value >>= 1;
1121 --value; /* Correct PC. */
adde6300
AM
1122
1123 if (value < -2048 || value > 2047)
1124 {
65aa24b6 1125 /* No wrap for devices with >8K of program memory. */
00d2865b 1126 if ((avr_mcu->isa & AVR_ISA_MEGA) || avr_opt.no_wrap)
94f592af 1127 as_bad_where (fixP->fx_file, fixP->fx_line,
adde6300
AM
1128 _("operand out of range: %ld"), value);
1129 }
1130
1131 value &= 0xfff;
1132 bfd_putl16 ((bfd_vma) (value | insn), where);
1133 break;
1134
1135 case BFD_RELOC_32:
1136 bfd_putl16 ((bfd_vma) value, where);
1137 break;
1138
1139 case BFD_RELOC_16:
1140 bfd_putl16 ((bfd_vma) value, where);
1141 break;
1142
1143 case BFD_RELOC_AVR_16_PM:
c6a7ab1f 1144 bfd_putl16 ((bfd_vma) (value >> 1), where);
adde6300
AM
1145 break;
1146
750bce0e
NC
1147 case BFD_RELOC_AVR_LDI:
1148 if (value > 255)
1149 as_bad_where (fixP->fx_file, fixP->fx_line,
1150 _("operand out of range: %ld"), value);
1151 bfd_putl16 ((bfd_vma) insn | LDI_IMMEDIATE (value), where);
1152 break;
1153
1154 case BFD_RELOC_AVR_6:
1155 if ((value > 63) || (value < 0))
1156 as_bad_where (fixP->fx_file, fixP->fx_line,
1157 _("operand out of range: %ld"), value);
1158 bfd_putl16 ((bfd_vma) insn | ((value & 7) | ((value & (3 << 3)) << 7) | ((value & (1 << 5)) << 8)), where);
1159 break;
1160
1161 case BFD_RELOC_AVR_6_ADIW:
1162 if ((value > 63) || (value < 0))
1163 as_bad_where (fixP->fx_file, fixP->fx_line,
1164 _("operand out of range: %ld"), value);
1165 bfd_putl16 ((bfd_vma) insn | (value & 0xf) | ((value & 0x30) << 2), where);
1166 break;
1167
adde6300
AM
1168 case BFD_RELOC_AVR_LO8_LDI:
1169 bfd_putl16 ((bfd_vma) insn | LDI_IMMEDIATE (value), where);
1170 break;
1171
adde6300
AM
1172 case BFD_RELOC_AVR_HI8_LDI:
1173 bfd_putl16 ((bfd_vma) insn | LDI_IMMEDIATE (value >> 8), where);
1174 break;
1175
df406460 1176 case BFD_RELOC_AVR_MS8_LDI:
adde6300
AM
1177 bfd_putl16 ((bfd_vma) insn | LDI_IMMEDIATE (value >> 24), where);
1178 break;
1179
1180 case BFD_RELOC_AVR_HH8_LDI:
1181 bfd_putl16 ((bfd_vma) insn | LDI_IMMEDIATE (value >> 16), where);
1182 break;
1183
1184 case BFD_RELOC_AVR_LO8_LDI_NEG:
1185 bfd_putl16 ((bfd_vma) insn | LDI_IMMEDIATE (-value), where);
1186 break;
1187
adde6300
AM
1188 case BFD_RELOC_AVR_HI8_LDI_NEG:
1189 bfd_putl16 ((bfd_vma) insn | LDI_IMMEDIATE (-value >> 8), where);
1190 break;
1191
df406460 1192 case BFD_RELOC_AVR_MS8_LDI_NEG:
adde6300
AM
1193 bfd_putl16 ((bfd_vma) insn | LDI_IMMEDIATE (-value >> 24), where);
1194 break;
1195
1196 case BFD_RELOC_AVR_HH8_LDI_NEG:
1197 bfd_putl16 ((bfd_vma) insn | LDI_IMMEDIATE (-value >> 16), where);
1198 break;
1199
1200 case BFD_RELOC_AVR_LO8_LDI_PM:
1201 bfd_putl16 ((bfd_vma) insn | LDI_IMMEDIATE (value >> 1), where);
1202 break;
1203
1204 case BFD_RELOC_AVR_HI8_LDI_PM:
1205 bfd_putl16 ((bfd_vma) insn | LDI_IMMEDIATE (value >> 9), where);
1206 break;
1207
1208 case BFD_RELOC_AVR_HH8_LDI_PM:
1209 bfd_putl16 ((bfd_vma) insn | LDI_IMMEDIATE (value >> 17), where);
1210 break;
1211
1212 case BFD_RELOC_AVR_LO8_LDI_PM_NEG:
1213 bfd_putl16 ((bfd_vma) insn | LDI_IMMEDIATE (-value >> 1), where);
1214 break;
1215
1216 case BFD_RELOC_AVR_HI8_LDI_PM_NEG:
1217 bfd_putl16 ((bfd_vma) insn | LDI_IMMEDIATE (-value >> 9), where);
1218 break;
1219
1220 case BFD_RELOC_AVR_HH8_LDI_PM_NEG:
1221 bfd_putl16 ((bfd_vma) insn | LDI_IMMEDIATE (-value >> 17), where);
1222 break;
1223
1224 case BFD_RELOC_AVR_CALL:
1225 {
1226 unsigned long x;
1dab94dd 1227
adde6300
AM
1228 x = bfd_getl16 (where);
1229 if (value & 1)
94f592af 1230 as_bad_where (fixP->fx_file, fixP->fx_line,
adde6300
AM
1231 _("odd address operand: %ld"), value);
1232 value >>= 1;
1233 x |= ((value & 0x10000) | ((value << 3) & 0x1f00000)) >> 16;
1234 bfd_putl16 ((bfd_vma) x, where);
c6a7ab1f 1235 bfd_putl16 ((bfd_vma) (value & 0xffff), where + 2);
adde6300
AM
1236 }
1237 break;
1238
1239 default:
c6a7ab1f 1240 as_fatal (_("line %d: unknown relocation type: 0x%x"),
94f592af 1241 fixP->fx_line, fixP->fx_r_type);
adde6300
AM
1242 break;
1243 }
1244 }
1245 else
1246 {
94f592af 1247 switch (fixP->fx_r_type)
adde6300
AM
1248 {
1249 case -BFD_RELOC_AVR_HI8_LDI_NEG:
1250 case -BFD_RELOC_AVR_HI8_LDI:
1251 case -BFD_RELOC_AVR_LO8_LDI_NEG:
1252 case -BFD_RELOC_AVR_LO8_LDI:
94f592af 1253 as_bad_where (fixP->fx_file, fixP->fx_line,
adde6300 1254 _("only constant expression allowed"));
94f592af 1255 fixP->fx_done = 1;
adde6300
AM
1256 break;
1257 default:
1258 break;
1259 }
adde6300 1260 }
adde6300
AM
1261}
1262
7be1c489
AM
1263/* GAS will call this to generate a reloc, passing the resulting reloc
1264 to `bfd_install_relocation'. This currently works poorly, as
1265 `bfd_install_relocation' often does the wrong thing, and instances of
1266 `tc_gen_reloc' have been written to work around the problems, which
1267 in turns makes it difficult to fix `bfd_install_relocation'. */
adde6300
AM
1268
1269/* If while processing a fixup, a reloc really needs to be created
1270 then it is done here. */
1271
1272arelent *
dc191a8f
NC
1273tc_gen_reloc (asection *seg ATTRIBUTE_UNUSED,
1274 fixS *fixp)
adde6300
AM
1275{
1276 arelent *reloc;
1277
df406460
NC
1278 if (fixp->fx_addsy && fixp->fx_subsy)
1279 {
1280 long value = 0;
1281
1282 if ((S_GET_SEGMENT (fixp->fx_addsy) != S_GET_SEGMENT (fixp->fx_subsy))
1283 || S_GET_SEGMENT (fixp->fx_addsy) == undefined_section)
1284 {
1285 as_bad_where (fixp->fx_file, fixp->fx_line,
1286 "Difference of symbols in different sections is not supported");
1287 return NULL;
1288 }
1289
28c9d252 1290 /* We are dealing with two symbols defined in the same section.
df406460
NC
1291 Let us fix-up them here. */
1292 value += S_GET_VALUE (fixp->fx_addsy);
1293 value -= S_GET_VALUE (fixp->fx_subsy);
1294
1295 /* When fx_addsy and fx_subsy both are zero, md_apply_fix
1296 only takes it's second operands for the fixup value. */
1297 fixp->fx_addsy = NULL;
1298 fixp->fx_subsy = NULL;
1299 md_apply_fix (fixp, (valueT *) &value, NULL);
1300
1301 return NULL;
1302 }
1303
dc191a8f 1304 reloc = xmalloc (sizeof (arelent));
adde6300 1305
dc191a8f 1306 reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
adde6300
AM
1307 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
1308
1309 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
1310 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
1311 if (reloc->howto == (reloc_howto_type *) NULL)
1312 {
1313 as_bad_where (fixp->fx_file, fixp->fx_line,
c6a7ab1f
NC
1314 _("reloc %d not supported by object file format"),
1315 (int) fixp->fx_r_type);
adde6300
AM
1316 return NULL;
1317 }
1318
1319 if (fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT
1320 || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
1321 reloc->address = fixp->fx_offset;
1322
1323 reloc->addend = fixp->fx_offset;
1324
1325 return reloc;
1326}
1327
adde6300 1328void
dc191a8f 1329md_assemble (char *str)
adde6300 1330{
c6a7ab1f 1331 struct avr_opcodes_s *opcode;
adde6300
AM
1332 char op[11];
1333
c6a7ab1f 1334 str = skip_space (extract_word (str, op, sizeof (op)));
adde6300
AM
1335
1336 if (!op[0])
00d2865b 1337 as_bad (_("can't find opcode "));
adde6300
AM
1338
1339 opcode = (struct avr_opcodes_s *) hash_find (avr_hash, op);
1340
1341 if (opcode == NULL)
1342 {
00d2865b 1343 as_bad (_("unknown opcode `%s'"), op);
adde6300
AM
1344 return;
1345 }
1346
b170af93 1347 /* Special case for opcodes with optional operands (lpm, elpm) -
1188e082 1348 version with operands exists in avr_opcodes[] in the next entry. */
c6a7ab1f 1349
1188e082
DC
1350 if (*str && *opcode->constraints == '?')
1351 ++opcode;
b170af93 1352
00d2865b
NC
1353 if (!avr_opt.all_opcodes && (opcode->isa & avr_mcu->isa) != opcode->isa)
1354 as_bad (_("illegal opcode %s for mcu %s"), opcode->name, avr_mcu->name);
adde6300
AM
1355
1356 /* We used to set input_line_pointer to the result of get_operands,
1357 but that is wrong. Our caller assumes we don't change it. */
1358 {
1359 char *t = input_line_pointer;
dc191a8f 1360
adde6300 1361 avr_operands (opcode, &str);
b170af93 1362 if (*skip_space (str))
00d2865b 1363 as_bad (_("garbage at end of line"));
adde6300
AM
1364 input_line_pointer = t;
1365 }
1366}
1367
adde6300 1368/* Flag to pass `pm' mode between `avr_parse_cons_expression' and
c6a7ab1f 1369 `avr_cons_fix_new'. */
adde6300
AM
1370static int exp_mod_pm = 0;
1371
1372/* Parse special CONS expression: pm (expression)
28c9d252
NC
1373 or alternatively: gs (expression).
1374 These are used for addressing program memory.
c6a7ab1f
NC
1375 Relocation: BFD_RELOC_AVR_16_PM. */
1376
adde6300 1377void
dc191a8f 1378avr_parse_cons_expression (expressionS *exp, int nbytes)
adde6300 1379{
c6a7ab1f 1380 char *tmp;
adde6300
AM
1381
1382 exp_mod_pm = 0;
1383
1384 tmp = input_line_pointer = skip_space (input_line_pointer);
1385
1386 if (nbytes == 2)
1387 {
28c9d252
NC
1388 char *pm_name1 = "pm";
1389 char *pm_name2 = "gs";
1390 int len = strlen (pm_name1);
1391 /* len must be the same for both pm identifiers. */
1dab94dd 1392
28c9d252
NC
1393 if (strncasecmp (input_line_pointer, pm_name1, len) == 0
1394 || strncasecmp (input_line_pointer, pm_name2, len) == 0)
adde6300
AM
1395 {
1396 input_line_pointer = skip_space (input_line_pointer + len);
1dab94dd 1397
adde6300
AM
1398 if (*input_line_pointer == '(')
1399 {
1400 input_line_pointer = skip_space (input_line_pointer + 1);
1401 exp_mod_pm = 1;
1402 expression (exp);
1dab94dd 1403
adde6300
AM
1404 if (*input_line_pointer == ')')
1405 ++input_line_pointer;
1406 else
1407 {
00d2865b 1408 as_bad (_("`)' required"));
adde6300
AM
1409 exp_mod_pm = 0;
1410 }
1dab94dd 1411
adde6300
AM
1412 return;
1413 }
1dab94dd 1414
adde6300
AM
1415 input_line_pointer = tmp;
1416 }
1417 }
1dab94dd 1418
adde6300
AM
1419 expression (exp);
1420}
1421
1422void
dc191a8f
NC
1423avr_cons_fix_new (fragS *frag,
1424 int where,
1425 int nbytes,
1426 expressionS *exp)
adde6300
AM
1427{
1428 if (exp_mod_pm == 0)
1429 {
1430 if (nbytes == 2)
b34976b6 1431 fix_new_exp (frag, where, nbytes, exp, FALSE, BFD_RELOC_16);
adde6300 1432 else if (nbytes == 4)
b34976b6 1433 fix_new_exp (frag, where, nbytes, exp, FALSE, BFD_RELOC_32);
adde6300 1434 else
00d2865b 1435 as_bad (_("illegal %srelocation size: %d"), "", nbytes);
adde6300
AM
1436 }
1437 else
1438 {
1439 if (nbytes == 2)
b34976b6 1440 fix_new_exp (frag, where, nbytes, exp, FALSE, BFD_RELOC_AVR_16_PM);
adde6300 1441 else
00d2865b 1442 as_bad (_("illegal %srelocation size: %d"), "`pm' ", nbytes);
adde6300
AM
1443 exp_mod_pm = 0;
1444 }
1445}
This page took 0.448415 seconds and 4 git commands to generate.