aboutsummaryrefslogtreecommitdiff
path: root/gas/config/tc-arc.c
diff options
context:
space:
mode:
authorClaudiu Zissulescu <claziss@synopsys.com>2017-02-15 11:57:51 +0100
committerClaudiu Zissulescu <claziss@synopsys.com>2017-02-15 12:02:28 +0100
commitcc07cda69e26ef28895086e1f214ddd1d3cb939d (patch)
treec221de4efbefdc22bec9a4178caa306784847d40 /gas/config/tc-arc.c
parent7c723eecec713e1de9a95017aac29a40f3b9853a (diff)
downloadgdb-cc07cda69e26ef28895086e1f214ddd1d3cb939d.zip
gdb-cc07cda69e26ef28895086e1f214ddd1d3cb939d.tar.gz
gdb-cc07cda69e26ef28895086e1f214ddd1d3cb939d.tar.bz2
[ARC] Fix assembler relaxation.
Fix assembler relaxation step for add, ld, mov, mpy and sub instructions. Add tests to it. gas/ 2017-02-15 Claudiu Zissulescu <claziss@synopsys.com> * config/tc-arc.c (md_convert_frag): Remove @pcl relocation information from input expression. (assemble_insn): Make sure pcrel is correctly set. (arc_pcrel_adjust): Compensate for PCL rounding. * testsuite/gas/arc/relax-add01.d: New file. * testsuite/gas/arc/relax-add01.s: Likewise. * testsuite/gas/arc/relax-add02.d: Likewise. * testsuite/gas/arc/relax-add02.s: Likewise. * testsuite/gas/arc/relax-add03.d: Likewise. * testsuite/gas/arc/relax-add03.s: Likewise. * testsuite/gas/arc/relax-add04.d: Likewise. * testsuite/gas/arc/relax-add04.s: Likewise. * testsuite/gas/arc/relax-ld01.d: Likewise. * testsuite/gas/arc/relax-ld01.s: Likewise. * testsuite/gas/arc/relax-ld02.d: Likewise. * testsuite/gas/arc/relax-ld02.s: Likewise. * testsuite/gas/arc/relax-mov01.d: Likewise. * testsuite/gas/arc/relax-mov01.s: Likewise. * testsuite/gas/arc/relax-mov02.d: Likewise. * testsuite/gas/arc/relax-mov02.s: Likewise. * testsuite/gas/arc/relax-mpy01.d: Likewise. * testsuite/gas/arc/relax-mpy01.s: Likewise. * testsuite/gas/arc/relax-sub01.d: Likewise. * testsuite/gas/arc/relax-sub01.s: Likewise. * testsuite/gas/arc/relax-sub02.d: Likewise. * testsuite/gas/arc/relax-sub02.s: Likewise. * testsuite/gas/arc/relax-sub03.d: Likewise. * testsuite/gas/arc/relax-sub03.s: Likewise. * testsuite/gas/arc/relax-sub04.d: Likewise. * testsuite/gas/arc/relax-sub04.s: Likewise. opcodes/ 2017-02-15 Claudiu Zissulescu <claziss@synopsys.com> * arc-opc.c (UIMM6_20R): Define. (SIMM12_20): Use above. (SIMM12_20R): Define. (SIMM3_5_S): Use above. (UIMM7_A32_11R_S): Define. (UIMM7_9_S): Use above. (UIMM3_13R_S): Define. (SIMM11_A32_7_S): Use above. (SIMM9_8R): Define. (UIMM10_A32_8_S): Use above. (UIMM8_8R_S): Define. (W6): Use above. (arc_relax_opcodes): Use all above defines.
Diffstat (limited to 'gas/config/tc-arc.c')
-rw-r--r--gas/config/tc-arc.c41
1 files changed, 32 insertions, 9 deletions
diff --git a/gas/config/tc-arc.c b/gas/config/tc-arc.c
index 9a3b26b..a1fd71d 100644
--- a/gas/config/tc-arc.c
+++ b/gas/config/tc-arc.c
@@ -2773,7 +2773,7 @@ insert_operand (unsigned long long insn,
val, min, max, file, line);
}
- pr_debug ("insert field: %ld <= %ld <= %ld in 0x%08llx\n",
+ pr_debug ("insert field: %ld <= %lld <= %ld in 0x%08llx\n",
min, val, max, insn);
if ((operand->flags & ARC_OPERAND_ALIGNED32)
@@ -3910,12 +3910,22 @@ assemble_insn (const struct arc_opcode *opcode,
reloc = ARC_RELOC_TABLE (t->X_md)->reloc;
break;
case O_pcl:
- reloc = ARC_RELOC_TABLE (t->X_md)->reloc;
- if (arc_opcode_len (opcode) == 2
- || opcode->insn_class == JUMP)
- as_bad_where (frag_now->fr_file, frag_now->fr_line,
- _("Unable to use @pcl relocation for insn %s"),
- opcode->name);
+ if (operand->flags & ARC_OPERAND_LIMM)
+ {
+ reloc = ARC_RELOC_TABLE (t->X_md)->reloc;
+ if (arc_opcode_len (opcode) == 2
+ || opcode->insn_class == JUMP)
+ as_bad_where (frag_now->fr_file, frag_now->fr_line,
+ _("Unable to use @pcl relocation for insn %s"),
+ opcode->name);
+ }
+ else
+ {
+ /* This is a relaxed operand which initially was
+ limm, choose whatever we have defined in the
+ opcode as reloc. */
+ reloc = operand->default_reloc;
+ }
break;
case O_sda:
reloc = find_reloc ("sda", opcode->name,
@@ -3975,7 +3985,15 @@ assemble_insn (const struct arc_opcode *opcode,
fixup = &insn->fixups[insn->nfixups++];
fixup->exp = *t;
fixup->reloc = reloc;
- pcrel = (operand->flags & ARC_OPERAND_PCREL) ? 1 : 0;
+ if ((int) reloc < 0)
+ pcrel = (operand->flags & ARC_OPERAND_PCREL) ? 1 : 0;
+ else
+ {
+ reloc_howto_type *reloc_howto =
+ bfd_reloc_type_lookup (stdoutput,
+ (bfd_reloc_code_real_type) fixup->reloc);
+ pcrel = reloc_howto->pc_relative;
+ }
fixup->pcrel = pcrel;
fixup->islong = (operand->flags & ARC_OPERAND_LIMM) ?
TRUE : FALSE;
@@ -4234,10 +4252,15 @@ arc_frob_label (symbolS * sym)
int
arc_pcrel_adjust (fragS *fragP)
{
+ pr_debug ("arc_pcrel_adjust: address=%ld, fix=%ld, PCrel %s\n",
+ fragP->fr_address, fragP->fr_fix,
+ fragP->tc_frag_data.pcrel ? "Y" : "N");
+
if (!fragP->tc_frag_data.pcrel)
return fragP->fr_address + fragP->fr_fix;
- return 0;
+ /* Take into account the PCL rounding. */
+ return (fragP->fr_address + fragP->fr_fix) & 0x03;
}
/* Initialize the DWARF-2 unwind information for this procedure. */