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