*** empty log message ***
[deliverable/binutils-gdb.git] / gas / config / tc-avr.c
CommitLineData
adde6300
AM
1/* tc-avr.c -- Assembler code for the ATMEL AVR
2
d669d37f 3 Copyright 1999, 2000, 2001, 2002, 2004, 2005, 2006, 2007, 2008
2132e3a3 4 Free Software Foundation, Inc.
adde6300
AM
5 Contributed by Denis Chertykov <denisc@overta.ru>
6
7 This file is part of GAS, the GNU Assembler.
8
9 GAS is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
ec2655a6 11 the Free Software Foundation; either version 3, or (at your option)
adde6300
AM
12 any later version.
13
14 GAS is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with GAS; see the file COPYING. If not, write to
4b4da160
NC
21 the Free Software Foundation, 51 Franklin Street - Fifth Floor,
22 Boston, MA 02110-1301, USA. */
adde6300 23
adde6300 24#include "as.h"
3882b010 25#include "safe-ctype.h"
adde6300
AM
26#include "subsegs.h"
27
1188e082
DC
28struct avr_opcodes_s
29{
dc191a8f
NC
30 char * name;
31 char * constraints;
32 int insn_size; /* In words. */
33 int isa;
34 unsigned int bin_opcode;
1188e082
DC
35};
36
37#define AVR_INSN(NAME, CONSTR, OPCODE, SIZE, ISA, BIN) \
38{#NAME, CONSTR, SIZE, ISA, BIN},
39
40struct avr_opcodes_s avr_opcodes[] =
41{
42 #include "opcode/avr.h"
43 {NULL, NULL, 0, 0, 0}
44};
45
adde6300
AM
46const char comment_chars[] = ";";
47const char line_comment_chars[] = "#";
48const char line_separator_chars[] = "$";
49
adde6300
AM
50const char *md_shortopts = "m:";
51struct mcu_type_s
52{
53 char *name;
54 int isa;
55 int mach;
56};
57
1f8ae5e6
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 88 {"attiny13", AVR_ISA_TINY2, bfd_mach_avr2},
3bb06f78 89 {"attiny13a", AVR_ISA_TINY2, bfd_mach_avr2},
28c9d252
NC
90 {"attiny2313", AVR_ISA_TINY2, bfd_mach_avr2},
91 {"attiny261", AVR_ISA_TINY2, bfd_mach_avr2},
92 {"attiny461", AVR_ISA_TINY2, bfd_mach_avr2},
93 {"attiny861", AVR_ISA_TINY2, bfd_mach_avr2},
94 {"attiny24", AVR_ISA_TINY2, bfd_mach_avr2},
95 {"attiny44", AVR_ISA_TINY2, bfd_mach_avr2},
96 {"attiny84", AVR_ISA_TINY2, bfd_mach_avr2},
97 {"attiny25", AVR_ISA_TINY2, bfd_mach_avr2},
98 {"attiny45", AVR_ISA_TINY2, bfd_mach_avr2},
99 {"attiny85", AVR_ISA_TINY2, bfd_mach_avr2},
922f0bac
NC
100 {"attiny43u", AVR_ISA_TINY2, bfd_mach_avr2},
101 {"attiny48", AVR_ISA_TINY2, bfd_mach_avr2},
71fe8fb3 102 {"attiny88", AVR_ISA_TINY2, bfd_mach_avr2},
28c9d252
NC
103 {"atmega103", AVR_ISA_M103, bfd_mach_avr3},
104 {"at43usb320", AVR_ISA_M103, bfd_mach_avr3},
105 {"at43usb355", AVR_ISA_M603, bfd_mach_avr3},
106 {"at76c711", AVR_ISA_M603, bfd_mach_avr3},
982b62a0
EW
107 {"at90usb82", AVR_ISA_USB162, bfd_mach_avr3},
108 {"at90usb162", AVR_ISA_USB162, bfd_mach_avr3},
2460c166 109 {"attiny167", AVR_ISA_TINY3, bfd_mach_avr3},
28c9d252 110 {"atmega48", AVR_ISA_PWMx, bfd_mach_avr4},
5cc9c0ab 111 {"atmega48p", AVR_ISA_PWMx, bfd_mach_avr4},
28c9d252 112 {"atmega8", AVR_ISA_M8, bfd_mach_avr4},
28c9d252 113 {"atmega88", AVR_ISA_PWMx, bfd_mach_avr4},
5cc9c0ab 114 {"atmega88p", AVR_ISA_PWMx, bfd_mach_avr4},
28c9d252
NC
115 {"atmega8515", AVR_ISA_M8, bfd_mach_avr4},
116 {"atmega8535", AVR_ISA_M8, bfd_mach_avr4},
8eb2af8e 117 {"atmega8hva", AVR_ISA_PWMx, bfd_mach_avr4},
7b60f473 118 {"at90pwm1", AVR_ISA_PWMx, bfd_mach_avr4},
28c9d252 119 {"at90pwm2", AVR_ISA_PWMx, bfd_mach_avr4},
7337fc21 120 {"at90pwm2b", AVR_ISA_PWMx, bfd_mach_avr4},
28c9d252 121 {"at90pwm3", AVR_ISA_PWMx, bfd_mach_avr4},
7337fc21 122 {"at90pwm3b", AVR_ISA_PWMx, bfd_mach_avr4},
28c9d252
NC
123 {"atmega16", AVR_ISA_M323, bfd_mach_avr5},
124 {"atmega161", AVR_ISA_M161, bfd_mach_avr5},
125 {"atmega162", AVR_ISA_M323, bfd_mach_avr5},
126 {"atmega163", AVR_ISA_M161, bfd_mach_avr5},
026dcbd7 127 {"atmega164p", AVR_ISA_M323, bfd_mach_avr5},
28c9d252 128 {"atmega165", AVR_ISA_M323, bfd_mach_avr5},
026dcbd7 129 {"atmega165p", AVR_ISA_M323, bfd_mach_avr5},
28c9d252 130 {"atmega168", AVR_ISA_M323, bfd_mach_avr5},
5cc9c0ab 131 {"atmega168p", AVR_ISA_M323, bfd_mach_avr5},
28c9d252 132 {"atmega169", AVR_ISA_M323, bfd_mach_avr5},
026dcbd7 133 {"atmega169p", AVR_ISA_M323, bfd_mach_avr5},
28c9d252
NC
134 {"atmega32", AVR_ISA_M323, bfd_mach_avr5},
135 {"atmega323", AVR_ISA_M323, bfd_mach_avr5},
026dcbd7 136 {"atmega324p", AVR_ISA_M323, bfd_mach_avr5},
28c9d252 137 {"atmega325", AVR_ISA_M323, bfd_mach_avr5},
7b60f473 138 {"atmega325p", AVR_ISA_M323, bfd_mach_avr5},
5cc9c0ab 139 {"atmega328p", AVR_ISA_M323, bfd_mach_avr5},
28c9d252 140 {"atmega329", AVR_ISA_M323, bfd_mach_avr5},
7b60f473 141 {"atmega329p", AVR_ISA_M323, bfd_mach_avr5},
28c9d252 142 {"atmega3250", AVR_ISA_M323, bfd_mach_avr5},
7b60f473 143 {"atmega3250p",AVR_ISA_M323, bfd_mach_avr5},
28c9d252 144 {"atmega3290", AVR_ISA_M323, bfd_mach_avr5},
7b60f473 145 {"atmega3290p",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:
0a903bab
NC
625 /* PR 5523: Do not generate a warning here,
626 legitimate code can trigger this case. */
627 break;
28c9d252
NC
628 }
629 }
630 return reloc_to_return;
dc191a8f
NC
631 }
632 }
633 }
750bce0e
NC
634
635 input_line_pointer = tmp;
636 expression (exp);
637
638 /* Warn about expressions that fail to use lo8 (). */
639 if (exp->X_op == O_constant)
640 {
641 int x = exp->X_add_number;
dc191a8f 642
750bce0e
NC
643 if (x < -255 || x > 255)
644 as_warn (_("constant out of 8-bit range: %d"), x);
645 }
dc191a8f
NC
646
647 return BFD_RELOC_AVR_LDI;
750bce0e
NC
648}
649
df136245 650/* Parse one instruction operand.
c6a7ab1f
NC
651 Return operand bitmask. Also fixups can be generated. */
652
adde6300 653static unsigned int
dc191a8f
NC
654avr_operand (struct avr_opcodes_s *opcode,
655 int where,
656 char *op,
657 char **line)
adde6300 658{
adde6300 659 expressionS op_expr;
df136245
DC
660 unsigned int op_mask = 0;
661 char *str = skip_space (*line);
adde6300 662
adde6300
AM
663 switch (*op)
664 {
665 /* Any register operand. */
666 case 'w':
667 case 'd':
668 case 'r':
b170af93
DC
669 case 'a':
670 case 'v':
c6a7ab1f
NC
671 if (*str == 'r' || *str == 'R')
672 {
673 char r_name[20];
1dab94dd 674
c6a7ab1f 675 str = extract_word (str, r_name, sizeof (r_name));
65b1d096 676 op_mask = 0xff;
3882b010 677 if (ISDIGIT (r_name[1]))
c6a7ab1f
NC
678 {
679 if (r_name[2] == '\0')
680 op_mask = r_name[1] - '0';
681 else if (r_name[1] != '0'
3882b010 682 && ISDIGIT (r_name[2])
c6a7ab1f
NC
683 && r_name[3] == '\0')
684 op_mask = (r_name[1] - '0') * 10 + r_name[2] - '0';
685 }
686 }
687 else
688 {
689 op_mask = avr_get_constant (str, 31);
690 str = input_line_pointer;
691 }
1dab94dd 692
c6a7ab1f
NC
693 if (op_mask <= 31)
694 {
695 switch (*op)
696 {
697 case 'a':
698 if (op_mask < 16 || op_mask > 23)
699 as_bad (_("register r16-r23 required"));
700 op_mask -= 16;
701 break;
1dab94dd 702
c6a7ab1f
NC
703 case 'd':
704 if (op_mask < 16)
705 as_bad (_("register number above 15 required"));
706 op_mask -= 16;
707 break;
1dab94dd 708
c6a7ab1f
NC
709 case 'v':
710 if (op_mask & 1)
711 as_bad (_("even register number required"));
712 op_mask >>= 1;
713 break;
1dab94dd 714
c6a7ab1f 715 case 'w':
65b1d096 716 if ((op_mask & 1) || op_mask < 24)
c6a7ab1f 717 as_bad (_("register r24, r26, r28 or r30 required"));
65b1d096 718 op_mask = (op_mask - 24) >> 1;
c6a7ab1f
NC
719 break;
720 }
721 break;
722 }
723 as_bad (_("register name or number from 0 to 31 required"));
adde6300
AM
724 break;
725
726 case 'e':
727 {
728 char c;
1dab94dd 729
adde6300
AM
730 if (*str == '-')
731 {
c6a7ab1f 732 str = skip_space (str + 1);
adde6300
AM
733 op_mask = 0x1002;
734 }
3882b010 735 c = TOLOWER (*str);
adde6300
AM
736 if (c == 'x')
737 op_mask |= 0x100c;
738 else if (c == 'y')
739 op_mask |= 0x8;
740 else if (c != 'z')
00d2865b 741 as_bad (_("pointer register (X, Y or Z) required"));
adde6300 742
c6a7ab1f 743 str = skip_space (str + 1);
adde6300
AM
744 if (*str == '+')
745 {
746 ++str;
747 if (op_mask & 2)
00d2865b 748 as_bad (_("cannot both predecrement and postincrement"));
adde6300
AM
749 op_mask |= 0x1001;
750 }
e38c9cc2 751
1188e082 752 /* avr1 can do "ld r,Z" and "st Z,r" but no other pointer
e38c9cc2 753 registers, no predecrement, no postincrement. */
00d2865b
NC
754 if (!avr_opt.all_opcodes && (op_mask & 0x100F)
755 && !(avr_mcu->isa & AVR_ISA_SRAM))
756 as_bad (_("addressing mode not supported"));
adde6300
AM
757 }
758 break;
759
b170af93 760 case 'z':
c6a7ab1f
NC
761 if (*str == '-')
762 as_bad (_("can't predecrement"));
1dab94dd 763
c6a7ab1f
NC
764 if (! (*str == 'z' || *str == 'Z'))
765 as_bad (_("pointer register Z required"));
1dab94dd 766
c6a7ab1f
NC
767 str = skip_space (str + 1);
768
769 if (*str == '+')
770 {
771 ++str;
772 op_mask |= 1;
773 }
d669d37f
NC
774
775 /* attiny26 can do "lpm" and "lpm r,Z" but not "lpm r,Z+". */
776 if (!avr_opt.all_opcodes
777 && (op_mask & 0x0001)
778 && !(avr_mcu->isa & AVR_ISA_MOVW))
779 as_bad (_("postincrement not supported"));
b170af93
DC
780 break;
781
adde6300
AM
782 case 'b':
783 {
3882b010 784 char c = TOLOWER (*str++);
1dab94dd 785
adde6300
AM
786 if (c == 'y')
787 op_mask |= 0x8;
788 else if (c != 'z')
00d2865b 789 as_bad (_("pointer register (Y or Z) required"));
adde6300
AM
790 str = skip_space (str);
791 if (*str++ == '+')
792 {
750bce0e
NC
793 input_line_pointer = str;
794 avr_offset_expression (& op_expr);
adde6300 795 str = input_line_pointer;
750bce0e
NC
796 fix_new_exp (frag_now, where, 3,
797 &op_expr, FALSE, BFD_RELOC_AVR_6);
adde6300
AM
798 }
799 }
800 break;
801
802 case 'h':
c6a7ab1f
NC
803 str = parse_exp (str, &op_expr);
804 fix_new_exp (frag_now, where, opcode->insn_size * 2,
b34976b6 805 &op_expr, FALSE, BFD_RELOC_AVR_CALL);
adde6300
AM
806 break;
807
808 case 'L':
c6a7ab1f
NC
809 str = parse_exp (str, &op_expr);
810 fix_new_exp (frag_now, where, opcode->insn_size * 2,
b34976b6 811 &op_expr, TRUE, BFD_RELOC_AVR_13_PCREL);
adde6300
AM
812 break;
813
814 case 'l':
c6a7ab1f
NC
815 str = parse_exp (str, &op_expr);
816 fix_new_exp (frag_now, where, opcode->insn_size * 2,
b34976b6 817 &op_expr, TRUE, BFD_RELOC_AVR_7_PCREL);
adde6300
AM
818 break;
819
820 case 'i':
c6a7ab1f
NC
821 str = parse_exp (str, &op_expr);
822 fix_new_exp (frag_now, where + 2, opcode->insn_size * 2,
b34976b6 823 &op_expr, FALSE, BFD_RELOC_16);
adde6300
AM
824 break;
825
826 case 'M':
827 {
828 bfd_reloc_code_real_type r_type;
1dab94dd 829
c6a7ab1f
NC
830 input_line_pointer = str;
831 r_type = avr_ldi_expression (&op_expr);
832 str = input_line_pointer;
adde6300 833 fix_new_exp (frag_now, where, 3,
b34976b6 834 &op_expr, FALSE, r_type);
adde6300
AM
835 }
836 break;
837
838 case 'n':
839 {
840 unsigned int x;
1dab94dd 841
adde6300
AM
842 x = ~avr_get_constant (str, 255);
843 str = input_line_pointer;
844 op_mask |= (x & 0xf) | ((x << 4) & 0xf00);
845 }
846 break;
847
848 case 'K':
750bce0e
NC
849 input_line_pointer = str;
850 avr_offset_expression (& op_expr);
851 str = input_line_pointer;
852 fix_new_exp (frag_now, where, 3,
853 & op_expr, FALSE, BFD_RELOC_AVR_6_ADIW);
adde6300
AM
854 break;
855
856 case 'S':
857 case 's':
858 {
859 unsigned int x;
1dab94dd 860
adde6300
AM
861 x = avr_get_constant (str, 7);
862 str = input_line_pointer;
863 if (*op == 'S')
864 x <<= 4;
865 op_mask |= x;
866 }
867 break;
868
869 case 'P':
870 {
871 unsigned int x;
1dab94dd 872
adde6300
AM
873 x = avr_get_constant (str, 63);
874 str = input_line_pointer;
875 op_mask |= (x & 0xf) | ((x & 0x30) << 5);
876 }
877 break;
878
879 case 'p':
880 {
881 unsigned int x;
1dab94dd 882
adde6300
AM
883 x = avr_get_constant (str, 31);
884 str = input_line_pointer;
885 op_mask |= x << 3;
886 }
887 break;
1dab94dd 888
1188e082
DC
889 case '?':
890 break;
1dab94dd 891
adde6300 892 default:
00d2865b 893 as_bad (_("unknown constraint `%c'"), *op);
adde6300 894 }
1dab94dd 895
adde6300
AM
896 *line = str;
897 return op_mask;
898}
899
dc191a8f
NC
900/* Parse instruction operands.
901 Return binary opcode. */
902
903static unsigned int
904avr_operands (struct avr_opcodes_s *opcode, char **line)
905{
906 char *op = opcode->constraints;
907 unsigned int bin = opcode->bin_opcode;
908 char *frag = frag_more (opcode->insn_size * 2);
909 char *str = *line;
910 int where = frag - frag_now->fr_literal;
911 static unsigned int prev = 0; /* Previous opcode. */
912
913 /* Opcode have operands. */
914 if (*op)
915 {
916 unsigned int reg1 = 0;
917 unsigned int reg2 = 0;
918 int reg1_present = 0;
919 int reg2_present = 0;
920
921 /* Parse first operand. */
922 if (REGISTER_P (*op))
923 reg1_present = 1;
924 reg1 = avr_operand (opcode, where, op, &str);
925 ++op;
926
927 /* Parse second operand. */
928 if (*op)
929 {
930 if (*op == ',')
931 ++op;
932
933 if (*op == '=')
934 {
935 reg2 = reg1;
936 reg2_present = 1;
937 }
938 else
939 {
940 if (REGISTER_P (*op))
941 reg2_present = 1;
942
943 str = skip_space (str);
944 if (*str++ != ',')
945 as_bad (_("`,' required"));
946 str = skip_space (str);
947
948 reg2 = avr_operand (opcode, where, op, &str);
949 }
950
951 if (reg1_present && reg2_present)
952 reg2 = (reg2 & 0xf) | ((reg2 << 5) & 0x200);
953 else if (reg2_present)
954 reg2 <<= 4;
955 }
956 if (reg1_present)
957 reg1 <<= 4;
958 bin |= reg1 | reg2;
959 }
960
961 /* Detect undefined combinations (like ld r31,Z+). */
962 if (!avr_opt.all_opcodes && AVR_UNDEF_P (bin))
963 as_warn (_("undefined combination of operands"));
964
965 if (opcode->insn_size == 2)
966 {
967 /* Warn if the previous opcode was cpse/sbic/sbis/sbrc/sbrs
968 (AVR core bug, fixed in the newer devices). */
969 if (!(avr_opt.no_skip_bug ||
970 (avr_mcu->isa & (AVR_ISA_MUL | AVR_ISA_MOVW)))
971 && AVR_SKIP_P (prev))
972 as_warn (_("skipping two-word instruction"));
973
974 bfd_putl32 ((bfd_vma) bin, frag);
975 }
976 else
977 bfd_putl16 ((bfd_vma) bin, frag);
978
979 prev = bin;
980 *line = str;
981 return bin;
982}
983
adde6300
AM
984/* GAS will call this function for each section at the end of the assembly,
985 to permit the CPU backend to adjust the alignment of a section. */
c6a7ab1f 986
adde6300 987valueT
dc191a8f 988md_section_align (asection *seg, valueT addr)
adde6300
AM
989{
990 int align = bfd_get_section_alignment (stdoutput, seg);
991 return ((addr + (1 << align) - 1) & (-1 << align));
992}
993
994/* If you define this macro, it should return the offset between the
995 address of a PC relative fixup and the position from which the PC
996 relative adjustment should be made. On many processors, the base
997 of a PC relative instruction is the next instruction, so this
998 macro would return the length of an instruction. */
c6a7ab1f 999
adde6300 1000long
dc191a8f 1001md_pcrel_from_section (fixS *fixp, segT sec)
adde6300 1002{
c6a7ab1f 1003 if (fixp->fx_addsy != (symbolS *) NULL
adde6300
AM
1004 && (!S_IS_DEFINED (fixp->fx_addsy)
1005 || (S_GET_SEGMENT (fixp->fx_addsy) != sec)))
1006 return 0;
1dab94dd 1007
adde6300
AM
1008 return fixp->fx_frag->fr_address + fixp->fx_where;
1009}
1010
1011/* GAS will call this for each fixup. It should store the correct
c6a7ab1f
NC
1012 value in the object file. */
1013
94f592af 1014void
dc191a8f 1015md_apply_fix (fixS *fixP, valueT * valP, segT seg)
adde6300
AM
1016{
1017 unsigned char *where;
1018 unsigned long insn;
a161fe53 1019 long value = *valP;
adde6300 1020
94f592af
NC
1021 if (fixP->fx_addsy == (symbolS *) NULL)
1022 fixP->fx_done = 1;
1023
87733541
AM
1024 else if (fixP->fx_pcrel)
1025 {
1026 segT s = S_GET_SEGMENT (fixP->fx_addsy);
1027
1028 if (s == seg || s == absolute_section)
1029 {
1030 value += S_GET_VALUE (fixP->fx_addsy);
1031 fixP->fx_done = 1;
1032 }
1033 }
1034
a161fe53
AM
1035 /* We don't actually support subtracting a symbol. */
1036 if (fixP->fx_subsy != (symbolS *) NULL)
1037 as_bad_where (fixP->fx_file, fixP->fx_line, _("expression too complex"));
1dab94dd 1038
94f592af 1039 switch (fixP->fx_r_type)
adde6300
AM
1040 {
1041 default:
94f592af 1042 fixP->fx_no_overflow = 1;
adde6300
AM
1043 break;
1044 case BFD_RELOC_AVR_7_PCREL:
1045 case BFD_RELOC_AVR_13_PCREL:
1046 case BFD_RELOC_32:
1047 case BFD_RELOC_16:
1048 case BFD_RELOC_AVR_CALL:
1049 break;
1050 }
1051
94f592af 1052 if (fixP->fx_done)
adde6300
AM
1053 {
1054 /* Fetch the instruction, insert the fully resolved operand
1055 value, and stuff the instruction back again. */
2132e3a3 1056 where = (unsigned char *) fixP->fx_frag->fr_literal + fixP->fx_where;
adde6300
AM
1057 insn = bfd_getl16 (where);
1058
94f592af 1059 switch (fixP->fx_r_type)
adde6300
AM
1060 {
1061 case BFD_RELOC_AVR_7_PCREL:
1062 if (value & 1)
94f592af 1063 as_bad_where (fixP->fx_file, fixP->fx_line,
adde6300 1064 _("odd address operand: %ld"), value);
1dab94dd 1065
adde6300
AM
1066 /* Instruction addresses are always right-shifted by 1. */
1067 value >>= 1;
1068 --value; /* Correct PC. */
1dab94dd 1069
adde6300 1070 if (value < -64 || value > 63)
94f592af 1071 as_bad_where (fixP->fx_file, fixP->fx_line,
adde6300
AM
1072 _("operand out of range: %ld"), value);
1073 value = (value << 3) & 0x3f8;
1074 bfd_putl16 ((bfd_vma) (value | insn), where);
1075 break;
1076
1077 case BFD_RELOC_AVR_13_PCREL:
1078 if (value & 1)
94f592af 1079 as_bad_where (fixP->fx_file, fixP->fx_line,
adde6300 1080 _("odd address operand: %ld"), value);
1dab94dd 1081
adde6300
AM
1082 /* Instruction addresses are always right-shifted by 1. */
1083 value >>= 1;
1084 --value; /* Correct PC. */
adde6300
AM
1085
1086 if (value < -2048 || value > 2047)
1087 {
65aa24b6 1088 /* No wrap for devices with >8K of program memory. */
00d2865b 1089 if ((avr_mcu->isa & AVR_ISA_MEGA) || avr_opt.no_wrap)
94f592af 1090 as_bad_where (fixP->fx_file, fixP->fx_line,
adde6300
AM
1091 _("operand out of range: %ld"), value);
1092 }
1093
1094 value &= 0xfff;
1095 bfd_putl16 ((bfd_vma) (value | insn), where);
1096 break;
1097
1098 case BFD_RELOC_32:
1099 bfd_putl16 ((bfd_vma) value, where);
1100 break;
1101
1102 case BFD_RELOC_16:
1103 bfd_putl16 ((bfd_vma) value, where);
1104 break;
1105
1106 case BFD_RELOC_AVR_16_PM:
c6a7ab1f 1107 bfd_putl16 ((bfd_vma) (value >> 1), where);
adde6300
AM
1108 break;
1109
750bce0e
NC
1110 case BFD_RELOC_AVR_LDI:
1111 if (value > 255)
1112 as_bad_where (fixP->fx_file, fixP->fx_line,
1113 _("operand out of range: %ld"), value);
1114 bfd_putl16 ((bfd_vma) insn | LDI_IMMEDIATE (value), where);
1115 break;
1116
1117 case BFD_RELOC_AVR_6:
1118 if ((value > 63) || (value < 0))
1119 as_bad_where (fixP->fx_file, fixP->fx_line,
1120 _("operand out of range: %ld"), value);
1121 bfd_putl16 ((bfd_vma) insn | ((value & 7) | ((value & (3 << 3)) << 7) | ((value & (1 << 5)) << 8)), where);
1122 break;
1123
1124 case BFD_RELOC_AVR_6_ADIW:
1125 if ((value > 63) || (value < 0))
1126 as_bad_where (fixP->fx_file, fixP->fx_line,
1127 _("operand out of range: %ld"), value);
1128 bfd_putl16 ((bfd_vma) insn | (value & 0xf) | ((value & 0x30) << 2), where);
1129 break;
1130
adde6300
AM
1131 case BFD_RELOC_AVR_LO8_LDI:
1132 bfd_putl16 ((bfd_vma) insn | LDI_IMMEDIATE (value), where);
1133 break;
1134
adde6300
AM
1135 case BFD_RELOC_AVR_HI8_LDI:
1136 bfd_putl16 ((bfd_vma) insn | LDI_IMMEDIATE (value >> 8), where);
1137 break;
1138
df406460 1139 case BFD_RELOC_AVR_MS8_LDI:
adde6300
AM
1140 bfd_putl16 ((bfd_vma) insn | LDI_IMMEDIATE (value >> 24), where);
1141 break;
1142
1143 case BFD_RELOC_AVR_HH8_LDI:
1144 bfd_putl16 ((bfd_vma) insn | LDI_IMMEDIATE (value >> 16), where);
1145 break;
1146
1147 case BFD_RELOC_AVR_LO8_LDI_NEG:
1148 bfd_putl16 ((bfd_vma) insn | LDI_IMMEDIATE (-value), where);
1149 break;
1150
adde6300
AM
1151 case BFD_RELOC_AVR_HI8_LDI_NEG:
1152 bfd_putl16 ((bfd_vma) insn | LDI_IMMEDIATE (-value >> 8), where);
1153 break;
1154
df406460 1155 case BFD_RELOC_AVR_MS8_LDI_NEG:
adde6300
AM
1156 bfd_putl16 ((bfd_vma) insn | LDI_IMMEDIATE (-value >> 24), where);
1157 break;
1158
1159 case BFD_RELOC_AVR_HH8_LDI_NEG:
1160 bfd_putl16 ((bfd_vma) insn | LDI_IMMEDIATE (-value >> 16), where);
1161 break;
1162
1163 case BFD_RELOC_AVR_LO8_LDI_PM:
1164 bfd_putl16 ((bfd_vma) insn | LDI_IMMEDIATE (value >> 1), where);
1165 break;
1166
1167 case BFD_RELOC_AVR_HI8_LDI_PM:
1168 bfd_putl16 ((bfd_vma) insn | LDI_IMMEDIATE (value >> 9), where);
1169 break;
1170
1171 case BFD_RELOC_AVR_HH8_LDI_PM:
1172 bfd_putl16 ((bfd_vma) insn | LDI_IMMEDIATE (value >> 17), where);
1173 break;
1174
1175 case BFD_RELOC_AVR_LO8_LDI_PM_NEG:
1176 bfd_putl16 ((bfd_vma) insn | LDI_IMMEDIATE (-value >> 1), where);
1177 break;
1178
1179 case BFD_RELOC_AVR_HI8_LDI_PM_NEG:
1180 bfd_putl16 ((bfd_vma) insn | LDI_IMMEDIATE (-value >> 9), where);
1181 break;
1182
1183 case BFD_RELOC_AVR_HH8_LDI_PM_NEG:
1184 bfd_putl16 ((bfd_vma) insn | LDI_IMMEDIATE (-value >> 17), where);
1185 break;
1186
1187 case BFD_RELOC_AVR_CALL:
1188 {
1189 unsigned long x;
1dab94dd 1190
adde6300
AM
1191 x = bfd_getl16 (where);
1192 if (value & 1)
94f592af 1193 as_bad_where (fixP->fx_file, fixP->fx_line,
adde6300
AM
1194 _("odd address operand: %ld"), value);
1195 value >>= 1;
1196 x |= ((value & 0x10000) | ((value << 3) & 0x1f00000)) >> 16;
1197 bfd_putl16 ((bfd_vma) x, where);
c6a7ab1f 1198 bfd_putl16 ((bfd_vma) (value & 0xffff), where + 2);
adde6300
AM
1199 }
1200 break;
1201
1202 default:
c6a7ab1f 1203 as_fatal (_("line %d: unknown relocation type: 0x%x"),
94f592af 1204 fixP->fx_line, fixP->fx_r_type);
adde6300
AM
1205 break;
1206 }
1207 }
1208 else
1209 {
94f592af 1210 switch (fixP->fx_r_type)
adde6300
AM
1211 {
1212 case -BFD_RELOC_AVR_HI8_LDI_NEG:
1213 case -BFD_RELOC_AVR_HI8_LDI:
1214 case -BFD_RELOC_AVR_LO8_LDI_NEG:
1215 case -BFD_RELOC_AVR_LO8_LDI:
94f592af 1216 as_bad_where (fixP->fx_file, fixP->fx_line,
adde6300 1217 _("only constant expression allowed"));
94f592af 1218 fixP->fx_done = 1;
adde6300
AM
1219 break;
1220 default:
1221 break;
1222 }
adde6300 1223 }
adde6300
AM
1224}
1225
7be1c489
AM
1226/* GAS will call this to generate a reloc, passing the resulting reloc
1227 to `bfd_install_relocation'. This currently works poorly, as
1228 `bfd_install_relocation' often does the wrong thing, and instances of
1229 `tc_gen_reloc' have been written to work around the problems, which
1230 in turns makes it difficult to fix `bfd_install_relocation'. */
adde6300
AM
1231
1232/* If while processing a fixup, a reloc really needs to be created
1233 then it is done here. */
1234
1235arelent *
dc191a8f
NC
1236tc_gen_reloc (asection *seg ATTRIBUTE_UNUSED,
1237 fixS *fixp)
adde6300
AM
1238{
1239 arelent *reloc;
1240
df406460
NC
1241 if (fixp->fx_addsy && fixp->fx_subsy)
1242 {
1243 long value = 0;
1244
1245 if ((S_GET_SEGMENT (fixp->fx_addsy) != S_GET_SEGMENT (fixp->fx_subsy))
1246 || S_GET_SEGMENT (fixp->fx_addsy) == undefined_section)
1247 {
1248 as_bad_where (fixp->fx_file, fixp->fx_line,
1249 "Difference of symbols in different sections is not supported");
1250 return NULL;
1251 }
1252
28c9d252 1253 /* We are dealing with two symbols defined in the same section.
df406460
NC
1254 Let us fix-up them here. */
1255 value += S_GET_VALUE (fixp->fx_addsy);
1256 value -= S_GET_VALUE (fixp->fx_subsy);
1257
1258 /* When fx_addsy and fx_subsy both are zero, md_apply_fix
1259 only takes it's second operands for the fixup value. */
1260 fixp->fx_addsy = NULL;
1261 fixp->fx_subsy = NULL;
1262 md_apply_fix (fixp, (valueT *) &value, NULL);
1263
1264 return NULL;
1265 }
1266
dc191a8f 1267 reloc = xmalloc (sizeof (arelent));
adde6300 1268
dc191a8f 1269 reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
adde6300
AM
1270 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
1271
1272 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
1273 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
1274 if (reloc->howto == (reloc_howto_type *) NULL)
1275 {
1276 as_bad_where (fixp->fx_file, fixp->fx_line,
c6a7ab1f
NC
1277 _("reloc %d not supported by object file format"),
1278 (int) fixp->fx_r_type);
adde6300
AM
1279 return NULL;
1280 }
1281
1282 if (fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT
1283 || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
1284 reloc->address = fixp->fx_offset;
1285
1286 reloc->addend = fixp->fx_offset;
1287
1288 return reloc;
1289}
1290
adde6300 1291void
dc191a8f 1292md_assemble (char *str)
adde6300 1293{
c6a7ab1f 1294 struct avr_opcodes_s *opcode;
adde6300
AM
1295 char op[11];
1296
c6a7ab1f 1297 str = skip_space (extract_word (str, op, sizeof (op)));
adde6300
AM
1298
1299 if (!op[0])
00d2865b 1300 as_bad (_("can't find opcode "));
adde6300
AM
1301
1302 opcode = (struct avr_opcodes_s *) hash_find (avr_hash, op);
1303
1304 if (opcode == NULL)
1305 {
00d2865b 1306 as_bad (_("unknown opcode `%s'"), op);
adde6300
AM
1307 return;
1308 }
1309
b170af93 1310 /* Special case for opcodes with optional operands (lpm, elpm) -
1188e082 1311 version with operands exists in avr_opcodes[] in the next entry. */
c6a7ab1f 1312
1188e082
DC
1313 if (*str && *opcode->constraints == '?')
1314 ++opcode;
b170af93 1315
00d2865b
NC
1316 if (!avr_opt.all_opcodes && (opcode->isa & avr_mcu->isa) != opcode->isa)
1317 as_bad (_("illegal opcode %s for mcu %s"), opcode->name, avr_mcu->name);
adde6300
AM
1318
1319 /* We used to set input_line_pointer to the result of get_operands,
1320 but that is wrong. Our caller assumes we don't change it. */
1321 {
1322 char *t = input_line_pointer;
dc191a8f 1323
adde6300 1324 avr_operands (opcode, &str);
b170af93 1325 if (*skip_space (str))
00d2865b 1326 as_bad (_("garbage at end of line"));
adde6300
AM
1327 input_line_pointer = t;
1328 }
1329}
1330
adde6300 1331/* Flag to pass `pm' mode between `avr_parse_cons_expression' and
c6a7ab1f 1332 `avr_cons_fix_new'. */
adde6300
AM
1333static int exp_mod_pm = 0;
1334
1335/* Parse special CONS expression: pm (expression)
28c9d252
NC
1336 or alternatively: gs (expression).
1337 These are used for addressing program memory.
c6a7ab1f
NC
1338 Relocation: BFD_RELOC_AVR_16_PM. */
1339
adde6300 1340void
dc191a8f 1341avr_parse_cons_expression (expressionS *exp, int nbytes)
adde6300 1342{
c6a7ab1f 1343 char *tmp;
adde6300
AM
1344
1345 exp_mod_pm = 0;
1346
1347 tmp = input_line_pointer = skip_space (input_line_pointer);
1348
1349 if (nbytes == 2)
1350 {
28c9d252
NC
1351 char *pm_name1 = "pm";
1352 char *pm_name2 = "gs";
1353 int len = strlen (pm_name1);
1354 /* len must be the same for both pm identifiers. */
1dab94dd 1355
28c9d252
NC
1356 if (strncasecmp (input_line_pointer, pm_name1, len) == 0
1357 || strncasecmp (input_line_pointer, pm_name2, len) == 0)
adde6300
AM
1358 {
1359 input_line_pointer = skip_space (input_line_pointer + len);
1dab94dd 1360
adde6300
AM
1361 if (*input_line_pointer == '(')
1362 {
1363 input_line_pointer = skip_space (input_line_pointer + 1);
1364 exp_mod_pm = 1;
1365 expression (exp);
1dab94dd 1366
adde6300
AM
1367 if (*input_line_pointer == ')')
1368 ++input_line_pointer;
1369 else
1370 {
00d2865b 1371 as_bad (_("`)' required"));
adde6300
AM
1372 exp_mod_pm = 0;
1373 }
1dab94dd 1374
adde6300
AM
1375 return;
1376 }
1dab94dd 1377
adde6300
AM
1378 input_line_pointer = tmp;
1379 }
1380 }
1dab94dd 1381
adde6300
AM
1382 expression (exp);
1383}
1384
1385void
dc191a8f
NC
1386avr_cons_fix_new (fragS *frag,
1387 int where,
1388 int nbytes,
1389 expressionS *exp)
adde6300
AM
1390{
1391 if (exp_mod_pm == 0)
1392 {
1393 if (nbytes == 2)
b34976b6 1394 fix_new_exp (frag, where, nbytes, exp, FALSE, BFD_RELOC_16);
adde6300 1395 else if (nbytes == 4)
b34976b6 1396 fix_new_exp (frag, where, nbytes, exp, FALSE, BFD_RELOC_32);
adde6300 1397 else
00d2865b 1398 as_bad (_("illegal %srelocation size: %d"), "", nbytes);
adde6300
AM
1399 }
1400 else
1401 {
1402 if (nbytes == 2)
b34976b6 1403 fix_new_exp (frag, where, nbytes, exp, FALSE, BFD_RELOC_AVR_16_PM);
adde6300 1404 else
00d2865b 1405 as_bad (_("illegal %srelocation size: %d"), "`pm' ", nbytes);
adde6300
AM
1406 exp_mod_pm = 0;
1407 }
1408}
This page took 0.455998 seconds and 4 git commands to generate.