mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-25 11:04:18 +08:00
Add support for converting VLDR <reg>,=<constant> to a VMOV instruction when appropriate.
PR gas/18500 gas * config/tc-arm.c (is_double_a_single): New function. (double_to_single): New function. (move_or_literal_pool): Add support for converting VLDR to VMOV. tests * gas/arm/vfpv2-ldr_immediate.s: New test case. * gas/arm/vfpv2-ldr_immediate.d: Expected disassembly. * gas/arm/vfpv3-ldr_immediate.s: New test case. * gas/arm/vfpv3-ldr_immediate.d: Expected disassembly. * gas/arm/vfpv3xd-ldr_immediate.s: New test case. * gas/arm/vfpv3xd-ldr_immediate.d: Expected disassembly.
This commit is contained in:
parent
fc24848555
commit
ba592044bc
@ -1,3 +1,10 @@
|
||||
2015-06-17 Alessandro Marzocchi <alessandro.marzocchi@gmail.com>
|
||||
|
||||
PR gas/18500
|
||||
* config/tc-arm.c (is_double_a_single): New function.
|
||||
(double_to_single): New function.
|
||||
(move_or_literal_pool): Add support for converting VLDR to VMOV.
|
||||
|
||||
2015-06-17 Nicolas Pitre <nico@linaro.org>
|
||||
|
||||
* as.c (show_usage): Document --sectname-subst.
|
||||
|
@ -4924,7 +4924,9 @@ parse_fpa_immediate (char ** str)
|
||||
{
|
||||
/* FIXME: 5 = X_PRECISION, should be #define'd where we can use it.
|
||||
Ditto for 15. */
|
||||
if (gen_to_words (words, 5, (long) 15) == 0)
|
||||
#define X_PRECISION 5
|
||||
#define E_PRECISION 15L
|
||||
if (gen_to_words (words, X_PRECISION, E_PRECISION) == 0)
|
||||
{
|
||||
for (i = 0; i < NUM_FLOAT_VALS; i++)
|
||||
{
|
||||
@ -7750,6 +7752,52 @@ neon_cmode_for_move_imm (unsigned immlo, unsigned immhi, int float_p,
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
/* Returns TRUE if double precision value V may be cast
|
||||
to single precision without loss of accuracy. */
|
||||
|
||||
static bfd_boolean
|
||||
is_double_a_single (long int v)
|
||||
{
|
||||
int exp = (int) (v >> 52) & 0x7FF;
|
||||
long int mantissa = (v & 0xFFFFFFFFFFFFFl);
|
||||
|
||||
return (exp == 0 || exp == 0x7FF
|
||||
|| (exp >= 1023 - 126 && exp <= 1023 + 127))
|
||||
&& (mantissa & 0x1FFFFFFFl) == 0;
|
||||
}
|
||||
|
||||
/* Returns a double precision value casted to single precision
|
||||
(ignoring the least significant bits in exponent and mantissa). */
|
||||
|
||||
static int
|
||||
double_to_single (long int v)
|
||||
{
|
||||
int sign = (int) ((v >> 63) & 1l);
|
||||
int exp = (int) (v >> 52) & 0x7FF;
|
||||
long int mantissa = (v & 0xFFFFFFFFFFFFFl);
|
||||
|
||||
if (exp == 0x7FF)
|
||||
exp = 0xFF;
|
||||
else
|
||||
{
|
||||
exp = exp - 1023 + 127;
|
||||
if (exp >= 0xFF)
|
||||
{
|
||||
/* Infinity. */
|
||||
exp = 0x7F;
|
||||
mantissa = 0;
|
||||
}
|
||||
else if (exp < 0)
|
||||
{
|
||||
/* No denormalized numbers. */
|
||||
exp = 0;
|
||||
mantissa = 0;
|
||||
}
|
||||
}
|
||||
mantissa >>= 29;
|
||||
return (sign << 31) | (exp << 23) | mantissa;
|
||||
}
|
||||
|
||||
enum lit_type
|
||||
{
|
||||
CONST_THUMB,
|
||||
@ -7757,6 +7805,8 @@ enum lit_type
|
||||
CONST_VEC
|
||||
};
|
||||
|
||||
static void do_vfp_nsyn_opcode (const char *);
|
||||
|
||||
/* inst.reloc.exp describes an "=expr" load pseudo-operation.
|
||||
Determine whether it can be performed with a move instruction; if
|
||||
it can, convert inst.instruction to that move instruction and
|
||||
@ -7772,7 +7822,6 @@ move_or_literal_pool (int i, enum lit_type t, bfd_boolean mode_3)
|
||||
unsigned long tbit;
|
||||
bfd_boolean thumb_p = (t == CONST_THUMB);
|
||||
bfd_boolean arm_p = (t == CONST_ARM);
|
||||
bfd_boolean vec64_p = (t == CONST_VEC) && !inst.operands[i].issingle;
|
||||
|
||||
if (thumb_p)
|
||||
tbit = (inst.instruction > 0xffff) ? THUMB2_LOAD_BIT : THUMB_LOAD_BIT;
|
||||
@ -7784,6 +7833,7 @@ move_or_literal_pool (int i, enum lit_type t, bfd_boolean mode_3)
|
||||
inst.error = _("invalid pseudo operation");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (inst.reloc.exp.X_op != O_constant
|
||||
&& inst.reloc.exp.X_op != O_symbol
|
||||
&& inst.reloc.exp.X_op != O_big)
|
||||
@ -7791,77 +7841,130 @@ move_or_literal_pool (int i, enum lit_type t, bfd_boolean mode_3)
|
||||
inst.error = _("constant expression expected");
|
||||
return TRUE;
|
||||
}
|
||||
if ((inst.reloc.exp.X_op == O_constant
|
||||
|| inst.reloc.exp.X_op == O_big)
|
||||
&& !inst.operands[i].issingle)
|
||||
|
||||
if (inst.reloc.exp.X_op == O_constant
|
||||
|| inst.reloc.exp.X_op == O_big)
|
||||
{
|
||||
if (thumb_p && inst.reloc.exp.X_op == O_constant)
|
||||
offsetT v;
|
||||
|
||||
if (inst.reloc.exp.X_op == O_big)
|
||||
{
|
||||
if (!unified_syntax && (inst.reloc.exp.X_add_number & ~0xFF) == 0)
|
||||
LITTLENUM_TYPE w[X_PRECISION];
|
||||
LITTLENUM_TYPE * l;
|
||||
|
||||
if (inst.reloc.exp.X_add_number == -1)
|
||||
{
|
||||
/* This can be done with a mov(1) instruction. */
|
||||
inst.instruction = T_OPCODE_MOV_I8 | (inst.operands[i].reg << 8);
|
||||
inst.instruction |= inst.reloc.exp.X_add_number;
|
||||
return TRUE;
|
||||
gen_to_words (w, X_PRECISION, E_PRECISION);
|
||||
l = w;
|
||||
/* FIXME: Should we check words w[2..5] ? */
|
||||
}
|
||||
else
|
||||
l = generic_bignum;
|
||||
|
||||
v = ((l[1] & LITTLENUM_MASK) << LITTLENUM_NUMBER_OF_BITS)
|
||||
| (l[0] & LITTLENUM_MASK);
|
||||
}
|
||||
else
|
||||
v = inst.reloc.exp.X_add_number;
|
||||
|
||||
if (!inst.operands[i].issingle)
|
||||
{
|
||||
if (thumb_p && inst.reloc.exp.X_op == O_constant)
|
||||
{
|
||||
if (!unified_syntax && (v & ~0xFF) == 0)
|
||||
{
|
||||
/* This can be done with a mov(1) instruction. */
|
||||
inst.instruction = T_OPCODE_MOV_I8 | (inst.operands[i].reg << 8);
|
||||
inst.instruction |= v;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
else if (arm_p && inst.reloc.exp.X_op == O_constant)
|
||||
{
|
||||
int value = encode_arm_immediate (v);
|
||||
if (value != FAIL)
|
||||
{
|
||||
/* This can be done with a mov instruction. */
|
||||
inst.instruction &= LITERAL_MASK;
|
||||
inst.instruction |= INST_IMMEDIATE | (OPCODE_MOV << DATA_OP_SHIFT);
|
||||
inst.instruction |= value & 0xfff;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
value = encode_arm_immediate (~ v);
|
||||
if (value != FAIL)
|
||||
{
|
||||
/* This can be done with a mvn instruction. */
|
||||
inst.instruction &= LITERAL_MASK;
|
||||
inst.instruction |= INST_IMMEDIATE | (OPCODE_MVN << DATA_OP_SHIFT);
|
||||
inst.instruction |= value & 0xfff;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
else if (t == CONST_VEC)
|
||||
{
|
||||
int op = 0;
|
||||
unsigned immbits = 0;
|
||||
unsigned immlo = inst.operands[1].imm;
|
||||
unsigned immhi = inst.operands[1].regisimm
|
||||
? inst.operands[1].reg
|
||||
: inst.reloc.exp.X_unsigned
|
||||
? 0
|
||||
: ((bfd_int64_t)((int) immlo)) >> 32;
|
||||
int cmode = neon_cmode_for_move_imm (immlo, immhi, FALSE, &immbits,
|
||||
&op, 64, NT_invtype);
|
||||
|
||||
if (cmode == FAIL)
|
||||
{
|
||||
neon_invert_size (&immlo, &immhi, 64);
|
||||
op = !op;
|
||||
cmode = neon_cmode_for_move_imm (immlo, immhi, FALSE, &immbits,
|
||||
&op, 64, NT_invtype);
|
||||
}
|
||||
|
||||
if (cmode != FAIL)
|
||||
{
|
||||
inst.instruction = (inst.instruction & VLDR_VMOV_SAME)
|
||||
| (1 << 23)
|
||||
| (cmode << 8)
|
||||
| (op << 5)
|
||||
| (1 << 4);
|
||||
|
||||
/* Fill other bits in vmov encoding for both thumb and arm. */
|
||||
if (thumb_mode)
|
||||
inst.instruction |= (0x7 << 29) | (0xF << 24);
|
||||
else
|
||||
inst.instruction |= (0xF << 28) | (0x1 << 25);
|
||||
neon_write_immbits (immbits);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (arm_p && inst.reloc.exp.X_op == O_constant)
|
||||
{
|
||||
int value = encode_arm_immediate (inst.reloc.exp.X_add_number);
|
||||
if (value != FAIL)
|
||||
{
|
||||
/* This can be done with a mov instruction. */
|
||||
inst.instruction &= LITERAL_MASK;
|
||||
inst.instruction |= INST_IMMEDIATE | (OPCODE_MOV << DATA_OP_SHIFT);
|
||||
inst.instruction |= value & 0xfff;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
value = encode_arm_immediate (~inst.reloc.exp.X_add_number);
|
||||
if (value != FAIL)
|
||||
{
|
||||
/* This can be done with a mvn instruction. */
|
||||
inst.instruction &= LITERAL_MASK;
|
||||
inst.instruction |= INST_IMMEDIATE | (OPCODE_MVN << DATA_OP_SHIFT);
|
||||
inst.instruction |= value & 0xfff;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
else if (vec64_p)
|
||||
if (t == CONST_VEC)
|
||||
{
|
||||
int op = 0;
|
||||
unsigned immbits = 0;
|
||||
unsigned immlo = inst.operands[1].imm;
|
||||
unsigned immhi = inst.operands[1].regisimm
|
||||
? inst.operands[1].reg
|
||||
: inst.reloc.exp.X_unsigned
|
||||
? 0
|
||||
: ((bfd_int64_t)((int) immlo)) >> 32;
|
||||
int cmode = neon_cmode_for_move_imm (immlo, immhi, FALSE, &immbits,
|
||||
&op, 64, NT_invtype);
|
||||
|
||||
if (cmode == FAIL)
|
||||
/* Check if vldr Rx, =constant could be optimized to vmov Rx, #constant. */
|
||||
if (inst.operands[i].issingle
|
||||
&& is_quarter_float (inst.operands[1].imm)
|
||||
&& ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v3xd))
|
||||
{
|
||||
neon_invert_size (&immlo, &immhi, 64);
|
||||
op = !op;
|
||||
cmode = neon_cmode_for_move_imm (immlo, immhi, FALSE, &immbits,
|
||||
&op, 64, NT_invtype);
|
||||
}
|
||||
if (cmode != FAIL)
|
||||
{
|
||||
inst.instruction = (inst.instruction & VLDR_VMOV_SAME)
|
||||
| (1 << 23)
|
||||
| (cmode << 8)
|
||||
| (op << 5)
|
||||
| (1 << 4);
|
||||
/* Fill other bits in vmov encoding for both thumb and arm. */
|
||||
if (thumb_mode)
|
||||
inst.instruction |= (0x7 << 29) | (0xF << 24);
|
||||
else
|
||||
inst.instruction |= (0xF << 28) | (0x1 << 25);
|
||||
neon_write_immbits (immbits);
|
||||
inst.operands[1].imm =
|
||||
neon_qfloat_bits (v);
|
||||
do_vfp_nsyn_opcode ("fconsts");
|
||||
return TRUE;
|
||||
}
|
||||
else if (!inst.operands[1].issingle
|
||||
&& ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v3))
|
||||
{
|
||||
if (is_double_a_single (v)
|
||||
&& is_quarter_float (double_to_single (v)))
|
||||
{
|
||||
inst.operands[1].imm =
|
||||
neon_qfloat_bits (double_to_single (v));
|
||||
do_vfp_nsyn_opcode ("fconstd");
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -8799,8 +8902,6 @@ do_mov16 (void)
|
||||
}
|
||||
}
|
||||
|
||||
static void do_vfp_nsyn_opcode (const char *);
|
||||
|
||||
static int
|
||||
do_vfp_nsyn_mrs (void)
|
||||
{
|
||||
|
@ -1,3 +1,13 @@
|
||||
2015-06-17 Alessandro Marzocchi <alessandro.marzocchi@gmail.com>
|
||||
|
||||
PR gas/18500
|
||||
* gas/arm/vfpv2-ldr_immediate.s: New test case.
|
||||
* gas/arm/vfpv2-ldr_immediate.d: Expected disassembly.
|
||||
* gas/arm/vfpv3-ldr_immediate.s: New test case.
|
||||
* gas/arm/vfpv3-ldr_immediate.d: Expected disassembly.
|
||||
* gas/arm/vfpv3xd-ldr_immediate.s: New test case.
|
||||
* gas/arm/vfpv3xd-ldr_immediate.d: Expected disassembly.
|
||||
|
||||
2015-06-16 Matthew Wahab <matthew.wahab@arm.com>
|
||||
|
||||
* sysreg.d: Add id_mmfr4_el1, update expected output.
|
||||
|
50
gas/testsuite/gas/arm/vfpv2-ldr_immediate.d
Normal file
50
gas/testsuite/gas/arm/vfpv2-ldr_immediate.d
Normal file
@ -0,0 +1,50 @@
|
||||
# name: VFPv2 vldr to vmov
|
||||
# as: -mfpu=vfpv2
|
||||
# objdump: -dr --prefix-addresses --show-raw-insn
|
||||
|
||||
.*: +file format .*arm.*
|
||||
|
||||
Disassembly of section \.text:
|
||||
|
||||
0[0-9a-fx]+ .*ed9f0b00 vldr d0, \[pc\].*
|
||||
0[0-9a-fx]+ .*ed9f0a01 vldr s0, \[pc, #4\].*
|
||||
0[0-9a-fx]+ .*00000000 .*
|
||||
0[0-9a-fx]+ .*3fbe0000 .*
|
||||
0[0-9a-fx]+ .*3df00000 .*
|
||||
.*
|
||||
0[0-9a-fx]+ .*ed9f0b00 vldr d0, \[pc\].*
|
||||
0[0-9a-fx]+ .*ed9f0a01 vldr s0, \[pc, #4\].*
|
||||
0[0-9a-fx]+ .*00000000 .*
|
||||
0[0-9a-fx]+ .*bfc00000 .*
|
||||
0[0-9a-fx]+ .*be000000 .*
|
||||
.*
|
||||
0[0-9a-fx]+ .*ed9f0b00 vldr d0, \[pc\].*
|
||||
0[0-9a-fx]+ .*ed9f0a01 vldr s0, \[pc, #4\].*
|
||||
0[0-9a-fx]+ .*00000000 .*
|
||||
0[0-9a-fx]+ .*3fc00000 .*
|
||||
0[0-9a-fx]+ .*3e000000 .*
|
||||
.*
|
||||
0[0-9a-fx]+ .*ed9f0b00 vldr d0, \[pc\].*
|
||||
0[0-9a-fx]+ .*ed9f0a01 vldr s0, \[pc, #4\].*
|
||||
0[0-9a-fx]+ .*00000000 .*
|
||||
0[0-9a-fx]+ .*3fe08000 .*
|
||||
0[0-9a-fx]+ .*3f040000 .*
|
||||
.*
|
||||
0[0-9a-fx]+ .*ed9f0b00 vldr d0, \[pc\].*
|
||||
0[0-9a-fx]+ .*ed9f0a01 vldr s0, \[pc, #4\].*
|
||||
0[0-9a-fx]+ .*00000000 .*
|
||||
0[0-9a-fx]+ .*3fef0000 .*
|
||||
0[0-9a-fx]+ .*3f780000 .*
|
||||
.*
|
||||
0[0-9a-fx]+ .*ed9f0b00 vldr d0, \[pc\].*
|
||||
0[0-9a-fx]+ .*ed9f0a01 vldr s0, \[pc, #4\].*
|
||||
0[0-9a-fx]+ .*00000000 .*
|
||||
0[0-9a-fx]+ .*403f0000 .*
|
||||
0[0-9a-fx]+ .*41f80000 .*
|
||||
.*
|
||||
0[0-9a-fx]+ .*ed9f0b00 vldr d0, \[pc\].*
|
||||
0[0-9a-fx]+ .*ed9f0a01 vldr s0, \[pc, #4\].*
|
||||
0[0-9a-fx]+ .*00000000 .*
|
||||
0[0-9a-fx]+ .*40400000 .*
|
||||
0[0-9a-fx]+ .*42000000 .*
|
||||
#pass
|
48
gas/testsuite/gas/arm/vfpv2-ldr_immediate.s
Normal file
48
gas/testsuite/gas/arm/vfpv2-ldr_immediate.s
Normal file
@ -0,0 +1,48 @@
|
||||
.arm
|
||||
.syntax unified
|
||||
# VFPv2 has no VMOV instruction... all vldr will be kept
|
||||
|
||||
# 15 * 2^-7 =0.1171875 VMOV does not exists
|
||||
.align 3
|
||||
vldr d0,=0x3FBE000000000000
|
||||
vldr s0,=0x3df00000
|
||||
.pool
|
||||
|
||||
# -16 * 2^-7 =0.125 VMOV does not exists
|
||||
.align 3
|
||||
vldr d0,=0xbfc0000000000000
|
||||
vldr s0,=0xbe000000
|
||||
.pool
|
||||
|
||||
# 16 * 2^-7 =0.125 VMOV does not exists
|
||||
.align 3
|
||||
vldr d0,=0x3fc0000000000000
|
||||
vldr s0,=0x3e000000
|
||||
.pool
|
||||
|
||||
# 16.5 * 2^-7 =0.125 VMOV does not exists
|
||||
.align 3
|
||||
vldr d0,=0x3fe0800000000000
|
||||
vldr s0,=0x3f040000
|
||||
.pool
|
||||
|
||||
# 31 * 2^-5 = 0.96875 VMOV does not exists
|
||||
.align 3
|
||||
vldr d0,=0x3fef000000000000
|
||||
vldr s0,=0x3f780000
|
||||
.pool
|
||||
|
||||
# 31 * 2^ 0 = 31 VMOV does not exists
|
||||
.align 3
|
||||
vldr d0,=0x403F000000000000
|
||||
vldr s0,=0x41f80000
|
||||
.pool
|
||||
|
||||
# 16 * 2^ 1 = 32 VMOV does not exists
|
||||
.align 3
|
||||
vldr d0,=0x4040000000000000
|
||||
vldr s0,=0x42000000
|
||||
.pool
|
||||
|
||||
nop
|
||||
|
35
gas/testsuite/gas/arm/vfpv3-ldr_immediate.d
Normal file
35
gas/testsuite/gas/arm/vfpv3-ldr_immediate.d
Normal file
@ -0,0 +1,35 @@
|
||||
# name: VFPv3 vldr to vmov
|
||||
# as: -mfpu=vfp3
|
||||
# objdump: -dr --prefix-addresses --show-raw-insn
|
||||
|
||||
.*: +file format .*arm.*
|
||||
|
||||
Disassembly of section \.text:
|
||||
|
||||
0[0-9a-fx]+ .*ed9f0b00 vldr d0, \[pc\].*
|
||||
0[0-9a-fx]+ .*ed9f0a01 vldr s0, \[pc, #4\].*
|
||||
0[0-9a-fx]+ .*00000000 .*
|
||||
0[0-9a-fx]+ .*3fbe0000 .*
|
||||
0[0-9a-fx]+ .*3df00000 .*
|
||||
.*
|
||||
|
||||
0[0-9a-fx]+ .*eebc0b00 (vmov\.f64|fconstd) d0, #192.*
|
||||
0[0-9a-fx]+ .*eebc0a00 (vmov\.f32|fconsts) s0, #192.*
|
||||
0[0-9a-fx]+ .*eeb40b00 (vmov\.f64|fconstd) d0, #64.*
|
||||
0[0-9a-fx]+ .*eeb40a00 (vmov\.f32|fconsts) s0, #64.*
|
||||
0[0-9a-fx]+ .*ed9f0b00 vldr d0, \[pc\].*
|
||||
0[0-9a-fx]+ .*ed9f0a01 vldr s0, \[pc, #4\].*
|
||||
0[0-9a-fx]+ .*00000000 .*
|
||||
0[0-9a-fx]+ .*3fe08000 .*
|
||||
0[0-9a-fx]+ .*3f040000 .*
|
||||
.*
|
||||
0[0-9a-fx]+ .*eeb60b0f (vmov\.f64|fconstd) d0, #111.*
|
||||
0[0-9a-fx]+ .*eeb60a0f (vmov\.f32|fconsts) s0, #111.*
|
||||
0[0-9a-fx]+ .*eeb30b0f (vmov\.f64|fconstd) d0, #63.*
|
||||
0[0-9a-fx]+ .*eeb30a0f (vmov\.f32|fconsts) s0, #63.*
|
||||
0[0-9a-fx]+ .*ed9f0b00 vldr d0, \[pc\].*
|
||||
0[0-9a-fx]+ .*ed9f0a01 vldr s0, \[pc, #4\].*
|
||||
0[0-9a-fx]+ .*00000000 .*
|
||||
0[0-9a-fx]+ .*40400000 .*
|
||||
0[0-9a-fx]+ .*42000000 .*
|
||||
#pass
|
46
gas/testsuite/gas/arm/vfpv3-ldr_immediate.s
Normal file
46
gas/testsuite/gas/arm/vfpv3-ldr_immediate.s
Normal file
@ -0,0 +1,46 @@
|
||||
.arm
|
||||
.syntax unified
|
||||
# 15 * 2^-7 =0.1171875 Not convertible to VMOV
|
||||
.align 3
|
||||
vldr d0,=0x3FBE000000000000
|
||||
vldr s0,=0x3df00000
|
||||
.pool
|
||||
|
||||
# -16 * 2^-7 =-0.125 Convertible to VMOV
|
||||
.align 3
|
||||
vldr d0,=0xbfc0000000000000
|
||||
vldr s0,=0xbe000000
|
||||
.pool
|
||||
|
||||
# 16 * 2^-7 =0.125 Convertible to VMOV
|
||||
.align 3
|
||||
vldr d0,=0x3fc0000000000000
|
||||
vldr s0,=0x3e000000
|
||||
.pool
|
||||
|
||||
# 16.5 * 2^-7 =0.125 Not convertible to VMOV
|
||||
.align 3
|
||||
vldr d0,=0x3fe0800000000000
|
||||
vldr s0,=0x3f040000
|
||||
.pool
|
||||
|
||||
# 31 * 2^-5 = 0.96875 Convertible to VMOV
|
||||
.align 3
|
||||
vldr d0,=0x3fef000000000000
|
||||
vldr s0,=0x3f780000
|
||||
.pool
|
||||
|
||||
# 31 * 2^ 0 = 31 Convertible to VMOV
|
||||
.align 3
|
||||
vldr d0,=0x403F000000000000
|
||||
vldr s0,=0x41f80000
|
||||
.pool
|
||||
|
||||
# 16 * 2^ 1 = 32 Not convertible to VMOV
|
||||
.align 3
|
||||
vldr d0,=0x4040000000000000
|
||||
vldr s0,=0x42000000
|
||||
.pool
|
||||
|
||||
nop
|
||||
|
42
gas/testsuite/gas/arm/vfpv3xd-ldr_immediate.d
Normal file
42
gas/testsuite/gas/arm/vfpv3xd-ldr_immediate.d
Normal file
@ -0,0 +1,42 @@
|
||||
# name: VFPv3xd vldr to vmov
|
||||
# as: -mfpu=vfpv3xd
|
||||
# objdump: -dr --prefix-addresses --show-raw-insn
|
||||
|
||||
.*: +file format .*arm.*
|
||||
|
||||
Disassembly of section \.text:
|
||||
|
||||
0[0-9a-fx]+ .*ed9f0b00 vldr d0, \[pc\].*
|
||||
0[0-9a-fx]+ .*ed9f0a01 vldr s0, \[pc, #4\].*
|
||||
0[0-9a-fx]+ .*00000000 .*
|
||||
0[0-9a-fx]+ .*3fbe0000 .*
|
||||
0[0-9a-fx]+ .*3df00000 .*
|
||||
.*
|
||||
0[0-9a-fx]+ .*ed9f0b00 vldr d0, \[pc\].*
|
||||
0[0-9a-fx]+ .*eebc0a00 (vmov\.f32|fconsts) s0, #192.*
|
||||
0[0-9a-fx]+ .*00000000 .*
|
||||
0[0-9a-fx]+ .*bfc00000 .*
|
||||
0[0-9a-fx]+ .*ed9f0b00 vldr d0, \[pc\].*
|
||||
0[0-9a-fx]+ .*eeb40a00 (vmov\.f32|fconsts) s0, #64.*
|
||||
0[0-9a-fx]+ .*00000000 .*
|
||||
0[0-9a-fx]+ .*3fc00000 .*
|
||||
0[0-9a-fx]+ .*ed9f0b00 vldr d0, \[pc\].*
|
||||
0[0-9a-fx]+ .*ed9f0a01 vldr s0, \[pc, #4\].*
|
||||
0[0-9a-fx]+ .*00000000 .*
|
||||
0[0-9a-fx]+ .*3fe08000 .*
|
||||
0[0-9a-fx]+ .*3f040000 .*
|
||||
.*
|
||||
0[0-9a-fx]+ .*ed9f0b00 vldr d0, \[pc\].*
|
||||
0[0-9a-fx]+ .*eeb60a0f (vmov\.f32|fconsts) s0, #111.*
|
||||
0[0-9a-fx]+ .*00000000 .*
|
||||
0[0-9a-fx]+ .*3fef0000 .*
|
||||
0[0-9a-fx]+ .*ed9f0b00 vldr d0, \[pc\].*
|
||||
0[0-9a-fx]+ .*eeb30a0f (vmov\.f32|fconsts) s0, #63.*
|
||||
0[0-9a-fx]+ .*00000000 .*
|
||||
0[0-9a-fx]+ .*403f0000 .*
|
||||
0[0-9a-fx]+ .*ed9f0b00 vldr d0, \[pc\].*
|
||||
0[0-9a-fx]+ .*ed9f0a01 vldr s0, \[pc, #4\].*
|
||||
0[0-9a-fx]+ .*00000000 .*
|
||||
0[0-9a-fx]+ .*40400000 .*
|
||||
0[0-9a-fx]+ .*42000000 .*
|
||||
#pass
|
47
gas/testsuite/gas/arm/vfpv3xd-ldr_immediate.s
Normal file
47
gas/testsuite/gas/arm/vfpv3xd-ldr_immediate.s
Normal file
@ -0,0 +1,47 @@
|
||||
.arm
|
||||
.syntax unified
|
||||
# VFPv3xD has no VMOV instruction for double precision registers...
|
||||
# 15 * 2^-7 =0.1171875 Not convertible to VMOV
|
||||
.align 3
|
||||
vldr d0,=0x3FBE000000000000
|
||||
vldr s0,=0x3df00000
|
||||
.pool
|
||||
|
||||
# -16 * 2^-7 =0.125 Convertible to VMOV
|
||||
.align 3
|
||||
vldr d0,=0xbfc0000000000000
|
||||
vldr s0,=0xbe000000
|
||||
.pool
|
||||
|
||||
# 16 * 2^-7 =0.125 Convertible to VMOV
|
||||
.align 3
|
||||
vldr d0,=0x3fc0000000000000
|
||||
vldr s0,=0x3e000000
|
||||
.pool
|
||||
|
||||
# 16.5 * 2^-7 =0.125 Not convertible to VMOV
|
||||
.align 3
|
||||
vldr d0,=0x3fe0800000000000
|
||||
vldr s0,=0x3f040000
|
||||
.pool
|
||||
|
||||
# 31 * 2^-5 = 0.96875 Convertible to VMOV
|
||||
.align 3
|
||||
vldr d0,=0x3fef000000000000
|
||||
vldr s0,=0x3f780000
|
||||
.pool
|
||||
|
||||
# 31 * 2^ 0 = 31 Convertible to VMOV
|
||||
.align 3
|
||||
vldr d0,=0x403F000000000000
|
||||
vldr s0,=0x41f80000
|
||||
.pool
|
||||
|
||||
# 16 * 2^ 1 = 32 Not convertible to VMOV
|
||||
.align 3
|
||||
vldr d0,=0x4040000000000000
|
||||
vldr s0,=0x42000000
|
||||
.pool
|
||||
|
||||
nop
|
||||
|
11
gas/write.c
11
gas/write.c
@ -1585,7 +1585,9 @@ write_contents (bfd *abfd ATTRIBUTE_UNUSED,
|
||||
f->fr_literal, (file_ptr) offset,
|
||||
(bfd_size_type) f->fr_fix);
|
||||
if (!x)
|
||||
as_fatal (_("can't write %s: %s"), stdoutput->filename,
|
||||
as_fatal (_("can't write %ld bytes to section %s of %s because: '%s'"),
|
||||
(long) f->fr_fix, sec->name,
|
||||
stdoutput->filename,
|
||||
bfd_errmsg (bfd_get_error ()));
|
||||
offset += f->fr_fix;
|
||||
}
|
||||
@ -1606,7 +1608,9 @@ write_contents (bfd *abfd ATTRIBUTE_UNUSED,
|
||||
(file_ptr) offset,
|
||||
(bfd_size_type) fill_size);
|
||||
if (!x)
|
||||
as_fatal (_("can't write %s: %s"), stdoutput->filename,
|
||||
as_fatal (_("can't fill %ld bytes in section %s of %s because '%s'"),
|
||||
(long) fill_size, sec->name,
|
||||
stdoutput->filename,
|
||||
bfd_errmsg (bfd_get_error ()));
|
||||
offset += fill_size;
|
||||
}
|
||||
@ -1636,7 +1640,8 @@ write_contents (bfd *abfd ATTRIBUTE_UNUSED,
|
||||
(stdoutput, sec, buf, (file_ptr) offset,
|
||||
(bfd_size_type) n_per_buf * fill_size);
|
||||
if (!x)
|
||||
as_fatal (_("cannot write to output file '%s': %s"),
|
||||
as_fatal (_("cannot fill %ld bytes in section %s of %s because: '%s'"),
|
||||
(long)(n_per_buf * fill_size), sec->name,
|
||||
stdoutput->filename,
|
||||
bfd_errmsg (bfd_get_error ()));
|
||||
offset += n_per_buf * fill_size;
|
||||
|
Loading…
Reference in New Issue
Block a user