From patchwork Mon Oct 27 03:14:27 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Victor Kamensky X-Patchwork-Id: 3388 Received: (qmail 9133 invoked by alias); 27 Oct 2014 03:14:53 -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 8977 invoked by uid 89); 27 Oct 2014 03:14:52 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.5 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 X-HELO: mail-pa0-f45.google.com Received: from mail-pa0-f45.google.com (HELO mail-pa0-f45.google.com) (209.85.220.45) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-SHA encrypted) ESMTPS; Mon, 27 Oct 2014 03:14:50 +0000 Received: by mail-pa0-f45.google.com with SMTP id lf10so2127355pab.32 for ; Sun, 26 Oct 2014 20:14:49 -0700 (PDT) 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:date:message-id:in-reply-to :references; bh=OyOW8Cl3EPzEX9wpzZH9q1k4IHMmF05DmKKKqReM8ZE=; b=UI+1/47iR4usBwFbPVRlffCYAhpD35kWtUZbZgTQp6Q/M7hRmyr5ROzEeoafeHEyW4 B8eIHWCUiyixCYQlvf53v2aC6wori+XyDUWIlgTvAJTPqz076N0Y45jEzMwP4zBQNymu IQZCu7mmxMF1SQXSzOkU3INtoG1SYJmBS786Fl93DwjGasbil9EEYo0OBTQ+mXaXA6+z bSJvwN+gjFFzqvkNQgOQMe9roxy+iDMvoQP6I8RvBVEug/+0n1M8z6+6yA9Outy39ItH twSEpbETY7kKksrmrxxpO0vQgY0lm/8EA48kdK7r2aCHJzt9dIxeyLMWk9yE4oiXwUn5 tauQ== X-Gm-Message-State: ALoCoQkfbTf5tzVwrFr4OvR7q936h26mHuZGoISOdNfzsz2duxyDu5GITevlBusar8IOa0lVHBlF X-Received: by 10.70.49.40 with SMTP id r8mr21436584pdn.97.1414379689215; Sun, 26 Oct 2014 20:14:49 -0700 (PDT) Received: from kamensky-w530.cisco.com (128-107-239-233.cisco.com. [128.107.239.233]) by mx.google.com with ESMTPSA id te2sm2220682pbc.51.2014.10.26.20.14.47 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 26 Oct 2014 20:14:48 -0700 (PDT) From: Victor Kamensky To: gdb-patches@sourceware.org Cc: Yao Qi , Andrew Pinski , victor.kamensky@linaro.org Subject: [PATCH 1/2] aarch64: handle big endian float registers correctly Date: Sun, 26 Oct 2014 20:14:27 -0700 Message-Id: <1414379668-5351-2-git-send-email-victor.kamensky@linaro.org> In-Reply-To: <1414379668-5351-1-git-send-email-victor.kamensky@linaro.org> References: <1414379668-5351-1-git-send-email-victor.kamensky@linaro.org> In big endian case vreg memory is in big endian format and all pseudo registers will be in big endian format. But all smaller pseudo registers are at higher memory addresses (least siginificant part of vreg memory). Introduce reg_addr_in_vreg function would return correct address of pseudo register memory depending on current target endianity. aarch64_pseudo_read_value and aarch64_pseudo_write and other functions use that function to get address within vreg to copy into/from target pseudo register memory. That fixes numerous floating point gdb testsuite failures on aarch64 big endian target. For example gdb.base/structs.exp, gdb.base/float.exp, gdb.base/call-ar-st.exp and many others. gdb/ChangeLog: 2014-10-24 Victor Kamensky * aarch64-tdep.c (reg_addr_in_vreg): New function. (pass_in_v): Added type parameter. Use reg_addr_in_vreg to place memory in vreg depending on endianity and type size. (pass_in_v_or_stack): Pass type to pass_in_v function. (aarch64_push_dummy_call): Handle big endian case correctly. (aarch64_extract_return_value): Ditto. (aarch64_store_return_value): Ditto. (aarch64_pseudo_read_value): Ditto. (aarch64_pseudo_write): Ditto. --- gdb/aarch64-tdep.c | 57 ++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 36 insertions(+), 21 deletions(-) diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c index 1898f6b..959035e 100644 --- a/gdb/aarch64-tdep.c +++ b/gdb/aarch64-tdep.c @@ -1382,6 +1382,16 @@ pass_in_x (struct gdbarch *gdbarch, struct regcache *regcache, } } +static gdb_byte * reg_addr_in_vreg (struct gdbarch *gdbarch, + gdb_byte *vreg_addr, + size_t size) +{ + gdb_byte *ret = vreg_addr; + if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG) + ret = vreg_addr + (V_REGISTER_SIZE - size); + return ret; +} + /* Attempt to marshall a value in a V register. Return 1 if successful, or 0 if insufficient registers are available. This function, unlike the equivalent pass_in_x() function does not @@ -1391,17 +1401,21 @@ static int pass_in_v (struct gdbarch *gdbarch, struct regcache *regcache, struct aarch64_call_info *info, + struct type *type, const bfd_byte *buf) { if (info->nsrn < 8) { - enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); + bfd_byte xbuf[V_REGISTER_SIZE]; + int len = TYPE_LENGTH (type); + int copy_len = len > V_REGISTER_SIZE ? V_REGISTER_SIZE : len; int regnum = AARCH64_V0_REGNUM + info->nsrn; info->argnum++; info->nsrn++; - regcache_cooked_write (regcache, regnum, buf); + memcpy (reg_addr_in_vreg (gdbarch, xbuf, copy_len), buf, copy_len); + regcache_cooked_write (regcache, regnum, xbuf); if (aarch64_debug) fprintf_unfiltered (gdb_stdlog, "arg %d in %s\n", info->argnum, @@ -1491,7 +1505,7 @@ pass_in_v_or_stack (struct gdbarch *gdbarch, struct type *type, const bfd_byte *buf) { - if (!pass_in_v (gdbarch, regcache, info, buf)) + if (!pass_in_v (gdbarch, regcache, info, type, buf)) pass_on_stack (info, type, buf); } @@ -1616,8 +1630,8 @@ aarch64_push_dummy_call (struct gdbarch *gdbarch, struct value *function, struct type *target_type = check_typedef (TYPE_TARGET_TYPE (arg_type)); - pass_in_v (gdbarch, regcache, &info, buf); - pass_in_v (gdbarch, regcache, &info, + pass_in_v (gdbarch, regcache, &info, target_type, buf); + pass_in_v (gdbarch, regcache, &info, target_type, buf + TYPE_LENGTH (target_type)); } else @@ -1925,7 +1939,7 @@ aarch64_extract_return_value (struct type *type, struct regcache *regs, int len = TYPE_LENGTH (type); regcache_cooked_read (regs, AARCH64_V0_REGNUM, buf); - memcpy (valbuf, buf, len); + memcpy (valbuf, reg_addr_in_vreg (gdbarch, buf, len), len); } else if (TYPE_CODE (type) == TYPE_CODE_INT || TYPE_CODE (type) == TYPE_CODE_CHAR @@ -1961,10 +1975,10 @@ aarch64_extract_return_value (struct type *type, struct regcache *regs, int len = TYPE_LENGTH (target_type); regcache_cooked_read (regs, regno, buf); - memcpy (valbuf, buf, len); + memcpy (valbuf, reg_addr_in_vreg (gdbarch, buf, len), len); valbuf += len; regcache_cooked_read (regs, regno + 1, buf); - memcpy (valbuf, buf, len); + memcpy (valbuf, reg_addr_in_vreg (gdbarch, buf, len), len); valbuf += len; } else if (is_hfa (type)) @@ -1986,7 +2000,7 @@ aarch64_extract_return_value (struct type *type, struct regcache *regs, gdbarch_register_name (gdbarch, regno)); regcache_cooked_read (regs, regno, buf); - memcpy (valbuf, buf, len); + memcpy (valbuf, reg_addr_in_vreg (gdbarch, buf, len), len); valbuf += len; } } @@ -2058,8 +2072,9 @@ aarch64_store_return_value (struct type *type, struct regcache *regs, { bfd_byte buf[V_REGISTER_SIZE]; int len = TYPE_LENGTH (type); + int copy_len = len > V_REGISTER_SIZE ? V_REGISTER_SIZE : len; - memcpy (buf, valbuf, len > V_REGISTER_SIZE ? V_REGISTER_SIZE : len); + memcpy (reg_addr_in_vreg (gdbarch, buf, copy_len), valbuf, copy_len); regcache_cooked_write (regs, AARCH64_V0_REGNUM, buf); } else if (TYPE_CODE (type) == TYPE_CODE_INT @@ -2113,7 +2128,7 @@ aarch64_store_return_value (struct type *type, struct regcache *regs, i + 1, gdbarch_register_name (gdbarch, regno)); - memcpy (tmpbuf, valbuf, len); + memcpy (reg_addr_in_vreg (gdbarch, tmpbuf, len), valbuf, len); regcache_cooked_write (regs, regno, tmpbuf); valbuf += len; } @@ -2360,7 +2375,7 @@ aarch64_pseudo_read_value (struct gdbarch *gdbarch, mark_value_bytes_unavailable (result_value, 0, TYPE_LENGTH (value_type (result_value))); else - memcpy (buf, reg_buf, Q_REGISTER_SIZE); + memcpy (buf, reg_addr_in_vreg (gdbarch, reg_buf, Q_REGISTER_SIZE), Q_REGISTER_SIZE); return result_value; } @@ -2375,7 +2390,7 @@ aarch64_pseudo_read_value (struct gdbarch *gdbarch, mark_value_bytes_unavailable (result_value, 0, TYPE_LENGTH (value_type (result_value))); else - memcpy (buf, reg_buf, D_REGISTER_SIZE); + memcpy (buf, reg_addr_in_vreg (gdbarch, reg_buf, D_REGISTER_SIZE), D_REGISTER_SIZE); return result_value; } @@ -2386,7 +2401,7 @@ aarch64_pseudo_read_value (struct gdbarch *gdbarch, v_regnum = AARCH64_V0_REGNUM + regnum - AARCH64_S0_REGNUM; status = regcache_raw_read (regcache, v_regnum, reg_buf); - memcpy (buf, reg_buf, S_REGISTER_SIZE); + memcpy (buf, reg_addr_in_vreg (gdbarch, reg_buf, S_REGISTER_SIZE), S_REGISTER_SIZE); return result_value; } @@ -2401,7 +2416,7 @@ aarch64_pseudo_read_value (struct gdbarch *gdbarch, mark_value_bytes_unavailable (result_value, 0, TYPE_LENGTH (value_type (result_value))); else - memcpy (buf, reg_buf, H_REGISTER_SIZE); + memcpy (buf, reg_addr_in_vreg (gdbarch, reg_buf, H_REGISTER_SIZE), H_REGISTER_SIZE); return result_value; } @@ -2416,7 +2431,7 @@ aarch64_pseudo_read_value (struct gdbarch *gdbarch, mark_value_bytes_unavailable (result_value, 0, TYPE_LENGTH (value_type (result_value))); else - memcpy (buf, reg_buf, B_REGISTER_SIZE); + memcpy (buf, reg_addr_in_vreg (gdbarch, reg_buf, B_REGISTER_SIZE), B_REGISTER_SIZE); return result_value; } @@ -2445,7 +2460,7 @@ aarch64_pseudo_write (struct gdbarch *gdbarch, struct regcache *regcache, unsigned v_regnum; v_regnum = AARCH64_V0_REGNUM + regnum - AARCH64_Q0_REGNUM; - memcpy (reg_buf, buf, Q_REGISTER_SIZE); + memcpy (reg_addr_in_vreg (gdbarch, reg_buf, Q_REGISTER_SIZE), buf, Q_REGISTER_SIZE); regcache_raw_write (regcache, v_regnum, reg_buf); return; } @@ -2456,7 +2471,7 @@ aarch64_pseudo_write (struct gdbarch *gdbarch, struct regcache *regcache, unsigned v_regnum; v_regnum = AARCH64_V0_REGNUM + regnum - AARCH64_D0_REGNUM; - memcpy (reg_buf, buf, D_REGISTER_SIZE); + memcpy (reg_addr_in_vreg (gdbarch, reg_buf, D_REGISTER_SIZE), buf, D_REGISTER_SIZE); regcache_raw_write (regcache, v_regnum, reg_buf); return; } @@ -2466,7 +2481,7 @@ aarch64_pseudo_write (struct gdbarch *gdbarch, struct regcache *regcache, unsigned v_regnum; v_regnum = AARCH64_V0_REGNUM + regnum - AARCH64_S0_REGNUM; - memcpy (reg_buf, buf, S_REGISTER_SIZE); + memcpy (reg_addr_in_vreg (gdbarch, reg_buf, S_REGISTER_SIZE), buf, S_REGISTER_SIZE); regcache_raw_write (regcache, v_regnum, reg_buf); return; } @@ -2477,7 +2492,7 @@ aarch64_pseudo_write (struct gdbarch *gdbarch, struct regcache *regcache, unsigned v_regnum; v_regnum = AARCH64_V0_REGNUM + regnum - AARCH64_H0_REGNUM; - memcpy (reg_buf, buf, H_REGISTER_SIZE); + memcpy (reg_addr_in_vreg (gdbarch, reg_buf, H_REGISTER_SIZE), buf, H_REGISTER_SIZE); regcache_raw_write (regcache, v_regnum, reg_buf); return; } @@ -2488,7 +2503,7 @@ aarch64_pseudo_write (struct gdbarch *gdbarch, struct regcache *regcache, unsigned v_regnum; v_regnum = AARCH64_V0_REGNUM + regnum - AARCH64_B0_REGNUM; - memcpy (reg_buf, buf, B_REGISTER_SIZE); + memcpy (reg_addr_in_vreg (gdbarch, reg_buf, B_REGISTER_SIZE), buf, B_REGISTER_SIZE); regcache_raw_write (regcache, v_regnum, reg_buf); return; }