This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
[RFA] e500 PPC port -- GAS
- From: Elena Zannoni <ezannoni at redhat dot com>
- To: binutils at sources dot redhat dot com
- Date: Sat, 17 Aug 2002 23:52:49 -0400
- Subject: [RFA] e500 PPC port -- GAS
Gas and testsuite changes.
Elena
[gas]
2002-08-17 Elena Zannoni <ezannoni@redhat.com>
From matthew green <mrg@redhat.com>
* config/tc-ppc.c (PPC_OPCODE_CLASSIC): Enable this everywhere
PPC_OPCODE_PPC is, except for BookE architectures.
(md_parse_option): Add support for -mspe.
(md_show_usage): Add -mspe.
(md_parse_option): Add support for -me500 and
-me500x2 to generate code for Motorola e500 core complex.
(md_show_usage): Add -me500 and -me500x2.
(PPC_APUINFO_ISEL, PPC_APUINFO_PMR, PPC_APUINFO_RFMCI,
PPC_APUINFO_CACHELCK, PPC_APUINFO_SPE, PPC_APUINFO_EFS,
PPC_APUINFO_BRLOCK): New macros.
(ppc_cleanup): New function.
(ppc_apuinfo_section_add): New function.
(APUID): New macro.
(md_assemble): Collect info and write the APUinfo section.
* config/tc-ppc.h (md_cleanup): Define.
(ppc_cleanup): Export.
(ELF_TC_SPECIAL_SECTIONS): Add .PPC.EMB.apuinfo section.
Index: tc-ppc.c
===================================================================
RCS file: /cvs/uberbaum/gas/config/tc-ppc.c,v
retrieving revision 1.53
diff -u -r1.53 tc-ppc.c
--- tc-ppc.c 6 Aug 2002 02:30:06 -0000 1.53
+++ tc-ppc.c 18 Aug 2002 03:29:59 -0000
@@ -130,6 +130,7 @@
static void ppc_elf_rdata PARAMS ((int));
static void ppc_elf_lcomm PARAMS ((int));
static void ppc_elf_validate_fix PARAMS ((fixS *, segT));
+static void ppc_apuinfo_section_add PARAMS((unsigned int apu, unsigned int version));
#endif
#ifdef TE_PE
@@ -787,6 +788,20 @@
#ifdef OBJ_ELF
symbolS *GOT_symbol; /* Pre-defined "_GLOBAL_OFFSET_TABLE" */
+#define PPC_APUINFO_ISEL 0x40
+#define PPC_APUINFO_PMR 0x41
+#define PPC_APUINFO_RFMCI 0x42
+#define PPC_APUINFO_CACHELCK 0x43
+#define PPC_APUINFO_SPE 0x100
+#define PPC_APUINFO_EFS 0x101
+#define PPC_APUINFO_BRLOCK 0x102
+
+/*
+ * We keep a list of APUinfo
+ */
+unsigned long *ppc_apuinfo_list;
+unsigned int ppc_apuinfo_num;
+unsigned int ppc_apuinfo_num_alloc;
#endif /* OBJ_ELF */
#ifdef OBJ_ELF
@@ -870,43 +885,62 @@
/* -m601 means to assemble for the PowerPC 601, which includes
instructions that are holdovers from the Power. */
else if (strcmp (arg, "601") == 0)
- ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_601 | PPC_OPCODE_32;
+ ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC
+ | PPC_OPCODE_601 | PPC_OPCODE_32;
/* -mppc, -mppc32, -m603, and -m604 mean to assemble for the
PowerPC 603/604. */
else if (strcmp (arg, "ppc") == 0
|| strcmp (arg, "ppc32") == 0
|| strcmp (arg, "603") == 0
|| strcmp (arg, "604") == 0)
- ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_32;
+ ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_32;
/* -m403 and -m405 mean to assemble for the PowerPC 403/405. */
else if (strcmp (arg, "403") == 0
|| strcmp (arg, "405") == 0)
- ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_403 | PPC_OPCODE_32;
+ ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC
+ | PPC_OPCODE_403 | PPC_OPCODE_32;
else if (strcmp (arg, "7400") == 0
|| strcmp (arg, "7410") == 0
|| strcmp (arg, "7450") == 0
|| strcmp (arg, "7455") == 0)
- ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_ALTIVEC | PPC_OPCODE_32;
+ ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC
+ | PPC_OPCODE_ALTIVEC | PPC_OPCODE_32;
else if (strcmp (arg, "altivec") == 0)
{
if (ppc_cpu == 0)
- ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_ALTIVEC;
+ ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_ALTIVEC;
else
ppc_cpu |= PPC_OPCODE_ALTIVEC;
}
+ else if (strcmp (arg, "e500") == 0 || strcmp (arg, "e500x2") == 0)
+ {
+ ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_SPE
+ | PPC_OPCODE_ISEL | PPC_OPCODE_EFS | PPC_OPCODE_BRLOCK
+ | PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI;
+ }
+ else if (strcmp (arg, "spe") == 0)
+ {
+ if (ppc_cpu == 0)
+ ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_SPE | PPC_OPCODE_EFS;
+ else
+ ppc_cpu |= PPC_OPCODE_SPE;
+ }
/* -mppc64 and -m620 mean to assemble for the 64-bit PowerPC
620. */
else if (strcmp (arg, "ppc64") == 0 || strcmp (arg, "620") == 0)
{
- ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_64;
+ ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_64;
}
else if (strcmp (arg, "ppc64bridge") == 0)
{
- ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_64_BRIDGE | PPC_OPCODE_64;
+ ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC
+ | PPC_OPCODE_64_BRIDGE | PPC_OPCODE_64;
}
/* -mbooke/-mbooke32 mean enable 32-bit BookE support. */
else if (strcmp (arg, "booke") == 0 || strcmp (arg, "booke32") == 0)
- ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_32;
+ {
+ ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_32;
+ }
/* -mbooke64 means enable 64-bit BookE support. */
else if (strcmp (arg, "booke64") == 0)
{
@@ -915,7 +949,8 @@
}
else if (strcmp (arg, "power4") == 0)
{
- ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_POWER4;
+ ppc_cpu = PPC_OPCODE_PPC| PPC_OPCODE_CLASSIC
+ | PPC_OPCODE_64 | PPC_OPCODE_POWER4;
}
/* -mcom means assemble for the common intersection between Power
and PowerPC. At present, we just allow the union, rather
@@ -1037,6 +1072,9 @@
-many generate code for any architecture (PWR/PWRX/PPC)\n\
-mregnames Allow symbolic names for registers\n\
-mno-regnames Do not allow symbolic names for registers\n"));
+ fprintf (stream, _("\
+-me500, -me500x2 generate code for Motorola e500 core complex\n\
+-mspe generate code for Motorola SPE instructions\n"));
#ifdef OBJ_ELF
fprintf (stream, _("\
-mrelocatable support for GCC's -mrelocatble option\n\
@@ -1070,12 +1108,12 @@
else if (strcmp (default_cpu, "rs6000") == 0)
ppc_cpu = PPC_OPCODE_POWER | PPC_OPCODE_32;
else if (strncmp (default_cpu, "powerpc", 7) == 0)
- {
- if (default_cpu[7] == '6' && default_cpu[8] == '4')
- ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_64;
- else
- ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_32;
- }
+ {
+ if (default_cpu[7] == '6' && default_cpu[8] == '4')
+ ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_64;
+ else
+ ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_32;
+ }
else
as_fatal (_("Unknown default cpu = %s, os = %s"),
default_cpu, default_os);
@@ -1240,6 +1278,64 @@
#endif
}
+void
+ppc_cleanup ()
+{
+ if (ppc_apuinfo_list == NULL)
+ return;
+
+ /* Ok, so write the section info out. We have this layout:
+
+ byte data what
+ ---- ---- ----
+ 0 8 length of "APUinfo\0"
+ 4 (n*4) number of APU's (4 bytes each)
+ 8 2 note type 2
+ 12 "APUinfo\0" name
+ 20 APU#1 first APU's info
+ 24 APU#2 second APU's info
+ ... ...
+ */
+ {
+ char *p;
+ asection *seg = now_seg;
+ subsegT subseg = now_subseg;
+ asection *apuinfo_secp = (asection *) NULL;
+ int i;
+
+ /* Create the .PPC.EMB.apuinfo section. */
+ apuinfo_secp = subseg_new (".PPC.EMB.apuinfo", 0);
+ bfd_set_section_flags (stdoutput,
+ apuinfo_secp,
+ SEC_HAS_CONTENTS | SEC_READONLY | SEC_MERGE);
+
+ p = frag_more (4);
+ md_number_to_chars (p, (valueT) 8, 4);
+
+ p = frag_more (4);
+ md_number_to_chars (p, (valueT) ppc_apuinfo_num, 4);
+
+ p = frag_more (4);
+ md_number_to_chars (p, (valueT) 2, 4);
+
+ p = frag_more (8);
+ strcpy (p, "APUinfo");
+
+ for (i = 0; i < ppc_apuinfo_num; i++)
+ {
+ p = frag_more (4);
+ md_number_to_chars (p, (valueT) ppc_apuinfo_list[i], 4);
+ }
+
+ frag_align (2, 0, 0);
+
+ /* We probably can't restore the current segment, for there likely
+ isn't one yet... */
+ if (seg && subseg)
+ subseg_set (seg, subseg);
+ }
+}
+
/* Insert an operand value into an instruction. */
static unsigned long
@@ -1837,6 +1933,38 @@
#endif
+#define APUID(a,v) ((((a) & 0xffff) << 16) | ((v) & 0xffff))
+static void
+ppc_apuinfo_section_add(apu, version)
+ unsigned int apu, version;
+{
+ unsigned int i;
+
+ /* Check we don't already exist. */
+ for (i = 0; i < ppc_apuinfo_num; i++)
+ if (ppc_apuinfo_list[i] == APUID(apu, version))
+ return;
+
+ if (ppc_apuinfo_num == ppc_apuinfo_num_alloc)
+ {
+ if (ppc_apuinfo_num_alloc == 0)
+ {
+ ppc_apuinfo_num_alloc = 4;
+ ppc_apuinfo_list = (unsigned long *)
+ xmalloc (sizeof (unsigned long) * ppc_apuinfo_num_alloc);
+ }
+ else
+ {
+ ppc_apuinfo_num_alloc += 4;
+ ppc_apuinfo_list = (unsigned long *) xrealloc (ppc_apuinfo_list,
+ sizeof (unsigned long) * ppc_apuinfo_num_alloc);
+ }
+ }
+ ppc_apuinfo_list[ppc_apuinfo_num++] = APUID(apu, version);
+}
+#undef APUID
+
+
/* We need to keep a list of fixups. We can't simply generate them as
we go, because that would require us to first create the frag, and
that would screw up references to ``.''. */
@@ -1961,7 +2089,6 @@
operand = &powerpc_operands[next_opindex];
next_opindex = 0;
}
-
errmsg = NULL;
/* If this is a fake operand, then we do not expect anything
@@ -2322,6 +2449,29 @@
if (*str != '\0')
as_bad (_("junk at end of line: `%s'"), str);
+ /* Do we need/want a APUinfo section? */
+ if (ppc_cpu & (PPC_OPCODE_SPE
+ | PPC_OPCODE_ISEL | PPC_OPCODE_EFS
+ | PPC_OPCODE_BRLOCK | PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK
+ | PPC_OPCODE_RFMCI))
+ {
+ /* These are all version "1". */
+ if (opcode->flags & PPC_OPCODE_SPE)
+ ppc_apuinfo_section_add(PPC_APUINFO_SPE, 1);
+ if (opcode->flags & PPC_OPCODE_ISEL)
+ ppc_apuinfo_section_add(PPC_APUINFO_ISEL, 1);
+ if (opcode->flags & PPC_OPCODE_EFS)
+ ppc_apuinfo_section_add(PPC_APUINFO_EFS, 1);
+ if (opcode->flags & PPC_OPCODE_BRLOCK)
+ ppc_apuinfo_section_add(PPC_APUINFO_BRLOCK, 1);
+ if (opcode->flags & PPC_OPCODE_PMR)
+ ppc_apuinfo_section_add(PPC_APUINFO_PMR, 1);
+ if (opcode->flags & PPC_OPCODE_CACHELCK)
+ ppc_apuinfo_section_add(PPC_APUINFO_CACHELCK, 1);
+ if (opcode->flags & PPC_OPCODE_RFMCI)
+ ppc_apuinfo_section_add(PPC_APUINFO_RFMCI, 1);
+ }
+
/* Write out the instruction. */
f = frag_more (4);
md_number_to_chars (f, insn, 4);
@@ -5221,16 +5371,16 @@
&& operand->shift == 0)
fixP->fx_r_type = BFD_RELOC_PPC_B26;
else if ((operand->flags & PPC_OPERAND_RELATIVE) != 0
- && operand->bits == 16
- && operand->shift == 0)
- {
- fixP->fx_r_type = BFD_RELOC_PPC_B16;
+ && operand->bits == 16
+ && operand->shift == 0)
+ {
+ fixP->fx_r_type = BFD_RELOC_PPC_B16;
#ifdef OBJ_XCOFF
- fixP->fx_size = 2;
- if (target_big_endian)
- fixP->fx_where += 2;
+ fixP->fx_size = 2;
+ if (target_big_endian)
+ fixP->fx_where += 2;
#endif
- }
+ }
else if ((operand->flags & PPC_OPERAND_ABSOLUTE) != 0
&& operand->bits == 26
&& operand->shift == 0)
@@ -5238,14 +5388,14 @@
else if ((operand->flags & PPC_OPERAND_ABSOLUTE) != 0
&& operand->bits == 16
&& operand->shift == 0)
- {
- fixP->fx_r_type = BFD_RELOC_PPC_BA16;
+ {
+ fixP->fx_r_type = BFD_RELOC_PPC_BA16;
#ifdef OBJ_XCOFF
- fixP->fx_size = 2;
- if (target_big_endian)
- fixP->fx_where += 2;
+ fixP->fx_size = 2;
+ if (target_big_endian)
+ fixP->fx_where += 2;
#endif
- }
+ }
#if defined (OBJ_XCOFF) || defined (OBJ_ELF)
else if ((operand->flags & PPC_OPERAND_PARENS) != 0
&& operand->bits == 16
Index: tc-ppc.h
===================================================================
RCS file: /cvs/uberbaum/gas/config/tc-ppc.h,v
retrieving revision 1.18
diff -u -r1.18 tc-ppc.h
--- tc-ppc.h 11 Jul 2002 01:07:49 -0000 1.18
+++ tc-ppc.h 18 Aug 2002 03:29:59 -0000
@@ -248,6 +248,7 @@
{ ".sbss", SHT_NOBITS, SHF_ALLOC + SHF_WRITE }, \
{ ".sdata2", SHT_PROGBITS, SHF_ALLOC }, \
{ ".sbss2", SHT_PROGBITS, SHF_ALLOC }, \
+ { ".PPC.EMB.apuinfo", SHT_NOTE, 0 }, \
{ ".PPC.EMB.sdata0", SHT_PROGBITS, SHF_ALLOC }, \
{ ".PPC.EMB.sbss0", SHT_PROGBITS, SHF_ALLOC }, \
/* Extra sections for 64-bit ELF PPC. */ \
@@ -285,3 +286,6 @@
extern int ppc_parse_name PARAMS ((const char *, struct expressionS *));
#define md_operand(x)
+
+#define md_cleanup() ppc_cleanup ()
+ extern void ppc_cleanup PARAMS ((void));
[gas/testsuite]
2002-08-17 Elena Zannoni <ezannoni@redhat.com>
From matthew green <mrg@redhat.com>
* e500.s: New tests for e500 instructions.
* e500.d: Results for new test.
* ppc.exp: Test e500.s.
Index: ppc.exp
===================================================================
RCS file: /cvs/uberbaum/gas/testsuite/gas/ppc/ppc.exp,v
retrieving revision 1.6
diff -u -r1.6 ppc.exp
--- ppc.exp 21 Feb 2002 03:57:34 -0000 1.6
+++ ppc.exp 18 Aug 2002 03:39:23 -0000
@@ -37,3 +37,7 @@
run_dump_test "booke"
}
}
+
+if { [istarget powerpc*-*-*] } then {
+ run_dump_test "e500"
+}
--- /dev/null Sat Aug 17 18:49:30 2002
+++ e500.s Sat Aug 17 17:15:06 2002
@@ -0,0 +1,15 @@
+# Motorola PowerPC e500 tests
+ .section ".text"
+start:
+ isel 2, 3, 4, 23
+ dcblc 4, 5, 6
+ dcbtls 7, 8, 9
+ dcbtstls 10, 11, 12
+ icbtls 13, 14, 15
+ icblc 16, 17, 18
+ mtpmr 201, 4
+ mfpmr 5, 203
+ bblels
+ bbelr
+ mtspefscr 8
+ mfspefscr 9
--- /dev/null Sat Aug 17 18:49:30 2002
+++ e500.d Sat Aug 17 17:15:06 2002
@@ -0,0 +1,22 @@
+#as: -mppc -me500
+#objdump: -Dr -Me500
+#name: e500 tests
+
+.*: +file format elf(32)?(64)?-powerpc
+
+Disassembly of section \.text:
+
+0+0000000 <start>:
+ 0: 7c 43 25 de isel r2,r3,r4,23
+ 4: 7c 85 33 0c dcblc 4,r5,r6
+ 8: 7c e8 49 4c dcbtls 7,r8,r9
+ c: 7d 4b 61 0c dcbtstls 10,r11,r12
+ 10: 7d ae 7b cc icbtls 13,r14,r15
+ 14: 7e 11 91 cc icblc 16,r17,r18
+ 18: 7c 89 43 9c mtpmr r41,r4
+ 1c: 7c ab 52 9c mfpmr r5,r43
+ 20: 7c 00 04 0c bblels
+ 24: 7c 00 04 4c bbelr
+ 28: 7d 00 83 a6 mtspefscr r8
+ 2c: 7d 20 82 a6 mfspefscr r9
+Disassembly of section \.data: