ChangeLog typo fix
[platform/upstream/binutils.git] / opcodes / aarch64-asm.c
index e10240a..d28d955 100644 (file)
@@ -1,5 +1,5 @@
 /* aarch64-asm.c -- AArch64 assembler support.
-   Copyright 2012  Free Software Foundation, Inc.
+   Copyright (C) 2012-2014 Free Software Foundation, Inc.
    Contributed by ARM Ltd.
 
    This file is part of the GNU opcodes library.
@@ -31,7 +31,7 @@
    N.B. the fields are required to be in such an order than the least signficant
    field for VALUE comes the first, e.g. the <index> in
     SQDMLAL <Va><d>, <Vb><n>, <Vm>.<Ts>[<index>]
-   is encoded in H:L:M in some cases, the the fields H:L:M should be passed in
+   is encoded in H:L:M in some cases, the fields H:L:M should be passed in
    the order of M, L, H.  */
 
 static inline void
@@ -146,7 +146,7 @@ aarch64_ins_ldst_reglist (const aarch64_operand *self ATTRIBUTE_UNUSED,
                          const aarch64_opnd_info *info, aarch64_insn *code,
                          const aarch64_inst *inst)
 {
-  aarch64_insn value;
+  aarch64_insn value = 0;
   /* Number of elements in each structure to be loaded/stored.  */
   unsigned num = get_opcode_dependent_value (inst->opcode);
 
@@ -215,8 +215,8 @@ aarch64_ins_ldst_elemlist (const aarch64_operand *self ATTRIBUTE_UNUSED,
                           const aarch64_inst *inst ATTRIBUTE_UNUSED)
 {
   aarch64_field field = {0, 0};
-  aarch64_insn QSsize;         /* fields Q:S:size.  */
-  aarch64_insn opcodeh2;       /* opcode<2:1> */
+  aarch64_insn QSsize = 0;     /* fields Q:S:size.  */
+  aarch64_insn opcodeh2 = 0;   /* opcode<2:1> */
 
   assert (info->reglist.has_index);
 
@@ -336,8 +336,7 @@ aarch64_ins_imm (const aarch64_operand *self, const aarch64_opnd_info *info,
      MOVZ <Wd>, #<imm16>{, LSL #<shift>}.  */
 const char *
 aarch64_ins_imm_half (const aarch64_operand *self, const aarch64_opnd_info *info,
-                     aarch64_insn *code,
-                     const aarch64_inst *inst ATTRIBUTE_UNUSED)
+                     aarch64_insn *code, const aarch64_inst *inst)
 {
   /* imm16 */
   aarch64_ins_imm (self, info, code, inst);
@@ -371,7 +370,6 @@ aarch64_ins_advsimd_imm_modified (const aarch64_operand *self ATTRIBUTE_UNUSED,
       imm = aarch64_shrink_expanded_imm8 (imm);
       assert ((int)imm >= 0);
     }
-  assert (imm <= 255);
   insert_fields (code, imm, 0, 2, FLD_defgh, FLD_abc);
 
   if (kind == AARCH64_MOD_NONE)
@@ -383,7 +381,11 @@ aarch64_ins_advsimd_imm_modified (const aarch64_operand *self ATTRIBUTE_UNUSED,
     {
       /* AARCH64_MOD_LSL: shift zeros.  */
       int esize = aarch64_get_qualifier_esize (opnd0_qualifier);
-      assert (esize == 4 || esize == 2);
+      assert (esize == 4 || esize == 2 || esize == 1);
+      /* For 8-bit move immediate, the optional LSL #0 does not require
+        encoding.  */
+      if (esize == 1)
+       return NULL;
       amount >>= 3;
       if (esize == 4)
        gen_sub_field (FLD_cmode, 1, 2, &field);        /* per word */
@@ -453,7 +455,7 @@ const char *
 aarch64_ins_ft (const aarch64_operand *self, const aarch64_opnd_info *info,
                aarch64_insn *code, const aarch64_inst *inst)
 {
-  aarch64_insn value;
+  aarch64_insn value = 0;
 
   assert (info->idx == 0);
 
@@ -532,7 +534,8 @@ aarch64_ins_addr_regoff (const aarch64_operand *self ATTRIBUTE_UNUSED,
 const char *
 aarch64_ins_addr_simm (const aarch64_operand *self,
                       const aarch64_opnd_info *info,
-                      aarch64_insn *code, const aarch64_inst *inst)
+                      aarch64_insn *code,
+                      const aarch64_inst *inst ATTRIBUTE_UNUSED)
 {
   int imm;
 
@@ -834,7 +837,7 @@ static void
 do_special_encoding (struct aarch64_inst *inst)
 {
   int idx;
-  aarch64_insn value;
+  aarch64_insn value = 0;
 
   DEBUG_TRACE ("enter with coding 0x%x", (uint32_t) inst->value);
 
@@ -853,6 +856,14 @@ do_special_encoding (struct aarch64_inst *inst)
       if (inst->opcode->flags & F_N)
        insert_field (FLD_N, &inst->value, value, inst->opcode->mask);
     }
+  if (inst->opcode->flags & F_LSE_SZ)
+    {
+      idx = select_operand_for_sf_field_coding (inst->opcode);
+      value = (inst->operands[idx].qualifier == AARCH64_OPND_QLF_X
+              || inst->operands[idx].qualifier == AARCH64_OPND_QLF_SP)
+       ? 1 : 0;
+      insert_field (FLD_lse_sz, &inst->value, value, 0);
+    }
   if (inst->opcode->flags & F_SIZEQ)
     encode_sizeq (inst);
   if (inst->opcode->flags & F_FPTYPE)
@@ -954,6 +965,16 @@ convert_ror_to_extr (aarch64_inst *inst)
   copy_operand_info (inst, 2, 1);
 }
 
+/* UXTL<Q> <Vd>.<Ta>, <Vn>.<Tb>
+     is equivalent to:
+   USHLL<Q> <Vd>.<Ta>, <Vn>.<Tb>, #0.  */
+static void
+convert_xtl_to_shll (aarch64_inst *inst)
+{
+  inst->operands[2].qualifier = inst->operands[1].qualifier;
+  inst->operands[2].imm.value = 0;
+}
+
 /* Convert
      LSR <Xd>, <Xn>, #<shift>
    to
@@ -1090,8 +1111,9 @@ convert_mov_to_movewide (aarch64_inst *inst)
     }
   inst->operands[1].type = AARCH64_OPND_HALF;
   is32 = inst->operands[0].qualifier == AARCH64_OPND_QLF_W;
-  /* This should have been guaranteed by the constraint check.  */
-  assert (aarch64_wide_constant_p (value, is32, &shift_amount) == TRUE);
+  if (! aarch64_wide_constant_p (value, is32, &shift_amount))
+    /* The constraint check should have guaranteed this wouldn't happen.  */
+    assert (0);
   value >>= shift_amount;
   value &= 0xffff;
   inst->operands[1].imm.value = value;
@@ -1162,6 +1184,12 @@ convert_to_real (aarch64_inst *inst, const aarch64_opcode *real)
     case OP_ROR_IMM:
       convert_ror_to_extr (inst);
       break;
+    case OP_SXTL:
+    case OP_SXTL2:
+    case OP_UXTL:
+    case OP_UXTL2:
+      convert_xtl_to_shll (inst);
+      break;
     default:
       break;
     }