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