Line 1... |
Line 1... |
/* tc-score7.c -- Assembler for Score7
|
/* tc-score7.c -- Assembler for Score7
|
Copyright 2009 Free Software Foundation, Inc.
|
Copyright 2009, 2011 Free Software Foundation, Inc.
|
Contributed by:
|
Contributed by:
|
Brain.lin (brain.lin@sunplusct.com)
|
Brain.lin (brain.lin@sunplusct.com)
|
Mei Ligang (ligang@sunnorth.com.cn)
|
Mei Ligang (ligang@sunnorth.com.cn)
|
Pei-Lin Tsai (pltsai@sunplus.com)
|
Pei-Lin Tsai (pltsai@sunplus.com)
|
|
|
Line 1258... |
Line 1258... |
|
|
static int
|
static int
|
s7_my_get_expression (expressionS * ep, char **str)
|
s7_my_get_expression (expressionS * ep, char **str)
|
{
|
{
|
char *save_in;
|
char *save_in;
|
segT seg;
|
|
|
|
save_in = input_line_pointer;
|
save_in = input_line_pointer;
|
input_line_pointer = *str;
|
input_line_pointer = *str;
|
s7_in_my_get_expression = 1;
|
s7_in_my_get_expression = 1;
|
seg = expression (ep);
|
|
|
(void) expression (ep);
|
s7_in_my_get_expression = 0;
|
s7_in_my_get_expression = 0;
|
|
|
if (ep->X_op == O_illegal)
|
if (ep->X_op == O_illegal)
|
{
|
{
|
*str = input_line_pointer;
|
*str = input_line_pointer;
|
Line 3094... |
Line 3094... |
{
|
{
|
int pre_inc = 0;
|
int pre_inc = 0;
|
int conflict_reg;
|
int conflict_reg;
|
int value;
|
int value;
|
char * temp;
|
char * temp;
|
char *strbak;
|
|
char *dataptr;
|
char *dataptr;
|
int reg;
|
int reg;
|
int ldst_idx = 0;
|
int ldst_idx = 0;
|
|
|
int hex_p = 0;
|
int hex_p = 0;
|
|
|
strbak = str;
|
|
s7_skip_whitespace (str);
|
s7_skip_whitespace (str);
|
|
|
if (((conflict_reg = s7_reg_required_here (&str, 20, s7_REG_TYPE_SCORE)) == (int) s7_FAIL)
|
if (((conflict_reg = s7_reg_required_here (&str, 20, s7_REG_TYPE_SCORE)) == (int) s7_FAIL)
|
|| (s7_skip_past_comma (&str) == (int) s7_FAIL))
|
|| (s7_skip_past_comma (&str) == (int) s7_FAIL))
|
return;
|
return;
|
Line 5242... |
Line 5240... |
static int
|
static int
|
s7_b32_relax_to_b16 (fragS * fragp)
|
s7_b32_relax_to_b16 (fragS * fragp)
|
{
|
{
|
int grows = 0;
|
int grows = 0;
|
int relaxable_p = 0;
|
int relaxable_p = 0;
|
int r_old;
|
|
int r_new;
|
|
int frag_addr = fragp->fr_address + fragp->insn_addr;
|
int frag_addr = fragp->fr_address + fragp->insn_addr;
|
|
|
addressT symbol_address = 0;
|
addressT symbol_address = 0;
|
symbolS *s;
|
symbolS *s;
|
offsetT offset;
|
offsetT offset;
|
Line 5257... |
Line 5253... |
/* FIXME : here may be able to modify better .
|
/* FIXME : here may be able to modify better .
|
I don't know how to get the fragp's section ,
|
I don't know how to get the fragp's section ,
|
so in relax stage , it may be wrong to calculate the symbol's offset when the frag's section
|
so in relax stage , it may be wrong to calculate the symbol's offset when the frag's section
|
is different from the symbol's. */
|
is different from the symbol's. */
|
|
|
r_old = s7_RELAX_OLD (fragp->fr_subtype);
|
|
r_new = s7_RELAX_NEW (fragp->fr_subtype);
|
|
relaxable_p = s7_RELAX_OPT (fragp->fr_subtype);
|
relaxable_p = s7_RELAX_OPT (fragp->fr_subtype);
|
|
|
s = fragp->fr_symbol;
|
s = fragp->fr_symbol;
|
/* b/bl immediate */
|
/* b/bl immediate */
|
if (s == NULL)
|
if (s == NULL)
|
Line 5646... |
Line 5640... |
int maybe_text;
|
int maybe_text;
|
|
|
/* Generate a .pdr section. */
|
/* Generate a .pdr section. */
|
segT saved_seg = now_seg;
|
segT saved_seg = now_seg;
|
subsegT saved_subseg = now_subseg;
|
subsegT saved_subseg = now_subseg;
|
valueT dot;
|
|
expressionS exp;
|
expressionS exp;
|
char *fragp;
|
char *fragp;
|
|
|
if (!is_end_of_line[(unsigned char)*input_line_pointer])
|
if (!is_end_of_line[(unsigned char)*input_line_pointer])
|
{
|
{
|
Line 5697... |
Line 5690... |
(s7_cur_proc_ptr->frame_offset == 0xdeafbeaf) ||
|
(s7_cur_proc_ptr->frame_offset == 0xdeafbeaf) ||
|
(s7_cur_proc_ptr->frame_reg == 0xdeafbeaf) || (s7_cur_proc_ptr->pc_reg == 0xdeafbeaf));
|
(s7_cur_proc_ptr->frame_reg == 0xdeafbeaf) || (s7_cur_proc_ptr->pc_reg == 0xdeafbeaf));
|
|
|
else
|
else
|
{
|
{
|
dot = frag_now_fix ();
|
(void) frag_now_fix ();
|
gas_assert (s7_pdr_seg);
|
gas_assert (s7_pdr_seg);
|
subseg_set (s7_pdr_seg, 0);
|
subseg_set (s7_pdr_seg, 0);
|
/* Write the symbol. */
|
/* Write the symbol. */
|
exp.X_op = O_symbol;
|
exp.X_op = O_symbol;
|
exp.X_add_symbol = p;
|
exp.X_add_symbol = p;
|
Line 6374... |
Line 6367... |
fragS * fragp,
|
fragS * fragp,
|
long stretch ATTRIBUTE_UNUSED)
|
long stretch ATTRIBUTE_UNUSED)
|
{
|
{
|
int grows = 0;
|
int grows = 0;
|
int insn_size;
|
int insn_size;
|
int insn_relax_size;
|
|
int do_relax_p = 0; /* Indicate doing relaxation for this frag. */
|
int do_relax_p = 0; /* Indicate doing relaxation for this frag. */
|
int relaxable_p = 0;
|
int relaxable_p = 0;
|
bfd_boolean word_align_p = FALSE;
|
bfd_boolean word_align_p = FALSE;
|
fragS *next_fragp;
|
fragS *next_fragp;
|
|
|
Line 6394... |
Line 6386... |
|
|
word_align_p = ((fragp->fr_address + fragp->insn_addr) % 4 == 0) ? TRUE : FALSE;
|
word_align_p = ((fragp->fr_address + fragp->insn_addr) % 4 == 0) ? TRUE : FALSE;
|
|
|
/* Get instruction size and relax size after the last relaxation. */
|
/* Get instruction size and relax size after the last relaxation. */
|
if (fragp->fr_opcode)
|
if (fragp->fr_opcode)
|
{
|
|
insn_size = s7_RELAX_NEW (fragp->fr_subtype);
|
insn_size = s7_RELAX_NEW (fragp->fr_subtype);
|
insn_relax_size = s7_RELAX_OLD (fragp->fr_subtype);
|
|
}
|
|
else
|
else
|
{
|
|
insn_size = s7_RELAX_OLD (fragp->fr_subtype);
|
insn_size = s7_RELAX_OLD (fragp->fr_subtype);
|
insn_relax_size = s7_RELAX_NEW (fragp->fr_subtype);
|
|
}
|
|
|
|
/* Handle specially for s7_GP instruction. for, s7_judge_size_before_relax() has already determine
|
/* Handle specially for s7_GP instruction. for, s7_judge_size_before_relax() has already determine
|
whether the s7_GP instruction should do relax. */
|
whether the s7_GP instruction should do relax. */
|
if ((s7_RELAX_TYPE (fragp->fr_subtype) == Insn_GP)
|
if ((s7_RELAX_TYPE (fragp->fr_subtype) == Insn_GP)
|
|| (s7_RELAX_TYPE (fragp->fr_subtype) == Insn_PIC))
|
|| (s7_RELAX_TYPE (fragp->fr_subtype) == Insn_PIC))
|
Line 6889... |
Line 6875... |
{
|
{
|
static arelent *retval[MAX_RELOC_EXPANSION + 1]; /* MAX_RELOC_EXPANSION equals 2. */
|
static arelent *retval[MAX_RELOC_EXPANSION + 1]; /* MAX_RELOC_EXPANSION equals 2. */
|
arelent *reloc;
|
arelent *reloc;
|
bfd_reloc_code_real_type code;
|
bfd_reloc_code_real_type code;
|
char *type;
|
char *type;
|
fragS *f;
|
|
symbolS *s;
|
|
expressionS e;
|
|
|
|
reloc = retval[0] = xmalloc (sizeof (arelent));
|
reloc = retval[0] = xmalloc (sizeof (arelent));
|
retval[1] = NULL;
|
retval[1] = NULL;
|
|
|
reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
|
reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
|
Line 6930... |
Line 6913... |
retval[2] = NULL;
|
retval[2] = NULL;
|
retval[1]->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
|
retval[1]->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
|
*retval[1]->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
|
*retval[1]->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
|
retval[1]->address = (reloc->address + s7_RELAX_RELOC2 (fixp->fx_frag->fr_subtype));
|
retval[1]->address = (reloc->address + s7_RELAX_RELOC2 (fixp->fx_frag->fr_subtype));
|
|
|
f = fixp->fx_frag;
|
|
s = f->fr_symbol;
|
|
e = s->sy_value;
|
|
|
|
retval[1]->addend = 0;
|
retval[1]->addend = 0;
|
retval[1]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_LO16);
|
retval[1]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_LO16);
|
gas_assert (retval[1]->howto != NULL);
|
gas_assert (retval[1]->howto != NULL);
|
|
|
fixp->fx_r_type = BFD_RELOC_HI16_S;
|
fixp->fx_r_type = BFD_RELOC_HI16_S;
|