Jim fixed the fixups for conditional and unconditional branches.
Added code to support the bss and common sections in thr ZDA and SDA areas.
This commit is contained in:
parent
5ff4668dea
commit
c280609300
@ -1,3 +1,26 @@
|
|||||||
|
Fri Oct 10 17:48:29 1997 Nick Clifton <nickc@cygnus.com>
|
||||||
|
|
||||||
|
* config/tc-v850.c (md_relax_table): Add support for relaxing
|
||||||
|
unconditional branches. This patch is courtesy of Jim Wilson.
|
||||||
|
(md_convert_frag): Fix relaxing of branches. This patch is
|
||||||
|
courtesy of Jim Wilson.
|
||||||
|
(md_assemble): Create different fixups for conditional and
|
||||||
|
unconditional branches. This patch is courtesy of Jim Wilson.
|
||||||
|
(md_estimate_size_before_relax): Estimate size of variable part of
|
||||||
|
fixup based on whether it is for a conditional or an unconditional
|
||||||
|
branch. This patch is courtesy of Jim Wilson.
|
||||||
|
(v850_sdata, v850_tdata, v850_zdata, v850_sbss, v850_tbss,
|
||||||
|
v850_zbss, v850_rosdata, v850_rozdata, v850_bss): Add call to
|
||||||
|
obj_elf_section_change_hook().
|
||||||
|
(v850_comm): New function.
|
||||||
|
(md_pseudo_table): Add new pseudo ops .zcomm, .scomm and .tcomm.
|
||||||
|
(md_begin): Add bss flag to seg_info of bss sections.
|
||||||
|
|
||||||
|
Add support for .scommon, .tcommon and .zcommon sections.
|
||||||
|
|
||||||
|
* config/tc-v850.h (ELF_TC_SPECIAL_SECTIONS): Add .scommon,
|
||||||
|
.zcommon, .tbss, .call_table_data and .call_table_text.
|
||||||
|
|
||||||
Fri Oct 10 15:01:14 1997 Doug Evans <dje@canuck.cygnus.com>
|
Fri Oct 10 15:01:14 1997 Doug Evans <dje@canuck.cygnus.com>
|
||||||
|
|
||||||
* configure.in (sparc): Set DEFAULT_ARCH from correct target.
|
* configure.in (sparc): Set DEFAULT_ARCH from correct target.
|
||||||
|
@ -24,6 +24,10 @@
|
|||||||
#include "subsegs.h"
|
#include "subsegs.h"
|
||||||
#include "opcode/v850.h"
|
#include "opcode/v850.h"
|
||||||
|
|
||||||
|
#define AREA_ZDA 0
|
||||||
|
#define AREA_SDA 1
|
||||||
|
#define AREA_TDA 2
|
||||||
|
|
||||||
/* sign-extend a 16-bit number */
|
/* sign-extend a 16-bit number */
|
||||||
#define SEXT16(x) ((((x) & 0xffff) ^ (~ 0x7fff)) + 0x8000)
|
#define SEXT16(x) ((((x) & 0xffff) ^ (~ 0x7fff)) + 0x8000)
|
||||||
|
|
||||||
@ -69,9 +73,14 @@ const char EXP_CHARS[] = "eE";
|
|||||||
const char FLT_CHARS[] = "dD";
|
const char FLT_CHARS[] = "dD";
|
||||||
|
|
||||||
|
|
||||||
const relax_typeS md_relax_table[] = {
|
const relax_typeS md_relax_table[] =
|
||||||
{0xff, -0x100, 2, 1},
|
{
|
||||||
|
/* Conditional branches. */
|
||||||
|
{0xff, -0x100, 2, 1},
|
||||||
{0x1fffff, -0x200000, 6, 0},
|
{0x1fffff, -0x200000, 6, 0},
|
||||||
|
/* Unconditional branches. */
|
||||||
|
{0xff, -0x100, 2, 3},
|
||||||
|
{0x1fffff, -0x200000, 4, 0},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -83,6 +92,9 @@ static segT tbss_section = NULL;
|
|||||||
static segT zbss_section = NULL;
|
static segT zbss_section = NULL;
|
||||||
static segT rosdata_section = NULL;
|
static segT rosdata_section = NULL;
|
||||||
static segT rozdata_section = NULL;
|
static segT rozdata_section = NULL;
|
||||||
|
static segT scommon_section = NULL;
|
||||||
|
static segT tcommon_section = NULL;
|
||||||
|
static segT zcommon_section = NULL;
|
||||||
/* start-sanitize-v850e */
|
/* start-sanitize-v850e */
|
||||||
static segT call_table_data_section = NULL;
|
static segT call_table_data_section = NULL;
|
||||||
static segT call_table_text_section = NULL;
|
static segT call_table_text_section = NULL;
|
||||||
@ -109,14 +121,18 @@ static int fc;
|
|||||||
void
|
void
|
||||||
v850_sdata (int ignore)
|
v850_sdata (int ignore)
|
||||||
{
|
{
|
||||||
subseg_set (sdata_section, (subsegT) get_absolute_expression ());
|
obj_elf_section_change_hook();
|
||||||
|
|
||||||
|
subseg_set (sdata_section, (subsegT) get_absolute_expression ());
|
||||||
|
|
||||||
demand_empty_rest_of_line ();
|
demand_empty_rest_of_line ();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
v850_tdata (int ignore)
|
v850_tdata (int ignore)
|
||||||
{
|
{
|
||||||
|
obj_elf_section_change_hook();
|
||||||
|
|
||||||
subseg_set (tdata_section, (subsegT) get_absolute_expression ());
|
subseg_set (tdata_section, (subsegT) get_absolute_expression ());
|
||||||
|
|
||||||
demand_empty_rest_of_line ();
|
demand_empty_rest_of_line ();
|
||||||
@ -125,6 +141,8 @@ v850_tdata (int ignore)
|
|||||||
void
|
void
|
||||||
v850_zdata (int ignore)
|
v850_zdata (int ignore)
|
||||||
{
|
{
|
||||||
|
obj_elf_section_change_hook();
|
||||||
|
|
||||||
subseg_set (zdata_section, (subsegT) get_absolute_expression ());
|
subseg_set (zdata_section, (subsegT) get_absolute_expression ());
|
||||||
|
|
||||||
demand_empty_rest_of_line ();
|
demand_empty_rest_of_line ();
|
||||||
@ -133,6 +151,8 @@ v850_zdata (int ignore)
|
|||||||
void
|
void
|
||||||
v850_sbss (int ignore)
|
v850_sbss (int ignore)
|
||||||
{
|
{
|
||||||
|
obj_elf_section_change_hook();
|
||||||
|
|
||||||
subseg_set (sbss_section, (subsegT) get_absolute_expression ());
|
subseg_set (sbss_section, (subsegT) get_absolute_expression ());
|
||||||
|
|
||||||
demand_empty_rest_of_line ();
|
demand_empty_rest_of_line ();
|
||||||
@ -141,6 +161,8 @@ v850_sbss (int ignore)
|
|||||||
void
|
void
|
||||||
v850_tbss (int ignore)
|
v850_tbss (int ignore)
|
||||||
{
|
{
|
||||||
|
obj_elf_section_change_hook();
|
||||||
|
|
||||||
subseg_set (tbss_section, (subsegT) get_absolute_expression ());
|
subseg_set (tbss_section, (subsegT) get_absolute_expression ());
|
||||||
|
|
||||||
demand_empty_rest_of_line ();
|
demand_empty_rest_of_line ();
|
||||||
@ -149,6 +171,8 @@ v850_tbss (int ignore)
|
|||||||
void
|
void
|
||||||
v850_zbss (int ignore)
|
v850_zbss (int ignore)
|
||||||
{
|
{
|
||||||
|
obj_elf_section_change_hook();
|
||||||
|
|
||||||
subseg_set (zbss_section, (subsegT) get_absolute_expression ());
|
subseg_set (zbss_section, (subsegT) get_absolute_expression ());
|
||||||
|
|
||||||
demand_empty_rest_of_line ();
|
demand_empty_rest_of_line ();
|
||||||
@ -157,6 +181,8 @@ v850_zbss (int ignore)
|
|||||||
void
|
void
|
||||||
v850_rosdata (int ignore)
|
v850_rosdata (int ignore)
|
||||||
{
|
{
|
||||||
|
obj_elf_section_change_hook();
|
||||||
|
|
||||||
subseg_set (rosdata_section, (subsegT) get_absolute_expression ());
|
subseg_set (rosdata_section, (subsegT) get_absolute_expression ());
|
||||||
|
|
||||||
demand_empty_rest_of_line ();
|
demand_empty_rest_of_line ();
|
||||||
@ -165,6 +191,8 @@ v850_rosdata (int ignore)
|
|||||||
void
|
void
|
||||||
v850_rozdata (int ignore)
|
v850_rozdata (int ignore)
|
||||||
{
|
{
|
||||||
|
obj_elf_section_change_hook();
|
||||||
|
|
||||||
subseg_set (rozdata_section, (subsegT) get_absolute_expression ());
|
subseg_set (rozdata_section, (subsegT) get_absolute_expression ());
|
||||||
|
|
||||||
demand_empty_rest_of_line ();
|
demand_empty_rest_of_line ();
|
||||||
@ -174,6 +202,8 @@ v850_rozdata (int ignore)
|
|||||||
void
|
void
|
||||||
v850_call_table_data (int ignore)
|
v850_call_table_data (int ignore)
|
||||||
{
|
{
|
||||||
|
obj_elf_section_change_hook();
|
||||||
|
|
||||||
subseg_set (call_table_data_section, (subsegT) get_absolute_expression ());
|
subseg_set (call_table_data_section, (subsegT) get_absolute_expression ());
|
||||||
|
|
||||||
demand_empty_rest_of_line ();
|
demand_empty_rest_of_line ();
|
||||||
@ -182,30 +212,14 @@ v850_call_table_data (int ignore)
|
|||||||
void
|
void
|
||||||
v850_call_table_text (int ignore)
|
v850_call_table_text (int ignore)
|
||||||
{
|
{
|
||||||
|
obj_elf_section_change_hook();
|
||||||
|
|
||||||
subseg_set (call_table_text_section, (subsegT) get_absolute_expression ());
|
subseg_set (call_table_text_section, (subsegT) get_absolute_expression ());
|
||||||
|
|
||||||
demand_empty_rest_of_line ();
|
demand_empty_rest_of_line ();
|
||||||
}
|
}
|
||||||
/* end-sanitize-v850e */
|
/* end-sanitize-v850e */
|
||||||
|
|
||||||
static void
|
|
||||||
v850_section (int arg)
|
|
||||||
{
|
|
||||||
char saved_c;
|
|
||||||
char * ptr;
|
|
||||||
|
|
||||||
for (ptr = input_line_pointer; * ptr != '\n' && * ptr != 0; ptr ++)
|
|
||||||
if (* ptr == ',' && ptr[1] == '.')
|
|
||||||
break;
|
|
||||||
|
|
||||||
saved_c = * ptr;
|
|
||||||
* ptr = ';';
|
|
||||||
|
|
||||||
obj_elf_section (arg);
|
|
||||||
|
|
||||||
* ptr = saved_c;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
v850_bss (int ignore)
|
v850_bss (int ignore)
|
||||||
{
|
{
|
||||||
@ -214,7 +228,7 @@ v850_bss (int ignore)
|
|||||||
obj_elf_section_change_hook();
|
obj_elf_section_change_hook();
|
||||||
|
|
||||||
subseg_set (bss_section, (subsegT) temp);
|
subseg_set (bss_section, (subsegT) temp);
|
||||||
|
|
||||||
demand_empty_rest_of_line ();
|
demand_empty_rest_of_line ();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -231,6 +245,225 @@ v850_offset (int ignore)
|
|||||||
demand_empty_rest_of_line ();
|
demand_empty_rest_of_line ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Copied from obj_elf_common() in gas/config/obj-elf.c */
|
||||||
|
static void
|
||||||
|
v850_comm (area)
|
||||||
|
int area;
|
||||||
|
{
|
||||||
|
char * name;
|
||||||
|
char c;
|
||||||
|
char * p;
|
||||||
|
int temp;
|
||||||
|
int size;
|
||||||
|
symbolS * symbolP;
|
||||||
|
int have_align;
|
||||||
|
|
||||||
|
name = input_line_pointer;
|
||||||
|
c = get_symbol_end ();
|
||||||
|
/* just after name is now '\0' */
|
||||||
|
p = input_line_pointer;
|
||||||
|
*p = c;
|
||||||
|
SKIP_WHITESPACE ();
|
||||||
|
if (*input_line_pointer != ',')
|
||||||
|
{
|
||||||
|
as_bad ("Expected comma after symbol-name");
|
||||||
|
ignore_rest_of_line ();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
input_line_pointer++; /* skip ',' */
|
||||||
|
if ((temp = get_absolute_expression ()) < 0)
|
||||||
|
{
|
||||||
|
as_bad (".COMMon length (%d.) <0! Ignored.", temp);
|
||||||
|
ignore_rest_of_line ();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
size = temp;
|
||||||
|
*p = 0;
|
||||||
|
symbolP = symbol_find_or_make (name);
|
||||||
|
*p = c;
|
||||||
|
if (S_IS_DEFINED (symbolP) && ! S_IS_COMMON (symbolP))
|
||||||
|
{
|
||||||
|
as_bad ("Ignoring attempt to re-define symbol");
|
||||||
|
ignore_rest_of_line ();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (S_GET_VALUE (symbolP) != 0)
|
||||||
|
{
|
||||||
|
if (S_GET_VALUE (symbolP) != size)
|
||||||
|
{
|
||||||
|
as_warn ("Length of .comm \"%s\" is already %ld. Not changed to %d.",
|
||||||
|
S_GET_NAME (symbolP), (long) S_GET_VALUE (symbolP), size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
know (symbolP->sy_frag == &zero_address_frag);
|
||||||
|
if (*input_line_pointer != ',')
|
||||||
|
have_align = 0;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
have_align = 1;
|
||||||
|
input_line_pointer++;
|
||||||
|
SKIP_WHITESPACE ();
|
||||||
|
}
|
||||||
|
if (! have_align || *input_line_pointer != '"')
|
||||||
|
{
|
||||||
|
if (! have_align)
|
||||||
|
temp = 0;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
temp = get_absolute_expression ();
|
||||||
|
if (temp < 0)
|
||||||
|
{
|
||||||
|
temp = 0;
|
||||||
|
as_warn ("Common alignment negative; 0 assumed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (symbolP->local)
|
||||||
|
{
|
||||||
|
segT old_sec;
|
||||||
|
int old_subsec;
|
||||||
|
char * pfrag;
|
||||||
|
int align;
|
||||||
|
|
||||||
|
/* allocate_bss: */
|
||||||
|
old_sec = now_seg;
|
||||||
|
old_subsec = now_subseg;
|
||||||
|
if (temp)
|
||||||
|
{
|
||||||
|
/* convert to a power of 2 alignment */
|
||||||
|
for (align = 0; (temp & 1) == 0; temp >>= 1, ++align);
|
||||||
|
if (temp != 1)
|
||||||
|
{
|
||||||
|
as_bad ("Common alignment not a power of 2");
|
||||||
|
ignore_rest_of_line ();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
align = 0;
|
||||||
|
switch (area)
|
||||||
|
{
|
||||||
|
case AREA_SDA:
|
||||||
|
record_alignment (sbss_section, align);
|
||||||
|
obj_elf_section_change_hook();
|
||||||
|
subseg_set (sbss_section, 0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AREA_ZDA:
|
||||||
|
record_alignment (zbss_section, align);
|
||||||
|
obj_elf_section_change_hook();
|
||||||
|
subseg_set (zbss_section, 0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AREA_TDA:
|
||||||
|
record_alignment (tbss_section, align);
|
||||||
|
obj_elf_section_change_hook();
|
||||||
|
subseg_set (tbss_section, 0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (align)
|
||||||
|
frag_align (align, 0, 0);
|
||||||
|
|
||||||
|
switch (area)
|
||||||
|
{
|
||||||
|
case AREA_SDA:
|
||||||
|
if (S_GET_SEGMENT (symbolP) == sbss_section)
|
||||||
|
symbolP->sy_frag->fr_symbol = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AREA_ZDA:
|
||||||
|
if (S_GET_SEGMENT (symbolP) == zbss_section)
|
||||||
|
symbolP->sy_frag->fr_symbol = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AREA_TDA:
|
||||||
|
if (S_GET_SEGMENT (symbolP) == tbss_section)
|
||||||
|
symbolP->sy_frag->fr_symbol = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
symbolP->sy_frag = frag_now;
|
||||||
|
pfrag = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP,
|
||||||
|
(offsetT) size, (char *) 0);
|
||||||
|
*pfrag = 0;
|
||||||
|
S_SET_SIZE (symbolP, size);
|
||||||
|
|
||||||
|
switch (area)
|
||||||
|
{
|
||||||
|
case AREA_SDA: S_SET_SEGMENT (symbolP, sbss_section); break;
|
||||||
|
case AREA_ZDA: S_SET_SEGMENT (symbolP, zbss_section); break;
|
||||||
|
case AREA_TDA: S_SET_SEGMENT (symbolP, tbss_section); break;
|
||||||
|
default:
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
S_CLEAR_EXTERNAL (symbolP);
|
||||||
|
obj_elf_section_change_hook();
|
||||||
|
subseg_set (old_sec, old_subsec);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
allocate_common:
|
||||||
|
S_SET_VALUE (symbolP, (valueT) size);
|
||||||
|
S_SET_ALIGN (symbolP, temp);
|
||||||
|
S_SET_EXTERNAL (symbolP);
|
||||||
|
|
||||||
|
switch (area)
|
||||||
|
{
|
||||||
|
case AREA_SDA: S_SET_SEGMENT (symbolP, scommon_section); break;
|
||||||
|
case AREA_ZDA: S_SET_SEGMENT (symbolP, zcommon_section); break;
|
||||||
|
case AREA_TDA: S_SET_SEGMENT (symbolP, tcommon_section); break;
|
||||||
|
default:
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
input_line_pointer++;
|
||||||
|
/* @@ Some use the dot, some don't. Can we get some consistency?? */
|
||||||
|
if (*input_line_pointer == '.')
|
||||||
|
input_line_pointer++;
|
||||||
|
/* @@ Some say data, some say bss. */
|
||||||
|
if (strncmp (input_line_pointer, "bss\"", 4)
|
||||||
|
&& strncmp (input_line_pointer, "data\"", 5))
|
||||||
|
{
|
||||||
|
while (*--input_line_pointer != '"')
|
||||||
|
;
|
||||||
|
input_line_pointer--;
|
||||||
|
goto bad_common_segment;
|
||||||
|
}
|
||||||
|
while (*input_line_pointer++ != '"')
|
||||||
|
;
|
||||||
|
goto allocate_common;
|
||||||
|
}
|
||||||
|
|
||||||
|
symbolP->bsym->flags |= BSF_OBJECT;
|
||||||
|
|
||||||
|
demand_empty_rest_of_line ();
|
||||||
|
return;
|
||||||
|
|
||||||
|
{
|
||||||
|
bad_common_segment:
|
||||||
|
p = input_line_pointer;
|
||||||
|
while (*p && *p != '\n')
|
||||||
|
p++;
|
||||||
|
c = *p;
|
||||||
|
*p = '\0';
|
||||||
|
as_bad ("bad .common segment %s", input_line_pointer + 1);
|
||||||
|
*p = c;
|
||||||
|
input_line_pointer = p;
|
||||||
|
ignore_rest_of_line ();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
set_machine (int number)
|
set_machine (int number)
|
||||||
{
|
{
|
||||||
@ -260,8 +493,10 @@ const pseudo_typeS md_pseudo_table[] =
|
|||||||
{"rozdata", v850_rozdata, 0},
|
{"rozdata", v850_rozdata, 0},
|
||||||
{"bss", v850_bss, 0},
|
{"bss", v850_bss, 0},
|
||||||
{"offset", v850_offset, 0},
|
{"offset", v850_offset, 0},
|
||||||
{"section", v850_section, 0},
|
|
||||||
{"word", cons, 4},
|
{"word", cons, 4},
|
||||||
|
{"zcomm", v850_comm, AREA_ZDA},
|
||||||
|
{"scomm", v850_comm, AREA_SDA},
|
||||||
|
{"tcomm", v850_comm, AREA_TDA},
|
||||||
{"v850", set_machine, 0},
|
{"v850", set_machine, 0},
|
||||||
/* start-sanitize-v850e */
|
/* start-sanitize-v850e */
|
||||||
{"call_table_data", v850_call_table_data, 0},
|
{"call_table_data", v850_call_table_data, 0},
|
||||||
@ -324,6 +559,7 @@ static const struct reg_name pre_defined_registers[] =
|
|||||||
static const struct reg_name system_registers[] =
|
static const struct reg_name system_registers[] =
|
||||||
{
|
{
|
||||||
/* start-sanitize-v850e */
|
/* start-sanitize-v850e */
|
||||||
|
|
||||||
{ "ctbp", 20 },
|
{ "ctbp", 20 },
|
||||||
{ "ctpc", 16 },
|
{ "ctpc", 16 },
|
||||||
{ "ctpsw", 17 },
|
{ "ctpsw", 17 },
|
||||||
@ -580,9 +816,10 @@ skip_white_space (void)
|
|||||||
* insn is the partially constructed instruction.
|
* insn is the partially constructed instruction.
|
||||||
* operand is the operand being inserted.
|
* operand is the operand being inserted.
|
||||||
*
|
*
|
||||||
* out: True if the parse completed successfully, False otherwise.
|
* out: NULL if the parse completed successfully, otherwise a
|
||||||
* If the parse completes the correct bit fields in the
|
* pointer to an error message is returned. If the parse
|
||||||
* instruction will be filled in.
|
* completes the correct bit fields in the instruction
|
||||||
|
* will be filled in.
|
||||||
*
|
*
|
||||||
* Parses register lists with the syntax:
|
* Parses register lists with the syntax:
|
||||||
*
|
*
|
||||||
@ -627,7 +864,7 @@ parse_register_list
|
|||||||
skip_white_space();
|
skip_white_space();
|
||||||
|
|
||||||
/* If the expression starts with a curly brace it is a register list.
|
/* If the expression starts with a curly brace it is a register list.
|
||||||
Otherwise it is a constant expression ,whoes bits indicate which
|
Otherwise it is a constant expression, whoes bits indicate which
|
||||||
registers are to be included in the list. */
|
registers are to be included in the list. */
|
||||||
|
|
||||||
if (* input_line_pointer != '{')
|
if (* input_line_pointer != '{')
|
||||||
@ -919,32 +1156,47 @@ md_convert_frag (abfd, sec, fragP)
|
|||||||
fragS * fragP;
|
fragS * fragP;
|
||||||
{
|
{
|
||||||
subseg_change (sec, 0);
|
subseg_change (sec, 0);
|
||||||
if (fragP->fr_subtype == 0)
|
|
||||||
|
/* In range conditional or unconditional branch. */
|
||||||
|
if (fragP->fr_subtype == 0 || fragP->fr_subtype == 2)
|
||||||
{
|
{
|
||||||
fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
|
fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
|
||||||
fragP->fr_offset, 1, BFD_RELOC_UNUSED + (int)fragP->fr_opcode);
|
fragP->fr_offset, 1, BFD_RELOC_UNUSED + (int)fragP->fr_opcode);
|
||||||
fragP->fr_var = 0;
|
fragP->fr_var = 0;
|
||||||
fragP->fr_fix += 2;
|
fragP->fr_fix += 2;
|
||||||
}
|
}
|
||||||
|
/* Out of range conditional branch. Emit a branch around a jump. */
|
||||||
else if (fragP->fr_subtype == 1)
|
else if (fragP->fr_subtype == 1)
|
||||||
{
|
{
|
||||||
|
unsigned char *buffer =
|
||||||
|
(unsigned char *) (fragP->fr_fix + fragP->fr_literal);
|
||||||
|
|
||||||
/* Reverse the condition of the first branch. */
|
/* Reverse the condition of the first branch. */
|
||||||
fragP->fr_literal[0] &= 0xf7;
|
buffer[0] ^= 0x08;
|
||||||
/* Mask off all the displacement bits. */
|
/* Mask off all the displacement bits. */
|
||||||
fragP->fr_literal[0] &= 0x8f;
|
buffer[0] &= 0x8f;
|
||||||
fragP->fr_literal[1] &= 0x07;
|
buffer[1] &= 0x07;
|
||||||
/* Now set the displacement bits so that we branch
|
/* Now set the displacement bits so that we branch
|
||||||
around the unconditional branch. */
|
around the unconditional branch. */
|
||||||
fragP->fr_literal[0] |= 0x30;
|
buffer[0] |= 0x30;
|
||||||
|
|
||||||
/* Now create the unconditional branch + fixup to the final
|
/* Now create the unconditional branch + fixup to the final
|
||||||
target. */
|
target. */
|
||||||
md_number_to_chars (&fragP->fr_literal[2], 0x00000780, 4);
|
md_number_to_chars (buffer + 2, 0x00000780, 4);
|
||||||
fix_new (fragP, fragP->fr_fix + 2, 4, fragP->fr_symbol,
|
fix_new (fragP, fragP->fr_fix + 2, 4, fragP->fr_symbol,
|
||||||
fragP->fr_offset, 1, BFD_RELOC_UNUSED + (int)fragP->fr_opcode + 1);
|
fragP->fr_offset, 1, BFD_RELOC_UNUSED + (int)fragP->fr_opcode + 1);
|
||||||
fragP->fr_var = 0;
|
fragP->fr_var = 0;
|
||||||
fragP->fr_fix += 6;
|
fragP->fr_fix += 6;
|
||||||
}
|
}
|
||||||
|
/* Out of range unconditional branch. Emit a jump. */
|
||||||
|
else if (fragP->fr_subtype == 3)
|
||||||
|
{
|
||||||
|
md_number_to_chars (fragP->fr_fix + fragP->fr_literal, 0x00000780, 4);
|
||||||
|
fix_new (fragP, fragP->fr_fix, 4, fragP->fr_symbol,
|
||||||
|
fragP->fr_offset, 1, BFD_RELOC_UNUSED + (int)fragP->fr_opcode + 1);
|
||||||
|
fragP->fr_var = 0;
|
||||||
|
fragP->fr_fix += 4;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
abort ();
|
abort ();
|
||||||
}
|
}
|
||||||
@ -1029,12 +1281,15 @@ md_begin ()
|
|||||||
|
|
||||||
sbss_section = subseg_new (".sbss", 0);
|
sbss_section = subseg_new (".sbss", 0);
|
||||||
bfd_set_section_flags (stdoutput, sbss_section, applicable & SEC_ALLOC);
|
bfd_set_section_flags (stdoutput, sbss_section, applicable & SEC_ALLOC);
|
||||||
|
seg_info (sbss_section)->bss = 1;
|
||||||
|
|
||||||
tbss_section = subseg_new (".tbss", 0);
|
tbss_section = subseg_new (".tbss", 0);
|
||||||
bfd_set_section_flags (stdoutput, tbss_section, applicable & SEC_ALLOC);
|
bfd_set_section_flags (stdoutput, tbss_section, applicable & SEC_ALLOC);
|
||||||
|
seg_info (tbss_section)->bss = 1;
|
||||||
|
|
||||||
zbss_section = subseg_new (".zbss", 0);
|
zbss_section = subseg_new (".zbss", 0);
|
||||||
bfd_set_section_flags (stdoutput, zbss_section, applicable & SEC_ALLOC);
|
bfd_set_section_flags (stdoutput, zbss_section, applicable & SEC_ALLOC);
|
||||||
|
seg_info (zbss_section)->bss = 1;
|
||||||
|
|
||||||
rosdata_section = subseg_new (".rosdata", 0);
|
rosdata_section = subseg_new (".rosdata", 0);
|
||||||
bfd_set_section_flags (stdoutput, rosdata_section, applicable & (SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_READONLY));
|
bfd_set_section_flags (stdoutput, rosdata_section, applicable & (SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_READONLY));
|
||||||
@ -1042,6 +1297,12 @@ md_begin ()
|
|||||||
rozdata_section = subseg_new (".rozdata", 0);
|
rozdata_section = subseg_new (".rozdata", 0);
|
||||||
bfd_set_section_flags (stdoutput, rozdata_section, applicable & (SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_READONLY));
|
bfd_set_section_flags (stdoutput, rozdata_section, applicable & (SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_READONLY));
|
||||||
|
|
||||||
|
scommon_section = subseg_new (".scommon", 0);
|
||||||
|
bfd_set_section_flags (stdoutput, scommon_section, applicable & (SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_DATA | SEC_HAS_CONTENTS | SEC_IS_COMMON));
|
||||||
|
|
||||||
|
zcommon_section = subseg_new (".zcommon", 0);
|
||||||
|
bfd_set_section_flags (stdoutput, zcommon_section, applicable & (SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_DATA | SEC_HAS_CONTENTS | SEC_IS_COMMON));
|
||||||
|
|
||||||
/* start-sanitize-v850e */
|
/* start-sanitize-v850e */
|
||||||
call_table_data_section = subseg_new (".call_table_data", 0);
|
call_table_data_section = subseg_new (".call_table_data", 0);
|
||||||
bfd_set_section_flags (stdoutput, call_table_data_section, applicable & (SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_DATA | SEC_HAS_CONTENTS));
|
bfd_set_section_flags (stdoutput, call_table_data_section, applicable & (SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_DATA | SEC_HAS_CONTENTS));
|
||||||
@ -1162,7 +1423,7 @@ v850_reloc_prefix (const struct v850_operand * operand)
|
|||||||
CHECK_ ("tdaoff", handle_tdaoff (operand));
|
CHECK_ ("tdaoff", handle_tdaoff (operand));
|
||||||
|
|
||||||
/* start-sanitize-v850e */
|
/* start-sanitize-v850e */
|
||||||
CHECK_ ("hilo", BFD_RELOC_32);
|
CHECK_ ("hilo", BFD_RELOC_32);
|
||||||
CHECK_ ("ctoff", handle_ctoff (operand));
|
CHECK_ ("ctoff", handle_ctoff (operand));
|
||||||
/* end-sanitize-v850e */
|
/* end-sanitize-v850e */
|
||||||
|
|
||||||
@ -1193,7 +1454,7 @@ md_assemble (str)
|
|||||||
unsigned extra_data_len;
|
unsigned extra_data_len;
|
||||||
unsigned long extra_data;
|
unsigned long extra_data;
|
||||||
char * saved_input_line_pointer;
|
char * saved_input_line_pointer;
|
||||||
|
|
||||||
/* Get the opcode. */
|
/* Get the opcode. */
|
||||||
for (s = str; *s != '\0' && ! isspace (*s); s++)
|
for (s = str; *s != '\0' && ! isspace (*s); s++)
|
||||||
continue;
|
continue;
|
||||||
@ -1491,7 +1752,7 @@ md_assemble (str)
|
|||||||
if (errmsg)
|
if (errmsg)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
/* fprintf (stderr, "insn: %x, operand %d, op: %d, add_number: %d\n", insn, opindex_ptr - opcode->operands, ex.X_op, ex.X_add_number ); */
|
/* fprintf (stderr, " insn: %x, operand %d, op: %d, add_number: %d\n", insn, opindex_ptr - opcode->operands, ex.X_op, ex.X_add_number); */
|
||||||
|
|
||||||
switch (ex.X_op)
|
switch (ex.X_op)
|
||||||
{
|
{
|
||||||
@ -1564,22 +1825,35 @@ md_assemble (str)
|
|||||||
|
|
||||||
input_line_pointer = str;
|
input_line_pointer = str;
|
||||||
|
|
||||||
/* Write out the instruction.
|
/* Write out the instruction. */
|
||||||
|
|
||||||
Four byte insns have an opcode with the two high bits on. */
|
|
||||||
if (relaxable && fc > 0)
|
if (relaxable && fc > 0)
|
||||||
{
|
{
|
||||||
f = frag_var (rs_machine_dependent, 6, 4, 0,
|
|
||||||
fixups[0].exp.X_add_symbol,
|
|
||||||
fixups[0].exp.X_add_number,
|
|
||||||
(char *)fixups[0].opindex);
|
|
||||||
insn_size = 2;
|
insn_size = 2;
|
||||||
md_number_to_chars (f, insn, insn_size);
|
|
||||||
md_number_to_chars (f + 2, 0, 4);
|
|
||||||
fc = 0;
|
fc = 0;
|
||||||
|
|
||||||
|
if (!strcmp (opcode->name, "br"))
|
||||||
|
{
|
||||||
|
f = frag_var (rs_machine_dependent, 4, 2, 2,
|
||||||
|
fixups[0].exp.X_add_symbol,
|
||||||
|
fixups[0].exp.X_add_number,
|
||||||
|
(char *)fixups[0].opindex);
|
||||||
|
md_number_to_chars (f, insn, insn_size);
|
||||||
|
md_number_to_chars (f + 2, 0, 2);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
f = frag_var (rs_machine_dependent, 6, 4, 0,
|
||||||
|
fixups[0].exp.X_add_symbol,
|
||||||
|
fixups[0].exp.X_add_number,
|
||||||
|
(char *)fixups[0].opindex);
|
||||||
|
md_number_to_chars (f, insn, insn_size);
|
||||||
|
md_number_to_chars (f + 2, 0, 4);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
/* Four byte insns have an opcode with the two high bits on. */
|
||||||
if ((insn & 0x0600) == 0x0600)
|
if ((insn & 0x0600) == 0x0600)
|
||||||
insn_size = 4;
|
insn_size = 4;
|
||||||
else
|
else
|
||||||
@ -1708,7 +1982,12 @@ md_estimate_size_before_relax (fragp, seg)
|
|||||||
fragS * fragp;
|
fragS * fragp;
|
||||||
asection * seg;
|
asection * seg;
|
||||||
{
|
{
|
||||||
fragp->fr_var = 4;
|
if (fragp->fr_subtype == 0)
|
||||||
|
fragp->fr_var = 4;
|
||||||
|
else if (fragp->fr_subtype == 2)
|
||||||
|
fragp->fr_var = 2;
|
||||||
|
else
|
||||||
|
abort ();
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1806,6 +2085,7 @@ md_apply_fix3 (fixp, valuep, seg)
|
|||||||
{
|
{
|
||||||
/* We still have to insert the value into memory! */
|
/* We still have to insert the value into memory! */
|
||||||
where = fixp->fx_frag->fr_literal + fixp->fx_where;
|
where = fixp->fx_frag->fr_literal + fixp->fx_where;
|
||||||
|
|
||||||
if (fixp->fx_size == 1)
|
if (fixp->fx_size == 1)
|
||||||
*where = value & 0xff;
|
*where = value & 0xff;
|
||||||
else if (fixp->fx_size == 2)
|
else if (fixp->fx_size == 2)
|
||||||
|
@ -32,28 +32,6 @@
|
|||||||
/* The target BFD format. */
|
/* The target BFD format. */
|
||||||
#define TARGET_FORMAT "elf32-v850"
|
#define TARGET_FORMAT "elf32-v850"
|
||||||
|
|
||||||
/* The target BFD machine number. */
|
|
||||||
#define TARGET_MACHINE 0
|
|
||||||
/* start-sanitize-v850e */
|
|
||||||
#undef TARGET_MACHINE
|
|
||||||
#define TARGET_MACHINE bfd_mach_v850e
|
|
||||||
/* end-sanitize-v850e */
|
|
||||||
/* start-sanitize-v850eq */
|
|
||||||
#undef TARGET_MACHINE
|
|
||||||
#define TARGET_MACHINE bfd_mach_v850eq
|
|
||||||
/* end-sanitize-v850eq */
|
|
||||||
|
|
||||||
/* The target processor mask. */
|
|
||||||
#define TARGET_PROCESSOR PROCESSOR_V850
|
|
||||||
/* start-sanitize-v850e */
|
|
||||||
#undef TARGET_PROCESSOR
|
|
||||||
#define TARGET_PROCESSOR PROCESSOR_V850E
|
|
||||||
/* end-sanitize-v850e */
|
|
||||||
/* start-sanitize-v850eq */
|
|
||||||
#undef TARGET_PROCESSOR
|
|
||||||
#define TARGET_PROCESSOR PROCESSOR_V850EQ
|
|
||||||
/* end-sanitize-v850eq */
|
|
||||||
|
|
||||||
|
|
||||||
#define MD_APPLY_FIX3
|
#define MD_APPLY_FIX3
|
||||||
#define md_operand(x)
|
#define md_operand(x)
|
||||||
@ -87,8 +65,13 @@ extern const struct relax_type md_relax_table[];
|
|||||||
{ ".sdata", SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_V850_GPREL }, \
|
{ ".sdata", SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_V850_GPREL }, \
|
||||||
{ ".sbss", SHT_NOBITS, SHF_ALLOC + SHF_WRITE + SHF_V850_GPREL }, \
|
{ ".sbss", SHT_NOBITS, SHF_ALLOC + SHF_WRITE + SHF_V850_GPREL }, \
|
||||||
{ ".rosdata", SHT_PROGBITS, SHF_ALLOC + SHF_V850_GPREL }, \
|
{ ".rosdata", SHT_PROGBITS, SHF_ALLOC + SHF_V850_GPREL }, \
|
||||||
|
{ ".scommon", SHT_NOBITS, SHF_ALLOC + SHF_WRITE + SHF_V850_GPREL }, \
|
||||||
{ ".tdata", SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_V850_EPREL }, \
|
{ ".tdata", SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_V850_EPREL }, \
|
||||||
|
{ ".tbss", SHT_NOBITS, SHF_ALLOC + SHF_WRITE + SHF_V850_EPREL }, \
|
||||||
{ ".zdata", SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_V850_R0REL }, \
|
{ ".zdata", SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_V850_R0REL }, \
|
||||||
{ ".rozdata", SHT_PROGBITS, SHF_ALLOC + SHF_V850_R0REL }, \
|
{ ".rozdata", SHT_PROGBITS, SHF_ALLOC + SHF_V850_R0REL }, \
|
||||||
{ ".zbss", SHT_NOBITS, SHF_ALLOC + SHF_WRITE + SHF_V850_R0REL },
|
{ ".zcommon", SHT_NOBITS, SHF_ALLOC + SHF_WRITE + SHF_V850_R0REL }, \
|
||||||
|
{ ".zbss", SHT_NOBITS, SHF_ALLOC + SHF_WRITE + SHF_V850_R0REL }, \
|
||||||
|
{ ".call_table_data", SHT_PROGBITS, SHF_ALLOC + SHF_WRITE }, \
|
||||||
|
{ ".call_table_text", SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_EXECINSTR },
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user