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