PR gas/5228
[deliverable/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},
28c9d252
NC
71 {"attiny11", AVR_ISA_TINY1, bfd_mach_avr1},
72 {"attiny12", AVR_ISA_TINY1, bfd_mach_avr1},
73 {"attiny15", AVR_ISA_TINY1, bfd_mach_avr1},
74 {"attiny28", AVR_ISA_TINY1, bfd_mach_avr1},
75 {"at90s2313", AVR_ISA_2xxx, bfd_mach_avr2},
76 {"at90s2323", AVR_ISA_2xxx, bfd_mach_avr2},
77 {"at90s2333", AVR_ISA_2xxx, bfd_mach_avr2}, /* XXX -> 4433 */
78 {"at90s2343", AVR_ISA_2xxx, bfd_mach_avr2},
79 {"attiny22", AVR_ISA_2xxx, bfd_mach_avr2}, /* XXX -> 2343 */
80 {"attiny26", AVR_ISA_2xxx, bfd_mach_avr2},
81 {"at90s4433", AVR_ISA_2xxx, bfd_mach_avr2},
82 {"at90s4414", AVR_ISA_2xxx, bfd_mach_avr2}, /* XXX -> 8515 */
83 {"at90s4434", AVR_ISA_2xxx, bfd_mach_avr2}, /* XXX -> 8535 */
84 {"at90s8515", AVR_ISA_2xxx, bfd_mach_avr2},
85 {"at90s8535", AVR_ISA_2xxx, bfd_mach_avr2},
86 {"at90c8534", AVR_ISA_2xxx, bfd_mach_avr2},
87 {"at86rf401", AVR_ISA_2xxx, bfd_mach_avr2},
88 {"attiny13", AVR_ISA_TINY2, bfd_mach_avr2},
89 {"attiny2313", AVR_ISA_TINY2, bfd_mach_avr2},
90 {"attiny261", AVR_ISA_TINY2, bfd_mach_avr2},
91 {"attiny461", AVR_ISA_TINY2, bfd_mach_avr2},
92 {"attiny861", AVR_ISA_TINY2, bfd_mach_avr2},
93 {"attiny24", AVR_ISA_TINY2, bfd_mach_avr2},
94 {"attiny44", AVR_ISA_TINY2, bfd_mach_avr2},
95 {"attiny84", AVR_ISA_TINY2, bfd_mach_avr2},
96 {"attiny25", AVR_ISA_TINY2, bfd_mach_avr2},
97 {"attiny45", AVR_ISA_TINY2, bfd_mach_avr2},
98 {"attiny85", AVR_ISA_TINY2, bfd_mach_avr2},
922f0bac
NC
99 {"attiny43u", AVR_ISA_TINY2, bfd_mach_avr2},
100 {"attiny48", AVR_ISA_TINY2, bfd_mach_avr2},
28c9d252
NC
101 {"atmega103", AVR_ISA_M103, bfd_mach_avr3},
102 {"at43usb320", AVR_ISA_M103, bfd_mach_avr3},
103 {"at43usb355", AVR_ISA_M603, bfd_mach_avr3},
104 {"at76c711", AVR_ISA_M603, bfd_mach_avr3},
105 {"atmega48", AVR_ISA_PWMx, bfd_mach_avr4},
106 {"atmega8", AVR_ISA_M8, bfd_mach_avr4},
28c9d252
NC
107 {"atmega88", AVR_ISA_PWMx, bfd_mach_avr4},
108 {"atmega8515", AVR_ISA_M8, bfd_mach_avr4},
109 {"atmega8535", AVR_ISA_M8, bfd_mach_avr4},
8eb2af8e 110 {"atmega8hva", AVR_ISA_PWMx, bfd_mach_avr4},
7b60f473 111 {"at90pwm1", AVR_ISA_PWMx, bfd_mach_avr4},
28c9d252 112 {"at90pwm2", AVR_ISA_PWMx, bfd_mach_avr4},
7337fc21 113 {"at90pwm2b", AVR_ISA_PWMx, bfd_mach_avr4},
28c9d252 114 {"at90pwm3", AVR_ISA_PWMx, bfd_mach_avr4},
7337fc21 115 {"at90pwm3b", AVR_ISA_PWMx, bfd_mach_avr4},
28c9d252
NC
116 {"atmega16", AVR_ISA_M323, bfd_mach_avr5},
117 {"atmega161", AVR_ISA_M161, bfd_mach_avr5},
118 {"atmega162", AVR_ISA_M323, bfd_mach_avr5},
119 {"atmega163", AVR_ISA_M161, bfd_mach_avr5},
026dcbd7 120 {"atmega164p", AVR_ISA_M323, bfd_mach_avr5},
28c9d252 121 {"atmega165", AVR_ISA_M323, bfd_mach_avr5},
026dcbd7 122 {"atmega165p", AVR_ISA_M323, bfd_mach_avr5},
28c9d252
NC
123 {"atmega168", AVR_ISA_M323, bfd_mach_avr5},
124 {"atmega169", AVR_ISA_M323, bfd_mach_avr5},
026dcbd7 125 {"atmega169p", AVR_ISA_M323, bfd_mach_avr5},
28c9d252
NC
126 {"atmega32", AVR_ISA_M323, bfd_mach_avr5},
127 {"atmega323", AVR_ISA_M323, bfd_mach_avr5},
026dcbd7 128 {"atmega324p", AVR_ISA_M323, bfd_mach_avr5},
28c9d252 129 {"atmega325", AVR_ISA_M323, bfd_mach_avr5},
7b60f473 130 {"atmega325p", AVR_ISA_M323, bfd_mach_avr5},
28c9d252 131 {"atmega329", AVR_ISA_M323, bfd_mach_avr5},
7b60f473 132 {"atmega329p", AVR_ISA_M323, bfd_mach_avr5},
28c9d252 133 {"atmega3250", AVR_ISA_M323, bfd_mach_avr5},
7b60f473 134 {"atmega3250p",AVR_ISA_M323, bfd_mach_avr5},
28c9d252 135 {"atmega3290", AVR_ISA_M323, bfd_mach_avr5},
7b60f473 136 {"atmega3290p",AVR_ISA_M323, bfd_mach_avr5},
28c9d252
NC
137 {"atmega406", AVR_ISA_M323, bfd_mach_avr5},
138 {"atmega64", AVR_ISA_M323, bfd_mach_avr5},
139 {"atmega640", AVR_ISA_M323, bfd_mach_avr5},
140 {"atmega644", AVR_ISA_M323, bfd_mach_avr5},
026dcbd7 141 {"atmega644p", AVR_ISA_M323, bfd_mach_avr5},
28c9d252
NC
142 {"atmega128", AVR_ISA_M128, bfd_mach_avr5},
143 {"atmega1280", AVR_ISA_M128, bfd_mach_avr5},
144 {"atmega1281", AVR_ISA_M128, bfd_mach_avr5},
145 {"atmega645", AVR_ISA_M323, bfd_mach_avr5},
146 {"atmega649", AVR_ISA_M323, bfd_mach_avr5},
147 {"atmega6450", AVR_ISA_M323, bfd_mach_avr5},
148 {"atmega6490", AVR_ISA_M323, bfd_mach_avr5},
8eb2af8e 149 {"atmega16hva",AVR_ISA_M323, bfd_mach_avr5},
28c9d252
NC
150 {"at90can32" , AVR_ISA_M323, bfd_mach_avr5},
151 {"at90can64" , AVR_ISA_M323, bfd_mach_avr5},
152 {"at90can128", AVR_ISA_M128, bfd_mach_avr5},
485aa104
NC
153 {"at90pwm216", AVR_ISA_M323, bfd_mach_avr5},
154 {"at90pwm316", AVR_ISA_M323, 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"
7f5ba16d
EW
331 " avr3 - ATmega103\n"
332 " avr4 - ATmega8, ATmega88\n"
65aa24b6 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
adde6300 413char *
dc191a8f 414md_atof (int type, char *litP, int *sizeP)
adde6300 415{
499ac353 416 return ieee_md_atof (type, litP, sizeP, FALSE);
adde6300
AM
417}
418
419void
dc191a8f
NC
420md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
421 asection *sec ATTRIBUTE_UNUSED,
422 fragS *fragP ATTRIBUTE_UNUSED)
adde6300
AM
423{
424 abort ();
425}
426
adde6300 427void
dc191a8f 428md_begin (void)
adde6300 429{
df136245 430 unsigned int i;
adde6300 431 struct avr_opcodes_s *opcode;
dc191a8f 432
c6a7ab1f 433 avr_hash = hash_new ();
adde6300
AM
434
435 /* Insert unique names into hash table. This hash table then provides a
436 quick index to the first opcode with a particular name in the opcode
437 table. */
adde6300
AM
438 for (opcode = avr_opcodes; opcode->name; opcode++)
439 hash_insert (avr_hash, opcode->name, (char *) opcode);
440
441 avr_mod_hash = hash_new ();
442
dc191a8f 443 for (i = 0; i < ARRAY_SIZE (exp_mod); ++i)
8ad7c533
NC
444 {
445 mod_index m;
446
447 m.index = i + 10;
448 hash_insert (avr_mod_hash, EXP_MOD_NAME (i), m.ptr);
449 }
c6a7ab1f 450
adde6300
AM
451 bfd_set_arch_mach (stdoutput, TARGET_ARCH, avr_mcu->mach);
452}
453
df136245 454/* Resolve STR as a constant expression and return the result.
c6a7ab1f 455 If result greater than MAX then error. */
df136245
DC
456
457static unsigned int
dc191a8f 458avr_get_constant (char *str, int max)
df136245
DC
459{
460 expressionS ex;
dc191a8f 461
df136245
DC
462 str = skip_space (str);
463 input_line_pointer = str;
dc191a8f 464 expression (& ex);
df136245
DC
465
466 if (ex.X_op != O_constant)
467 as_bad (_("constant value required"));
468
469 if (ex.X_add_number > max || ex.X_add_number < 0)
73f4d86e 470 as_bad (_("number must be positive and less than %d"), max + 1);
1dab94dd 471
df136245
DC
472 return ex.X_add_number;
473}
474
dc191a8f 475/* Parse for ldd/std offset. */
df136245 476
dc191a8f
NC
477static void
478avr_offset_expression (expressionS *exp)
adde6300 479{
dc191a8f
NC
480 char *str = input_line_pointer;
481 char *tmp;
482 char op[8];
adde6300 483
dc191a8f
NC
484 tmp = str;
485 str = extract_word (str, op, sizeof (op));
486
487 input_line_pointer = tmp;
488 expression (exp);
489
490 /* Warn about expressions that fail to use lo8 (). */
491 if (exp->X_op == O_constant)
adde6300 492 {
dc191a8f 493 int x = exp->X_add_number;
28c9d252 494
dc191a8f
NC
495 if (x < -255 || x > 255)
496 as_warn (_("constant out of 8-bit range: %d"), x);
497 }
498}
adde6300 499
dc191a8f 500/* Parse ordinary expression. */
adde6300 501
dc191a8f
NC
502static char *
503parse_exp (char *s, expressionS *op)
504{
505 input_line_pointer = s;
506 expression (op);
507 if (op->X_op == O_absent)
508 as_bad (_("missing operand"));
509 return input_line_pointer;
510}
1dab94dd 511
dc191a8f
NC
512/* Parse special expressions (needed for LDI command):
513 xx8 (address)
514 xx8 (-address)
515 pm_xx8 (address)
516 pm_xx8 (-address)
517 where xx is: hh, hi, lo. */
adde6300 518
dc191a8f
NC
519static bfd_reloc_code_real_type
520avr_ldi_expression (expressionS *exp)
521{
522 char *str = input_line_pointer;
523 char *tmp;
524 char op[8];
525 int mod;
28c9d252
NC
526 int linker_stubs_should_be_generated = 0;
527
dc191a8f 528 tmp = str;
adde6300 529
dc191a8f 530 str = extract_word (str, op, sizeof (op));
adde6300 531
dc191a8f
NC
532 if (op[0])
533 {
8ad7c533 534 mod_index m;
28c9d252 535
8ad7c533
NC
536 m.ptr = hash_find (avr_mod_hash, op);
537 mod = m.index;
1dab94dd 538
dc191a8f
NC
539 if (mod)
540 {
541 int closes = 0;
b170af93 542
dc191a8f
NC
543 mod -= 10;
544 str = skip_space (str);
00d2865b 545
dc191a8f
NC
546 if (*str == '(')
547 {
28c9d252 548 bfd_reloc_code_real_type reloc_to_return;
dc191a8f 549 int neg_p = 0;
00d2865b 550
dc191a8f 551 ++str;
00d2865b 552
dc191a8f 553 if (strncmp ("pm(", str, 3) == 0
28c9d252
NC
554 || strncmp ("gs(",str,3) == 0
555 || strncmp ("-(gs(",str,5) == 0
dc191a8f
NC
556 || strncmp ("-(pm(", str, 5) == 0)
557 {
558 if (HAVE_PM_P (mod))
559 {
560 ++mod;
561 ++closes;
562 }
563 else
564 as_bad (_("illegal expression"));
b170af93 565
28c9d252
NC
566 if (str[0] == 'g' || str[2] == 'g')
567 linker_stubs_should_be_generated = 1;
568
dc191a8f
NC
569 if (*str == '-')
570 {
571 neg_p = 1;
572 ++closes;
573 str += 5;
574 }
575 else
576 str += 3;
577 }
adde6300 578
dc191a8f
NC
579 if (*str == '-' && *(str + 1) == '(')
580 {
581 neg_p ^= 1;
582 ++closes;
583 str += 2;
584 }
750bce0e 585
dc191a8f
NC
586 input_line_pointer = str;
587 expression (exp);
750bce0e 588
dc191a8f
NC
589 do
590 {
591 if (*input_line_pointer != ')')
592 {
593 as_bad (_("`)' required"));
594 break;
595 }
596 input_line_pointer++;
597 }
598 while (closes--);
599
28c9d252
NC
600 reloc_to_return =
601 neg_p ? EXP_MOD_NEG_RELOC (mod) : EXP_MOD_RELOC (mod);
602 if (linker_stubs_should_be_generated)
603 {
604 switch (reloc_to_return)
605 {
606 case BFD_RELOC_AVR_LO8_LDI_PM:
607 reloc_to_return = BFD_RELOC_AVR_LO8_LDI_GS;
608 break;
609 case BFD_RELOC_AVR_HI8_LDI_PM:
610 reloc_to_return = BFD_RELOC_AVR_HI8_LDI_GS;
611 break;
612
613 default:
614 as_warn (_("expression dangerous with linker stubs"));
615 }
616 }
617 return reloc_to_return;
dc191a8f
NC
618 }
619 }
620 }
750bce0e
NC
621
622 input_line_pointer = tmp;
623 expression (exp);
624
625 /* Warn about expressions that fail to use lo8 (). */
626 if (exp->X_op == O_constant)
627 {
628 int x = exp->X_add_number;
dc191a8f 629
750bce0e
NC
630 if (x < -255 || x > 255)
631 as_warn (_("constant out of 8-bit range: %d"), x);
632 }
dc191a8f
NC
633
634 return BFD_RELOC_AVR_LDI;
750bce0e
NC
635}
636
df136245 637/* Parse one instruction operand.
c6a7ab1f
NC
638 Return operand bitmask. Also fixups can be generated. */
639
adde6300 640static unsigned int
dc191a8f
NC
641avr_operand (struct avr_opcodes_s *opcode,
642 int where,
643 char *op,
644 char **line)
adde6300 645{
adde6300 646 expressionS op_expr;
df136245
DC
647 unsigned int op_mask = 0;
648 char *str = skip_space (*line);
adde6300 649
adde6300
AM
650 switch (*op)
651 {
652 /* Any register operand. */
653 case 'w':
654 case 'd':
655 case 'r':
b170af93
DC
656 case 'a':
657 case 'v':
c6a7ab1f
NC
658 if (*str == 'r' || *str == 'R')
659 {
660 char r_name[20];
1dab94dd 661
c6a7ab1f 662 str = extract_word (str, r_name, sizeof (r_name));
65b1d096 663 op_mask = 0xff;
3882b010 664 if (ISDIGIT (r_name[1]))
c6a7ab1f
NC
665 {
666 if (r_name[2] == '\0')
667 op_mask = r_name[1] - '0';
668 else if (r_name[1] != '0'
3882b010 669 && ISDIGIT (r_name[2])
c6a7ab1f
NC
670 && r_name[3] == '\0')
671 op_mask = (r_name[1] - '0') * 10 + r_name[2] - '0';
672 }
673 }
674 else
675 {
676 op_mask = avr_get_constant (str, 31);
677 str = input_line_pointer;
678 }
1dab94dd 679
c6a7ab1f
NC
680 if (op_mask <= 31)
681 {
682 switch (*op)
683 {
684 case 'a':
685 if (op_mask < 16 || op_mask > 23)
686 as_bad (_("register r16-r23 required"));
687 op_mask -= 16;
688 break;
1dab94dd 689
c6a7ab1f
NC
690 case 'd':
691 if (op_mask < 16)
692 as_bad (_("register number above 15 required"));
693 op_mask -= 16;
694 break;
1dab94dd 695
c6a7ab1f
NC
696 case 'v':
697 if (op_mask & 1)
698 as_bad (_("even register number required"));
699 op_mask >>= 1;
700 break;
1dab94dd 701
c6a7ab1f 702 case 'w':
65b1d096 703 if ((op_mask & 1) || op_mask < 24)
c6a7ab1f 704 as_bad (_("register r24, r26, r28 or r30 required"));
65b1d096 705 op_mask = (op_mask - 24) >> 1;
c6a7ab1f
NC
706 break;
707 }
708 break;
709 }
710 as_bad (_("register name or number from 0 to 31 required"));
adde6300
AM
711 break;
712
713 case 'e':
714 {
715 char c;
1dab94dd 716
adde6300
AM
717 if (*str == '-')
718 {
c6a7ab1f 719 str = skip_space (str + 1);
adde6300
AM
720 op_mask = 0x1002;
721 }
3882b010 722 c = TOLOWER (*str);
adde6300
AM
723 if (c == 'x')
724 op_mask |= 0x100c;
725 else if (c == 'y')
726 op_mask |= 0x8;
727 else if (c != 'z')
00d2865b 728 as_bad (_("pointer register (X, Y or Z) required"));
adde6300 729
c6a7ab1f 730 str = skip_space (str + 1);
adde6300
AM
731 if (*str == '+')
732 {
733 ++str;
734 if (op_mask & 2)
00d2865b 735 as_bad (_("cannot both predecrement and postincrement"));
adde6300
AM
736 op_mask |= 0x1001;
737 }
e38c9cc2 738
1188e082 739 /* avr1 can do "ld r,Z" and "st Z,r" but no other pointer
e38c9cc2 740 registers, no predecrement, no postincrement. */
00d2865b
NC
741 if (!avr_opt.all_opcodes && (op_mask & 0x100F)
742 && !(avr_mcu->isa & AVR_ISA_SRAM))
743 as_bad (_("addressing mode not supported"));
adde6300
AM
744 }
745 break;
746
b170af93 747 case 'z':
c6a7ab1f
NC
748 if (*str == '-')
749 as_bad (_("can't predecrement"));
1dab94dd 750
c6a7ab1f
NC
751 if (! (*str == 'z' || *str == 'Z'))
752 as_bad (_("pointer register Z required"));
1dab94dd 753
c6a7ab1f
NC
754 str = skip_space (str + 1);
755
756 if (*str == '+')
757 {
758 ++str;
759 op_mask |= 1;
760 }
b170af93
DC
761 break;
762
adde6300
AM
763 case 'b':
764 {
3882b010 765 char c = TOLOWER (*str++);
1dab94dd 766
adde6300
AM
767 if (c == 'y')
768 op_mask |= 0x8;
769 else if (c != 'z')
00d2865b 770 as_bad (_("pointer register (Y or Z) required"));
adde6300
AM
771 str = skip_space (str);
772 if (*str++ == '+')
773 {
750bce0e
NC
774 input_line_pointer = str;
775 avr_offset_expression (& op_expr);
adde6300 776 str = input_line_pointer;
750bce0e
NC
777 fix_new_exp (frag_now, where, 3,
778 &op_expr, FALSE, BFD_RELOC_AVR_6);
adde6300
AM
779 }
780 }
781 break;
782
783 case 'h':
c6a7ab1f
NC
784 str = parse_exp (str, &op_expr);
785 fix_new_exp (frag_now, where, opcode->insn_size * 2,
b34976b6 786 &op_expr, FALSE, BFD_RELOC_AVR_CALL);
adde6300
AM
787 break;
788
789 case 'L':
c6a7ab1f
NC
790 str = parse_exp (str, &op_expr);
791 fix_new_exp (frag_now, where, opcode->insn_size * 2,
b34976b6 792 &op_expr, TRUE, BFD_RELOC_AVR_13_PCREL);
adde6300
AM
793 break;
794
795 case 'l':
c6a7ab1f
NC
796 str = parse_exp (str, &op_expr);
797 fix_new_exp (frag_now, where, opcode->insn_size * 2,
b34976b6 798 &op_expr, TRUE, BFD_RELOC_AVR_7_PCREL);
adde6300
AM
799 break;
800
801 case 'i':
c6a7ab1f
NC
802 str = parse_exp (str, &op_expr);
803 fix_new_exp (frag_now, where + 2, opcode->insn_size * 2,
b34976b6 804 &op_expr, FALSE, BFD_RELOC_16);
adde6300
AM
805 break;
806
807 case 'M':
808 {
809 bfd_reloc_code_real_type r_type;
1dab94dd 810
c6a7ab1f
NC
811 input_line_pointer = str;
812 r_type = avr_ldi_expression (&op_expr);
813 str = input_line_pointer;
adde6300 814 fix_new_exp (frag_now, where, 3,
b34976b6 815 &op_expr, FALSE, r_type);
adde6300
AM
816 }
817 break;
818
819 case 'n':
820 {
821 unsigned int x;
1dab94dd 822
adde6300
AM
823 x = ~avr_get_constant (str, 255);
824 str = input_line_pointer;
825 op_mask |= (x & 0xf) | ((x << 4) & 0xf00);
826 }
827 break;
828
829 case 'K':
750bce0e
NC
830 input_line_pointer = str;
831 avr_offset_expression (& op_expr);
832 str = input_line_pointer;
833 fix_new_exp (frag_now, where, 3,
834 & op_expr, FALSE, BFD_RELOC_AVR_6_ADIW);
adde6300
AM
835 break;
836
837 case 'S':
838 case 's':
839 {
840 unsigned int x;
1dab94dd 841
adde6300
AM
842 x = avr_get_constant (str, 7);
843 str = input_line_pointer;
844 if (*op == 'S')
845 x <<= 4;
846 op_mask |= x;
847 }
848 break;
849
850 case 'P':
851 {
852 unsigned int x;
1dab94dd 853
adde6300
AM
854 x = avr_get_constant (str, 63);
855 str = input_line_pointer;
856 op_mask |= (x & 0xf) | ((x & 0x30) << 5);
857 }
858 break;
859
860 case 'p':
861 {
862 unsigned int x;
1dab94dd 863
adde6300
AM
864 x = avr_get_constant (str, 31);
865 str = input_line_pointer;
866 op_mask |= x << 3;
867 }
868 break;
1dab94dd 869
1188e082
DC
870 case '?':
871 break;
1dab94dd 872
adde6300 873 default:
00d2865b 874 as_bad (_("unknown constraint `%c'"), *op);
adde6300 875 }
1dab94dd 876
adde6300
AM
877 *line = str;
878 return op_mask;
879}
880
dc191a8f
NC
881/* Parse instruction operands.
882 Return binary opcode. */
883
884static unsigned int
885avr_operands (struct avr_opcodes_s *opcode, char **line)
886{
887 char *op = opcode->constraints;
888 unsigned int bin = opcode->bin_opcode;
889 char *frag = frag_more (opcode->insn_size * 2);
890 char *str = *line;
891 int where = frag - frag_now->fr_literal;
892 static unsigned int prev = 0; /* Previous opcode. */
893
894 /* Opcode have operands. */
895 if (*op)
896 {
897 unsigned int reg1 = 0;
898 unsigned int reg2 = 0;
899 int reg1_present = 0;
900 int reg2_present = 0;
901
902 /* Parse first operand. */
903 if (REGISTER_P (*op))
904 reg1_present = 1;
905 reg1 = avr_operand (opcode, where, op, &str);
906 ++op;
907
908 /* Parse second operand. */
909 if (*op)
910 {
911 if (*op == ',')
912 ++op;
913
914 if (*op == '=')
915 {
916 reg2 = reg1;
917 reg2_present = 1;
918 }
919 else
920 {
921 if (REGISTER_P (*op))
922 reg2_present = 1;
923
924 str = skip_space (str);
925 if (*str++ != ',')
926 as_bad (_("`,' required"));
927 str = skip_space (str);
928
929 reg2 = avr_operand (opcode, where, op, &str);
930 }
931
932 if (reg1_present && reg2_present)
933 reg2 = (reg2 & 0xf) | ((reg2 << 5) & 0x200);
934 else if (reg2_present)
935 reg2 <<= 4;
936 }
937 if (reg1_present)
938 reg1 <<= 4;
939 bin |= reg1 | reg2;
940 }
941
942 /* Detect undefined combinations (like ld r31,Z+). */
943 if (!avr_opt.all_opcodes && AVR_UNDEF_P (bin))
944 as_warn (_("undefined combination of operands"));
945
946 if (opcode->insn_size == 2)
947 {
948 /* Warn if the previous opcode was cpse/sbic/sbis/sbrc/sbrs
949 (AVR core bug, fixed in the newer devices). */
950 if (!(avr_opt.no_skip_bug ||
951 (avr_mcu->isa & (AVR_ISA_MUL | AVR_ISA_MOVW)))
952 && AVR_SKIP_P (prev))
953 as_warn (_("skipping two-word instruction"));
954
955 bfd_putl32 ((bfd_vma) bin, frag);
956 }
957 else
958 bfd_putl16 ((bfd_vma) bin, frag);
959
960 prev = bin;
961 *line = str;
962 return bin;
963}
964
adde6300
AM
965/* GAS will call this function for each section at the end of the assembly,
966 to permit the CPU backend to adjust the alignment of a section. */
c6a7ab1f 967
adde6300 968valueT
dc191a8f 969md_section_align (asection *seg, valueT addr)
adde6300
AM
970{
971 int align = bfd_get_section_alignment (stdoutput, seg);
972 return ((addr + (1 << align) - 1) & (-1 << align));
973}
974
975/* If you define this macro, it should return the offset between the
976 address of a PC relative fixup and the position from which the PC
977 relative adjustment should be made. On many processors, the base
978 of a PC relative instruction is the next instruction, so this
979 macro would return the length of an instruction. */
c6a7ab1f 980
adde6300 981long
dc191a8f 982md_pcrel_from_section (fixS *fixp, segT sec)
adde6300 983{
c6a7ab1f 984 if (fixp->fx_addsy != (symbolS *) NULL
adde6300
AM
985 && (!S_IS_DEFINED (fixp->fx_addsy)
986 || (S_GET_SEGMENT (fixp->fx_addsy) != sec)))
987 return 0;
1dab94dd 988
adde6300
AM
989 return fixp->fx_frag->fr_address + fixp->fx_where;
990}
991
992/* GAS will call this for each fixup. It should store the correct
c6a7ab1f
NC
993 value in the object file. */
994
94f592af 995void
dc191a8f 996md_apply_fix (fixS *fixP, valueT * valP, segT seg)
adde6300
AM
997{
998 unsigned char *where;
999 unsigned long insn;
a161fe53 1000 long value = *valP;
adde6300 1001
94f592af
NC
1002 if (fixP->fx_addsy == (symbolS *) NULL)
1003 fixP->fx_done = 1;
1004
87733541
AM
1005 else if (fixP->fx_pcrel)
1006 {
1007 segT s = S_GET_SEGMENT (fixP->fx_addsy);
1008
1009 if (s == seg || s == absolute_section)
1010 {
1011 value += S_GET_VALUE (fixP->fx_addsy);
1012 fixP->fx_done = 1;
1013 }
1014 }
1015
a161fe53
AM
1016 /* We don't actually support subtracting a symbol. */
1017 if (fixP->fx_subsy != (symbolS *) NULL)
1018 as_bad_where (fixP->fx_file, fixP->fx_line, _("expression too complex"));
1dab94dd 1019
94f592af 1020 switch (fixP->fx_r_type)
adde6300
AM
1021 {
1022 default:
94f592af 1023 fixP->fx_no_overflow = 1;
adde6300
AM
1024 break;
1025 case BFD_RELOC_AVR_7_PCREL:
1026 case BFD_RELOC_AVR_13_PCREL:
1027 case BFD_RELOC_32:
1028 case BFD_RELOC_16:
1029 case BFD_RELOC_AVR_CALL:
1030 break;
1031 }
1032
94f592af 1033 if (fixP->fx_done)
adde6300
AM
1034 {
1035 /* Fetch the instruction, insert the fully resolved operand
1036 value, and stuff the instruction back again. */
2132e3a3 1037 where = (unsigned char *) fixP->fx_frag->fr_literal + fixP->fx_where;
adde6300
AM
1038 insn = bfd_getl16 (where);
1039
94f592af 1040 switch (fixP->fx_r_type)
adde6300
AM
1041 {
1042 case BFD_RELOC_AVR_7_PCREL:
1043 if (value & 1)
94f592af 1044 as_bad_where (fixP->fx_file, fixP->fx_line,
adde6300 1045 _("odd address operand: %ld"), value);
1dab94dd 1046
adde6300
AM
1047 /* Instruction addresses are always right-shifted by 1. */
1048 value >>= 1;
1049 --value; /* Correct PC. */
1dab94dd 1050
adde6300 1051 if (value < -64 || value > 63)
94f592af 1052 as_bad_where (fixP->fx_file, fixP->fx_line,
adde6300
AM
1053 _("operand out of range: %ld"), value);
1054 value = (value << 3) & 0x3f8;
1055 bfd_putl16 ((bfd_vma) (value | insn), where);
1056 break;
1057
1058 case BFD_RELOC_AVR_13_PCREL:
1059 if (value & 1)
94f592af 1060 as_bad_where (fixP->fx_file, fixP->fx_line,
adde6300 1061 _("odd address operand: %ld"), value);
1dab94dd 1062
adde6300
AM
1063 /* Instruction addresses are always right-shifted by 1. */
1064 value >>= 1;
1065 --value; /* Correct PC. */
adde6300
AM
1066
1067 if (value < -2048 || value > 2047)
1068 {
65aa24b6 1069 /* No wrap for devices with >8K of program memory. */
00d2865b 1070 if ((avr_mcu->isa & AVR_ISA_MEGA) || avr_opt.no_wrap)
94f592af 1071 as_bad_where (fixP->fx_file, fixP->fx_line,
adde6300
AM
1072 _("operand out of range: %ld"), value);
1073 }
1074
1075 value &= 0xfff;
1076 bfd_putl16 ((bfd_vma) (value | insn), where);
1077 break;
1078
1079 case BFD_RELOC_32:
1080 bfd_putl16 ((bfd_vma) value, where);
1081 break;
1082
1083 case BFD_RELOC_16:
1084 bfd_putl16 ((bfd_vma) value, where);
1085 break;
1086
1087 case BFD_RELOC_AVR_16_PM:
c6a7ab1f 1088 bfd_putl16 ((bfd_vma) (value >> 1), where);
adde6300
AM
1089 break;
1090
750bce0e
NC
1091 case BFD_RELOC_AVR_LDI:
1092 if (value > 255)
1093 as_bad_where (fixP->fx_file, fixP->fx_line,
1094 _("operand out of range: %ld"), value);
1095 bfd_putl16 ((bfd_vma) insn | LDI_IMMEDIATE (value), where);
1096 break;
1097
1098 case BFD_RELOC_AVR_6:
1099 if ((value > 63) || (value < 0))
1100 as_bad_where (fixP->fx_file, fixP->fx_line,
1101 _("operand out of range: %ld"), value);
1102 bfd_putl16 ((bfd_vma) insn | ((value & 7) | ((value & (3 << 3)) << 7) | ((value & (1 << 5)) << 8)), where);
1103 break;
1104
1105 case BFD_RELOC_AVR_6_ADIW:
1106 if ((value > 63) || (value < 0))
1107 as_bad_where (fixP->fx_file, fixP->fx_line,
1108 _("operand out of range: %ld"), value);
1109 bfd_putl16 ((bfd_vma) insn | (value & 0xf) | ((value & 0x30) << 2), where);
1110 break;
1111
adde6300
AM
1112 case BFD_RELOC_AVR_LO8_LDI:
1113 bfd_putl16 ((bfd_vma) insn | LDI_IMMEDIATE (value), where);
1114 break;
1115
adde6300
AM
1116 case BFD_RELOC_AVR_HI8_LDI:
1117 bfd_putl16 ((bfd_vma) insn | LDI_IMMEDIATE (value >> 8), where);
1118 break;
1119
df406460 1120 case BFD_RELOC_AVR_MS8_LDI:
adde6300
AM
1121 bfd_putl16 ((bfd_vma) insn | LDI_IMMEDIATE (value >> 24), where);
1122 break;
1123
1124 case BFD_RELOC_AVR_HH8_LDI:
1125 bfd_putl16 ((bfd_vma) insn | LDI_IMMEDIATE (value >> 16), where);
1126 break;
1127
1128 case BFD_RELOC_AVR_LO8_LDI_NEG:
1129 bfd_putl16 ((bfd_vma) insn | LDI_IMMEDIATE (-value), where);
1130 break;
1131
adde6300
AM
1132 case BFD_RELOC_AVR_HI8_LDI_NEG:
1133 bfd_putl16 ((bfd_vma) insn | LDI_IMMEDIATE (-value >> 8), where);
1134 break;
1135
df406460 1136 case BFD_RELOC_AVR_MS8_LDI_NEG:
adde6300
AM
1137 bfd_putl16 ((bfd_vma) insn | LDI_IMMEDIATE (-value >> 24), where);
1138 break;
1139
1140 case BFD_RELOC_AVR_HH8_LDI_NEG:
1141 bfd_putl16 ((bfd_vma) insn | LDI_IMMEDIATE (-value >> 16), where);
1142 break;
1143
1144 case BFD_RELOC_AVR_LO8_LDI_PM:
1145 bfd_putl16 ((bfd_vma) insn | LDI_IMMEDIATE (value >> 1), where);
1146 break;
1147
1148 case BFD_RELOC_AVR_HI8_LDI_PM:
1149 bfd_putl16 ((bfd_vma) insn | LDI_IMMEDIATE (value >> 9), where);
1150 break;
1151
1152 case BFD_RELOC_AVR_HH8_LDI_PM:
1153 bfd_putl16 ((bfd_vma) insn | LDI_IMMEDIATE (value >> 17), where);
1154 break;
1155
1156 case BFD_RELOC_AVR_LO8_LDI_PM_NEG:
1157 bfd_putl16 ((bfd_vma) insn | LDI_IMMEDIATE (-value >> 1), where);
1158 break;
1159
1160 case BFD_RELOC_AVR_HI8_LDI_PM_NEG:
1161 bfd_putl16 ((bfd_vma) insn | LDI_IMMEDIATE (-value >> 9), where);
1162 break;
1163
1164 case BFD_RELOC_AVR_HH8_LDI_PM_NEG:
1165 bfd_putl16 ((bfd_vma) insn | LDI_IMMEDIATE (-value >> 17), where);
1166 break;
1167
1168 case BFD_RELOC_AVR_CALL:
1169 {
1170 unsigned long x;
1dab94dd 1171
adde6300
AM
1172 x = bfd_getl16 (where);
1173 if (value & 1)
94f592af 1174 as_bad_where (fixP->fx_file, fixP->fx_line,
adde6300
AM
1175 _("odd address operand: %ld"), value);
1176 value >>= 1;
1177 x |= ((value & 0x10000) | ((value << 3) & 0x1f00000)) >> 16;
1178 bfd_putl16 ((bfd_vma) x, where);
c6a7ab1f 1179 bfd_putl16 ((bfd_vma) (value & 0xffff), where + 2);
adde6300
AM
1180 }
1181 break;
1182
1183 default:
c6a7ab1f 1184 as_fatal (_("line %d: unknown relocation type: 0x%x"),
94f592af 1185 fixP->fx_line, fixP->fx_r_type);
adde6300
AM
1186 break;
1187 }
1188 }
1189 else
1190 {
94f592af 1191 switch (fixP->fx_r_type)
adde6300
AM
1192 {
1193 case -BFD_RELOC_AVR_HI8_LDI_NEG:
1194 case -BFD_RELOC_AVR_HI8_LDI:
1195 case -BFD_RELOC_AVR_LO8_LDI_NEG:
1196 case -BFD_RELOC_AVR_LO8_LDI:
94f592af 1197 as_bad_where (fixP->fx_file, fixP->fx_line,
adde6300 1198 _("only constant expression allowed"));
94f592af 1199 fixP->fx_done = 1;
adde6300
AM
1200 break;
1201 default:
1202 break;
1203 }
adde6300 1204 }
adde6300
AM
1205}
1206
7be1c489
AM
1207/* GAS will call this to generate a reloc, passing the resulting reloc
1208 to `bfd_install_relocation'. This currently works poorly, as
1209 `bfd_install_relocation' often does the wrong thing, and instances of
1210 `tc_gen_reloc' have been written to work around the problems, which
1211 in turns makes it difficult to fix `bfd_install_relocation'. */
adde6300
AM
1212
1213/* If while processing a fixup, a reloc really needs to be created
1214 then it is done here. */
1215
1216arelent *
dc191a8f
NC
1217tc_gen_reloc (asection *seg ATTRIBUTE_UNUSED,
1218 fixS *fixp)
adde6300
AM
1219{
1220 arelent *reloc;
1221
df406460
NC
1222 if (fixp->fx_addsy && fixp->fx_subsy)
1223 {
1224 long value = 0;
1225
1226 if ((S_GET_SEGMENT (fixp->fx_addsy) != S_GET_SEGMENT (fixp->fx_subsy))
1227 || S_GET_SEGMENT (fixp->fx_addsy) == undefined_section)
1228 {
1229 as_bad_where (fixp->fx_file, fixp->fx_line,
1230 "Difference of symbols in different sections is not supported");
1231 return NULL;
1232 }
1233
28c9d252 1234 /* We are dealing with two symbols defined in the same section.
df406460
NC
1235 Let us fix-up them here. */
1236 value += S_GET_VALUE (fixp->fx_addsy);
1237 value -= S_GET_VALUE (fixp->fx_subsy);
1238
1239 /* When fx_addsy and fx_subsy both are zero, md_apply_fix
1240 only takes it's second operands for the fixup value. */
1241 fixp->fx_addsy = NULL;
1242 fixp->fx_subsy = NULL;
1243 md_apply_fix (fixp, (valueT *) &value, NULL);
1244
1245 return NULL;
1246 }
1247
dc191a8f 1248 reloc = xmalloc (sizeof (arelent));
adde6300 1249
dc191a8f 1250 reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
adde6300
AM
1251 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
1252
1253 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
1254 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
1255 if (reloc->howto == (reloc_howto_type *) NULL)
1256 {
1257 as_bad_where (fixp->fx_file, fixp->fx_line,
c6a7ab1f
NC
1258 _("reloc %d not supported by object file format"),
1259 (int) fixp->fx_r_type);
adde6300
AM
1260 return NULL;
1261 }
1262
1263 if (fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT
1264 || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
1265 reloc->address = fixp->fx_offset;
1266
1267 reloc->addend = fixp->fx_offset;
1268
1269 return reloc;
1270}
1271
adde6300 1272void
dc191a8f 1273md_assemble (char *str)
adde6300 1274{
c6a7ab1f 1275 struct avr_opcodes_s *opcode;
adde6300
AM
1276 char op[11];
1277
c6a7ab1f 1278 str = skip_space (extract_word (str, op, sizeof (op)));
adde6300
AM
1279
1280 if (!op[0])
00d2865b 1281 as_bad (_("can't find opcode "));
adde6300
AM
1282
1283 opcode = (struct avr_opcodes_s *) hash_find (avr_hash, op);
1284
1285 if (opcode == NULL)
1286 {
00d2865b 1287 as_bad (_("unknown opcode `%s'"), op);
adde6300
AM
1288 return;
1289 }
1290
b170af93 1291 /* Special case for opcodes with optional operands (lpm, elpm) -
1188e082 1292 version with operands exists in avr_opcodes[] in the next entry. */
c6a7ab1f 1293
1188e082
DC
1294 if (*str && *opcode->constraints == '?')
1295 ++opcode;
b170af93 1296
00d2865b
NC
1297 if (!avr_opt.all_opcodes && (opcode->isa & avr_mcu->isa) != opcode->isa)
1298 as_bad (_("illegal opcode %s for mcu %s"), opcode->name, avr_mcu->name);
adde6300
AM
1299
1300 /* We used to set input_line_pointer to the result of get_operands,
1301 but that is wrong. Our caller assumes we don't change it. */
1302 {
1303 char *t = input_line_pointer;
dc191a8f 1304
adde6300 1305 avr_operands (opcode, &str);
b170af93 1306 if (*skip_space (str))
00d2865b 1307 as_bad (_("garbage at end of line"));
adde6300
AM
1308 input_line_pointer = t;
1309 }
1310}
1311
adde6300 1312/* Flag to pass `pm' mode between `avr_parse_cons_expression' and
c6a7ab1f 1313 `avr_cons_fix_new'. */
adde6300
AM
1314static int exp_mod_pm = 0;
1315
1316/* Parse special CONS expression: pm (expression)
28c9d252
NC
1317 or alternatively: gs (expression).
1318 These are used for addressing program memory.
c6a7ab1f
NC
1319 Relocation: BFD_RELOC_AVR_16_PM. */
1320
adde6300 1321void
dc191a8f 1322avr_parse_cons_expression (expressionS *exp, int nbytes)
adde6300 1323{
c6a7ab1f 1324 char *tmp;
adde6300
AM
1325
1326 exp_mod_pm = 0;
1327
1328 tmp = input_line_pointer = skip_space (input_line_pointer);
1329
1330 if (nbytes == 2)
1331 {
28c9d252
NC
1332 char *pm_name1 = "pm";
1333 char *pm_name2 = "gs";
1334 int len = strlen (pm_name1);
1335 /* len must be the same for both pm identifiers. */
1dab94dd 1336
28c9d252
NC
1337 if (strncasecmp (input_line_pointer, pm_name1, len) == 0
1338 || strncasecmp (input_line_pointer, pm_name2, len) == 0)
adde6300
AM
1339 {
1340 input_line_pointer = skip_space (input_line_pointer + len);
1dab94dd 1341
adde6300
AM
1342 if (*input_line_pointer == '(')
1343 {
1344 input_line_pointer = skip_space (input_line_pointer + 1);
1345 exp_mod_pm = 1;
1346 expression (exp);
1dab94dd 1347
adde6300
AM
1348 if (*input_line_pointer == ')')
1349 ++input_line_pointer;
1350 else
1351 {
00d2865b 1352 as_bad (_("`)' required"));
adde6300
AM
1353 exp_mod_pm = 0;
1354 }
1dab94dd 1355
adde6300
AM
1356 return;
1357 }
1dab94dd 1358
adde6300
AM
1359 input_line_pointer = tmp;
1360 }
1361 }
1dab94dd 1362
adde6300
AM
1363 expression (exp);
1364}
1365
1366void
dc191a8f
NC
1367avr_cons_fix_new (fragS *frag,
1368 int where,
1369 int nbytes,
1370 expressionS *exp)
adde6300
AM
1371{
1372 if (exp_mod_pm == 0)
1373 {
1374 if (nbytes == 2)
b34976b6 1375 fix_new_exp (frag, where, nbytes, exp, FALSE, BFD_RELOC_16);
adde6300 1376 else if (nbytes == 4)
b34976b6 1377 fix_new_exp (frag, where, nbytes, exp, FALSE, BFD_RELOC_32);
adde6300 1378 else
00d2865b 1379 as_bad (_("illegal %srelocation size: %d"), "", nbytes);
adde6300
AM
1380 }
1381 else
1382 {
1383 if (nbytes == 2)
b34976b6 1384 fix_new_exp (frag, where, nbytes, exp, FALSE, BFD_RELOC_AVR_16_PM);
adde6300 1385 else
00d2865b 1386 as_bad (_("illegal %srelocation size: %d"), "`pm' ", nbytes);
adde6300
AM
1387 exp_mod_pm = 0;
1388 }
1389}
This page took 0.383503 seconds and 4 git commands to generate.