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