#include "subsegs.h"
#include "struc-symbol.h"
#include "dwarf2dbg.h"
+#include "dw2gencfi.h"
#include "safe-ctype.h"
#include "opcode/arc.h"
const struct arc_flags *, int, struct arc_insn *);
/* The cpu for which we are generating code. */
-static unsigned arc_target = ARC_OPCODE_BASE;
-static const char *arc_target_name = "<all>";
-static unsigned arc_features = 0x00;
+static unsigned arc_target;
+static const char *arc_target_name;
+static unsigned arc_features;
/* The default architecture. */
-static int arc_mach_type = bfd_mach_arc_arcv2;
+static int arc_mach_type;
/* Non-zero if the cpu type has been explicitly specified. */
static int mach_type_specified_p = 0;
{ "arc700", ARC_OPCODE_ARC700, bfd_mach_arc_arc700,
E_ARC_MACH_ARC700, 0x00},
{ "arcem", ARC_OPCODE_ARCv2EM, bfd_mach_arc_arcv2,
- EF_ARC_CPU_ARCV2EM, 0x00},
+ EF_ARC_CPU_ARCV2EM, ARC_CD},
{ "archs", ARC_OPCODE_ARCv2HS, bfd_mach_arc_arcv2,
EF_ARC_CPU_ARCV2HS, ARC_CD},
- { "all", ARC_OPCODE_BASE, bfd_mach_arc_arcv2,
- 0x00, 0x00 },
{ 0, 0, 0, 0, 0 }
};
}
}
+/* Select an appropriate entry from CPU_TYPES based on ARG and initialise
+ the relevant static global variables. */
+
+static void
+arc_select_cpu (const char *arg)
+{
+ int cpu_flags = EF_ARC_CPU_GENERIC;
+ int i;
+
+ for (i = 0; cpu_types[i].name; ++i)
+ {
+ if (!strcasecmp (cpu_types[i].name, arg))
+ {
+ arc_target = cpu_types[i].flags;
+ arc_target_name = cpu_types[i].name;
+ arc_features = cpu_types[i].features;
+ arc_mach_type = cpu_types[i].mach;
+ cpu_flags = cpu_types[i].eflags;
+ break;
+ }
+ }
+
+ if (!cpu_types[i].name)
+ as_fatal (_("unknown architecture: %s\n"), arg);
+
+ if (cpu_flags != EF_ARC_CPU_GENERIC)
+ arc_eflag = (arc_eflag & ~EF_ARC_MACH_MSK) | cpu_flags;
+}
+
/* Here ends all the ARCompact extension instruction assembling
stuff. */
lab = symbol_find_or_make (lab_name);
restore_line_pointer (c);
}
+
+ /* These relocations exist as a mechanism for the compiler to tell the
+ linker how to patch the code if the tls model is optimised. However,
+ the relocation itself does not require any space within the assembler
+ fragment, and so we pass a size of 0.
+
+ The lines that generate these relocations look like this:
+
+ .tls_gd_ld @.tdata`bl __tls_get_addr@plt
+
+ The '.tls_gd_ld @.tdata' is processed first and generates the
+ additional relocation, while the 'bl __tls_get_addr@plt' is processed
+ second and generates the additional branch.
+
+ It is possible that the additional relocation generated by the
+ '.tls_gd_ld @.tdata' will be attached at the very end of one fragment,
+ while the 'bl __tls_get_addr@plt' will be generated as the first thing
+ in the next fragment. This will be fine; both relocations will still
+ appear to be at the same address in the generated object file.
+ However, this only works as the additional relocation is generated
+ with size of 0 bytes. */
fixS *fixP
= fix_new (frag_now, /* Which frag? */
frag_now_fix (), /* Where in that frag? */
- 2, /* size: 1, 2, or 4 usually. */
+ 0, /* size: 1, 2, or 4 usually. */
sym, /* X_add_symbol. */
0, /* X_add_number. */
FALSE, /* TRUE if PC-relative relocation. */
/* Callback to insert a register into the hash table. */
static void
-declare_register (char *name, int number)
+declare_register (const char *name, int number)
{
const char *err;
symbolS *regS = symbol_create (name, reg_section,
{
unsigned int i;
+ if (!mach_type_specified_p)
+ arc_select_cpu ("arc700");
+
/* The endianness can be chosen "at the factory". */
target_big_endian = byte_order == BIG_ENDIAN;
insert_operand (unsigned insn,
const struct arc_operand *operand,
offsetT val,
- char *file,
+ const char *file,
unsigned line)
{
offsetT min = 0, max = 0;
int
md_parse_option (int c, char *arg ATTRIBUTE_UNUSED)
{
- int cpu_flags = EF_ARC_CPU_GENERIC;
-
switch (c)
{
case OPTION_ARC600:
case OPTION_MCPU:
{
- int i;
- char *s = alloca (strlen (arg) + 1);
-
- {
- char *t = s;
- char *arg1 = arg;
-
- do
- *t = TOLOWER (*arg1++);
- while (*t++);
- }
-
- for (i = 0; cpu_types[i].name; ++i)
- {
- if (!strcmp (cpu_types[i].name, s))
- {
- arc_target = cpu_types[i].flags;
- arc_target_name = cpu_types[i].name;
- arc_features = cpu_types[i].features;
- arc_mach_type = cpu_types[i].mach;
- cpu_flags = cpu_types[i].eflags;
-
- mach_type_specified_p = 1;
- break;
- }
- }
-
- if (!cpu_types[i].name)
- {
- as_fatal (_("unknown architecture: %s\n"), arg);
- }
+ arc_select_cpu (arg);
+ mach_type_specified_p = 1;
break;
}
return 0;
}
- if (cpu_flags != EF_ARC_CPU_GENERIC)
- arc_eflag = (arc_eflag & ~EF_ARC_MACH_MSK) | cpu_flags;
-
return 1;
}
break;
}
- return 0; /* FIXME! return 1, fix it in the linker. */
+ return 1;
}
/* Compute the reloc type of an expression EXP. */
return 0;
}
+
+/* Initialize the DWARF-2 unwind information for this procedure. */
+
+void
+tc_arc_frame_initial_instructions (void)
+{
+ /* Stack pointer is register 28. */
+ cfi_add_CFA_def_cfa_register (28);
+}
+
+int
+tc_arc_regname_to_dw2regnum (char *regname)
+{
+ struct symbol *sym;
+
+ sym = hash_find (arc_reg_hash, regname);
+ if (sym)
+ return S_GET_VALUE (sym);
+
+ return -1;
+}