From patchwork Thu Jun 9 12:56:07 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Antoine Tremblay X-Patchwork-Id: 12907 Received: (qmail 67333 invoked by alias); 9 Jun 2016 12:57:00 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 67144 invoked by uid 89); 9 Jun 2016 12:56:59 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.9 required=5.0 tests=BAYES_00, SPF_PASS autolearn=ham version=3.3.2 spammy=cbz X-HELO: usplmg20.ericsson.net Received: from usplmg20.ericsson.net (HELO usplmg20.ericsson.net) (198.24.6.45) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-SHA encrypted) ESMTPS; Thu, 09 Jun 2016 12:56:48 +0000 Received: from EUSAAHC001.ericsson.se (Unknown_Domain [147.117.188.75]) by usplmg20.ericsson.net (Symantec Mail Security) with SMTP id EC.D8.09012.13E59575; Thu, 9 Jun 2016 14:16:49 +0200 (CEST) Received: from elxa4wqvvz1.dyn.mo.ca.am.ericsson.se (147.117.188.8) by smtps-am.internal.ericsson.com (147.117.188.75) with Microsoft SMTP Server (TLS) id 14.3.294.0; Thu, 9 Jun 2016 08:56:30 -0400 From: Antoine Tremblay To: CC: Simon Marchi Subject: [PATCH v2 09/17] Move Thumb 16 bits instruction decode functions to arch/arm-insn-reloc.c Date: Thu, 9 Jun 2016 08:56:07 -0400 Message-ID: <1465476975-25062-10-git-send-email-antoine.tremblay@ericsson.com> In-Reply-To: <1465476975-25062-1-git-send-email-antoine.tremblay@ericsson.com> References: <1465476975-25062-1-git-send-email-antoine.tremblay@ericsson.com> MIME-Version: 1.0 X-IsSubscribed: yes From: Simon Marchi This patch does the same as the previous one, but for 16-bits Thumb instructions-related functions. gdb/ChangeLog: * arch/arm-insn-reloc.c (thumb_decode_pc_relative_16bit): Move from arm-tdep.c. (thumb_16bit_relocate_insn): Likewise. * arch/arm-insn-reloc.h (struct thumb_16bit_insn_reloc_visitor): Move from arm-tdep.c. (thumb_16bit_relocate_insn): New declaration. * arm-tdep.c (struct thumb_16bit_insn_reloc_visitor): Move to arch/arm-insn-reloc.h. (thumb_decode_pc_relative_16bit): Move to arch/arm-insn-reloc.c. (thumb_16bit_relocate_insn): Likewise. --- gdb/arch/arm-insn-reloc.c | 106 ++++++++++++++++++++++++++++++++++++++++ gdb/arch/arm-insn-reloc.h | 20 ++++++++ gdb/arm-tdep.c | 121 ---------------------------------------------- 3 files changed, 126 insertions(+), 121 deletions(-) diff --git a/gdb/arch/arm-insn-reloc.c b/gdb/arch/arm-insn-reloc.c index f598c64..b6ede60 100644 --- a/gdb/arch/arm-insn-reloc.c +++ b/gdb/arch/arm-insn-reloc.c @@ -744,3 +744,109 @@ thumb_32bit_relocate_insn (uint16_t insn1, uint16_t insn2, return err; } + +static int +thumb_decode_pc_relative_16bit (uint16_t insn, + struct thumb_16bit_insn_reloc_visitor *visitor, + struct arm_insn_reloc_data *data) +{ + unsigned int rd = bits (insn, 8, 10); + unsigned int imm8 = bits (insn, 0, 7); + + return visitor->pc_relative_16bit (insn, data, rd, imm8); +} + +int +thumb_16bit_relocate_insn (uint16_t insn1, + struct thumb_16bit_insn_reloc_visitor *visitor, + struct arm_insn_reloc_data *data) +{ + unsigned short op_bit_12_15 = bits (insn1, 12, 15); + unsigned short op_bit_10_11 = bits (insn1, 10, 11); + int err = 0; + + /* 16-bit thumb instructions. */ + switch (op_bit_12_15) + { + /* Shift (imme), add, subtract, move and compare. */ + case 0: case 1: case 2: case 3: + err = visitor->others (insn1, "shift/add/sub/mov/cmp", data); + break; + case 4: + switch (op_bit_10_11) + { + case 0: /* Data-processing */ + err = visitor->others (insn1, "data-processing", data); + break; + case 1: /* Special data instructions and branch and exchange. */ + { + unsigned short op = bits (insn1, 7, 9); + if (op == 6 || op == 7) /* BX or BLX */ + err = visitor->bx_blx_reg (insn1, data); + else if (bits (insn1, 6, 7) != 0) /* ADD/MOV/CMP high registers. */ + err = visitor->alu_reg (insn1, data); + else + err = visitor->others (insn1, "special data", data); + } + break; + default: /* LDR (literal) */ + err = visitor->load_literal (insn1, data); + } + break; + case 5: case 6: case 7: case 8: case 9: /* Load/Store single data item */ + err = visitor->others (insn1, "ldr/str", data); + break; + case 10: + if (op_bit_10_11 < 2) /* Generate PC-relative address */ + err = thumb_decode_pc_relative_16bit (insn1, visitor, data); + else /* Generate SP-relative address */ + err = visitor->others (insn1, "sp-relative", data); + break; + case 11: /* Misc 16-bit instructions */ + { + switch (bits (insn1, 8, 11)) + { + case 1: case 3: case 9: case 11: /* CBNZ, CBZ */ + err = visitor->cbnz_cbz (insn1, data); + break; + case 12: case 13: /* POP */ + if (bit (insn1, 8)) /* PC is in register list. */ + err = visitor->pop_pc_16bit (insn1, data); + else + err = visitor->others (insn1, "pop", data); + break; + case 15: /* If-Then, and hints */ + if (bits (insn1, 0, 3)) + /* If-Then makes up to four following instructions conditional. + IT instruction itself is not conditional, so handle it as a + common unmodified instruction. */ + err = visitor->others (insn1, "If-Then", data); + else + err = visitor->others (insn1, "hints", data); + break; + default: + err = visitor->others (insn1, "misc", data); + } + } + break; + case 12: + if (op_bit_10_11 < 2) /* Store multiple registers */ + err = visitor->others (insn1, "stm", data); + else /* Load multiple registers */ + err = visitor->others (insn1, "ldm", data); + break; + case 13: /* Conditional branch and supervisor call */ + if (bits (insn1, 9, 11) != 7) /* conditional branch */ + err = visitor->b (insn1, data); + else + err = visitor->svc (insn1, data); + break; + case 14: /* Unconditional branch */ + err = visitor->b (insn1, data); + break; + default: + err = 1; + } + + return err; +} diff --git a/gdb/arch/arm-insn-reloc.h b/gdb/arch/arm-insn-reloc.h index ebfc89a..6e83ad4 100644 --- a/gdb/arch/arm-insn-reloc.h +++ b/gdb/arch/arm-insn-reloc.h @@ -69,6 +69,21 @@ struct thumb_32bit_insn_reloc_visitor struct arm_insn_reloc_data *data); }; +struct thumb_16bit_insn_reloc_visitor +{ + int (*alu_reg) (uint16_t insn, struct arm_insn_reloc_data *data); + int (*b) (uint16_t insn, struct arm_insn_reloc_data *data); + int (*bx_blx_reg) (uint16_t insn, struct arm_insn_reloc_data *data); + int (*cbnz_cbz) (uint16_t insn1, struct arm_insn_reloc_data *data); + int (*load_literal) (uint16_t insn1, struct arm_insn_reloc_data *data); + int (*others) (uint16_t insn, const char *iname, + struct arm_insn_reloc_data *data); + int (*pc_relative_16bit) (uint16_t insn, struct arm_insn_reloc_data *data, + int rd, unsigned int imm); + int (*pop_pc_16bit) (uint16_t insn, struct arm_insn_reloc_data *data); + int (*svc) (uint16_t insn, struct arm_insn_reloc_data *data); +}; + extern int arm_relocate_insn (uint32_t insn, struct arm_insn_reloc_visitor *visitor, struct arm_insn_reloc_data *data); @@ -78,4 +93,9 @@ extern int thumb_32bit_relocate_insn ( struct thumb_32bit_insn_reloc_visitor *visitor, struct arm_insn_reloc_data *data); +extern int thumb_16bit_relocate_insn ( + uint16_t insn1, + struct thumb_16bit_insn_reloc_visitor *visitor, + struct arm_insn_reloc_data *data); + #endif /* ARM_INSN_RELOC_H */ diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c index 4f4b6b2..4a4826a 100644 --- a/gdb/arm-tdep.c +++ b/gdb/arm-tdep.c @@ -4481,21 +4481,6 @@ struct arm_insn_reloc_data struct regcache *regs; }; -struct thumb_16bit_insn_reloc_visitor -{ - int (*alu_reg) (uint16_t insn, struct arm_insn_reloc_data *data); - int (*b) (uint16_t insn, struct arm_insn_reloc_data *data); - int (*bx_blx_reg) (uint16_t insn, struct arm_insn_reloc_data *data); - int (*cbnz_cbz) (uint16_t insn1, struct arm_insn_reloc_data *data); - int (*load_literal) (uint16_t insn1, struct arm_insn_reloc_data *data); - int (*others) (uint16_t insn, const char *iname, - struct arm_insn_reloc_data *data); - int (*pc_relative_16bit) (uint16_t insn, struct arm_insn_reloc_data *data, - int rd, unsigned int imm); - int (*pop_pc_16bit) (uint16_t insn, struct arm_insn_reloc_data *data); - int (*svc) (uint16_t insn, struct arm_insn_reloc_data *data); -}; - /* Helper for register reads for displaced stepping. In particular, this returns the PC as it would be seen by the instruction at its original location. */ @@ -6512,17 +6497,6 @@ thumb_copy_pc_relative_16bit (uint16_t insn, struct arm_insn_reloc_data *data, } static int -thumb_decode_pc_relative_16bit (uint16_t insn, - struct thumb_16bit_insn_reloc_visitor *visitor, - struct arm_insn_reloc_data *data) -{ - unsigned int rd = bits (insn, 8, 10); - unsigned int imm8 = bits (insn, 0, 7); - - return visitor->pc_relative_16bit (insn, data, rd, imm8); -} - -static int thumb_copy_pc_relative_32bit (uint16_t insn1, uint16_t insn2, struct arm_insn_reloc_data *data) { @@ -6783,101 +6757,6 @@ thumb_copy_pop_pc_16bit (uint16_t insn1, struct arm_insn_reloc_data *data) return 0; } -static int -thumb_16bit_relocate_insn (uint16_t insn1, - struct thumb_16bit_insn_reloc_visitor *visitor, - struct arm_insn_reloc_data *data) -{ - unsigned short op_bit_12_15 = bits (insn1, 12, 15); - unsigned short op_bit_10_11 = bits (insn1, 10, 11); - int err = 0; - - /* 16-bit thumb instructions. */ - switch (op_bit_12_15) - { - /* Shift (imme), add, subtract, move and compare. */ - case 0: case 1: case 2: case 3: - err = visitor->others (insn1, "shift/add/sub/mov/cmp", data); - break; - case 4: - switch (op_bit_10_11) - { - case 0: /* Data-processing */ - err = visitor->others (insn1, "data-processing", data); - break; - case 1: /* Special data instructions and branch and exchange. */ - { - unsigned short op = bits (insn1, 7, 9); - if (op == 6 || op == 7) /* BX or BLX */ - err = visitor->bx_blx_reg (insn1, data); - else if (bits (insn1, 6, 7) != 0) /* ADD/MOV/CMP high registers. */ - err = visitor->alu_reg (insn1, data); - else - err = visitor->others (insn1, "special data", data); - } - break; - default: /* LDR (literal) */ - err = visitor->load_literal (insn1, data); - } - break; - case 5: case 6: case 7: case 8: case 9: /* Load/Store single data item */ - err = visitor->others (insn1, "ldr/str", data); - break; - case 10: - if (op_bit_10_11 < 2) /* Generate PC-relative address */ - err = thumb_decode_pc_relative_16bit (insn1, visitor, data); - else /* Generate SP-relative address */ - err = visitor->others (insn1, "sp-relative", data); - break; - case 11: /* Misc 16-bit instructions */ - { - switch (bits (insn1, 8, 11)) - { - case 1: case 3: case 9: case 11: /* CBNZ, CBZ */ - err = visitor->cbnz_cbz (insn1, data); - break; - case 12: case 13: /* POP */ - if (bit (insn1, 8)) /* PC is in register list. */ - err = visitor->pop_pc_16bit (insn1, data); - else - err = visitor->others (insn1, "pop", data); - break; - case 15: /* If-Then, and hints */ - if (bits (insn1, 0, 3)) - /* If-Then makes up to four following instructions conditional. - IT instruction itself is not conditional, so handle it as a - common unmodified instruction. */ - err = visitor->others (insn1, "If-Then", data); - else - err = visitor->others (insn1, "hints", data); - break; - default: - err = visitor->others (insn1, "misc", data); - } - } - break; - case 12: - if (op_bit_10_11 < 2) /* Store multiple registers */ - err = visitor->others (insn1, "stm", data); - else /* Load multiple registers */ - err = visitor->others (insn1, "ldm", data); - break; - case 13: /* Conditional branch and supervisor call */ - if (bits (insn1, 9, 11) != 7) /* conditional branch */ - err = visitor->b (insn1, data); - else - err = visitor->svc (insn1, data); - break; - case 14: /* Unconditional branch */ - err = visitor->b (insn1, data); - break; - default: - err = 1; - } - - return err; -} - static struct arm_insn_reloc_visitor arm_insn_reloc_visitor = { arm_copy_alu_imm,