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