mirror of
https://github.com/darlinghq/darling-gdb.git
synced 2025-02-12 04:31:28 +00:00
Fix bugs in the simulation of the AArch64's ADDP, FADDP, LD1, CCMP and CCMP instructions.
* simulator.c (set_flags_for_sub32): Correct type of signbit. (CondCompare): Swap interpretation of bit 30. (DO_ADDP): Delete macro. (do_vec_ADDP): Copy source registers before starting to update destination register. (do_vec_FADDP): Likewise. (do_vec_load_store): Fix computation of sizeof_operation. (rbit64): Fix type of constant. (aarch64_step): When displaying insn value, display all 32 bits.
This commit is contained in:
parent
c40c8d4b67
commit
57aa174243
@ -1,3 +1,15 @@
|
|||||||
|
2016-03-03 Nick Clifton <nickc@redhat.com>
|
||||||
|
|
||||||
|
* simulator.c (set_flags_for_sub32): Correct type of signbit.
|
||||||
|
(CondCompare): Swap interpretation of bit 30.
|
||||||
|
(DO_ADDP): Delete macro.
|
||||||
|
(do_vec_ADDP): Copy source registers before starting to update
|
||||||
|
destination register.
|
||||||
|
(do_vec_FADDP): Likewise.
|
||||||
|
(do_vec_load_store): Fix computation of sizeof_operation.
|
||||||
|
(rbit64): Fix type of constant.
|
||||||
|
(aarch64_step): When displaying insn value, display all 32 bits.
|
||||||
|
|
||||||
2016-01-10 Mike Frysinger <vapier@gentoo.org>
|
2016-01-10 Mike Frysinger <vapier@gentoo.org>
|
||||||
|
|
||||||
* config.in, configure: Regenerate.
|
* config.in, configure: Regenerate.
|
||||||
|
@ -1625,7 +1625,7 @@ set_flags_for_sub32 (sim_cpu *cpu, uint32_t value1, uint32_t value2)
|
|||||||
{
|
{
|
||||||
uint32_t result = value1 - value2;
|
uint32_t result = value1 - value2;
|
||||||
uint32_t flags = 0;
|
uint32_t flags = 0;
|
||||||
uint32_t signbit = 1ULL << 31;
|
uint32_t signbit = 1U << 31;
|
||||||
|
|
||||||
if (result == 0)
|
if (result == 0)
|
||||||
flags |= Z;
|
flags |= Z;
|
||||||
@ -2454,7 +2454,7 @@ static void
|
|||||||
CondCompare (sim_cpu *cpu) /* aka: ccmp and ccmn */
|
CondCompare (sim_cpu *cpu) /* aka: ccmp and ccmn */
|
||||||
{
|
{
|
||||||
/* instr[31] = size : 0 ==> 32 bit, 1 ==> 64 bit
|
/* instr[31] = size : 0 ==> 32 bit, 1 ==> 64 bit
|
||||||
instr[30] = compare with positive (0) or negative value (1)
|
instr[30] = compare with positive (1) or negative value (0)
|
||||||
instr[29,21] = 1 1101 0010
|
instr[29,21] = 1 1101 0010
|
||||||
instr[20,16] = Rm or const
|
instr[20,16] = Rm or const
|
||||||
instr[15,12] = cond
|
instr[15,12] = cond
|
||||||
@ -2477,7 +2477,7 @@ CondCompare (sim_cpu *cpu) /* aka: ccmp and ccmn */
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
negate = uimm (aarch64_get_instr (cpu), 30, 30) ? -1 : 1;
|
negate = uimm (aarch64_get_instr (cpu), 30, 30) ? 1 : -1;
|
||||||
rm = uimm (aarch64_get_instr (cpu), 20, 16);
|
rm = uimm (aarch64_get_instr (cpu), 20, 16);
|
||||||
rn = uimm (aarch64_get_instr (cpu), 9, 5);
|
rn = uimm (aarch64_get_instr (cpu), 9, 5);
|
||||||
|
|
||||||
@ -5089,21 +5089,6 @@ do_vec_sub_long (sim_cpu *cpu)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define DO_ADDP(FN) \
|
|
||||||
do \
|
|
||||||
{ \
|
|
||||||
for (i = 0; i < range; i++) \
|
|
||||||
{ \
|
|
||||||
aarch64_set_vec_##FN (cpu, vd, i, \
|
|
||||||
aarch64_get_vec_##FN (cpu, vn, i * 2) \
|
|
||||||
+ aarch64_get_vec_##FN (cpu, vn, i * 2 + 1)); \
|
|
||||||
aarch64_set_vec_##FN (cpu, vd, i + range, \
|
|
||||||
aarch64_get_vec_##FN (cpu, vm, i * 2) \
|
|
||||||
+ aarch64_get_vec_##FN (cpu, vm, i * 2 + 1)); \
|
|
||||||
} \
|
|
||||||
} \
|
|
||||||
while (0)
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
do_vec_ADDP (sim_cpu *cpu)
|
do_vec_ADDP (sim_cpu *cpu)
|
||||||
{
|
{
|
||||||
@ -5117,6 +5102,8 @@ do_vec_ADDP (sim_cpu *cpu)
|
|||||||
instr[9,5] = Vn
|
instr[9,5] = Vn
|
||||||
instr[4,0] = V dest. */
|
instr[4,0] = V dest. */
|
||||||
|
|
||||||
|
FRegister copy_vn;
|
||||||
|
FRegister copy_vm;
|
||||||
unsigned full = uimm (aarch64_get_instr (cpu), 30, 30);
|
unsigned full = uimm (aarch64_get_instr (cpu), 30, 30);
|
||||||
unsigned size = uimm (aarch64_get_instr (cpu), 23, 22);
|
unsigned size = uimm (aarch64_get_instr (cpu), 23, 22);
|
||||||
unsigned vm = uimm (aarch64_get_instr (cpu), 20, 16);
|
unsigned vm = uimm (aarch64_get_instr (cpu), 20, 16);
|
||||||
@ -5128,28 +5115,50 @@ do_vec_ADDP (sim_cpu *cpu)
|
|||||||
NYI_assert (21, 21, 1);
|
NYI_assert (21, 21, 1);
|
||||||
NYI_assert (15, 10, 0x2F);
|
NYI_assert (15, 10, 0x2F);
|
||||||
|
|
||||||
|
/* Make copies of the source registers in case vd == vn/vm. */
|
||||||
|
copy_vn = cpu->fr[vn];
|
||||||
|
copy_vm = cpu->fr[vm];
|
||||||
|
|
||||||
switch (size)
|
switch (size)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
range = full ? 8 : 4;
|
range = full ? 8 : 4;
|
||||||
DO_ADDP (u8);
|
for (i = 0; i < range; i++)
|
||||||
|
{
|
||||||
|
aarch64_set_vec_u8 (cpu, vd, i,
|
||||||
|
copy_vn.b[i * 2] + copy_vn.b[i * 2 + 1]);
|
||||||
|
aarch64_set_vec_u8 (cpu, vd, i + range,
|
||||||
|
copy_vm.b[i * 2] + copy_vm.b[i * 2 + 1]);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
range = full ? 4 : 2;
|
range = full ? 4 : 2;
|
||||||
DO_ADDP (u16);
|
for (i = 0; i < range; i++)
|
||||||
|
{
|
||||||
|
aarch64_set_vec_u16 (cpu, vd, i,
|
||||||
|
copy_vn.h[i * 2] + copy_vn.h[i * 2 + 1]);
|
||||||
|
aarch64_set_vec_u16 (cpu, vd, i + range,
|
||||||
|
copy_vm.h[i * 2] + copy_vm.h[i * 2 + 1]);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
range = full ? 2 : 1;
|
range = full ? 2 : 1;
|
||||||
DO_ADDP (u32);
|
for (i = 0; i < range; i++)
|
||||||
|
{
|
||||||
|
aarch64_set_vec_u32 (cpu, vd, i,
|
||||||
|
copy_vn.w[i * 2] + copy_vn.w[i * 2 + 1]);
|
||||||
|
aarch64_set_vec_u32 (cpu, vd, i + range,
|
||||||
|
copy_vm.w[i * 2] + copy_vm.w[i * 2 + 1]);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case 3:
|
case 3:
|
||||||
if (! full)
|
if (! full)
|
||||||
HALT_UNALLOC;
|
HALT_UNALLOC;
|
||||||
range = 1;
|
aarch64_set_vec_u64 (cpu, vd, 0, copy_vn.v[0] + copy_vn.v[1]);
|
||||||
DO_ADDP (u64);
|
aarch64_set_vec_u64 (cpu, vd, 1, copy_vm.v[0] + copy_vm.v[1]);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -6054,28 +6063,43 @@ do_vec_FADDP (sim_cpu *cpu)
|
|||||||
|
|
||||||
if (uimm (aarch64_get_instr (cpu), 22, 22))
|
if (uimm (aarch64_get_instr (cpu), 22, 22))
|
||||||
{
|
{
|
||||||
|
/* Extract values before adding them incase vd == vn/vm. */
|
||||||
|
double tmp1 = aarch64_get_vec_double (cpu, vn, 0);
|
||||||
|
double tmp2 = aarch64_get_vec_double (cpu, vn, 1);
|
||||||
|
double tmp3 = aarch64_get_vec_double (cpu, vm, 0);
|
||||||
|
double tmp4 = aarch64_get_vec_double (cpu, vm, 1);
|
||||||
|
|
||||||
if (! full)
|
if (! full)
|
||||||
HALT_UNALLOC;
|
HALT_UNALLOC;
|
||||||
|
|
||||||
aarch64_set_vec_double (cpu, vd, 0, aarch64_get_vec_double (cpu, vn, 0)
|
aarch64_set_vec_double (cpu, vd, 0, tmp1 + tmp2);
|
||||||
+ aarch64_get_vec_double (cpu, vn, 1));
|
aarch64_set_vec_double (cpu, vd, 1, tmp3 + tmp4);
|
||||||
aarch64_set_vec_double (cpu, vd, 1, aarch64_get_vec_double (cpu, vm, 0)
|
|
||||||
+ aarch64_get_vec_double (cpu, vm, 1));
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
aarch64_set_vec_float (cpu, vd, 0, aarch64_get_vec_float (cpu, vn, 0)
|
/* Extract values before adding them incase vd == vn/vm. */
|
||||||
+ aarch64_get_vec_float (cpu, vn, 1));
|
float tmp1 = aarch64_get_vec_float (cpu, vn, 0);
|
||||||
|
float tmp2 = aarch64_get_vec_float (cpu, vn, 1);
|
||||||
|
float tmp5 = aarch64_get_vec_float (cpu, vm, 0);
|
||||||
|
float tmp6 = aarch64_get_vec_float (cpu, vm, 1);
|
||||||
|
|
||||||
if (full)
|
if (full)
|
||||||
aarch64_set_vec_float (cpu, vd, 1, aarch64_get_vec_float (cpu, vn, 2)
|
{
|
||||||
+ aarch64_get_vec_float (cpu, vn, 3));
|
float tmp3 = aarch64_get_vec_float (cpu, vn, 2);
|
||||||
aarch64_set_vec_float (cpu, vd, full ? 2 : 1,
|
float tmp4 = aarch64_get_vec_float (cpu, vn, 3);
|
||||||
aarch64_get_vec_float (cpu, vm, 0)
|
float tmp7 = aarch64_get_vec_float (cpu, vm, 2);
|
||||||
+ aarch64_get_vec_float (cpu, vm, 1));
|
float tmp8 = aarch64_get_vec_float (cpu, vm, 3);
|
||||||
if (full)
|
|
||||||
aarch64_set_vec_float (cpu, vd, 3,
|
aarch64_set_vec_float (cpu, vd, 0, tmp1 + tmp2);
|
||||||
aarch64_get_vec_float (cpu, vm, 2)
|
aarch64_set_vec_float (cpu, vd, 1, tmp3 + tmp4);
|
||||||
+ aarch64_get_vec_float (cpu, vm, 3));
|
aarch64_set_vec_float (cpu, vd, 2, tmp5 + tmp6);
|
||||||
|
aarch64_set_vec_float (cpu, vd, 3, tmp7 + tmp8);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
aarch64_set_vec_float (cpu, vd, 0, tmp1 + tmp2);
|
||||||
|
aarch64_set_vec_float (cpu, vd, 1, tmp5 + tmp6);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -10937,11 +10961,24 @@ do_vec_load_store (sim_cpu *cpu)
|
|||||||
sizeof_operation <<= uimm (aarch64_get_instr (cpu), 11, 10);
|
sizeof_operation <<= uimm (aarch64_get_instr (cpu), 11, 10);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2:
|
|
||||||
case 6:
|
|
||||||
case 10:
|
|
||||||
case 7:
|
case 7:
|
||||||
sizeof_operation = 2 << uimm (aarch64_get_instr (cpu), 11, 10);
|
/* One register, immediate offset variant. */
|
||||||
|
sizeof_operation = 8;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 10:
|
||||||
|
/* Two registers, immediate offset variant. */
|
||||||
|
sizeof_operation = 16;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 6:
|
||||||
|
/* Three registers, immediate offset variant. */
|
||||||
|
sizeof_operation = 24;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
/* Four registers, immediate offset variant. */
|
||||||
|
sizeof_operation = 32;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -11421,7 +11458,7 @@ rbit64 (sim_cpu *cpu)
|
|||||||
for (i = 0; i < 64; i++)
|
for (i = 0; i < 64; i++)
|
||||||
{
|
{
|
||||||
result <<= 1;
|
result <<= 1;
|
||||||
result |= (value & 1L);
|
result |= (value & 1UL);
|
||||||
value >>= 1;
|
value >>= 1;
|
||||||
}
|
}
|
||||||
aarch64_set_reg_u64 (cpu, rd, NO_SP, result);
|
aarch64_set_reg_u64 (cpu, rd, NO_SP, result);
|
||||||
@ -13019,7 +13056,7 @@ aarch64_step (sim_cpu *cpu)
|
|||||||
aarch64_set_next_PC (cpu, pc + 4);
|
aarch64_set_next_PC (cpu, pc + 4);
|
||||||
aarch64_get_instr (cpu) = aarch64_get_mem_u32 (cpu, pc);
|
aarch64_get_instr (cpu) = aarch64_get_mem_u32 (cpu, pc);
|
||||||
|
|
||||||
TRACE_INSN (cpu, " pc = %" PRIx64 " instr = %x", pc,
|
TRACE_INSN (cpu, " pc = %" PRIx64 " instr = %08x", pc,
|
||||||
aarch64_get_instr (cpu));
|
aarch64_get_instr (cpu));
|
||||||
TRACE_DISASM (cpu, pc);
|
TRACE_DISASM (cpu, pc);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user