Add "attn", "lq" and "stq" power4 insns.

This commit is contained in:
Alan Modra 2003-06-10 07:44:11 +00:00
parent 2a93846b50
commit adadcc0cc9
12 changed files with 484 additions and 171 deletions

View file

@ -1,3 +1,8 @@
2003-06-10 Alan Modra <amodra@bigpond.net.au>
Gary Hade <garyhade@us.ibm.com>
* elf64-ppc.c (ppc64_elf_relocate_section <*_DS>): Special case lq.
2003-06-10 Richard Sandiford <rsandifo@redhat.com>
* archures.c (bfd_mach_h8300sxn): New architecture.

View file

@ -7315,7 +7315,7 @@ ppc64_elf_relocate_section (output_bfd, info, input_bfd, input_section,
bfd_vma relocation;
bfd_boolean unresolved_reloc;
bfd_boolean warned;
long insn;
long insn, mask;
struct ppc_stub_hash_entry *stub_entry;
bfd_vma max_br_offset;
bfd_vma from;
@ -8406,12 +8406,23 @@ ppc64_elf_relocate_section (output_bfd, info, input_bfd, input_section,
case R_PPC64_TPREL16_LO_DS:
case R_PPC64_DTPREL16_DS:
case R_PPC64_DTPREL16_LO_DS:
if (((relocation + addend) & 3) != 0)
insn = bfd_get_32 (input_bfd, contents + (rel->r_offset & ~3));
mask = 3;
/* If this reloc is against an lq insn, then the value must be
a multiple of 16. This is somewhat of a hack, but the
"correct" way to do this by defining _DQ forms of all the
_DS relocs bloats all reloc switches in this file. It
doesn't seem to make much sense to use any of these relocs
in data, so testing the insn should be safe. */
if ((insn & (0x3f << 26)) == (56 << 26))
mask = 15;
if (((relocation + addend) & mask) != 0)
{
(*_bfd_error_handler)
(_("%s: error: relocation %s not a multiple of 4"),
(_("%s: error: relocation %s not a multiple of %d"),
bfd_archive_filename (input_bfd),
ppc64_elf_howto_table[(int) r_type]->name);
ppc64_elf_howto_table[(int) r_type]->name,
mask + 1);
bfd_set_error (bfd_error_bad_value);
ret = FALSE;
continue;

View file

@ -1,3 +1,9 @@
2003-06-10 Alan Modra <amodra@bigpond.net.au>
Gary Hade <garyhade@us.ibm.com>
* config/tc-ppc.c (md_assemble): Handle PPC_OPERAND_DQ.
(md_apply_fix3): Special case lq insn.
2003-06-10 Richard Sandiford <rsandifo@redhat.com>
* config/tc-h8300.c (get_rtsl_operands): Accept unbracketed register

View file

@ -2447,7 +2447,7 @@ md_assemble (str)
}
if (ppc_obj64
&& (operand->flags & PPC_OPERAND_DS) != 0)
&& (operand->flags & (PPC_OPERAND_DS | PPC_OPERAND_DQ)) != 0)
{
switch (reloc)
{
@ -5714,13 +5714,18 @@ md_apply_fix3 (fixP, valP, seg)
abort ();
{
unsigned char *where = fixP->fx_frag->fr_literal + fixP->fx_where;
unsigned long val;
long val, mask;
if (target_big_endian)
val = bfd_getb16 (where);
val = bfd_getb32 (where - 2);
else
val = bfd_getl16 (where);
val |= (value & 0xfffc);
val = bfd_getl32 (where);
mask = 0xfffc;
/* lq insns reserve the four lsbs. */
if ((ppc_cpu & PPC_OPCODE_POWER4) != 0
&& (val & (0x3f << 26)) == (56 << 26))
mask = 0xfff0;
val |= value & mask;
if (target_big_endian)
bfd_putb16 ((bfd_vma) val, where);
else

View file

@ -1,3 +1,8 @@
2003-06-10 Gary Hade <garyhade@us.ibm.com>
* gas/ppc/test2elf64.{s,d}: New test.
* gas/ppc/ppc.exp: Run new test.
2003-06-10 Richard Sandiford <rsandifo@redhat.com>
* gas/h8300/h8sx_mov_imm.[sd]: New test.

View file

@ -10,6 +10,7 @@ if { [istarget powerpc64*-*-*] || [istarget *-*-elf64*]} then {
run_dump_test "astest64"
run_dump_test "astest2_64"
run_dump_test "test1elf64"
run_dump_test "test2elf64"
} elseif { [istarget powerpc*-*aix*] } then {
run_dump_test "test1xcoff32"
} elseif { [istarget powerpc*-*-*bsd*] \

View file

@ -0,0 +1,101 @@
#objdump: -Drx -Mpower4
#as: -mpower4
#name: PowerPC Test 2, 64 bit elf, power4 instructions
.*: +file format elf64-powerpc
.*
architecture: powerpc:common64, flags 0x0+11:
HAS_RELOC, HAS_SYMS
start address 0x0+
Sections:
Idx Name +Size +VMA +LMA +File off +Algn
+0 \.text +0+68 +0+ +0+ +.*
+CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
+1 \.data +0+10 +0+ +0+ +.*
+CONTENTS, ALLOC, LOAD, DATA
+2 \.bss +0+ +0+ +0+ +.*
+ALLOC
+3 \.toc +0+30 +0+ +0+ +.*
+CONTENTS, ALLOC, LOAD, RELOC, DATA
SYMBOL TABLE:
0+ l +d +\.text 0+
0+ l +d +\.data 0+
0+ l +d +\.bss 0+
0+ l +\.data 0+ dsym0
0+8 l +\.data 0+ dsym1
0+ l +d +\.toc 0+
0+8 l +\.data 0+ usym0
0+10 l +\.data 0+ usym1
0+ +\*UND\* 0+ esym0
0+ +\*UND\* 0+ esym1
Disassembly of section \.text:
0+ <\.text>:
+0: e0 83 00 00 lq r4,0\(r3\)
2: R_PPC64_ADDR16_LO_DS dsym0
+4: e0 83 00 00 lq r4,0\(r3\)
6: R_PPC64_ADDR16_LO_DS dsym1
+8: e0 83 00 00 lq r4,0\(r3\)
a: R_PPC64_ADDR16_LO_DS usym0
+c: e0 83 00 00 lq r4,0\(r3\)
e: R_PPC64_ADDR16_LO_DS usym1
+10: e0 83 00 00 lq r4,0\(r3\)
12: R_PPC64_ADDR16_LO_DS esym0
+14: e0 83 00 00 lq r4,0\(r3\)
16: R_PPC64_ADDR16_LO_DS esym1
+18: e0 82 00 00 lq r4,0\(r2\)
1a: R_PPC64_TOC16_DS \.toc
+1c: e0 82 00 00 lq r4,0\(r2\)
1e: R_PPC64_TOC16_DS \.toc\+0x8
+20: e0 82 00 10 lq r4,16\(r2\)
22: R_PPC64_TOC16_DS \.toc\+0x10
+24: e0 82 00 10 lq r4,16\(r2\)
26: R_PPC64_TOC16_DS \.toc\+0x18
+28: e0 82 00 20 lq r4,32\(r2\)
2a: R_PPC64_TOC16_DS \.toc\+0x20
+2c: e0 82 00 20 lq r4,32\(r2\)
2e: R_PPC64_TOC16_DS \.toc\+0x28
+30: e0 c2 00 20 lq r6,32\(r2\)
32: R_PPC64_TOC16_LO_DS \.toc\+0x28
+34: e0 80 00 00 lq r4,0\(r0\)
36: R_PPC64_ADDR16_LO_DS \.text
+38: e0 c3 00 00 lq r6,0\(r3\)
3a: R_PPC64_GOT16_DS dsym0
+3c: e0 c3 00 00 lq r6,0\(r3\)
3e: R_PPC64_GOT16_LO_DS dsym0
+40: e0 c3 00 00 lq r6,0\(r3\)
42: R_PPC64_PLT16_LO_DS dsym0
+44: e0 c3 00 00 lq r6,0\(r3\)
46: R_PPC64_SECTOFF_DS dsym1
+48: e0 c3 00 00 lq r6,0\(r3\)
4a: R_PPC64_SECTOFF_LO_DS dsym1
+4c: e0 c4 00 10 lq r6,16\(r4\)
+50: f8 c7 00 02 stq r6,0\(r7\)
+54: f8 c7 00 12 stq r6,16\(r7\)
+58: f8 c7 ff f2 stq r6,-16\(r7\)
+5c: f8 c7 80 02 stq r6,-32768\(r7\)
+60: f8 c7 7f f2 stq r6,32752\(r7\)
+64: 00 00 02 00 attn
Disassembly of section \.data:
0+ <dsym0>:
+0: 00 00 00 00 \.long 0x0
+4: de ad be ef stfdu f21,-16657\(r13\)
0+8 <dsym1>:
+8: 00 00 00 00 \.long 0x0
+c: ca fe ba be lfd f23,-17730\(r30\)
Disassembly of section \.toc:
0+ <\.toc>:
\.\.\.
0: R_PPC64_ADDR64 dsym0
8: R_PPC64_ADDR64 dsym1
10: R_PPC64_ADDR64 usym0
18: R_PPC64_ADDR64 usym1
20: R_PPC64_ADDR64 esym0
28: R_PPC64_ADDR64 esym1

View file

@ -0,0 +1,53 @@
.section ".data"
dsym0: .llong 0xdeadbeef
dsym1:
.section ".toc"
.L_tsym0:
.tc ignored0[TC],dsym0
.L_tsym1:
.tc ignored1[TC],dsym1
.L_tsym2:
.tc ignored2[TC],usym0
.L_tsym3:
.tc ignored3[TC],usym1
.L_tsym4:
.tc ignored4[TC],esym0
.L_tsym5:
.tc ignored5[TC],esym1
.section ".text"
lq 4,dsym0@l(3)
lq 4,dsym1@l(3)
lq 4,usym0@l(3)
lq 4,usym1@l(3)
lq 4,esym0@l(3)
lq 4,esym1@l(3)
lq 4,.L_tsym0@toc(2)
lq 4,.L_tsym1@toc(2)
lq 4,.L_tsym2@toc(2)
lq 4,.L_tsym3@toc(2)
lq 4,.L_tsym4@toc(2)
lq 4,.L_tsym5@toc(2)
lq 6,.L_tsym5@toc@l(2)
lq 4,.text@l(0)
lq 6,dsym0@got(3)
lq 6,dsym0@got@l(3)
lq 6,dsym0@plt@l(3)
lq 6,dsym1@sectoff(3)
lq 6,dsym1@sectoff@l(3)
lq 6,usym1-dsym0@l(4)
stq 6, 0(7)
stq 6, 16(7)
stq 6, -16(7)
stq 6, -32768(7)
stq 6, 32752(7)
attn
.section ".data"
usym0: .llong 0xcafebabe
usym1:

View file

@ -1,3 +1,7 @@
2003-06-10 Gary Hade <garyhade@us.ibm.com>
* ppc.h (PPC_OPERAND_DQ): Define.
2003-06-10 Richard Sandiford <rsandifo@redhat.com>
* h8300.h (IMM4_NS, IMM8_NS): New.

View file

@ -1,5 +1,5 @@
/* ppc.h -- Header file for PowerPC opcode table
Copyright 1994, 1995, 1999, 2000, 2001, 2002
Copyright 1994, 1995, 1999, 2000, 2001, 2002, 2003
Free Software Foundation, Inc.
Written by Ian Lance Taylor, Cygnus Support
@ -273,6 +273,9 @@ extern const struct powerpc_operand powerpc_operands[];
/* This operand is for the DS field in a DS form instruction. */
#define PPC_OPERAND_DS (020000)
/* This operand is for the DQ field in a DQ form instruction. */
#define PPC_OPERAND_DQ (040000)
/* The POWER and PowerPC assemblers use a few macros. We keep them
with the operands table for simplicity. The macro table is an

View file

@ -1,3 +1,10 @@
2003-06-10 Gary Hade <garyhade@us.ibm.com>
Alan Modra <amodra@bigpond.net.au>
* ppc-opc.c (DQ, RAQ, RSQ, RTQ): Define.
(insert_dq, extract_dq, insert_raq, insert_rtq, insert_rsq): New.
(powerpc_opcodes): Add "attn", "lq" and "stq".
2003-06-10 Richard Sandiford <rsandifo@redhat.com>
* h8300-dis.c (bfd_h8_disassemble): Don't print brackets round

View file

@ -68,6 +68,10 @@ static unsigned long insert_boe
PARAMS ((unsigned long, long, int, const char **));
static long extract_boe
PARAMS ((unsigned long, int, int *));
static unsigned long insert_dq
PARAMS ((unsigned long, long, int, const char **));
static long extract_dq
PARAMS ((unsigned long, int, int *));
static unsigned long insert_ds
PARAMS ((unsigned long, long, int, const char **));
static long extract_ds
@ -104,12 +108,18 @@ static unsigned long insert_ral
PARAMS ((unsigned long, long, int, const char **));
static unsigned long insert_ram
PARAMS ((unsigned long, long, int, const char **));
static unsigned long insert_raq
PARAMS ((unsigned long, long, int, const char **));
static unsigned long insert_ras
PARAMS ((unsigned long, long, int, const char **));
static unsigned long insert_rbs
PARAMS ((unsigned long, long, int, const char **));
static long extract_rbs
PARAMS ((unsigned long, int, int *));
static unsigned long insert_rsq
PARAMS ((unsigned long, long, int, const char **));
static unsigned long insert_rtq
PARAMS ((unsigned long, long, int, const char **));
static unsigned long insert_sh6
PARAMS ((unsigned long, long, int, const char **));
static long extract_sh6
@ -279,9 +289,15 @@ const struct powerpc_operand powerpc_operands[] =
#define DES DE + 1
{ 14, 0, insert_des, extract_des, PPC_OPERAND_PARENS | PPC_OPERAND_SIGNED },
/* The DQ field in a DQ form instruction. This is like D, but the
lower four bits are forced to zero. */
#define DQ DES + 1
{ 16, 0, insert_dq, extract_dq,
PPC_OPERAND_PARENS | PPC_OPERAND_SIGNED | PPC_OPERAND_DQ },
/* The DS field in a DS form instruction. This is like D, but the
lower two bits are forced to zero. */
#define DS DES + 1
#define DS DQ + 1
{ 16, 0, insert_ds, extract_ds,
PPC_OPERAND_PARENS | PPC_OPERAND_SIGNED | PPC_OPERAND_DS },
@ -389,15 +405,20 @@ const struct powerpc_operand powerpc_operands[] =
{ 16, 0, insert_nsi, extract_nsi,
PPC_OPERAND_NEGATIVE | PPC_OPERAND_SIGNED },
/* The RA field in an D, DS, X, XO, M, or MDS form instruction. */
/* The RA field in an D, DS, DQ, X, XO, M, or MDS form instruction. */
#define RA NSI + 1
#define RA_MASK (0x1f << 16)
{ 5, 16, 0, 0, PPC_OPERAND_GPR },
/* The RA field in the DQ form lq instruction, which has special
value restrictions. */
#define RAQ RA + 1
{ 5, 16, insert_raq, 0, PPC_OPERAND_GPR },
/* The RA field in a D or X form instruction which is an updating
load, which means that the RA field may not be zero and may not
equal the RT field. */
#define RAL RA + 1
#define RAL RAQ + 1
{ 5, 16, insert_ral, 0, PPC_OPERAND_GPR },
/* The RA field in an lmw instruction, which has special value
@ -430,8 +451,18 @@ const struct powerpc_operand powerpc_operands[] =
#define RT_MASK (0x1f << 21)
{ 5, 21, 0, 0, PPC_OPERAND_GPR },
/* The RS field of the DS form stq instruction, which has special
value restrictions. */
#define RSQ RS + 1
{ 5, 21, insert_rsq, 0, PPC_OPERAND_GPR },
/* The RT field of the DQ form lq instruction, which has special
value restrictions. */
#define RTQ RSQ + 1
{ 5, 21, insert_rtq, 0, PPC_OPERAND_GPR },
/* The SH field in an X or M form instruction. */
#define SH RS + 1
#define SH RTQ + 1
#define SH_MASK (0x1f << 11)
{ 5, 11, 0, 0, 0 },
@ -870,6 +901,32 @@ extract_boe (insn, dialect, invalid)
return value & 0x1e;
}
/* The DQ field in a DQ form instruction. This is like D, but the
lower four bits are forced to zero. */
/*ARGSUSED*/
static unsigned long
insert_dq (insn, value, dialect, errmsg)
unsigned long insn;
long value;
int dialect ATTRIBUTE_UNUSED;
const char ** errmsg ATTRIBUTE_UNUSED;
{
if ((value & 0xf) != 0 && errmsg != NULL)
*errmsg = _("offset not a multiple of 16");
return insn | (value & 0xfff0);
}
/*ARGSUSED*/
static long
extract_dq (insn, dialect, invalid)
unsigned long insn;
int dialect ATTRIBUTE_UNUSED;
int *invalid ATTRIBUTE_UNUSED;
{
return ((insn & 0xfff0) ^ 0x8000) - 0x8000;
}
static unsigned long
insert_ev2 (insn, value, dialect, errmsg)
unsigned long insn;
@ -1253,6 +1310,24 @@ insert_ram (insn, value, dialect, errmsg)
return insn | ((value & 0x1f) << 16);
}
/* The RA field in the DQ form lq instruction, which has special
value restrictions. */
/*ARGSUSED*/
static unsigned long
insert_raq (insn, value, dialect, errmsg)
unsigned long insn;
long value;
int dialect ATTRIBUTE_UNUSED;
const char **errmsg;
{
long rtvalue = (insn & RT_MASK) >> 21;
if (value == rtvalue && errmsg != NULL)
*errmsg = _("source and target register operands must be different");
return insn | ((value & 0x1f) << 16);
}
/* The RA field in a D or X form instruction which is an updating
store or an updating floating point load, which means that the RA
field may not be zero. */
@ -1298,6 +1373,38 @@ extract_rbs (insn, dialect, invalid)
return 0;
}
/* The RT field of the DQ form lq instruction, which has special
value restrictions. */
/*ARGSUSED*/
static unsigned long
insert_rtq (insn, value, dialect, errmsg)
unsigned long insn;
long value;
int dialect ATTRIBUTE_UNUSED;
const char **errmsg;
{
if ((value & 1) != 0 && errmsg != NULL)
*errmsg = _("target register operand must be even");
return insn | ((value & 0x1f) << 21);
}
/* The RS field of the DS form stq instruction, which has special
value restrictions. */
/*ARGSUSED*/
static unsigned long
insert_rsq (insn, value, dialect, errmsg)
unsigned long insn;
long value ATTRIBUTE_UNUSED;
int dialect ATTRIBUTE_UNUSED;
const char **errmsg;
{
if ((value & 1) != 0 && errmsg != NULL)
*errmsg = _("source register operand must be even");
return insn | ((value & 0x1f) << 21);
}
/* The SH field in an MD form instruction. This is split. */
/*ARGSUSED*/
@ -1768,6 +1875,7 @@ extract_tbr (insn, dialect, invalid)
sorted by major opcode. */
const struct powerpc_opcode powerpc_opcodes[] = {
{ "attn", X(0,256), X_MASK, POWER4, { 0 } },
{ "tdlgti", OPTO(2,TOLGT), OPTO_MASK, PPC64, { RA, SI } },
{ "tdllti", OPTO(2,TOLLT), OPTO_MASK, PPC64, { RA, SI } },
{ "tdeqi", OPTO(2,TOEQ), OPTO_MASK, PPC64, { RA, SI } },
@ -4335,6 +4443,8 @@ const struct powerpc_opcode powerpc_opcodes[] = {
{ "stfdu", OP(55), OP_MASK, COM, { FRS, D, RAS } },
{ "lq", OP(56), OP_MASK, POWER4, { RTQ, DQ, RAQ } },
{ "lfq", OP(56), OP_MASK, POWER2, { FRT, D, RA } },
{ "lfqu", OP(57), OP_MASK, POWER2, { FRT, D, RA } },
@ -4411,6 +4521,8 @@ const struct powerpc_opcode powerpc_opcodes[] = {
{ "stdu", DSO(62,1), DS_MASK, PPC64, { RS, DS, RAS } },
{ "stq", DSO(62,2), DS_MASK, POWER4, { RSQ, DS, RA } },
{ "fcmpu", X(63,0), X_MASK|(3<<21), COM, { BF, FRA, FRB } },
{ "frsp", XRC(63,12,0), XRA_MASK, COM, { FRT, FRB } },