2011-06-09 Tristan Gingold <gingold@adacore.com>
[deliverable/binutils-gdb.git] / gas / config / tc-sh64.h
CommitLineData
324bfcf3 1/* This file is tc-sh64.h
aa820537 2 Copyright 2000, 2001, 2002, 2003, 2005, 2007, 2008
20ee54e8 3 Free Software Foundation, Inc.
324bfcf3
AO
4
5 This file is part of GAS, the GNU Assembler.
6
7 GAS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
ec2655a6 9 the Free Software Foundation; either version 3, or (at your option)
324bfcf3
AO
10 any later version.
11
12 GAS is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GAS; see the file COPYING. If not, write to
4b4da160
NC
19 the Free Software Foundation, 51 Franklin Street - Fifth Floor,
20 Boston, MA 02110-1301, USA. */
324bfcf3
AO
21
22#define TC_SH64
23#include "config/tc-sh.h"
24#include "elf/sh.h"
f0abc2a1 25#include "elf32-sh64.h"
324bfcf3
AO
26
27/* We need to override the tc-sh.h settings of HANDLE_ALIGN and
28 MAX_MEM_FOR_RS_ALIGN_CODE; we might need to put in SHmedia NOP:s, not
29 SHcompact NOP:s. */
30#undef HANDLE_ALIGN
31#define HANDLE_ALIGN(frag) sh64_handle_align (frag)
8edc77b9 32extern void sh64_handle_align (fragS *);
324bfcf3
AO
33
34#undef MAX_MEM_FOR_RS_ALIGN_CODE
35#define MAX_MEM_FOR_RS_ALIGN_CODE sh64_max_mem_for_rs_align_code ()
8edc77b9 36extern int sh64_max_mem_for_rs_align_code (void);
324bfcf3
AO
37
38#undef LISTING_HEADER
39#define LISTING_HEADER \
40 (target_big_endian ? \
ef230218
JR
41 "SuperH SHcompact/SHmedia Big Endian GAS" \
42 : "SuperH SHcompact/SHmedia Little Endian GAS")
324bfcf3
AO
43
44/* We need to record the new frag position after an .align. */
8edc77b9 45extern void sh64_do_align (int, const char *, int, int);
324bfcf3
AO
46#define md_do_align(n, fill, len, max, l) \
47 do { sh64_do_align (n, fill, len, max); goto l; } while (0)
48
49struct sh64_segment_info_type
50{
51 /* The type of the section is initialized when the range_start_symbol
52 member is non-NULL. */
53 symbolS *mode_start_symbol;
54 subsegT mode_start_subseg;
55
56 /* A stored symbol indicating location of last call of
57 "md_flush_pending_output". It is NULLed when we actually use it;
58 otherwise the contents is just filled in with segment, frag and
59 offset within frag. */
60 symbolS *last_contents_mark;
61
62 unsigned int emitted_ranges;
63 enum sh64_elf_cr_type contents_type;
64
65 /* This is used by the SH1-4 parts; we set it to 0 for SHmedia code and
66 data. */
67 unsigned int in_code : 1;
68};
69
70#undef TC_SEGMENT_INFO_TYPE
71#define TC_SEGMENT_INFO_TYPE struct sh64_segment_info_type
72
73#undef TARGET_FORMAT
74#define TARGET_FORMAT sh64_target_format ()
8edc77b9 75extern const char *sh64_target_format (void);
324bfcf3
AO
76
77#define TARGET_MACH sh64_target_mach ()
8edc77b9 78extern int sh64_target_mach (void);
324bfcf3 79
a161fe53
AM
80#undef TC_FORCE_RELOCATION_LOCAL
81#define TC_FORCE_RELOCATION_LOCAL(FIX) \
82 (!(FIX)->fx_pcrel \
a161fe53
AM
83 || (FIX)->fx_r_type == BFD_RELOC_32_PLT_PCREL \
84 || (FIX)->fx_r_type == BFD_RELOC_SH_PLT_LOW16 \
85 || (FIX)->fx_r_type == BFD_RELOC_SH_PLT_MEDLOW16 \
86 || (FIX)->fx_r_type == BFD_RELOC_SH_PLT_MEDHI16 \
87 || (FIX)->fx_r_type == BFD_RELOC_SH_PLT_HI16 \
88 || (FIX)->fx_r_type == BFD_RELOC_32_GOT_PCREL \
89 || (FIX)->fx_r_type == BFD_RELOC_SH_GOT_LOW16 \
90 || (FIX)->fx_r_type == BFD_RELOC_SH_GOT_MEDLOW16 \
91 || (FIX)->fx_r_type == BFD_RELOC_SH_GOT_MEDHI16 \
92 || (FIX)->fx_r_type == BFD_RELOC_SH_GOT_HI16 \
93 || (FIX)->fx_r_type == BFD_RELOC_SH_GOT10BY4 \
94 || (FIX)->fx_r_type == BFD_RELOC_SH_GOT10BY8 \
95 || (FIX)->fx_r_type == BFD_RELOC_SH_GOTPLT32 \
96 || (FIX)->fx_r_type == BFD_RELOC_SH_GOTPLT_LOW16 \
97 || (FIX)->fx_r_type == BFD_RELOC_SH_GOTPLT_MEDLOW16 \
98 || (FIX)->fx_r_type == BFD_RELOC_SH_GOTPLT_MEDHI16 \
99 || (FIX)->fx_r_type == BFD_RELOC_SH_GOTPLT_HI16 \
100 || (FIX)->fx_r_type == BFD_RELOC_SH_GOTPLT10BY4 \
101 || (FIX)->fx_r_type == BFD_RELOC_SH_GOTPLT10BY8 \
102 || (FIX)->fx_r_type == BFD_RELOC_SH_GOTPC \
103 || (FIX)->fx_r_type == BFD_RELOC_SH_GOTPC_LOW16 \
104 || (FIX)->fx_r_type == BFD_RELOC_SH_GOTPC_MEDLOW16 \
105 || (FIX)->fx_r_type == BFD_RELOC_SH_GOTPC_MEDHI16 \
106 || (FIX)->fx_r_type == BFD_RELOC_SH_GOTPC_HI16 \
107 || TC_FORCE_RELOCATION (FIX))
108
109#undef TC_FORCE_RELOCATION_SUB_SAME
ae6063d4
AM
110#define TC_FORCE_RELOCATION_SUB_SAME(FIX, SEC) \
111 (! SEG_NORMAL (SEC) \
112 || TC_FORCE_RELOCATION (FIX) \
a161fe53
AM
113 || (sh_relax && SWITCH_TABLE (FIX)) \
114 || *symbol_get_tc ((FIX)->fx_addsy) != NULL)
115
116/* Don't complain when we leave fx_subsy around. */
117#undef TC_VALIDATE_FIX_SUB
5db484ff
AM
118#define TC_VALIDATE_FIX_SUB(FIX, SEG) \
119 ((md_register_arithmetic || (SEG) != reg_section) \
120 && ((FIX)->fx_r_type == BFD_RELOC_32_PLT_PCREL \
121 || (sh_relax && SWITCH_TABLE (FIX)) \
122 || *symbol_get_tc ((FIX)->fx_addsy) != NULL))
324bfcf3
AO
123
124/* Note the kludge: we want to put back C, and we also want to consume the
125 expression, since we have handled it ourselves. FIXME: What we really
126 need is a new GAS infrastructure feature: md_qualifier. */
127#undef md_parse_name
9497f5ac
NC
128#define md_parse_name(NAME, EXP, MODE, CP) \
129 sh64_consume_datalabel (NAME, EXP, MODE, CP, operand)
130extern int sh64_consume_datalabel (const char *, expressionS *,
131 enum expr_mode, char *,
132 segT (*) (expressionS *, enum expr_mode));
324bfcf3
AO
133
134/* Saying "$" is the same as saying ".". */
135#define DOLLAR_DOT
136
a074e149 137#undef MD_PCREL_FROM_SECTION
a161fe53
AM
138#define MD_PCREL_FROM_SECTION(FIX, SEC) \
139 shmedia_md_pcrel_from_section (FIX, SEC)
324bfcf3 140
8edc77b9 141extern valueT shmedia_md_pcrel_from_section (struct fix *, segT);
324bfcf3
AO
142
143/* We need to mark this symbol as a BranchTarget; setting st_other for it
144 and adding 1 to its value (temporarily). */
8edc77b9 145extern void sh64_frob_label (symbolS *);
324bfcf3
AO
146
147#undef tc_frob_label
148#define tc_frob_label(sym) \
07a53e5c 149 do { sh_frob_label (sym); sh64_frob_label (sym); } while (0)
324bfcf3
AO
150
151#define tc_symbol_new_hook(s) sh64_frob_label (s)
152
153/* We use this to mark our "datalabel" symbol copies. The "mark" is NULL
154 for an ordinary symbol, and the pointer to the "ordinary" symbol for a
155 datalabel symbol. */
156#define TC_SYMFIELD_TYPE symbolS *
157
158#define tc_frob_symbol(symp, punt) \
159 do \
160 { \
161 punt = sh64_exclude_symbol (symp); \
162 } \
163 while (0)
164
8edc77b9 165extern int sh64_exclude_symbol (symbolS *);
324bfcf3 166
8edc77b9 167extern void sh64_adjust_symtab (void);
324bfcf3
AO
168#define tc_adjust_symtab sh64_adjust_symtab
169
170#undef md_flush_pending_output
171#define md_flush_pending_output() sh64_flush_pending_output ()
8edc77b9 172extern void sh64_flush_pending_output (void);
324bfcf3
AO
173
174/* Note that tc-sh.c has a sh_frob_section, but it's called from
175 tc_frob_file_before_adjust. */
176#define tc_frob_section(sec) shmedia_frob_section_type (sec)
8edc77b9 177extern void shmedia_frob_section_type (asection *);
324bfcf3 178
324bfcf3
AO
179/* We need to emit fixups relative to the frag in which the instruction
180 resides. Safest way without calculating max fragment growth or making
181 it a fixed number is to provide a pointer to the opcode frag.
182
183 We also need to emit the right NOP pattern in .align frags. This is
184 done after the text-to-bits assembly pass, so we need to mark it with
185 the ISA setting at the time the .align was assembled. */
186#define TC_FRAG_TYPE struct sh64_tc_frag_data
187
188enum sh64_isa_values
189 {
190 sh64_isa_unspecified,
191 sh64_isa_shcompact,
192 sh64_isa_shmedia,
193
194 /* Special guard value used in contexts when we don't know which ISA it
195 is, just that it's specified (not sh64_isa_unspecified). */
196 sh64_isa_sh5_guard
197 };
198
199struct sh64_tc_frag_data
200{
201 fragS *opc_frag;
202 enum sh64_isa_values isa;
203};
204
205extern enum sh64_isa_values sh64_isa_mode;
206
207#define TC_FRAG_INIT(FRAGP) \
208 do \
209 { \
210 (FRAGP)->tc_frag_data.opc_frag = sh64_last_insn_frag; \
211 (FRAGP)->tc_frag_data.isa = sh64_isa_mode; \
212 } \
213 while (0)
214
215/* This variable is set whenever we generate (or grow) a new opcode frag
216 in shmedia_build_Mytes. */
217extern fragS *sh64_last_insn_frag;
218
219#define md_end() shmedia_md_end ()
8edc77b9 220void shmedia_md_end (void);
324bfcf3
AO
221
222/* Because we make .debug_line hold the SHmedia instruction address | 1,
223 we have to say we only have minimum byte-size insns. */
224#undef DWARF2_LINE_MIN_INSN_LENGTH
225#define DWARF2_LINE_MIN_INSN_LENGTH 1
c9cd7160
L
226
227#define TC_FAKE_LABEL(NAME) sh64_fake_label(NAME)
228extern int sh64_fake_label (const char *);
This page took 0.43657 seconds and 4 git commands to generate.