aboutsummaryrefslogtreecommitdiff
path: root/bfd/elf32-nds32.h
blob: d4d4e934fd7abf045f2f6e62bb2676542118d1e4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
/* NDS32-specific support for 32-bit ELF.
   Copyright (C) 2012-2014 Free Software Foundation, Inc.
   Contributed by Andes Technology Corporation.

   This file is part of BFD, the Binary File Descriptor library.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
   02110-1301, USA.*/

#ifndef ELF32_NDS32_H
#define ELF32_NDS32_H

/* Relocation flags encoded in r_addend.  */

/* Relocation flags for R_NDS32_ERLAX_ENTRY.  */

/* Set if relax on this section is done or disabled.  */
#define R_NDS32_RELAX_ENTRY_DISABLE_RELAX_FLAG			(1 << 31)
/* Optimize for performance.  */
#define R_NDS32_RELAX_ENTRY_OPTIMIZE_FLAG			(1 << 30)
/* Optimize for size.  Branch destination 4-byte adjustment
   may be disabled.  */
#define R_NDS32_RELAX_ENTRY_OPTIMIZE_FOR_SPACE_FLAG		(1 << 29)
/* To distinguish the assembly code generated by compiler
   or written manually.  */
#define R_NDS32_RELAX_ENTRY_VERBATIM_FLAG			(1 << 28)
/* EX9 and link-time IFC must be explicitly enabled, so we
   won't mess up handcraft assembly code.  */
/* Enable EX9 optimization for this section.  */
#define R_NDS32_RELAX_ENTRY_EX9_FLAG				(1 << 2)
/* Enable IFC optimization for this section.  */
#define R_NDS32_RELAX_ENTRY_IFC_FLAG				(1 << 3)


/* Relocation flags for R_NDS32_INSN16.  */

/* Tag the nop16 can be removed.  */
#define R_NDS32_INSN16_CONVERT_FLAG				(1 << 0)
/* Convert a gp-relative access (e.g., lwi.gp)
   to fp-as-gp access (lwi37.fp).
   This value is used by linker internally only.
   It's fine to change the vlaue.  */
#define R_NDS32_INSN16_FP7U2_FLAG				(1 << 1)

/* Relocation flags for R_NDS32_RELAX_REGION_OMIT_FP_START/END.  */

/* OMIT_FP_FLAG marks the region for applying fp-as-gp
   optimization.  */
#define R_NDS32_RELAX_REGION_OMIT_FP_FLAG			(1 << 0)
/* NOT_OMIT_FP_FLAG is set if this region is not worth
   for fp-as-gp.  */
#define R_NDS32_RELAX_REGION_NOT_OMIT_FP_FLAG			(1 << 1)
/* Suppress EX9 optimization in the region.  */
#define R_NDS32_RELAX_REGION_NO_EX9_FLAG			(1 << 2)
/* A Innermost loop region.  Some optimizations is suppressed
   in this region due to performance drop.  */
#define R_NDS32_RELAX_REGION_INNERMOST_LOOP_FLAG		(1 << 4)

/* Tag range for LOADSTORE relocation.  */
enum
{
  NDS32_LOADSTORE_NONE = 0x0,
  NDS32_LOADSTORE_BYTE = 0x1,
  NDS32_LOADSTORE_HALF = 0x2,
  NDS32_LOADSTORE_WORD = 0x4,
  NDS32_LOADSTORE_FLOAT_S = 0x8,
  NDS32_LOADSTORE_FLOAT_D = 0x10,
  NDS32_LOADSTORE_IMM = 0x20
};

/* Relax tag for nds32_elf_relax_section, we have to specify which
   optimization do in this round.  */
enum
{
  NDS32_RELAX_NONE_ROUND = 0,
  NDS32_RELAX_NORMAL_ROUND,
  NDS32_RELAX_JUMP_IFC_ROUND,
  NDS32_RELAX_EX9_BUILD_ROUND,
  NDS32_RELAX_EX9_REPLACE_ROUND,
  NDS32_RELAX_EMPTY_ROUND
};

/* Optimization status mask.  */
#define NDS32_RELAX_JUMP_IFC_DONE	(1 << 0)
#define NDS32_RELAX_EX9_DONE		(1 << 1)

/* Optimization turn on mask.  */
#define NDS32_RELAX_JUMP_IFC_ON		(1 << 0)
#define NDS32_RELAX_EX9_ON		(1 << 1)

extern void nds32_insertion_sort
  (void *, size_t, size_t, int (*) (const void *, const void *));

extern int         nds32_elf_ex9_init (void);
extern int         nds32_convert_32_to_16 (bfd *, uint32_t, uint16_t *, int *);
extern int         nds32_convert_16_to_32 (bfd *, uint16_t, uint32_t *);
extern void        bfd_elf32_nds32_set_target_option (struct bfd_link_info *,
						      int, int, FILE *, int,
						      int, int, int, FILE *,
						      FILE *, int, int,
						      bfd_boolean, bfd_boolean);

#define nds32_elf_hash_table(info) \
  (elf_hash_table_id ((struct elf_link_hash_table *) ((info)->hash)) \
   == NDS32_ELF_DATA ? \
   ((struct elf_nds32_link_hash_table *) ((info)->hash)) : NULL)

/* Hash table structure for target nds32.  There are some members to
   save target options passed from nds32elf.em to bfd.  */

struct elf_nds32_link_hash_table
{
  struct elf_link_hash_table root;

  /* Short-cuts to get to dynamic linker sections.  */
  asection *sgot;
  asection *sgotplt;
  asection *srelgot;
  asection *splt;
  asection *srelplt;
  asection *sdynbss;
  asection *srelbss;

  /* Small local sym to section mapping cache.  */
  struct sym_cache sym_cache;

  /* Target dependent options.  */
  int relax_fp_as_gp;		/* --mrelax-omit-fp  */
  int eliminate_gc_relocs;	/* --meliminate-gc-relocs  */
  FILE *sym_ld_script;		/* --mgen-symbol-ld-script=<file>  */
  /* Disable if linking a dynamically linked executable.  */
  int load_store_relax;
  int target_optimize;		/* Switch optimization.  */
  int relax_status;		/* Finished optimization.  */
  int relax_round;		/* Going optimization.  */
  FILE *ex9_export_file;	/* --mexport-ex9=<file>  */
  FILE *ex9_import_file;	/* --mimport-ex9=<file>  */
  int update_ex9_table;		/* --mupdate-ex9.  */
  int ex9_limit;
  bfd_boolean ex9_loop_aware;	/* Ignore ex9 if inside a loop.  */
  bfd_boolean ifc_loop_aware;	/* Ignore ifc if inside a loop.  */
};
#endif