* config/tc-arc.c (md_pseudo_table): Add .cpu.
(comment_chars): Add ';'. (arc_mach_type, mach_type_specified, cpu_tables_init_p): New globals. (md_parse_option): Delete support for -mmult. Add -mcpu=xxx. (md_begin): Current ARCs are little endian. Call bfd_set_arch_mach to set the cpu type. (init_opcode_tables): New function. (md_begin): Ignore suffixes and registers not supported by cpu. (md_assemble): Initialize opcode tables here. Ignore opcodes not supported by selected cpu. Always ask for more memory in one piece. (arc_cpu): New function. (md_numbers_to_chars): Support both endians (will probably be needed eventually anyway). (md_apply_fix): Likewise.
This commit is contained in:
parent
2db01c3d52
commit
31add5f0c9
@ -1,5 +1,5 @@
|
||||
/* tc-arc.c -- Assembler for the ARC
|
||||
Copyright (C) 1994 Free Software Foundation, Inc.
|
||||
Copyright (C) 1994, 1995 Free Software Foundation, Inc.
|
||||
Contributed by Doug Evans (dje@cygnus.com).
|
||||
|
||||
This file is part of GAS, the GNU Assembler.
|
||||
@ -23,8 +23,10 @@
|
||||
#include "as.h"
|
||||
#include "subsegs.h"
|
||||
#include "opcode/arc.h"
|
||||
#include "elf/arc.h"
|
||||
|
||||
extern int target_big_endian;
|
||||
extern int arc_get_mach PARAMS ((char *));
|
||||
|
||||
static arc_insn arc_insert_operand PARAMS ((arc_insn insn,
|
||||
const struct arc_operand *operand,
|
||||
@ -33,31 +35,22 @@ static arc_insn arc_insert_operand PARAMS ((arc_insn insn,
|
||||
offsetT val,
|
||||
char *file, unsigned int line));
|
||||
|
||||
static void s_data1 PARAMS ((void));
|
||||
static void s_seg PARAMS ((int));
|
||||
static void s_proc PARAMS ((int));
|
||||
static void s_reserve PARAMS ((int));
|
||||
static void s_common PARAMS ((int));
|
||||
static void arc_common PARAMS ((int));
|
||||
static void arc_cpu PARAMS ((int));
|
||||
/*static void arc_rename PARAMS ((int));*/
|
||||
|
||||
static int find_mach PARAMS ((char *));
|
||||
|
||||
const pseudo_typeS md_pseudo_table[] =
|
||||
{
|
||||
{"align", s_align_bytes, 0}, /* Defaulting is invalid (0) */
|
||||
{"common", s_common, 0},
|
||||
{"global", s_globl, 0},
|
||||
{"half", cons, 2},
|
||||
{"optim", s_ignore, 0},
|
||||
{"proc", s_proc, 0},
|
||||
{"reserve", s_reserve, 0},
|
||||
{"seg", s_seg, 0},
|
||||
{"skip", s_space, 0},
|
||||
{"word", cons, 4},
|
||||
{"xword", cons, 8},
|
||||
{"pushsection", obj_elf_section, 0},
|
||||
{"popsection", obj_elf_previous, 0},
|
||||
{"uahalf", cons, 2},
|
||||
{"uaword", cons, 4},
|
||||
{"uaxword", cons, 8},
|
||||
{NULL, 0, 0},
|
||||
{ "align", s_align_bytes, 0 }, /* Defaulting is invalid (0) */
|
||||
{ "common", arc_common, 0 },
|
||||
/*{ "hword", cons, 2 }, - already exists */
|
||||
{ "word", cons, 4 },
|
||||
{ "xword", cons, 8 },
|
||||
{ "cpu", arc_cpu, 0 },
|
||||
/*{ "rename", arc_rename, 0 },*/
|
||||
{ NULL, 0, 0 },
|
||||
};
|
||||
|
||||
const int md_short_jump_size = 4;
|
||||
@ -66,7 +59,7 @@ const int md_reloc_size = 12; /* Size of relocation record */
|
||||
|
||||
/* This array holds the chars that always start a comment. If the
|
||||
pre-processor is disabled, these aren't very useful */
|
||||
const char comment_chars[] = "#";
|
||||
const char comment_chars[] = "#;";
|
||||
|
||||
/* This array holds the chars that only start a comment at the beginning of
|
||||
a line. If the line seems to have the form '# 123 filename'
|
||||
@ -88,6 +81,16 @@ const char EXP_CHARS[] = "eE";
|
||||
/* or 0d1.2345e12 */
|
||||
const char FLT_CHARS[] = "rRsSfFdDxXpP";
|
||||
|
||||
/* One of bfd_mach_arc_xxx. */
|
||||
static int arc_mach_type = bfd_mach_arc_base;
|
||||
|
||||
/* Non-zero if the cpu type was specified on the command line. */
|
||||
static int mach_type_specified = 0;
|
||||
|
||||
/* Non-zero if opcode tables have been initialized.
|
||||
A .cpu command must appear before any instructions. */
|
||||
static int cpu_tables_init_p = 0;
|
||||
|
||||
static const char *arc_condition_codes[] =
|
||||
{
|
||||
"al", "eq", "ne", "p", "n", "c", "nc", "v",
|
||||
@ -99,13 +102,11 @@ static struct hash_control *arc_suffix_hash = NULL;
|
||||
static struct hash_control *arc_reg_hash = NULL;
|
||||
|
||||
const char *md_shortopts = "m:";
|
||||
struct option md_longopts[] = {
|
||||
{NULL, no_argument, NULL, 0}
|
||||
struct option md_longopts[] =
|
||||
{
|
||||
{ NULL, no_argument, NULL, 0 }
|
||||
};
|
||||
size_t md_longopts_size = sizeof(md_longopts);
|
||||
|
||||
/* Non-zero if we accept the mul/mulu and variable shift insns. */
|
||||
static int have_mult = 0;
|
||||
size_t md_longopts_size = sizeof (md_longopts);
|
||||
|
||||
/*
|
||||
* md_parse_option
|
||||
@ -122,14 +123,19 @@ md_parse_option (c, arg)
|
||||
switch (c)
|
||||
{
|
||||
case 'm':
|
||||
if (strcmp (arg, "mult") == 0)
|
||||
have_mult = 1;
|
||||
else
|
||||
if (strncmp (arg, "cpu=", 4) == 0)
|
||||
{
|
||||
as_bad ("invalid architecture -m%s", arg);
|
||||
return 0;
|
||||
int mach = arc_get_mach (arg + 4);
|
||||
|
||||
if (mach != -1)
|
||||
{
|
||||
arc_mach_type = mach;
|
||||
mach_type_specified = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
as_bad ("invalid architecture -m%s", arg);
|
||||
return 0;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
@ -144,24 +150,55 @@ md_show_usage (stream)
|
||||
{
|
||||
fprintf (stream, "\
|
||||
ARC options:\n\
|
||||
-mmult recognize the mul/mulu and variable shift instructions\n");
|
||||
-mcpu={base,host,graphics,audio} select cpu type\n");
|
||||
}
|
||||
|
||||
/* This function is called once, at assembler startup time. It should
|
||||
set up all the tables, etc. that the MD part of the assembler will need. */
|
||||
set up all the tables, etc. that the MD part of the assembler will need.
|
||||
Opcode selection is defered until later because we might see a .cpu
|
||||
command. */
|
||||
|
||||
void
|
||||
md_begin ()
|
||||
{
|
||||
register unsigned int i = 0;
|
||||
char *last;
|
||||
/* The endianness can be chosen "at the factory". One day we may have
|
||||
to be bi-endian. */
|
||||
target_big_endian = 0;
|
||||
|
||||
target_big_endian = 1;
|
||||
if (!bfd_set_arch_mach (stdoutput, bfd_arch_arc, arc_mach_type))
|
||||
as_warn ("could not set architecture and machine");
|
||||
}
|
||||
|
||||
/* Initialize the various opcode and operand tables.
|
||||
MACH is one of bfd_mach_arc_xxx. */
|
||||
|
||||
static void
|
||||
init_opcode_tables (mach)
|
||||
int mach;
|
||||
{
|
||||
register unsigned int i;
|
||||
char *last;
|
||||
/* Indexed by bfd_mach_arc_xxx. */
|
||||
static int cpu_type_map[] =
|
||||
{
|
||||
ARC_CPU_BASE,
|
||||
ARC_CPU_HOST,
|
||||
ARC_CPU_GRAPHICS,
|
||||
ARC_CPU_AUDIO,
|
||||
};
|
||||
|
||||
if ((arc_ops_hash = hash_new ()) == NULL
|
||||
|| (arc_suffix_hash = hash_new ()) == NULL
|
||||
|| (arc_reg_hash = hash_new ()) == NULL)
|
||||
as_fatal ("Virtual memory exhausted");
|
||||
|
||||
if (!bfd_set_arch_mach (stdoutput, bfd_arch_arc, mach))
|
||||
as_warn ("could not set architecture and machine");
|
||||
|
||||
/* This initializes a few things in arc-opc.c that we need.
|
||||
This must be called before the various arc_xxx_supported fns. */
|
||||
arc_opcode_init_tables (cpu_type_map[mach]);
|
||||
|
||||
#if 0
|
||||
for (i = 0; i < arc_opcodes_count; i++)
|
||||
hash_insert (arc_ops_hash, arc_opcodes[i].name, (PTR) (arc_opcodes + i));
|
||||
@ -172,6 +209,8 @@ md_begin ()
|
||||
last = "";
|
||||
for (i = 0; i < arc_suffixes_count; i++)
|
||||
{
|
||||
if (! arc_opval_supported (&arc_suffixes[i]))
|
||||
continue;
|
||||
if (strcmp (arc_suffixes[i].name, last) != 0)
|
||||
hash_insert (arc_suffix_hash, arc_suffixes[i].name, (PTR) (arc_suffixes + i));
|
||||
last = arc_suffixes[i].name;
|
||||
@ -179,10 +218,14 @@ md_begin ()
|
||||
|
||||
/* ??? This is the simple version. See tc-arm.c for something snazzier. */
|
||||
for (i = 0; i < arc_reg_names_count; i++)
|
||||
hash_insert (arc_reg_hash, arc_reg_names[i].name, (PTR) (arc_reg_names + i));
|
||||
{
|
||||
if (! arc_opval_supported (&arc_reg_names[i]))
|
||||
continue;
|
||||
hash_insert (arc_reg_hash, arc_reg_names[i].name, (PTR) (arc_reg_names + i));
|
||||
}
|
||||
|
||||
/* This initializes a few things in arc-opc.c that we need. */
|
||||
arc_opcode_init_tables (have_mult ? ARC_HAVE_MULT_SHIFT : 0);
|
||||
/* Tell `s_cpu' it's too late. */
|
||||
cpu_tables_init_p = 1;
|
||||
}
|
||||
|
||||
/* Insert an operand value into an instruction.
|
||||
@ -275,6 +318,15 @@ md_assemble (str)
|
||||
char *start;
|
||||
arc_insn insn;
|
||||
bfd_reloc_code_real_type reloc;
|
||||
static int init_tables_p = 0;
|
||||
|
||||
/* Opcode table initialization is deferred until here because we have to
|
||||
wait for a possible .cpu command. */
|
||||
if (!init_tables_p)
|
||||
{
|
||||
init_opcode_tables (arc_mach_type);
|
||||
init_tables_p = 1;
|
||||
}
|
||||
|
||||
/* Skip leading white space. */
|
||||
while (isspace (*str))
|
||||
@ -294,6 +346,7 @@ md_assemble (str)
|
||||
|
||||
/* Keep looking until we find a match. If we haven't found a match, and the
|
||||
first character no longer matches, we needn't look any further. */
|
||||
|
||||
start = str;
|
||||
for ( ; opcode < opcode_end && *opcode->syntax == *start; ++opcode)
|
||||
{
|
||||
@ -302,6 +355,10 @@ md_assemble (str)
|
||||
struct arc_fixup fixups[MAX_INSN_FIXUPS];
|
||||
int fc,limm_reloc_p;
|
||||
|
||||
/* Is this opcode supported by the selected cpu? */
|
||||
if (! arc_opcode_supported (opcode))
|
||||
continue;
|
||||
|
||||
/* Scan the syntax string. If it doesn't match, try the next one. */
|
||||
|
||||
arc_opcode_init_insert ();
|
||||
@ -583,18 +640,26 @@ md_assemble (str)
|
||||
if (*str != '\0')
|
||||
as_bad ("junk at end of line: `%s'", str);
|
||||
|
||||
/* Write out the instruction. */
|
||||
f = frag_more (4);
|
||||
md_number_to_chars (f, insn, 4);
|
||||
|
||||
/* Write out the instruction.
|
||||
It is important to fetch enough space in one call to `frag_more'.
|
||||
We use (f - frag_now->fr_literal) to compute where we are and we
|
||||
don't want frag_now to change between calls. */
|
||||
if (arc_opcode_limm_p (&limm))
|
||||
{
|
||||
char *f2 = frag_more (4);
|
||||
md_number_to_chars (f2, limm, 4);
|
||||
f = frag_more (8);
|
||||
md_number_to_chars (f, insn, 4);
|
||||
md_number_to_chars (f + 4, limm, 4);
|
||||
}
|
||||
else if (limm_reloc_p)
|
||||
/* Ahh! We need a limm reloc, but the tables think we don't. */
|
||||
abort ();
|
||||
{
|
||||
/* We need a limm reloc, but the tables think we don't. */
|
||||
abort ();
|
||||
}
|
||||
else
|
||||
{
|
||||
f = frag_more (4);
|
||||
md_number_to_chars (f, insn, 4);
|
||||
}
|
||||
|
||||
/* Create any fixups. At this point we do not use a
|
||||
bfd_reloc_code_real_type, but instead just use the operand index.
|
||||
@ -625,150 +690,8 @@ md_assemble (str)
|
||||
as_bad ("bad instruction `%s'", start);
|
||||
}
|
||||
|
||||
/*
|
||||
* sort of like s_lcomm
|
||||
*
|
||||
*/
|
||||
#ifndef OBJ_ELF
|
||||
static int max_alignment = 15;
|
||||
#endif
|
||||
|
||||
static void
|
||||
s_reserve (ignore)
|
||||
int ignore;
|
||||
{
|
||||
char *name;
|
||||
char *p;
|
||||
char c;
|
||||
int align;
|
||||
int size;
|
||||
int temp;
|
||||
symbolS *symbolP;
|
||||
|
||||
name = input_line_pointer;
|
||||
c = get_symbol_end ();
|
||||
p = input_line_pointer;
|
||||
*p = c;
|
||||
SKIP_WHITESPACE ();
|
||||
|
||||
if (*input_line_pointer != ',')
|
||||
{
|
||||
as_bad ("Expected comma after name");
|
||||
ignore_rest_of_line ();
|
||||
return;
|
||||
}
|
||||
|
||||
++input_line_pointer;
|
||||
|
||||
if ((size = get_absolute_expression ()) < 0)
|
||||
{
|
||||
as_bad ("BSS length (%d.) <0! Ignored.", size);
|
||||
ignore_rest_of_line ();
|
||||
return;
|
||||
} /* bad length */
|
||||
|
||||
*p = 0;
|
||||
symbolP = symbol_find_or_make (name);
|
||||
*p = c;
|
||||
|
||||
if (strncmp (input_line_pointer, ",\"bss\"", 6) != 0
|
||||
&& strncmp (input_line_pointer, ",\".bss\"", 7) != 0)
|
||||
{
|
||||
as_bad ("bad .reserve segment -- expected BSS segment");
|
||||
return;
|
||||
}
|
||||
|
||||
if (input_line_pointer[2] == '.')
|
||||
input_line_pointer += 7;
|
||||
else
|
||||
input_line_pointer += 6;
|
||||
SKIP_WHITESPACE ();
|
||||
|
||||
if (*input_line_pointer == ',')
|
||||
{
|
||||
++input_line_pointer;
|
||||
|
||||
SKIP_WHITESPACE ();
|
||||
if (*input_line_pointer == '\n')
|
||||
{
|
||||
as_bad ("Missing alignment");
|
||||
return;
|
||||
}
|
||||
|
||||
align = get_absolute_expression ();
|
||||
#ifndef OBJ_ELF
|
||||
if (align > max_alignment)
|
||||
{
|
||||
align = max_alignment;
|
||||
as_warn ("Alignment too large: %d. assumed.", align);
|
||||
}
|
||||
#endif
|
||||
if (align < 0)
|
||||
{
|
||||
align = 0;
|
||||
as_warn ("Alignment negative. 0 assumed.");
|
||||
}
|
||||
|
||||
record_alignment (bss_section, align);
|
||||
|
||||
/* convert to a power of 2 alignment */
|
||||
for (temp = 0; (align & 1) == 0; align >>= 1, ++temp);;
|
||||
|
||||
if (align != 1)
|
||||
{
|
||||
as_bad ("Alignment not a power of 2");
|
||||
ignore_rest_of_line ();
|
||||
return;
|
||||
} /* not a power of two */
|
||||
|
||||
align = temp;
|
||||
} /* if has optional alignment */
|
||||
else
|
||||
align = 0;
|
||||
|
||||
if ((S_GET_SEGMENT (symbolP) == bss_section
|
||||
|| !S_IS_DEFINED (symbolP))
|
||||
#ifdef OBJ_AOUT
|
||||
&& S_GET_OTHER (symbolP) == 0
|
||||
&& S_GET_DESC (symbolP) == 0
|
||||
#endif
|
||||
)
|
||||
{
|
||||
if (! need_pass_2)
|
||||
{
|
||||
char *pfrag;
|
||||
segT current_seg = now_seg;
|
||||
subsegT current_subseg = now_subseg;
|
||||
|
||||
subseg_set (bss_section, 1); /* switch to bss */
|
||||
|
||||
if (align)
|
||||
frag_align (align, 0); /* do alignment */
|
||||
|
||||
/* detach from old frag */
|
||||
if (S_GET_SEGMENT(symbolP) == bss_section)
|
||||
symbolP->sy_frag->fr_symbol = NULL;
|
||||
|
||||
symbolP->sy_frag = frag_now;
|
||||
pfrag = frag_var (rs_org, 1, 1, (relax_substateT)0, symbolP,
|
||||
size, (char *)0);
|
||||
*pfrag = 0;
|
||||
|
||||
S_SET_SEGMENT (symbolP, bss_section);
|
||||
|
||||
subseg_set (current_seg, current_subseg);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
as_warn("Ignoring attempt to re-define symbol %s.", name);
|
||||
} /* if not redefining */
|
||||
|
||||
demand_empty_rest_of_line ();
|
||||
}
|
||||
|
||||
static void
|
||||
s_common (ignore)
|
||||
arc_common (ignore)
|
||||
int ignore;
|
||||
{
|
||||
char *name;
|
||||
@ -785,7 +708,7 @@ s_common (ignore)
|
||||
SKIP_WHITESPACE ();
|
||||
if (*input_line_pointer != ',')
|
||||
{
|
||||
as_bad ("Expected comma after symbol-name");
|
||||
as_bad ("expected comma after symbol-name");
|
||||
ignore_rest_of_line ();
|
||||
return;
|
||||
}
|
||||
@ -802,7 +725,7 @@ s_common (ignore)
|
||||
*p = c;
|
||||
if (S_IS_DEFINED (symbolP))
|
||||
{
|
||||
as_bad ("Ignoring attempt to re-define symbol");
|
||||
as_bad ("ignoring attempt to re-define symbol");
|
||||
ignore_rest_of_line ();
|
||||
return;
|
||||
}
|
||||
@ -824,7 +747,7 @@ s_common (ignore)
|
||||
assert (symbolP->sy_frag == &zero_address_frag);
|
||||
if (*input_line_pointer != ',')
|
||||
{
|
||||
as_bad ("Expected comma after common length");
|
||||
as_bad ("expected comma after common length");
|
||||
ignore_rest_of_line ();
|
||||
return;
|
||||
}
|
||||
@ -921,59 +844,105 @@ s_common (ignore)
|
||||
}
|
||||
}
|
||||
|
||||
/* Select the cpu we're assembling for. */
|
||||
|
||||
static void
|
||||
s_seg (ignore)
|
||||
arc_cpu (ignore)
|
||||
int ignore;
|
||||
{
|
||||
int mach;
|
||||
char c;
|
||||
char *cpu;
|
||||
static int seen_p = 0;
|
||||
|
||||
if (strncmp (input_line_pointer, "\"text\"", 6) == 0)
|
||||
/* Allow only one .cpu. */
|
||||
if (seen_p)
|
||||
{
|
||||
input_line_pointer += 6;
|
||||
s_text (0);
|
||||
as_bad ("only one .cpu command allowed");
|
||||
ignore_rest_of_line ();
|
||||
return;
|
||||
}
|
||||
if (strncmp (input_line_pointer, "\"data\"", 6) == 0)
|
||||
seen_p = 1;
|
||||
|
||||
/* If an instruction has already been seen, it's too late. */
|
||||
if (cpu_tables_init_p)
|
||||
{
|
||||
input_line_pointer += 6;
|
||||
s_data (0);
|
||||
as_bad (".cpu command must appear before any instructions");
|
||||
ignore_rest_of_line ();
|
||||
return;
|
||||
}
|
||||
if (strncmp (input_line_pointer, "\"data1\"", 7) == 0)
|
||||
{
|
||||
input_line_pointer += 7;
|
||||
s_data1 ();
|
||||
return;
|
||||
}
|
||||
if (strncmp (input_line_pointer, "\"bss\"", 5) == 0)
|
||||
{
|
||||
input_line_pointer += 5;
|
||||
/* We only support 2 segments -- text and data -- for now, so
|
||||
things in the "bss segment" will have to go into data for now.
|
||||
You can still allocate SEG_BSS stuff with .lcomm or .reserve. */
|
||||
subseg_set (data_section, 255); /* FIXME-SOMEDAY */
|
||||
return;
|
||||
}
|
||||
as_bad ("Unknown segment type");
|
||||
|
||||
cpu = input_line_pointer;
|
||||
c = get_symbol_end ();
|
||||
mach = arc_get_mach (cpu);
|
||||
*input_line_pointer = c;
|
||||
if (mach == -1)
|
||||
goto bad_cpu;
|
||||
|
||||
/* Kind of overkill but what the heck. */
|
||||
demand_empty_rest_of_line ();
|
||||
|
||||
/* The cpu may have been selected on the command line.
|
||||
The choices must match. */
|
||||
if (mach_type_specified && mach != arc_mach_type)
|
||||
as_bad (".cpu conflicts with -mcpu flag");
|
||||
else
|
||||
{
|
||||
arc_mach_type = mach;
|
||||
if (!bfd_set_arch_mach (stdoutput, bfd_arch_arc, mach))
|
||||
as_warn ("could not set architecture and machine");
|
||||
}
|
||||
return;
|
||||
|
||||
bad_cpu:
|
||||
as_bad ("bad .cpu op");
|
||||
ignore_rest_of_line ();
|
||||
}
|
||||
|
||||
static void
|
||||
s_data1 ()
|
||||
{
|
||||
subseg_set (data_section, 1);
|
||||
demand_empty_rest_of_line ();
|
||||
}
|
||||
#if 0
|
||||
/* The .rename pseudo-op. This is used by gcc to implement
|
||||
-mmangle-cpu-libgcc. */
|
||||
|
||||
static void
|
||||
s_proc (ignore)
|
||||
arc_rename (ignore)
|
||||
int ignore;
|
||||
{
|
||||
while (!is_end_of_line[(unsigned char) *input_line_pointer])
|
||||
char *name,*new;
|
||||
char c;
|
||||
symbolS *sym;
|
||||
int len;
|
||||
|
||||
name = input_line_pointer;
|
||||
c = get_symbol_end ();
|
||||
sym = symbol_find_or_make (name);
|
||||
*input_line_pointer = c;
|
||||
|
||||
if (*input_line_pointer != ',')
|
||||
{
|
||||
++input_line_pointer;
|
||||
as_bad ("missing rename string");
|
||||
ignore_rest_of_line ();
|
||||
return;
|
||||
}
|
||||
++input_line_pointer;
|
||||
SKIP_WHITESPACE ();
|
||||
|
||||
name = input_line_pointer;
|
||||
c = get_symbol_end ();
|
||||
if (*name == '\0')
|
||||
{
|
||||
*input_line_pointer = c;
|
||||
as_bad ("invalid symbol to rename to");
|
||||
ignore_rest_of_line ();
|
||||
return;
|
||||
}
|
||||
new = (char *) xmalloc (strlen (name) + 1);
|
||||
strcpy (new, name);
|
||||
*input_line_pointer = c;
|
||||
sym->sy_tc.real_name = new;
|
||||
|
||||
demand_empty_rest_of_line ();
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Turn a string in input_line_pointer into a floating point constant of type
|
||||
type, and store the appropriate bytes in *litP. The number of LITTLENUMS
|
||||
@ -1034,7 +1003,11 @@ md_number_to_chars (buf, val, n)
|
||||
valueT val;
|
||||
int n;
|
||||
{
|
||||
number_to_chars_bigendian (buf, val, n);
|
||||
/* The ARC isn't bi-endian. Yet. */
|
||||
if (target_big_endian)
|
||||
number_to_chars_bigendian (buf, val, n);
|
||||
else
|
||||
number_to_chars_littleendian (buf, val, n);
|
||||
}
|
||||
|
||||
/* Round up a section size to the appropriate boundary. */
|
||||
@ -1106,11 +1079,8 @@ md_pcrel_from (fixP)
|
||||
{
|
||||
if (fixP->fx_addsy != (symbolS *) NULL
|
||||
&& ! S_IS_DEFINED (fixP->fx_addsy))
|
||||
{
|
||||
/* This makes a branch to an undefined symbol be a branch to the
|
||||
current location. */
|
||||
return 4;
|
||||
}
|
||||
/* Return offset from PC to delay slot. Offsets are from there. */
|
||||
return 4;
|
||||
|
||||
/* Return the address of the delay slot. */
|
||||
return fixP->fx_frag->fr_address + fixP->fx_where + fixP->fx_size;
|
||||
@ -1181,10 +1151,16 @@ md_apply_fix (fixP, valueP)
|
||||
/* Fetch the instruction, insert the fully resolved operand
|
||||
value, and stuff the instruction back again. */
|
||||
where = fixP->fx_frag->fr_literal + fixP->fx_where;
|
||||
insn = bfd_getb32 ((unsigned char *) where);
|
||||
if (target_big_endian)
|
||||
insn = bfd_getb32 ((unsigned char *) where);
|
||||
else
|
||||
insn = bfd_getl32 ((unsigned char *) where);
|
||||
insn = arc_insert_operand (insn, operand, -1, NULL, (offsetT) value,
|
||||
fixP->fx_file, fixP->fx_line);
|
||||
bfd_putb32 ((bfd_vma) insn, (unsigned char *) where);
|
||||
if (target_big_endian)
|
||||
bfd_putb32 ((bfd_vma) insn, (unsigned char *) where);
|
||||
else
|
||||
bfd_putl32 ((bfd_vma) insn, (unsigned char *) where);
|
||||
|
||||
if (fixP->fx_done)
|
||||
{
|
||||
@ -1270,3 +1246,20 @@ tc_gen_reloc (section, fixP)
|
||||
|
||||
return reloc;
|
||||
}
|
||||
|
||||
/* Frobbers. */
|
||||
|
||||
#if 0
|
||||
/* Set the real name if the .rename pseudo-op was used.
|
||||
Return 1 if the symbol should not be included in the symbol table. */
|
||||
|
||||
int
|
||||
arc_frob_symbol (sym)
|
||||
symbolS *sym;
|
||||
{
|
||||
if (sym->sy_tc.real_name != (char *) NULL)
|
||||
S_SET_NAME (sym, sym->sy_tc.real_name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user