tc-mt.c revision 1.1 1 1.1 skrll /* tc-mt.c -- Assembler for the Morpho Technologies mt .
2 1.1 skrll Copyright (C) 2005, 2006, 2007 Free Software Foundation.
3 1.1 skrll
4 1.1 skrll This file is part of GAS, the GNU Assembler.
5 1.1 skrll
6 1.1 skrll GAS is free software; you can redistribute it and/or modify
7 1.1 skrll it under the terms of the GNU General Public License as published by
8 1.1 skrll the Free Software Foundation; either version 3, or (at your option)
9 1.1 skrll any later version.
10 1.1 skrll
11 1.1 skrll GAS is distributed in the hope that it will be useful,
12 1.1 skrll but WITHOUT ANY WARRANTY; without even the implied warranty of
13 1.1 skrll MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 1.1 skrll GNU General Public License for more details.
15 1.1 skrll
16 1.1 skrll You should have received a copy of the GNU General Public License
17 1.1 skrll along with GAS; see the file COPYING. If not, write to
18 1.1 skrll the Free Software Foundation, 59 Temple Place - Suite 330,
19 1.1 skrll Boston, MA 02111-1307, USA. */
20 1.1 skrll
21 1.1 skrll #include "as.h"
22 1.1 skrll #include "dwarf2dbg.h"
23 1.1 skrll #include "subsegs.h"
24 1.1 skrll #include "symcat.h"
25 1.1 skrll #include "opcodes/mt-desc.h"
26 1.1 skrll #include "opcodes/mt-opc.h"
27 1.1 skrll #include "cgen.h"
28 1.1 skrll #include "elf/common.h"
29 1.1 skrll #include "elf/mt.h"
30 1.1 skrll #include "libbfd.h"
31 1.1 skrll
32 1.1 skrll /* Structure to hold all of the different components
33 1.1 skrll describing an individual instruction. */
34 1.1 skrll typedef struct
35 1.1 skrll {
36 1.1 skrll const CGEN_INSN * insn;
37 1.1 skrll const CGEN_INSN * orig_insn;
38 1.1 skrll CGEN_FIELDS fields;
39 1.1 skrll #if CGEN_INT_INSN_P
40 1.1 skrll CGEN_INSN_INT buffer [1];
41 1.1 skrll #define INSN_VALUE(buf) (*(buf))
42 1.1 skrll #else
43 1.1 skrll unsigned char buffer [CGEN_MAX_INSN_SIZE];
44 1.1 skrll #define INSN_VALUE(buf) (buf)
45 1.1 skrll #endif
46 1.1 skrll char * addr;
47 1.1 skrll fragS * frag;
48 1.1 skrll int num_fixups;
49 1.1 skrll fixS * fixups [GAS_CGEN_MAX_FIXUPS];
50 1.1 skrll int indices [MAX_OPERAND_INSTANCES];
51 1.1 skrll }
52 1.1 skrll mt_insn;
53 1.1 skrll
54 1.1 skrll
55 1.1 skrll const char comment_chars[] = ";";
56 1.1 skrll const char line_comment_chars[] = "#";
57 1.1 skrll const char line_separator_chars[] = "";
58 1.1 skrll const char EXP_CHARS[] = "eE";
59 1.1 skrll const char FLT_CHARS[] = "dD";
60 1.1 skrll
61 1.1 skrll /* The target specific pseudo-ops which we support. */
62 1.1 skrll const pseudo_typeS md_pseudo_table[] =
63 1.1 skrll {
64 1.1 skrll { "word", cons, 4 },
65 1.1 skrll { NULL, NULL, 0 }
66 1.1 skrll };
67 1.1 skrll
68 1.1 skrll
69 1.1 skrll
71 1.1 skrll static int no_scheduling_restrictions = 0;
72 1.1 skrll
73 1.1 skrll struct option md_longopts[] =
74 1.1 skrll {
75 1.1 skrll #define OPTION_NO_SCHED_REST (OPTION_MD_BASE)
76 1.1 skrll { "nosched", no_argument, NULL, OPTION_NO_SCHED_REST },
77 1.1 skrll #define OPTION_MARCH (OPTION_MD_BASE + 1)
78 1.1 skrll { "march", required_argument, NULL, OPTION_MARCH},
79 1.1 skrll { NULL, no_argument, NULL, 0 },
80 1.1 skrll };
81 1.1 skrll size_t md_longopts_size = sizeof (md_longopts);
82 1.1 skrll
83 1.1 skrll const char * md_shortopts = "";
84 1.1 skrll
85 1.1 skrll /* Mach selected from command line. */
86 1.1 skrll static int mt_mach = bfd_mach_ms1;
87 1.1 skrll static unsigned mt_mach_bitmask = 1 << MACH_MS1;
88 1.1 skrll
89 1.1 skrll /* Flags to set in the elf header */
90 1.1 skrll static flagword mt_flags = EF_MT_CPU_MRISC;
91 1.1 skrll
92 1.1 skrll /* The architecture to use. */
93 1.1 skrll enum mt_architectures
94 1.1 skrll {
95 1.1 skrll ms1_64_001,
96 1.1 skrll ms1_16_002,
97 1.1 skrll ms1_16_003,
98 1.1 skrll ms2
99 1.1 skrll };
100 1.1 skrll
101 1.1 skrll /* MT architecture we are using for this output file. */
102 1.1 skrll static enum mt_architectures mt_arch = ms1_16_002;
103 1.1 skrll
104 1.1 skrll int
105 1.1 skrll md_parse_option (int c ATTRIBUTE_UNUSED, char * arg)
106 1.1 skrll {
107 1.1 skrll switch (c)
108 1.1 skrll {
109 1.1 skrll case OPTION_MARCH:
110 1.1 skrll if (strcmp (arg, "ms1-64-001") == 0)
111 1.1 skrll {
112 1.1 skrll mt_flags = (mt_flags & ~EF_MT_CPU_MASK) | EF_MT_CPU_MRISC;
113 1.1 skrll mt_mach = bfd_mach_ms1;
114 1.1 skrll mt_mach_bitmask = 1 << MACH_MS1;
115 1.1 skrll mt_arch = ms1_64_001;
116 1.1 skrll }
117 1.1 skrll else if (strcmp (arg, "ms1-16-002") == 0)
118 1.1 skrll {
119 1.1 skrll mt_flags = (mt_flags & ~EF_MT_CPU_MASK) | EF_MT_CPU_MRISC;
120 1.1 skrll mt_mach = bfd_mach_ms1;
121 1.1 skrll mt_mach_bitmask = 1 << MACH_MS1;
122 1.1 skrll mt_arch = ms1_16_002;
123 1.1 skrll }
124 1.1 skrll else if (strcmp (arg, "ms1-16-003") == 0)
125 1.1 skrll {
126 1.1 skrll mt_flags = (mt_flags & ~EF_MT_CPU_MASK) | EF_MT_CPU_MRISC2;
127 1.1 skrll mt_mach = bfd_mach_mrisc2;
128 1.1 skrll mt_mach_bitmask = 1 << MACH_MS1_003;
129 1.1 skrll mt_arch = ms1_16_003;
130 1.1 skrll }
131 1.1 skrll else if (strcmp (arg, "ms2") == 0)
132 1.1 skrll {
133 1.1 skrll mt_flags = (mt_flags & ~EF_MT_CPU_MASK) | EF_MT_CPU_MS2;
134 1.1 skrll mt_mach = bfd_mach_mrisc2;
135 1.1 skrll mt_mach_bitmask = 1 << MACH_MS2;
136 1.1 skrll mt_arch = ms2;
137 1.1 skrll }
138 1.1 skrll case OPTION_NO_SCHED_REST:
139 1.1 skrll no_scheduling_restrictions = 1;
140 1.1 skrll break;
141 1.1 skrll default:
142 1.1 skrll return 0;
143 1.1 skrll }
144 1.1 skrll
145 1.1 skrll return 1;
146 1.1 skrll }
147 1.1 skrll
148 1.1 skrll
149 1.1 skrll void
150 1.1 skrll md_show_usage (FILE * stream)
151 1.1 skrll {
152 1.1 skrll fprintf (stream, _("MT specific command line options:\n"));
153 1.1 skrll fprintf (stream, _(" -march=ms1-64-001 allow ms1-64-001 instructions\n"));
154 1.1 skrll fprintf (stream, _(" -march=ms1-16-002 allow ms1-16-002 instructions (default)\n"));
155 1.1 skrll fprintf (stream, _(" -march=ms1-16-003 allow ms1-16-003 instructions\n"));
156 1.1 skrll fprintf (stream, _(" -march=ms2 allow ms2 instructions \n"));
157 1.1 skrll fprintf (stream, _(" -nosched disable scheduling restrictions\n"));
158 1.1 skrll }
159 1.1 skrll
160 1.1 skrll
161 1.1 skrll void
163 1.1 skrll md_begin (void)
164 1.1 skrll {
165 1.1 skrll /* Initialize the `cgen' interface. */
166 1.1 skrll
167 1.1 skrll /* Set the machine number and endian. */
168 1.1 skrll gas_cgen_cpu_desc = mt_cgen_cpu_open (CGEN_CPU_OPEN_MACHS, mt_mach_bitmask,
169 1.1 skrll CGEN_CPU_OPEN_ENDIAN,
170 1.1 skrll CGEN_ENDIAN_BIG,
171 1.1 skrll CGEN_CPU_OPEN_END);
172 1.1 skrll mt_cgen_init_asm (gas_cgen_cpu_desc);
173 1.1 skrll
174 1.1 skrll /* This is a callback from cgen to gas to parse operands. */
175 1.1 skrll cgen_set_parse_operand_fn (gas_cgen_cpu_desc, gas_cgen_parse_operand);
176 1.1 skrll
177 1.1 skrll /* Set the ELF flags if desired. */
178 1.1 skrll if (mt_flags)
179 1.1 skrll bfd_set_private_flags (stdoutput, mt_flags);
180 1.1 skrll
181 1.1 skrll /* Set the machine type. */
182 1.1 skrll bfd_default_set_arch_mach (stdoutput, bfd_arch_mt, mt_mach);
183 1.1 skrll }
184 1.1 skrll
185 1.1 skrll void
186 1.1 skrll md_assemble (char * str)
187 1.1 skrll {
188 1.1 skrll static long delayed_load_register = 0;
189 1.1 skrll static long prev_delayed_load_register = 0;
190 1.1 skrll static int last_insn_had_delay_slot = 0;
191 1.1 skrll static int last_insn_in_noncond_delay_slot = 0;
192 1.1 skrll static int last_insn_has_load_delay = 0;
193 1.1 skrll static int last_insn_was_memory_access = 0;
194 1.1 skrll static int last_insn_was_io_insn = 0;
195 1.1 skrll static int last_insn_was_arithmetic_or_logic = 0;
196 1.1 skrll static int last_insn_was_branch_insn = 0;
197 1.1 skrll static int last_insn_was_conditional_branch_insn = 0;
198 1.1 skrll
199 1.1 skrll mt_insn insn;
200 1.1 skrll char * errmsg;
201 1.1 skrll
202 1.1 skrll /* Initialize GAS's cgen interface for a new instruction. */
203 1.1 skrll gas_cgen_init_parse ();
204 1.1 skrll
205 1.1 skrll insn.insn = mt_cgen_assemble_insn
206 1.1 skrll (gas_cgen_cpu_desc, str, & insn.fields, insn.buffer, & errmsg);
207 1.1 skrll
208 1.1 skrll if (!insn.insn)
209 1.1 skrll {
210 1.1 skrll as_bad ("%s", errmsg);
211 1.1 skrll return;
212 1.1 skrll }
213 1.1 skrll
214 1.1 skrll /* Doesn't really matter what we pass for RELAX_P here. */
215 1.1 skrll gas_cgen_finish_insn (insn.insn, insn.buffer,
216 1.1 skrll CGEN_FIELDS_BITSIZE (& insn.fields), 1, NULL);
217 1.1 skrll
218 1.1 skrll
219 1.1 skrll /* Handle Scheduling Restrictions. */
220 1.1 skrll if (!no_scheduling_restrictions)
221 1.1 skrll {
222 1.1 skrll /* Detect consecutive Memory Accesses. */
223 1.1 skrll if (last_insn_was_memory_access
224 1.1 skrll && CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_MEMORY_ACCESS)
225 1.1 skrll && mt_mach == ms1_64_001)
226 1.1 skrll as_warn (_("instruction %s may not follow another memory access instruction."),
227 1.1 skrll CGEN_INSN_NAME (insn.insn));
228 1.1 skrll
229 1.1 skrll /* Detect consecutive I/O Instructions. */
230 1.1 skrll else if (last_insn_was_io_insn
231 1.1 skrll && CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_IO_INSN))
232 1.1 skrll as_warn (_("instruction %s may not follow another I/O instruction."),
233 1.1 skrll CGEN_INSN_NAME (insn.insn));
234 1.1 skrll
235 1.1 skrll /* Detect consecutive branch instructions. */
236 1.1 skrll else if (last_insn_was_branch_insn
237 1.1 skrll && CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_BR_INSN))
238 1.1 skrll as_warn (_("%s may not occupy the delay slot of another branch insn."),
239 1.1 skrll CGEN_INSN_NAME (insn.insn));
240 1.1 skrll
241 1.1 skrll /* Detect data dependencies on delayed loads: memory and input insns. */
242 1.1 skrll if (last_insn_has_load_delay && delayed_load_register)
243 1.1 skrll {
244 1.1 skrll if (CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_USES_FRSR1)
245 1.1 skrll && insn.fields.f_sr1 == delayed_load_register)
246 1.1 skrll as_warn (_("operand references R%ld of previous load."),
247 1.1 skrll insn.fields.f_sr1);
248 1.1 skrll
249 1.1 skrll if (CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_USES_FRSR2)
250 1.1 skrll && insn.fields.f_sr2 == delayed_load_register)
251 1.1 skrll as_warn (_("operand references R%ld of previous load."),
252 1.1 skrll insn.fields.f_sr2);
253 1.1 skrll }
254 1.1 skrll
255 1.1 skrll /* Detect JAL/RETI hazard */
256 1.1 skrll if (mt_mach == ms2
257 1.1 skrll && CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_JAL_HAZARD))
258 1.1 skrll {
259 1.1 skrll if ((CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_USES_FRSR1)
260 1.1 skrll && insn.fields.f_sr1 == delayed_load_register)
261 1.1 skrll || (CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_USES_FRSR2)
262 1.1 skrll && insn.fields.f_sr2 == delayed_load_register))
263 1.1 skrll as_warn (_("operand references R%ld of previous instrutcion."),
264 1.1 skrll delayed_load_register);
265 1.1 skrll else if ((CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_USES_FRSR1)
266 1.1 skrll && insn.fields.f_sr1 == prev_delayed_load_register)
267 1.1 skrll || (CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_USES_FRSR2)
268 1.1 skrll && insn.fields.f_sr2 == prev_delayed_load_register))
269 1.1 skrll as_warn (_("operand references R%ld of instructcion before previous."),
270 1.1 skrll prev_delayed_load_register);
271 1.1 skrll }
272 1.1 skrll
273 1.1 skrll /* Detect data dependency between conditional branch instruction
274 1.1 skrll and an immediately preceding arithmetic or logical instruction. */
275 1.1 skrll if (last_insn_was_arithmetic_or_logic
276 1.1 skrll && !last_insn_in_noncond_delay_slot
277 1.1 skrll && (delayed_load_register != 0)
278 1.1 skrll && CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_BR_INSN)
279 1.1 skrll && mt_arch == ms1_64_001)
280 1.1 skrll {
281 1.1 skrll if (CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_USES_FRSR1)
282 1.1 skrll && insn.fields.f_sr1 == delayed_load_register)
283 1.1 skrll as_warn (_("conditional branch or jal insn's operand references R%ld of previous arithmetic or logic insn."),
284 1.1 skrll insn.fields.f_sr1);
285 1.1 skrll
286 1.1 skrll if (CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_USES_FRSR2)
287 1.1 skrll && insn.fields.f_sr2 == delayed_load_register)
288 1.1 skrll as_warn (_("conditional branch or jal insn's operand references R%ld of previous arithmetic or logic insn."),
289 1.1 skrll insn.fields.f_sr2);
290 1.1 skrll }
291 1.1 skrll }
292 1.1 skrll
293 1.1 skrll /* Keep track of details of this insn for processing next insn. */
294 1.1 skrll last_insn_in_noncond_delay_slot = last_insn_was_branch_insn
295 1.1 skrll && !last_insn_was_conditional_branch_insn;
296 1.1 skrll
297 1.1 skrll last_insn_had_delay_slot =
298 1.1 skrll CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_DELAY_SLOT);
299 1.1 skrll
300 1.1 skrll last_insn_has_load_delay =
301 1.1 skrll CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_LOAD_DELAY);
302 1.1 skrll
303 1.1 skrll last_insn_was_memory_access =
304 1.1 skrll CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_MEMORY_ACCESS);
305 1.1 skrll
306 1.1 skrll last_insn_was_io_insn =
307 1.1 skrll CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_IO_INSN);
308 1.1 skrll
309 1.1 skrll last_insn_was_arithmetic_or_logic =
310 1.1 skrll CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_AL_INSN);
311 1.1 skrll
312 1.1 skrll last_insn_was_branch_insn =
313 1.1 skrll CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_BR_INSN);
314 1.1 skrll
315 1.1 skrll last_insn_was_conditional_branch_insn =
316 1.1 skrll CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_BR_INSN)
317 1.1 skrll && CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_USES_FRSR2);
318 1.1 skrll
319 1.1 skrll prev_delayed_load_register = delayed_load_register;
320 1.1 skrll
321 1.1 skrll if (CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_USES_FRDR))
322 1.1 skrll delayed_load_register = insn.fields.f_dr;
323 1.1 skrll else if (CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_USES_FRDRRR))
324 1.1 skrll delayed_load_register = insn.fields.f_drrr;
325 1.1 skrll else /* Insns has no destination register. */
326 1.1 skrll delayed_load_register = 0;
327 1.1 skrll
328 1.1 skrll /* Generate dwarf2 line numbers. */
329 1.1 skrll dwarf2_emit_insn (4);
330 1.1 skrll }
331 1.1 skrll
332 1.1 skrll valueT
333 1.1 skrll md_section_align (segT segment, valueT size)
334 1.1 skrll {
335 1.1 skrll int align = bfd_get_section_alignment (stdoutput, segment);
336 1.1 skrll
337 1.1 skrll return ((size + (1 << align) - 1) & (-1 << align));
338 1.1 skrll }
339 1.1 skrll
340 1.1 skrll symbolS *
341 1.1 skrll md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
342 1.1 skrll {
343 1.1 skrll return NULL;
344 1.1 skrll }
345 1.1 skrll
346 1.1 skrll int
348 1.1 skrll md_estimate_size_before_relax (fragS * fragP ATTRIBUTE_UNUSED,
349 1.1 skrll segT segment ATTRIBUTE_UNUSED)
350 1.1 skrll {
351 1.1 skrll as_fatal (_("md_estimate_size_before_relax\n"));
352 1.1 skrll return 1;
353 1.1 skrll }
354 1.1 skrll
355 1.1 skrll /* *fragP has been relaxed to its final size, and now needs to have
356 1.1 skrll the bytes inside it modified to conform to the new size.
357 1.1 skrll
358 1.1 skrll Called after relaxation is finished.
359 1.1 skrll fragP->fr_type == rs_machine_dependent.
360 1.1 skrll fragP->fr_subtype is the subtype of what the address relaxed to. */
361 1.1 skrll
362 1.1 skrll void
363 1.1 skrll md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
364 1.1 skrll segT sec ATTRIBUTE_UNUSED,
365 1.1 skrll fragS * fragP ATTRIBUTE_UNUSED)
366 1.1 skrll {
367 1.1 skrll }
368 1.1 skrll
369 1.1 skrll
370 1.1 skrll /* Functions concerning relocs. */
372 1.1 skrll
373 1.1 skrll long
374 1.1 skrll md_pcrel_from_section (fixS *fixP, segT sec)
375 1.1 skrll {
376 1.1 skrll if (fixP->fx_addsy != (symbolS *) NULL
377 1.1 skrll && (!S_IS_DEFINED (fixP->fx_addsy)
378 1.1 skrll || S_GET_SEGMENT (fixP->fx_addsy) != sec))
379 1.1 skrll /* The symbol is undefined (or is defined but not in this section).
380 1.1 skrll Let the linker figure it out. */
381 1.1 skrll return 0;
382 1.1 skrll
383 1.1 skrll /* Return the address of the opcode - cgen adjusts for opcode size
384 1.1 skrll itself, to be consistent with the disassembler, which must do
385 1.1 skrll so. */
386 1.1 skrll return fixP->fx_where + fixP->fx_frag->fr_address;
387 1.1 skrll }
388 1.1 skrll
389 1.1 skrll
390 1.1 skrll /* Return the bfd reloc type for OPERAND of INSN at fixup FIXP.
391 1.1 skrll Returns BFD_RELOC_NONE if no reloc type can be found.
392 1.1 skrll *FIXP may be modified if desired. */
393 1.1 skrll
394 1.1 skrll bfd_reloc_code_real_type
395 1.1 skrll md_cgen_lookup_reloc (const CGEN_INSN * insn ATTRIBUTE_UNUSED,
396 1.1 skrll const CGEN_OPERAND * operand,
397 1.1 skrll fixS * fixP ATTRIBUTE_UNUSED)
398 1.1 skrll {
399 1.1 skrll bfd_reloc_code_real_type result;
400 1.1 skrll
401 1.1 skrll result = BFD_RELOC_NONE;
402 1.1 skrll
403 1.1 skrll switch (operand->type)
404 1.1 skrll {
405 1.1 skrll case MT_OPERAND_IMM16O:
406 1.1 skrll result = BFD_RELOC_16_PCREL;
407 1.1 skrll fixP->fx_pcrel = 1;
408 1.1 skrll /* fixP->fx_no_overflow = 1; */
409 1.1 skrll break;
410 1.1 skrll case MT_OPERAND_IMM16:
411 1.1 skrll case MT_OPERAND_IMM16Z:
412 1.1 skrll /* These may have been processed at parse time. */
413 1.1 skrll if (fixP->fx_cgen.opinfo != 0)
414 1.1 skrll result = fixP->fx_cgen.opinfo;
415 1.1 skrll fixP->fx_no_overflow = 1;
416 1.1 skrll break;
417 1.1 skrll case MT_OPERAND_LOOPSIZE:
418 1.1 skrll result = BFD_RELOC_MT_PCINSN8;
419 1.1 skrll fixP->fx_pcrel = 1;
420 1.1 skrll /* Adjust for the delay slot, which is not part of the loop */
421 1.1 skrll fixP->fx_offset -= 8;
422 1.1 skrll break;
423 1.1 skrll default:
424 1.1 skrll result = BFD_RELOC_NONE;
425 1.1 skrll break;
426 1.1 skrll }
427 1.1 skrll
428 1.1 skrll return result;
429 1.1 skrll }
430 1.1 skrll
431 1.1 skrll /* Write a value out to the object file, using the appropriate endianness. */
432 1.1 skrll
433 1.1 skrll void
434 1.1 skrll md_number_to_chars (char * buf, valueT val, int n)
435 1.1 skrll {
436 1.1 skrll number_to_chars_bigendian (buf, val, n);
437 1.1 skrll }
438 1.1 skrll
439 1.1 skrll char *
440 1.1 skrll md_atof (int type, char * litP, int * sizeP)
441 1.1 skrll {
442 1.1 skrll return ieee_md_atof (type, litP, sizeP, FALSE);
443 1.1 skrll }
444 1.1 skrll
445 1.1 skrll /* See whether we need to force a relocation into the output file. */
446 1.1 skrll
447 1.1 skrll int
448 1.1 skrll mt_force_relocation (fixS * fixp ATTRIBUTE_UNUSED)
449 1.1 skrll {
450 1.1 skrll return 0;
451 1.1 skrll }
452 1.1 skrll
453 1.1 skrll void
454 1.1 skrll mt_apply_fix (fixS *fixP, valueT *valueP, segT seg)
455 1.1 skrll {
456 1.1 skrll if ((fixP->fx_pcrel != 0) && (fixP->fx_r_type == BFD_RELOC_32))
457 1.1 skrll fixP->fx_r_type = BFD_RELOC_32_PCREL;
458 1.1 skrll
459 1.1 skrll gas_cgen_md_apply_fix (fixP, valueP, seg);
460 1.1 skrll }
461 1.1 skrll
462 1.1 skrll bfd_boolean
463 1.1 skrll mt_fix_adjustable (fixS * fixP)
464 1.1 skrll {
465 1.1 skrll bfd_reloc_code_real_type reloc_type;
466 1.1 skrll
467 1.1 skrll if ((int) fixP->fx_r_type >= (int) BFD_RELOC_UNUSED)
468 1.1 skrll {
469 1.1 skrll const CGEN_INSN *insn = NULL;
470 1.1 skrll int opindex = (int) fixP->fx_r_type - (int) BFD_RELOC_UNUSED;
471 1.1 skrll const CGEN_OPERAND *operand;
472 1.1 skrll
473 1.1 skrll operand = cgen_operand_lookup_by_num(gas_cgen_cpu_desc, opindex);
474 1.1 skrll reloc_type = md_cgen_lookup_reloc (insn, operand, fixP);
475 1.1 skrll }
476 1.1 skrll else
477 1.1 skrll reloc_type = fixP->fx_r_type;
478 1.1 skrll
479 1.1 skrll if (fixP->fx_addsy == NULL)
480 1.1 skrll return TRUE;
481 1.1 skrll
482 1.1 skrll /* Prevent all adjustments to global symbols. */
483 1.1 skrll if (S_IS_EXTERNAL (fixP->fx_addsy))
484 1.1 skrll return FALSE;
485 1.1 skrll
486 1.1 skrll if (S_IS_WEAK (fixP->fx_addsy))
487 return FALSE;
488
489 return 1;
490 }
491