From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 1320 invoked by alias); 26 Feb 2016 14:54:38 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Received: (qmail 1289 invoked by uid 89); 26 Feb 2016 14:54:37 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.6 required=5.0 tests=AWL,BAYES_00,FREEMAIL_FROM,RCVD_IN_DNSWL_LOW,SPF_PASS autolearn=ham version=3.3.2 spammy=H*RU:209.85.220.66, Hx-spam-relays-external:209.85.220.66, vmov, 886 X-HELO: mail-pa0-f66.google.com Received: from mail-pa0-f66.google.com (HELO mail-pa0-f66.google.com) (209.85.220.66) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Fri, 26 Feb 2016 14:54:35 +0000 Received: by mail-pa0-f66.google.com with SMTP id fl4so4590471pad.2 for ; Fri, 26 Feb 2016 06:54:35 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:references:date:in-reply-to :message-id:user-agent:mime-version:content-transfer-encoding; bh=GJ0ZpNgPcxx/52gWLlvxvom13VvUHKuqsnA+gi0N+BA=; b=IcMC8p+P/3rQV8Dr2H95+Hiry1i9bUeW4ZCGuPih2MGP6zos2AUop7qU3Ew7pflppy yjwfrS/M/NtRbWM7POaiml/zocF9bDWxuf/AwtnmCUyjeA6fzJoUTWotSHV8dhUqC2rW G1lW/UOdbL6A6ZNNXP0hPuJTfvlFifqpozPTEdD4lcC13aOerybbwLHckRroOB6ZOjST HJ0wF/vDwXqwg21l0BO9hmN2zXiDk+f2kqa9Vh3b1TFcsX6ufcu7b3BXt2aWrc37ora2 Rs/J9pVUTIYEoeUIXL0C7KnvRdn3JjhSK1hsqviqdY3rXKyRSuIZ8tYkjqYiN9O3OO+l 5k5g== X-Gm-Message-State: AD7BkJKF83MMenU5NdiIOVLsLW8YUDCtH6X0IAG6Ul5Fzm5KY+o5vEPlnMUx2ZtSFPsW/w== X-Received: by 10.66.231.100 with SMTP id tf4mr2665099pac.44.1456498473598; Fri, 26 Feb 2016 06:54:33 -0800 (PST) Received: from E107787-LIN (gcc1-power7.osuosl.org. [140.211.15.137]) by smtp.gmail.com with ESMTPSA id g74sm20045608pfj.1.2016.02.26.06.54.30 (version=TLS1_2 cipher=AES128-SHA bits=128/128); Fri, 26 Feb 2016 06:54:32 -0800 (PST) From: Yao Qi To: Luis Machado Cc: Yao Qi , Subject: Re: [PATCH 3/3] Fix various bugs in arm_record_exreg_ld_st_insn References: <1456159999-5644-1-git-send-email-yao.qi@linaro.org> <1456159999-5644-4-git-send-email-yao.qi@linaro.org> <56CCBA0F.3000205@codesourcery.com> Date: Fri, 26 Feb 2016 14:54:00 -0000 In-Reply-To: <56CCBA0F.3000205@codesourcery.com> (Luis Machado's message of "Tue, 23 Feb 2016 16:59:11 -0300") Message-ID: <86d1rjbjz5.fsf@gmail.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.3 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-IsSubscribed: yes X-SW-Source: 2016-02/txt/msg00861.txt.bz2 Luis Machado writes: >> - while (reg_count > 0) >> + /* If the instruction loads memory to D register, REG_COUNT should >> + divide 2, according to the ARM Architecture Reference Manual. > > "...should be divided by 2..."? > >> + If the instruction loads memory to S register, divide 2 as well > > "... divide by 2..." > >> + because two S registers are mapped to D register. */ >> + reg_count =3D reg_count / 2; >> + if (single_reg && bit_d) >> { >> - if (single_reg) >> - record_buf[reg_index++] =3D num_regs + reg_vd + reg_count - 1; >> - else >> - record_buf[reg_index++] =3D ARM_D0_REGNUM + reg_vd + reg_count - 1; >> + /* Increase the register count if S register list starts from >> + odd number (bit d is one). */ > > "...from an odd number..."? Hi Luis, Thanks for the review. I fixed them. --=20 Yao (=E9=BD=90=E5=B0=A7) =46rom 8600280115853d508d82ae47932b3cbb8d4c22ac Mon Sep 17 00:00:00 2001 From: Yao Qi Date: Tue, 16 Feb 2016 12:59:03 +0000 Subject: [PATCH] Fix various bugs in arm_record_exreg_ld_st_insn This patch fixes various bugs in arm_record_exreg_ld_st_insn, and use gdb.reverse/insn-reverse.c to test more arm instructions. - Set flag SINGLE_REG correctly. In the arch reference manual, SING_REG is true when the bit 8 of instruction is zero. - Record the right D registers for instructions changing S registers. - Fix the order of length and address in record_buf_mem array. - Shift the offset by 2 instead of by 24. This patch also fixes one internal error, (gdb) PASS: gdb.reverse/finish-precsave.exp: BP at end of main continue^M Continuing.^M ../../binutils-gdb/gdb/utils.c:1072: internal-error: virtual memory exhaust= ed.^M A problem internal to GDB has been detected,FAIL: gdb.reverse/finish-precsa= ve.exp: run to end of main (GDB internal error) gdb: 2016-02-26 Yao Qi * arm-tdep.c (arm_record_exreg_ld_st_insn): Set 'single_reg' per bit 8. Check bit 20 instead of bit 4 for VMOV instruction. Record D registers for instructions changing S registers. Change of the order of length and address in record_buf_mem array. gdb/testsuite: 2016-02-26 Yao Qi * gdb.reverse/insn-reverse.c [__arm__] (ext_reg_load): New. [__arm__] (ext_reg_mov, ext_reg_push_pop): New. (testcases): Update. diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c index bd0ee97..2eb7bb1 100644 --- a/gdb/arm-tdep.c +++ b/gdb/arm-tdep.c @@ -10909,13 +10909,13 @@ arm_record_exreg_ld_st_insn (insn_decode_record *= arm_insn_r) const int num_regs =3D gdbarch_num_regs (arm_insn_r->gdbarch); =20 opcode =3D bits (arm_insn_r->arm_insn, 20, 24); - single_reg =3D bit (arm_insn_r->arm_insn, 8); + single_reg =3D !bit (arm_insn_r->arm_insn, 8); op_vldm_vstm =3D opcode & 0x1b; =20 /* Handle VMOV instructions. */ if ((opcode & 0x1e) =3D=3D 0x04) { - if (bit (arm_insn_r->arm_insn, 4)) + if (bit (arm_insn_r->arm_insn, 20)) /* to_arm_registers bit 20? */ { record_buf[0] =3D bits (arm_insn_r->arm_insn, 12, 15); record_buf[1] =3D bits (arm_insn_r->arm_insn, 16, 19); @@ -10923,18 +10923,29 @@ arm_record_exreg_ld_st_insn (insn_decode_record *= arm_insn_r) } else { - uint8_t reg_m =3D ((bits (arm_insn_r->arm_insn, 0, 3) << 1) - | bit (arm_insn_r->arm_insn, 5)); + uint8_t reg_m =3D bits (arm_insn_r->arm_insn, 0, 3); + uint8_t bit_m =3D bit (arm_insn_r->arm_insn, 5); =20 - if (!single_reg) + if (single_reg) { - record_buf[0] =3D num_regs + reg_m; - record_buf[1] =3D num_regs + reg_m + 1; - arm_insn_r->reg_rec_count =3D 2; + /* The first S register number m is REG_M:M (M is bit 5), + the corresponding D register number is REG_M:M / 2, which + is REG_M. */ + record_buf[arm_insn_r->reg_rec_count++] =3D ARM_D0_REGNUM + reg_m; + /* The second S register number is REG_M:M + 1, the + corresponding D register number is (REG_M:M + 1) / 2. + IOW, if bit M is 1, the first and second S registers + are mapped to different D registers, otherwise, they are + in the same D register. */ + if (bit_m) + { + record_buf[arm_insn_r->reg_rec_count++] + =3D ARM_D0_REGNUM + reg_m + 1; + } } else { - record_buf[0] =3D reg_m + ARM_D0_REGNUM; + record_buf[0] =3D ((bit_m << 4) + reg_m + ARM_D0_REGNUM); arm_insn_r->reg_rec_count =3D 1; } } @@ -10949,7 +10960,7 @@ arm_record_exreg_ld_st_insn (insn_decode_record *ar= m_insn_r) reg_rn =3D bits (arm_insn_r->arm_insn, 16, 19); regcache_raw_read_unsigned (reg_cache, reg_rn, &u_regval); imm_off8 =3D bits (arm_insn_r->arm_insn, 0, 7); - imm_off32 =3D imm_off8 << 24; + imm_off32 =3D imm_off8 << 2; memory_count =3D imm_off8; =20 if (bit (arm_insn_r->arm_insn, 23)) @@ -10965,19 +10976,19 @@ arm_record_exreg_ld_st_insn (insn_decode_record *= arm_insn_r) =20 while (memory_count > 0) { - if (!single_reg) + if (single_reg) { - record_buf_mem[memory_index] =3D start_address; - record_buf_mem[memory_index + 1] =3D 4; + record_buf_mem[memory_index] =3D 4; + record_buf_mem[memory_index + 1] =3D start_address; start_address =3D start_address + 4; memory_index =3D memory_index + 2; } else { - record_buf_mem[memory_index] =3D start_address; - record_buf_mem[memory_index + 1] =3D 4; - record_buf_mem[memory_index + 2] =3D start_address + 4; - record_buf_mem[memory_index + 3] =3D 4; + record_buf_mem[memory_index] =3D 4; + record_buf_mem[memory_index + 1] =3D start_address; + record_buf_mem[memory_index + 2] =3D 4; + record_buf_mem[memory_index + 3] =3D start_address + 4; start_address =3D start_address + 8; memory_index =3D memory_index + 4; } @@ -10991,25 +11002,36 @@ arm_record_exreg_ld_st_insn (insn_decode_record *= arm_insn_r) { uint32_t reg_count, reg_vd; uint32_t reg_index =3D 0; + uint32_t bit_d =3D bit (arm_insn_r->arm_insn, 22); =20 reg_vd =3D bits (arm_insn_r->arm_insn, 12, 15); reg_count =3D bits (arm_insn_r->arm_insn, 0, 7); =20 - if (single_reg) - reg_vd =3D reg_vd | (bit (arm_insn_r->arm_insn, 22) << 4); - else - reg_vd =3D (reg_vd << 1) | bit (arm_insn_r->arm_insn, 22); + /* REG_VD is the first D register number. If the instruction + loads memory to S registers (SINGLE_REG is TRUE), the register + number is (REG_VD << 1 | bit D), so the corresponding D + register number is (REG_VD << 1 | bit D) / 2 =3D REG_VD. */ + if (!single_reg) + reg_vd =3D reg_vd | (bit_d << 4); =20 - if (bit (arm_insn_r->arm_insn, 21)) + if (bit (arm_insn_r->arm_insn, 21) /* write back */) record_buf[reg_index++] =3D bits (arm_insn_r->arm_insn, 16, 19); =20 - while (reg_count > 0) + /* If the instruction loads memory to D register, REG_COUNT should + be divided by 2, according to the ARM Architecture Reference + Manual. If the instruction loads memory to S register, divide by + 2 as well because two S registers are mapped to D register. */ + reg_count =3D reg_count / 2; + if (single_reg && bit_d) { - if (single_reg) - record_buf[reg_index++] =3D num_regs + reg_vd + reg_count - 1; - else - record_buf[reg_index++] =3D ARM_D0_REGNUM + reg_vd + reg_count - 1; + /* Increase the register count if S register list starts from + an odd number (bit d is one). */ + reg_count++; + } =20 + while (reg_count > 0) + { + record_buf[reg_index++] =3D ARM_D0_REGNUM + reg_vd + reg_count - 1; reg_count--; } arm_insn_r->reg_rec_count =3D reg_index; @@ -11023,7 +11045,7 @@ arm_record_exreg_ld_st_insn (insn_decode_record *ar= m_insn_r) reg_rn =3D bits (arm_insn_r->arm_insn, 16, 19); regcache_raw_read_unsigned (reg_cache, reg_rn, &u_regval); imm_off8 =3D bits (arm_insn_r->arm_insn, 0, 7); - imm_off32 =3D imm_off8 << 24; + imm_off32 =3D imm_off8 << 2; =20 if (bit (arm_insn_r->arm_insn, 23)) start_address =3D u_regval + imm_off32; @@ -11032,16 +11054,16 @@ arm_record_exreg_ld_st_insn (insn_decode_record *= arm_insn_r) =20 if (single_reg) { - record_buf_mem[memory_index] =3D start_address; - record_buf_mem[memory_index + 1] =3D 4; + record_buf_mem[memory_index] =3D 4; + record_buf_mem[memory_index + 1] =3D start_address; arm_insn_r->mem_rec_count =3D 1; } else { - record_buf_mem[memory_index] =3D start_address; - record_buf_mem[memory_index + 1] =3D 4; - record_buf_mem[memory_index + 2] =3D start_address + 4; - record_buf_mem[memory_index + 3] =3D 4; + record_buf_mem[memory_index] =3D 4; + record_buf_mem[memory_index + 1] =3D start_address; + record_buf_mem[memory_index + 2] =3D 4; + record_buf_mem[memory_index + 3] =3D start_address + 4; arm_insn_r->mem_rec_count =3D 2; } } @@ -11058,7 +11080,8 @@ arm_record_exreg_ld_st_insn (insn_decode_record *ar= m_insn_r) else { reg_vd =3D (reg_vd << 1) | bit (arm_insn_r->arm_insn, 22); - record_buf[0] =3D num_regs + reg_vd; + /* Record register D rather than pseudo register S. */ + record_buf[0] =3D ARM_D0_REGNUM + reg_vd / 2; } arm_insn_r->reg_rec_count =3D 1; } diff --git a/gdb/testsuite/gdb.reverse/insn-reverse.c b/gdb/testsuite/gdb.r= everse/insn-reverse.c index 1bfb8b0..22cd267 100644 --- a/gdb/testsuite/gdb.reverse/insn-reverse.c +++ b/gdb/testsuite/gdb.reverse/insn-reverse.c @@ -88,6 +88,45 @@ adv_simd_vect_shift (void) { asm ("fcvtzs s0, s0, #1"); } +#elif (defined __arm__) +static void +ext_reg_load (void) +{ + char in[8]; + + asm ("vldr d0, [%0]" : : "r" (in)); + asm ("vldr s3, [%0]" : : "r" (in)); + + asm ("vldm %0, {d3-d4}" : : "r" (in)); + asm ("vldm %0, {s9-s11}" : : "r" (in)); +} + +static void +ext_reg_mov (void) +{ + int i, j; + double d; + + i =3D 1; + j =3D 2; + + asm ("vmov s4, s5, %0, %1" : "=3Dr" (i), "=3Dr" (j): ); + asm ("vmov s7, s8, %0, %1" : "=3Dr" (i), "=3Dr" (j): ); + asm ("vmov %0, %1, s10, s11" : : "r" (i), "r" (j)); + asm ("vmov %0, %1, s1, s2" : : "r" (i), "r" (j)); + + asm ("vmov %P2, %0, %1" : "=3Dr" (i), "=3Dr" (j): "w" (d)); + asm ("vmov %1, %2, %P0" : "=3Dw" (d) : "r" (i), "r" (j)); +} + +static void +ext_reg_push_pop (void) +{ + double d; + + asm ("vpush {%P0}" : : "w" (d)); + asm ("vpop {%P0}" : : "w" (d)); +} #endif =20 typedef void (*testcase_ftype) (void); @@ -104,6 +143,10 @@ static testcase_ftype testcases[] =3D adv_simd_scalar_index, adv_simd_smlal, adv_simd_vect_shift, +#elif (defined __arm__) + ext_reg_load, + ext_reg_mov, + ext_reg_push_pop, #endif }; =20