/* tc-aarch64.c -- Assemble for the AArch64 ISA
- Copyright (C) 2009-2015 Free Software Foundation, Inc.
+ Copyright (C) 2009-2016 Free Software Foundation, Inc.
Contributed by ARM Ltd.
This file is part of GAS.
of LITTLENUMS emitted is stored in *SIZEP. An error message is
returned, or NULL on OK. */
-char *
+const char *
md_atof (int type, char *litP, int *sizeP)
{
return ieee_md_atof (type, litP, sizeP, target_big_endian);
otherwise return FALSE.
Accept only one occurrence of:
- 8b 16b 4h 8h 2s 4s 1d 2d
+ 8b 16b 2h 4h 8h 2s 4s 1d 2d
b h s d q */
static bfd_boolean
parse_neon_type_for_operand (struct neon_type_el *parsed_type, char **str)
first_error (_("missing element size"));
return FALSE;
}
- if (width != 0 && width * element_size != 64 && width * element_size != 128)
+ if (width != 0 && width * element_size != 64 && width * element_size != 128
+ && !(width == 2 && element_size == 16))
{
first_error_fmt (_
("invalid element size %d and vector size combination %c"),
nlen = strlen (newname);
#endif
- nbuf = alloca (nlen + 1);
- memcpy (nbuf, newname, nlen);
- nbuf[nlen] = '\0';
+ nbuf = xmemdup0 (newname, nlen);
/* Create aliases under the new name as stated; an all-lowercase
version of the new name; and an all-uppercase version of the new
the artificial FOO alias because it has already been created by the
first .req. */
if (insert_reg_alias (nbuf, old->number, old->type) == NULL)
- return TRUE;
+ {
+ free (nbuf);
+ return TRUE;
+ }
}
for (p = nbuf; *p; p++)
insert_reg_alias (nbuf, old->number, old->type);
}
+ free (nbuf);
return TRUE;
}
static bfd_boolean
parse_half (char **str, int *internal_fixup_p)
{
- char *p, *saved;
- int dummy;
+ char *p = *str;
- p = *str;
skip_past_char (&p, '#');
gas_assert (internal_fixup_p);
else
*internal_fixup_p = 1;
- /* Avoid parsing a register as a general symbol. */
- saved = p;
- if (aarch64_reg_parse_32_64 (&p, 0, 0, &dummy, &dummy) != PARSE_FAIL)
- return FALSE;
- p = saved;
-
if (! my_get_expression (&inst.reloc.exp, &p, GE_NO_PREFIX, 1))
return FALSE;
/* Get one empty record. */
if (free_opnd_error_record_nodes == NULL)
{
- record = xmalloc (sizeof (operand_error_record));
- if (record == NULL)
- abort ();
+ record = XNEW (operand_error_record);
}
else
{
static void
output_info (const char *format, ...)
{
- char *file;
+ const char *file;
unsigned int line;
va_list args;
- as_where (&file, &line);
+ file = as_where (&line);
if (file)
{
if (line != 0)
/* Element size in bytes indexed by neon_el_type. */
const unsigned char ele_size[5]
= {1, 2, 4, 8, 16};
+ const unsigned int ele_base [5] =
+ {
+ AARCH64_OPND_QLF_V_8B,
+ AARCH64_OPND_QLF_V_2H,
+ AARCH64_OPND_QLF_V_2S,
+ AARCH64_OPND_QLF_V_1D,
+ AARCH64_OPND_QLF_V_1Q
+ };
if (!vectype->defined || vectype->type == NT_invtype)
goto vectype_conversion_fail;
/* Vector register. */
int reg_size = ele_size[vectype->type] * vectype->width;
unsigned offset;
- if (reg_size != 16 && reg_size != 8)
+ unsigned shift;
+ if (reg_size != 16 && reg_size != 8 && reg_size != 4)
goto vectype_conversion_fail;
- /* The conversion is calculated based on the relation of the order of
- qualifiers to the vector element size and vector register size. */
- offset = (vectype->type == NT_q)
- ? 8 : (vectype->type << 1) + (reg_size >> 4);
- gas_assert (offset <= 8);
- return AARCH64_OPND_QLF_V_8B + offset;
+
+ /* The conversion is by calculating the offset from the base operand
+ qualifier for the vector type. The operand qualifiers are regular
+ enough that the offset can established by shifting the vector width by
+ a vector-type dependent amount. */
+ shift = 0;
+ if (vectype->type == NT_b)
+ shift = 4;
+ else if (vectype->type == NT_h || vectype->type == NT_s)
+ shift = 2;
+ else if (vectype->type >= NT_d)
+ shift = 1;
+ else
+ gas_assert (0);
+
+ offset = ele_base [vectype->type] + (vectype->width >> shift);
+ gas_assert (AARCH64_OPND_QLF_V_8B <= offset
+ && offset <= AARCH64_OPND_QLF_V_1Q);
+ return offset;
}
vectype_conversion_fail:
store the instruction information for the future fix-up. */
struct aarch64_inst *copy;
gas_assert (inst.reloc.type != BFD_RELOC_UNUSED);
- if ((copy = xmalloc (sizeof (struct aarch64_inst))) == NULL)
- abort ();
+ copy = XNEW (struct aarch64_inst);
memcpy (copy, &inst.base, sizeof (struct aarch64_inst));
output_inst (copy);
}
{
/* NOP = d503201f */
/* AArch64 instructions are always little-endian. */
- static char const aarch64_noop[4] = { 0x1f, 0x20, 0x03, 0xd5 };
+ static unsigned char const aarch64_noop[4] = { 0x1f, 0x20, 0x03, 0xd5 };
int bytes, fix, noop_size;
char *p;
arelent *reloc;
bfd_reloc_code_real_type code;
- reloc = xmalloc (sizeof (arelent));
+ reloc = XNEW (arelent);
- reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
+ reloc->sym_ptr_ptr = XNEW (asymbol *);
*reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
{
char *ret;
size_t len = strlen (str);
- if ((ret = xmalloc (len + 1)) == NULL)
- abort ();
+ ret = XNEWVEC (char, len + 1);
convert_to_upper (ret, str, len);
return ret;
}
struct aarch64_option_table
{
- char *option; /* Option name to match. */
- char *help; /* Help information. */
+ const char *option; /* Option name to match. */
+ const char *help; /* Help information. */
int *var; /* Variable to change. */
int value; /* What to change it to. */
char *deprecated; /* If non-null, print this message. */
struct aarch64_cpu_option_table
{
- char *name;
+ const char *name;
const aarch64_feature_set value;
/* The canonical name of the CPU, or NULL to use NAME converted to upper
case. */
struct aarch64_arch_option_table
{
- char *name;
+ const char *name;
const aarch64_feature_set value;
};
/* ISA extensions. */
struct aarch64_option_cpu_value_table
{
- char *name;
+ const char *name;
const aarch64_feature_set value;
};
{"simd", AARCH64_FEATURE (AARCH64_FEATURE_SIMD, 0)},
{"pan", AARCH64_FEATURE (AARCH64_FEATURE_PAN, 0)},
{"lor", AARCH64_FEATURE (AARCH64_FEATURE_LOR, 0)},
+ {"ras", AARCH64_FEATURE (AARCH64_FEATURE_RAS, 0)},
{"rdma", AARCH64_FEATURE (AARCH64_FEATURE_SIMD
| AARCH64_FEATURE_RDMA, 0)},
{"fp16", AARCH64_FEATURE (AARCH64_FEATURE_F16
struct aarch64_long_option_table
{
- char *option; /* Substring to match. */
- char *help; /* Help information. */
- int (*func) (char *subopt); /* Function to decode sub-option. */
+ const char *option; /* Substring to match. */
+ const char *help; /* Help information. */
+ int (*func) (const char *subopt); /* Function to decode sub-option. */
char *deprecated; /* If non-null, print this message. */
};
static int
-aarch64_parse_features (char *str, const aarch64_feature_set **opt_p,
+aarch64_parse_features (const char *str, const aarch64_feature_set **opt_p,
bfd_boolean ext_only)
{
/* We insist on extensions being added before being removed. We achieve
adding an extension (1) or removing it (0) and only allowing it to
change in the order -1 -> 1 -> 0. */
int adding_value = -1;
- aarch64_feature_set *ext_set = xmalloc (sizeof (aarch64_feature_set));
+ aarch64_feature_set *ext_set = XNEW (aarch64_feature_set);
/* Copy the feature set, so that we can modify it. */
*ext_set = **opt_p;
while (str != NULL && *str != 0)
{
const struct aarch64_option_cpu_value_table *opt;
- char *ext = NULL;
+ const char *ext = NULL;
int optlen;
if (!ext_only)
}
static int
-aarch64_parse_cpu (char *str)
+aarch64_parse_cpu (const char *str)
{
const struct aarch64_cpu_option_table *opt;
- char *ext = strchr (str, '+');
+ const char *ext = strchr (str, '+');
size_t optlen;
if (ext != NULL)
}
static int
-aarch64_parse_arch (char *str)
+aarch64_parse_arch (const char *str)
{
const struct aarch64_arch_option_table *opt;
- char *ext = strchr (str, '+');
+ const char *ext = strchr (str, '+');
size_t optlen;
if (ext != NULL)
/* ABIs. */
struct aarch64_option_abi_value_table
{
- char *name;
+ const char *name;
enum aarch64_abi_type value;
};
};
static int
-aarch64_parse_abi (char *str)
+aarch64_parse_abi (const char *str)
{
const struct aarch64_option_abi_value_table *opt;
size_t optlen = strlen (str);
};
int
-md_parse_option (int c, char *arg)
+md_parse_option (int c, const char *arg)
{
struct aarch64_option_table *opt;
struct aarch64_long_option_table *lopt;