projects
/
deliverable
/
binutils-gdb.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
x86-64: accept 64-bit LFS/LGS/LSS forms with suffix or operand size specifier
[deliverable/binutils-gdb.git]
/
gas
/
config
/
tc-rl78.c
diff --git
a/gas/config/tc-rl78.c
b/gas/config/tc-rl78.c
index c9d5c9791d899c7269ba6cfaa675535904626bcf..9160cc027fb077118e666d344f57d3e8fa150928 100644
(file)
--- a/
gas/config/tc-rl78.c
+++ b/
gas/config/tc-rl78.c
@@
-1,5
+1,5
@@
/* tc-rl78.c -- Assembler for the Renesas RL78
/* tc-rl78.c -- Assembler for the Renesas RL78
- Copyright (C) 2011-201
5
Free Software Foundation, Inc.
+ Copyright (C) 2011-201
9
Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
This file is part of GAS, the GNU Assembler.
@@
-19,10
+19,8
@@
02110-1301, USA. */
#include "as.h"
02110-1301, USA. */
#include "as.h"
-#include "struc-symbol.h"
#include "safe-ctype.h"
#include "dwarf2dbg.h"
#include "safe-ctype.h"
#include "dwarf2dbg.h"
-#include "libbfd.h"
#include "elf/common.h"
#include "elf/rl78.h"
#include "rl78-defs.h"
#include "elf/common.h"
#include "elf/rl78.h"
#include "rl78-defs.h"
@@
-102,6
+100,7
@@
rl78_linkrelax_addr16 (void)
void
rl78_linkrelax_branch (void)
{
void
rl78_linkrelax_branch (void)
{
+ rl78_relax (RL78_RELAX_BRANCH, 0);
rl78_bytes.link_relax |= RL78_RELAXA_BRA;
}
rl78_bytes.link_relax |= RL78_RELAXA_BRA;
}
@@
-130,7
+129,7
@@
rl78_prefix (int p)
}
int
}
int
-rl78_has_prefix ()
+rl78_has_prefix (
void
)
{
return rl78_bytes.n_prefix;
}
{
return rl78_bytes.n_prefix;
}
@@
-280,6
+279,7
@@
rl78_field (int val, int pos, int sz)
enum options
{
OPTION_RELAX = OPTION_MD_BASE,
enum options
{
OPTION_RELAX = OPTION_MD_BASE,
+ OPTION_NORELAX,
OPTION_G10,
OPTION_G13,
OPTION_G14,
OPTION_G10,
OPTION_G13,
OPTION_G14,
@@
-294,6
+294,7
@@
const char * md_shortopts = RL78_SHORTOPTS;
struct option md_longopts[] =
{
{"relax", no_argument, NULL, OPTION_RELAX},
struct option md_longopts[] =
{
{"relax", no_argument, NULL, OPTION_RELAX},
+ {"norelax", no_argument, NULL, OPTION_NORELAX},
{"mg10", no_argument, NULL, OPTION_G10},
{"mg13", no_argument, NULL, OPTION_G13},
{"mg14", no_argument, NULL, OPTION_G14},
{"mg10", no_argument, NULL, OPTION_G10},
{"mg13", no_argument, NULL, OPTION_G13},
{"mg14", no_argument, NULL, OPTION_G14},
@@
-305,13
+306,16
@@
struct option md_longopts[] =
size_t md_longopts_size = sizeof (md_longopts);
int
size_t md_longopts_size = sizeof (md_longopts);
int
-md_parse_option (int c, char * arg ATTRIBUTE_UNUSED)
+md_parse_option (int c, c
onst c
har * arg ATTRIBUTE_UNUSED)
{
switch (c)
{
case OPTION_RELAX:
linkrelax = 1;
return 1;
{
switch (c)
{
case OPTION_RELAX:
linkrelax = 1;
return 1;
+ case OPTION_NORELAX:
+ linkrelax = 0;
+ return 1;
case OPTION_G10:
elf_flags &= ~ E_FLAG_RL78_CPU_MASK;
case OPTION_G10:
elf_flags &= ~ E_FLAG_RL78_CPU_MASK;
@@
-430,7
+434,7
@@
md_number_to_chars (char * buf, valueT val, int n)
}
static void
}
static void
-require_end_of_expr (char *fname)
+require_end_of_expr (c
onst c
har *fname)
{
while (* input_line_pointer == ' '
|| * input_line_pointer == '\t')
{
while (* input_line_pointer == ' '
|| * input_line_pointer == '\t')
@@
-448,7
+452,7
@@
require_end_of_expr (char *fname)
static struct
{
static struct
{
- char * fname;
+ c
onst c
har * fname;
int reloc;
}
reloc_functions[] =
int reloc;
}
reloc_functions[] =
@@
-496,7
+500,7
@@
rl78_frag_init (fragS * fragP)
{
if (rl78_bytes.n_relax || rl78_bytes.link_relax)
{
{
if (rl78_bytes.n_relax || rl78_bytes.link_relax)
{
- fragP->tc_frag_data =
malloc (sizeof (rl78_bytesT)
);
+ fragP->tc_frag_data =
XNEW (rl78_bytesT
);
memcpy (fragP->tc_frag_data, & rl78_bytes, sizeof (rl78_bytesT));
}
else
memcpy (fragP->tc_frag_data, & rl78_bytes, sizeof (rl78_bytesT));
}
else
@@
-527,7
+531,7
@@
rl78_handle_align (fragS * frag)
}
}
}
}
-char *
+c
onst c
har *
md_atof (int type, char * litP, int * sizeP)
{
return ieee_md_atof (type, litP, sizeP, target_big_endian);
md_atof (int type, char * litP, int * sizeP)
{
return ieee_md_atof (type, litP, sizeP, target_big_endian);
@@
-757,7
+761,10
@@
typedef enum
OT_bt_sfr,
OT_bt_es,
OT_bc,
OT_bt_sfr,
OT_bt_es,
OT_bc,
- OT_bh
+ OT_bh,
+ OT_sk,
+ OT_call,
+ OT_br,
} op_type_T;
/* We're looking for these types of relaxations:
} op_type_T;
/* We're looking for these types of relaxations:
@@
-780,8
+787,10
@@
typedef enum
a different size later. */
static op_type_T
a different size later. */
static op_type_T
-rl78_opcode_type (char * op)
+rl78_opcode_type (char * op
s
)
{
{
+ unsigned char *op = (unsigned char *)ops;
+
if (op[0] == 0x31
&& ((op[1] & 0x0f) == 0x05
|| (op[1] & 0x0f) == 0x03))
if (op[0] == 0x31
&& ((op[1] & 0x0f) == 0x05
|| (op[1] & 0x0f) == 0x03))
@@
-805,6
+814,20
@@
rl78_opcode_type (char * op)
&& (op[1] & 0xef) == 0xc3)
return OT_bh;
&& (op[1] & 0xef) == 0xc3)
return OT_bh;
+ if (op[0] == 0x61
+ && (op[1] & 0xcf) == 0xc8)
+ return OT_sk;
+
+ if (op[0] == 0x61
+ && (op[1] & 0xef) == 0xe3)
+ return OT_sk;
+
+ if (op[0] == 0xfc)
+ return OT_call;
+
+ if ((op[0] & 0xec) == 0xec)
+ return OT_br;
+
return OT_other;
}
return OT_other;
}
@@
-901,6
+924,11
@@
rl78_relax_frag (segT segment ATTRIBUTE_UNUSED, fragS * fragP, long stretch)
fragP->tc_frag_data->relax[ri].type != RL78_RELAX_BRANCH,
& sym_addr))
{
fragP->tc_frag_data->relax[ri].type != RL78_RELAX_BRANCH,
& sym_addr))
{
+ /* If we don't expect the linker to do relaxing, don't emit
+ expanded opcodes that only the linker will relax. */
+ if (!linkrelax)
+ return newsize - oldsize;
+
/* If we don't, we must use the maximum size for the linker. */
switch (fragP->tc_frag_data->relax[ri].type)
{
/* If we don't, we must use the maximum size for the linker. */
switch (fragP->tc_frag_data->relax[ri].type)
{
@@
-920,7
+948,10
@@
rl78_relax_frag (segT segment ATTRIBUTE_UNUSED, fragS * fragP, long stretch)
case OT_bh:
newsize = 6;
break;
case OT_bh:
newsize = 6;
break;
- case OT_other:
+ case OT_sk:
+ newsize = 2;
+ break;
+ default:
newsize = oldsize;
break;
}
newsize = oldsize;
break;
}
@@
-967,7
+998,10
@@
rl78_relax_frag (segT segment ATTRIBUTE_UNUSED, fragS * fragP, long stretch)
else
newsize = 6;
break;
else
newsize = 6;
break;
- case OT_other:
+ case OT_sk:
+ newsize = 2;
+ break;
+ default:
newsize = oldsize;
break;
}
newsize = oldsize;
break;
}
@@
-1062,6
+1096,7
@@
md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
case OPCODE (OT_bt, 3): /* BT A,$ - no change. */
disp -= 3;
op[2] = disp;
case OPCODE (OT_bt, 3): /* BT A,$ - no change. */
disp -= 3;
op[2] = disp;
+ reloc_type = keep_reloc ? BFD_RELOC_8_PCREL : BFD_RELOC_NONE;
break;
case OPCODE (OT_bt, 6): /* BT A,$ - long version. */
break;
case OPCODE (OT_bt, 6): /* BT A,$ - long version. */
@@
-1079,6
+1114,7
@@
md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
case OPCODE (OT_bt_sfr, 4): /* BT PSW,$ - no change. */
disp -= 4;
op[3] = disp;
case OPCODE (OT_bt_sfr, 4): /* BT PSW,$ - no change. */
disp -= 4;
op[3] = disp;
+ reloc_type = keep_reloc ? BFD_RELOC_8_PCREL : BFD_RELOC_NONE;
break;
case OPCODE (OT_bt_sfr, 7): /* BT PSW,$ - long version. */
break;
case OPCODE (OT_bt_sfr, 7): /* BT PSW,$ - long version. */
@@
-1096,6
+1132,7
@@
md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
case OPCODE (OT_bt_es, 4): /* BT ES:[HL],$ - no change. */
disp -= 4;
op[3] = disp;
case OPCODE (OT_bt_es, 4): /* BT ES:[HL],$ - no change. */
disp -= 4;
op[3] = disp;
+ reloc_type = keep_reloc ? BFD_RELOC_8_PCREL : BFD_RELOC_NONE;
break;
case OPCODE (OT_bt_es, 7): /* BT PSW,$ - long version. */
break;
case OPCODE (OT_bt_es, 7): /* BT PSW,$ - long version. */
@@
-1113,6
+1150,7
@@
md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
case OPCODE (OT_bc, 2): /* BC $ - no change. */
disp -= 2;
op[1] = disp;
case OPCODE (OT_bc, 2): /* BC $ - no change. */
disp -= 2;
op[1] = disp;
+ reloc_type = keep_reloc ? BFD_RELOC_8_PCREL : BFD_RELOC_NONE;
break;
case OPCODE (OT_bc, 5): /* BC $ - long version. */
break;
case OPCODE (OT_bc, 5): /* BC $ - long version. */
@@
-1130,6
+1168,7
@@
md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
case OPCODE (OT_bh, 3): /* BH $ - no change. */
disp -= 3;
op[2] = disp;
case OPCODE (OT_bh, 3): /* BH $ - no change. */
disp -= 3;
op[2] = disp;
+ reloc_type = keep_reloc ? BFD_RELOC_8_PCREL : BFD_RELOC_NONE;
break;
case OPCODE (OT_bh, 6): /* BC $ - long version. */
break;
case OPCODE (OT_bh, 6): /* BC $ - long version. */
@@
-1144,11
+1183,13
@@
md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
reloc_adjust = 2;
break;
reloc_adjust = 2;
break;
+ case OPCODE (OT_sk, 2): /* SK<cond> - no change */
+ reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE;
+ break;
+
default:
default:
- fprintf(stderr, "Missed case %d %d at 0x%lx\n",
- rl78_opcode_type (fragP->fr_opcode), fragP->fr_subtype, mypc);
- abort ();
-
+ reloc_type = fix ? fix->fx_r_type : BFD_RELOC_NONE;
+ break;
}
break;
}
break;
@@
-1192,8
+1233,7
@@
md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
fragP->fr_next);
if (fragP->fr_next != NULL
fragP->fr_next);
if (fragP->fr_next != NULL
- && ((offsetT) (fragP->fr_next->fr_address - fragP->fr_address)
- != fragP->fr_fix))
+ && fragP->fr_next->fr_address - fragP->fr_address != fragP->fr_fix)
as_bad (_("bad frag at %p : fix %ld addr %ld %ld \n"), fragP,
(long) fragP->fr_fix,
(long) fragP->fr_address, (long) fragP->fr_next->fr_address);
as_bad (_("bad frag at %p : fix %ld addr %ld %ld \n"), fragP,
(long) fragP->fr_fix,
(long) fragP->fr_address, (long) fragP->fr_next->fr_address);
@@
-1215,6
+1255,12
@@
tc_gen_reloc (asection * seg ATTRIBUTE_UNUSED, fixS * fixp)
return reloc;
}
return reloc;
}
+ if (fixp->fx_r_type == BFD_RELOC_RL78_RELAX && !linkrelax)
+ {
+ reloc[0] = NULL;
+ return reloc;
+ }
+
if (fixp->fx_subsy
&& S_GET_SEGMENT (fixp->fx_subsy) == absolute_section)
{
if (fixp->fx_subsy
&& S_GET_SEGMENT (fixp->fx_subsy) == absolute_section)
{
@@
-1222,8
+1268,8
@@
tc_gen_reloc (asection * seg ATTRIBUTE_UNUSED, fixS * fixp)
fixp->fx_subsy = NULL;
}
fixp->fx_subsy = NULL;
}
- reloc[0] =
(arelent *) xmalloc (sizeof (arelent)
);
- reloc[0]->sym_ptr_ptr =
(asymbol **) xmalloc (sizeof (asymbol *)
);
+ reloc[0] =
XNEW (arelent
);
+ reloc[0]->sym_ptr_ptr =
XNEW (asymbol *
);
* reloc[0]->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
reloc[0]->address = fixp->fx_frag->fr_address + fixp->fx_where;
reloc[0]->addend = fixp->fx_offset;
* reloc[0]->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
reloc[0]->address = fixp->fx_frag->fr_address + fixp->fx_where;
reloc[0]->addend = fixp->fx_offset;
@@
-1235,8
+1281,8
@@
tc_gen_reloc (asection * seg ATTRIBUTE_UNUSED, fixS * fixp)
}
#define OPX(REL,SYM,ADD) \
}
#define OPX(REL,SYM,ADD) \
- reloc[rp] =
(arelent *) xmalloc (sizeof (arelent)
); \
- reloc[rp]->sym_ptr_ptr =
(asymbol **) xmalloc (sizeof (asymbol *));
\
+ reloc[rp] =
XNEW (arelent
); \
+ reloc[rp]->sym_ptr_ptr =
XNEW (asymbol *);
\
reloc[rp]->howto = bfd_reloc_type_lookup (stdoutput, REL); \
reloc[rp]->addend = ADD; \
* reloc[rp]->sym_ptr_ptr = SYM; \
reloc[rp]->howto = bfd_reloc_type_lookup (stdoutput, REL); \
reloc[rp]->addend = ADD; \
* reloc[rp]->sym_ptr_ptr = SYM; \
@@
-1253,7
+1299,7
@@
tc_gen_reloc (asection * seg ATTRIBUTE_UNUSED, fixS * fixp)
the __rl78_abs__ symbol and arrange for the linker scripts to place
this symbol at address 0. */
#define OPIMM(IMM) OPX (BFD_RELOC_RL78_SYM, symbol_get_bfdsym (rl78_abs_sym), IMM)
the __rl78_abs__ symbol and arrange for the linker scripts to place
this symbol at address 0. */
#define OPIMM(IMM) OPX (BFD_RELOC_RL78_SYM, symbol_get_bfdsym (rl78_abs_sym), IMM)
-
+
#define OP(OP) OPX(BFD_RELOC_RL78_##OP, *reloc[0]->sym_ptr_ptr, 0)
#define SYM0() reloc[0]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RL78_SYM)
#define OP(OP) OPX(BFD_RELOC_RL78_##OP, *reloc[0]->sym_ptr_ptr, 0)
#define SYM0() reloc[0]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RL78_SYM)
@@
-1376,6
+1422,11
@@
md_apply_fix (struct fix * f ATTRIBUTE_UNUSED,
char * op;
unsigned long val;
char * op;
unsigned long val;
+ /* We always defer overflow checks for these to the linker, as it
+ needs to do PLT stuff. */
+ if (f->fx_r_type == BFD_RELOC_RL78_CODE)
+ f->fx_no_overflow = 1;
+
if (f->fx_addsy && S_FORCE_RELOC (f->fx_addsy, 1))
return;
if (f->fx_subsy && S_FORCE_RELOC (f->fx_subsy, 1))
if (f->fx_addsy && S_FORCE_RELOC (f->fx_addsy, 1))
return;
if (f->fx_subsy && S_FORCE_RELOC (f->fx_subsy, 1))
@@
-1384,13
+1435,16
@@
md_apply_fix (struct fix * f ATTRIBUTE_UNUSED,
op = f->fx_frag->fr_literal + f->fx_where;
val = (unsigned long) * t;
op = f->fx_frag->fr_literal + f->fx_where;
val = (unsigned long) * t;
+ if (f->fx_addsy == NULL)
+ f->fx_done = 1;
+
switch (f->fx_r_type)
{
case BFD_RELOC_NONE:
break;
case BFD_RELOC_RL78_RELAX:
switch (f->fx_r_type)
{
case BFD_RELOC_NONE:
break;
case BFD_RELOC_RL78_RELAX:
- f->fx_done =
1
;
+ f->fx_done =
0
;
break;
case BFD_RELOC_8_PCREL:
break;
case BFD_RELOC_8_PCREL:
@@
-1461,13
+1515,11
@@
md_apply_fix (struct fix * f ATTRIBUTE_UNUSED,
break;
}
break;
}
- if (f->fx_addsy == NULL)
- f->fx_done = 1;
}
valueT
md_section_align (segT segment, valueT size)
{
}
valueT
md_section_align (segT segment, valueT size)
{
- int align = bfd_
get_section_alignment (stdoutput,
segment);
- return ((size + (1 << align) - 1) &
(-
1 << align));
+ int align = bfd_
section_alignment (
segment);
+ return ((size + (1 << align) - 1) &
-(
1 << align));
}
}
This page took
0.027381 seconds
and
4
git commands to generate.