From patchwork Tue Dec 19 11:24:38 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: YunQiang Su X-Patchwork-Id: 10123489 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 48A85602CB for ; Tue, 19 Dec 2017 15:40:53 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3A1CE28BB3 for ; Tue, 19 Dec 2017 15:40:53 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 2EEDC29384; Tue, 19 Dec 2017 15:40:53 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 6E2FB28BB3 for ; Tue, 19 Dec 2017 15:40:52 +0000 (UTC) Received: from localhost ([::1]:50338 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eRK0h-0004qw-Ei for patchwork-qemu-devel@patchwork.kernel.org; Tue, 19 Dec 2017 10:40:51 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43791) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eRG11-0006El-5i for qemu-devel@nongnu.org; Tue, 19 Dec 2017 06:24:56 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eRG0x-0000F3-7J for qemu-devel@nongnu.org; Tue, 19 Dec 2017 06:24:55 -0500 Received: from mail-pg0-x241.google.com ([2607:f8b0:400e:c05::241]:41990) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eRG0w-0000Ea-UI for qemu-devel@nongnu.org; Tue, 19 Dec 2017 06:24:51 -0500 Received: by mail-pg0-x241.google.com with SMTP id q67so1187032pga.9 for ; Tue, 19 Dec 2017 03:24:50 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id; bh=u/cnlCA3FWIi+d8SETCdI8MbzhZ3Y9mHwmemZ84901I=; b=iv4C5mNmdXPYtfG3zM0WAWtn2+LppP0NFLzbcVdw+VNjLrc27X7sV4hRj3FwvY8T3D KxSaWVnCAsHM3fT6chRASvm/vPLU6WpxRvlYHl363cJlagX4LlRsvxVaLwjF5qMV1tkS JbOdRQn+2K+Hfl0TF+5MQA/y/ZY1BbbhfUi4/WuWIr8NHbL6vj/DwlJfBujIIZX4UWwl GwQKeyyxBsbTXW0QS7GBqG3sXqljKoOJ65HNWwFP2hXmnJDhpNfWGzlfyNPELaaFMUaZ RiZ8SpMOlraAG08YjYMEI7IFZoJGUFx8M4o0q4jq3aTh15DiMNN05sywV6yFyBVVFh2D pdvw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id; bh=u/cnlCA3FWIi+d8SETCdI8MbzhZ3Y9mHwmemZ84901I=; b=BkM5umn3lqj5AGa73JXC3BQnjIxa7qnjx7ORo3377sOPzarz9ghrzJ5Ui8irmqbaHW PrrjQlwzWriXMLER3sBIg5kg3uQEeVM5+4TVk703gShqyAxebdLnmnsexm4W1DKjTpko dgzNr0we4JctTjOTSixnLBIcRp+PYuKFAxPPbCf2Wenpwm5IoljhpCEUmjAxc6eZ7rOb 6o12+66+eJJGSWF6HOEHnR6S7Wd36U6tAgTTSFNfmKN20VQUrNuC4zACpZ5NmCd4RWJz 7ktV92zbebW1HFfzwhVtgA6AQ6JnMhCTw9HEUjDTpjVwtYVwcuPBCy0lFNDGTFOyHIqP XAuw== X-Gm-Message-State: AKGB3mJ+mWlPgbOD7b7dv6qo+/4wJdRoiWfIT2KyQegFGunvcdSBcVDq U2EdXcFQ/pbCOgXOJQFDcBsIBxks X-Google-Smtp-Source: ACJfBovSrLmKjl5SCKqKH1m1vE/GwMogIRfYU2BLlfJaUZll/8iKen+DVGVw4XMBxGbpFygVIWbwwQ== X-Received: by 10.98.64.153 with SMTP id f25mr2930248pfd.213.1513682689504; Tue, 19 Dec 2017 03:24:49 -0800 (PST) Received: from loongson.vpn2.bfsu.edu.cn ([103.88.45.229]) by smtp.gmail.com with ESMTPSA id f10sm2251542pgr.36.2017.12.19.03.24.47 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 19 Dec 2017 03:24:48 -0800 (PST) From: YunQiang Su To: qemu-devel@nongnu.org Date: Tue, 19 Dec 2017 19:24:38 +0800 Message-Id: <20171219112438.6065-1-syq@debian.org> X-Mailer: git-send-email 2.15.1 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:400e:c05::241 X-Mailman-Approved-At: Tue, 19 Dec 2017 10:38:10 -0500 Subject: [Qemu-devel] [PATCH] linux-user: Fix support MIPS o32 FP64 mode X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: YunQiang Su Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP MIPS o32 has a mode called FP64, who has 32 64Bit FPU registers. To use it: add PR_GET_FP_MODE and PR_SET_FP_MODE options for prctl set CP0St_FR when binary as EF_MIPS_FP64 https://dmz-portal.mips.com/wiki/MIPS_O32_ABI_-_FR0_and_FR1_Interlinking Signed-off-by: YunQiang Su --- linux-user/main.c | 3 +++ linux-user/syscall.c | 24 +++++++++++++++++++++ target/mips/cpu.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++ target/mips/cpu.h | 9 ++++++++ 4 files changed, 95 insertions(+) diff --git a/linux-user/main.c b/linux-user/main.c index 2fd2a143ed..f2b02a99a2 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -4750,6 +4750,9 @@ int main(int argc, char **argv, char **envp) } restore_snan_bit_mode(env); } + if ((info->elf_flags & EF_MIPS_FP64) != 0) { + env->CP0_Status |= (1 << CP0St_FR); + } } #elif defined(TARGET_NIOS2) { diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 11c9116c4a..664dacda33 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -10530,6 +10530,30 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, * need. */ ret = -TARGET_EINVAL; break; +#ifdef TARGET_MIPS + case PR_GET_FP_MODE: + { + CPUMIPSState *env = ((CPUMIPSState *)cpu_env); + ret = 0; + if (env->CP0_Status & (1 << CP0St_FR)) { + ret |= PR_FP_MODE_FR; + } + if (env->CP0_Config5 & (1 << CP0C5_FRE)) { + ret |= PR_FP_MODE_FRE; + } + break; + } + case PR_SET_FP_MODE: + { + CPUMIPSState *env = ((CPUMIPSState *)cpu_env); + ret = mips_prctl_set_fp_mode(env, arg2); + if (ret < 0) { + ret = -TARGET_EOPNOTSUPP; + goto fail; + } + break; + } +#endif default: /* Most prctl options have no pointer arguments */ ret = get_errno(prctl(arg1, arg2, arg3, arg4, arg5)); diff --git a/target/mips/cpu.c b/target/mips/cpu.c index 069f93560e..6cf1907f9c 100644 --- a/target/mips/cpu.c +++ b/target/mips/cpu.c @@ -246,4 +246,63 @@ static void mips_cpu_register_types(void) } } +#ifdef CONFIG_USER_ONLY +abi_long mips_prctl_set_fp_mode(CPUMIPSState *env, abi_long arg2) +{ + abi_long ret; + CPUState *other_cpu; + bool old_fr = env->CP0_Status & (1 << CP0St_FR); + bool new_fr = arg2 & PR_FP_MODE_FR; + bool new_fre = arg2 & PR_FP_MODE_FRE; + + if (new_fr && !(env->active_fpu.fcr0 & (1 << FCR0_F64))) { + /* FR1 is not supported */ + ret = -1; + return ret; + } + + if (!new_fr && (env->active_fpu.fcr0 & (1 << FCR0_F64)) + && !(env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) { + /* cannot set FR=0 */ + ret = -1; + return ret; + } + + if (new_fre && !(env->active_fpu.fcr0 & (1 << FCR0_FREP))) { + /* Cannot set FRE=1 */ + ret = -1; + return ret; + } + + start_exclusive(); + CPU_FOREACH(other_cpu) { + int i; + MIPSCPU *cpu = MIPS_CPU(other_cpu); + env = &cpu->env; + for (i = 0; i < 32 ; i += 2) { + fpr_t *fpr = env->active_fpu.fpr; + if (!old_fr && new_fr) { + fpr[i].w[!FP_ENDIAN_IDX] = fpr[i + 1].w[FP_ENDIAN_IDX]; + } else if (old_fr && !new_fr) { + fpr[i + 1].w[FP_ENDIAN_IDX] = fpr[i].w[!FP_ENDIAN_IDX]; + } + } + if (new_fr) { + env->CP0_Status |= (1 << CP0St_FR); + } else { + env->CP0_Status &= ~(1 << CP0St_FR); + } + if (new_fre) { + env->CP0_Config5 |= (1 << CP0C5_FRE); + } else { + env->CP0_Config5 &= ~(1 << CP0C5_FRE); + } + compute_hflags(env); + } + end_exclusive(); + ret = 0; + return ret; +} +#endif + type_init(mips_cpu_register_types) diff --git a/target/mips/cpu.h b/target/mips/cpu.h index 7f8ba5ff3e..b5d9aac6d0 100644 --- a/target/mips/cpu.h +++ b/target/mips/cpu.h @@ -769,4 +769,13 @@ static inline void cpu_get_tb_cpu_state(CPUMIPSState *env, target_ulong *pc, MIPS_HFLAG_HWRENA_ULR); } +/* prctl interface. */ +#if defined(CONFIG_USER_ONLY) +#define PR_SET_FP_MODE 45 +#define PR_GET_FP_MODE 46 +#define PR_FP_MODE_FR (1 << 0) +#define PR_FP_MODE_FRE (1 << 1) +abi_long mips_prctl_set_fp_mode(CPUMIPSState *env, abi_long arg2); +#endif + #endif /* MIPS_CPU_H */