* Re: [PATCH 6/7] Support for recording aarch64 advanced SIMD instructions
@ 2014-09-18 23:01 Omair Javaid
2014-10-14 12:48 ` Omair Javaid
0 siblings, 1 reply; 5+ messages in thread
From: Omair Javaid @ 2014-09-18 23:01 UTC (permalink / raw)
To: Will Newton; +Cc: gdb-patches
On 2 September 2014 20:01, Will Newton <will.newton@linaro.org> wrote:
> On 29 August 2014 14:41, Omair Javaid <omair.javaid@linaro.org> wrote:
>> Updated patch after incorporating suggestions.
>>
>> gdb:
>>
>> 2014-08-28 Omair Javaid <omair.javaid@linaro.org>
>>
>> * aarch64-tdep.c (aarch64_record_data_proc_simd_fp): Add handler
>> for data processing SIMD and floating point insns.
>> (aarch64_record_asimd_load_store): Add handler to record ASIMD load
>> store insns.
>> (aarch64_record_load_store): Install record handler
>> aarch64_record_asimd_load_store.
>> (aarch64_record_decode_insn_handler): Install record handler
>> aarch64_record_data_proc_simd_fp.
>>
>> ---
>> gdb/aarch64-tdep.c | 228 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
>> 1 file changed, 226 insertions(+), 2 deletions(-)
>
> This looks OK to me.
>
>> diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c
>> index c6da25a..9437280 100644
>> --- a/gdb/aarch64-tdep.c
>> +++ b/gdb/aarch64-tdep.c
>> @@ -2986,6 +2986,144 @@ aarch64_record_branch_except_sys (insn_decode_record *aarch64_insn_r)
>> return AARCH64_RECORD_SUCCESS;
>> }
>>
>> +/* Record handler for advanced SIMD load and store instructions. */
>> +static unsigned int
>> +aarch64_record_asimd_load_store (insn_decode_record *aarch64_insn_r)
>> +{
>> + CORE_ADDR address;
>> + uint64_t addr_offset = 0;
>> + uint32_t record_buf[24];
>> + uint64_t record_buf_mem[24];
>> + uint32_t reg_rn, reg_rt, reg_rm;
>> + uint32_t reg_index = 0, mem_index = 0;
>> + uint8_t eindex, rindex, sindex, reg_tt, replicate;
>> + uint8_t elements, esize, rpt, selem, single, scale;
>> + uint8_t opcode_bits, size_bits, ld_flag, data_size, wback;
>> +
>> + reg_rt = bits (aarch64_insn_r->aarch64_insn, 0, 4);
>> + reg_rn = bits (aarch64_insn_r->aarch64_insn, 5, 9);
>> + reg_rm = bits (aarch64_insn_r->aarch64_insn, 16, 20);
>> +
>> + wback = bit (aarch64_insn_r->aarch64_insn, 23);
>> + single = bit (aarch64_insn_r->aarch64_insn, 24);
>> + ld_flag = bit (aarch64_insn_r->aarch64_insn, 22);
>> + size_bits = bits (aarch64_insn_r->aarch64_insn, 10, 11);
>> + opcode_bits = bits (aarch64_insn_r->aarch64_insn, 12, 15);
>> + regcache_raw_read_unsigned (aarch64_insn_r->regcache, reg_rn, &address);
>> +
>> + if (single)
>> + {
>> + scale = opcode_bits >> 2;
>> + selem = ((opcode_bits & 0x02) |
>> + bit (aarch64_insn_r->aarch64_insn, 21)) + 1;
>> + replicate = 0;
>> + switch (scale)
>> + {
>> + case 2:
>> + if (!(size_bits & 0x01) && ((size_bits >> 1) & 0x01))
>> + scale = 3;
>> + break;
>> + case 3:
>> + scale = size_bits;
>> + replicate = 1;
>> + break;
>> + default:
>> + break;
>> + }
>> + esize = 8 << scale;
>> + if (replicate)
>> + for (sindex = 0; sindex < selem; sindex++)
>> + {
>> + record_buf[reg_index++] = reg_rt + AARCH64_V0_REGNUM;
>> + reg_rt = (reg_rt + 1) % 32;
>> + }
>> + else
>> + {
>> + for (sindex = 0; sindex < selem; sindex++)
>> + if (ld_flag)
>> + record_buf[reg_index++] = reg_rt + AARCH64_V0_REGNUM;
>> + else
>> + {
>> + record_buf_mem[mem_index++] = esize / 8;
>> + record_buf_mem[mem_index++] = address + addr_offset;
>> + }
>> + addr_offset = addr_offset + (esize / 8);
>> + reg_rt = (reg_rt + 1) % 32;
>> + }
>> + }
>> + else
>> + {
>> + esize = 8 << size_bits;
>> + if (bit (aarch64_insn_r->aarch64_insn, 30))
>> + elements = 128 / esize;
>> + else
>> + elements = 64 / esize;
>> +
>> + switch (opcode_bits)
>> + {
>> + case 0:
>> + rpt = 1;
>> + selem = 4;
>> + break;
>> + case 2:
>> + rpt = 4;
>> + selem = 1;
>> + break;
>> + case 4:
>> + rpt = 1;
>> + selem = 3;
>> + break;
>> + case 6:
>> + rpt = 3;
>> + selem = 1;
>> + break;
>> + case 7:
>> + rpt = 1;
>> + selem = 1;
>> + break;
>> + case 8:
>> + rpt = 1;
>> + selem = 2;
>> + break;
>> + case 10:
>> + rpt = 2;
>> + selem = 1;
>> + break;
>> + default:
>> + return AARCH64_RECORD_UNSUPPORTED;
>> + break;
>> + }
>> + for (rindex = 0; rindex < rpt; rindex++)
>> + for (eindex = 0; eindex < elements; eindex++)
>> + {
>> + reg_tt = (reg_rt + rindex) % 32;
>> + for (sindex = 0; sindex < selem; sindex++)
>> + {
>> + if (ld_flag)
>> + record_buf[reg_index++] = reg_tt + AARCH64_V0_REGNUM;
>> + else
>> + {
>> + record_buf_mem[mem_index++] = esize / 8;
>> + record_buf_mem[mem_index++] = address + addr_offset;
>> + }
>> + addr_offset = addr_offset + (esize / 8);
>> + reg_tt = (reg_tt + 1) % 32;
>> + }
>> + }
>> + }
>> +
>> + if (wback)
>> + record_buf[reg_index++] = reg_rn;
>> +
>> + aarch64_insn_r->reg_rec_count = reg_index;
>> + aarch64_insn_r->mem_rec_count = mem_index / 2;
>> + MEM_ALLOC (aarch64_insn_r->aarch64_mems, aarch64_insn_r->mem_rec_count,
>> + record_buf_mem);
>> + REG_ALLOC (aarch64_insn_r->aarch64_regs, aarch64_insn_r->reg_rec_count,
>> + record_buf);
>> + return AARCH64_RECORD_SUCCESS;
>> +}
>> +
>> /* Record handler for load and store instructions. */
>> static unsigned int
>> aarch64_record_load_store (insn_decode_record *aarch64_insn_r)
>> @@ -3224,7 +3362,7 @@ aarch64_record_load_store (insn_decode_record *aarch64_insn_r)
>> }
>> /* Advanced SIMD load/store instructions. */
>> else
>> - return AARCH64_RECORD_UNSUPPORTED;
>> + return aarch64_record_asimd_load_store (aarch64_insn_r);
>>
>> MEM_ALLOC (aarch64_insn_r->aarch64_mems, aarch64_insn_r->mem_rec_count,
>> record_buf_mem);
>> @@ -3232,6 +3370,92 @@ aarch64_record_load_store (insn_decode_record *aarch64_insn_r)
>> record_buf);
>> return AARCH64_RECORD_SUCCESS;
>> }
>> +
>> +/* Record handler for data processing SIMD and floating point instructions. */
>> +
>> +static unsigned int
>> +aarch64_record_data_proc_simd_fp (insn_decode_record *aarch64_insn_r)
>> +{
>> + uint8_t insn_bit21, opcode, rmode, reg_rd;
>> + uint8_t insn_bits24_27, insn_bits28_31, insn_bits10_11, insn_bits12_15;
>> + uint8_t insn_bits11_14;
>> + uint32_t record_buf[2];
>> +
>> + insn_bits24_27 = bits (aarch64_insn_r->aarch64_insn, 24, 27);
>> + insn_bits28_31 = bits (aarch64_insn_r->aarch64_insn, 28, 31);
>> + insn_bits10_11 = bits (aarch64_insn_r->aarch64_insn, 10, 11);
>> + insn_bits12_15 = bits (aarch64_insn_r->aarch64_insn, 12, 15);
>> + insn_bits11_14 = bits (aarch64_insn_r->aarch64_insn, 11, 14);
>> + opcode = bits (aarch64_insn_r->aarch64_insn, 16, 18);
>> + rmode = bits (aarch64_insn_r->aarch64_insn, 19, 20);
>> + reg_rd = bits (aarch64_insn_r->aarch64_insn, 0, 4);
>> + insn_bit21 = bit (aarch64_insn_r->aarch64_insn, 21);
>> +
>> + if ((insn_bits28_31 & 0x05) == 0x01 && insn_bits24_27 == 0x0e)
>> + {
>> + /* Floating point - fixed point conversion instructions. */
>> + if (!insn_bit21)
>> + if ((opcode >> 1) == 0x0 && rmode == 0x03)
>> + record_buf[0] = reg_rd;
>> + else
>> + record_buf[0] = reg_rd + AARCH64_V0_REGNUM;
>> + /* Floating point - conditional compare instructions. */
>> + else if (insn_bits10_11 == 0x01)
>> + record_buf[0] = AARCH64_CPSR_REGNUM;
>> + /* Floating point - data processing (2-source) and
>> + conditional select instructions. */
>> + else if (insn_bits10_11 == 0x02 || insn_bits10_11 == 0x03)
>> + record_buf[0] = reg_rd + AARCH64_V0_REGNUM;
>> + else if (insn_bits10_11 == 0x00)
>> + {
>> + /* Floating point - immediate instructions. */
>> + if ((insn_bits12_15 & 0x01) == 0x01 || (insn_bits12_15 & 0x07) == 0x04)
>> + record_buf[0] = reg_rd + AARCH64_V0_REGNUM;
>> + /* Floating point - compare instructions. */
>> + else if ((insn_bits12_15 & 0x03) == 0x02)
>> + record_buf[0] = AARCH64_CPSR_REGNUM;
>> + /* Floating point - integer conversions instructions. */
>> + if (insn_bits12_15 == 0x00)
>> + {
>> + /* Convert float to integer instruction. */
>> + if (!(opcode >> 1) || ((opcode >> 1) == 0x02 && !rmode))
>> + record_buf[0] = reg_rd + AARCH64_X0_REGNUM;
>> + /* Convert integer to float instruction. */
>> + else if ((opcode >> 1) == 0x01 && !rmode)
>> + record_buf[0] = reg_rd + AARCH64_V0_REGNUM;
>> + /* Move float to integer instruction. */
>> + else if ((opcode >> 1) == 0x03)
>> + {
>> + if (!(opcode & 0x01))
>> + record_buf[0] = reg_rd + AARCH64_X0_REGNUM;
>> + else
>> + record_buf[0] = reg_rd + AARCH64_V0_REGNUM;
>> + }
>> + }
>> + }
>> + }
>> + else if ((insn_bits28_31 & 0x09) == 0x00 && insn_bits24_27 == 0x0E)
>> + {
>> + /* Advanced SIMD copy instructions. */
>> + if (!bits (aarch64_insn_r->aarch64_insn, 21, 23) &&
>> + !bit (aarch64_insn_r->aarch64_insn, 15) &&
>> + bit (aarch64_insn_r->aarch64_insn, 10))
>> + if (insn_bits11_14 == 0x05 || insn_bits11_14 == 0x07)
>> + record_buf[0] = reg_rd + AARCH64_X0_REGNUM;
>> + else
>> + record_buf[0] = reg_rd + AARCH64_V0_REGNUM;
>> + else
>> + record_buf[0] = reg_rd + AARCH64_V0_REGNUM;
>> + }
>> + /* All remaining floating point or advanced SIMD instructions. */
>> + else
>> + record_buf[0] = reg_rd + AARCH64_V0_REGNUM;
>> +
>> + REG_ALLOC (aarch64_insn_r->aarch64_regs, aarch64_insn_r->reg_rec_count,
>> + record_buf);
>> + return AARCH64_RECORD_SUCCESS;
>> +}
>> +
>> /* Decodes insns type and invokes its record handler. */
>>
>> static unsigned int
>> @@ -3262,7 +3486,7 @@ aarch64_record_decode_insn_handler (insn_decode_record *aarch64_insn_r)
>>
>> /* Data processing - SIMD and floating point instructions. */
>> if (ins_bit25 && ins_bit26 && ins_bit27)
>> - return AARCH64_RECORD_UNSUPPORTED;
>> + return aarch64_record_data_proc_simd_fp (aarch64_insn_r);
>>
>> return AARCH64_RECORD_UNSUPPORTED;
>> }
>> --
>> 1.9.1
>>
>
>
>
> --
> Will Newton
> Toolchain Working Group, Linaro
Ping! Are there any further comments for this patch? Kindly help me
approve this patch series.
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: [PATCH 6/7] Support for recording aarch64 advanced SIMD instructions
2014-09-18 23:01 [PATCH 6/7] Support for recording aarch64 advanced SIMD instructions Omair Javaid
@ 2014-10-14 12:48 ` Omair Javaid
2014-10-21 9:05 ` Omair Javaid
0 siblings, 1 reply; 5+ messages in thread
From: Omair Javaid @ 2014-10-14 12:48 UTC (permalink / raw)
To: Will Newton; +Cc: gdb-patches
On 19 September 2014 04:01, Omair Javaid <omair.javaid@linaro.org> wrote:
> On 2 September 2014 20:01, Will Newton <will.newton@linaro.org> wrote:
>> On 29 August 2014 14:41, Omair Javaid <omair.javaid@linaro.org> wrote:
>>> Updated patch after incorporating suggestions.
>>>
>>> gdb:
>>>
>>> 2014-08-28 Omair Javaid <omair.javaid@linaro.org>
>>>
>>> * aarch64-tdep.c (aarch64_record_data_proc_simd_fp): Add handler
>>> for data processing SIMD and floating point insns.
>>> (aarch64_record_asimd_load_store): Add handler to record ASIMD load
>>> store insns.
>>> (aarch64_record_load_store): Install record handler
>>> aarch64_record_asimd_load_store.
>>> (aarch64_record_decode_insn_handler): Install record handler
>>> aarch64_record_data_proc_simd_fp.
>>>
>>> ---
>>> gdb/aarch64-tdep.c | 228 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
>>> 1 file changed, 226 insertions(+), 2 deletions(-)
>>
>> This looks OK to me.
>>
>>> diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c
>>> index c6da25a..9437280 100644
>>> --- a/gdb/aarch64-tdep.c
>>> +++ b/gdb/aarch64-tdep.c
>>> @@ -2986,6 +2986,144 @@ aarch64_record_branch_except_sys (insn_decode_record *aarch64_insn_r)
>>> return AARCH64_RECORD_SUCCESS;
>>> }
>>>
>>> +/* Record handler for advanced SIMD load and store instructions. */
>>> +static unsigned int
>>> +aarch64_record_asimd_load_store (insn_decode_record *aarch64_insn_r)
>>> +{
>>> + CORE_ADDR address;
>>> + uint64_t addr_offset = 0;
>>> + uint32_t record_buf[24];
>>> + uint64_t record_buf_mem[24];
>>> + uint32_t reg_rn, reg_rt, reg_rm;
>>> + uint32_t reg_index = 0, mem_index = 0;
>>> + uint8_t eindex, rindex, sindex, reg_tt, replicate;
>>> + uint8_t elements, esize, rpt, selem, single, scale;
>>> + uint8_t opcode_bits, size_bits, ld_flag, data_size, wback;
>>> +
>>> + reg_rt = bits (aarch64_insn_r->aarch64_insn, 0, 4);
>>> + reg_rn = bits (aarch64_insn_r->aarch64_insn, 5, 9);
>>> + reg_rm = bits (aarch64_insn_r->aarch64_insn, 16, 20);
>>> +
>>> + wback = bit (aarch64_insn_r->aarch64_insn, 23);
>>> + single = bit (aarch64_insn_r->aarch64_insn, 24);
>>> + ld_flag = bit (aarch64_insn_r->aarch64_insn, 22);
>>> + size_bits = bits (aarch64_insn_r->aarch64_insn, 10, 11);
>>> + opcode_bits = bits (aarch64_insn_r->aarch64_insn, 12, 15);
>>> + regcache_raw_read_unsigned (aarch64_insn_r->regcache, reg_rn, &address);
>>> +
>>> + if (single)
>>> + {
>>> + scale = opcode_bits >> 2;
>>> + selem = ((opcode_bits & 0x02) |
>>> + bit (aarch64_insn_r->aarch64_insn, 21)) + 1;
>>> + replicate = 0;
>>> + switch (scale)
>>> + {
>>> + case 2:
>>> + if (!(size_bits & 0x01) && ((size_bits >> 1) & 0x01))
>>> + scale = 3;
>>> + break;
>>> + case 3:
>>> + scale = size_bits;
>>> + replicate = 1;
>>> + break;
>>> + default:
>>> + break;
>>> + }
>>> + esize = 8 << scale;
>>> + if (replicate)
>>> + for (sindex = 0; sindex < selem; sindex++)
>>> + {
>>> + record_buf[reg_index++] = reg_rt + AARCH64_V0_REGNUM;
>>> + reg_rt = (reg_rt + 1) % 32;
>>> + }
>>> + else
>>> + {
>>> + for (sindex = 0; sindex < selem; sindex++)
>>> + if (ld_flag)
>>> + record_buf[reg_index++] = reg_rt + AARCH64_V0_REGNUM;
>>> + else
>>> + {
>>> + record_buf_mem[mem_index++] = esize / 8;
>>> + record_buf_mem[mem_index++] = address + addr_offset;
>>> + }
>>> + addr_offset = addr_offset + (esize / 8);
>>> + reg_rt = (reg_rt + 1) % 32;
>>> + }
>>> + }
>>> + else
>>> + {
>>> + esize = 8 << size_bits;
>>> + if (bit (aarch64_insn_r->aarch64_insn, 30))
>>> + elements = 128 / esize;
>>> + else
>>> + elements = 64 / esize;
>>> +
>>> + switch (opcode_bits)
>>> + {
>>> + case 0:
>>> + rpt = 1;
>>> + selem = 4;
>>> + break;
>>> + case 2:
>>> + rpt = 4;
>>> + selem = 1;
>>> + break;
>>> + case 4:
>>> + rpt = 1;
>>> + selem = 3;
>>> + break;
>>> + case 6:
>>> + rpt = 3;
>>> + selem = 1;
>>> + break;
>>> + case 7:
>>> + rpt = 1;
>>> + selem = 1;
>>> + break;
>>> + case 8:
>>> + rpt = 1;
>>> + selem = 2;
>>> + break;
>>> + case 10:
>>> + rpt = 2;
>>> + selem = 1;
>>> + break;
>>> + default:
>>> + return AARCH64_RECORD_UNSUPPORTED;
>>> + break;
>>> + }
>>> + for (rindex = 0; rindex < rpt; rindex++)
>>> + for (eindex = 0; eindex < elements; eindex++)
>>> + {
>>> + reg_tt = (reg_rt + rindex) % 32;
>>> + for (sindex = 0; sindex < selem; sindex++)
>>> + {
>>> + if (ld_flag)
>>> + record_buf[reg_index++] = reg_tt + AARCH64_V0_REGNUM;
>>> + else
>>> + {
>>> + record_buf_mem[mem_index++] = esize / 8;
>>> + record_buf_mem[mem_index++] = address + addr_offset;
>>> + }
>>> + addr_offset = addr_offset + (esize / 8);
>>> + reg_tt = (reg_tt + 1) % 32;
>>> + }
>>> + }
>>> + }
>>> +
>>> + if (wback)
>>> + record_buf[reg_index++] = reg_rn;
>>> +
>>> + aarch64_insn_r->reg_rec_count = reg_index;
>>> + aarch64_insn_r->mem_rec_count = mem_index / 2;
>>> + MEM_ALLOC (aarch64_insn_r->aarch64_mems, aarch64_insn_r->mem_rec_count,
>>> + record_buf_mem);
>>> + REG_ALLOC (aarch64_insn_r->aarch64_regs, aarch64_insn_r->reg_rec_count,
>>> + record_buf);
>>> + return AARCH64_RECORD_SUCCESS;
>>> +}
>>> +
>>> /* Record handler for load and store instructions. */
>>> static unsigned int
>>> aarch64_record_load_store (insn_decode_record *aarch64_insn_r)
>>> @@ -3224,7 +3362,7 @@ aarch64_record_load_store (insn_decode_record *aarch64_insn_r)
>>> }
>>> /* Advanced SIMD load/store instructions. */
>>> else
>>> - return AARCH64_RECORD_UNSUPPORTED;
>>> + return aarch64_record_asimd_load_store (aarch64_insn_r);
>>>
>>> MEM_ALLOC (aarch64_insn_r->aarch64_mems, aarch64_insn_r->mem_rec_count,
>>> record_buf_mem);
>>> @@ -3232,6 +3370,92 @@ aarch64_record_load_store (insn_decode_record *aarch64_insn_r)
>>> record_buf);
>>> return AARCH64_RECORD_SUCCESS;
>>> }
>>> +
>>> +/* Record handler for data processing SIMD and floating point instructions. */
>>> +
>>> +static unsigned int
>>> +aarch64_record_data_proc_simd_fp (insn_decode_record *aarch64_insn_r)
>>> +{
>>> + uint8_t insn_bit21, opcode, rmode, reg_rd;
>>> + uint8_t insn_bits24_27, insn_bits28_31, insn_bits10_11, insn_bits12_15;
>>> + uint8_t insn_bits11_14;
>>> + uint32_t record_buf[2];
>>> +
>>> + insn_bits24_27 = bits (aarch64_insn_r->aarch64_insn, 24, 27);
>>> + insn_bits28_31 = bits (aarch64_insn_r->aarch64_insn, 28, 31);
>>> + insn_bits10_11 = bits (aarch64_insn_r->aarch64_insn, 10, 11);
>>> + insn_bits12_15 = bits (aarch64_insn_r->aarch64_insn, 12, 15);
>>> + insn_bits11_14 = bits (aarch64_insn_r->aarch64_insn, 11, 14);
>>> + opcode = bits (aarch64_insn_r->aarch64_insn, 16, 18);
>>> + rmode = bits (aarch64_insn_r->aarch64_insn, 19, 20);
>>> + reg_rd = bits (aarch64_insn_r->aarch64_insn, 0, 4);
>>> + insn_bit21 = bit (aarch64_insn_r->aarch64_insn, 21);
>>> +
>>> + if ((insn_bits28_31 & 0x05) == 0x01 && insn_bits24_27 == 0x0e)
>>> + {
>>> + /* Floating point - fixed point conversion instructions. */
>>> + if (!insn_bit21)
>>> + if ((opcode >> 1) == 0x0 && rmode == 0x03)
>>> + record_buf[0] = reg_rd;
>>> + else
>>> + record_buf[0] = reg_rd + AARCH64_V0_REGNUM;
>>> + /* Floating point - conditional compare instructions. */
>>> + else if (insn_bits10_11 == 0x01)
>>> + record_buf[0] = AARCH64_CPSR_REGNUM;
>>> + /* Floating point - data processing (2-source) and
>>> + conditional select instructions. */
>>> + else if (insn_bits10_11 == 0x02 || insn_bits10_11 == 0x03)
>>> + record_buf[0] = reg_rd + AARCH64_V0_REGNUM;
>>> + else if (insn_bits10_11 == 0x00)
>>> + {
>>> + /* Floating point - immediate instructions. */
>>> + if ((insn_bits12_15 & 0x01) == 0x01 || (insn_bits12_15 & 0x07) == 0x04)
>>> + record_buf[0] = reg_rd + AARCH64_V0_REGNUM;
>>> + /* Floating point - compare instructions. */
>>> + else if ((insn_bits12_15 & 0x03) == 0x02)
>>> + record_buf[0] = AARCH64_CPSR_REGNUM;
>>> + /* Floating point - integer conversions instructions. */
>>> + if (insn_bits12_15 == 0x00)
>>> + {
>>> + /* Convert float to integer instruction. */
>>> + if (!(opcode >> 1) || ((opcode >> 1) == 0x02 && !rmode))
>>> + record_buf[0] = reg_rd + AARCH64_X0_REGNUM;
>>> + /* Convert integer to float instruction. */
>>> + else if ((opcode >> 1) == 0x01 && !rmode)
>>> + record_buf[0] = reg_rd + AARCH64_V0_REGNUM;
>>> + /* Move float to integer instruction. */
>>> + else if ((opcode >> 1) == 0x03)
>>> + {
>>> + if (!(opcode & 0x01))
>>> + record_buf[0] = reg_rd + AARCH64_X0_REGNUM;
>>> + else
>>> + record_buf[0] = reg_rd + AARCH64_V0_REGNUM;
>>> + }
>>> + }
>>> + }
>>> + }
>>> + else if ((insn_bits28_31 & 0x09) == 0x00 && insn_bits24_27 == 0x0E)
>>> + {
>>> + /* Advanced SIMD copy instructions. */
>>> + if (!bits (aarch64_insn_r->aarch64_insn, 21, 23) &&
>>> + !bit (aarch64_insn_r->aarch64_insn, 15) &&
>>> + bit (aarch64_insn_r->aarch64_insn, 10))
>>> + if (insn_bits11_14 == 0x05 || insn_bits11_14 == 0x07)
>>> + record_buf[0] = reg_rd + AARCH64_X0_REGNUM;
>>> + else
>>> + record_buf[0] = reg_rd + AARCH64_V0_REGNUM;
>>> + else
>>> + record_buf[0] = reg_rd + AARCH64_V0_REGNUM;
>>> + }
>>> + /* All remaining floating point or advanced SIMD instructions. */
>>> + else
>>> + record_buf[0] = reg_rd + AARCH64_V0_REGNUM;
>>> +
>>> + REG_ALLOC (aarch64_insn_r->aarch64_regs, aarch64_insn_r->reg_rec_count,
>>> + record_buf);
>>> + return AARCH64_RECORD_SUCCESS;
>>> +}
>>> +
>>> /* Decodes insns type and invokes its record handler. */
>>>
>>> static unsigned int
>>> @@ -3262,7 +3486,7 @@ aarch64_record_decode_insn_handler (insn_decode_record *aarch64_insn_r)
>>>
>>> /* Data processing - SIMD and floating point instructions. */
>>> if (ins_bit25 && ins_bit26 && ins_bit27)
>>> - return AARCH64_RECORD_UNSUPPORTED;
>>> + return aarch64_record_data_proc_simd_fp (aarch64_insn_r);
>>>
>>> return AARCH64_RECORD_UNSUPPORTED;
>>> }
>>> --
>>> 1.9.1
>>>
>>
>>
>>
>> --
>> Will Newton
>> Toolchain Working Group, Linaro
>
> Ping! Are there any further comments for this patch? Kindly help me
> approve this patch series.
ping!
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: [PATCH 6/7] Support for recording aarch64 advanced SIMD instructions
2014-10-14 12:48 ` Omair Javaid
@ 2014-10-21 9:05 ` Omair Javaid
0 siblings, 0 replies; 5+ messages in thread
From: Omair Javaid @ 2014-10-21 9:05 UTC (permalink / raw)
To: Will Newton; +Cc: gdb-patches
On 14/10/2014 17:48, Omair Javaid wrote:
> On 19 September 2014 04:01, Omair Javaid <omair.javaid@linaro.org> wrote:
>> On 2 September 2014 20:01, Will Newton <will.newton@linaro.org> wrote:
>>> On 29 August 2014 14:41, Omair Javaid <omair.javaid@linaro.org> wrote:
>>>> Updated patch after incorporating suggestions.
>>>>
>>>> gdb:
>>>>
>>>> 2014-08-28 Omair Javaid <omair.javaid@linaro.org>
>>>>
>>>> * aarch64-tdep.c (aarch64_record_data_proc_simd_fp): Add handler
>>>> for data processing SIMD and floating point insns.
>>>> (aarch64_record_asimd_load_store): Add handler to record ASIMD load
>>>> store insns.
>>>> (aarch64_record_load_store): Install record handler
>>>> aarch64_record_asimd_load_store.
>>>> (aarch64_record_decode_insn_handler): Install record handler
>>>> aarch64_record_data_proc_simd_fp.
>>>>
>>>> ---
>>>> gdb/aarch64-tdep.c | 228 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
>>>> 1 file changed, 226 insertions(+), 2 deletions(-)
>>>
>>> This looks OK to me.
>>>
>>>> diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c
>>>> index c6da25a..9437280 100644
>>>> --- a/gdb/aarch64-tdep.c
>>>> +++ b/gdb/aarch64-tdep.c
>>>> @@ -2986,6 +2986,144 @@ aarch64_record_branch_except_sys (insn_decode_record *aarch64_insn_r)
>>>> return AARCH64_RECORD_SUCCESS;
>>>> }
>>>>
>>>> +/* Record handler for advanced SIMD load and store instructions. */
>>>> +static unsigned int
>>>> +aarch64_record_asimd_load_store (insn_decode_record *aarch64_insn_r)
>>>> +{
>>>> + CORE_ADDR address;
>>>> + uint64_t addr_offset = 0;
>>>> + uint32_t record_buf[24];
>>>> + uint64_t record_buf_mem[24];
>>>> + uint32_t reg_rn, reg_rt, reg_rm;
>>>> + uint32_t reg_index = 0, mem_index = 0;
>>>> + uint8_t eindex, rindex, sindex, reg_tt, replicate;
>>>> + uint8_t elements, esize, rpt, selem, single, scale;
>>>> + uint8_t opcode_bits, size_bits, ld_flag, data_size, wback;
>>>> +
>>>> + reg_rt = bits (aarch64_insn_r->aarch64_insn, 0, 4);
>>>> + reg_rn = bits (aarch64_insn_r->aarch64_insn, 5, 9);
>>>> + reg_rm = bits (aarch64_insn_r->aarch64_insn, 16, 20);
>>>> +
>>>> + wback = bit (aarch64_insn_r->aarch64_insn, 23);
>>>> + single = bit (aarch64_insn_r->aarch64_insn, 24);
>>>> + ld_flag = bit (aarch64_insn_r->aarch64_insn, 22);
>>>> + size_bits = bits (aarch64_insn_r->aarch64_insn, 10, 11);
>>>> + opcode_bits = bits (aarch64_insn_r->aarch64_insn, 12, 15);
>>>> + regcache_raw_read_unsigned (aarch64_insn_r->regcache, reg_rn, &address);
>>>> +
>>>> + if (single)
>>>> + {
>>>> + scale = opcode_bits >> 2;
>>>> + selem = ((opcode_bits & 0x02) |
>>>> + bit (aarch64_insn_r->aarch64_insn, 21)) + 1;
>>>> + replicate = 0;
>>>> + switch (scale)
>>>> + {
>>>> + case 2:
>>>> + if (!(size_bits & 0x01) && ((size_bits >> 1) & 0x01))
>>>> + scale = 3;
>>>> + break;
>>>> + case 3:
>>>> + scale = size_bits;
>>>> + replicate = 1;
>>>> + break;
>>>> + default:
>>>> + break;
>>>> + }
>>>> + esize = 8 << scale;
>>>> + if (replicate)
>>>> + for (sindex = 0; sindex < selem; sindex++)
>>>> + {
>>>> + record_buf[reg_index++] = reg_rt + AARCH64_V0_REGNUM;
>>>> + reg_rt = (reg_rt + 1) % 32;
>>>> + }
>>>> + else
>>>> + {
>>>> + for (sindex = 0; sindex < selem; sindex++)
>>>> + if (ld_flag)
>>>> + record_buf[reg_index++] = reg_rt + AARCH64_V0_REGNUM;
>>>> + else
>>>> + {
>>>> + record_buf_mem[mem_index++] = esize / 8;
>>>> + record_buf_mem[mem_index++] = address + addr_offset;
>>>> + }
>>>> + addr_offset = addr_offset + (esize / 8);
>>>> + reg_rt = (reg_rt + 1) % 32;
>>>> + }
>>>> + }
>>>> + else
>>>> + {
>>>> + esize = 8 << size_bits;
>>>> + if (bit (aarch64_insn_r->aarch64_insn, 30))
>>>> + elements = 128 / esize;
>>>> + else
>>>> + elements = 64 / esize;
>>>> +
>>>> + switch (opcode_bits)
>>>> + {
>>>> + case 0:
>>>> + rpt = 1;
>>>> + selem = 4;
>>>> + break;
>>>> + case 2:
>>>> + rpt = 4;
>>>> + selem = 1;
>>>> + break;
>>>> + case 4:
>>>> + rpt = 1;
>>>> + selem = 3;
>>>> + break;
>>>> + case 6:
>>>> + rpt = 3;
>>>> + selem = 1;
>>>> + break;
>>>> + case 7:
>>>> + rpt = 1;
>>>> + selem = 1;
>>>> + break;
>>>> + case 8:
>>>> + rpt = 1;
>>>> + selem = 2;
>>>> + break;
>>>> + case 10:
>>>> + rpt = 2;
>>>> + selem = 1;
>>>> + break;
>>>> + default:
>>>> + return AARCH64_RECORD_UNSUPPORTED;
>>>> + break;
>>>> + }
>>>> + for (rindex = 0; rindex < rpt; rindex++)
>>>> + for (eindex = 0; eindex < elements; eindex++)
>>>> + {
>>>> + reg_tt = (reg_rt + rindex) % 32;
>>>> + for (sindex = 0; sindex < selem; sindex++)
>>>> + {
>>>> + if (ld_flag)
>>>> + record_buf[reg_index++] = reg_tt + AARCH64_V0_REGNUM;
>>>> + else
>>>> + {
>>>> + record_buf_mem[mem_index++] = esize / 8;
>>>> + record_buf_mem[mem_index++] = address + addr_offset;
>>>> + }
>>>> + addr_offset = addr_offset + (esize / 8);
>>>> + reg_tt = (reg_tt + 1) % 32;
>>>> + }
>>>> + }
>>>> + }
>>>> +
>>>> + if (wback)
>>>> + record_buf[reg_index++] = reg_rn;
>>>> +
>>>> + aarch64_insn_r->reg_rec_count = reg_index;
>>>> + aarch64_insn_r->mem_rec_count = mem_index / 2;
>>>> + MEM_ALLOC (aarch64_insn_r->aarch64_mems, aarch64_insn_r->mem_rec_count,
>>>> + record_buf_mem);
>>>> + REG_ALLOC (aarch64_insn_r->aarch64_regs, aarch64_insn_r->reg_rec_count,
>>>> + record_buf);
>>>> + return AARCH64_RECORD_SUCCESS;
>>>> +}
>>>> +
>>>> /* Record handler for load and store instructions. */
>>>> static unsigned int
>>>> aarch64_record_load_store (insn_decode_record *aarch64_insn_r)
>>>> @@ -3224,7 +3362,7 @@ aarch64_record_load_store (insn_decode_record *aarch64_insn_r)
>>>> }
>>>> /* Advanced SIMD load/store instructions. */
>>>> else
>>>> - return AARCH64_RECORD_UNSUPPORTED;
>>>> + return aarch64_record_asimd_load_store (aarch64_insn_r);
>>>>
>>>> MEM_ALLOC (aarch64_insn_r->aarch64_mems, aarch64_insn_r->mem_rec_count,
>>>> record_buf_mem);
>>>> @@ -3232,6 +3370,92 @@ aarch64_record_load_store (insn_decode_record *aarch64_insn_r)
>>>> record_buf);
>>>> return AARCH64_RECORD_SUCCESS;
>>>> }
>>>> +
>>>> +/* Record handler for data processing SIMD and floating point instructions. */
>>>> +
>>>> +static unsigned int
>>>> +aarch64_record_data_proc_simd_fp (insn_decode_record *aarch64_insn_r)
>>>> +{
>>>> + uint8_t insn_bit21, opcode, rmode, reg_rd;
>>>> + uint8_t insn_bits24_27, insn_bits28_31, insn_bits10_11, insn_bits12_15;
>>>> + uint8_t insn_bits11_14;
>>>> + uint32_t record_buf[2];
>>>> +
>>>> + insn_bits24_27 = bits (aarch64_insn_r->aarch64_insn, 24, 27);
>>>> + insn_bits28_31 = bits (aarch64_insn_r->aarch64_insn, 28, 31);
>>>> + insn_bits10_11 = bits (aarch64_insn_r->aarch64_insn, 10, 11);
>>>> + insn_bits12_15 = bits (aarch64_insn_r->aarch64_insn, 12, 15);
>>>> + insn_bits11_14 = bits (aarch64_insn_r->aarch64_insn, 11, 14);
>>>> + opcode = bits (aarch64_insn_r->aarch64_insn, 16, 18);
>>>> + rmode = bits (aarch64_insn_r->aarch64_insn, 19, 20);
>>>> + reg_rd = bits (aarch64_insn_r->aarch64_insn, 0, 4);
>>>> + insn_bit21 = bit (aarch64_insn_r->aarch64_insn, 21);
>>>> +
>>>> + if ((insn_bits28_31 & 0x05) == 0x01 && insn_bits24_27 == 0x0e)
>>>> + {
>>>> + /* Floating point - fixed point conversion instructions. */
>>>> + if (!insn_bit21)
>>>> + if ((opcode >> 1) == 0x0 && rmode == 0x03)
>>>> + record_buf[0] = reg_rd;
>>>> + else
>>>> + record_buf[0] = reg_rd + AARCH64_V0_REGNUM;
>>>> + /* Floating point - conditional compare instructions. */
>>>> + else if (insn_bits10_11 == 0x01)
>>>> + record_buf[0] = AARCH64_CPSR_REGNUM;
>>>> + /* Floating point - data processing (2-source) and
>>>> + conditional select instructions. */
>>>> + else if (insn_bits10_11 == 0x02 || insn_bits10_11 == 0x03)
>>>> + record_buf[0] = reg_rd + AARCH64_V0_REGNUM;
>>>> + else if (insn_bits10_11 == 0x00)
>>>> + {
>>>> + /* Floating point - immediate instructions. */
>>>> + if ((insn_bits12_15 & 0x01) == 0x01 || (insn_bits12_15 & 0x07) == 0x04)
>>>> + record_buf[0] = reg_rd + AARCH64_V0_REGNUM;
>>>> + /* Floating point - compare instructions. */
>>>> + else if ((insn_bits12_15 & 0x03) == 0x02)
>>>> + record_buf[0] = AARCH64_CPSR_REGNUM;
>>>> + /* Floating point - integer conversions instructions. */
>>>> + if (insn_bits12_15 == 0x00)
>>>> + {
>>>> + /* Convert float to integer instruction. */
>>>> + if (!(opcode >> 1) || ((opcode >> 1) == 0x02 && !rmode))
>>>> + record_buf[0] = reg_rd + AARCH64_X0_REGNUM;
>>>> + /* Convert integer to float instruction. */
>>>> + else if ((opcode >> 1) == 0x01 && !rmode)
>>>> + record_buf[0] = reg_rd + AARCH64_V0_REGNUM;
>>>> + /* Move float to integer instruction. */
>>>> + else if ((opcode >> 1) == 0x03)
>>>> + {
>>>> + if (!(opcode & 0x01))
>>>> + record_buf[0] = reg_rd + AARCH64_X0_REGNUM;
>>>> + else
>>>> + record_buf[0] = reg_rd + AARCH64_V0_REGNUM;
>>>> + }
>>>> + }
>>>> + }
>>>> + }
>>>> + else if ((insn_bits28_31 & 0x09) == 0x00 && insn_bits24_27 == 0x0E)
>>>> + {
>>>> + /* Advanced SIMD copy instructions. */
>>>> + if (!bits (aarch64_insn_r->aarch64_insn, 21, 23) &&
>>>> + !bit (aarch64_insn_r->aarch64_insn, 15) &&
>>>> + bit (aarch64_insn_r->aarch64_insn, 10))
>>>> + if (insn_bits11_14 == 0x05 || insn_bits11_14 == 0x07)
>>>> + record_buf[0] = reg_rd + AARCH64_X0_REGNUM;
>>>> + else
>>>> + record_buf[0] = reg_rd + AARCH64_V0_REGNUM;
>>>> + else
>>>> + record_buf[0] = reg_rd + AARCH64_V0_REGNUM;
>>>> + }
>>>> + /* All remaining floating point or advanced SIMD instructions. */
>>>> + else
>>>> + record_buf[0] = reg_rd + AARCH64_V0_REGNUM;
>>>> +
>>>> + REG_ALLOC (aarch64_insn_r->aarch64_regs, aarch64_insn_r->reg_rec_count,
>>>> + record_buf);
>>>> + return AARCH64_RECORD_SUCCESS;
>>>> +}
>>>> +
>>>> /* Decodes insns type and invokes its record handler. */
>>>>
>>>> static unsigned int
>>>> @@ -3262,7 +3486,7 @@ aarch64_record_decode_insn_handler (insn_decode_record *aarch64_insn_r)
>>>>
>>>> /* Data processing - SIMD and floating point instructions. */
>>>> if (ins_bit25 && ins_bit26 && ins_bit27)
>>>> - return AARCH64_RECORD_UNSUPPORTED;
>>>> + return aarch64_record_data_proc_simd_fp (aarch64_insn_r);
>>>>
>>>> return AARCH64_RECORD_UNSUPPORTED;
>>>> }
>>>> --
>>>> 1.9.1
>>>>
>>>
>>>
>>>
>>> --
>>> Will Newton
>>> Toolchain Working Group, Linaro
>>
>> Ping! Are there any further comments for this patch? Kindly help me
>> approve this patch series.
>
> ping!
>
Ping!
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH 6/7] Support for recording aarch64 advance simd instructions
@ 2014-06-05 8:58 Will Newton
2014-08-29 13:41 ` [PATCH 6/7] Support for recording aarch64 advanced SIMD instructions Omair Javaid
0 siblings, 1 reply; 5+ messages in thread
From: Will Newton @ 2014-06-05 8:58 UTC (permalink / raw)
To: Omair Javaid; +Cc: gdb-patches
On 4 June 2014 17:21, Omair Javaid <omair.javaid@linaro.org> wrote:
> This patch adds support for recording A64 advance simd load/store and
> data processing instructions on aarch64-linux targets.
>
> gdb:
>
> 2014-06-04 Omair Javaid <omair.javaid@linaro.org>
>
> * aarch64-tdep.c (aarch64_record_load_store): Updated.
> (aarch64_record_data_proc_simd_fp): New function.
> (aarch64_record_decode_insn_handler): Updated.
> (aarch64_record_asimd_load_store): New function.
>
> ---
> gdb/aarch64-tdep.c | 227 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 225 insertions(+), 2 deletions(-)
>
> diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c
> index 2e2dc15..221006a 100644
> --- a/gdb/aarch64-tdep.c
> +++ b/gdb/aarch64-tdep.c
> @@ -2988,6 +2988,144 @@ aarch64_record_branch_except_sys (insn_decode_record *aarch64_insn_r)
> return AARCH64_RECORD_SUCCESS;
> }
>
> +/* Record handler for advance simd load and store instructions. */
I guess we should be consistent and call it "Advanced SIMD".
> +static unsigned int
> +aarch64_record_asimd_load_store (insn_decode_record *aarch64_insn_r)
> +{
> + CORE_ADDR address;
> + uint64_t addr_offset = 0;
> + uint32_t record_buf[24];
> + uint64_t record_buf_mem[24];
> + uint32_t reg_rn, reg_rt, reg_rm;
> + uint32_t reg_index = 0, mem_index = 0;
> + uint8_t eindex, rindex, sindex, reg_tt, replicate;
> + uint8_t elements, esize, rpt, selem, ebytes, single, scale;
I don't think ebytes is used.
> + uint8_t opcode_bits, qbit, size_bits, ld_flag, data_size, wback;
And qbit seems not to be used either.
> +
> + reg_rt = bits (aarch64_insn_r->aarch64_insn, 0, 4);
> + reg_rn = bits (aarch64_insn_r->aarch64_insn, 5, 9);
> + reg_rm = bits (aarch64_insn_r->aarch64_insn, 16, 20);
> +
> + wback = bit (aarch64_insn_r->aarch64_insn, 23);
> + single = bit (aarch64_insn_r->aarch64_insn, 24);
> + ld_flag = bit (aarch64_insn_r->aarch64_insn, 22);
> + size_bits = bits (aarch64_insn_r->aarch64_insn, 10, 11);
> + opcode_bits = bits (aarch64_insn_r->aarch64_insn, 12, 15);
> + regcache_raw_read_unsigned (aarch64_insn_r->regcache, reg_rn, &address);
> +
> + if (single)
> + {
> + scale = opcode_bits >> 2;
> + selem = ((opcode_bits & 0x02) |
> + bit (aarch64_insn_r->aarch64_insn, 21)) + 1;
> + replicate = 0;
> + switch (scale)
> + {
> + case 2:
> + if (!(size_bits & 0x01) && ((size_bits >> 1) & 0x01))
> + scale = 3;
> + break;
> + case 3:
> + scale = size_bits;
> + replicate = 1;
> + break;
> + default:
> + break;
> + }
> + esize = 8 << scale;
> + if (replicate)
> + for (sindex = 0; sindex < selem; sindex++)
> + {
> + record_buf[reg_index++] = reg_rt + AARCH64_V0_REGNUM;
> + reg_rt = (reg_rt + 1) % 32;
> + }
> + else
> + {
> + for (sindex = 0; sindex < selem; sindex++)
> + if (ld_flag)
> + record_buf[reg_index++] = reg_rt + AARCH64_V0_REGNUM;
> + else
> + {
> + record_buf_mem[mem_index++] = esize / 8;
> + record_buf_mem[mem_index++] = address + addr_offset;
> + }
> + addr_offset = addr_offset + (esize / 8);
> + reg_rt = (reg_rt + 1) % 32;
> + }
> + }
> + else
> + {
> + esize = 8 << size_bits;
> + if (bit (aarch64_insn_r->aarch64_insn, 30))
> + elements = 128 / esize;
> + else
> + elements = 64 / esize;
> +
> + switch (opcode_bits)
> + {
> + case 0:
> + rpt = 1;
> + selem = 4;
> + break;
> + case 2:
> + rpt = 4;
> + selem = 1;
> + break;
> + case 4:
> + rpt = 1;
> + selem = 3;
> + break;
> + case 6:
> + rpt = 3;
> + selem = 1;
> + break;
> + case 7:
> + rpt = 1;
> + selem = 1;
> + break;
> + case 8:
> + rpt = 1;
> + selem = 2;
> + break;
> + case 10:
> + rpt = 2;
> + selem = 1;
> + break;
> + default:
> + return AARCH64_RECORD_USUPPORTED;
> + break;
> + }
> + for (rindex = 0; rindex < rpt; rindex++)
> + for (eindex = 0; eindex < elements; eindex++)
> + {
> + reg_tt = (reg_rt + rindex) % 32;
> + for (sindex = 0; sindex < selem; sindex++)
> + {
> + if (ld_flag)
> + record_buf[reg_index++] = reg_tt + AARCH64_V0_REGNUM;
> + else
> + {
> + record_buf_mem[mem_index++] = esize / 8;
> + record_buf_mem[mem_index++] = address + addr_offset;
> + }
> + addr_offset = addr_offset + (esize / 8);
> + reg_tt = (reg_tt + 1) % 32;
> + }
> + }
> + }
> +
> + if (wback)
> + record_buf[reg_index++] = reg_rn;
> +
> + aarch64_insn_r->reg_rec_count = reg_index;
> + aarch64_insn_r->mem_rec_count = mem_index / 2;
> + MEM_ALLOC (aarch64_insn_r->aarch64_mems, aarch64_insn_r->mem_rec_count,
> + record_buf_mem);
> + REG_ALLOC (aarch64_insn_r->aarch64_regs, aarch64_insn_r->reg_rec_count,
> + record_buf);
> + return AARCH64_RECORD_SUCCESS;
> +}
> +
> /* Record handler for load and store instructions. */
> static unsigned int
> aarch64_record_load_store (insn_decode_record *aarch64_insn_r)
> @@ -3226,7 +3364,7 @@ aarch64_record_load_store (insn_decode_record *aarch64_insn_r)
> }
> /* Advanced SIMD load/store instructions. */
> else
> - return AARCH64_RECORD_USUPPORTED;
> + return aarch64_record_asimd_load_store (aarch64_insn_r);
>
> MEM_ALLOC (aarch64_insn_r->aarch64_mems, aarch64_insn_r->mem_rec_count,
> record_buf_mem);
> @@ -3234,6 +3372,91 @@ aarch64_record_load_store (insn_decode_record *aarch64_insn_r)
> record_buf);
> return AARCH64_RECORD_SUCCESS;
> }
> +
> +/* Record handler for data processing SIMD and floating point instructions. */
> +
> +static unsigned int
> +aarch64_record_data_proc_simd_fp (insn_decode_record *aarch64_insn_r)
> +{
> + uint8_t insn_bit21, opcode, rmode, reg_rd;
> + uint8_t insn_bits24_27, insn_bits28_31, insn_bits10_11, insn_bits12_15;
> + uint8_t insn_bits11_14;
> + uint32_t record_buf[2];
> +
> + insn_bits24_27 = bits (aarch64_insn_r->aarch64_insn, 24, 27);
> + insn_bits28_31 = bits (aarch64_insn_r->aarch64_insn, 28, 31);
> + insn_bits10_11 = bits (aarch64_insn_r->aarch64_insn, 10, 11);
> + insn_bits12_15 = bits (aarch64_insn_r->aarch64_insn, 12, 15);
> + insn_bits11_14 = bits (aarch64_insn_r->aarch64_insn, 11, 14);
> + opcode = bits (aarch64_insn_r->aarch64_insn, 16, 18);
> + rmode = bits (aarch64_insn_r->aarch64_insn, 19, 20);
> + reg_rd = bits (aarch64_insn_r->aarch64_insn, 0, 4);
> + insn_bit21 = bit (aarch64_insn_r->aarch64_insn, 21);
> +
> + if ((insn_bits28_31 & 0x05) == 0x01 && insn_bits24_27 == 0x0e)
> + {
> + /* Floating point - fixed-point conversion instructions. */
> + if (!insn_bit21)
> + if ((opcode >> 1) == 0x0 && rmode == 0x03)
> + record_buf[0] = reg_rd;
> + else
> + record_buf[0] = reg_rd + AARCH64_V0_REGNUM;
> + /* Floating point conditional compare instructions. */
> + else if (insn_bits10_11 == 0x01) //
> + record_buf[0] = AARCH64_CPSR_REGNUM;
> + /* Floating-point data-processing (2-source) and conditional select. */
> + else if (insn_bits10_11 == 0x02 || insn_bits10_11 == 0x03)
> + record_buf[0] = reg_rd + AARCH64_V0_REGNUM;
> + else if (insn_bits10_11 == 0x00)
> + {
> + /* Floating point immediate instructions. */
> + if ((insn_bits12_15 & 0x01) == 0x01 || (insn_bits12_15 & 0x07) == 0x04)
> + record_buf[0] = reg_rd + AARCH64_V0_REGNUM;
> + /* Floating point compare instructions. */
> + else if ((insn_bits12_15 & 0x03) == 0x02)
> + record_buf[0] = AARCH64_CPSR_REGNUM;
> + /* Floating-point - integer conversions instructions. */
> + if (insn_bits12_15 == 0x00)
> + {
> + /* Type - convert float to integer. */
> + if (!(opcode >> 1) || ((opcode >> 1) == 0x02 && !rmode))
> + record_buf[0] = reg_rd + AARCH64_X0_REGNUM;
> + /* Type - convert integer to float. */
> + else if ((opcode >> 1) == 0x01 && !rmode)
> + record_buf[0] = reg_rd + AARCH64_V0_REGNUM;
> + /* Type - move float to integer. */
> + else if ((opcode >> 1) == 0x03)
> + {
> + if (!(opcode & 0x01))
> + record_buf[0] = reg_rd + AARCH64_X0_REGNUM;
> + else
> + record_buf[0] = reg_rd + AARCH64_V0_REGNUM;
> + }
> + }
> + }
> + }
> + else if ((insn_bits28_31 & 0x09) == 0x00 && insn_bits24_27 == 0x0E)
> + {
> + /* Advanced SIMD copy instructions. */
> + if (!bits (aarch64_insn_r->aarch64_insn, 21, 23) &&
> + !bit (aarch64_insn_r->aarch64_insn, 15) &&
> + bit (aarch64_insn_r->aarch64_insn, 10))
> + if (insn_bits11_14 == 0x05 || insn_bits11_14 == 0x07)
> + record_buf[0] = reg_rd + AARCH64_X0_REGNUM;
> + else
> + record_buf[0] = reg_rd + AARCH64_V0_REGNUM;
> + else
> + record_buf[0] = reg_rd + AARCH64_V0_REGNUM;
> + }
> + /* All remaining floating point or advanced SIMD instructions. */
> + else
> + record_buf[0] = reg_rd + AARCH64_V0_REGNUM;
> +
> + REG_ALLOC (aarch64_insn_r->aarch64_regs, aarch64_insn_r->reg_rec_count,
> + record_buf);
> + return AARCH64_RECORD_SUCCESS;
> +}
> +
> /* Decodes thumb2 instruction type and invokes its record handler. */
>
> static unsigned int
> @@ -3264,7 +3487,7 @@ aarch64_record_decode_insn_handler (insn_decode_record *aarch64_insn_r)
>
> /* Data processing - SIMD and floating point instructions. */
> if (ins_bit25 && ins_bit26 && ins_bit27)
> - return AARCH64_RECORD_USUPPORTED;
> + return aarch64_record_data_proc_simd_fp (aarch64_insn_r);
>
> return AARCH64_RECORD_USUPPORTED;
> }
> --
> 1.9.1
>
--
Will Newton
Toolchain Working Group, Linaro
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: [PATCH 6/7] Support for recording aarch64 advanced SIMD instructions
2014-06-05 8:58 [PATCH 6/7] Support for recording aarch64 advance simd instructions Will Newton
@ 2014-08-29 13:41 ` Omair Javaid
2014-09-02 15:01 ` Will Newton
0 siblings, 1 reply; 5+ messages in thread
From: Omair Javaid @ 2014-08-29 13:41 UTC (permalink / raw)
To: gdb-patches
Updated patch after incorporating suggestions.
gdb:
2014-08-28 Omair Javaid <omair.javaid@linaro.org>
* aarch64-tdep.c (aarch64_record_data_proc_simd_fp): Add handler
for data processing SIMD and floating point insns.
(aarch64_record_asimd_load_store): Add handler to record ASIMD load
store insns.
(aarch64_record_load_store): Install record handler
aarch64_record_asimd_load_store.
(aarch64_record_decode_insn_handler): Install record handler
aarch64_record_data_proc_simd_fp.
---
gdb/aarch64-tdep.c | 228 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 226 insertions(+), 2 deletions(-)
diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c
index c6da25a..9437280 100644
--- a/gdb/aarch64-tdep.c
+++ b/gdb/aarch64-tdep.c
@@ -2986,6 +2986,144 @@ aarch64_record_branch_except_sys (insn_decode_record *aarch64_insn_r)
return AARCH64_RECORD_SUCCESS;
}
+/* Record handler for advanced SIMD load and store instructions. */
+static unsigned int
+aarch64_record_asimd_load_store (insn_decode_record *aarch64_insn_r)
+{
+ CORE_ADDR address;
+ uint64_t addr_offset = 0;
+ uint32_t record_buf[24];
+ uint64_t record_buf_mem[24];
+ uint32_t reg_rn, reg_rt, reg_rm;
+ uint32_t reg_index = 0, mem_index = 0;
+ uint8_t eindex, rindex, sindex, reg_tt, replicate;
+ uint8_t elements, esize, rpt, selem, single, scale;
+ uint8_t opcode_bits, size_bits, ld_flag, data_size, wback;
+
+ reg_rt = bits (aarch64_insn_r->aarch64_insn, 0, 4);
+ reg_rn = bits (aarch64_insn_r->aarch64_insn, 5, 9);
+ reg_rm = bits (aarch64_insn_r->aarch64_insn, 16, 20);
+
+ wback = bit (aarch64_insn_r->aarch64_insn, 23);
+ single = bit (aarch64_insn_r->aarch64_insn, 24);
+ ld_flag = bit (aarch64_insn_r->aarch64_insn, 22);
+ size_bits = bits (aarch64_insn_r->aarch64_insn, 10, 11);
+ opcode_bits = bits (aarch64_insn_r->aarch64_insn, 12, 15);
+ regcache_raw_read_unsigned (aarch64_insn_r->regcache, reg_rn, &address);
+
+ if (single)
+ {
+ scale = opcode_bits >> 2;
+ selem = ((opcode_bits & 0x02) |
+ bit (aarch64_insn_r->aarch64_insn, 21)) + 1;
+ replicate = 0;
+ switch (scale)
+ {
+ case 2:
+ if (!(size_bits & 0x01) && ((size_bits >> 1) & 0x01))
+ scale = 3;
+ break;
+ case 3:
+ scale = size_bits;
+ replicate = 1;
+ break;
+ default:
+ break;
+ }
+ esize = 8 << scale;
+ if (replicate)
+ for (sindex = 0; sindex < selem; sindex++)
+ {
+ record_buf[reg_index++] = reg_rt + AARCH64_V0_REGNUM;
+ reg_rt = (reg_rt + 1) % 32;
+ }
+ else
+ {
+ for (sindex = 0; sindex < selem; sindex++)
+ if (ld_flag)
+ record_buf[reg_index++] = reg_rt + AARCH64_V0_REGNUM;
+ else
+ {
+ record_buf_mem[mem_index++] = esize / 8;
+ record_buf_mem[mem_index++] = address + addr_offset;
+ }
+ addr_offset = addr_offset + (esize / 8);
+ reg_rt = (reg_rt + 1) % 32;
+ }
+ }
+ else
+ {
+ esize = 8 << size_bits;
+ if (bit (aarch64_insn_r->aarch64_insn, 30))
+ elements = 128 / esize;
+ else
+ elements = 64 / esize;
+
+ switch (opcode_bits)
+ {
+ case 0:
+ rpt = 1;
+ selem = 4;
+ break;
+ case 2:
+ rpt = 4;
+ selem = 1;
+ break;
+ case 4:
+ rpt = 1;
+ selem = 3;
+ break;
+ case 6:
+ rpt = 3;
+ selem = 1;
+ break;
+ case 7:
+ rpt = 1;
+ selem = 1;
+ break;
+ case 8:
+ rpt = 1;
+ selem = 2;
+ break;
+ case 10:
+ rpt = 2;
+ selem = 1;
+ break;
+ default:
+ return AARCH64_RECORD_UNSUPPORTED;
+ break;
+ }
+ for (rindex = 0; rindex < rpt; rindex++)
+ for (eindex = 0; eindex < elements; eindex++)
+ {
+ reg_tt = (reg_rt + rindex) % 32;
+ for (sindex = 0; sindex < selem; sindex++)
+ {
+ if (ld_flag)
+ record_buf[reg_index++] = reg_tt + AARCH64_V0_REGNUM;
+ else
+ {
+ record_buf_mem[mem_index++] = esize / 8;
+ record_buf_mem[mem_index++] = address + addr_offset;
+ }
+ addr_offset = addr_offset + (esize / 8);
+ reg_tt = (reg_tt + 1) % 32;
+ }
+ }
+ }
+
+ if (wback)
+ record_buf[reg_index++] = reg_rn;
+
+ aarch64_insn_r->reg_rec_count = reg_index;
+ aarch64_insn_r->mem_rec_count = mem_index / 2;
+ MEM_ALLOC (aarch64_insn_r->aarch64_mems, aarch64_insn_r->mem_rec_count,
+ record_buf_mem);
+ REG_ALLOC (aarch64_insn_r->aarch64_regs, aarch64_insn_r->reg_rec_count,
+ record_buf);
+ return AARCH64_RECORD_SUCCESS;
+}
+
/* Record handler for load and store instructions. */
static unsigned int
aarch64_record_load_store (insn_decode_record *aarch64_insn_r)
@@ -3224,7 +3362,7 @@ aarch64_record_load_store (insn_decode_record *aarch64_insn_r)
}
/* Advanced SIMD load/store instructions. */
else
- return AARCH64_RECORD_UNSUPPORTED;
+ return aarch64_record_asimd_load_store (aarch64_insn_r);
MEM_ALLOC (aarch64_insn_r->aarch64_mems, aarch64_insn_r->mem_rec_count,
record_buf_mem);
@@ -3232,6 +3370,92 @@ aarch64_record_load_store (insn_decode_record *aarch64_insn_r)
record_buf);
return AARCH64_RECORD_SUCCESS;
}
+
+/* Record handler for data processing SIMD and floating point instructions. */
+
+static unsigned int
+aarch64_record_data_proc_simd_fp (insn_decode_record *aarch64_insn_r)
+{
+ uint8_t insn_bit21, opcode, rmode, reg_rd;
+ uint8_t insn_bits24_27, insn_bits28_31, insn_bits10_11, insn_bits12_15;
+ uint8_t insn_bits11_14;
+ uint32_t record_buf[2];
+
+ insn_bits24_27 = bits (aarch64_insn_r->aarch64_insn, 24, 27);
+ insn_bits28_31 = bits (aarch64_insn_r->aarch64_insn, 28, 31);
+ insn_bits10_11 = bits (aarch64_insn_r->aarch64_insn, 10, 11);
+ insn_bits12_15 = bits (aarch64_insn_r->aarch64_insn, 12, 15);
+ insn_bits11_14 = bits (aarch64_insn_r->aarch64_insn, 11, 14);
+ opcode = bits (aarch64_insn_r->aarch64_insn, 16, 18);
+ rmode = bits (aarch64_insn_r->aarch64_insn, 19, 20);
+ reg_rd = bits (aarch64_insn_r->aarch64_insn, 0, 4);
+ insn_bit21 = bit (aarch64_insn_r->aarch64_insn, 21);
+
+ if ((insn_bits28_31 & 0x05) == 0x01 && insn_bits24_27 == 0x0e)
+ {
+ /* Floating point - fixed point conversion instructions. */
+ if (!insn_bit21)
+ if ((opcode >> 1) == 0x0 && rmode == 0x03)
+ record_buf[0] = reg_rd;
+ else
+ record_buf[0] = reg_rd + AARCH64_V0_REGNUM;
+ /* Floating point - conditional compare instructions. */
+ else if (insn_bits10_11 == 0x01)
+ record_buf[0] = AARCH64_CPSR_REGNUM;
+ /* Floating point - data processing (2-source) and
+ conditional select instructions. */
+ else if (insn_bits10_11 == 0x02 || insn_bits10_11 == 0x03)
+ record_buf[0] = reg_rd + AARCH64_V0_REGNUM;
+ else if (insn_bits10_11 == 0x00)
+ {
+ /* Floating point - immediate instructions. */
+ if ((insn_bits12_15 & 0x01) == 0x01 || (insn_bits12_15 & 0x07) == 0x04)
+ record_buf[0] = reg_rd + AARCH64_V0_REGNUM;
+ /* Floating point - compare instructions. */
+ else if ((insn_bits12_15 & 0x03) == 0x02)
+ record_buf[0] = AARCH64_CPSR_REGNUM;
+ /* Floating point - integer conversions instructions. */
+ if (insn_bits12_15 == 0x00)
+ {
+ /* Convert float to integer instruction. */
+ if (!(opcode >> 1) || ((opcode >> 1) == 0x02 && !rmode))
+ record_buf[0] = reg_rd + AARCH64_X0_REGNUM;
+ /* Convert integer to float instruction. */
+ else if ((opcode >> 1) == 0x01 && !rmode)
+ record_buf[0] = reg_rd + AARCH64_V0_REGNUM;
+ /* Move float to integer instruction. */
+ else if ((opcode >> 1) == 0x03)
+ {
+ if (!(opcode & 0x01))
+ record_buf[0] = reg_rd + AARCH64_X0_REGNUM;
+ else
+ record_buf[0] = reg_rd + AARCH64_V0_REGNUM;
+ }
+ }
+ }
+ }
+ else if ((insn_bits28_31 & 0x09) == 0x00 && insn_bits24_27 == 0x0E)
+ {
+ /* Advanced SIMD copy instructions. */
+ if (!bits (aarch64_insn_r->aarch64_insn, 21, 23) &&
+ !bit (aarch64_insn_r->aarch64_insn, 15) &&
+ bit (aarch64_insn_r->aarch64_insn, 10))
+ if (insn_bits11_14 == 0x05 || insn_bits11_14 == 0x07)
+ record_buf[0] = reg_rd + AARCH64_X0_REGNUM;
+ else
+ record_buf[0] = reg_rd + AARCH64_V0_REGNUM;
+ else
+ record_buf[0] = reg_rd + AARCH64_V0_REGNUM;
+ }
+ /* All remaining floating point or advanced SIMD instructions. */
+ else
+ record_buf[0] = reg_rd + AARCH64_V0_REGNUM;
+
+ REG_ALLOC (aarch64_insn_r->aarch64_regs, aarch64_insn_r->reg_rec_count,
+ record_buf);
+ return AARCH64_RECORD_SUCCESS;
+}
+
/* Decodes insns type and invokes its record handler. */
static unsigned int
@@ -3262,7 +3486,7 @@ aarch64_record_decode_insn_handler (insn_decode_record *aarch64_insn_r)
/* Data processing - SIMD and floating point instructions. */
if (ins_bit25 && ins_bit26 && ins_bit27)
- return AARCH64_RECORD_UNSUPPORTED;
+ return aarch64_record_data_proc_simd_fp (aarch64_insn_r);
return AARCH64_RECORD_UNSUPPORTED;
}
--
1.9.1
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: [PATCH 6/7] Support for recording aarch64 advanced SIMD instructions
2014-08-29 13:41 ` [PATCH 6/7] Support for recording aarch64 advanced SIMD instructions Omair Javaid
@ 2014-09-02 15:01 ` Will Newton
0 siblings, 0 replies; 5+ messages in thread
From: Will Newton @ 2014-09-02 15:01 UTC (permalink / raw)
To: Omair Javaid; +Cc: gdb-patches
On 29 August 2014 14:41, Omair Javaid <omair.javaid@linaro.org> wrote:
> Updated patch after incorporating suggestions.
>
> gdb:
>
> 2014-08-28 Omair Javaid <omair.javaid@linaro.org>
>
> * aarch64-tdep.c (aarch64_record_data_proc_simd_fp): Add handler
> for data processing SIMD and floating point insns.
> (aarch64_record_asimd_load_store): Add handler to record ASIMD load
> store insns.
> (aarch64_record_load_store): Install record handler
> aarch64_record_asimd_load_store.
> (aarch64_record_decode_insn_handler): Install record handler
> aarch64_record_data_proc_simd_fp.
>
> ---
> gdb/aarch64-tdep.c | 228 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 226 insertions(+), 2 deletions(-)
This looks OK to me.
> diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c
> index c6da25a..9437280 100644
> --- a/gdb/aarch64-tdep.c
> +++ b/gdb/aarch64-tdep.c
> @@ -2986,6 +2986,144 @@ aarch64_record_branch_except_sys (insn_decode_record *aarch64_insn_r)
> return AARCH64_RECORD_SUCCESS;
> }
>
> +/* Record handler for advanced SIMD load and store instructions. */
> +static unsigned int
> +aarch64_record_asimd_load_store (insn_decode_record *aarch64_insn_r)
> +{
> + CORE_ADDR address;
> + uint64_t addr_offset = 0;
> + uint32_t record_buf[24];
> + uint64_t record_buf_mem[24];
> + uint32_t reg_rn, reg_rt, reg_rm;
> + uint32_t reg_index = 0, mem_index = 0;
> + uint8_t eindex, rindex, sindex, reg_tt, replicate;
> + uint8_t elements, esize, rpt, selem, single, scale;
> + uint8_t opcode_bits, size_bits, ld_flag, data_size, wback;
> +
> + reg_rt = bits (aarch64_insn_r->aarch64_insn, 0, 4);
> + reg_rn = bits (aarch64_insn_r->aarch64_insn, 5, 9);
> + reg_rm = bits (aarch64_insn_r->aarch64_insn, 16, 20);
> +
> + wback = bit (aarch64_insn_r->aarch64_insn, 23);
> + single = bit (aarch64_insn_r->aarch64_insn, 24);
> + ld_flag = bit (aarch64_insn_r->aarch64_insn, 22);
> + size_bits = bits (aarch64_insn_r->aarch64_insn, 10, 11);
> + opcode_bits = bits (aarch64_insn_r->aarch64_insn, 12, 15);
> + regcache_raw_read_unsigned (aarch64_insn_r->regcache, reg_rn, &address);
> +
> + if (single)
> + {
> + scale = opcode_bits >> 2;
> + selem = ((opcode_bits & 0x02) |
> + bit (aarch64_insn_r->aarch64_insn, 21)) + 1;
> + replicate = 0;
> + switch (scale)
> + {
> + case 2:
> + if (!(size_bits & 0x01) && ((size_bits >> 1) & 0x01))
> + scale = 3;
> + break;
> + case 3:
> + scale = size_bits;
> + replicate = 1;
> + break;
> + default:
> + break;
> + }
> + esize = 8 << scale;
> + if (replicate)
> + for (sindex = 0; sindex < selem; sindex++)
> + {
> + record_buf[reg_index++] = reg_rt + AARCH64_V0_REGNUM;
> + reg_rt = (reg_rt + 1) % 32;
> + }
> + else
> + {
> + for (sindex = 0; sindex < selem; sindex++)
> + if (ld_flag)
> + record_buf[reg_index++] = reg_rt + AARCH64_V0_REGNUM;
> + else
> + {
> + record_buf_mem[mem_index++] = esize / 8;
> + record_buf_mem[mem_index++] = address + addr_offset;
> + }
> + addr_offset = addr_offset + (esize / 8);
> + reg_rt = (reg_rt + 1) % 32;
> + }
> + }
> + else
> + {
> + esize = 8 << size_bits;
> + if (bit (aarch64_insn_r->aarch64_insn, 30))
> + elements = 128 / esize;
> + else
> + elements = 64 / esize;
> +
> + switch (opcode_bits)
> + {
> + case 0:
> + rpt = 1;
> + selem = 4;
> + break;
> + case 2:
> + rpt = 4;
> + selem = 1;
> + break;
> + case 4:
> + rpt = 1;
> + selem = 3;
> + break;
> + case 6:
> + rpt = 3;
> + selem = 1;
> + break;
> + case 7:
> + rpt = 1;
> + selem = 1;
> + break;
> + case 8:
> + rpt = 1;
> + selem = 2;
> + break;
> + case 10:
> + rpt = 2;
> + selem = 1;
> + break;
> + default:
> + return AARCH64_RECORD_UNSUPPORTED;
> + break;
> + }
> + for (rindex = 0; rindex < rpt; rindex++)
> + for (eindex = 0; eindex < elements; eindex++)
> + {
> + reg_tt = (reg_rt + rindex) % 32;
> + for (sindex = 0; sindex < selem; sindex++)
> + {
> + if (ld_flag)
> + record_buf[reg_index++] = reg_tt + AARCH64_V0_REGNUM;
> + else
> + {
> + record_buf_mem[mem_index++] = esize / 8;
> + record_buf_mem[mem_index++] = address + addr_offset;
> + }
> + addr_offset = addr_offset + (esize / 8);
> + reg_tt = (reg_tt + 1) % 32;
> + }
> + }
> + }
> +
> + if (wback)
> + record_buf[reg_index++] = reg_rn;
> +
> + aarch64_insn_r->reg_rec_count = reg_index;
> + aarch64_insn_r->mem_rec_count = mem_index / 2;
> + MEM_ALLOC (aarch64_insn_r->aarch64_mems, aarch64_insn_r->mem_rec_count,
> + record_buf_mem);
> + REG_ALLOC (aarch64_insn_r->aarch64_regs, aarch64_insn_r->reg_rec_count,
> + record_buf);
> + return AARCH64_RECORD_SUCCESS;
> +}
> +
> /* Record handler for load and store instructions. */
> static unsigned int
> aarch64_record_load_store (insn_decode_record *aarch64_insn_r)
> @@ -3224,7 +3362,7 @@ aarch64_record_load_store (insn_decode_record *aarch64_insn_r)
> }
> /* Advanced SIMD load/store instructions. */
> else
> - return AARCH64_RECORD_UNSUPPORTED;
> + return aarch64_record_asimd_load_store (aarch64_insn_r);
>
> MEM_ALLOC (aarch64_insn_r->aarch64_mems, aarch64_insn_r->mem_rec_count,
> record_buf_mem);
> @@ -3232,6 +3370,92 @@ aarch64_record_load_store (insn_decode_record *aarch64_insn_r)
> record_buf);
> return AARCH64_RECORD_SUCCESS;
> }
> +
> +/* Record handler for data processing SIMD and floating point instructions. */
> +
> +static unsigned int
> +aarch64_record_data_proc_simd_fp (insn_decode_record *aarch64_insn_r)
> +{
> + uint8_t insn_bit21, opcode, rmode, reg_rd;
> + uint8_t insn_bits24_27, insn_bits28_31, insn_bits10_11, insn_bits12_15;
> + uint8_t insn_bits11_14;
> + uint32_t record_buf[2];
> +
> + insn_bits24_27 = bits (aarch64_insn_r->aarch64_insn, 24, 27);
> + insn_bits28_31 = bits (aarch64_insn_r->aarch64_insn, 28, 31);
> + insn_bits10_11 = bits (aarch64_insn_r->aarch64_insn, 10, 11);
> + insn_bits12_15 = bits (aarch64_insn_r->aarch64_insn, 12, 15);
> + insn_bits11_14 = bits (aarch64_insn_r->aarch64_insn, 11, 14);
> + opcode = bits (aarch64_insn_r->aarch64_insn, 16, 18);
> + rmode = bits (aarch64_insn_r->aarch64_insn, 19, 20);
> + reg_rd = bits (aarch64_insn_r->aarch64_insn, 0, 4);
> + insn_bit21 = bit (aarch64_insn_r->aarch64_insn, 21);
> +
> + if ((insn_bits28_31 & 0x05) == 0x01 && insn_bits24_27 == 0x0e)
> + {
> + /* Floating point - fixed point conversion instructions. */
> + if (!insn_bit21)
> + if ((opcode >> 1) == 0x0 && rmode == 0x03)
> + record_buf[0] = reg_rd;
> + else
> + record_buf[0] = reg_rd + AARCH64_V0_REGNUM;
> + /* Floating point - conditional compare instructions. */
> + else if (insn_bits10_11 == 0x01)
> + record_buf[0] = AARCH64_CPSR_REGNUM;
> + /* Floating point - data processing (2-source) and
> + conditional select instructions. */
> + else if (insn_bits10_11 == 0x02 || insn_bits10_11 == 0x03)
> + record_buf[0] = reg_rd + AARCH64_V0_REGNUM;
> + else if (insn_bits10_11 == 0x00)
> + {
> + /* Floating point - immediate instructions. */
> + if ((insn_bits12_15 & 0x01) == 0x01 || (insn_bits12_15 & 0x07) == 0x04)
> + record_buf[0] = reg_rd + AARCH64_V0_REGNUM;
> + /* Floating point - compare instructions. */
> + else if ((insn_bits12_15 & 0x03) == 0x02)
> + record_buf[0] = AARCH64_CPSR_REGNUM;
> + /* Floating point - integer conversions instructions. */
> + if (insn_bits12_15 == 0x00)
> + {
> + /* Convert float to integer instruction. */
> + if (!(opcode >> 1) || ((opcode >> 1) == 0x02 && !rmode))
> + record_buf[0] = reg_rd + AARCH64_X0_REGNUM;
> + /* Convert integer to float instruction. */
> + else if ((opcode >> 1) == 0x01 && !rmode)
> + record_buf[0] = reg_rd + AARCH64_V0_REGNUM;
> + /* Move float to integer instruction. */
> + else if ((opcode >> 1) == 0x03)
> + {
> + if (!(opcode & 0x01))
> + record_buf[0] = reg_rd + AARCH64_X0_REGNUM;
> + else
> + record_buf[0] = reg_rd + AARCH64_V0_REGNUM;
> + }
> + }
> + }
> + }
> + else if ((insn_bits28_31 & 0x09) == 0x00 && insn_bits24_27 == 0x0E)
> + {
> + /* Advanced SIMD copy instructions. */
> + if (!bits (aarch64_insn_r->aarch64_insn, 21, 23) &&
> + !bit (aarch64_insn_r->aarch64_insn, 15) &&
> + bit (aarch64_insn_r->aarch64_insn, 10))
> + if (insn_bits11_14 == 0x05 || insn_bits11_14 == 0x07)
> + record_buf[0] = reg_rd + AARCH64_X0_REGNUM;
> + else
> + record_buf[0] = reg_rd + AARCH64_V0_REGNUM;
> + else
> + record_buf[0] = reg_rd + AARCH64_V0_REGNUM;
> + }
> + /* All remaining floating point or advanced SIMD instructions. */
> + else
> + record_buf[0] = reg_rd + AARCH64_V0_REGNUM;
> +
> + REG_ALLOC (aarch64_insn_r->aarch64_regs, aarch64_insn_r->reg_rec_count,
> + record_buf);
> + return AARCH64_RECORD_SUCCESS;
> +}
> +
> /* Decodes insns type and invokes its record handler. */
>
> static unsigned int
> @@ -3262,7 +3486,7 @@ aarch64_record_decode_insn_handler (insn_decode_record *aarch64_insn_r)
>
> /* Data processing - SIMD and floating point instructions. */
> if (ins_bit25 && ins_bit26 && ins_bit27)
> - return AARCH64_RECORD_UNSUPPORTED;
> + return aarch64_record_data_proc_simd_fp (aarch64_insn_r);
>
> return AARCH64_RECORD_UNSUPPORTED;
> }
> --
> 1.9.1
>
--
Will Newton
Toolchain Working Group, Linaro
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2014-10-21 9:05 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-09-18 23:01 [PATCH 6/7] Support for recording aarch64 advanced SIMD instructions Omair Javaid
2014-10-14 12:48 ` Omair Javaid
2014-10-21 9:05 ` Omair Javaid
-- strict thread matches above, loose matches on Subject: below --
2014-06-05 8:58 [PATCH 6/7] Support for recording aarch64 advance simd instructions Will Newton
2014-08-29 13:41 ` [PATCH 6/7] Support for recording aarch64 advanced SIMD instructions Omair Javaid
2014-09-02 15:01 ` Will Newton
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox