From patchwork Wed Oct 14 11:14:29 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: henrik.wallin@windriver.com X-Patchwork-Id: 9112 Received: (qmail 89426 invoked by alias); 14 Oct 2015 15:08:07 -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 89362 invoked by uid 89); 14 Oct 2015 15:08:07 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=0.6 required=5.0 tests=AWL, BAYES_40, KAM_LAZY_DOMAIN_SECURITY, T_RP_MATCHES_RCVD autolearn=no version=3.3.2 X-HELO: mail.windriver.com Received: from mail.windriver.com (HELO mail.windriver.com) (147.11.1.11) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-SHA encrypted) ESMTPS; Wed, 14 Oct 2015 15:08:04 +0000 Received: from arn-build2.wrs.com (arn-build2.wrs.com [128.224.95.15]) by mail.windriver.com (8.15.2/8.15.1) with ESMTP id t9EBEZS3010723 for ; Wed, 14 Oct 2015 04:14:35 -0700 (PDT) Received: by arn-build2.wrs.com (Postfix, from userid 18580) id EEF9D220BA4; Wed, 14 Oct 2015 13:14:33 +0200 (CEST) From: henrik.wallin@windriver.com To: gdb-patches@sourceware.org Subject: [RFC][PATCH 11/15] gdbserver: Add helper functions to create arm instructions Date: Wed, 14 Oct 2015 13:14:29 +0200 Message-Id: <2bdf7fa13db6d0b92a727eeff8d01b74bd200229.1444820235.git.henrik.wallin@windriver.com> In-Reply-To: References: In-Reply-To: References: From: Henrik Wallin This adds the function. No users yet. gdb/gdbserver/ChangeLog: * linux-arm-low.c : Add code generation helpers Signed-off-by: Henrik Wallin --- gdb/gdbserver/linux-arm-low.c | 135 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 135 insertions(+) diff --git a/gdb/gdbserver/linux-arm-low.c b/gdb/gdbserver/linux-arm-low.c index 81d23d953434..044e7527a3b0 100644 --- a/gdb/gdbserver/linux-arm-low.c +++ b/gdb/gdbserver/linux-arm-low.c @@ -20,6 +20,7 @@ #include "linux-low.h" #include "arch/arm.h" #include "linux-aarch32-low.h" +#include #include /* Don't include elf.h if linux/elf.h got included by gdb_proc_service.h. @@ -916,6 +917,140 @@ arm_regs_info (void) return ®s_info_arm; } +static uint32_t +mk_t_b_rel (CORE_ADDR from, CORE_ADDR to) +{ + uint32_t from_ = ((uint32_t) from) & ~1; + uint32_t to_ = ((uint32_t) to) & ~1; + return to_ - from_ - 4; +} + +static int +mk_t_b_isreachable (CORE_ADDR from, CORE_ADDR to) +{ + int32_t rel = mk_t_b_rel (from, to); + rel >>= 24; + return !rel || !(rel + 1); +} + +static uint16_t * +mk_t_b_instr (uint16_t *mem, CORE_ADDR from, CORE_ADDR to) +{ + uint32_t imm10, imm11; + uint32_t s, j1, j2; + uint32_t rel; + + rel = mk_t_b_rel (from, to); + rel >>= 1; + + imm11 = rel & 0x7ff; + rel >>= 11; + imm10 = rel & 0x3ff; + rel >>= 10; + s = (rel > 3); + j1 = s ^ !(rel & 2); + j2 = s ^ !(rel & 1); + + *mem++ = 0xF000 | (s << 10) | imm10; + *mem++ = 0x9000 | (j1 << 13) | (j2 << 11) | imm11; + + return mem; +} + +static uint16_t * +mk_t_blx_instr (uint16_t *mem, int reg) +{ + reg &= 0xF; + *mem++ = 0x4780 | (reg << 3); + return mem; +} + +static uint16_t * +mk_t_load_instr (uint16_t *mem, int reg, uint32_t val) +{ + uint32_t imm4, imm3, imm8; + uint32_t i; + + imm8 = val & 0x00FF; + val >>= 8; + imm3 = val & 0x0007; + val >>= 3; + i = val & 0x0001; + val >>= 1; + imm4 = val & 0x000F; + val >>= 4; + + *mem++ = 0xF240 | (i << 10) | imm4; + *mem++ = 0x0000 | (imm3 << 12) | (reg << 8) | imm8; + + imm8 = val & 0x00FF; + val >>= 8; + imm3 = val & 0x0007; + val >>= 3; + i = val & 0x0001; + val >>= 1; + imm4 = val & 0x000F; + + *mem++ = 0xF2C0 | (i << 10) | imm4; + *mem++ = 0x0000 | (imm3 << 12) | (reg << 8) | imm8; + + return mem; +} + +static uint32_t +mk_a_b_rel (CORE_ADDR from, CORE_ADDR to) +{ + return (uint32_t) to - (uint32_t) from - 8; +} + +static int +mk_a_b_isreachable (CORE_ADDR from, CORE_ADDR to) +{ + int32_t rel = mk_a_b_rel (from, to); + rel >>= 25; + return !rel || !(rel + 1); +} + +static uint32_t * +mk_a_b_instr (uint32_t *mem, CORE_ADDR from, CORE_ADDR to) +{ + uint32_t imm24 = mk_a_b_rel (from, to); + + imm24 >>= 2; + imm24 &= 0x00FFFFFF; + *mem++ = 0xEA000000 | imm24; + + return mem; +} + +static uint32_t * +mk_a_blx_instr (uint32_t *mem, int reg) +{ + *mem++ = 0xE12FFF30 | (reg & 0xF); + return mem; +} + +static uint32_t * +mk_a_load_instr (uint32_t *mem, int reg, uint32_t val) +{ + uint32_t imm4, imm12; + + imm12 = val & 0x0FFF; + val >>= 12; + imm4 = val & 0xF; + val >>= 4; + + *mem++ = 0xE3000000 | ((reg & 0xF) << 12) | (imm4 << 16) | imm12; + + imm12 = val & 0x0FFF; + val >>= 12; + imm4 = val & 0xF; + + *mem++ = 0xE3400000 | ((reg & 0xF) << 12) | (imm4 << 16) | imm12; + + return mem; +} + struct linux_target_ops the_low_target = { arm_arch_setup, arm_regs_info,