-/* True if IMM has form 0bAAAAAAAABBBBBBBBCCCCCCCCDDDDDDDD for bits
- A, B, C, D. */
-
-static int
-neon_bits_same_in_bytes (unsigned imm)
-{
- return ((imm & 0x000000ff) == 0 || (imm & 0x000000ff) == 0x000000ff)
- && ((imm & 0x0000ff00) == 0 || (imm & 0x0000ff00) == 0x0000ff00)
- && ((imm & 0x00ff0000) == 0 || (imm & 0x00ff0000) == 0x00ff0000)
- && ((imm & 0xff000000) == 0 || (imm & 0xff000000) == 0xff000000);
-}
-
-/* For immediate of above form, return 0bABCD. */
-
-static unsigned
-neon_squash_bits (unsigned imm)
-{
- return (imm & 0x01) | ((imm & 0x0100) >> 7) | ((imm & 0x010000) >> 14)
- | ((imm & 0x01000000) >> 21);
-}
-
-/* Compress quarter-float representation to 0b...000 abcdefgh. */
-
-static unsigned
-neon_qfloat_bits (unsigned imm)
-{
- return ((imm >> 19) & 0x7f) | ((imm >> 24) & 0x80);
-}
-
-/* Returns CMODE. IMMBITS [7:0] is set to bits suitable for inserting into
- the instruction. *OP is passed as the initial value of the op field, and
- may be set to a different value depending on the constant (i.e.
- "MOV I64, 0bAAAAAAAABBBB..." which uses OP = 1 despite being MOV not
- MVN). If the immediate looks like a repeated pattern then also
- try smaller element sizes. */
-
-static int
-neon_cmode_for_move_imm (unsigned immlo, unsigned immhi, int float_p,
- unsigned *immbits, int *op, int size,
- enum neon_el_type type)
-{
- /* Only permit float immediates (including 0.0/-0.0) if the operand type is
- float. */
- if (type == NT_float && !float_p)
- return FAIL;
-
- if (type == NT_float && is_quarter_float (immlo) && immhi == 0)
- {
- if (size != 32 || *op == 1)
- return FAIL;
- *immbits = neon_qfloat_bits (immlo);
- return 0xf;
- }
-
- if (size == 64)
- {
- if (neon_bits_same_in_bytes (immhi)
- && neon_bits_same_in_bytes (immlo))
- {
- if (*op == 1)
- return FAIL;
- *immbits = (neon_squash_bits (immhi) << 4)
- | neon_squash_bits (immlo);
- *op = 1;
- return 0xe;
- }
-
- if (immhi != immlo)
- return FAIL;
- }
-
- if (size >= 32)
- {
- if (immlo == (immlo & 0x000000ff))
- {
- *immbits = immlo;
- return 0x0;
- }
- else if (immlo == (immlo & 0x0000ff00))
- {
- *immbits = immlo >> 8;
- return 0x2;
- }
- else if (immlo == (immlo & 0x00ff0000))
- {
- *immbits = immlo >> 16;
- return 0x4;
- }
- else if (immlo == (immlo & 0xff000000))
- {
- *immbits = immlo >> 24;
- return 0x6;
- }
- else if (immlo == ((immlo & 0x0000ff00) | 0x000000ff))
- {
- *immbits = (immlo >> 8) & 0xff;
- return 0xc;
- }
- else if (immlo == ((immlo & 0x00ff0000) | 0x0000ffff))
- {
- *immbits = (immlo >> 16) & 0xff;
- return 0xd;
- }
-
- if ((immlo & 0xffff) != (immlo >> 16))
- return FAIL;
- immlo &= 0xffff;
- }
-
- if (size >= 16)
- {
- if (immlo == (immlo & 0x000000ff))
- {
- *immbits = immlo;
- return 0x8;
- }
- else if (immlo == (immlo & 0x0000ff00))
- {
- *immbits = immlo >> 8;
- return 0xa;
- }
-
- if ((immlo & 0xff) != (immlo >> 8))
- return FAIL;
- immlo &= 0xff;
- }
-
- if (immlo == (immlo & 0x000000ff))
- {
- /* Don't allow MVN with 8-bit immediate. */
- if (*op == 1)
- return FAIL;
- *immbits = immlo;
- return 0xe;
- }
-
- return FAIL;
-}
-
-/* Write immediate bits [7:0] to the following locations:
-
- |28/24|23 19|18 16|15 4|3 0|
- | a |x x x x x|b c d|x x x x x x x x x x x x|e f g h|
-
- This function is used by VMOV/VMVN/VORR/VBIC. */
-
-static void
-neon_write_immbits (unsigned immbits)
-{
- inst.instruction |= immbits & 0xf;
- inst.instruction |= ((immbits >> 4) & 0x7) << 16;
- inst.instruction |= ((immbits >> 7) & 0x1) << 24;
-}
-
-/* Invert low-order SIZE bits of XHI:XLO. */
-
-static void
-neon_invert_size (unsigned *xlo, unsigned *xhi, int size)
-{
- unsigned immlo = xlo ? *xlo : 0;
- unsigned immhi = xhi ? *xhi : 0;
-
- switch (size)
- {
- case 8:
- immlo = (~immlo) & 0xff;
- break;
-
- case 16:
- immlo = (~immlo) & 0xffff;
- break;
-
- case 64:
- immhi = (~immhi) & 0xffffffff;
- /* fall through. */
-
- case 32:
- immlo = (~immlo) & 0xffffffff;
- break;
-
- default:
- abort ();
- }
-
- if (xlo)
- *xlo = immlo;
-
- if (xhi)
- *xhi = immhi;
-}
-