From patchwork Sat Dec 28 21:49:05 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 22771 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-pa0-f71.google.com (mail-pa0-f71.google.com [209.85.220.71]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 02BA0202E4 for ; Sat, 28 Dec 2013 21:56:54 +0000 (UTC) Received: by mail-pa0-f71.google.com with SMTP id kp14sf27075063pab.6 for ; Sat, 28 Dec 2013 13:56:54 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:delivered-to:from:to:cc:subject :date:message-id:in-reply-to:references:x-original-sender :x-original-authentication-results:precedence:mailing-list:list-id :list-post:list-help:list-archive:list-unsubscribe; bh=aBpIL35SLQyhgqE4r53POBvZTc+ccayG+vzzSEjITrY=; b=N8zLJN0k97nlsEWVrn2ClKmKwM2KdGB4HsVUtxAAqGpfIduH6oyDHI3T9gFUxMzkuN 2okhaf+cOsUEYJq12M57SbDcxU+smvS8ZUdLUbdcjt1PtbSdjT0hWnFXO4Yjm56jvZfJ 31Fu2ZTUa1wF5L0qJjVr8yL0RLGPBJyGTYUUSRG0jzsyysT0A+9nXhnmtmYLbQZ9/zyW lQ2+frdux4EfYJkMKRJfR8M4HmOlFMY77aN2zvGZ1PnWARVwcaMac4bSvsVGFo3XMQp8 ol8U1P0m6yZDKry4G2REXK4zK9Gtb5g1BnKs5e9hDRtDjN8ejP1cUqwBvxGBklRVqL6X nXWg== X-Gm-Message-State: ALoCoQkOYgzj9recNhGIesNuHAaHik+wdQWbRUBxPnvvK5Hv2f6JfLzR+UpyAJz+QgrXcHCzUN+B X-Received: by 10.66.189.163 with SMTP id gj3mr22640982pac.32.1388267813874; Sat, 28 Dec 2013 13:56:53 -0800 (PST) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.49.17.103 with SMTP id n7ls3307385qed.52.gmail; Sat, 28 Dec 2013 13:56:53 -0800 (PST) X-Received: by 10.58.133.193 with SMTP id pe1mr118190veb.58.1388267813687; Sat, 28 Dec 2013 13:56:53 -0800 (PST) Received: from mail-ve0-f170.google.com (mail-ve0-f170.google.com [209.85.128.170]) by mx.google.com with ESMTPS id gx6si13799828vdc.128.2013.12.28.13.56.53 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Sat, 28 Dec 2013 13:56:53 -0800 (PST) Received-SPF: neutral (google.com: 209.85.128.170 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) client-ip=209.85.128.170; Received: by mail-ve0-f170.google.com with SMTP id oy12so5495656veb.29 for ; Sat, 28 Dec 2013 13:56:53 -0800 (PST) X-Received: by 10.52.181.4 with SMTP id ds4mr102394vdc.51.1388267813596; Sat, 28 Dec 2013 13:56:53 -0800 (PST) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patches@linaro.org Received: by 10.59.13.131 with SMTP id ey3csp529505ved; Sat, 28 Dec 2013 13:56:53 -0800 (PST) X-Received: by 10.194.185.205 with SMTP id fe13mr7944396wjc.23.1388267812509; Sat, 28 Dec 2013 13:56:52 -0800 (PST) Received: from mnementh.archaic.org.uk (mnementh.archaic.org.uk. [2001:8b0:1d0::1]) by mx.google.com with ESMTPS id t3si250922wiz.40.2013.12.28.13.56.50 for (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Sat, 28 Dec 2013 13:56:52 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::1 as permitted sender) client-ip=2001:8b0:1d0::1; Received: from pm215 by mnementh.archaic.org.uk with local (Exim 4.80) (envelope-from ) id 1Vx1kt-0008Hv-B1; Sat, 28 Dec 2013 21:49:11 +0000 From: Peter Maydell To: qemu-devel@nongnu.org Cc: patches@linaro.org, Alexander Graf , Michael Matz , Claudio Fontana , Dirk Mueller , Laurent Desnogues , kvmarm@lists.cs.columbia.edu, Richard Henderson , =?UTF-8?q?Alex=20Benn=C3=A9e?= , Christoffer Dall , Will Newton Subject: [PATCH 04/10] target-arm: A64: Add "Floating-point data-processing (2 source)" insns Date: Sat, 28 Dec 2013 21:49:05 +0000 Message-Id: <1388267351-31818-5-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1388267351-31818-1-git-send-email-peter.maydell@linaro.org> References: <1388267351-31818-1-git-send-email-peter.maydell@linaro.org> X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: peter.maydell@linaro.org X-Original-Authentication-Results: mx.google.com; spf=neutral (google.com: 209.85.128.170 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Precedence: list Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org List-ID: X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , From: Alexander Graf This patch adds emulation for the "Floating-point data-processing (2 source)" group of instructions. Signed-off-by: Alexander Graf [WN: Commit message tweak, merge single and double precision patches. Rebase and update to new infrastructure. Incorporate FMIN/FMAX support patch by Michael Matz.] Signed-off-by: Will Newton [PMM: * added convenience accessors for FP s and d regs * pulled the field decode and opcode validity check up a level] Signed-off-by: Peter Maydell --- target-arm/translate-a64.c | 182 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 181 insertions(+), 1 deletion(-) diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c index c3fc503..49ed2d8 100644 --- a/target-arm/translate-a64.c +++ b/target-arm/translate-a64.c @@ -328,6 +328,60 @@ static inline int fp_reg_hi_offset(int regno) return offsetof(CPUARMState, vfp.regs[regno * 2 + 1]); } +/* Convenience accessors for reading and writing single and double + * FP registers. Writing clears the upper parts of the associated + * 128 bit vector register, as required by the architecture. + * Note that unlike the GP register accessors, the values returned + * by the read functions must be manually freed. + */ +static TCGv_i64 read_fp_dreg(DisasContext *s, int reg) +{ + TCGv_i64 v = tcg_temp_new_i64(); + + tcg_gen_ld_i64(v, cpu_env, fp_reg_offset(reg, MO_64)); + return v; +} + +static TCGv_i32 read_fp_sreg(DisasContext *s, int reg) +{ + TCGv_i32 v = tcg_temp_new_i32(); + + tcg_gen_ld_i32(v, cpu_env, fp_reg_offset(reg, MO_32)); + return v; +} + +static void write_fp_dreg(DisasContext *s, int reg, TCGv_i64 v) +{ + TCGv_i64 tcg_zero = tcg_const_i64(0); + + tcg_gen_st_i64(v, cpu_env, fp_reg_offset(reg, MO_64)); + tcg_gen_st_i64(tcg_zero, cpu_env, fp_reg_hi_offset(reg)); + tcg_temp_free_i64(tcg_zero); +} + +static void write_fp_sreg(DisasContext *s, int reg, TCGv_i32 v) +{ + TCGv_i64 tmp = tcg_temp_new_i64(); + + tcg_gen_extu_i32_i64(tmp, v); + write_fp_dreg(s, reg, tmp); + tcg_temp_free_i64(tmp); +} + +static TCGv_ptr get_fpstatus_ptr(void) +{ + TCGv_ptr statusptr = tcg_temp_new_ptr(); + int offset; + + /* In A64 all instructions (both FP and Neon) use the FPCR; + * there is no equivalent of the A32 Neon "standard FPSCR value" + * and all operations use vfp.fp_status. + */ + offset = offsetof(CPUARMState, vfp.fp_status); + tcg_gen_addi_ptr(statusptr, cpu_env, offset); + return statusptr; +} + /* Set ZF and NF based on a 64 bit result. This is alas fiddlier * than the 32 bit equivalent. */ @@ -3191,6 +3245,112 @@ static void disas_fp_1src(DisasContext *s, uint32_t insn) unsupported_encoding(s, insn); } +/* C3.6.26 Floating-point data-processing (2 source) - single precision */ +static void handle_fp_2src_single(DisasContext *s, int opcode, + int rd, int rn, int rm) +{ + TCGv_i32 tcg_op1; + TCGv_i32 tcg_op2; + TCGv_i32 tcg_res; + TCGv_ptr fpst; + + tcg_res = tcg_temp_new_i32(); + fpst = get_fpstatus_ptr(); + tcg_op1 = read_fp_sreg(s, rn); + tcg_op2 = read_fp_sreg(s, rm); + + switch (opcode) { + case 0x0: /* FMUL */ + gen_helper_vfp_muls(tcg_res, tcg_op1, tcg_op2, fpst); + break; + case 0x1: /* FDIV */ + gen_helper_vfp_divs(tcg_res, tcg_op1, tcg_op2, fpst); + break; + case 0x2: /* FADD */ + gen_helper_vfp_adds(tcg_res, tcg_op1, tcg_op2, fpst); + break; + case 0x3: /* FSUB */ + gen_helper_vfp_subs(tcg_res, tcg_op1, tcg_op2, fpst); + break; + case 0x4: /* FMAX */ + gen_helper_vfp_maxs(tcg_res, tcg_op1, tcg_op2, fpst); + break; + case 0x5: /* FMIN */ + gen_helper_vfp_mins(tcg_res, tcg_op1, tcg_op2, fpst); + break; + case 0x6: /* FMAXNM */ + gen_helper_vfp_maxnums(tcg_res, tcg_op1, tcg_op2, fpst); + break; + case 0x7: /* FMINNM */ + gen_helper_vfp_minnums(tcg_res, tcg_op1, tcg_op2, fpst); + break; + case 0x8: /* FNMUL */ + gen_helper_vfp_muls(tcg_res, tcg_op1, tcg_op2, fpst); + gen_helper_vfp_negs(tcg_res, tcg_res); + break; + } + + write_fp_sreg(s, rd, tcg_res); + + tcg_temp_free_ptr(fpst); + tcg_temp_free_i32(tcg_op1); + tcg_temp_free_i32(tcg_op2); + tcg_temp_free_i32(tcg_res); +} + +/* C3.6.26 Floating-point data-processing (2 source) - double precision */ +static void handle_fp_2src_double(DisasContext *s, int opcode, + int rd, int rn, int rm) +{ + TCGv_i64 tcg_op1; + TCGv_i64 tcg_op2; + TCGv_i64 tcg_res; + TCGv_ptr fpst; + + tcg_res = tcg_temp_new_i64(); + fpst = get_fpstatus_ptr(); + tcg_op1 = read_fp_dreg(s, rn); + tcg_op2 = read_fp_dreg(s, rm); + + switch (opcode) { + case 0x0: /* FMUL */ + gen_helper_vfp_muld(tcg_res, tcg_op1, tcg_op2, fpst); + break; + case 0x1: /* FDIV */ + gen_helper_vfp_divd(tcg_res, tcg_op1, tcg_op2, fpst); + break; + case 0x2: /* FADD */ + gen_helper_vfp_addd(tcg_res, tcg_op1, tcg_op2, fpst); + break; + case 0x3: /* FSUB */ + gen_helper_vfp_subd(tcg_res, tcg_op1, tcg_op2, fpst); + break; + case 0x4: /* FMAX */ + gen_helper_vfp_maxd(tcg_res, tcg_op1, tcg_op2, fpst); + break; + case 0x5: /* FMIN */ + gen_helper_vfp_mind(tcg_res, tcg_op1, tcg_op2, fpst); + break; + case 0x6: /* FMAXNM */ + gen_helper_vfp_maxnumd(tcg_res, tcg_op1, tcg_op2, fpst); + break; + case 0x7: /* FMINNM */ + gen_helper_vfp_minnumd(tcg_res, tcg_op1, tcg_op2, fpst); + break; + case 0x8: /* FNMUL */ + gen_helper_vfp_muld(tcg_res, tcg_op1, tcg_op2, fpst); + gen_helper_vfp_negd(tcg_res, tcg_res); + break; + } + + write_fp_dreg(s, rd, tcg_res); + + tcg_temp_free_ptr(fpst); + tcg_temp_free_i64(tcg_op1); + tcg_temp_free_i64(tcg_op2); + tcg_temp_free_i64(tcg_res); +} + /* C3.6.26 Floating point data-processing (2 source) * 31 30 29 28 24 23 22 21 20 16 15 12 11 10 9 5 4 0 * +---+---+---+-----------+------+---+------+--------+-----+------+------+ @@ -3199,7 +3359,27 @@ static void disas_fp_1src(DisasContext *s, uint32_t insn) */ static void disas_fp_2src(DisasContext *s, uint32_t insn) { - unsupported_encoding(s, insn); + int type = extract32(insn, 22, 2); + int rd = extract32(insn, 0, 5); + int rn = extract32(insn, 5, 5); + int rm = extract32(insn, 16, 5); + int opcode = extract32(insn, 12, 4); + + if (opcode > 8) { + unallocated_encoding(s); + return; + } + + switch (type) { + case 0: + handle_fp_2src_single(s, opcode, rd, rn, rm); + break; + case 1: + handle_fp_2src_double(s, opcode, rd, rn, rm); + break; + default: + unallocated_encoding(s); + } } /* C3.6.27 Floating point data-processing (3 source)