> > > + if (rel->r_type == R_TOCU)
> > > + *relocation = (*relocation & 0xffff0000) >> 16 ;
> > >
> > > Please double-check this. The doc might say "the high-order 16 bits
> > > of the displacement" but I suspect that isn't 100% correct. If the
> > > code in your testcases is proper usage, and I expect it is, then the
> > > high 16 bits needs to be adjusted for the low 16 bits being signed.
> > >
> > > You probably want:
> > > *relocation = ((*relocation + 0x8000) >> 16) & 0xffff;
> >
> > Yes, you're right. I wasn't aware of that.
> >
> > > +#ifdef OBJ_XCOFF
> > > + /* AIX often generates addis instructions using "addis RT, D(RA)"
> > > + format instead of the classic "addis RT, RA, SI" one.
> > > + Restore it to the default format as it's the one encoded
> > > + in ppc opcodes. */
> > > + if (!strcmp (opcode->name, "addis") && strchr (str, '(') != NULL)
> > > + ppc_xcoff_fixup_addis (&str);
> > > +#endif
> > > +
> > >
> > > Yikes, can't you tell people to fix their code? I see so many ways
> > > for this to go wrong, for example, if an expression calculating an
> > > offset happened to use parentheses. Also, ppc_xcoff_fixup_addis does
> > > no sanity checking and can easily cause buffer overflows.
> >
> > Sadly no... AIX assembler wants the 3rd argument of an addis to be absolute.
> > Thus, it's using a different syntax when it's not.
> > To be precise, "addis RT, RA, SI" is allowed only if SI is an absolute and
> > "addis RT, D(RA)" is allowed only if D is a label/symbol having a relocation.
> > Thus, I need to find a way to allow both in GNU as.
> > I agree that my solution isn't the best one, but I didn't find any way to
> > add an opcode in ppc-opc.c.
> > If you have any idea how to do it properly, I would be glad. Otherwise,
> > I will have to use this approach..
>
> The operand scanning isn't designed to support alternate operand
> syntax like this, so you are correct that transforming the input is
> likely the easiest way to support an ancient syntax not even mentioned
> in current powerpc architecture books. However, I'd like to see
> better syntax checking before attempting the transform. Something
> like the following, perhaps. Note the check for no comma past the
> first one found, use of strrchr, and checks for empty strings. Do you
> need to treat "subis" the same way?
>
> if (strcmp (opcode->name, "addis") == 0)
> {
> char *rt_e = strchr (str, ',');
> if (rt_e != NULL
> && strchr (rt_e + 1, ',') == NULL)
> {
> char *d_e = strchr (rt_e + 1, '(');
> if (d_e != NULL && d_e != rt_e + 1)
> {
> char *ra_e = strrchr (d_e + 1, ')');
> if (ra_e != NULL && ra_e != d_e + 1)
> ppc_xcoff_fixup_addis (str, rt_e, d_e, ra_e);
> }
> }
> }
AFAIK only addis as this strange syntax. By the way, in IBM website, they
describe this syntax (https://www.ibm.com/support/knowledgecenter/ssw_aix_72/assembler/idalangref_add_imm_shift_inst.html)
"The addis instruction has two syntax forms; however, the second form
is only valid when the R_TOCU relocation type is used in the D expression. "
Clément