blob: b9fa9ed8681c88aba09297ef0e4ae0762916a029 [file] [log] [blame]
Alan Modraadde6302000-03-27 08:39:14 +00001/* tc-avr.c -- Assembler code for the ATMEL AVR
2
Alan Modrafd67aa12024-01-04 22:22:08 +10303 Copyright (C) 1999-2024 Free Software Foundation, Inc.
Alan Modraadde6302000-03-27 08:39:14 +00004 Contributed by Denis Chertykov <denisc@overta.ru>
5
6 This file is part of GAS, the GNU Assembler.
7
8 GAS is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
Nick Cliftonec2655a2007-07-03 11:01:12 +000010 the Free Software Foundation; either version 3, or (at your option)
Alan Modraadde6302000-03-27 08:39:14 +000011 any later version.
12
13 GAS is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GAS; see the file COPYING. If not, write to
Nick Clifton4b4da162005-05-05 09:13:19 +000020 the Free Software Foundation, 51 Franklin Street - Fifth Floor,
21 Boston, MA 02110-1301, USA. */
Alan Modraadde6302000-03-27 08:39:14 +000022
Alan Modraadde6302000-03-27 08:39:14 +000023#include "as.h"
H.J. Lu3882b012001-09-19 05:33:36 +000024#include "safe-ctype.h"
Alan Modraadde6302000-03-27 08:39:14 +000025#include "subsegs.h"
Nick Cliftonfb5b7502013-01-23 12:01:12 +000026#include "dwarf2dbg.h"
Richard Hendersonaf3ecb42011-03-29 18:16:16 +000027#include "dw2gencfi.h"
Andrew Burgesseac74402014-11-22 23:19:31 +000028#include "elf/avr.h"
Andrew Burgessfdd410a2015-01-08 20:55:10 +000029#include "elf32-avr.h"
30
31/* For building a linked list of AVR_PROPERTY_RECORD structures. */
32struct avr_property_record_link
33{
34 struct avr_property_record record;
35 struct avr_property_record_link *next;
36};
Alan Modraadde6302000-03-27 08:39:14 +000037
Denis Chertykov1188e082000-06-07 17:42:44 +000038struct avr_opcodes_s
39{
Alan Modra5b7c81b2021-03-31 10:42:05 +103040 const char *name;
41 const char *constraints;
42 const char *opcode;
43 int insn_size; /* In words. */
44 int isa;
45 unsigned int bin_opcode;
Denis Chertykov1188e082000-06-07 17:42:44 +000046};
47
48#define AVR_INSN(NAME, CONSTR, OPCODE, SIZE, ISA, BIN) \
Eric B. Weddington8cc66332011-03-22 18:10:48 +000049{#NAME, CONSTR, OPCODE, SIZE, ISA, BIN},
Denis Chertykov1188e082000-06-07 17:42:44 +000050
51struct avr_opcodes_s avr_opcodes[] =
52{
53 #include "opcode/avr.h"
Eric B. Weddington8cc66332011-03-22 18:10:48 +000054 {NULL, NULL, NULL, 0, 0, 0}
Denis Chertykov1188e082000-06-07 17:42:44 +000055};
56
Georg-Johann Lay32f76c62017-06-30 16:37:39 +010057
58/* Stuff for the `__gcc_isr' pseudo instruction.
59
60 Purpose of the pseudo instruction is to emit more efficient ISR prologues
61 and epilogues than GCC currently does. GCC has no explicit (on RTL level)
62 modelling of SREG, TMP_REG or ZERO_REG. These regs are used implicitly
63 during instruction printing. That doesn't hurt too much for ordinary
64 functions, however for small ISRs there might be some overhead.
65
66 As implementing http://gcc.gnu.org/PR20296 would imply an almost complete
67 rewite of GCC's AVR back-end (which might pop up less optimized code in
68 other places), we provide a pseudo-instruction which is resolved by GAS
69 into ISR prologue / epilogue as expected by GCC.
70
71 Using GAS for this purpose has the additional benefit that it can scan
72 code emit by inline asm which is opaque to GCC.
73
74 The pseudo-instruction is only supposed to handle the starting of
75 prologue and the ending of epilogues (without RETI) which deal with
76 SREG, TMP_REG and ZERO_REG and one additional, optional general purpose
77 register.
78
79 __gcc_isr consists of 3 different "chunks":
80
81 __gcc_isr 1
82 Chunk 1 (ISR_CHUNK_Prologue)
83 Start the ISR code. Will be replaced by ISR prologue by next Done chunk.
84 Must be the 1st chunk in a file or follow a Done chunk from previous
85 ISR (which has been patched already).
86
87 It will finish the current frag and emit a new frag of
88 type rs_machine_dependent, subtype ISR_CHUNK_Prologue.
89
90 __gcc_isr 2
91 Chunk 2 (ISR_CHUNK_Epilogue)
92 Will be replaced by ISR epilogue by next Done chunk. Must follow
93 chunk 1 (Prologue) or chunk 2 (Epilogue). Functions might come
94 without epilogue or with more than one epilogue, and even code
95 located statically after the last epilogue might belong to a function.
96
97 It will finish the current frag and emit a new frag of
98 type rs_machine_dependent, subtype ISR_CHUNK_Epilogue.
99
100 __gcc_isr 0, Rx
101 Chunk 0 (ISR_CHUNK_Done)
102 Must follow chunk 1 (Prologue) or chunk 2 (Epilogue) and finishes
103 the ISR code. Only GCC can know where a function's code ends.
104
105 It triggers the patch-up of all rs_machine_dependent frags in the
106 current frag chain and turns them into ordinary rs_fill code frags.
107
108 If Rx is a register > ZERO_REG then GCC also wants to push / pop Rx.
109 If neither TMP_REG nor ZERO_REG are needed, Rx will be used in
110 the push / pop sequence avoiding the need for TMP_REG / ZERO_REG.
111 If Rx <= ZERO_REG then GCC doesn't assume anything about Rx.
112
113 Assumptions:
114
115 o GCC takes care of code that is opaque to GAS like tail calls
116 or non-local goto.
117
118 o Using SEI / CLI does not count as clobbering SREG. This is
119 because a final RETI will restore the I-flag.
120
121 o Using OUT or ST* is supposed not to clobber SREG. Sequences like
122
123 IN-SREG + CLI + Atomic-Code + OUT-SREG
124
125 will still work as expected because the scan will reveal any
126 clobber of SREG other than I-flag and emit PUSH / POP of SREG.
127*/
128
129enum
130 {
131 ISR_CHUNK_Done = 0,
132 ISR_CHUNK_Prologue = 1,
133 ISR_CHUNK_Epilogue = 2
134 };
135
136static struct
137{
138 /* Previous __gcc_isr chunk (one of the enums above)
139 and it's location for diagnostics. */
140 int prev_chunk;
141 unsigned line;
142 const char *file;
143 /* Replacer for __gcc_isr.n_pushed once we know how many regs are
144 pushed by the Prologue chunk. */
145 symbolS *sym_n_pushed;
146
147 /* Set and used during parse from chunk 1 (Prologue) up to chunk 0 (Done).
148 Set by `avr_update_gccisr' and used by `avr_patch_gccisr_frag'. */
149 int need_reg_tmp;
150 int need_reg_zero;
151 int need_sreg;
152} avr_isr;
153
154static void avr_gccisr_operands (struct avr_opcodes_s*, char**);
155static void avr_update_gccisr (struct avr_opcodes_s*, int, int);
156static struct avr_opcodes_s *avr_gccisr_opcode;
157
Alan Modraadde6302000-03-27 08:39:14 +0000158const char comment_chars[] = ";";
159const char line_comment_chars[] = "#";
Matt Jacobsond86d1fc2021-08-11 10:03:19 +0100160
161const char *avr_line_separator_chars = "$";
162static const char *avr_line_separator_chars_no_dollar = "";
Alan Modraadde6302000-03-27 08:39:14 +0000163
Alan Modraadde6302000-03-27 08:39:14 +0000164const char *md_shortopts = "m:";
165struct mcu_type_s
166{
Trevor Saunderse0471c12016-02-25 16:55:21 +0000167 const char *name;
Alan Modraadde6302000-03-27 08:39:14 +0000168 int isa;
169 int mach;
170};
171
Denis Chertykov1f8ae5e2001-11-10 09:35:53 +0000172/* XXX - devices that don't seem to exist (renamed, replaced with larger
Eric B. Weddington7b21ac32008-08-09 05:35:13 +0000173 ones, or planned but never produced), left here for compatibility. */
Denis Chertykov1f8ae5e2001-11-10 09:35:53 +0000174
Alan Modraadde6302000-03-27 08:39:14 +0000175static struct mcu_type_s mcu_types[] =
176{
Eric B. Weddington7b21ac32008-08-09 05:35:13 +0000177 {"avr1", AVR_ISA_AVR1, bfd_mach_avr1},
Nick Clifton33eaf5d2017-01-23 15:23:07 +0000178/* TODO: instruction set for avr2 architecture should be AVR_ISA_AVR2,
Nick Clifton99700d62012-05-11 12:59:23 +0000179 but set to AVR_ISA_AVR25 for some following version
180 of GCC (from 4.3) for backward compatibility. */
Eric B. Weddington7b21ac32008-08-09 05:35:13 +0000181 {"avr2", AVR_ISA_AVR25, bfd_mach_avr2},
182 {"avr25", AVR_ISA_AVR25, bfd_mach_avr25},
Nick Clifton33eaf5d2017-01-23 15:23:07 +0000183/* TODO: instruction set for avr3 architecture should be AVR_ISA_AVR3,
Nick Clifton99700d62012-05-11 12:59:23 +0000184 but set to AVR_ISA_AVR3_ALL for some following version
Eric B. Weddington7b21ac32008-08-09 05:35:13 +0000185 of GCC (from 4.3) for backward compatibility. */
186 {"avr3", AVR_ISA_AVR3_ALL, bfd_mach_avr3},
187 {"avr31", AVR_ISA_AVR31, bfd_mach_avr31},
188 {"avr35", AVR_ISA_AVR35, bfd_mach_avr35},
189 {"avr4", AVR_ISA_AVR4, bfd_mach_avr4},
Nick Clifton33eaf5d2017-01-23 15:23:07 +0000190/* TODO: instruction set for avr5 architecture should be AVR_ISA_AVR5,
Nick Clifton99700d62012-05-11 12:59:23 +0000191 but set to AVR_ISA_AVR51 for some following version
Eric B. Weddington7b21ac32008-08-09 05:35:13 +0000192 of GCC (from 4.3) for backward compatibility. */
193 {"avr5", AVR_ISA_AVR51, bfd_mach_avr5},
194 {"avr51", AVR_ISA_AVR51, bfd_mach_avr51},
195 {"avr6", AVR_ISA_AVR6, bfd_mach_avr6},
Eric B. Weddington8cc66332011-03-22 18:10:48 +0000196 {"avrxmega1", AVR_ISA_XMEGA, bfd_mach_avrxmega1},
197 {"avrxmega2", AVR_ISA_XMEGA, bfd_mach_avrxmega2},
198 {"avrxmega3", AVR_ISA_XMEGA, bfd_mach_avrxmega3},
199 {"avrxmega4", AVR_ISA_XMEGA, bfd_mach_avrxmega4},
200 {"avrxmega5", AVR_ISA_XMEGA, bfd_mach_avrxmega5},
201 {"avrxmega6", AVR_ISA_XMEGA, bfd_mach_avrxmega6},
202 {"avrxmega7", AVR_ISA_XMEGA, bfd_mach_avrxmega7},
Barney Stratfordf36e8882014-07-01 10:20:17 +0100203 {"avrtiny", AVR_ISA_AVRTINY, bfd_mach_avrtiny},
Nick Clifton28c9d252006-05-24 07:36:12 +0000204 {"at90s1200", AVR_ISA_1200, bfd_mach_avr1},
Eric B. Weddington7b21ac32008-08-09 05:35:13 +0000205 {"attiny11", AVR_ISA_AVR1, bfd_mach_avr1},
206 {"attiny12", AVR_ISA_AVR1, bfd_mach_avr1},
207 {"attiny15", AVR_ISA_AVR1, bfd_mach_avr1},
208 {"attiny28", AVR_ISA_AVR1, bfd_mach_avr1},
209 {"at90s2313", AVR_ISA_AVR2, bfd_mach_avr2},
210 {"at90s2323", AVR_ISA_AVR2, bfd_mach_avr2},
211 {"at90s2333", AVR_ISA_AVR2, bfd_mach_avr2}, /* XXX -> 4433 */
212 {"at90s2343", AVR_ISA_AVR2, bfd_mach_avr2},
213 {"attiny22", AVR_ISA_AVR2, bfd_mach_avr2}, /* XXX -> 2343 */
Nick Cliftond669d372008-02-14 13:04:29 +0000214 {"attiny26", AVR_ISA_2xxe, bfd_mach_avr2},
Eric B. Weddington7b21ac32008-08-09 05:35:13 +0000215 {"at90s4414", AVR_ISA_AVR2, bfd_mach_avr2}, /* XXX -> 8515 */
216 {"at90s4433", AVR_ISA_AVR2, bfd_mach_avr2},
217 {"at90s4434", AVR_ISA_AVR2, bfd_mach_avr2}, /* XXX -> 8535 */
218 {"at90s8515", AVR_ISA_AVR2, bfd_mach_avr2},
219 {"at90c8534", AVR_ISA_AVR2, bfd_mach_avr2},
220 {"at90s8535", AVR_ISA_AVR2, bfd_mach_avr2},
Denis Chertykov255d9ee2014-03-06 18:59:05 +0400221 {"ata5272", AVR_ISA_AVR25, bfd_mach_avr25},
Eric B. Weddington7b21ac32008-08-09 05:35:13 +0000222 {"attiny13", AVR_ISA_AVR25, bfd_mach_avr25},
223 {"attiny13a", AVR_ISA_AVR25, bfd_mach_avr25},
224 {"attiny2313", AVR_ISA_AVR25, bfd_mach_avr25},
Eric B. Weddington8453da22009-08-05 12:47:33 +0000225 {"attiny2313a",AVR_ISA_AVR25, bfd_mach_avr25},
Eric B. Weddington7b21ac32008-08-09 05:35:13 +0000226 {"attiny24", AVR_ISA_AVR25, bfd_mach_avr25},
Eric B. Weddington8453da22009-08-05 12:47:33 +0000227 {"attiny24a", AVR_ISA_AVR25, bfd_mach_avr25},
228 {"attiny4313", AVR_ISA_AVR25, bfd_mach_avr25},
Eric B. Weddington7b21ac32008-08-09 05:35:13 +0000229 {"attiny44", AVR_ISA_AVR25, bfd_mach_avr25},
Eric B. Weddington8453da22009-08-05 12:47:33 +0000230 {"attiny44a", AVR_ISA_AVR25, bfd_mach_avr25},
Eric B. Weddington7b21ac32008-08-09 05:35:13 +0000231 {"attiny84", AVR_ISA_AVR25, bfd_mach_avr25},
Eric B. Weddingtone760a812010-04-09 03:48:54 +0000232 {"attiny84a", AVR_ISA_AVR25, bfd_mach_avr25},
Eric B. Weddington7b21ac32008-08-09 05:35:13 +0000233 {"attiny25", AVR_ISA_AVR25, bfd_mach_avr25},
234 {"attiny45", AVR_ISA_AVR25, bfd_mach_avr25},
235 {"attiny85", AVR_ISA_AVR25, bfd_mach_avr25},
236 {"attiny261", AVR_ISA_AVR25, bfd_mach_avr25},
Eric B. Weddington8453da22009-08-05 12:47:33 +0000237 {"attiny261a", AVR_ISA_AVR25, bfd_mach_avr25},
Eric B. Weddington7b21ac32008-08-09 05:35:13 +0000238 {"attiny461", AVR_ISA_AVR25, bfd_mach_avr25},
Eric B. Weddingtone760a812010-04-09 03:48:54 +0000239 {"attiny461a", AVR_ISA_AVR25, bfd_mach_avr25},
Eric B. Weddington7b21ac32008-08-09 05:35:13 +0000240 {"attiny861", AVR_ISA_AVR25, bfd_mach_avr25},
Eric B. Weddington8453da22009-08-05 12:47:33 +0000241 {"attiny861a", AVR_ISA_AVR25, bfd_mach_avr25},
Nick Clifton2b02f872008-12-23 09:51:38 +0000242 {"attiny87", AVR_ISA_AVR25, bfd_mach_avr25},
Eric B. Weddington7b21ac32008-08-09 05:35:13 +0000243 {"attiny43u", AVR_ISA_AVR25, bfd_mach_avr25},
244 {"attiny48", AVR_ISA_AVR25, bfd_mach_avr25},
245 {"attiny88", AVR_ISA_AVR25, bfd_mach_avr25},
Denis Chertykov255d9ee2014-03-06 18:59:05 +0400246 {"attiny828", AVR_ISA_AVR25, bfd_mach_avr25},
Eric B. Weddington7b21ac32008-08-09 05:35:13 +0000247 {"at86rf401", AVR_ISA_RF401, bfd_mach_avr25},
248 {"at43usb355", AVR_ISA_AVR3, bfd_mach_avr3},
249 {"at76c711", AVR_ISA_AVR3, bfd_mach_avr3},
250 {"atmega103", AVR_ISA_AVR31, bfd_mach_avr31},
251 {"at43usb320", AVR_ISA_AVR31, bfd_mach_avr31},
252 {"attiny167", AVR_ISA_AVR35, bfd_mach_avr35},
253 {"at90usb82", AVR_ISA_AVR35, bfd_mach_avr35},
254 {"at90usb162", AVR_ISA_AVR35, bfd_mach_avr35},
Denis Chertykov255d9ee2014-03-06 18:59:05 +0400255 {"ata5505", AVR_ISA_AVR35, bfd_mach_avr35},
Eric B. Weddington11908002009-08-01 16:17:23 +0000256 {"atmega8u2", AVR_ISA_AVR35, bfd_mach_avr35},
257 {"atmega16u2", AVR_ISA_AVR35, bfd_mach_avr35},
258 {"atmega32u2", AVR_ISA_AVR35, bfd_mach_avr35},
Denis Chertykov255d9ee2014-03-06 18:59:05 +0400259 {"attiny1634", AVR_ISA_AVR35, bfd_mach_avr35},
Nick Clifton28c9d252006-05-24 07:36:12 +0000260 {"atmega8", AVR_ISA_M8, bfd_mach_avr4},
Nick Clifton8be59ac2013-07-18 11:47:30 +0000261 {"ata6289", AVR_ISA_AVR4, bfd_mach_avr4},
Denis Chertykov255d9ee2014-03-06 18:59:05 +0400262 {"atmega8a", AVR_ISA_M8, bfd_mach_avr4},
263 {"ata6285", AVR_ISA_AVR4, bfd_mach_avr4},
264 {"ata6286", AVR_ISA_AVR4, bfd_mach_avr4},
Eric B. Weddington7b21ac32008-08-09 05:35:13 +0000265 {"atmega48", AVR_ISA_AVR4, bfd_mach_avr4},
Eric B. Weddingtone760a812010-04-09 03:48:54 +0000266 {"atmega48a", AVR_ISA_AVR4, bfd_mach_avr4},
Denis Chertykov255d9ee2014-03-06 18:59:05 +0400267 {"atmega48pa", AVR_ISA_AVR4, bfd_mach_avr4},
Eric B. Weddington7b21ac32008-08-09 05:35:13 +0000268 {"atmega48p", AVR_ISA_AVR4, bfd_mach_avr4},
269 {"atmega88", AVR_ISA_AVR4, bfd_mach_avr4},
Eric B. Weddingtone760a812010-04-09 03:48:54 +0000270 {"atmega88a", AVR_ISA_AVR4, bfd_mach_avr4},
Eric B. Weddington7b21ac32008-08-09 05:35:13 +0000271 {"atmega88p", AVR_ISA_AVR4, bfd_mach_avr4},
Eric B. Weddingtone760a812010-04-09 03:48:54 +0000272 {"atmega88pa", AVR_ISA_AVR4, bfd_mach_avr4},
Nick Clifton28c9d252006-05-24 07:36:12 +0000273 {"atmega8515", AVR_ISA_M8, bfd_mach_avr4},
274 {"atmega8535", AVR_ISA_M8, bfd_mach_avr4},
Eric B. Weddington7b21ac32008-08-09 05:35:13 +0000275 {"atmega8hva", AVR_ISA_AVR4, bfd_mach_avr4},
276 {"at90pwm1", AVR_ISA_AVR4, bfd_mach_avr4},
277 {"at90pwm2", AVR_ISA_AVR4, bfd_mach_avr4},
278 {"at90pwm2b", AVR_ISA_AVR4, bfd_mach_avr4},
279 {"at90pwm3", AVR_ISA_AVR4, bfd_mach_avr4},
280 {"at90pwm3b", AVR_ISA_AVR4, bfd_mach_avr4},
Nick Clifton2b02f872008-12-23 09:51:38 +0000281 {"at90pwm81", AVR_ISA_AVR4, bfd_mach_avr4},
Denis Chertykov255d9ee2014-03-06 18:59:05 +0400282 {"at90pwm161", AVR_ISA_AVR5, bfd_mach_avr5},
283 {"ata5790", AVR_ISA_AVR5, bfd_mach_avr5},
284 {"ata5795", AVR_ISA_AVR5, bfd_mach_avr5},
Eric B. Weddington7b21ac32008-08-09 05:35:13 +0000285 {"atmega16", AVR_ISA_AVR5, bfd_mach_avr5},
Eric B. Weddingtone760a812010-04-09 03:48:54 +0000286 {"atmega16a", AVR_ISA_AVR5, bfd_mach_avr5},
Nick Clifton28c9d252006-05-24 07:36:12 +0000287 {"atmega161", AVR_ISA_M161, bfd_mach_avr5},
Eric B. Weddington7b21ac32008-08-09 05:35:13 +0000288 {"atmega162", AVR_ISA_AVR5, bfd_mach_avr5},
Nick Clifton28c9d252006-05-24 07:36:12 +0000289 {"atmega163", AVR_ISA_M161, bfd_mach_avr5},
Eric B. Weddingtone760a812010-04-09 03:48:54 +0000290 {"atmega164a", AVR_ISA_AVR5, bfd_mach_avr5},
Eric B. Weddington7b21ac32008-08-09 05:35:13 +0000291 {"atmega164p", AVR_ISA_AVR5, bfd_mach_avr5},
Denis Chertykov255d9ee2014-03-06 18:59:05 +0400292 {"atmega164pa",AVR_ISA_AVR5, bfd_mach_avr5},
Eric B. Weddington7b21ac32008-08-09 05:35:13 +0000293 {"atmega165", AVR_ISA_AVR5, bfd_mach_avr5},
Eric B. Weddingtone760a812010-04-09 03:48:54 +0000294 {"atmega165a", AVR_ISA_AVR5, bfd_mach_avr5},
Eric B. Weddington7b21ac32008-08-09 05:35:13 +0000295 {"atmega165p", AVR_ISA_AVR5, bfd_mach_avr5},
Denis Chertykov255d9ee2014-03-06 18:59:05 +0400296 {"atmega165pa",AVR_ISA_AVR5, bfd_mach_avr5},
Eric B. Weddington7b21ac32008-08-09 05:35:13 +0000297 {"atmega168", AVR_ISA_AVR5, bfd_mach_avr5},
Eric B. Weddingtone760a812010-04-09 03:48:54 +0000298 {"atmega168a", AVR_ISA_AVR5, bfd_mach_avr5},
Eric B. Weddington7b21ac32008-08-09 05:35:13 +0000299 {"atmega168p", AVR_ISA_AVR5, bfd_mach_avr5},
Denis Chertykov255d9ee2014-03-06 18:59:05 +0400300 {"atmega168pa",AVR_ISA_AVR5, bfd_mach_avr5},
Eric B. Weddington7b21ac32008-08-09 05:35:13 +0000301 {"atmega169", AVR_ISA_AVR5, bfd_mach_avr5},
Eric B. Weddingtone760a812010-04-09 03:48:54 +0000302 {"atmega169a", AVR_ISA_AVR5, bfd_mach_avr5},
Eric B. Weddington7b21ac32008-08-09 05:35:13 +0000303 {"atmega169p", AVR_ISA_AVR5, bfd_mach_avr5},
Eric B. Weddingtone760a812010-04-09 03:48:54 +0000304 {"atmega169pa",AVR_ISA_AVR5, bfd_mach_avr5},
Eric B. Weddington7b21ac32008-08-09 05:35:13 +0000305 {"atmega32", AVR_ISA_AVR5, bfd_mach_avr5},
Denis Chertykov255d9ee2014-03-06 18:59:05 +0400306 {"atmega32a", AVR_ISA_AVR5, bfd_mach_avr5},
Eric B. Weddington7b21ac32008-08-09 05:35:13 +0000307 {"atmega323", AVR_ISA_AVR5, bfd_mach_avr5},
Eric B. Weddingtone760a812010-04-09 03:48:54 +0000308 {"atmega324a", AVR_ISA_AVR5, bfd_mach_avr5},
Eric B. Weddington7b21ac32008-08-09 05:35:13 +0000309 {"atmega324p", AVR_ISA_AVR5, bfd_mach_avr5},
Eric B. Weddingtone760a812010-04-09 03:48:54 +0000310 {"atmega324pa",AVR_ISA_AVR5, bfd_mach_avr5},
Eric B. Weddington7b21ac32008-08-09 05:35:13 +0000311 {"atmega325", AVR_ISA_AVR5, bfd_mach_avr5},
Eric B. Weddingtone760a812010-04-09 03:48:54 +0000312 {"atmega325a", AVR_ISA_AVR5, bfd_mach_avr5},
Eric B. Weddington7b21ac32008-08-09 05:35:13 +0000313 {"atmega325p", AVR_ISA_AVR5, bfd_mach_avr5},
Eric B. Weddingtonb8c610a2011-03-24 17:03:03 +0000314 {"atmega325pa",AVR_ISA_AVR5, bfd_mach_avr5},
Eric B. Weddington7b21ac32008-08-09 05:35:13 +0000315 {"atmega3250", AVR_ISA_AVR5, bfd_mach_avr5},
Eric B. Weddingtone760a812010-04-09 03:48:54 +0000316 {"atmega3250a",AVR_ISA_AVR5, bfd_mach_avr5},
Eric B. Weddington7b21ac32008-08-09 05:35:13 +0000317 {"atmega3250p",AVR_ISA_AVR5, bfd_mach_avr5},
Eric B. Weddingtonb8c610a2011-03-24 17:03:03 +0000318 {"atmega3250pa",AVR_ISA_AVR5, bfd_mach_avr5},
Eric B. Weddingtone760a812010-04-09 03:48:54 +0000319 {"atmega328", AVR_ISA_AVR5, bfd_mach_avr5},
Eric B. Weddington7b21ac32008-08-09 05:35:13 +0000320 {"atmega328p", AVR_ISA_AVR5, bfd_mach_avr5},
321 {"atmega329", AVR_ISA_AVR5, bfd_mach_avr5},
Eric B. Weddingtone760a812010-04-09 03:48:54 +0000322 {"atmega329a", AVR_ISA_AVR5, bfd_mach_avr5},
Eric B. Weddington7b21ac32008-08-09 05:35:13 +0000323 {"atmega329p", AVR_ISA_AVR5, bfd_mach_avr5},
Eric B. Weddingtone760a812010-04-09 03:48:54 +0000324 {"atmega329pa",AVR_ISA_AVR5, bfd_mach_avr5},
Eric B. Weddington7b21ac32008-08-09 05:35:13 +0000325 {"atmega3290", AVR_ISA_AVR5, bfd_mach_avr5},
Eric B. Weddingtone760a812010-04-09 03:48:54 +0000326 {"atmega3290a",AVR_ISA_AVR5, bfd_mach_avr5},
Eric B. Weddington7b21ac32008-08-09 05:35:13 +0000327 {"atmega3290p",AVR_ISA_AVR5, bfd_mach_avr5},
Eric B. Weddingtonb8c610a2011-03-24 17:03:03 +0000328 {"atmega3290pa",AVR_ISA_AVR5, bfd_mach_avr5},
Eric B. Weddington7b21ac32008-08-09 05:35:13 +0000329 {"atmega406", AVR_ISA_AVR5, bfd_mach_avr5},
Denis Chertykov255d9ee2014-03-06 18:59:05 +0400330 {"atmega64rfr2", AVR_ISA_AVR5, bfd_mach_avr5},
331 {"atmega644rfr2",AVR_ISA_AVR5, bfd_mach_avr5},
Eric B. Weddington7b21ac32008-08-09 05:35:13 +0000332 {"atmega64", AVR_ISA_AVR5, bfd_mach_avr5},
Denis Chertykov255d9ee2014-03-06 18:59:05 +0400333 {"atmega64a", AVR_ISA_AVR5, bfd_mach_avr5},
Eric B. Weddington7b21ac32008-08-09 05:35:13 +0000334 {"atmega640", AVR_ISA_AVR5, bfd_mach_avr5},
335 {"atmega644", AVR_ISA_AVR5, bfd_mach_avr5},
Eric B. Weddingtone760a812010-04-09 03:48:54 +0000336 {"atmega644a", AVR_ISA_AVR5, bfd_mach_avr5},
Eric B. Weddington7b21ac32008-08-09 05:35:13 +0000337 {"atmega644p", AVR_ISA_AVR5, bfd_mach_avr5},
Eric B. Weddington8453da22009-08-05 12:47:33 +0000338 {"atmega644pa",AVR_ISA_AVR5, bfd_mach_avr5},
Eric B. Weddington7b21ac32008-08-09 05:35:13 +0000339 {"atmega645", AVR_ISA_AVR5, bfd_mach_avr5},
Eric B. Weddingtone760a812010-04-09 03:48:54 +0000340 {"atmega645a", AVR_ISA_AVR5, bfd_mach_avr5},
341 {"atmega645p", AVR_ISA_AVR5, bfd_mach_avr5},
Eric B. Weddington7b21ac32008-08-09 05:35:13 +0000342 {"atmega649", AVR_ISA_AVR5, bfd_mach_avr5},
Eric B. Weddingtone760a812010-04-09 03:48:54 +0000343 {"atmega649a", AVR_ISA_AVR5, bfd_mach_avr5},
344 {"atmega649p", AVR_ISA_AVR5, bfd_mach_avr5},
Eric B. Weddington7b21ac32008-08-09 05:35:13 +0000345 {"atmega6450", AVR_ISA_AVR5, bfd_mach_avr5},
Eric B. Weddingtone760a812010-04-09 03:48:54 +0000346 {"atmega6450a",AVR_ISA_AVR5, bfd_mach_avr5},
347 {"atmega6450p",AVR_ISA_AVR5, bfd_mach_avr5},
Eric B. Weddington7b21ac32008-08-09 05:35:13 +0000348 {"atmega6490", AVR_ISA_AVR5, bfd_mach_avr5},
Eric B. Weddingtone760a812010-04-09 03:48:54 +0000349 {"atmega6490a",AVR_ISA_AVR5, bfd_mach_avr5},
350 {"atmega6490p",AVR_ISA_AVR5, bfd_mach_avr5},
Nick Clifton4d13caa2013-04-09 15:39:37 +0000351 {"atmega64rfr2",AVR_ISA_AVR5, bfd_mach_avr5},
352 {"atmega644rfr2",AVR_ISA_AVR5, bfd_mach_avr5},
Eric B. Weddington7b21ac32008-08-09 05:35:13 +0000353 {"atmega16hva",AVR_ISA_AVR5, bfd_mach_avr5},
Denis Chertykov255d9ee2014-03-06 18:59:05 +0400354 {"atmega16hva2",AVR_ISA_AVR5, bfd_mach_avr5},
Nick Clifton2b02f872008-12-23 09:51:38 +0000355 {"atmega16hvb",AVR_ISA_AVR5, bfd_mach_avr5},
Eric B. Weddingtonb8c610a2011-03-24 17:03:03 +0000356 {"atmega16hvbrevb",AVR_ISA_AVR5,bfd_mach_avr5},
Nick Clifton2b02f872008-12-23 09:51:38 +0000357 {"atmega32hvb",AVR_ISA_AVR5, bfd_mach_avr5},
Eric B. Weddingtonb8c610a2011-03-24 17:03:03 +0000358 {"atmega32hvbrevb",AVR_ISA_AVR5,bfd_mach_avr5},
Eric B. Weddingtone760a812010-04-09 03:48:54 +0000359 {"atmega64hve",AVR_ISA_AVR5, bfd_mach_avr5},
Eric B. Weddington7b21ac32008-08-09 05:35:13 +0000360 {"at90can32" , AVR_ISA_AVR5, bfd_mach_avr5},
361 {"at90can64" , AVR_ISA_AVR5, bfd_mach_avr5},
Eric B. Weddingtonb8c610a2011-03-24 17:03:03 +0000362 {"at90pwm161", AVR_ISA_AVR5, bfd_mach_avr5},
Eric B. Weddington7b21ac32008-08-09 05:35:13 +0000363 {"at90pwm216", AVR_ISA_AVR5, bfd_mach_avr5},
364 {"at90pwm316", AVR_ISA_AVR5, bfd_mach_avr5},
365 {"atmega32c1", AVR_ISA_AVR5, bfd_mach_avr5},
Nick Clifton2b02f872008-12-23 09:51:38 +0000366 {"atmega64c1", AVR_ISA_AVR5, bfd_mach_avr5},
367 {"atmega16m1", AVR_ISA_AVR5, bfd_mach_avr5},
Eric B. Weddington7b21ac32008-08-09 05:35:13 +0000368 {"atmega32m1", AVR_ISA_AVR5, bfd_mach_avr5},
Nick Clifton2b02f872008-12-23 09:51:38 +0000369 {"atmega64m1", AVR_ISA_AVR5, bfd_mach_avr5},
370 {"atmega16u4", AVR_ISA_AVR5, bfd_mach_avr5},
Eric B. Weddington7b21ac32008-08-09 05:35:13 +0000371 {"atmega32u4", AVR_ISA_AVR5, bfd_mach_avr5},
Nick Clifton2b02f872008-12-23 09:51:38 +0000372 {"atmega32u6", AVR_ISA_AVR5, bfd_mach_avr5},
Eric B. Weddington7b21ac32008-08-09 05:35:13 +0000373 {"at90usb646", AVR_ISA_AVR5, bfd_mach_avr5},
374 {"at90usb647", AVR_ISA_AVR5, bfd_mach_avr5},
Nick Clifton2b02f872008-12-23 09:51:38 +0000375 {"at90scr100", AVR_ISA_AVR5, bfd_mach_avr5},
Nick Clifton28c9d252006-05-24 07:36:12 +0000376 {"at94k", AVR_ISA_94K, bfd_mach_avr5},
Eric B. Weddingtone760a812010-04-09 03:48:54 +0000377 {"m3000", AVR_ISA_AVR5, bfd_mach_avr5},
Eric B. Weddington7b21ac32008-08-09 05:35:13 +0000378 {"atmega128", AVR_ISA_AVR51, bfd_mach_avr51},
Denis Chertykov255d9ee2014-03-06 18:59:05 +0400379 {"atmega128a", AVR_ISA_AVR51, bfd_mach_avr51},
Eric B. Weddington7b21ac32008-08-09 05:35:13 +0000380 {"atmega1280", AVR_ISA_AVR51, bfd_mach_avr51},
381 {"atmega1281", AVR_ISA_AVR51, bfd_mach_avr51},
Denis Chertykov255d9ee2014-03-06 18:59:05 +0400382 {"atmega1284", AVR_ISA_AVR51, bfd_mach_avr51},
Eric B. Weddington7b21ac32008-08-09 05:35:13 +0000383 {"atmega1284p",AVR_ISA_AVR51, bfd_mach_avr51},
Eric B. Weddington17f48802009-01-26 13:38:52 +0000384 {"atmega128rfa1",AVR_ISA_AVR51, bfd_mach_avr51},
Nick Clifton4d13caa2013-04-09 15:39:37 +0000385 {"atmega128rfr2",AVR_ISA_AVR51, bfd_mach_avr51},
386 {"atmega1284rfr2",AVR_ISA_AVR51, bfd_mach_avr51},
Eric B. Weddington7b21ac32008-08-09 05:35:13 +0000387 {"at90can128", AVR_ISA_AVR51, bfd_mach_avr51},
388 {"at90usb1286",AVR_ISA_AVR51, bfd_mach_avr51},
389 {"at90usb1287",AVR_ISA_AVR51, bfd_mach_avr51},
390 {"atmega2560", AVR_ISA_AVR6, bfd_mach_avr6},
391 {"atmega2561", AVR_ISA_AVR6, bfd_mach_avr6},
Nick Clifton4d13caa2013-04-09 15:39:37 +0000392 {"atmega256rfr2", AVR_ISA_AVR6, bfd_mach_avr6},
393 {"atmega2564rfr2", AVR_ISA_AVR6, bfd_mach_avr6},
Eric B. Weddington8cc66332011-03-22 18:10:48 +0000394 {"atxmega16a4", AVR_ISA_XMEGA, bfd_mach_avrxmega2},
Denis Chertykov255d9ee2014-03-06 18:59:05 +0400395 {"atxmega16a4u",AVR_ISA_XMEGAU, bfd_mach_avrxmega2},
396 {"atxmega16c4", AVR_ISA_XMEGAU, bfd_mach_avrxmega2},
Eric B. Weddington8cc66332011-03-22 18:10:48 +0000397 {"atxmega16d4", AVR_ISA_XMEGA, bfd_mach_avrxmega2},
398 {"atxmega32a4", AVR_ISA_XMEGA, bfd_mach_avrxmega2},
Denis Chertykov255d9ee2014-03-06 18:59:05 +0400399 {"atxmega32a4u",AVR_ISA_XMEGAU, bfd_mach_avrxmega2},
400 {"atxmega32c4", AVR_ISA_XMEGAU, bfd_mach_avrxmega2},
Eric B. Weddington8cc66332011-03-22 18:10:48 +0000401 {"atxmega32d4", AVR_ISA_XMEGA, bfd_mach_avrxmega2},
Denis Chertykov255d9ee2014-03-06 18:59:05 +0400402 {"atxmega32e5", AVR_ISA_XMEGA, bfd_mach_avrxmega2},
403 {"atxmega16e5", AVR_ISA_XMEGA, bfd_mach_avrxmega2},
404 {"atxmega8e5", AVR_ISA_XMEGA, bfd_mach_avrxmega2},
Eric B. Weddington6f8a4442011-03-23 15:02:06 +0000405 {"atxmega32x1", AVR_ISA_XMEGA, bfd_mach_avrxmega2},
Georg-Johann Layf27dadc2017-07-17 10:23:10 +0100406 {"attiny212", AVR_ISA_XMEGA, bfd_mach_avrxmega3},
407 {"attiny214", AVR_ISA_XMEGA, bfd_mach_avrxmega3},
408 {"attiny412", AVR_ISA_XMEGA, bfd_mach_avrxmega3},
409 {"attiny414", AVR_ISA_XMEGA, bfd_mach_avrxmega3},
eorg-Johann Layf4203b22017-05-19 15:06:33 +0100410 {"attiny416", AVR_ISA_XMEGA, bfd_mach_avrxmega3},
411 {"attiny417", AVR_ISA_XMEGA, bfd_mach_avrxmega3},
Georg-Johann Layf27dadc2017-07-17 10:23:10 +0100412 {"attiny814", AVR_ISA_XMEGA, bfd_mach_avrxmega3},
eorg-Johann Layf4203b22017-05-19 15:06:33 +0100413 {"attiny816", AVR_ISA_XMEGA, bfd_mach_avrxmega3},
414 {"attiny817", AVR_ISA_XMEGA, bfd_mach_avrxmega3},
Georg-Johann Layf27dadc2017-07-17 10:23:10 +0100415 {"attiny1614", AVR_ISA_XMEGA, bfd_mach_avrxmega3},
416 {"attiny1616", AVR_ISA_XMEGA, bfd_mach_avrxmega3},
417 {"attiny1617", AVR_ISA_XMEGA, bfd_mach_avrxmega3},
418 {"attiny3214", AVR_ISA_XMEGA, bfd_mach_avrxmega3},
419 {"attiny3216", AVR_ISA_XMEGA, bfd_mach_avrxmega3},
420 {"attiny3217", AVR_ISA_XMEGA, bfd_mach_avrxmega3},
Eric B. Weddington8cc66332011-03-22 18:10:48 +0000421 {"atxmega64a3", AVR_ISA_XMEGA, bfd_mach_avrxmega4},
Denis Chertykov255d9ee2014-03-06 18:59:05 +0400422 {"atxmega64a3u",AVR_ISA_XMEGAU, bfd_mach_avrxmega4},
423 {"atxmega64a4u",AVR_ISA_XMEGAU, bfd_mach_avrxmega4},
424 {"atxmega64b1", AVR_ISA_XMEGAU, bfd_mach_avrxmega4},
425 {"atxmega64b3", AVR_ISA_XMEGAU, bfd_mach_avrxmega4},
426 {"atxmega64c3", AVR_ISA_XMEGAU, bfd_mach_avrxmega4},
Eric B. Weddington8cc66332011-03-22 18:10:48 +0000427 {"atxmega64d3", AVR_ISA_XMEGA, bfd_mach_avrxmega4},
Denis Chertykov255d9ee2014-03-06 18:59:05 +0400428 {"atxmega64d4", AVR_ISA_XMEGA, bfd_mach_avrxmega4},
Eric B. Weddington8cc66332011-03-22 18:10:48 +0000429 {"atxmega64a1", AVR_ISA_XMEGA, bfd_mach_avrxmega5},
Denis Chertykov7bab7632013-06-01 07:14:44 +0000430 {"atxmega64a1u",AVR_ISA_XMEGAU, bfd_mach_avrxmega5},
Eric B. Weddington8cc66332011-03-22 18:10:48 +0000431 {"atxmega128a3", AVR_ISA_XMEGA, bfd_mach_avrxmega6},
Denis Chertykov255d9ee2014-03-06 18:59:05 +0400432 {"atxmega128a3u",AVR_ISA_XMEGAU,bfd_mach_avrxmega6},
Denis Chertykov7bab7632013-06-01 07:14:44 +0000433 {"atxmega128b1", AVR_ISA_XMEGAU, bfd_mach_avrxmega6},
Denis Chertykov255d9ee2014-03-06 18:59:05 +0400434 {"atxmega128b3", AVR_ISA_XMEGAU,bfd_mach_avrxmega6},
435 {"atxmega128c3", AVR_ISA_XMEGAU,bfd_mach_avrxmega6},
Eric B. Weddington8cc66332011-03-22 18:10:48 +0000436 {"atxmega128d3", AVR_ISA_XMEGA, bfd_mach_avrxmega6},
Denis Chertykov255d9ee2014-03-06 18:59:05 +0400437 {"atxmega128d4", AVR_ISA_XMEGA, bfd_mach_avrxmega6},
Eric B. Weddington8cc66332011-03-22 18:10:48 +0000438 {"atxmega192a3", AVR_ISA_XMEGA, bfd_mach_avrxmega6},
Denis Chertykov255d9ee2014-03-06 18:59:05 +0400439 {"atxmega192a3u",AVR_ISA_XMEGAU,bfd_mach_avrxmega6},
440 {"atxmega192c3", AVR_ISA_XMEGAU, bfd_mach_avrxmega6},
Eric B. Weddington8cc66332011-03-22 18:10:48 +0000441 {"atxmega192d3", AVR_ISA_XMEGA, bfd_mach_avrxmega6},
442 {"atxmega256a3", AVR_ISA_XMEGA, bfd_mach_avrxmega6},
Denis Chertykov255d9ee2014-03-06 18:59:05 +0400443 {"atxmega256a3u",AVR_ISA_XMEGAU,bfd_mach_avrxmega6},
Eric B. Weddington8cc66332011-03-22 18:10:48 +0000444 {"atxmega256a3b",AVR_ISA_XMEGA, bfd_mach_avrxmega6},
Denis Chertykov7bab7632013-06-01 07:14:44 +0000445 {"atxmega256a3bu",AVR_ISA_XMEGAU, bfd_mach_avrxmega6},
Denis Chertykov255d9ee2014-03-06 18:59:05 +0400446 {"atxmega256c3", AVR_ISA_XMEGAU,bfd_mach_avrxmega6},
Eric B. Weddington8cc66332011-03-22 18:10:48 +0000447 {"atxmega256d3", AVR_ISA_XMEGA, bfd_mach_avrxmega6},
Denis Chertykov255d9ee2014-03-06 18:59:05 +0400448 {"atxmega384c3", AVR_ISA_XMEGAU,bfd_mach_avrxmega6},
449 {"atxmega384d3", AVR_ISA_XMEGA, bfd_mach_avrxmega6},
Eric B. Weddington8cc66332011-03-22 18:10:48 +0000450 {"atxmega128a1", AVR_ISA_XMEGA, bfd_mach_avrxmega7},
Denis Chertykov7bab7632013-06-01 07:14:44 +0000451 {"atxmega128a1u", AVR_ISA_XMEGAU, bfd_mach_avrxmega7},
Denis Chertykov255d9ee2014-03-06 18:59:05 +0400452 {"atxmega128a4u", AVR_ISA_XMEGAU, bfd_mach_avrxmega7},
Barney Stratfordf36e8882014-07-01 10:20:17 +0100453 {"attiny4", AVR_ISA_AVRTINY, bfd_mach_avrtiny},
454 {"attiny5", AVR_ISA_AVRTINY, bfd_mach_avrtiny},
455 {"attiny9", AVR_ISA_AVRTINY, bfd_mach_avrtiny},
456 {"attiny10", AVR_ISA_AVRTINY, bfd_mach_avrtiny},
457 {"attiny20", AVR_ISA_AVRTINY, bfd_mach_avrtiny},
458 {"attiny40", AVR_ISA_AVRTINY, bfd_mach_avrtiny},
Alan Modraadde6302000-03-27 08:39:14 +0000459 {NULL, 0, 0}
460};
461
Denis Chertykovaf910972014-03-29 09:53:16 +0400462
Alan Modraadde6302000-03-27 08:39:14 +0000463/* Current MCU type. */
Eric B. Weddington7b21ac32008-08-09 05:35:13 +0000464static struct mcu_type_s default_mcu = {"avr2", AVR_ISA_AVR2, bfd_mach_avr2};
Denis Chertykovaf910972014-03-29 09:53:16 +0400465static struct mcu_type_s specified_mcu;
Nick Cliftondc191a82005-10-12 10:56:46 +0000466static struct mcu_type_s * avr_mcu = & default_mcu;
Alan Modraadde6302000-03-27 08:39:14 +0000467
Nick Clifton00d28652000-07-03 22:25:33 +0000468/* AVR target-specific switches. */
469struct avr_opt_s
470{
Nick Cliftondc191a82005-10-12 10:56:46 +0000471 int all_opcodes; /* -mall-opcodes: accept all known AVR opcodes. */
472 int no_skip_bug; /* -mno-skip-bug: no warnings for skipping 2-word insns. */
473 int no_wrap; /* -mno-wrap: reject rjmp/rcall with 8K wrap-around. */
Andrew Burgessedc9e9a2014-10-27 10:51:17 +0000474 int no_link_relax; /* -mno-link-relax / -mlink-relax: generate (or not)
475 relocations for linker relaxation. */
Georg-Johann Lay32f76c62017-06-30 16:37:39 +0100476 int have_gccisr; /* Whether "__gcc_isr" is a known (pseudo) insn. */
Nick Clifton00d28652000-07-03 22:25:33 +0000477};
478
Georg-Johann Lay32f76c62017-06-30 16:37:39 +0100479static struct avr_opt_s avr_opt = { 0, 0, 0, 0, 0 };
Nick Clifton00d28652000-07-03 22:25:33 +0000480
Alan Modraadde6302000-03-27 08:39:14 +0000481const char EXP_CHARS[] = "eE";
482const char FLT_CHARS[] = "dD";
Nick Cliftondc191a82005-10-12 10:56:46 +0000483
484static void avr_set_arch (int);
Alan Modraadde6302000-03-27 08:39:14 +0000485
486/* The target specific pseudo-ops which we support. */
487const pseudo_typeS md_pseudo_table[] =
488{
489 {"arch", avr_set_arch, 0},
490 { NULL, NULL, 0}
491};
492
493#define LDI_IMMEDIATE(x) (((x) & 0xf) | (((x) << 4) & 0xf00))
Alan Modraadde6302000-03-27 08:39:14 +0000494
Nick Cliftondc191a82005-10-12 10:56:46 +0000495#define EXP_MOD_NAME(i) exp_mod[i].name
496#define EXP_MOD_RELOC(i) exp_mod[i].reloc
497#define EXP_MOD_NEG_RELOC(i) exp_mod[i].neg_reloc
498#define HAVE_PM_P(i) exp_mod[i].have_pm
Alan Modraadde6302000-03-27 08:39:14 +0000499
500struct exp_mod_s
501{
Trevor Saunderse0471c12016-02-25 16:55:21 +0000502 const char * name;
Nick Cliftondc191a82005-10-12 10:56:46 +0000503 bfd_reloc_code_real_type reloc;
504 bfd_reloc_code_real_type neg_reloc;
505 int have_pm;
Alan Modraadde6302000-03-27 08:39:14 +0000506};
507
Nick Cliftonc6a7ab12000-07-28 00:42:18 +0000508static struct exp_mod_s exp_mod[] =
509{
Alan Modraadde6302000-03-27 08:39:14 +0000510 {"hh8", BFD_RELOC_AVR_HH8_LDI, BFD_RELOC_AVR_HH8_LDI_NEG, 1},
511 {"pm_hh8", BFD_RELOC_AVR_HH8_LDI_PM, BFD_RELOC_AVR_HH8_LDI_PM_NEG, 0},
512 {"hi8", BFD_RELOC_AVR_HI8_LDI, BFD_RELOC_AVR_HI8_LDI_NEG, 1},
513 {"pm_hi8", BFD_RELOC_AVR_HI8_LDI_PM, BFD_RELOC_AVR_HI8_LDI_PM_NEG, 0},
514 {"lo8", BFD_RELOC_AVR_LO8_LDI, BFD_RELOC_AVR_LO8_LDI_NEG, 1},
515 {"pm_lo8", BFD_RELOC_AVR_LO8_LDI_PM, BFD_RELOC_AVR_LO8_LDI_PM_NEG, 0},
Nick Cliftondf406462006-03-03 15:25:31 +0000516 {"hlo8", BFD_RELOC_AVR_HH8_LDI, BFD_RELOC_AVR_HH8_LDI_NEG, 0},
Nick Cliftone4efb662012-06-11 14:26:41 +0000517 {"hhi8", BFD_RELOC_AVR_MS8_LDI, BFD_RELOC_AVR_MS8_LDI_NEG, 0},
Alan Modraadde6302000-03-27 08:39:14 +0000518};
519
Ambrogino Modigliani2b0f3762016-11-25 21:01:41 +0100520/* A union used to store indices into the exp_mod[] array
Nick Clifton8ad7c532006-01-11 17:39:50 +0000521 in a hash table which expects void * data types. */
522typedef union
523{
524 void * ptr;
525 int index;
526} mod_index;
527
Alan Modraadde6302000-03-27 08:39:14 +0000528/* Opcode hash table. */
Martin Liska629310a2020-08-18 10:57:21 +0200529static htab_t avr_hash;
Alan Modraadde6302000-03-27 08:39:14 +0000530
531/* Reloc modifiers hash control (hh8,hi8,lo8,pm_xx). */
Martin Liska629310a2020-08-18 10:57:21 +0200532static htab_t avr_mod_hash;
Alan Modraadde6302000-03-27 08:39:14 +0000533
Georg-Johann Lay32f76c62017-06-30 16:37:39 +0100534/* Whether some opcode does not change SREG. */
Martin Liska629310a2020-08-18 10:57:21 +0200535static htab_t avr_no_sreg_hash;
Georg-Johann Lay32f76c62017-06-30 16:37:39 +0100536
537static const char* const avr_no_sreg[] =
538 {
539 /* Arithmetic */
540 "ldi", "swap", "mov", "movw",
541 /* Special instructions. I-Flag will be restored by RETI, and we don't
542 consider I-Flag as being clobbered when changed. */
543 "sei", "cli", "reti", "brie", "brid",
544 "nop", "wdr", "sleep",
545 /* Load / Store */
546 "ld", "ldd", "lds", "pop", "in", "lpm", "elpm",
547 "st", "std", "sts", "push", "out",
548 /* Jumps and Calls. Calls might call code that changes SREG.
549 GCC has to filter out ABI calls. The non-ABI transparent calls
550 must use [R]CALL and are filtered out now by not mentioning them. */
551 "rjmp", "jmp", "ijmp", "ret",
552 /* Skipping. Branches need SREG to be set, hence we regard them
553 as if they changed SREG and don't list them here. */
554 "sbrc", "sbrs", "sbic", "sbis", "cpse",
555 /* I/O Manipulation */
556 "sbi", "cbi",
557 /* Read-Modify-Write */
558 "lac", "las", "lat", "xch"
559 };
560
Nick Clifton00d28652000-07-03 22:25:33 +0000561#define OPTION_MMCU 'm'
Nick Cliftondc191a82005-10-12 10:56:46 +0000562enum options
563{
564 OPTION_ALL_OPCODES = OPTION_MD_BASE + 1,
565 OPTION_NO_SKIP_BUG,
Denis Chertykovaf910972014-03-29 09:53:16 +0400566 OPTION_NO_WRAP,
Denis Chertykove4ef1b62014-04-10 19:50:33 +0400567 OPTION_ISA_RMW,
Andrew Burgessedc9e9a2014-10-27 10:51:17 +0000568 OPTION_LINK_RELAX,
Georg-Johann Lay32f76c62017-06-30 16:37:39 +0100569 OPTION_NO_LINK_RELAX,
Matt Jacobsond86d1fc2021-08-11 10:03:19 +0100570 OPTION_HAVE_GCCISR,
571 OPTION_NO_DOLLAR_LINE_SEPARATOR,
Nick Cliftondc191a82005-10-12 10:56:46 +0000572};
Alan Modraadde6302000-03-27 08:39:14 +0000573
Nick Cliftonc6a7ab12000-07-28 00:42:18 +0000574struct option md_longopts[] =
575{
Nick Clifton00d28652000-07-03 22:25:33 +0000576 { "mmcu", required_argument, NULL, OPTION_MMCU },
577 { "mall-opcodes", no_argument, NULL, OPTION_ALL_OPCODES },
578 { "mno-skip-bug", no_argument, NULL, OPTION_NO_SKIP_BUG },
579 { "mno-wrap", no_argument, NULL, OPTION_NO_WRAP },
Denis Chertykovaf910972014-03-29 09:53:16 +0400580 { "mrmw", no_argument, NULL, OPTION_ISA_RMW },
Denis Chertykove4ef1b62014-04-10 19:50:33 +0400581 { "mlink-relax", no_argument, NULL, OPTION_LINK_RELAX },
Andrew Burgessedc9e9a2014-10-27 10:51:17 +0000582 { "mno-link-relax", no_argument, NULL, OPTION_NO_LINK_RELAX },
Georg-Johann Lay32f76c62017-06-30 16:37:39 +0100583 { "mgcc-isr", no_argument, NULL, OPTION_HAVE_GCCISR },
Matt Jacobsond86d1fc2021-08-11 10:03:19 +0100584 { "mno-dollar-line-separator", no_argument, NULL, OPTION_NO_DOLLAR_LINE_SEPARATOR },
Nick Clifton00d28652000-07-03 22:25:33 +0000585 { NULL, no_argument, NULL, 0 }
Alan Modraadde6302000-03-27 08:39:14 +0000586};
Alan Modraadde6302000-03-27 08:39:14 +0000587
Nick Cliftonc6a7ab12000-07-28 00:42:18 +0000588size_t md_longopts_size = sizeof (md_longopts);
Nick Clifton00d28652000-07-03 22:25:33 +0000589
590/* Display nicely formatted list of known MCU names. */
Nick Cliftonc6a7ab12000-07-28 00:42:18 +0000591
Nick Clifton00d28652000-07-03 22:25:33 +0000592static void
Nick Cliftondc191a82005-10-12 10:56:46 +0000593show_mcu_list (FILE *stream)
Nick Clifton00d28652000-07-03 22:25:33 +0000594{
595 int i, x;
596
597 fprintf (stream, _("Known MCU names:"));
598 x = 1000;
Kazu Hirata1dab94d2000-09-15 01:06:52 +0000599
Nick Clifton00d28652000-07-03 22:25:33 +0000600 for (i = 0; mcu_types[i].name; i++)
601 {
602 int len = strlen (mcu_types[i].name);
Kazu Hirata1dab94d2000-09-15 01:06:52 +0000603
Nick Clifton00d28652000-07-03 22:25:33 +0000604 x += len + 1;
Kazu Hirata1dab94d2000-09-15 01:06:52 +0000605
Nick Clifton00d28652000-07-03 22:25:33 +0000606 if (x < 75)
Nick Cliftonc6a7ab12000-07-28 00:42:18 +0000607 fprintf (stream, " %s", mcu_types[i].name);
Nick Clifton00d28652000-07-03 22:25:33 +0000608 else
609 {
610 fprintf (stream, "\n %s", mcu_types[i].name);
611 x = len + 2;
612 }
613 }
Kazu Hirata1dab94d2000-09-15 01:06:52 +0000614
Nick Cliftonc6a7ab12000-07-28 00:42:18 +0000615 fprintf (stream, "\n");
Nick Clifton00d28652000-07-03 22:25:33 +0000616}
617
Alan Modraadde6302000-03-27 08:39:14 +0000618static inline char *
Nick Cliftondc191a82005-10-12 10:56:46 +0000619skip_space (char *s)
Alan Modraadde6302000-03-27 08:39:14 +0000620{
621 while (*s == ' ' || *s == '\t')
622 ++s;
623 return s;
624}
625
626/* Extract one word from FROM and copy it to TO. */
Nick Cliftonc6a7ab12000-07-28 00:42:18 +0000627
Alan Modraadde6302000-03-27 08:39:14 +0000628static char *
629extract_word (char *from, char *to, int limit)
630{
Alan Modraadde6302000-03-27 08:39:14 +0000631 char *op_end;
632 int size = 0;
633
634 /* Drop leading whitespace. */
635 from = skip_space (from);
636 *to = 0;
Nick Cliftonc6a7ab12000-07-28 00:42:18 +0000637
Alan Modraadde6302000-03-27 08:39:14 +0000638 /* Find the op code end. */
Alan Modra87975d22010-06-28 14:06:57 +0000639 for (op_end = from; *op_end != 0 && is_part_of_name (*op_end);)
Alan Modraadde6302000-03-27 08:39:14 +0000640 {
641 to[size++] = *op_end++;
642 if (size + 1 >= limit)
643 break;
644 }
Kazu Hirata1dab94d2000-09-15 01:06:52 +0000645
Alan Modraadde6302000-03-27 08:39:14 +0000646 to[size] = 0;
647 return op_end;
648}
649
650int
Nick Cliftondc191a82005-10-12 10:56:46 +0000651md_estimate_size_before_relax (fragS *fragp ATTRIBUTE_UNUSED,
652 asection *seg ATTRIBUTE_UNUSED)
Alan Modraadde6302000-03-27 08:39:14 +0000653{
654 abort ();
655 return 0;
656}
657
658void
Nick Cliftondc191a82005-10-12 10:56:46 +0000659md_show_usage (FILE *stream)
Alan Modraadde6302000-03-27 08:39:14 +0000660{
Nick Clifton00d28652000-07-03 22:25:33 +0000661 fprintf (stream,
Eric B. Weddington4fb8d1c2011-03-21 20:25:56 +0000662 _("AVR Assembler options:\n"
Alan Modraadde6302000-03-27 08:39:14 +0000663 " -mmcu=[avr-name] select microcontroller variant\n"
664 " [avr-name] can be:\n"
Eric B. Weddington7b21ac32008-08-09 05:35:13 +0000665 " avr1 - classic AVR core without data RAM\n"
666 " avr2 - classic AVR core with up to 8K program memory\n"
667 " avr25 - classic AVR core with up to 8K program memory\n"
668 " plus the MOVW instruction\n"
669 " avr3 - classic AVR core with up to 64K program memory\n"
670 " avr31 - classic AVR core with up to 128K program memory\n"
671 " avr35 - classic AVR core with up to 64K program memory\n"
672 " plus the MOVW instruction\n"
673 " avr4 - enhanced AVR core with up to 8K program memory\n"
674 " avr5 - enhanced AVR core with up to 64K program memory\n"
675 " avr51 - enhanced AVR core with up to 128K program memory\n"
676 " avr6 - enhanced AVR core with up to 256K program memory\n"
Nick Clifton8c997c22013-07-18 11:52:47 +0000677 " avrxmega2 - XMEGA, > 8K, < 64K FLASH, < 64K RAM\n"
Georg-Johann Layf27dadc2017-07-17 10:23:10 +0100678 " avrxmega3 - XMEGA, RAM + FLASH < 64K, Flash visible in RAM\n"
Eric B. Weddington8cc66332011-03-22 18:10:48 +0000679 " avrxmega4 - XMEGA, > 64K, <= 128K FLASH, <= 64K RAM\n"
680 " avrxmega5 - XMEGA, > 64K, <= 128K FLASH, > 64K RAM\n"
681 " avrxmega6 - XMEGA, > 128K, <= 256K FLASH, <= 64K RAM\n"
682 " avrxmega7 - XMEGA, > 128K, <= 256K FLASH, > 64K RAM\n"
Barney Stratfordf36e8882014-07-01 10:20:17 +0100683 " avrtiny - AVR Tiny core with 16 gp registers\n"));
Nick Clifton00d28652000-07-03 22:25:33 +0000684 fprintf (stream,
685 _(" -mall-opcodes accept all AVR opcodes, even if not supported by MCU\n"
686 " -mno-skip-bug disable warnings for skipping two-word instructions\n"
687 " (default for avr4, avr5)\n"
688 " -mno-wrap reject rjmp/rcall instructions with 8K wrap-around\n"
Denis Chertykovaf910972014-03-29 09:53:16 +0400689 " (default for avr3, avr5)\n"
690 " -mrmw accept Read-Modify-Write instructions\n"
Andrew Burgessedc9e9a2014-10-27 10:51:17 +0000691 " -mlink-relax generate relocations for linker relaxation (default)\n"
692 " -mno-link-relax don't generate relocations for linker relaxation.\n"
Georg-Johann Lay32f76c62017-06-30 16:37:39 +0100693 " -mgcc-isr accept the __gcc_isr pseudo-instruction.\n"
Matt Jacobsond86d1fc2021-08-11 10:03:19 +0100694 " -mno-dollar-line-separator\n"
695 " do not treat the $ character as a line separator.\n"
Andrew Burgessedc9e9a2014-10-27 10:51:17 +0000696 ));
Nick Clifton00d28652000-07-03 22:25:33 +0000697 show_mcu_list (stream);
Alan Modraadde6302000-03-27 08:39:14 +0000698}
699
700static void
Nick Cliftondc191a82005-10-12 10:56:46 +0000701avr_set_arch (int dummy ATTRIBUTE_UNUSED)
Alan Modraadde6302000-03-27 08:39:14 +0000702{
Nick Cliftondc191a82005-10-12 10:56:46 +0000703 char str[20];
Kazu Hirata1dab94d2000-09-15 01:06:52 +0000704
Alan Modraadde6302000-03-27 08:39:14 +0000705 input_line_pointer = extract_word (input_line_pointer, str, 20);
Nick Clifton00d28652000-07-03 22:25:33 +0000706 md_parse_option (OPTION_MMCU, str);
Alan Modraadde6302000-03-27 08:39:14 +0000707 bfd_set_arch_mach (stdoutput, TARGET_ARCH, avr_mcu->mach);
708}
709
710int
Trevor Saunders17b9d672016-02-27 09:35:32 -0500711md_parse_option (int c, const char *arg)
Alan Modraadde6302000-03-27 08:39:14 +0000712{
Nick Clifton00d28652000-07-03 22:25:33 +0000713 switch (c)
Alan Modraadde6302000-03-27 08:39:14 +0000714 {
Nick Clifton00d28652000-07-03 22:25:33 +0000715 case OPTION_MMCU:
716 {
717 int i;
Nick Clifton65aa24b2000-06-27 01:45:30 +0000718
Nick Clifton00d28652000-07-03 22:25:33 +0000719 for (i = 0; mcu_types[i].name; ++i)
Trevor Saundersf73e41e2016-04-02 07:57:10 -0400720 if (strcasecmp (mcu_types[i].name, arg) == 0)
Nick Clifton00d28652000-07-03 22:25:33 +0000721 break;
Nick Clifton65aa24b2000-06-27 01:45:30 +0000722
Nick Clifton00d28652000-07-03 22:25:33 +0000723 if (!mcu_types[i].name)
724 {
725 show_mcu_list (stderr);
726 as_fatal (_("unknown MCU: %s\n"), arg);
727 }
728
729 /* It is OK to redefine mcu type within the same avr[1-5] bfd machine
730 type - this for allows passing -mmcu=... via gcc ASM_SPEC as well
731 as .arch ... in the asm output at the same time. */
Nick Clifton00d28652000-07-03 22:25:33 +0000732 if (avr_mcu == &default_mcu || avr_mcu->mach == mcu_types[i].mach)
Nick Cliftone1fa0162016-03-21 16:31:46 +0000733 {
734 specified_mcu.name = mcu_types[i].name;
735 specified_mcu.isa |= mcu_types[i].isa;
736 specified_mcu.mach = mcu_types[i].mach;
737 avr_mcu = &specified_mcu;
738 }
Nick Clifton00d28652000-07-03 22:25:33 +0000739 else
740 as_fatal (_("redefinition of mcu type `%s' to `%s'"),
741 avr_mcu->name, mcu_types[i].name);
742 return 1;
743 }
744 case OPTION_ALL_OPCODES:
745 avr_opt.all_opcodes = 1;
746 return 1;
747 case OPTION_NO_SKIP_BUG:
748 avr_opt.no_skip_bug = 1;
749 return 1;
750 case OPTION_NO_WRAP:
751 avr_opt.no_wrap = 1;
Alan Modraadde6302000-03-27 08:39:14 +0000752 return 1;
Denis Chertykovaf910972014-03-29 09:53:16 +0400753 case OPTION_ISA_RMW:
754 specified_mcu.isa |= AVR_ISA_RMW;
755 return 1;
Denis Chertykove4ef1b62014-04-10 19:50:33 +0400756 case OPTION_LINK_RELAX:
Andrew Burgessedc9e9a2014-10-27 10:51:17 +0000757 avr_opt.no_link_relax = 0;
758 return 1;
759 case OPTION_NO_LINK_RELAX:
760 avr_opt.no_link_relax = 1;
Denis Chertykove4ef1b62014-04-10 19:50:33 +0400761 return 1;
Georg-Johann Lay32f76c62017-06-30 16:37:39 +0100762 case OPTION_HAVE_GCCISR:
763 avr_opt.have_gccisr = 1;
764 return 1;
Matt Jacobsond86d1fc2021-08-11 10:03:19 +0100765 case OPTION_NO_DOLLAR_LINE_SEPARATOR:
766 avr_line_separator_chars = avr_line_separator_chars_no_dollar;
767 lex_type['$'] = LEX_NAME | LEX_BEGIN_NAME;
768 return 1;
Alan Modraadde6302000-03-27 08:39:14 +0000769 }
Kazu Hirata1dab94d2000-09-15 01:06:52 +0000770
Alan Modraadde6302000-03-27 08:39:14 +0000771 return 0;
772}
773
Georg-Johann Lay32f76c62017-06-30 16:37:39 +0100774
775/* Implement `md_undefined_symbol' */
776/* If we are in `__gcc_isr' chunk, pop up `__gcc_isr.n_pushed.<NUM>'
777 instead of `__gcc_isr.n_pushed'. This will be resolved by the Done
778 chunk in `avr_patch_gccisr_frag' to the number of PUSHes produced by
779 the Prologue chunk. */
780
Alan Modraadde6302000-03-27 08:39:14 +0000781symbolS *
Georg-Johann Lay32f76c62017-06-30 16:37:39 +0100782avr_undefined_symbol (char *name)
Alan Modraadde6302000-03-27 08:39:14 +0000783{
Georg-Johann Lay32f76c62017-06-30 16:37:39 +0100784 if (ISR_CHUNK_Done != avr_isr.prev_chunk
785 && 0 == strcmp (name, "__gcc_isr.n_pushed"))
786 {
787 if (!avr_isr.sym_n_pushed)
788 {
789 static unsigned suffix;
790 char xname[30];
791 sprintf (xname, "%s.%03u", name, (++suffix) % 1000);
792 avr_isr.sym_n_pushed = symbol_new (xname, undefined_section,
Alan Modrae01e1ce2020-08-21 09:17:53 +0930793 &zero_address_frag, (valueT) 0);
Georg-Johann Lay32f76c62017-06-30 16:37:39 +0100794 }
795 return avr_isr.sym_n_pushed;
796 }
797
Nick Cliftondc191a82005-10-12 10:56:46 +0000798 return NULL;
Alan Modraadde6302000-03-27 08:39:14 +0000799}
800
Alan Modra6d4af3c2016-04-01 22:37:50 +1030801const char *
Nick Cliftondc191a82005-10-12 10:56:46 +0000802md_atof (int type, char *litP, int *sizeP)
Alan Modraadde6302000-03-27 08:39:14 +0000803{
Alan Modra5b7c81b2021-03-31 10:42:05 +1030804 return ieee_md_atof (type, litP, sizeP, false);
Alan Modraadde6302000-03-27 08:39:14 +0000805}
806
807void
Nick Cliftondc191a82005-10-12 10:56:46 +0000808md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
809 asection *sec ATTRIBUTE_UNUSED,
810 fragS *fragP ATTRIBUTE_UNUSED)
Alan Modraadde6302000-03-27 08:39:14 +0000811{
812 abort ();
813}
814
Alan Modraadde6302000-03-27 08:39:14 +0000815void
Nick Cliftondc191a82005-10-12 10:56:46 +0000816md_begin (void)
Alan Modraadde6302000-03-27 08:39:14 +0000817{
Denis Chertykovdf136242000-05-01 11:14:05 +0000818 unsigned int i;
Alan Modraadde6302000-03-27 08:39:14 +0000819 struct avr_opcodes_s *opcode;
Nick Cliftondc191a82005-10-12 10:56:46 +0000820
Martin Liska629310a2020-08-18 10:57:21 +0200821 avr_hash = str_htab_create ();
Alan Modraadde6302000-03-27 08:39:14 +0000822
823 /* Insert unique names into hash table. This hash table then provides a
824 quick index to the first opcode with a particular name in the opcode
825 table. */
Alan Modraadde6302000-03-27 08:39:14 +0000826 for (opcode = avr_opcodes; opcode->name; opcode++)
Alan Modrafe0e9212020-08-22 17:59:57 +0930827 str_hash_insert (avr_hash, opcode->name, opcode, 0);
Alan Modraadde6302000-03-27 08:39:14 +0000828
Martin Liska629310a2020-08-18 10:57:21 +0200829 avr_mod_hash = str_htab_create ();
Alan Modraadde6302000-03-27 08:39:14 +0000830
Nick Cliftondc191a82005-10-12 10:56:46 +0000831 for (i = 0; i < ARRAY_SIZE (exp_mod); ++i)
Nick Clifton8ad7c532006-01-11 17:39:50 +0000832 {
833 mod_index m;
834
835 m.index = i + 10;
Alan Modrafe0e9212020-08-22 17:59:57 +0930836 str_hash_insert (avr_mod_hash, EXP_MOD_NAME (i), m.ptr, 0);
Nick Clifton8ad7c532006-01-11 17:39:50 +0000837 }
Nick Cliftonc6a7ab12000-07-28 00:42:18 +0000838
Martin Liska629310a2020-08-18 10:57:21 +0200839 avr_no_sreg_hash = str_htab_create ();
Georg-Johann Lay32f76c62017-06-30 16:37:39 +0100840
841 for (i = 0; i < ARRAY_SIZE (avr_no_sreg); ++i)
842 {
Martin Liska629310a2020-08-18 10:57:21 +0200843 gas_assert (str_hash_find (avr_hash, avr_no_sreg[i]));
Alan Modrafe0e9212020-08-22 17:59:57 +0930844 str_hash_insert (avr_no_sreg_hash, avr_no_sreg[i],
845 (void *) 4 /* dummy */, 0);
Georg-Johann Lay32f76c62017-06-30 16:37:39 +0100846 }
847
Alan Modrafe0e9212020-08-22 17:59:57 +0930848 avr_gccisr_opcode = (struct avr_opcodes_s*) str_hash_find (avr_hash,
849 "__gcc_isr");
Georg-Johann Lay32f76c62017-06-30 16:37:39 +0100850 gas_assert (avr_gccisr_opcode);
851
Alan Modraadde6302000-03-27 08:39:14 +0000852 bfd_set_arch_mach (stdoutput, TARGET_ARCH, avr_mcu->mach);
Andrew Burgessedc9e9a2014-10-27 10:51:17 +0000853 linkrelax = !avr_opt.no_link_relax;
Alan Modraadde6302000-03-27 08:39:14 +0000854}
855
Denis Chertykovdf136242000-05-01 11:14:05 +0000856/* Resolve STR as a constant expression and return the result.
Nick Cliftonc6a7ab12000-07-28 00:42:18 +0000857 If result greater than MAX then error. */
Denis Chertykovdf136242000-05-01 11:14:05 +0000858
859static unsigned int
Nick Cliftondc191a82005-10-12 10:56:46 +0000860avr_get_constant (char *str, int max)
Denis Chertykovdf136242000-05-01 11:14:05 +0000861{
862 expressionS ex;
Nick Cliftondc191a82005-10-12 10:56:46 +0000863
Denis Chertykovdf136242000-05-01 11:14:05 +0000864 str = skip_space (str);
865 input_line_pointer = str;
Nick Cliftondc191a82005-10-12 10:56:46 +0000866 expression (& ex);
Denis Chertykovdf136242000-05-01 11:14:05 +0000867
868 if (ex.X_op != O_constant)
869 as_bad (_("constant value required"));
870
871 if (ex.X_add_number > max || ex.X_add_number < 0)
Nick Clifton73f4d862007-10-03 14:35:06 +0000872 as_bad (_("number must be positive and less than %d"), max + 1);
Kazu Hirata1dab94d2000-09-15 01:06:52 +0000873
Denis Chertykovdf136242000-05-01 11:14:05 +0000874 return ex.X_add_number;
875}
876
Nick Cliftondc191a82005-10-12 10:56:46 +0000877/* Parse for ldd/std offset. */
Nick Clifton750bce02004-12-22 14:25:42 +0000878
879static void
880avr_offset_expression (expressionS *exp)
881{
882 char *str = input_line_pointer;
883 char *tmp;
884 char op[8];
885
886 tmp = str;
887 str = extract_word (str, op, sizeof (op));
888
889 input_line_pointer = tmp;
890 expression (exp);
891
892 /* Warn about expressions that fail to use lo8 (). */
893 if (exp->X_op == O_constant)
894 {
895 int x = exp->X_add_number;
Nick Clifton28c9d252006-05-24 07:36:12 +0000896
Nick Clifton750bce02004-12-22 14:25:42 +0000897 if (x < -255 || x > 255)
898 as_warn (_("constant out of 8-bit range: %d"), x);
899 }
900}
901
Nick Cliftondc191a82005-10-12 10:56:46 +0000902/* Parse ordinary expression. */
903
904static char *
905parse_exp (char *s, expressionS *op)
906{
907 input_line_pointer = s;
908 expression (op);
909 if (op->X_op == O_absent)
910 as_bad (_("missing operand"));
911 return input_line_pointer;
912}
913
914/* Parse special expressions (needed for LDI command):
915 xx8 (address)
916 xx8 (-address)
917 pm_xx8 (address)
918 pm_xx8 (-address)
919 where xx is: hh, hi, lo. */
920
921static bfd_reloc_code_real_type
922avr_ldi_expression (expressionS *exp)
923{
924 char *str = input_line_pointer;
925 char *tmp;
926 char op[8];
927 int mod;
Nick Clifton28c9d252006-05-24 07:36:12 +0000928 int linker_stubs_should_be_generated = 0;
929
Nick Cliftondc191a82005-10-12 10:56:46 +0000930 tmp = str;
931
932 str = extract_word (str, op, sizeof (op));
933
934 if (op[0])
935 {
Nick Clifton8ad7c532006-01-11 17:39:50 +0000936 mod_index m;
Nick Clifton28c9d252006-05-24 07:36:12 +0000937
Martin Liska629310a2020-08-18 10:57:21 +0200938 m.ptr = str_hash_find (avr_mod_hash, op);
Nick Clifton8ad7c532006-01-11 17:39:50 +0000939 mod = m.index;
Nick Cliftondc191a82005-10-12 10:56:46 +0000940
941 if (mod)
942 {
943 int closes = 0;
944
945 mod -= 10;
946 str = skip_space (str);
947
948 if (*str == '(')
949 {
Nick Clifton28c9d252006-05-24 07:36:12 +0000950 bfd_reloc_code_real_type reloc_to_return;
Nick Cliftondc191a82005-10-12 10:56:46 +0000951 int neg_p = 0;
952
953 ++str;
954
Martin Liskad34049e2021-03-22 13:33:04 +0100955 if (startswith (str, "pm(")
956 || startswith (str, "gs(")
957 || startswith (str, "-(gs(")
958 || startswith (str, "-(pm("))
Nick Cliftondc191a82005-10-12 10:56:46 +0000959 {
960 if (HAVE_PM_P (mod))
961 {
962 ++mod;
963 ++closes;
964 }
965 else
966 as_bad (_("illegal expression"));
967
Nick Clifton28c9d252006-05-24 07:36:12 +0000968 if (str[0] == 'g' || str[2] == 'g')
969 linker_stubs_should_be_generated = 1;
970
Nick Cliftondc191a82005-10-12 10:56:46 +0000971 if (*str == '-')
972 {
973 neg_p = 1;
974 ++closes;
975 str += 5;
976 }
977 else
978 str += 3;
979 }
980
981 if (*str == '-' && *(str + 1) == '(')
982 {
983 neg_p ^= 1;
984 ++closes;
985 str += 2;
986 }
987
988 input_line_pointer = str;
989 expression (exp);
990
991 do
992 {
993 if (*input_line_pointer != ')')
994 {
995 as_bad (_("`)' required"));
996 break;
997 }
998 input_line_pointer++;
999 }
1000 while (closes--);
1001
Nick Clifton28c9d252006-05-24 07:36:12 +00001002 reloc_to_return =
1003 neg_p ? EXP_MOD_NEG_RELOC (mod) : EXP_MOD_RELOC (mod);
1004 if (linker_stubs_should_be_generated)
1005 {
1006 switch (reloc_to_return)
1007 {
1008 case BFD_RELOC_AVR_LO8_LDI_PM:
1009 reloc_to_return = BFD_RELOC_AVR_LO8_LDI_GS;
1010 break;
1011 case BFD_RELOC_AVR_HI8_LDI_PM:
1012 reloc_to_return = BFD_RELOC_AVR_HI8_LDI_GS;
1013 break;
1014
1015 default:
Nick Clifton0a903ba2008-05-30 14:20:27 +00001016 /* PR 5523: Do not generate a warning here,
1017 legitimate code can trigger this case. */
1018 break;
Nick Clifton28c9d252006-05-24 07:36:12 +00001019 }
1020 }
1021 return reloc_to_return;
Nick Cliftondc191a82005-10-12 10:56:46 +00001022 }
1023 }
1024 }
1025
1026 input_line_pointer = tmp;
1027 expression (exp);
1028
1029 /* Warn about expressions that fail to use lo8 (). */
1030 if (exp->X_op == O_constant)
1031 {
1032 int x = exp->X_add_number;
1033
1034 if (x < -255 || x > 255)
1035 as_warn (_("constant out of 8-bit range: %d"), x);
1036 }
1037
1038 return BFD_RELOC_AVR_LDI;
1039}
1040
Denis Chertykovdf136242000-05-01 11:14:05 +00001041/* Parse one instruction operand.
Nick Cliftonc6a7ab12000-07-28 00:42:18 +00001042 Return operand bitmask. Also fixups can be generated. */
1043
Alan Modraadde6302000-03-27 08:39:14 +00001044static unsigned int
Nick Cliftondc191a82005-10-12 10:56:46 +00001045avr_operand (struct avr_opcodes_s *opcode,
1046 int where,
Trevor Saunderse0471c12016-02-25 16:55:21 +00001047 const char *op,
Georg-Johann Lay32f76c62017-06-30 16:37:39 +01001048 char **line,
1049 int *pregno)
Alan Modraadde6302000-03-27 08:39:14 +00001050{
Alan Modraadde6302000-03-27 08:39:14 +00001051 expressionS op_expr;
Denis Chertykovdf136242000-05-01 11:14:05 +00001052 unsigned int op_mask = 0;
1053 char *str = skip_space (*line);
Alan Modraadde6302000-03-27 08:39:14 +00001054
Alan Modraadde6302000-03-27 08:39:14 +00001055 switch (*op)
1056 {
1057 /* Any register operand. */
1058 case 'w':
1059 case 'd':
1060 case 'r':
Denis Chertykovb170af92000-05-01 08:48:32 +00001061 case 'a':
1062 case 'v':
Barney Stratford75f58082014-07-07 16:15:19 +01001063 {
1064 char * old_str = str;
1065 char *lower;
1066 char r_name[20];
Kazu Hirata1dab94d2000-09-15 01:06:52 +00001067
Barney Stratford75f58082014-07-07 16:15:19 +01001068 str = extract_word (str, r_name, sizeof (r_name));
1069 for (lower = r_name; *lower; ++lower)
1070 {
1071 if (*lower >= 'A' && *lower <= 'Z')
1072 *lower += 'a' - 'A';
1073 }
1074
1075 if (r_name[0] == 'r' && ISDIGIT (r_name[1]) && r_name[2] == 0)
1076 /* Single-digit register number, ie r0-r9. */
1077 op_mask = r_name[1] - '0';
1078 else if (r_name[0] == 'r' && ISDIGIT (r_name[1])
1079 && ISDIGIT (r_name[2]) && r_name[3] == 0)
1080 /* Double-digit register number, ie r10 - r32. */
1081 op_mask = (r_name[1] - '0') * 10 + r_name[2] - '0';
1082 else if (r_name[0] >= 'x' && r_name[0] <= 'z'
1083 && (r_name[1] == 'l' || r_name[1] == 'h') && r_name[2] == 0)
1084 /* Registers r26-r31 referred to by name, ie xl, xh, yl, yh, zl, zh. */
1085 op_mask = (r_name[0] - 'x') * 2 + (r_name[1] == 'h') + 26;
1086 else if ((*op == 'v' || *op == 'w')
1087 && r_name[0] >= 'x' && r_name[0] <= 'z' && r_name[1] == 0)
1088 /* For the movw and addiw instructions, refer to registers x, y and z by name. */
1089 op_mask = (r_name[0] - 'x') * 2 + 26;
1090 else
1091 {
1092 /* Numeric or symbolic constant register number. */
1093 op_mask = avr_get_constant (old_str, 31);
1094 str = input_line_pointer;
1095 }
1096 }
Kazu Hirata1dab94d2000-09-15 01:06:52 +00001097
Georg-Johann Lay32f76c62017-06-30 16:37:39 +01001098 if (pregno)
1099 *pregno = op_mask;
1100
Barney Stratfordf36e8882014-07-01 10:20:17 +01001101 if (avr_mcu->mach == bfd_mach_avrtiny)
1102 {
1103 if (op_mask < 16 || op_mask > 31)
1104 {
1105 as_bad (_("register name or number from 16 to 31 required"));
1106 break;
1107 }
1108 }
1109 else if (op_mask > 31)
1110 {
1111 as_bad (_("register name or number from 0 to 31 required"));
1112 break;
1113 }
1114
Nick Cliftonc6a7ab12000-07-28 00:42:18 +00001115 switch (*op)
1116 {
1117 case 'a':
1118 if (op_mask < 16 || op_mask > 23)
1119 as_bad (_("register r16-r23 required"));
1120 op_mask -= 16;
1121 break;
Kazu Hirata1dab94d2000-09-15 01:06:52 +00001122
Nick Cliftonc6a7ab12000-07-28 00:42:18 +00001123 case 'd':
1124 if (op_mask < 16)
1125 as_bad (_("register number above 15 required"));
1126 op_mask -= 16;
1127 break;
Kazu Hirata1dab94d2000-09-15 01:06:52 +00001128
Nick Cliftonc6a7ab12000-07-28 00:42:18 +00001129 case 'v':
1130 if (op_mask & 1)
1131 as_bad (_("even register number required"));
1132 op_mask >>= 1;
1133 break;
Kazu Hirata1dab94d2000-09-15 01:06:52 +00001134
Nick Cliftonc6a7ab12000-07-28 00:42:18 +00001135 case 'w':
Denis Chertykov65b1d092000-08-06 14:03:58 +00001136 if ((op_mask & 1) || op_mask < 24)
Nick Cliftonc6a7ab12000-07-28 00:42:18 +00001137 as_bad (_("register r24, r26, r28 or r30 required"));
Denis Chertykov65b1d092000-08-06 14:03:58 +00001138 op_mask = (op_mask - 24) >> 1;
Nick Cliftonc6a7ab12000-07-28 00:42:18 +00001139 break;
1140 }
1141 break;
Alan Modraadde6302000-03-27 08:39:14 +00001142
1143 case 'e':
1144 {
1145 char c;
Kazu Hirata1dab94d2000-09-15 01:06:52 +00001146
Alan Modraadde6302000-03-27 08:39:14 +00001147 if (*str == '-')
1148 {
Nick Cliftonc6a7ab12000-07-28 00:42:18 +00001149 str = skip_space (str + 1);
Alan Modraadde6302000-03-27 08:39:14 +00001150 op_mask = 0x1002;
1151 }
H.J. Lu3882b012001-09-19 05:33:36 +00001152 c = TOLOWER (*str);
Alan Modraadde6302000-03-27 08:39:14 +00001153 if (c == 'x')
1154 op_mask |= 0x100c;
1155 else if (c == 'y')
1156 op_mask |= 0x8;
1157 else if (c != 'z')
Nick Clifton00d28652000-07-03 22:25:33 +00001158 as_bad (_("pointer register (X, Y or Z) required"));
Alan Modraadde6302000-03-27 08:39:14 +00001159
Nick Cliftonc6a7ab12000-07-28 00:42:18 +00001160 str = skip_space (str + 1);
Alan Modraadde6302000-03-27 08:39:14 +00001161 if (*str == '+')
1162 {
1163 ++str;
1164 if (op_mask & 2)
Nick Clifton00d28652000-07-03 22:25:33 +00001165 as_bad (_("cannot both predecrement and postincrement"));
Alan Modraadde6302000-03-27 08:39:14 +00001166 op_mask |= 0x1001;
1167 }
Denis Chertykove38c9cc2000-06-07 18:56:15 +00001168
Denis Chertykov1188e082000-06-07 17:42:44 +00001169 /* avr1 can do "ld r,Z" and "st Z,r" but no other pointer
Denis Chertykove38c9cc2000-06-07 18:56:15 +00001170 registers, no predecrement, no postincrement. */
Nick Clifton00d28652000-07-03 22:25:33 +00001171 if (!avr_opt.all_opcodes && (op_mask & 0x100F)
1172 && !(avr_mcu->isa & AVR_ISA_SRAM))
1173 as_bad (_("addressing mode not supported"));
Alan Modraadde6302000-03-27 08:39:14 +00001174 }
1175 break;
1176
Denis Chertykovb170af92000-05-01 08:48:32 +00001177 case 'z':
Nick Cliftonc6a7ab12000-07-28 00:42:18 +00001178 if (*str == '-')
1179 as_bad (_("can't predecrement"));
Kazu Hirata1dab94d2000-09-15 01:06:52 +00001180
Nick Cliftonc6a7ab12000-07-28 00:42:18 +00001181 if (! (*str == 'z' || *str == 'Z'))
1182 as_bad (_("pointer register Z required"));
Kazu Hirata1dab94d2000-09-15 01:06:52 +00001183
Nick Cliftonc6a7ab12000-07-28 00:42:18 +00001184 str = skip_space (str + 1);
Denis Chertykovb170af92000-05-01 08:48:32 +00001185
Nick Cliftonc6a7ab12000-07-28 00:42:18 +00001186 if (*str == '+')
1187 {
1188 ++str;
Trevor Saunderse0471c12016-02-25 16:55:21 +00001189 const char *s;
Eric B. Weddington8cc66332011-03-22 18:10:48 +00001190 for (s = opcode->opcode; *s; ++s)
1191 {
1192 if (*s == '+')
1193 op_mask |= (1 << (15 - (s - opcode->opcode)));
1194 }
Nick Cliftonc6a7ab12000-07-28 00:42:18 +00001195 }
Nick Cliftond669d372008-02-14 13:04:29 +00001196
1197 /* attiny26 can do "lpm" and "lpm r,Z" but not "lpm r,Z+". */
1198 if (!avr_opt.all_opcodes
1199 && (op_mask & 0x0001)
1200 && !(avr_mcu->isa & AVR_ISA_MOVW))
1201 as_bad (_("postincrement not supported"));
Denis Chertykovb170af92000-05-01 08:48:32 +00001202 break;
1203
Alan Modraadde6302000-03-27 08:39:14 +00001204 case 'b':
1205 {
H.J. Lu3882b012001-09-19 05:33:36 +00001206 char c = TOLOWER (*str++);
Kazu Hirata1dab94d2000-09-15 01:06:52 +00001207
Alan Modraadde6302000-03-27 08:39:14 +00001208 if (c == 'y')
1209 op_mask |= 0x8;
1210 else if (c != 'z')
Nick Clifton00d28652000-07-03 22:25:33 +00001211 as_bad (_("pointer register (Y or Z) required"));
Alan Modraadde6302000-03-27 08:39:14 +00001212 str = skip_space (str);
1213 if (*str++ == '+')
1214 {
Nick Clifton750bce02004-12-22 14:25:42 +00001215 input_line_pointer = str;
1216 avr_offset_expression (& op_expr);
Alan Modraadde6302000-03-27 08:39:14 +00001217 str = input_line_pointer;
Nick Clifton750bce02004-12-22 14:25:42 +00001218 fix_new_exp (frag_now, where, 3,
Alan Modra5b7c81b2021-03-31 10:42:05 +10301219 &op_expr, false, BFD_RELOC_AVR_6);
Alan Modraadde6302000-03-27 08:39:14 +00001220 }
1221 }
1222 break;
1223
1224 case 'h':
Nick Cliftonc6a7ab12000-07-28 00:42:18 +00001225 str = parse_exp (str, &op_expr);
1226 fix_new_exp (frag_now, where, opcode->insn_size * 2,
Alan Modra5b7c81b2021-03-31 10:42:05 +10301227 &op_expr, false, BFD_RELOC_AVR_CALL);
Alan Modraadde6302000-03-27 08:39:14 +00001228 break;
1229
1230 case 'L':
Nick Cliftonc6a7ab12000-07-28 00:42:18 +00001231 str = parse_exp (str, &op_expr);
1232 fix_new_exp (frag_now, where, opcode->insn_size * 2,
Alan Modra5b7c81b2021-03-31 10:42:05 +10301233 &op_expr, true, BFD_RELOC_AVR_13_PCREL);
Alan Modraadde6302000-03-27 08:39:14 +00001234 break;
1235
1236 case 'l':
Nick Cliftonc6a7ab12000-07-28 00:42:18 +00001237 str = parse_exp (str, &op_expr);
1238 fix_new_exp (frag_now, where, opcode->insn_size * 2,
Alan Modra5b7c81b2021-03-31 10:42:05 +10301239 &op_expr, true, BFD_RELOC_AVR_7_PCREL);
Alan Modraadde6302000-03-27 08:39:14 +00001240 break;
1241
1242 case 'i':
Nick Cliftonc6a7ab12000-07-28 00:42:18 +00001243 str = parse_exp (str, &op_expr);
1244 fix_new_exp (frag_now, where + 2, opcode->insn_size * 2,
Alan Modra5b7c81b2021-03-31 10:42:05 +10301245 &op_expr, false, BFD_RELOC_16);
Alan Modraadde6302000-03-27 08:39:14 +00001246 break;
1247
Barney Stratfordf36e8882014-07-01 10:20:17 +01001248 case 'j':
1249 str = parse_exp (str, &op_expr);
1250 fix_new_exp (frag_now, where, opcode->insn_size * 2,
Alan Modra5b7c81b2021-03-31 10:42:05 +10301251 &op_expr, false, BFD_RELOC_AVR_LDS_STS_16);
Barney Stratfordf36e8882014-07-01 10:20:17 +01001252 break;
1253
Alan Modraadde6302000-03-27 08:39:14 +00001254 case 'M':
1255 {
1256 bfd_reloc_code_real_type r_type;
Kazu Hirata1dab94d2000-09-15 01:06:52 +00001257
Nick Cliftonc6a7ab12000-07-28 00:42:18 +00001258 input_line_pointer = str;
1259 r_type = avr_ldi_expression (&op_expr);
1260 str = input_line_pointer;
Alan Modraadde6302000-03-27 08:39:14 +00001261 fix_new_exp (frag_now, where, 3,
Alan Modra5b7c81b2021-03-31 10:42:05 +10301262 &op_expr, false, r_type);
Alan Modraadde6302000-03-27 08:39:14 +00001263 }
1264 break;
1265
1266 case 'n':
1267 {
1268 unsigned int x;
Kazu Hirata1dab94d2000-09-15 01:06:52 +00001269
Alan Modraadde6302000-03-27 08:39:14 +00001270 x = ~avr_get_constant (str, 255);
1271 str = input_line_pointer;
1272 op_mask |= (x & 0xf) | ((x << 4) & 0xf00);
1273 }
1274 break;
1275
Georg-Johann Lay32f76c62017-06-30 16:37:39 +01001276 case 'N':
1277 {
1278 unsigned int x;
1279
1280 x = avr_get_constant (str, 255);
1281 str = input_line_pointer;
1282 op_mask = x;
1283 }
1284 break;
1285
Alan Modraadde6302000-03-27 08:39:14 +00001286 case 'K':
Nick Clifton750bce02004-12-22 14:25:42 +00001287 input_line_pointer = str;
1288 avr_offset_expression (& op_expr);
1289 str = input_line_pointer;
1290 fix_new_exp (frag_now, where, 3,
Alan Modra5b7c81b2021-03-31 10:42:05 +10301291 & op_expr, false, BFD_RELOC_AVR_6_ADIW);
Alan Modraadde6302000-03-27 08:39:14 +00001292 break;
1293
1294 case 'S':
1295 case 's':
1296 {
1297 unsigned int x;
Kazu Hirata1dab94d2000-09-15 01:06:52 +00001298
Alan Modraadde6302000-03-27 08:39:14 +00001299 x = avr_get_constant (str, 7);
1300 str = input_line_pointer;
1301 if (*op == 'S')
1302 x <<= 4;
1303 op_mask |= x;
1304 }
1305 break;
1306
1307 case 'P':
Barney Stratford75f58082014-07-07 16:15:19 +01001308 str = parse_exp (str, &op_expr);
1309 fix_new_exp (frag_now, where, opcode->insn_size * 2,
Alan Modra5b7c81b2021-03-31 10:42:05 +10301310 &op_expr, false, BFD_RELOC_AVR_PORT6);
Alan Modraadde6302000-03-27 08:39:14 +00001311 break;
1312
1313 case 'p':
Barney Stratford75f58082014-07-07 16:15:19 +01001314 str = parse_exp (str, &op_expr);
1315 fix_new_exp (frag_now, where, opcode->insn_size * 2,
Alan Modra5b7c81b2021-03-31 10:42:05 +10301316 &op_expr, false, BFD_RELOC_AVR_PORT5);
Alan Modraadde6302000-03-27 08:39:14 +00001317 break;
Kazu Hirata1dab94d2000-09-15 01:06:52 +00001318
Eric B. Weddington8cc66332011-03-22 18:10:48 +00001319 case 'E':
1320 {
1321 unsigned int x;
1322
1323 x = avr_get_constant (str, 15);
1324 str = input_line_pointer;
1325 op_mask |= (x << 4);
1326 }
1327 break;
Nick Clifton99700d62012-05-11 12:59:23 +00001328
Denis Chertykov1188e082000-06-07 17:42:44 +00001329 case '?':
1330 break;
Kazu Hirata1dab94d2000-09-15 01:06:52 +00001331
Alan Modraadde6302000-03-27 08:39:14 +00001332 default:
Nick Clifton00d28652000-07-03 22:25:33 +00001333 as_bad (_("unknown constraint `%c'"), *op);
Alan Modraadde6302000-03-27 08:39:14 +00001334 }
Kazu Hirata1dab94d2000-09-15 01:06:52 +00001335
Alan Modraadde6302000-03-27 08:39:14 +00001336 *line = str;
1337 return op_mask;
1338}
1339
Nick Clifton95e42ad2017-10-19 16:21:51 +01001340/* TC_FRAG_INIT hook */
1341
1342void
1343avr_frag_init (fragS *frag)
1344{
1345 memset (& frag->tc_frag_data, 0, sizeof frag->tc_frag_data);
1346}
1347
1348
Nick Cliftondc191a82005-10-12 10:56:46 +00001349/* Parse instruction operands.
1350 Return binary opcode. */
1351
1352static unsigned int
1353avr_operands (struct avr_opcodes_s *opcode, char **line)
1354{
Trevor Saunderse0471c12016-02-25 16:55:21 +00001355 const char *op = opcode->constraints;
Nick Cliftondc191a82005-10-12 10:56:46 +00001356 unsigned int bin = opcode->bin_opcode;
1357 char *frag = frag_more (opcode->insn_size * 2);
1358 char *str = *line;
1359 int where = frag - frag_now->fr_literal;
Georg-Johann Lay32f76c62017-06-30 16:37:39 +01001360 int regno1 = -2;
1361 int regno2 = -2;
Nick Cliftondc191a82005-10-12 10:56:46 +00001362
1363 /* Opcode have operands. */
1364 if (*op)
1365 {
1366 unsigned int reg1 = 0;
1367 unsigned int reg2 = 0;
1368 int reg1_present = 0;
1369 int reg2_present = 0;
1370
1371 /* Parse first operand. */
1372 if (REGISTER_P (*op))
1373 reg1_present = 1;
Georg-Johann Lay32f76c62017-06-30 16:37:39 +01001374 reg1 = avr_operand (opcode, where, op, &str, &regno1);
Nick Cliftondc191a82005-10-12 10:56:46 +00001375 ++op;
1376
1377 /* Parse second operand. */
1378 if (*op)
1379 {
1380 if (*op == ',')
1381 ++op;
1382
1383 if (*op == '=')
1384 {
1385 reg2 = reg1;
1386 reg2_present = 1;
Georg-Johann Lay32f76c62017-06-30 16:37:39 +01001387 regno2 = regno1;
Nick Cliftondc191a82005-10-12 10:56:46 +00001388 }
1389 else
1390 {
1391 if (REGISTER_P (*op))
1392 reg2_present = 1;
1393
1394 str = skip_space (str);
1395 if (*str++ != ',')
1396 as_bad (_("`,' required"));
1397 str = skip_space (str);
1398
Georg-Johann Lay32f76c62017-06-30 16:37:39 +01001399 reg2 = avr_operand (opcode, where, op, &str, &regno2);
Nick Cliftondc191a82005-10-12 10:56:46 +00001400 }
1401
1402 if (reg1_present && reg2_present)
1403 reg2 = (reg2 & 0xf) | ((reg2 << 5) & 0x200);
1404 else if (reg2_present)
1405 reg2 <<= 4;
1406 }
1407 if (reg1_present)
1408 reg1 <<= 4;
1409 bin |= reg1 | reg2;
1410 }
1411
Georg-Johann Lay32f76c62017-06-30 16:37:39 +01001412 if (avr_opt.have_gccisr)
1413 avr_update_gccisr (opcode, regno1, regno2);
1414
Nick Cliftondc191a82005-10-12 10:56:46 +00001415 /* Detect undefined combinations (like ld r31,Z+). */
1416 if (!avr_opt.all_opcodes && AVR_UNDEF_P (bin))
1417 as_warn (_("undefined combination of operands"));
1418
1419 if (opcode->insn_size == 2)
1420 {
1421 /* Warn if the previous opcode was cpse/sbic/sbis/sbrc/sbrs
1422 (AVR core bug, fixed in the newer devices). */
1423 if (!(avr_opt.no_skip_bug ||
1424 (avr_mcu->isa & (AVR_ISA_MUL | AVR_ISA_MOVW)))
Nick Clifton95e42ad2017-10-19 16:21:51 +01001425 && AVR_SKIP_P (frag_now->tc_frag_data.prev_opcode))
Nick Cliftondc191a82005-10-12 10:56:46 +00001426 as_warn (_("skipping two-word instruction"));
1427
1428 bfd_putl32 ((bfd_vma) bin, frag);
1429 }
1430 else
1431 bfd_putl16 ((bfd_vma) bin, frag);
1432
Nick Clifton95e42ad2017-10-19 16:21:51 +01001433 frag_now->tc_frag_data.prev_opcode = bin;
Nick Cliftondc191a82005-10-12 10:56:46 +00001434 *line = str;
1435 return bin;
1436}
1437
Alan Modraadde6302000-03-27 08:39:14 +00001438/* GAS will call this function for each section at the end of the assembly,
1439 to permit the CPU backend to adjust the alignment of a section. */
Nick Cliftonc6a7ab12000-07-28 00:42:18 +00001440
Alan Modraadde6302000-03-27 08:39:14 +00001441valueT
Nick Cliftondc191a82005-10-12 10:56:46 +00001442md_section_align (asection *seg, valueT addr)
Alan Modraadde6302000-03-27 08:39:14 +00001443{
Alan Modrafd361982019-09-16 20:25:17 +09301444 int align = bfd_section_alignment (seg);
Chen Gangdce55a02015-09-05 16:02:08 +08001445 return ((addr + (1 << align) - 1) & (-1UL << align));
Alan Modraadde6302000-03-27 08:39:14 +00001446}
1447
1448/* If you define this macro, it should return the offset between the
1449 address of a PC relative fixup and the position from which the PC
1450 relative adjustment should be made. On many processors, the base
1451 of a PC relative instruction is the next instruction, so this
1452 macro would return the length of an instruction. */
Nick Cliftonc6a7ab12000-07-28 00:42:18 +00001453
Alan Modraadde6302000-03-27 08:39:14 +00001454long
Nick Cliftondc191a82005-10-12 10:56:46 +00001455md_pcrel_from_section (fixS *fixp, segT sec)
Alan Modraadde6302000-03-27 08:39:14 +00001456{
Nick Cliftonc6a7ab12000-07-28 00:42:18 +00001457 if (fixp->fx_addsy != (symbolS *) NULL
Alan Modraadde6302000-03-27 08:39:14 +00001458 && (!S_IS_DEFINED (fixp->fx_addsy)
1459 || (S_GET_SEGMENT (fixp->fx_addsy) != sec)))
1460 return 0;
Kazu Hirata1dab94d2000-09-15 01:06:52 +00001461
Alan Modraadde6302000-03-27 08:39:14 +00001462 return fixp->fx_frag->fr_address + fixp->fx_where;
1463}
1464
Alan Modra5b7c81b2021-03-31 10:42:05 +10301465static bool
Denis Chertykove4ef1b62014-04-10 19:50:33 +04001466relaxable_section (asection *sec)
1467{
Andrew Burgessedc9e9a2014-10-27 10:51:17 +00001468 return ((sec->flags & SEC_DEBUGGING) == 0
1469 && (sec->flags & SEC_CODE) != 0
1470 && (sec->flags & SEC_ALLOC) != 0);
Denis Chertykove4ef1b62014-04-10 19:50:33 +04001471}
1472
Barney Stratford75f58082014-07-07 16:15:19 +01001473/* Does whatever the xtensa port does. */
Denis Chertykove4ef1b62014-04-10 19:50:33 +04001474int
1475avr_validate_fix_sub (fixS *fix)
1476{
1477 segT add_symbol_segment, sub_symbol_segment;
1478
1479 /* The difference of two symbols should be resolved by the assembler when
1480 linkrelax is not set. If the linker may relax the section containing
1481 the symbols, then an Xtensa DIFF relocation must be generated so that
1482 the linker knows to adjust the difference value. */
1483 if (!linkrelax || fix->fx_addsy == NULL)
1484 return 0;
1485
1486 /* Make sure both symbols are in the same segment, and that segment is
1487 "normal" and relaxable. If the segment is not "normal", then the
1488 fix is not valid. If the segment is not "relaxable", then the fix
1489 should have been handled earlier. */
1490 add_symbol_segment = S_GET_SEGMENT (fix->fx_addsy);
1491 if (! SEG_NORMAL (add_symbol_segment) ||
1492 ! relaxable_section (add_symbol_segment))
1493 return 0;
1494
1495 sub_symbol_segment = S_GET_SEGMENT (fix->fx_subsy);
1496 return (sub_symbol_segment == add_symbol_segment);
1497}
1498
1499/* TC_FORCE_RELOCATION hook */
1500
1501/* If linkrelax is turned on, and the symbol to relocate
1502 against is in a relaxable segment, don't compute the value -
Barney Stratford75f58082014-07-07 16:15:19 +01001503 generate a relocation instead. */
Denis Chertykove4ef1b62014-04-10 19:50:33 +04001504int
1505avr_force_relocation (fixS *fix)
1506{
1507 if (linkrelax && fix->fx_addsy
1508 && relaxable_section (S_GET_SEGMENT (fix->fx_addsy)))
1509 return 1;
1510
1511 return generic_force_reloc (fix);
1512}
1513
Alan Modraadde6302000-03-27 08:39:14 +00001514/* GAS will call this for each fixup. It should store the correct
Nick Cliftonc6a7ab12000-07-28 00:42:18 +00001515 value in the object file. */
1516
Nick Clifton94f592a2001-11-15 21:29:00 +00001517void
Nick Cliftondc191a82005-10-12 10:56:46 +00001518md_apply_fix (fixS *fixP, valueT * valP, segT seg)
Alan Modraadde6302000-03-27 08:39:14 +00001519{
1520 unsigned char *where;
1521 unsigned long insn;
Alan Modraa161fe52002-09-05 00:01:18 +00001522 long value = *valP;
Alan Modraadde6302000-03-27 08:39:14 +00001523
Nick Clifton94f592a2001-11-15 21:29:00 +00001524 if (fixP->fx_addsy == (symbolS *) NULL)
1525 fixP->fx_done = 1;
Kazu Hirata1dab94d2000-09-15 01:06:52 +00001526
Alan Modra87733542002-09-27 04:38:47 +00001527 else if (fixP->fx_pcrel)
1528 {
1529 segT s = S_GET_SEGMENT (fixP->fx_addsy);
1530
1531 if (s == seg || s == absolute_section)
1532 {
1533 value += S_GET_VALUE (fixP->fx_addsy);
1534 fixP->fx_done = 1;
1535 }
1536 }
Denis Chertykove4ef1b62014-04-10 19:50:33 +04001537 else if (linkrelax && fixP->fx_subsy)
1538 {
1539 /* For a subtraction relocation expression, generate one
1540 of the DIFF relocs, with the value being the difference.
1541 Note that a sym1 - sym2 expression is adjusted into a
1542 section_start_sym + sym4_offset_from_section_start - sym1
1543 expression. fixP->fx_addsy holds the section start symbol,
1544 fixP->fx_offset holds sym2's offset, and fixP->fx_subsy
1545 holds sym1. Calculate the current difference and write value,
Barney Stratford75f58082014-07-07 16:15:19 +01001546 but leave fx_offset as is - during relaxation,
1547 fx_offset - value gives sym1's value. */
Alan Modra87733542002-09-27 04:38:47 +00001548
Denis Chertykove4ef1b62014-04-10 19:50:33 +04001549 switch (fixP->fx_r_type)
1550 {
1551 case BFD_RELOC_8:
1552 fixP->fx_r_type = BFD_RELOC_AVR_DIFF8;
1553 break;
1554 case BFD_RELOC_16:
1555 fixP->fx_r_type = BFD_RELOC_AVR_DIFF16;
1556 break;
1557 case BFD_RELOC_32:
1558 fixP->fx_r_type = BFD_RELOC_AVR_DIFF32;
1559 break;
1560 default:
Alan Modra4bf09422021-07-21 14:39:29 +09301561 as_bad_subtract (fixP);
Denis Chertykove4ef1b62014-04-10 19:50:33 +04001562 break;
1563 }
1564
1565 value = S_GET_VALUE (fixP->fx_addsy) +
1566 fixP->fx_offset - S_GET_VALUE (fixP->fx_subsy);
Andrew Burgess491793b2015-01-04 00:03:16 +00001567 *valP = value;
Denis Chertykove4ef1b62014-04-10 19:50:33 +04001568
1569 fixP->fx_subsy = NULL;
1570 }
Alan Modraa161fe52002-09-05 00:01:18 +00001571 /* We don't actually support subtracting a symbol. */
1572 if (fixP->fx_subsy != (symbolS *) NULL)
Alan Modra4bf09422021-07-21 14:39:29 +09301573 as_bad_subtract (fixP);
Kazu Hirata1dab94d2000-09-15 01:06:52 +00001574
Denis Chertykove4ef1b62014-04-10 19:50:33 +04001575 /* For the DIFF relocs, write the value into the object file while still
1576 keeping fx_done FALSE, as both the difference (recorded in the object file)
Barney Stratford75f58082014-07-07 16:15:19 +01001577 and the sym offset (part of fixP) are needed at link relax time. */
Denis Chertykove4ef1b62014-04-10 19:50:33 +04001578 where = (unsigned char *) fixP->fx_frag->fr_literal + fixP->fx_where;
Nick Clifton94f592a2001-11-15 21:29:00 +00001579 switch (fixP->fx_r_type)
Alan Modraadde6302000-03-27 08:39:14 +00001580 {
1581 default:
Nick Clifton94f592a2001-11-15 21:29:00 +00001582 fixP->fx_no_overflow = 1;
Alan Modraadde6302000-03-27 08:39:14 +00001583 break;
1584 case BFD_RELOC_AVR_7_PCREL:
1585 case BFD_RELOC_AVR_13_PCREL:
1586 case BFD_RELOC_32:
1587 case BFD_RELOC_16:
Denis Chertykove4ef1b62014-04-10 19:50:33 +04001588 break;
1589 case BFD_RELOC_AVR_DIFF8:
1590 *where = value;
1591 break;
1592 case BFD_RELOC_AVR_DIFF16:
1593 bfd_putl16 ((bfd_vma) value, where);
1594 break;
1595 case BFD_RELOC_AVR_DIFF32:
1596 bfd_putl32 ((bfd_vma) value, where);
1597 break;
Alan Modraadde6302000-03-27 08:39:14 +00001598 case BFD_RELOC_AVR_CALL:
1599 break;
1600 }
1601
Nick Clifton94f592a2001-11-15 21:29:00 +00001602 if (fixP->fx_done)
Alan Modraadde6302000-03-27 08:39:14 +00001603 {
1604 /* Fetch the instruction, insert the fully resolved operand
1605 value, and stuff the instruction back again. */
Alan Modra2132e3a2005-02-23 12:28:06 +00001606 where = (unsigned char *) fixP->fx_frag->fr_literal + fixP->fx_where;
Alan Modraadde6302000-03-27 08:39:14 +00001607 insn = bfd_getl16 (where);
1608
Nick Clifton94f592a2001-11-15 21:29:00 +00001609 switch (fixP->fx_r_type)
Alan Modraadde6302000-03-27 08:39:14 +00001610 {
1611 case BFD_RELOC_AVR_7_PCREL:
1612 if (value & 1)
Nick Clifton94f592a2001-11-15 21:29:00 +00001613 as_bad_where (fixP->fx_file, fixP->fx_line,
Alan Modraadde6302000-03-27 08:39:14 +00001614 _("odd address operand: %ld"), value);
Kazu Hirata1dab94d2000-09-15 01:06:52 +00001615
Alan Modraadde6302000-03-27 08:39:14 +00001616 /* Instruction addresses are always right-shifted by 1. */
1617 value >>= 1;
1618 --value; /* Correct PC. */
Kazu Hirata1dab94d2000-09-15 01:06:52 +00001619
Alan Modraadde6302000-03-27 08:39:14 +00001620 if (value < -64 || value > 63)
Nick Clifton94f592a2001-11-15 21:29:00 +00001621 as_bad_where (fixP->fx_file, fixP->fx_line,
Alan Modraadde6302000-03-27 08:39:14 +00001622 _("operand out of range: %ld"), value);
1623 value = (value << 3) & 0x3f8;
1624 bfd_putl16 ((bfd_vma) (value | insn), where);
1625 break;
1626
1627 case BFD_RELOC_AVR_13_PCREL:
1628 if (value & 1)
Nick Clifton94f592a2001-11-15 21:29:00 +00001629 as_bad_where (fixP->fx_file, fixP->fx_line,
Alan Modraadde6302000-03-27 08:39:14 +00001630 _("odd address operand: %ld"), value);
Kazu Hirata1dab94d2000-09-15 01:06:52 +00001631
Alan Modraadde6302000-03-27 08:39:14 +00001632 /* Instruction addresses are always right-shifted by 1. */
1633 value >>= 1;
1634 --value; /* Correct PC. */
Alan Modraadde6302000-03-27 08:39:14 +00001635
1636 if (value < -2048 || value > 2047)
1637 {
Nick Clifton65aa24b2000-06-27 01:45:30 +00001638 /* No wrap for devices with >8K of program memory. */
Nick Clifton00d28652000-07-03 22:25:33 +00001639 if ((avr_mcu->isa & AVR_ISA_MEGA) || avr_opt.no_wrap)
Nick Clifton94f592a2001-11-15 21:29:00 +00001640 as_bad_where (fixP->fx_file, fixP->fx_line,
Alan Modraadde6302000-03-27 08:39:14 +00001641 _("operand out of range: %ld"), value);
1642 }
1643
1644 value &= 0xfff;
1645 bfd_putl16 ((bfd_vma) (value | insn), where);
1646 break;
1647
1648 case BFD_RELOC_32:
Richard Sandiford0b649252012-04-17 13:59:41 +00001649 bfd_putl32 ((bfd_vma) value, where);
Alan Modraadde6302000-03-27 08:39:14 +00001650 break;
1651
1652 case BFD_RELOC_16:
1653 bfd_putl16 ((bfd_vma) value, where);
1654 break;
1655
Nick Clifton17e57232010-02-23 11:38:36 +00001656 case BFD_RELOC_8:
1657 if (value > 255 || value < -128)
1658 as_warn_where (fixP->fx_file, fixP->fx_line,
1659 _("operand out of range: %ld"), value);
1660 *where = value;
1661 break;
1662
Alan Modraadde6302000-03-27 08:39:14 +00001663 case BFD_RELOC_AVR_16_PM:
Nick Cliftonc6a7ab12000-07-28 00:42:18 +00001664 bfd_putl16 ((bfd_vma) (value >> 1), where);
Alan Modraadde6302000-03-27 08:39:14 +00001665 break;
1666
Nick Clifton750bce02004-12-22 14:25:42 +00001667 case BFD_RELOC_AVR_LDI:
1668 if (value > 255)
1669 as_bad_where (fixP->fx_file, fixP->fx_line,
1670 _("operand out of range: %ld"), value);
1671 bfd_putl16 ((bfd_vma) insn | LDI_IMMEDIATE (value), where);
1672 break;
1673
Barney Stratfordf36e8882014-07-01 10:20:17 +01001674 case BFD_RELOC_AVR_LDS_STS_16:
1675 if ((value < 0x40) || (value > 0xBF))
1676 as_warn_where (fixP->fx_file, fixP->fx_line,
1677 _("operand out of range: 0x%lx"),
1678 (unsigned long)value);
1679 insn |= ((value & 0xF) | ((value & 0x30) << 5) | ((value & 0x40) << 2));
1680 bfd_putl16 ((bfd_vma) insn, where);
1681 break;
1682
Nick Clifton750bce02004-12-22 14:25:42 +00001683 case BFD_RELOC_AVR_6:
1684 if ((value > 63) || (value < 0))
1685 as_bad_where (fixP->fx_file, fixP->fx_line,
1686 _("operand out of range: %ld"), value);
Barney Stratfordf36e8882014-07-01 10:20:17 +01001687 bfd_putl16 ((bfd_vma) insn | ((value & 7) | ((value & (3 << 3)) << 7)
1688 | ((value & (1 << 5)) << 8)), where);
Nick Clifton750bce02004-12-22 14:25:42 +00001689 break;
1690
1691 case BFD_RELOC_AVR_6_ADIW:
1692 if ((value > 63) || (value < 0))
1693 as_bad_where (fixP->fx_file, fixP->fx_line,
1694 _("operand out of range: %ld"), value);
1695 bfd_putl16 ((bfd_vma) insn | (value & 0xf) | ((value & 0x30) << 2), where);
1696 break;
1697
Alan Modraadde6302000-03-27 08:39:14 +00001698 case BFD_RELOC_AVR_LO8_LDI:
1699 bfd_putl16 ((bfd_vma) insn | LDI_IMMEDIATE (value), where);
1700 break;
1701
Alan Modraadde6302000-03-27 08:39:14 +00001702 case BFD_RELOC_AVR_HI8_LDI:
1703 bfd_putl16 ((bfd_vma) insn | LDI_IMMEDIATE (value >> 8), where);
1704 break;
1705
Nick Cliftondf406462006-03-03 15:25:31 +00001706 case BFD_RELOC_AVR_MS8_LDI:
Alan Modraadde6302000-03-27 08:39:14 +00001707 bfd_putl16 ((bfd_vma) insn | LDI_IMMEDIATE (value >> 24), where);
1708 break;
1709
1710 case BFD_RELOC_AVR_HH8_LDI:
1711 bfd_putl16 ((bfd_vma) insn | LDI_IMMEDIATE (value >> 16), where);
1712 break;
1713
1714 case BFD_RELOC_AVR_LO8_LDI_NEG:
1715 bfd_putl16 ((bfd_vma) insn | LDI_IMMEDIATE (-value), where);
1716 break;
1717
Alan Modraadde6302000-03-27 08:39:14 +00001718 case BFD_RELOC_AVR_HI8_LDI_NEG:
1719 bfd_putl16 ((bfd_vma) insn | LDI_IMMEDIATE (-value >> 8), where);
1720 break;
1721
Nick Cliftondf406462006-03-03 15:25:31 +00001722 case BFD_RELOC_AVR_MS8_LDI_NEG:
Alan Modraadde6302000-03-27 08:39:14 +00001723 bfd_putl16 ((bfd_vma) insn | LDI_IMMEDIATE (-value >> 24), where);
1724 break;
1725
1726 case BFD_RELOC_AVR_HH8_LDI_NEG:
1727 bfd_putl16 ((bfd_vma) insn | LDI_IMMEDIATE (-value >> 16), where);
1728 break;
1729
1730 case BFD_RELOC_AVR_LO8_LDI_PM:
1731 bfd_putl16 ((bfd_vma) insn | LDI_IMMEDIATE (value >> 1), where);
1732 break;
1733
1734 case BFD_RELOC_AVR_HI8_LDI_PM:
1735 bfd_putl16 ((bfd_vma) insn | LDI_IMMEDIATE (value >> 9), where);
1736 break;
1737
1738 case BFD_RELOC_AVR_HH8_LDI_PM:
1739 bfd_putl16 ((bfd_vma) insn | LDI_IMMEDIATE (value >> 17), where);
1740 break;
1741
1742 case BFD_RELOC_AVR_LO8_LDI_PM_NEG:
1743 bfd_putl16 ((bfd_vma) insn | LDI_IMMEDIATE (-value >> 1), where);
1744 break;
1745
1746 case BFD_RELOC_AVR_HI8_LDI_PM_NEG:
1747 bfd_putl16 ((bfd_vma) insn | LDI_IMMEDIATE (-value >> 9), where);
1748 break;
1749
1750 case BFD_RELOC_AVR_HH8_LDI_PM_NEG:
1751 bfd_putl16 ((bfd_vma) insn | LDI_IMMEDIATE (-value >> 17), where);
1752 break;
1753
1754 case BFD_RELOC_AVR_CALL:
1755 {
1756 unsigned long x;
Kazu Hirata1dab94d2000-09-15 01:06:52 +00001757
Alan Modraadde6302000-03-27 08:39:14 +00001758 x = bfd_getl16 (where);
1759 if (value & 1)
Nick Clifton94f592a2001-11-15 21:29:00 +00001760 as_bad_where (fixP->fx_file, fixP->fx_line,
Alan Modraadde6302000-03-27 08:39:14 +00001761 _("odd address operand: %ld"), value);
1762 value >>= 1;
1763 x |= ((value & 0x10000) | ((value << 3) & 0x1f00000)) >> 16;
1764 bfd_putl16 ((bfd_vma) x, where);
Nick Cliftonc6a7ab12000-07-28 00:42:18 +00001765 bfd_putl16 ((bfd_vma) (value & 0xffff), where + 2);
Alan Modraadde6302000-03-27 08:39:14 +00001766 }
1767 break;
1768
Nick Clifton99700d62012-05-11 12:59:23 +00001769 case BFD_RELOC_AVR_8_LO:
1770 *where = 0xff & value;
1771 break;
1772
1773 case BFD_RELOC_AVR_8_HI:
1774 *where = 0xff & (value >> 8);
1775 break;
1776
Nick Clifton40551fb2012-05-16 14:52:16 +00001777 case BFD_RELOC_AVR_8_HLO:
Nick Clifton99700d62012-05-11 12:59:23 +00001778 *where = 0xff & (value >> 16);
1779 break;
1780
1781 default:
Nick Cliftonc6a7ab12000-07-28 00:42:18 +00001782 as_fatal (_("line %d: unknown relocation type: 0x%x"),
Nick Clifton94f592a2001-11-15 21:29:00 +00001783 fixP->fx_line, fixP->fx_r_type);
Alan Modraadde6302000-03-27 08:39:14 +00001784 break;
Barney Stratford75f58082014-07-07 16:15:19 +01001785
1786 case BFD_RELOC_AVR_PORT6:
1787 if (value > 63)
1788 as_bad_where (fixP->fx_file, fixP->fx_line,
1789 _("operand out of range: %ld"), value);
1790 bfd_putl16 ((bfd_vma) insn | ((value & 0x30) << 5) | (value & 0x0f), where);
1791 break;
1792
1793 case BFD_RELOC_AVR_PORT5:
1794 if (value > 31)
1795 as_bad_where (fixP->fx_file, fixP->fx_line,
1796 _("operand out of range: %ld"), value);
1797 bfd_putl16 ((bfd_vma) insn | ((value & 0x1f) << 3), where);
1798 break;
Alan Modraadde6302000-03-27 08:39:14 +00001799 }
1800 }
1801 else
1802 {
Nick Cliftona61a9fb2009-07-17 15:22:11 +00001803 switch ((int) fixP->fx_r_type)
Alan Modraadde6302000-03-27 08:39:14 +00001804 {
1805 case -BFD_RELOC_AVR_HI8_LDI_NEG:
1806 case -BFD_RELOC_AVR_HI8_LDI:
1807 case -BFD_RELOC_AVR_LO8_LDI_NEG:
1808 case -BFD_RELOC_AVR_LO8_LDI:
Nick Clifton94f592a2001-11-15 21:29:00 +00001809 as_bad_where (fixP->fx_file, fixP->fx_line,
Alan Modraadde6302000-03-27 08:39:14 +00001810 _("only constant expression allowed"));
Nick Clifton94f592a2001-11-15 21:29:00 +00001811 fixP->fx_done = 1;
Alan Modraadde6302000-03-27 08:39:14 +00001812 break;
1813 default:
1814 break;
1815 }
Alan Modraadde6302000-03-27 08:39:14 +00001816 }
Alan Modraadde6302000-03-27 08:39:14 +00001817}
1818
Alan Modra7be1c482005-08-11 01:25:29 +00001819/* GAS will call this to generate a reloc, passing the resulting reloc
1820 to `bfd_install_relocation'. This currently works poorly, as
1821 `bfd_install_relocation' often does the wrong thing, and instances of
1822 `tc_gen_reloc' have been written to work around the problems, which
1823 in turns makes it difficult to fix `bfd_install_relocation'. */
Alan Modraadde6302000-03-27 08:39:14 +00001824
1825/* If while processing a fixup, a reloc really needs to be created
1826 then it is done here. */
1827
1828arelent *
Nick Cliftondc191a82005-10-12 10:56:46 +00001829tc_gen_reloc (asection *seg ATTRIBUTE_UNUSED,
1830 fixS *fixp)
Alan Modraadde6302000-03-27 08:39:14 +00001831{
1832 arelent *reloc;
Denis Chertykov328e7bf2015-07-08 21:35:19 +03001833 bfd_reloc_code_real_type code = fixp->fx_r_type;
Alan Modraadde6302000-03-27 08:39:14 +00001834
Alan Modra94d44332013-02-05 23:02:54 +00001835 if (fixp->fx_subsy != NULL)
Nick Cliftondf406462006-03-03 15:25:31 +00001836 {
Alan Modra4bf09422021-07-21 14:39:29 +09301837 as_bad_subtract (fixp);
Nick Cliftondf406462006-03-03 15:25:31 +00001838 return NULL;
1839 }
1840
Trevor Saunders325801b2016-04-01 09:26:30 -04001841 reloc = XNEW (arelent);
Alan Modraadde6302000-03-27 08:39:14 +00001842
Trevor Saunders325801b2016-04-01 09:26:30 -04001843 reloc->sym_ptr_ptr = XNEW (asymbol *);
Alan Modraadde6302000-03-27 08:39:14 +00001844 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
1845
1846 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
Denis Chertykov328e7bf2015-07-08 21:35:19 +03001847
1848 if ((fixp->fx_r_type == BFD_RELOC_32) && (fixp->fx_pcrel))
1849 {
1850 if (seg->use_rela_p)
1851 fixp->fx_offset -= md_pcrel_from_section (fixp, seg);
1852 else
1853 fixp->fx_offset = reloc->address;
1854
1855 code = BFD_RELOC_32_PCREL;
1856 }
1857
1858 reloc->addend = fixp->fx_offset;
1859
1860 reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
1861
Alan Modraadde6302000-03-27 08:39:14 +00001862 if (reloc->howto == (reloc_howto_type *) NULL)
1863 {
1864 as_bad_where (fixp->fx_file, fixp->fx_line,
Nick Cliftonc6a7ab12000-07-28 00:42:18 +00001865 _("reloc %d not supported by object file format"),
1866 (int) fixp->fx_r_type);
Alan Modraadde6302000-03-27 08:39:14 +00001867 return NULL;
1868 }
1869
1870 if (fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT
1871 || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
1872 reloc->address = fixp->fx_offset;
1873
Alan Modraadde6302000-03-27 08:39:14 +00001874
1875 return reloc;
1876}
1877
Alan Modraadde6302000-03-27 08:39:14 +00001878void
Nick Cliftondc191a82005-10-12 10:56:46 +00001879md_assemble (char *str)
Alan Modraadde6302000-03-27 08:39:14 +00001880{
Nick Cliftonc6a7ab12000-07-28 00:42:18 +00001881 struct avr_opcodes_s *opcode;
Alan Modraadde6302000-03-27 08:39:14 +00001882 char op[11];
1883
Nick Cliftonc6a7ab12000-07-28 00:42:18 +00001884 str = skip_space (extract_word (str, op, sizeof (op)));
Alan Modraadde6302000-03-27 08:39:14 +00001885
1886 if (!op[0])
Nick Clifton00d28652000-07-03 22:25:33 +00001887 as_bad (_("can't find opcode "));
Alan Modraadde6302000-03-27 08:39:14 +00001888
Martin Liska629310a2020-08-18 10:57:21 +02001889 opcode = (struct avr_opcodes_s *) str_hash_find (avr_hash, op);
Alan Modraadde6302000-03-27 08:39:14 +00001890
Barney Stratfordf36e8882014-07-01 10:20:17 +01001891 if (opcode && !avr_opt.all_opcodes)
1892 {
Barney Stratford75f58082014-07-07 16:15:19 +01001893 /* Check if the instruction's ISA bit is ON in the ISA bits of the part
Barney Stratfordf36e8882014-07-01 10:20:17 +01001894 specified by the user. If not look for other instructions
Barney Stratford75f58082014-07-07 16:15:19 +01001895 specifications with same mnemonic who's ISA bits matches.
Barney Stratfordf36e8882014-07-01 10:20:17 +01001896
1897 This requires include/opcode/avr.h to have the instructions with
Nick Clifton33eaf5d2017-01-23 15:23:07 +00001898 same mnemonic to be specified in sequence. */
Barney Stratfordf36e8882014-07-01 10:20:17 +01001899
1900 while ((opcode->isa & avr_mcu->isa) != opcode->isa)
1901 {
1902 opcode++;
Barney Stratford75f58082014-07-07 16:15:19 +01001903
Barney Stratfordf36e8882014-07-01 10:20:17 +01001904 if (opcode->name && strcmp(op, opcode->name))
1905 {
Barney Stratford75f58082014-07-07 16:15:19 +01001906 as_bad (_("illegal opcode %s for mcu %s"),
Barney Stratfordf36e8882014-07-01 10:20:17 +01001907 opcode->name, avr_mcu->name);
1908 return;
1909 }
1910 }
Barney Stratford75f58082014-07-07 16:15:19 +01001911 }
Barney Stratfordf36e8882014-07-01 10:20:17 +01001912
Alan Modraadde6302000-03-27 08:39:14 +00001913 if (opcode == NULL)
1914 {
Nick Clifton00d28652000-07-03 22:25:33 +00001915 as_bad (_("unknown opcode `%s'"), op);
Alan Modraadde6302000-03-27 08:39:14 +00001916 return;
1917 }
1918
Georg-Johann Lay32f76c62017-06-30 16:37:39 +01001919 if (opcode == avr_gccisr_opcode
1920 && !avr_opt.have_gccisr)
1921 {
1922 as_bad (_("pseudo instruction `%s' not supported"), op);
1923 return;
1924 }
1925
Denis Chertykovb170af92000-05-01 08:48:32 +00001926 /* Special case for opcodes with optional operands (lpm, elpm) -
Denis Chertykov1188e082000-06-07 17:42:44 +00001927 version with operands exists in avr_opcodes[] in the next entry. */
Nick Cliftonc6a7ab12000-07-28 00:42:18 +00001928
Denis Chertykov1188e082000-06-07 17:42:44 +00001929 if (*str && *opcode->constraints == '?')
1930 ++opcode;
Denis Chertykovb170af92000-05-01 08:48:32 +00001931
Alan Modrad4f4f3f2009-09-08 10:36:39 +00001932 dwarf2_emit_insn (0);
1933
Alan Modraadde6302000-03-27 08:39:14 +00001934 /* We used to set input_line_pointer to the result of get_operands,
1935 but that is wrong. Our caller assumes we don't change it. */
1936 {
1937 char *t = input_line_pointer;
Nick Cliftondc191a82005-10-12 10:56:46 +00001938
Georg-Johann Lay32f76c62017-06-30 16:37:39 +01001939 if (opcode == avr_gccisr_opcode)
1940 avr_gccisr_operands (opcode, &str);
1941 else
1942 avr_operands (opcode, &str);
Denis Chertykovb170af92000-05-01 08:48:32 +00001943 if (*skip_space (str))
Nick Clifton00d28652000-07-03 22:25:33 +00001944 as_bad (_("garbage at end of line"));
Alan Modraadde6302000-03-27 08:39:14 +00001945 input_line_pointer = t;
1946 }
1947}
1948
Alan Modra62ebcb52014-04-08 14:38:22 +09301949const exp_mod_data_t exp_mod_data[] =
Nick Clifton99700d62012-05-11 12:59:23 +00001950{
1951 /* Default, must be first. */
1952 { "", 0, BFD_RELOC_16, "" },
1953 /* Divides by 2 to get word address. Generate Stub. */
1954 { "gs", 2, BFD_RELOC_AVR_16_PM, "`gs' " },
1955 { "pm", 2, BFD_RELOC_AVR_16_PM, "`pm' " },
1956 /* The following are used together with avr-gcc's __memx address space
1957 in order to initialize a 24-bit pointer variable with a 24-bit address.
Nick Clifton40551fb2012-05-16 14:52:16 +00001958 For address in flash, hlo8 will contain the flash segment if the
1959 symbol is located in flash. If the symbol is located in RAM; hlo8
Nick Clifton99700d62012-05-11 12:59:23 +00001960 will contain 0x80 which matches avr-gcc's notion of how 24-bit RAM/flash
1961 addresses linearize address space. */
1962 { "lo8", 1, BFD_RELOC_AVR_8_LO, "`lo8' " },
1963 { "hi8", 1, BFD_RELOC_AVR_8_HI, "`hi8' " },
Nick Clifton40551fb2012-05-16 14:52:16 +00001964 { "hlo8", 1, BFD_RELOC_AVR_8_HLO, "`hlo8' " },
1965 { "hh8", 1, BFD_RELOC_AVR_8_HLO, "`hh8' " },
Nick Clifton99700d62012-05-11 12:59:23 +00001966};
1967
Nick Clifton99700d62012-05-11 12:59:23 +00001968/* Parse special CONS expression: pm (expression) or alternatively
1969 gs (expression). These are used for addressing program memory. Moreover,
Nick Clifton40551fb2012-05-16 14:52:16 +00001970 define lo8 (expression), hi8 (expression) and hlo8 (expression). */
Nick Cliftonc6a7ab12000-07-28 00:42:18 +00001971
Alan Modra62ebcb52014-04-08 14:38:22 +09301972const exp_mod_data_t *
Nick Cliftondc191a82005-10-12 10:56:46 +00001973avr_parse_cons_expression (expressionS *exp, int nbytes)
Alan Modraadde6302000-03-27 08:39:14 +00001974{
Nick Cliftonc6a7ab12000-07-28 00:42:18 +00001975 char *tmp;
Trevor Saunders814f1482016-05-13 02:51:41 -04001976 unsigned int i;
Alan Modraadde6302000-03-27 08:39:14 +00001977
Alan Modraadde6302000-03-27 08:39:14 +00001978 tmp = input_line_pointer = skip_space (input_line_pointer);
1979
Nick Clifton99700d62012-05-11 12:59:23 +00001980 /* The first entry of exp_mod_data[] contains an entry if no
1981 expression modifier is present. Skip it. */
Kazu Hirata1dab94d2000-09-15 01:06:52 +00001982
Trevor Saunders814f1482016-05-13 02:51:41 -04001983 for (i = 0; i < ARRAY_SIZE (exp_mod_data); i++)
Nick Clifton99700d62012-05-11 12:59:23 +00001984 {
Trevor Saunders814f1482016-05-13 02:51:41 -04001985 const exp_mod_data_t *pexp = &exp_mod_data[i];
Nick Clifton99700d62012-05-11 12:59:23 +00001986 int len = strlen (pexp->name);
1987
1988 if (nbytes == pexp->nbytes
1989 && strncasecmp (input_line_pointer, pexp->name, len) == 0)
Alan Modraadde6302000-03-27 08:39:14 +00001990 {
1991 input_line_pointer = skip_space (input_line_pointer + len);
Kazu Hirata1dab94d2000-09-15 01:06:52 +00001992
Alan Modraadde6302000-03-27 08:39:14 +00001993 if (*input_line_pointer == '(')
1994 {
1995 input_line_pointer = skip_space (input_line_pointer + 1);
Alan Modraadde6302000-03-27 08:39:14 +00001996 expression (exp);
Kazu Hirata1dab94d2000-09-15 01:06:52 +00001997
Alan Modraadde6302000-03-27 08:39:14 +00001998 if (*input_line_pointer == ')')
Alan Modra62ebcb52014-04-08 14:38:22 +09301999 {
2000 ++input_line_pointer;
2001 return pexp;
2002 }
Alan Modraadde6302000-03-27 08:39:14 +00002003 else
2004 {
Nick Clifton00d28652000-07-03 22:25:33 +00002005 as_bad (_("`)' required"));
Alan Modra62ebcb52014-04-08 14:38:22 +09302006 return &exp_mod_data[0];
Alan Modraadde6302000-03-27 08:39:14 +00002007 }
Alan Modraadde6302000-03-27 08:39:14 +00002008 }
Kazu Hirata1dab94d2000-09-15 01:06:52 +00002009
Alan Modraadde6302000-03-27 08:39:14 +00002010 input_line_pointer = tmp;
Nick Clifton99700d62012-05-11 12:59:23 +00002011
2012 break;
Alan Modraadde6302000-03-27 08:39:14 +00002013 }
2014 }
Kazu Hirata1dab94d2000-09-15 01:06:52 +00002015
Alan Modraadde6302000-03-27 08:39:14 +00002016 expression (exp);
Alan Modra62ebcb52014-04-08 14:38:22 +09302017 return &exp_mod_data[0];
Alan Modraadde6302000-03-27 08:39:14 +00002018}
2019
2020void
Nick Cliftondc191a82005-10-12 10:56:46 +00002021avr_cons_fix_new (fragS *frag,
2022 int where,
2023 int nbytes,
Alan Modra62ebcb52014-04-08 14:38:22 +09302024 expressionS *exp,
2025 const exp_mod_data_t *pexp_mod_data)
Alan Modraadde6302000-03-27 08:39:14 +00002026{
Nick Clifton99700d62012-05-11 12:59:23 +00002027 int bad = 0;
2028
2029 switch (pexp_mod_data->reloc)
Alan Modraadde6302000-03-27 08:39:14 +00002030 {
Nick Clifton99700d62012-05-11 12:59:23 +00002031 default:
Nick Clifton17e57232010-02-23 11:38:36 +00002032 if (nbytes == 1)
Alan Modra5b7c81b2021-03-31 10:42:05 +10302033 fix_new_exp (frag, where, nbytes, exp, false, BFD_RELOC_8);
Nick Clifton17e57232010-02-23 11:38:36 +00002034 else if (nbytes == 2)
Alan Modra5b7c81b2021-03-31 10:42:05 +10302035 fix_new_exp (frag, where, nbytes, exp, false, BFD_RELOC_16);
Alan Modraadde6302000-03-27 08:39:14 +00002036 else if (nbytes == 4)
Alan Modra5b7c81b2021-03-31 10:42:05 +10302037 fix_new_exp (frag, where, nbytes, exp, false, BFD_RELOC_32);
Alan Modraadde6302000-03-27 08:39:14 +00002038 else
Nick Clifton99700d62012-05-11 12:59:23 +00002039 bad = 1;
2040 break;
2041
2042 case BFD_RELOC_AVR_16_PM:
2043 case BFD_RELOC_AVR_8_LO:
2044 case BFD_RELOC_AVR_8_HI:
Nick Clifton40551fb2012-05-16 14:52:16 +00002045 case BFD_RELOC_AVR_8_HLO:
Nick Clifton99700d62012-05-11 12:59:23 +00002046 if (nbytes == pexp_mod_data->nbytes)
Alan Modra5b7c81b2021-03-31 10:42:05 +10302047 fix_new_exp (frag, where, nbytes, exp, false, pexp_mod_data->reloc);
Alan Modraadde6302000-03-27 08:39:14 +00002048 else
Nick Clifton99700d62012-05-11 12:59:23 +00002049 bad = 1;
2050 break;
Alan Modraadde6302000-03-27 08:39:14 +00002051 }
Nick Clifton99700d62012-05-11 12:59:23 +00002052
2053 if (bad)
Nick Clifton33eaf5d2017-01-23 15:23:07 +00002054 as_bad (_("illegal %s relocation size: %d"), pexp_mod_data->error, nbytes);
Alan Modraadde6302000-03-27 08:39:14 +00002055}
Richard Hendersonaf3ecb42011-03-29 18:16:16 +00002056
Alan Modra5b7c81b2021-03-31 10:42:05 +10302057static bool
Nick Clifton71863e72013-03-21 14:47:34 +00002058mcu_has_3_byte_pc (void)
2059{
Barney Stratford75f58082014-07-07 16:15:19 +01002060 int mach = avr_mcu->mach;
Nick Clifton71863e72013-03-21 14:47:34 +00002061
Barney Stratford75f58082014-07-07 16:15:19 +01002062 return mach == bfd_mach_avr6
2063 || mach == bfd_mach_avrxmega6
Nick Clifton71863e72013-03-21 14:47:34 +00002064 || mach == bfd_mach_avrxmega7;
2065}
2066
Richard Hendersonaf3ecb42011-03-29 18:16:16 +00002067void
2068tc_cfi_frame_initial_instructions (void)
2069{
2070 /* AVR6 pushes 3 bytes for calls. */
Nick Clifton71863e72013-03-21 14:47:34 +00002071 int return_size = (mcu_has_3_byte_pc () ? 3 : 2);
Richard Hendersonaf3ecb42011-03-29 18:16:16 +00002072
2073 /* The CFA is the caller's stack location before the call insn. */
2074 /* Note that the stack pointer is dwarf register number 32. */
2075 cfi_add_CFA_def_cfa (32, return_size);
2076
2077 /* Note that AVR consistently uses post-decrement, which means that things
Nick Clifton33eaf5d2017-01-23 15:23:07 +00002078 do not line up the same way as for targets that use pre-decrement. */
Richard Hendersonaf3ecb42011-03-29 18:16:16 +00002079 cfi_add_CFA_offset (DWARF2_DEFAULT_RETURN_COLUMN, 1-return_size);
2080}
Denis Chertykove4ef1b62014-04-10 19:50:33 +04002081
Alan Modra5b7c81b2021-03-31 10:42:05 +10302082bool
Denis Chertykove4ef1b62014-04-10 19:50:33 +04002083avr_allow_local_subtract (expressionS * left,
2084 expressionS * right,
2085 segT section)
2086{
Barney Stratford75f58082014-07-07 16:15:19 +01002087 /* If we are not in relaxation mode, subtraction is OK. */
Denis Chertykove4ef1b62014-04-10 19:50:33 +04002088 if (!linkrelax)
Alan Modra5b7c81b2021-03-31 10:42:05 +10302089 return true;
Denis Chertykove4ef1b62014-04-10 19:50:33 +04002090
2091 /* If the symbols are not in a code section then they are OK. */
2092 if ((section->flags & SEC_CODE) == 0)
Alan Modra5b7c81b2021-03-31 10:42:05 +10302093 return true;
Denis Chertykove4ef1b62014-04-10 19:50:33 +04002094
2095 if (left->X_add_symbol == right->X_add_symbol)
Alan Modra5b7c81b2021-03-31 10:42:05 +10302096 return true;
Denis Chertykove4ef1b62014-04-10 19:50:33 +04002097
2098 /* We have to assume that there may be instructions between the
2099 two symbols and that relaxation may increase the distance between
2100 them. */
Alan Modra5b7c81b2021-03-31 10:42:05 +10302101 return false;
Denis Chertykove4ef1b62014-04-10 19:50:33 +04002102}
Andrew Burgesseac74402014-11-22 23:19:31 +00002103
2104void
2105avr_elf_final_processing (void)
2106{
2107 if (linkrelax)
2108 elf_elfheader (stdoutput)->e_flags |= EF_AVR_LINKRELAX_PREPARED;
2109}
Andrew Burgessfdd410a2015-01-08 20:55:10 +00002110
2111/* Write out the header of a .avr.prop section into the area pointed to by
2112 DATA. The RECORD_COUNT will be placed in the header as the number of
2113 records that are to follow.
2114 The area DATA must be big enough the receive the header, which is
2115 AVR_PROPERTY_SECTION_HEADER_SIZE bytes long. */
2116
2117static char *
2118avr_output_property_section_header (char *data,
2119 unsigned int record_count)
2120{
2121 char *orig_data = data;
2122
2123 md_number_to_chars (data, AVR_PROPERTY_RECORDS_VERSION, 1);
2124 data++;
2125 /* There's space for a single byte flags field, but right now there's
2126 nothing to go in here, so just set the value to zero. */
2127 md_number_to_chars (data, 0, 1);
2128 data++;
2129 md_number_to_chars (data, record_count, 2);
2130 data+=2;
2131
2132 gas_assert (data - orig_data == AVR_PROPERTY_SECTION_HEADER_SIZE);
2133
2134 return data;
2135}
2136
2137/* Return the number of bytes required to store RECORD into the .avr.prop
2138 section. The size returned is the compressed size that corresponds to
2139 how the record will be written out in AVR_OUTPUT_PROPERTY_RECORD. */
2140
2141static int
2142avr_record_size (const struct avr_property_record *record)
2143{
2144 /* The first 5 bytes are a 4-byte address, followed by a 1-byte type
2145 identifier. */
2146 int size = 5;
2147
2148 switch (record->type)
2149 {
2150 case RECORD_ORG:
2151 size += 0; /* No extra information. */
2152 break;
2153
2154 case RECORD_ORG_AND_FILL:
2155 size += 4; /* A 4-byte fill value. */
2156 break;
2157
2158 case RECORD_ALIGN:
2159 size += 4; /* A 4-byte alignment value. */
2160 break;
2161
2162 case RECORD_ALIGN_AND_FILL:
2163 size += 8; /* A 4-byte alignment, and 4-byte fill value. */
2164 break;
2165
2166 default:
2167 as_fatal (_("unknown record type %d (in %s)"),
2168 record->type, __PRETTY_FUNCTION__);
2169 }
2170
2171 return size;
2172}
2173
2174/* Write out RECORD. FRAG_BASE points to the start of the data area setup
2175 to hold all of the .avr.prop content, FRAG_PTR points to the next
2176 writable location. The data area must be big enough to hold all of the
2177 records. The size of the data written out for this RECORD must match
2178 the size from AVR_RECORD_SIZE. */
2179
2180static char *
2181avr_output_property_record (char * const frag_base, char *frag_ptr,
2182 const struct avr_property_record *record)
2183{
2184 fixS *fix;
2185 int where;
2186 char *init_frag_ptr = frag_ptr;
2187
2188 where = frag_ptr - frag_base;
2189 fix = fix_new (frag_now, where, 4,
2190 section_symbol (record->section),
Alan Modra5b7c81b2021-03-31 10:42:05 +10302191 record->offset, false, BFD_RELOC_32);
Andrew Burgessfdd410a2015-01-08 20:55:10 +00002192 fix->fx_file = "<internal>";
2193 fix->fx_line = 0;
2194 frag_ptr += 4;
2195
2196 md_number_to_chars (frag_ptr, (bfd_byte) record->type, 1);
2197 frag_ptr += 1;
2198
2199 /* Write out the rest of the data. */
2200 switch (record->type)
2201 {
2202 case RECORD_ORG:
2203 break;
2204
2205 case RECORD_ORG_AND_FILL:
2206 md_number_to_chars (frag_ptr, record->data.org.fill, 4);
2207 frag_ptr += 4;
2208 break;
2209
2210 case RECORD_ALIGN:
2211 md_number_to_chars (frag_ptr, record->data.align.bytes, 4);
2212 frag_ptr += 4;
2213 break;
2214
2215 case RECORD_ALIGN_AND_FILL:
2216 md_number_to_chars (frag_ptr, record->data.align.bytes, 4);
Andrew Burgess431ff072015-10-07 20:47:38 +01002217 md_number_to_chars (frag_ptr + 4, record->data.align.fill, 4);
Andrew Burgessfdd410a2015-01-08 20:55:10 +00002218 frag_ptr += 8;
2219 break;
2220
2221 default:
2222 as_fatal (_("unknown record type %d (in %s)"),
2223 record->type, __PRETTY_FUNCTION__);
2224 }
2225
2226 gas_assert (frag_ptr - init_frag_ptr == avr_record_size (record));
2227
2228 return frag_ptr;
2229}
2230
2231/* Create the section to hold the AVR property information. Return the
2232 section. */
2233
2234static asection *
2235avr_create_property_section (void)
2236{
2237 asection *sec;
2238 flagword flags = (SEC_RELOC | SEC_HAS_CONTENTS | SEC_READONLY);
2239 const char *section_name = AVR_PROPERTY_RECORD_SECTION_NAME;
2240
2241 sec = bfd_make_section (stdoutput, section_name);
2242 if (sec == NULL)
2243 as_fatal (_("Failed to create property section `%s'\n"), section_name);
Alan Modrafd361982019-09-16 20:25:17 +09302244 bfd_set_section_flags (sec, flags);
Andrew Burgessfdd410a2015-01-08 20:55:10 +00002245 sec->output_section = sec;
2246 return sec;
2247}
2248
2249/* This hook is called when alignment is performed, and allows us to
2250 capture the details of both .org and .align directives. */
2251
2252void
2253avr_handle_align (fragS *fragP)
2254{
2255 if (linkrelax)
2256 {
2257 /* Ignore alignment requests at FR_ADDRESS 0, these are at the very
2258 start of a section, and will be handled by the standard section
2259 alignment mechanism. */
2260 if ((fragP->fr_type == rs_align
2261 || fragP->fr_type == rs_align_code)
Andrew Burgessfdd410a2015-01-08 20:55:10 +00002262 && fragP->fr_offset > 0)
2263 {
Andrew Burgess431ff072015-10-07 20:47:38 +01002264 char *p = fragP->fr_literal + fragP->fr_fix;
2265
Alan Modra5b7c81b2021-03-31 10:42:05 +10302266 fragP->tc_frag_data.is_align = true;
Andrew Burgessfdd410a2015-01-08 20:55:10 +00002267 fragP->tc_frag_data.alignment = fragP->fr_offset;
Andrew Burgess431ff072015-10-07 20:47:38 +01002268 fragP->tc_frag_data.fill = *p;
2269 fragP->tc_frag_data.has_fill = (fragP->tc_frag_data.fill != 0);
Andrew Burgessfdd410a2015-01-08 20:55:10 +00002270 }
2271
2272 if (fragP->fr_type == rs_org && fragP->fr_offset > 0)
2273 {
2274 char *p = fragP->fr_literal + fragP->fr_fix;
2275
Alan Modra5b7c81b2021-03-31 10:42:05 +10302276 fragP->tc_frag_data.is_org = true;
Andrew Burgessfdd410a2015-01-08 20:55:10 +00002277 fragP->tc_frag_data.fill = *p;
2278 fragP->tc_frag_data.has_fill = (fragP->tc_frag_data.fill != 0);
2279 }
2280 }
2281}
2282
2283/* Return TRUE if this section is not one for which we need to record
2284 information in the avr property section. */
2285
Alan Modra5b7c81b2021-03-31 10:42:05 +10302286static bool
Andrew Burgessfdd410a2015-01-08 20:55:10 +00002287exclude_section_from_property_tables (segT sec)
2288{
2289 /* Only generate property information for sections on which linker
2290 relaxation could be performed. */
2291 return !relaxable_section (sec);
2292}
2293
2294/* Create a property record for fragment FRAGP from section SEC and place
2295 it into an AVR_PROPERTY_RECORD_LINK structure, which can then formed
2296 into a linked list by the caller. */
2297
2298static struct avr_property_record_link *
2299create_record_for_frag (segT sec, fragS *fragP)
2300{
Senthil Kumar Selvarajef7a9362015-04-17 20:55:54 +09302301 struct avr_property_record_link *prop_rec_link;
Andrew Burgessfdd410a2015-01-08 20:55:10 +00002302
Trevor Saunders325801b2016-04-01 09:26:30 -04002303 prop_rec_link = XCNEW (struct avr_property_record_link);
Andrew Burgess431ff072015-10-07 20:47:38 +01002304 gas_assert (fragP->fr_next != NULL);
Andrew Burgessfdd410a2015-01-08 20:55:10 +00002305
2306 if (fragP->tc_frag_data.is_org)
2307 {
Senthil Kumar Selvarajef7a9362015-04-17 20:55:54 +09302308 prop_rec_link->record.offset = fragP->fr_next->fr_address;
2309 prop_rec_link->record.section = sec;
Andrew Burgessfdd410a2015-01-08 20:55:10 +00002310
2311 if (fragP->tc_frag_data.has_fill)
2312 {
Senthil Kumar Selvarajef7a9362015-04-17 20:55:54 +09302313 prop_rec_link->record.data.org.fill = fragP->tc_frag_data.fill;
2314 prop_rec_link->record.type = RECORD_ORG_AND_FILL;
Andrew Burgessfdd410a2015-01-08 20:55:10 +00002315 }
2316 else
Senthil Kumar Selvarajef7a9362015-04-17 20:55:54 +09302317 prop_rec_link->record.type = RECORD_ORG;
Andrew Burgessfdd410a2015-01-08 20:55:10 +00002318 }
2319 else
2320 {
Andrew Burgess431ff072015-10-07 20:47:38 +01002321 prop_rec_link->record.offset = fragP->fr_next->fr_address;
Senthil Kumar Selvarajef7a9362015-04-17 20:55:54 +09302322 prop_rec_link->record.section = sec;
Andrew Burgessfdd410a2015-01-08 20:55:10 +00002323
2324 gas_assert (fragP->tc_frag_data.is_align);
2325 if (fragP->tc_frag_data.has_fill)
2326 {
Senthil Kumar Selvarajef7a9362015-04-17 20:55:54 +09302327 prop_rec_link->record.data.align.fill = fragP->tc_frag_data.fill;
2328 prop_rec_link->record.type = RECORD_ALIGN_AND_FILL;
Andrew Burgessfdd410a2015-01-08 20:55:10 +00002329 }
2330 else
Senthil Kumar Selvarajef7a9362015-04-17 20:55:54 +09302331 prop_rec_link->record.type = RECORD_ALIGN;
2332 prop_rec_link->record.data.align.bytes = fragP->tc_frag_data.alignment;
Andrew Burgessfdd410a2015-01-08 20:55:10 +00002333 }
2334
Senthil Kumar Selvarajef7a9362015-04-17 20:55:54 +09302335 return prop_rec_link;
Andrew Burgessfdd410a2015-01-08 20:55:10 +00002336}
2337
2338/* Build a list of AVR_PROPERTY_RECORD_LINK structures for section SEC, and
2339 merged them onto the list pointed to by NEXT_PTR. Return a pointer to
2340 the last list item created. */
2341
2342static struct avr_property_record_link **
2343append_records_for_section (segT sec,
2344 struct avr_property_record_link **next_ptr)
2345{
2346 segment_info_type *seginfo = seg_info (sec);
2347 fragS *fragP;
2348
2349 if (seginfo && seginfo->frchainP)
2350 {
2351 for (fragP = seginfo->frchainP->frch_root;
2352 fragP;
2353 fragP = fragP->fr_next)
2354 {
2355 if (fragP->tc_frag_data.is_align
2356 || fragP->tc_frag_data.is_org)
2357 {
2358 /* Create a single new entry. */
2359 struct avr_property_record_link *new_link
2360 = create_record_for_frag (sec, fragP);
2361
2362 *next_ptr = new_link;
2363 next_ptr = &new_link->next;
2364 }
2365 }
2366 }
2367
2368 return next_ptr;
2369}
2370
2371/* Create the AVR property section and fill it with records of .org and
2372 .align directives that were used. The section is only created if it
2373 will actually have any content. */
2374
2375static void
2376avr_create_and_fill_property_section (void)
2377{
2378 segT *seclist;
2379 asection *prop_sec;
2380 struct avr_property_record_link *r_list, **next_ptr;
2381 char *frag_ptr, *frag_base;
2382 bfd_size_type sec_size;
2383 struct avr_property_record_link *rec;
2384 unsigned int record_count;
2385
2386 /* First walk over all sections. For sections on which linker
2387 relaxation could be applied, extend the record list. The record list
2388 holds information that the linker will need to know. */
2389
2390 prop_sec = NULL;
2391 r_list = NULL;
2392 next_ptr = &r_list;
2393 for (seclist = &stdoutput->sections;
2394 seclist && *seclist;
2395 seclist = &(*seclist)->next)
2396 {
2397 segT sec = *seclist;
2398
2399 if (exclude_section_from_property_tables (sec))
2400 continue;
2401
2402 next_ptr = append_records_for_section (sec, next_ptr);
2403 }
2404
2405 /* Create property section and ensure the size is correct. We've already
2406 passed the point where gas could size this for us. */
2407 sec_size = AVR_PROPERTY_SECTION_HEADER_SIZE;
2408 record_count = 0;
2409 for (rec = r_list; rec != NULL; rec = rec->next)
2410 {
2411 record_count++;
2412 sec_size += avr_record_size (&rec->record);
2413 }
2414
2415 if (record_count == 0)
2416 return;
2417
2418 prop_sec = avr_create_property_section ();
Alan Modrafd361982019-09-16 20:25:17 +09302419 bfd_set_section_size (prop_sec, sec_size);
Andrew Burgessfdd410a2015-01-08 20:55:10 +00002420
2421 subseg_set (prop_sec, 0);
2422 frag_base = frag_more (sec_size);
2423
2424 frag_ptr =
2425 avr_output_property_section_header (frag_base, record_count);
2426
2427 for (rec = r_list; rec != NULL; rec = rec->next)
2428 frag_ptr = avr_output_property_record (frag_base, frag_ptr, &rec->record);
2429
2430 frag_wane (frag_now);
2431 frag_new (0);
2432 frag_wane (frag_now);
2433}
2434
2435/* We're using this hook to build up the AVR property section. It's called
2436 late in the assembly process which suits our needs. */
2437void
2438avr_post_relax_hook (void)
2439{
2440 avr_create_and_fill_property_section ();
2441}
Georg-Johann Lay32f76c62017-06-30 16:37:39 +01002442
2443
2444/* Accumulate information about instruction sequence to `avr_isr':
2445 wheter TMP_REG, ZERO_REG and SREG might be touched. Used during parse.
2446 REG1 is either -1 or a register number used by the instruction as input
2447 or output operand. Similar for REG2. */
2448
2449static void
2450avr_update_gccisr (struct avr_opcodes_s *opcode, int reg1, int reg2)
2451{
2452 const int tiny_p = avr_mcu->mach == bfd_mach_avrtiny;
2453 const int reg_tmp = tiny_p ? 16 : 0;
2454 const int reg_zero = 1 + reg_tmp;
2455
2456 if (ISR_CHUNK_Done == avr_isr.prev_chunk
2457 || (avr_isr.need_sreg
2458 && avr_isr.need_reg_tmp
2459 && avr_isr.need_reg_zero))
2460 {
2461 /* Nothing (more) to do */
2462 return;
2463 }
2464
2465 /* SREG: Look up instructions that don't clobber SREG. */
2466
2467 if (!avr_isr.need_sreg
Martin Liska629310a2020-08-18 10:57:21 +02002468 && !str_hash_find (avr_no_sreg_hash, opcode->name))
Georg-Johann Lay32f76c62017-06-30 16:37:39 +01002469 {
2470 avr_isr.need_sreg = 1;
2471 }
2472
2473 /* Handle explicit register operands. Record *any* use as clobber.
2474 This is because TMP_REG and ZERO_REG are not global and using
2475 them makes no sense without a previous set. */
2476
2477 avr_isr.need_reg_tmp |= reg1 == reg_tmp || reg2 == reg_tmp;
2478 avr_isr.need_reg_zero |= reg1 == reg_zero || reg2 == reg_zero;
2479
2480 /* Handle implicit register operands and some opaque stuff. */
2481
2482 if (strstr (opcode->name, "lpm")
2483 && '?' == *opcode->constraints)
2484 {
2485 avr_isr.need_reg_tmp = 1;
2486 }
2487
2488 if (strstr (opcode->name, "call")
2489 || strstr (opcode->name, "mul")
2490 || 0 == strcmp (opcode->name, "des")
2491 || (0 == strcmp (opcode->name, "movw")
2492 && (reg1 == reg_tmp || reg2 == reg_tmp)))
2493 {
2494 avr_isr.need_reg_tmp = 1;
2495 avr_isr.need_reg_zero = 1;
2496 }
2497}
2498
2499
2500/* Emit some 1-word instruction to **PWHERE and advance *PWHERE by the number
2501 of octets written. INSN specifies the desired instruction and REG is the
2502 register used by it. This function is only used with restricted subset of
2503 instructions as might be emit by `__gcc_isr'. IN / OUT will use SREG
2504 and LDI loads 0. */
2505
2506static void
2507avr_emit_insn (const char *insn, int reg, char **pwhere)
2508{
2509 const int sreg = 0x3f;
2510 unsigned bin = 0;
2511 const struct avr_opcodes_s *op
Martin Liska629310a2020-08-18 10:57:21 +02002512 = (struct avr_opcodes_s*) str_hash_find (avr_hash, insn);
Georg-Johann Lay32f76c62017-06-30 16:37:39 +01002513
2514 /* We only have to deal with: IN, OUT, PUSH, POP, CLR, LDI 0. All of
2515 these deal with at least one Reg and are 1-word instructions. */
2516
2517 gas_assert (op && 1 == op->insn_size);
2518 gas_assert (reg >= 0 && reg <= 31);
2519
2520 if (strchr (op->constraints, 'r'))
2521 {
2522 bin = op->bin_opcode | (reg << 4);
2523 }
2524 else if (strchr (op->constraints, 'd'))
2525 {
2526 gas_assert (reg >= 16);
2527 bin = op->bin_opcode | ((reg & 0xf) << 4);
2528 }
2529 else
2530 abort();
2531
2532 if (strchr (op->constraints, 'P'))
2533 {
2534 bin |= ((sreg & 0x30) << 5) | (sreg & 0x0f);
2535 }
2536 else if (0 == strcmp ("r=r", op->constraints))
2537 {
2538 bin |= ((reg & 0x10) << 5) | (reg & 0x0f);
2539 }
2540 else
2541 gas_assert (0 == strcmp ("r", op->constraints)
2542 || 0 == strcmp ("ldi", op->name));
2543
2544 bfd_putl16 ((bfd_vma) bin, *pwhere);
2545 (*pwhere) += 2 * op->insn_size;
2546}
2547
2548
2549/* Turn rs_machine_dependent frag *FR into an ordinary rs_fill code frag,
2550 using information gathered in `avr_isr'. REG is the register number as
2551 supplied by Done chunk "__gcc_isr 0,REG". */
2552
2553static void
2554avr_patch_gccisr_frag (fragS *fr, int reg)
2555{
2556 int treg;
2557 int n_pushed = 0;
2558 char *where = fr->fr_literal;
2559 const int tiny_p = avr_mcu->mach == bfd_mach_avrtiny;
2560 const int reg_tmp = tiny_p ? 16 : 0;
2561 const int reg_zero = 1 + reg_tmp;
2562
2563 /* Clearing ZERO_REG on non-Tiny needs CLR which clobbers SREG. */
2564
2565 avr_isr.need_sreg |= !tiny_p && avr_isr.need_reg_zero;
2566
2567 /* A working register to PUSH / POP the SREG. We might use the register
2568 as supplied by ISR_CHUNK_Done for that purpose as GCC wants to push
2569 it anyways. If GCC passes ZERO_REG or TMP_REG, it has no clue (and
2570 no additional regs to safe) and we use that reg. */
2571
2572 treg
2573 = avr_isr.need_reg_tmp ? reg_tmp
2574 : avr_isr.need_reg_zero ? reg_zero
2575 : avr_isr.need_sreg ? reg
2576 : reg > reg_zero ? reg
2577 : -1;
2578
2579 if (treg >= 0)
2580 {
2581 /* Non-empty prologue / epilogue */
2582
2583 if (ISR_CHUNK_Prologue == fr->fr_subtype)
2584 {
2585 avr_emit_insn ("push", treg, &where);
2586 n_pushed++;
2587
2588 if (avr_isr.need_sreg)
2589 {
2590 avr_emit_insn ("in", treg, &where);
2591 avr_emit_insn ("push", treg, &where);
2592 n_pushed++;
2593 }
2594
2595 if (avr_isr.need_reg_zero)
2596 {
2597 if (reg_zero != treg)
2598 {
2599 avr_emit_insn ("push", reg_zero, &where);
2600 n_pushed++;
2601 }
2602 avr_emit_insn (tiny_p ? "ldi" : "clr", reg_zero, &where);
2603 }
2604
2605 if (reg > reg_zero && reg != treg)
2606 {
2607 avr_emit_insn ("push", reg, &where);
2608 n_pushed++;
2609 }
2610 }
2611 else if (ISR_CHUNK_Epilogue == fr->fr_subtype)
2612 {
2613 /* Same logic as in Prologue but in reverse order and with counter
2614 parts of either instruction: POP instead of PUSH and OUT instead
2615 of IN. Clearing ZERO_REG has no couter part. */
2616
2617 if (reg > reg_zero && reg != treg)
2618 avr_emit_insn ("pop", reg, &where);
2619
2620 if (avr_isr.need_reg_zero
2621 && reg_zero != treg)
2622 avr_emit_insn ("pop", reg_zero, &where);
2623
2624 if (avr_isr.need_sreg)
2625 {
2626 avr_emit_insn ("pop", treg, &where);
2627 avr_emit_insn ("out", treg, &where);
2628 }
2629
2630 avr_emit_insn ("pop", treg, &where);
2631 }
2632 else
2633 abort();
2634 } /* treg >= 0 */
2635
2636 if (ISR_CHUNK_Prologue == fr->fr_subtype
2637 && avr_isr.sym_n_pushed)
2638 {
2639 symbolS *sy = avr_isr.sym_n_pushed;
2640 /* Turn magic `__gcc_isr.n_pushed' into its now known value. */
2641
Alan Modra8d1015a2018-10-29 16:37:24 +10302642 S_SET_VALUE (sy, n_pushed);
Georg-Johann Lay32f76c62017-06-30 16:37:39 +01002643 S_SET_SEGMENT (sy, expr_section);
2644 avr_isr.sym_n_pushed = NULL;
2645 }
2646
2647 /* Turn frag into ordinary code frag of now known size. */
2648
2649 fr->fr_var = 0;
Alan Modra871a6bd2019-04-15 21:51:44 +09302650 fr->fr_fix = where - fr->fr_literal;
2651 gas_assert (fr->fr_fix <= (valueT) fr->fr_offset);
Georg-Johann Lay32f76c62017-06-30 16:37:39 +01002652 fr->fr_offset = 0;
2653 fr->fr_type = rs_fill;
2654 fr->fr_subtype = 0;
2655}
2656
2657
2658/* Implements `__gcc_isr' pseudo-instruction. For Prologue and Epilogue
2659 chunks, emit a new rs_machine_dependent frag. For Done chunks, traverse
2660 the current segment and patch all rs_machine_dependent frags to become
2661 appropriate rs_fill code frags. If chunks are seen in an odd ordering,
2662 throw an error instead. */
2663
2664static void
2665avr_gccisr_operands (struct avr_opcodes_s *opcode, char **line)
2666{
2667 int bad = 0;
2668 int chunk, reg = 0;
2669 char *str = *line;
2670
2671 gas_assert (avr_opt.have_gccisr);
2672
2673 /* We only use operands "N" and "r" which don't pop new fix-ups. */
2674
2675 /* 1st operand: Which chunk of __gcc_isr: 0...2. */
2676
2677 chunk = avr_operand (opcode, -1, "N", &str, NULL);
2678 if (chunk < 0 || chunk > 2)
2679 as_bad (_("%s requires value 0-2 as operand 1"), opcode->name);
2680
2681 if (ISR_CHUNK_Done == chunk)
2682 {
2683 /* 2nd operand: A register to push / pop. */
2684
2685 str = skip_space (str);
2686 if (*str == '\0' || *str++ != ',')
2687 as_bad (_("`,' required"));
2688 else
2689 avr_operand (opcode, -1, "r", &str, &reg);
2690 }
2691
2692 *line = str;
2693
2694 /* Chunks must follow in a specific order:
2695 - Prologue: Exactly one
2696 - Epilogue: Any number
2697 - Done: Exactly one. */
2698 bad |= ISR_CHUNK_Prologue == chunk && avr_isr.prev_chunk != ISR_CHUNK_Done;
2699 bad |= ISR_CHUNK_Epilogue == chunk && avr_isr.prev_chunk == ISR_CHUNK_Done;
2700 bad |= ISR_CHUNK_Done == chunk && avr_isr.prev_chunk == ISR_CHUNK_Done;
2701 if (bad)
2702 {
2703 if (avr_isr.file)
2704 as_bad (_("`%s %d' after `%s %d' from %s:%u"), opcode->name, chunk,
2705 opcode->name, avr_isr.prev_chunk, avr_isr.file, avr_isr.line);
2706 else
2707 as_bad (_("`%s %d' but no chunk open yet"), opcode->name, chunk);
2708 }
2709
2710 if (!had_errors())
2711 {
2712 /* The longest sequence (prologue) might have up to 6 insns (words):
2713
2714 push R0
2715 in R0, SREG
2716 push R0
2717 push R1
2718 clr R1
2719 push Rx
2720 */
2721 unsigned int size = 2 * 6;
2722 fragS *fr;
2723
2724 switch (chunk)
2725 {
2726 case ISR_CHUNK_Prologue:
2727 avr_isr.need_reg_tmp = 0;
2728 avr_isr.need_reg_zero = 0;
2729 avr_isr.need_sreg = 0;
2730 avr_isr.sym_n_pushed = NULL;
2731 /* FALLTHRU */
2732
2733 case ISR_CHUNK_Epilogue:
2734 /* Emit a new rs_machine_dependent fragment into the fragment chain.
2735 It will be patched and cleaned up once we see the matching
2736 ISR_CHUNK_Done. */
2737 frag_wane (frag_now);
2738 frag_new (0);
2739 frag_more (size);
2740
2741 frag_now->fr_var = 1;
2742 frag_now->fr_offset = size;
2743 frag_now->fr_fix = 0;
2744 frag_now->fr_type = rs_machine_dependent;
2745 frag_now->fr_subtype = chunk;
2746 frag_new (size);
2747 break;
2748
2749 case ISR_CHUNK_Done:
2750 /* Traverse all frags of the current subseg and turn ones of type
2751 rs_machine_dependent into ordinary code as expected by GCC. */
2752
2753 for (fr = frchain_now->frch_root; fr; fr = fr->fr_next)
2754 if (fr->fr_type == rs_machine_dependent)
2755 avr_patch_gccisr_frag (fr, reg);
2756 break;
2757
2758 default:
2759 abort();
2760 break;
2761 }
2762 } /* !had_errors */
2763
2764 avr_isr.prev_chunk = chunk;
2765 avr_isr.file = as_where (&avr_isr.line);
2766}
2767
2768
2769/* Callback used by the function below. Diagnose any dangling stuff from
2770 `__gcc_isr', i.e. frags of type rs_machine_dependent. Such frags should
2771 have been resolved during parse by ISR_CHUNK_Done. If such a frag is
2772 seen, report an error and turn it into something harmless. */
2773
2774static void
2775avr_check_gccisr_done (bfd *abfd ATTRIBUTE_UNUSED,
2776 segT section,
2777 void *xxx ATTRIBUTE_UNUSED)
2778{
2779 segment_info_type *info = seg_info (section);
2780
2781 if (SEG_NORMAL (section)
2782 /* BFD may have introduced its own sections without using
2783 subseg_new, so it is possible that seg_info is NULL. */
2784 && info)
2785 {
2786 fragS *fr;
2787 frchainS *frch;
2788
2789 for (frch = info->frchainP; frch; frch = frch->frch_next)
2790 for (fr = frch->frch_root; fr; fr = fr->fr_next)
2791 if (fr->fr_type == rs_machine_dependent)
2792 {
2793 if (avr_isr.file)
2794 as_bad_where (avr_isr.file, avr_isr.line,
2795 _("dangling `__gcc_isr %d'"), avr_isr.prev_chunk);
2796 else if (!had_errors())
2797 as_bad (_("dangling `__gcc_isr'"));
2798
2799 avr_isr.file = NULL;
2800
2801 /* Avoid Internal errors due to rs_machine_dependent in the
2802 remainder: Turn frag into something harmless. */
2803 fr->fr_var = 0;
2804 fr->fr_fix = 0;
2805 fr->fr_offset = 0;
2806 fr->fr_type = rs_fill;
2807 fr->fr_subtype = 0;
2808 }
2809 }
2810}
2811
2812
2813/* Implement `md_pre_output_hook' */
2814/* Run over all relevant sections and diagnose any dangling `__gcc_isr'.
2815 This runs after parsing all inputs but before relaxing and writing. */
2816
2817void
2818avr_pre_output_hook (void)
2819{
2820 if (avr_opt.have_gccisr)
2821 bfd_map_over_sections (stdoutput, avr_check_gccisr_done, NULL);
2822}
Nick Cliftonf3be70d2021-12-16 16:40:57 +00002823
2824/* Return false if the fixup in fixp should be left alone and not
2825 adjusted. */
2826
2827bool
2828avr_fix_adjustable (struct fix *fixp)
2829{
2830 if (! linkrelax || fixp->fx_addsy == NULL)
2831 return true;
2832
2833 /* Do not adjust relocations involving symbols in code sections,
2834 because it breaks linker relaxations. This could be fixed in the
2835 linker, but this fix is simpler, and it pretty much only affects
2836 object size a little bit. */
2837 if (S_GET_SEGMENT (fixp->fx_addsy)->flags & SEC_CODE)
2838 return false;
2839
2840 /* Likewise, do not adjust symbols that won't be merged, or debug
2841 symbols, because they too break relaxation. We do want to adjust
2842 other mergeable symbols, like .rodata, because code relaxations
2843 need section-relative symbols to properly relax them. */
2844 if (! (S_GET_SEGMENT (fixp->fx_addsy)->flags & SEC_MERGE))
2845 return false;
2846
2847 return true;
2848}