+2021-04-12 Alan Modra <amodra@gmail.com>
+
+ * config/tc-ppc.c (insn_validate): Use uint64_t for operand values.
+ (md_assemble): Likewise. Handle bignum operands.
+ (ppc_elf_suffix): Handle O_big. Remove unnecessary input_line_pointer
+ check.
+ * expr.c: Delete unnecessary forward declarations.
+ (generic_bignum_to_int32): Return uint32_t.
+ (generic_bignum_to_int64): Return uint64_t. Compile always.
+ (operand): Twiddle X_extrabit for unary '~'. Set X_unsigned and
+ clear X_extrabit for unary '!'.
+ * expr.h (generic_bignum_to_int32): Declare.
+ (generic_bignum_to_int64): Declare.
+ * testsuite/gas/ppc/prefix-pcrel.s,
+ * testsuite/gas/ppc/prefix-pcrel.d: Add more instructions.
+
+2021-04-09 Tejas Belagod <tejas.belagod@arm.com>
+
2021-04-12 Nelson Chu <nelson.chu@sifive.com>
* testsuite/gas/riscv/march-fail-order-x-std.d: Renamed from
2021-04-09 Tejas Belagod <tejas.belagod@arm.com>
- * config/tc-aarch64.c (warn_unpredictable_ldst): Clean-up diagnostic messages
- for LD/ST Exclusive instructions.
+ * config/tc-aarch64.c (warn_unpredictable_ldst): Clean-up
+ diagnostic messages for LD/ST Exclusive instructions.
* testsuite/gas/aarch64/diagnostic.s: Add a diagnostic test for STLXP.
- * testsuite/gas/aarch64/diagnostic.l: Fix-up test after message clean-up.
+ * testsuite/gas/aarch64/diagnostic.l: Fix-up test after message
+ clean-up.
2021-04-09 Alan Modra <amodra@gmail.com>
well as Intel syntax tests.
* testsuite/gas/i386/invlpgb.d, testsuite/gas/i386/snp.d: Adjust
expectations.
- * testsuite/gas/i386/invlpgb64.d, testsuite/gas/i386/snp64.d:
+ * testsuite/gas/i386/invlpgb64.d, testsuite/gas/i386/snp64.d:
Likewise. Drop passing --def-sym to as.
2021-03-25 Jan Beulich <jbeulich@suse.com>
2021-02-12 Nick Clifton <nickc@redhat.com>
* testsuite/gas/mach-o/sections-1.d: Stop automatic debug link
- following.
+ following.
* testsuite/gas/xgate/insns-dwarf2.d: Likewise.
2021-02-12 Alan Modra <amodra@gmail.com>
if (operand->shift == (int) PPC_OPSHIFT_INV)
{
const char *errmsg;
- int64_t val;
+ uint64_t val;
errmsg = NULL;
val = -1;
{
int reloc = ptr->reloc;
- if (!ppc_obj64 && exp_p->X_add_number != 0)
+ if (!ppc_obj64 && (exp_p->X_op == O_big || exp_p->X_add_number != 0))
{
switch (reloc)
{
input_line_pointer = str;
expression (&new_exp);
- if (new_exp.X_op == O_constant)
+ if (new_exp.X_op == O_constant && exp_p->X_op != O_big)
{
exp_p->X_add_number += new_exp.X_add_number;
str = input_line_pointer;
}
-
- if (&input_line_pointer != str_p)
- input_line_pointer = orig_line;
+ input_line_pointer = orig_line;
}
*str_p = str;
}
if (--num_optional_provided < 0)
{
- int64_t val = ppc_optional_operand_value (operand, insn, ppc_cpu,
- num_optional_provided);
+ uint64_t val = ppc_optional_operand_value (operand, insn, ppc_cpu,
+ num_optional_provided);
if (operand->insert)
{
insn = (*operand->insert) (insn, val, ppc_cpu, &errmsg);
insn = ppc_insert_operand (insn, operand, ex.X_add_number,
ppc_cpu, (char *) NULL, 0);
}
- else if (ex.X_op == O_constant)
+ else if (ex.X_op == O_constant
+ || (ex.X_op == O_big && ex.X_add_number > 0))
{
+ uint64_t val;
+ if (ex.X_op == O_constant)
+ {
+ val = ex.X_add_number;
+ if (sizeof (ex.X_add_number) < sizeof (val)
+ && (ex.X_add_number < 0) != ex.X_extrabit)
+ val = val ^ ((addressT) -1 ^ (uint64_t) -1);
+ }
+ else
+ val = generic_bignum_to_int64 ();
#ifdef OBJ_ELF
/* Allow @HA, @L, @H on constants. */
- bfd_reloc_code_real_type reloc;
char *orig_str = str;
+ bfd_reloc_code_real_type reloc = ppc_elf_suffix (&str, &ex);
- if ((reloc = ppc_elf_suffix (&str, &ex)) != BFD_RELOC_NONE)
+ if (ex.X_op == O_constant)
+ {
+ val = ex.X_add_number;
+ if (sizeof (ex.X_add_number) < sizeof (val)
+ && (ex.X_add_number < 0) != ex.X_extrabit)
+ val = val ^ ((addressT) -1 ^ (uint64_t) -1);
+ }
+ if (reloc != BFD_RELOC_NONE)
switch (reloc)
{
default:
break;
case BFD_RELOC_LO16:
- ex.X_add_number &= 0xffff;
+ val &= 0xffff;
if ((operand->flags & PPC_OPERAND_SIGNED) != 0)
- ex.X_add_number = SEX16 (ex.X_add_number);
+ val = SEX16 (val);
break;
case BFD_RELOC_HI16:
if (REPORT_OVERFLOW_HI && ppc_obj64)
{
/* PowerPC64 @h is tested for overflow. */
- ex.X_add_number = (addressT) ex.X_add_number >> 16;
+ val = val >> 16;
if ((operand->flags & PPC_OPERAND_SIGNED) != 0)
{
- addressT sign = (((addressT) -1 >> 16) + 1) >> 1;
- ex.X_add_number
- = ((addressT) ex.X_add_number ^ sign) - sign;
+ uint64_t sign = (((uint64_t) -1 >> 16) + 1) >> 1;
+ val = (val ^ sign) - sign;
}
break;
}
/* Fallthru */
case BFD_RELOC_PPC64_ADDR16_HIGH:
- ex.X_add_number = PPC_HI (ex.X_add_number);
+ val = PPC_HI (val);
if ((operand->flags & PPC_OPERAND_SIGNED) != 0)
- ex.X_add_number = SEX16 (ex.X_add_number);
+ val = SEX16 (val);
break;
case BFD_RELOC_HI16_S:
if (REPORT_OVERFLOW_HI && ppc_obj64)
{
/* PowerPC64 @ha is tested for overflow. */
- ex.X_add_number
- = ((addressT) ex.X_add_number + 0x8000) >> 16;
+ val = (val + 0x8000) >> 16;
if ((operand->flags & PPC_OPERAND_SIGNED) != 0)
{
- addressT sign = (((addressT) -1 >> 16) + 1) >> 1;
- ex.X_add_number
- = ((addressT) ex.X_add_number ^ sign) - sign;
+ uint64_t sign = (((uint64_t) -1 >> 16) + 1) >> 1;
+ val = (val ^ sign) - sign;
}
break;
}
/* Fallthru */
case BFD_RELOC_PPC64_ADDR16_HIGHA:
- ex.X_add_number = PPC_HA (ex.X_add_number);
+ val = PPC_HA (val);
if ((operand->flags & PPC_OPERAND_SIGNED) != 0)
- ex.X_add_number = SEX16 (ex.X_add_number);
+ val = SEX16 (val);
break;
case BFD_RELOC_PPC64_HIGHER:
- ex.X_add_number = PPC_HIGHER (ex.X_add_number);
+ val = PPC_HIGHER (val);
if ((operand->flags & PPC_OPERAND_SIGNED) != 0)
- ex.X_add_number = SEX16 (ex.X_add_number);
+ val = SEX16 (val);
break;
case BFD_RELOC_PPC64_HIGHER_S:
- ex.X_add_number = PPC_HIGHERA (ex.X_add_number);
+ val = PPC_HIGHERA (val);
if ((operand->flags & PPC_OPERAND_SIGNED) != 0)
- ex.X_add_number = SEX16 (ex.X_add_number);
+ val = SEX16 (val);
break;
case BFD_RELOC_PPC64_HIGHEST:
- ex.X_add_number = PPC_HIGHEST (ex.X_add_number);
+ val = PPC_HIGHEST (val);
if ((operand->flags & PPC_OPERAND_SIGNED) != 0)
- ex.X_add_number = SEX16 (ex.X_add_number);
+ val = SEX16 (val);
break;
case BFD_RELOC_PPC64_HIGHEST_S:
- ex.X_add_number = PPC_HIGHESTA (ex.X_add_number);
+ val = PPC_HIGHESTA (val);
if ((operand->flags & PPC_OPERAND_SIGNED) != 0)
- ex.X_add_number = SEX16 (ex.X_add_number);
+ val = SEX16 (val);
break;
}
#endif /* OBJ_ELF */
- insn = ppc_insert_operand (insn, operand, ex.X_add_number,
- ppc_cpu, (char *) NULL, 0);
+ insn = ppc_insert_operand (insn, operand, val, ppc_cpu, NULL, 0);
}
else
{
bool literal_prefix_dollar_hex = false;
-static void floating_constant (expressionS * expressionP);
-static valueT generic_bignum_to_int32 (void);
-#ifdef BFD64
-static valueT generic_bignum_to_int64 (void);
-#endif
-static void integer_constant (int radix, expressionS * expressionP);
-static void mri_char_constant (expressionS *);
static void clean_up_expression (expressionS * expressionP);
-static segT operand (expressionS *, enum expr_mode);
-static operatorT operatorf (int *);
/* We keep a mapping of expression symbols to file positions, so that
we can provide better error messages. */
expressionP->X_add_number = -1;
}
-static valueT
+uint32_t
generic_bignum_to_int32 (void)
{
- valueT number =
- ((((valueT) generic_bignum[1] & LITTLENUM_MASK) << LITTLENUM_NUMBER_OF_BITS)
- | ((valueT) generic_bignum[0] & LITTLENUM_MASK));
- number &= 0xffffffff;
- return number;
+ return ((((uint32_t) generic_bignum[1] & LITTLENUM_MASK)
+ << LITTLENUM_NUMBER_OF_BITS)
+ | ((uint32_t) generic_bignum[0] & LITTLENUM_MASK));
}
-#ifdef BFD64
-static valueT
+uint64_t
generic_bignum_to_int64 (void)
{
- valueT number =
- ((((((((valueT) generic_bignum[3] & LITTLENUM_MASK)
- << LITTLENUM_NUMBER_OF_BITS)
- | ((valueT) generic_bignum[2] & LITTLENUM_MASK))
- << LITTLENUM_NUMBER_OF_BITS)
- | ((valueT) generic_bignum[1] & LITTLENUM_MASK))
- << LITTLENUM_NUMBER_OF_BITS)
- | ((valueT) generic_bignum[0] & LITTLENUM_MASK));
- return number;
+ return ((((((((uint64_t) generic_bignum[3] & LITTLENUM_MASK)
+ << LITTLENUM_NUMBER_OF_BITS)
+ | ((uint64_t) generic_bignum[2] & LITTLENUM_MASK))
+ << LITTLENUM_NUMBER_OF_BITS)
+ | ((uint64_t) generic_bignum[1] & LITTLENUM_MASK))
+ << LITTLENUM_NUMBER_OF_BITS)
+ | ((uint64_t) generic_bignum[0] & LITTLENUM_MASK));
}
-#endif
static void
integer_constant (int radix, expressionS *expressionP)
expressionP->X_extrabit ^= 1;
}
else if (c == '~' || c == '"')
- expressionP->X_add_number = ~ expressionP->X_add_number;
+ {
+ expressionP->X_add_number = ~ expressionP->X_add_number;
+ expressionP->X_extrabit ^= 1;
+ }
else if (c == '!')
- expressionP->X_add_number = ! expressionP->X_add_number;
+ {
+ expressionP->X_add_number = ! expressionP->X_add_number;
+ expressionP->X_unsigned = 1;
+ expressionP->X_extrabit = 0;
+ }
}
else if (expressionP->X_op == O_big
&& expressionP->X_add_number <= 0
extern symbolS *expr_build_uconstant (offsetT);
extern symbolS *expr_build_dot (void);
+extern uint32_t generic_bignum_to_int32 (void);
+extern uint64_t generic_bignum_to_int64 (void);
int resolve_expression (expressionS *);
.*: (df eb 00 60|60 00 eb df)
.*: (04 10 00 00|00 00 10 04) pstxv vs63,96 # 3d8
.*: (df e0 00 60|60 00 e0 df)
+.*: (06 00 7f ff|ff 7f 00 06) pli r1,2147483647
+.*: (38 20 ff ff|ff ff 20 38)
+.*: (06 00 80 00|00 80 00 06) pli r2,2147483648
+.*: (38 40 00 00|00 00 40 38)
+.*: (06 00 ff ff|ff ff 00 06) pli r3,4294967295
+.*: (38 60 ff ff|ff ff 60 38)
+.*: (06 00 00 00|00 00 00 06) pli r4,0
+.*: (38 80 00 00|00 00 80 38)
+.*: (06 03 ff ff|ff ff 03 06) pli r5,-1
+.*: (38 a0 ff ff|ff ff a0 38)
+.*: (06 03 80 00|00 80 03 06) pli r6,-2147483647
+.*: (38 c0 00 01|01 00 c0 38)
+.*: (06 03 80 00|00 80 03 06) pli r7,-2147483648
+.*: (38 e0 00 00|00 00 e0 38)
+.*: (06 03 80 00|00 80 03 06) pli r8,-2147483648
+.*: (39 00 00 00|00 00 00 39)
+.*: (06 03 7f ff|ff 7f 03 06) pli r9,-2147483649
+.*: (39 20 ff ff|ff ff 20 39)
#pass
pstxv 13,96(0),1
pstxv 63,96(11),0
pstxv 63,96(0),1
+
+# test d34 values of interest when bfd_vma is 32-bit
+ pli 1,0x7fffffff
+ pli 2,0x80000000
+ pli 3,0xffffffff
+ pli 4,0
+ pli 5,-1
+ pli 6,-0x7fffffff
+ pli 7,-0x80000000
+ pli 8,~0x7fffffff
+ pli 9,~0x80000000