/* tc-ppc.c -- Assemble for the PowerPC or POWER (RS/6000)
- Copyright (C) 1994, 95, 96, 97, 98, 1999 Free Software Foundation, Inc.
+ Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000
+ Free Software Foundation, Inc.
Written by Ian Lance Taylor, Cygnus Support.
This file is part of GAS, the GNU Assembler.
static void ppc_rename PARAMS ((int));
static void ppc_toc PARAMS ((int));
static void ppc_xcoff_cons PARAMS ((int));
+static void ppc_machine PARAMS ((int));
static void ppc_vbyte PARAMS ((int));
#endif
{ "text", ppc_section, 't' },
{ "toc", ppc_toc, 0 },
{ "long", ppc_xcoff_cons, 2 },
+ { "llong", ppc_xcoff_cons, 3 },
{ "word", ppc_xcoff_cons, 1 },
{ "short", ppc_xcoff_cons, 1 },
{ "vbyte", ppc_vbyte, 0 },
+ { "machine", ppc_machine, 0 },
#endif
#ifdef OBJ_ELF
1. r<reg_num> which has the value <reg_num>.
2. r.<reg_num> which has the value <reg_num>.
-
Each floating point register has predefined names of the form:
1. f<reg_num> which has the value <reg_num>.
2. f.<reg_num> which has the value <reg_num>.
+ Each vector unit register has predefined names of the form:
+ 1. v<reg_num> which has the value <reg_num>.
+ 2. v.<reg_num> which has the value <reg_num>.
+
Each condition register has predefined names of the form:
1. cr<reg_num> which has the value <reg_num>.
2. cr.<reg_num> which has the value <reg_num>.
{ "srr0", 26 }, /* Machine Status Save/Restore Register 0 */
{ "srr1", 27 }, /* Machine Status Save/Restore Register 1 */
+
+ { "v.0", 0 }, /* Vector registers */
+ { "v.1", 1 },
+ { "v.10", 10 },
+ { "v.11", 11 },
+ { "v.12", 12 },
+ { "v.13", 13 },
+ { "v.14", 14 },
+ { "v.15", 15 },
+ { "v.16", 16 },
+ { "v.17", 17 },
+ { "v.18", 18 },
+ { "v.19", 19 },
+ { "v.2", 2 },
+ { "v.20", 20 },
+ { "v.21", 21 },
+ { "v.22", 22 },
+ { "v.23", 23 },
+ { "v.24", 24 },
+ { "v.25", 25 },
+ { "v.26", 26 },
+ { "v.27", 27 },
+ { "v.28", 28 },
+ { "v.29", 29 },
+ { "v.3", 3 },
+ { "v.30", 30 },
+ { "v.31", 31 },
+ { "v.4", 4 },
+ { "v.5", 5 },
+ { "v.6", 6 },
+ { "v.7", 7 },
+ { "v.8", 8 },
+ { "v.9", 9 },
+
+ { "v0", 0 },
+ { "v1", 1 },
+ { "v10", 10 },
+ { "v11", 11 },
+ { "v12", 12 },
+ { "v13", 13 },
+ { "v14", 14 },
+ { "v15", 15 },
+ { "v16", 16 },
+ { "v17", 17 },
+ { "v18", 18 },
+ { "v19", 19 },
+ { "v2", 2 },
+ { "v20", 20 },
+ { "v21", 21 },
+ { "v22", 22 },
+ { "v23", 23 },
+ { "v24", 24 },
+ { "v25", 25 },
+ { "v26", 26 },
+ { "v27", 27 },
+ { "v28", 28 },
+ { "v29", 29 },
+ { "v3", 3 },
+ { "v30", 30 },
+ { "v31", 31 },
+ { "v4", 4 },
+ { "v5", 5 },
+ { "v6", 6 },
+ { "v7", 7 },
+ { "v8", 8 },
+ { "v9", 9 },
{ "xer", 1 },
/* The size of the processor we are assembling for. This is either
PPC_OPCODE_32 or PPC_OPCODE_64. */
-static int ppc_size = PPC_OPCODE_32;
+static unsigned long ppc_size = PPC_OPCODE_32;
+
+/* Whether to target xcoff64 */
+static int ppc_xcoff64 = 0;
/* Opcode hash table. */
static struct hash_control *ppc_hash;
break;
#endif
+ /* a64 and a32 determine whether to use XCOFF64 or XCOFF32. */
+ case 'a':
+ if (strcmp (arg, "64") == 0)
+ ppc_xcoff64 = 1;
+ else if (strcmp (arg, "32") == 0)
+ ppc_xcoff64 = 0;
+ else
+ return 0;
+ break;
+
case 'm':
/* -mpwrx and -mpwr2 mean to assemble for the IBM POWER/2
(RIOS2). */
|| strcmp (arg, "603") == 0
|| strcmp (arg, "604") == 0)
ppc_cpu = PPC_OPCODE_PPC;
+ else if (strcmp (arg, "7400") == 0)
+ ppc_cpu = PPC_OPCODE_PPC | PPC_OPCODE_ALTIVEC;
/* -mppc64 and -m620 mean to assemble for the 64-bit PowerPC
620. */
else if (strcmp (arg, "ppc64") == 0 || strcmp (arg, "620") == 0)
return bfd_arch_unknown;
}
+unsigned long
+ppc_mach ()
+{
+ return (ppc_size == PPC_OPCODE_64) ? 620 : 0;
+}
+
+int
+ppc_subseg_align()
+{
+ return (ppc_xcoff64) ? 3 : 2;
+}
+
+extern char*
+ppc_target_format()
+{
+#ifdef OBJ_COFF
+#ifdef TE_PE
+ return (target_big_endian ? "pe-powerpc" : "pe-powerpcle");
+#elif TE_POWERMAC
+#else
+ return (ppc_xcoff64 ? "aixcoff64-rs6000" : "aixcoff-rs6000");
+#endif
+#ifdef TE_POWERMAC
+ return "xcoff-powermac";
+#endif
+#endif
+#ifdef OBJ_ELF
+ return (target_big_endian ? "elf32-powerpc" : "elf32-powerpcle");
+#endif
+}
+
/* This function is called when the assembler starts up. It is called
after the options have been parsed and the output file has been
opened. */
valid, but, to permit this code to assemble on a 64
bit host, we sign extend the 32 bit value. */
if (val > 0
- && (val & 0x80000000) != 0
- && (val & 0xffffffff) == val)
+ && (val & (offsetT) 0x80000000) != 0
+ && (val & (offsetT) 0xffffffff) == val)
{
val -= 0x80000000;
val -= 0x80000000;
/* Pseudo op to make file scope bss items */
static void
ppc_elf_lcomm(xxx)
- int xxx;
+ int xxx ATTRIBUTE_UNUSED;
{
register char *name;
register char c;
break;
case BFD_RELOC_HI16_S:
- ex.X_add_number = (((ex.X_add_number >> 16) & 0xffff)
- + ((ex.X_add_number >> 15) & 1));
+ ex.X_add_number = ((((ex.X_add_number >> 16) & 0xffff)
+ + ((ex.X_add_number >> 15) & 1))
+ & 0xffff);
break;
}
#endif
static void
ppc_byte (ignore)
- int ignore;
+ int ignore ATTRIBUTE_UNUSED;
{
if (*input_line_pointer != '\"')
{
static void
ppc_csect (ignore)
- int ignore;
+ int ignore ATTRIBUTE_UNUSED;
{
char *name;
char endc;
symbol_set_frag (sym, frag_now);
S_SET_VALUE (sym, (valueT) frag_now_fix ());
- symbol_get_tc (sym)->align = 2;
+ symbol_get_tc (sym)->align = (ppc_xcoff64) ? 3 : 2;
symbol_get_tc (sym)->output = 1;
symbol_get_tc (sym)->within = sym;
static void
ppc_named_section (ignore)
- int ignore;
+ int ignore ATTRIBUTE_UNUSED;
{
char *user_name;
const char *real_name;
static void
ppc_extern (ignore)
- int ignore;
+ int ignore ATTRIBUTE_UNUSED;
{
char *name;
char endc;
static void
ppc_lglobl (ignore)
- int ignore;
+ int ignore ATTRIBUTE_UNUSED;
{
char *name;
char endc;
static void
ppc_rename (ignore)
- int ignore;
+ int ignore ATTRIBUTE_UNUSED;
{
char *name;
char endc;
static void
ppc_stabx (ignore)
- int ignore;
+ int ignore ATTRIBUTE_UNUSED;
{
char *name;
int len;
static void
ppc_function (ignore)
- int ignore;
+ int ignore ATTRIBUTE_UNUSED;
{
char *name;
char endc;
static void
ppc_bf (ignore)
- int ignore;
+ int ignore ATTRIBUTE_UNUSED;
{
symbolS *sym;
static void
ppc_ef (ignore)
- int ignore;
+ int ignore ATTRIBUTE_UNUSED;
{
symbolS *sym;
static void
ppc_bs (ignore)
- int ignore;
+ int ignore ATTRIBUTE_UNUSED;
{
char *name;
char endc;
static void
ppc_es (ignore)
- int ignore;
+ int ignore ATTRIBUTE_UNUSED;
{
symbolS *sym;
static void
ppc_bb (ignore)
- int ignore;
+ int ignore ATTRIBUTE_UNUSED;
{
symbolS *sym;
static void
ppc_eb (ignore)
- int ignore;
+ int ignore ATTRIBUTE_UNUSED;
{
symbolS *sym;
static void
ppc_bc (ignore)
- int ignore;
+ int ignore ATTRIBUTE_UNUSED;
{
char *name;
int len;
static void
ppc_ec (ignore)
- int ignore;
+ int ignore ATTRIBUTE_UNUSED;
{
symbolS *sym;
static void
ppc_toc (ignore)
- int ignore;
+ int ignore ATTRIBUTE_UNUSED;
{
if (ppc_toc_csect != (symbolS *) NULL)
subseg_set (data_section, symbol_get_tc (ppc_toc_csect)->subseg);
cons (1 << log_size);
}
+static void
+ppc_machine(dummy)
+ int dummy ATTRIBUTE_UNUSED;
+{
+ discard_rest_of_line();
+ /* What does aix use this for? */
+}
+
static void
ppc_vbyte (dummy)
- int dummy;
+ int dummy ATTRIBUTE_UNUSED;
{
expressionS exp;
int byte_count;
static void
ppc_tc (ignore)
- int ignore;
+ int ignore ATTRIBUTE_UNUSED;
{
#ifdef OBJ_XCOFF
else
{
++input_line_pointer;
- cons (4);
+ cons ((ppc_size == PPC_OPCODE_64) ? 8 : 4);
}
}
\f
*/
static void
ppc_previous(ignore)
- int ignore;
+ int ignore ATTRIBUTE_UNUSED;
{
symbolS *tmp;
*/
static void
ppc_pdata(ignore)
- int ignore;
+ int ignore ATTRIBUTE_UNUSED;
{
if (pdata_section == 0)
{
*/
static void
ppc_ydata(ignore)
- int ignore;
+ int ignore ATTRIBUTE_UNUSED;
{
if (ydata_section == 0)
{
*/
static void
ppc_reldata(ignore)
- int ignore;
+ int ignore ATTRIBUTE_UNUSED;
{
if (reldata_section == 0)
{
*/
static void
ppc_rdata(ignore)
- int ignore;
+ int ignore ATTRIBUTE_UNUSED;
{
if (rdata_section == 0)
{
*/
static void
ppc_ualong(ignore)
- int ignore;
+ int ignore ATTRIBUTE_UNUSED;
{
/* try for long */
cons ( 4 );
*/
static void
ppc_znop(ignore)
- int ignore;
+ int ignore ATTRIBUTE_UNUSED;
{
unsigned long insn;
const struct powerpc_opcode *opcode;
void
ppc_pe_section (ignore)
- int ignore;
+ int ignore ATTRIBUTE_UNUSED;
{
/* Strip out the section name */
char *section_name;
static void
ppc_pe_function (ignore)
- int ignore;
+ int ignore ATTRIBUTE_UNUSED;
{
char *name;
char endc;
static void
ppc_pe_tocd (ignore)
- int ignore;
+ int ignore ATTRIBUTE_UNUSED;
{
if (tocdata_section == 0)
{
int
md_estimate_size_before_relax (fragp, seg)
- fragS *fragp;
- asection *seg;
+ fragS *fragp ATTRIBUTE_UNUSED;
+ asection *seg ATTRIBUTE_UNUSED;
{
abort ();
return 0;
void
md_convert_frag (abfd, sec, fragp)
- bfd *abfd;
- asection *sec;
- fragS *fragp;
+ bfd *abfd ATTRIBUTE_UNUSED;
+ asection *sec ATTRIBUTE_UNUSED;
+ fragS *fragp ATTRIBUTE_UNUSED;
{
abort ();
}
/*ARGSUSED*/
symbolS *
md_undefined_symbol (name)
- char *name;
+ char *name ATTRIBUTE_UNUSED;
{
return 0;
}
long
md_pcrel_from_section (fixp, sec)
fixS *fixp;
- segT sec;
+ segT sec ATTRIBUTE_UNUSED;
{
return fixp->fx_frag->fr_address + fixp->fx_where;
}
{
while (symbol_get_tc (csect)->next != (symbolS *) NULL
&& (symbol_get_frag (symbol_get_tc (csect)->next)->fr_address
- <= symbol_get_frag (fix->fx_addsy)->fr_address))
+ <= val))
{
/* If the csect address equals the symbol value, then we
have to look through the full symbol table to see
whether this is the csect we want. Note that we will
only get here if the csect has zero length. */
- if ((symbol_get_frag (csect)->fr_address
- == symbol_get_frag (fix->fx_addsy)->fr_address)
+ if ((symbol_get_frag (csect)->fr_address == val)
&& S_GET_VALUE (csect) == S_GET_VALUE (fix->fx_addsy))
{
symbolS *scan;
else if ((operand->flags & PPC_OPERAND_PARENS) != 0
&& operand->bits == 16
&& operand->shift == 0
- && operand->insert == NULL
&& fixp->fx_addsy != NULL
&& ppc_is_toc_sym (fixp->fx_addsy))
{
value, 4);
break;
+ case BFD_RELOC_64:
+ if (fixp->fx_pcrel)
+ fixp->fx_r_type = BFD_RELOC_64_PCREL;
+ /* fall through */
+ case BFD_RELOC_64_PCREL:
+ md_number_to_chars (fixp->fx_frag->fr_literal + fixp->fx_where,
+ value, 8);
+ break;
case BFD_RELOC_LO16:
case BFD_RELOC_16:
case BFD_RELOC_GPREL16:
arelent *
tc_gen_reloc (seg, fixp)
- asection *seg;
+ asection *seg ATTRIBUTE_UNUSED;
fixS *fixp;
{
arelent *reloc;