From patchwork Fri Nov 19 06:13:05 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: gaosong X-Patchwork-Id: 1556924 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4HwRgG0KLSz9sPf for ; Fri, 19 Nov 2021 17:32:58 +1100 (AEDT) Received: from localhost ([::1]:39802 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mnxSA-00059m-M6 for incoming@patchwork.ozlabs.org; Fri, 19 Nov 2021 01:32:54 -0500 Received: from eggs.gnu.org ([209.51.188.92]:46272) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mnx9i-0003rm-CU for qemu-devel@nongnu.org; Fri, 19 Nov 2021 01:13:50 -0500 Received: from mail.loongson.cn ([114.242.206.163]:46520 helo=loongson.cn) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mnx9Z-0004WX-J4 for qemu-devel@nongnu.org; Fri, 19 Nov 2021 01:13:47 -0500 Received: from kvm-dev1.localdomain (unknown [10.2.5.134]) by mail.loongson.cn (Coremail) with SMTP id AQAAf9Dxj8+KQJdhSG0AAA--.1952S3; Fri, 19 Nov 2021 14:13:34 +0800 (CST) From: Song Gao To: qemu-devel@nongnu.org Subject: [PATCH v11 01/26] target/loongarch: Add README Date: Fri, 19 Nov 2021 14:13:05 +0800 Message-Id: <1637302410-24632-2-git-send-email-gaosong@loongson.cn> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1637302410-24632-1-git-send-email-gaosong@loongson.cn> References: <1637302410-24632-1-git-send-email-gaosong@loongson.cn> X-CM-TRANSID: AQAAf9Dxj8+KQJdhSG0AAA--.1952S3 X-Coremail-Antispam: 1UD129KBjvJXoWxXrWUGr1xCw4rKr1DKF4Durg_yoW5tF1xpF 1fuFyfKrWUX3sxtrnag34fWFnYyr4fGr1xWanIkw1rC3sxtryq9w1rta4IqFy7Xwn5trWv vrykCw1UWa1UCa7anT9S1TB71UUUUUUqnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnUUvcSsGvfC2KfnxnUUI43ZEXa7xR_UUUUUUUUU== X-CM-SenderInfo: 5jdr20tqj6z05rqj20fqof0/ Received-SPF: pass client-ip=114.242.206.163; envelope-from=gaosong@loongson.cn; helo=loongson.cn X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Xiaojuan Yang , richard.henderson@linaro.org, laurent@vivier.eu Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" This patch gives an introduction to the LoongArch target. Signed-off-by: Song Gao Signed-off-by: Xiaojuan Yang Reviewed-by: Richard Henderson --- MAINTAINERS | 5 ++++ target/loongarch/README | 76 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+) create mode 100644 target/loongarch/README diff --git a/MAINTAINERS b/MAINTAINERS index d3879aa..935bbce 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -213,6 +213,11 @@ S: Maintained F: target/hppa/ F: disas/hppa.c +LoongArch TCG CPUS +M: Song Gao +S: Maintained +F: target/loongarch/ + M68K TCG CPUs M: Laurent Vivier S: Maintained diff --git a/target/loongarch/README b/target/loongarch/README new file mode 100644 index 0000000..09f809c --- /dev/null +++ b/target/loongarch/README @@ -0,0 +1,76 @@ +- Introduction + + LoongArch is the general processor architecture of Loongson. + + The following versions of the LoongArch core are supported + core: 3A5000 + https://github.com/loongson/LoongArch-Documentation/releases/download/2021.08.17/LoongArch-Vol1-v1.00-EN.pdf + + We can get the latest loongarch documents at https://github.com/loongson/LoongArch-Documentation/tags. + + +- Linux-user emulation + + We already support Linux user emulation. We can use LoongArch cross-tools to build LoongArch executables on X86 machines, + and We can also use qemu-loongarch64 to run LoongArch executables. + + 1. Install LoongArch cross-tools on X86 machines. + + Download cross-tools. + + wget https://github.com/loongson/build-tools/releases/latest/download/loongarch64-clfs-20210831-cross-tools.tar.xz + + tar -vxf loongarch64-clfs-20210831-cross-tools.tar.xz -C /opt + + Config cross-tools env. + + . setenv.sh + + setenv.sh: + + #!/bin/sh + set -x + CC_PREFIX=/opt/cross-tools + + export PATH=$CC_PREFIX/bin:$PATH + export LD_LIBRARY_PATH=$CC_PREFIX/lib:$LD_LIBRARY_PATH + export LD_LIBRARY_PATH=$CC_PREFIX/loongarch64-unknown-linux-gnu/lib/:$LD_LIBRARY_PATH + set +x + + 2. Test tests/tcg/multiarch. + + ./configure --disable-rdma --disable-pvrdma --prefix=/usr \ + --target-list="loongarch64-linux-user" \ + --disable-libiscsi --disable-libnfs --disable-libpmem \ + --disable-glusterfs --enable-libusb --enable-usb-redir \ + --disable-opengl --disable-xen --enable-spice --disable-werror \ + --enable-debug --disable-capstone --disable-kvm --enable-profiler + + cd build/ + + make && make check-tcg + + 3. Run LoongArch system basic command with loongarch-clfs-system. + + Download clfs-system. + + wget https://github.com/loongson/build-tools/releases/latest/download/loongarch64-clfs-system-2021-08-31.tar.bz2 + + tar -vxf loongarch64-clfs-system-2021-08-31.tar.bz2 -C /opt/clfs + + Config env. + + cp /opt/clfs/lib64/ld-linux-loongarch64.so.1 /lib64 + + export LD_LIBRARY_PATH="/opt/clfs/lib64" + + Run LoongArch system basic command. + + ./qemu-loongarch64 /opt/clfs/usr/bin/bash + ./qemu-loongarch64 /opt/clfs/usr/bin/ls + ./qemu-loongarch64 /opt/clfs/usr/bin/pwd + ... + + +- Note. + We can get the latest LoongArch documents or LoongArch tools at https://github.com/loongson/ From patchwork Fri Nov 19 06:13:06 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: gaosong X-Patchwork-Id: 1556916 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4HwRQ43Cryz9sXN for ; Fri, 19 Nov 2021 17:21:32 +1100 (AEDT) Received: from localhost ([::1]:50846 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mnxH8-0001Oi-60 for incoming@patchwork.ozlabs.org; Fri, 19 Nov 2021 01:21:30 -0500 Received: from eggs.gnu.org ([209.51.188.92]:46260) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mnx9i-0003rW-0j for qemu-devel@nongnu.org; Fri, 19 Nov 2021 01:13:50 -0500 Received: from mail.loongson.cn ([114.242.206.163]:46544 helo=loongson.cn) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mnx9Z-0004Wc-Ty for qemu-devel@nongnu.org; Fri, 19 Nov 2021 01:13:46 -0500 Received: from kvm-dev1.localdomain (unknown [10.2.5.134]) by mail.loongson.cn (Coremail) with SMTP id AQAAf9Dxj8+KQJdhSG0AAA--.1952S4; Fri, 19 Nov 2021 14:13:35 +0800 (CST) From: Song Gao To: qemu-devel@nongnu.org Subject: [PATCH v11 02/26] target/loongarch: Add core definition Date: Fri, 19 Nov 2021 14:13:06 +0800 Message-Id: <1637302410-24632-3-git-send-email-gaosong@loongson.cn> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1637302410-24632-1-git-send-email-gaosong@loongson.cn> References: <1637302410-24632-1-git-send-email-gaosong@loongson.cn> X-CM-TRANSID: AQAAf9Dxj8+KQJdhSG0AAA--.1952S4 X-Coremail-Antispam: 1UD129KBjvAXoW3trykKw47ZFW7Gw1fKr18AFb_yoW8AF4DXo WrAF4Iq3yrJw1xCa1q9rnYqa4jgry8CF4kC3WI9r409a4xtr98KFyrKw1SkF17Jrn8WFy8 u3y29Fn3GrW2qr1xn29KB7ZKAUJUUUUU529EdanIXcx71UUUUU7v73VFW2AGmfu7bjvjm3 AaLaJ3UjIYCTnIWjDUYxBIdaVFxhVjvjDU0xZFpf9x0zRUUUUUUUUU= X-CM-SenderInfo: 5jdr20tqj6z05rqj20fqof0/ Received-SPF: pass client-ip=114.242.206.163; envelope-from=gaosong@loongson.cn; helo=loongson.cn X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Xiaojuan Yang , richard.henderson@linaro.org, laurent@vivier.eu Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" This patch adds target state header, target definitions and initialization routines. Signed-off-by: Song Gao Signed-off-by: Xiaojuan Yang Reviewed-by: Richard Henderson --- target/loongarch/cpu-param.h | 18 +++ target/loongarch/cpu.c | 314 +++++++++++++++++++++++++++++++++++++++++++ target/loongarch/cpu.h | 253 ++++++++++++++++++++++++++++++++++ target/loongarch/internals.h | 21 +++ 4 files changed, 606 insertions(+) create mode 100644 target/loongarch/cpu-param.h create mode 100644 target/loongarch/cpu.c create mode 100644 target/loongarch/cpu.h create mode 100644 target/loongarch/internals.h diff --git a/target/loongarch/cpu-param.h b/target/loongarch/cpu-param.h new file mode 100644 index 0000000..9a769b6 --- /dev/null +++ b/target/loongarch/cpu-param.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * LoongArch CPU parameters for QEMU. + * + * Copyright (c) 2021 Loongson Technology Corporation Limited + */ + +#ifndef LOONGARCH_CPU_PARAM_H +#define LOONGARCH_CPU_PARAM_H + +#define TARGET_LONG_BITS 64 +#define TARGET_PHYS_ADDR_SPACE_BITS 48 +#define TARGET_VIRT_ADDR_SPACE_BITS 48 + +#define TARGET_PAGE_BITS 14 +#define NB_MMU_MODES 4 + +#endif diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c new file mode 100644 index 0000000..b3f4444 --- /dev/null +++ b/target/loongarch/cpu.c @@ -0,0 +1,314 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * QEMU LoongArch CPU + * + * Copyright (c) 2021 Loongson Technology Corporation Limited + */ + +#include "qemu/osdep.h" +#include "qemu/qemu-print.h" +#include "qapi/error.h" +#include "qemu/module.h" +#include "sysemu/qtest.h" +#include "exec/exec-all.h" +#include "qapi/qapi-commands-machine-target.h" +#include "cpu.h" +#include "internals.h" +#include "fpu/softfloat-helpers.h" + +const char * const regnames[] = { + "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", + "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", + "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", + "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31", +}; + +const char * const fregnames[] = { + "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", + "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", + "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", + "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", +}; + +static const char * const excp_names[EXCP_LAST + 1] = { + [EXCP_ADE] = "Address error", + [EXCP_SYSCALL] = "Syscall", + [EXCP_BREAK] = "Break", + [EXCP_INE] = "Instruction Non-existent", + [EXCP_FPE] = "Floating Point Exception", +}; + +const char *loongarch_exception_name(int32_t exception) +{ + return excp_names[exception]; +} + +void QEMU_NORETURN do_raise_exception(CPULoongArchState *env, + uint32_t exception, + uintptr_t pc) +{ + CPUState *cs = env_cpu(env); + + qemu_log_mask(CPU_LOG_INT, "%s: %d (%s)\n", + __func__, + exception, + loongarch_exception_name(exception)); + cs->exception_index = exception; + + cpu_loop_exit_restore(cs, pc); +} + +static void loongarch_cpu_set_pc(CPUState *cs, vaddr value) +{ + LoongArchCPU *cpu = LOONGARCH_CPU(cs); + CPULoongArchState *env = &cpu->env; + + env->pc = value; +} + +#ifdef CONFIG_TCG +static void loongarch_cpu_synchronize_from_tb(CPUState *cs, + const TranslationBlock *tb) +{ + LoongArchCPU *cpu = LOONGARCH_CPU(cs); + CPULoongArchState *env = &cpu->env; + + env->pc = tb->pc; +} +#endif /* CONFIG_TCG */ + +static bool loongarch_cpu_has_work(CPUState *cs) +{ + return true; +} + +static void loongarch_3a5000_initfn(Object *obj) +{ + LoongArchCPU *cpu = LOONGARCH_CPU(obj); + CPULoongArchState *env = &cpu->env; + int i; + + for (i = 0; i < 21; i++) { + env->cpucfg[i] = 0x0; + } + + env->cpucfg[0] = 0x14c010; /* PRID */ + + uint32_t data = 0; + data = FIELD_DP32(data, CPUCFG1, ARCH, 2); + data = FIELD_DP32(data, CPUCFG1, PGMMU, 1); + data = FIELD_DP32(data, CPUCFG1, IOCSR, 1); + data = FIELD_DP32(data, CPUCFG1, PALEN, 0x2f); + data = FIELD_DP32(data, CPUCFG1, VALEN, 0x2f); + data = FIELD_DP32(data, CPUCFG1, UAL, 1); + data = FIELD_DP32(data, CPUCFG1, RI, 1); + data = FIELD_DP32(data, CPUCFG1, EP, 1); + data = FIELD_DP32(data, CPUCFG1, RPLV, 1); + data = FIELD_DP32(data, CPUCFG1, HP, 1); + data = FIELD_DP32(data, CPUCFG1, IOCSR_BRD, 1); + env->cpucfg[1] = data; + + data = 0; + data = FIELD_DP32(data, CPUCFG2, FP, 1); + data = FIELD_DP32(data, CPUCFG2, FP_SP, 1); + data = FIELD_DP32(data, CPUCFG2, FP_DP, 1); + data = FIELD_DP32(data, CPUCFG2, FP_VER, 1); + data = FIELD_DP32(data, CPUCFG2, LLFTP, 1); + data = FIELD_DP32(data, CPUCFG2, LLFTP_VER, 1); + data = FIELD_DP32(data, CPUCFG2, LSPW, 1); + data = FIELD_DP32(data, CPUCFG2, LAM, 1); + env->cpucfg[2] = data; + + env->cpucfg[4] = 0x5f5e100; /* Crystal frequency */ + + data = 0; + data = FIELD_DP32(data, CPUCFG5, CC_MUL, 1); + data = FIELD_DP32(data, CPUCFG5, CC_DIV, 1); + env->cpucfg[5] = data; + + data = 0; + data = FIELD_DP32(data, CPUCFG16, L1_IUPRE, 1); + data = FIELD_DP32(data, CPUCFG16, L1_DPRE, 1); + data = FIELD_DP32(data, CPUCFG16, L2_IUPRE, 1); + data = FIELD_DP32(data, CPUCFG16, L2_IUUNIFY, 1); + data = FIELD_DP32(data, CPUCFG16, L2_IUPRIV, 1); + data = FIELD_DP32(data, CPUCFG16, L3_IUPRE, 1); + data = FIELD_DP32(data, CPUCFG16, L3_IUUNIFY, 1); + data = FIELD_DP32(data, CPUCFG16, L3_IUINCL, 1); + env->cpucfg[16] = data; + + data = 0; + data = FIELD_DP32(data, CPUCFG17, L1IU_WAYS, 0x8003); + data = FIELD_DP32(data, CPUCFG17, L1IU_SETS, 0x60); + env->cpucfg[17] = data; + + data = 0; + data = FIELD_DP32(data, CPUCFG18, L1D_WAYS, 0x8003); + data = FIELD_DP32(data, CPUCFG18, L1D_SETS, 0x60); + env->cpucfg[18] = data; + + data = 0; + data = FIELD_DP32(data, CPUCFG19, L2IU_WAYS, 0x800f); + data = FIELD_DP32(data, CPUCFG19, L2IU_SETS, 0x60); + env->cpucfg[19] = data; + + data = 0; + data = FIELD_DP32(data, CPUCFG20, L3IU_WAYS, 0xf00f); + data = FIELD_DP32(data, CPUCFG20, L3IU_SETS, 0x60); + env->cpucfg[20] = data; +} + +static void loongarch_cpu_list_entry(gpointer data, gpointer user_data) +{ + const char *typename = object_class_get_name(OBJECT_CLASS(data)); + + qemu_printf("%s\n", typename); +} + +void loongarch_cpu_list(void) +{ + GSList *list; + list = object_class_get_list_sorted(TYPE_LOONGARCH_CPU, false); + g_slist_foreach(list, loongarch_cpu_list_entry, NULL); + g_slist_free(list); +} + +static void loongarch_cpu_reset(DeviceState *dev) +{ + CPUState *cs = CPU(dev); + LoongArchCPU *cpu = LOONGARCH_CPU(cs); + LoongArchCPUClass *lacc = LOONGARCH_CPU_GET_CLASS(cpu); + CPULoongArchState *env = &cpu->env; + + lacc->parent_reset(dev); + + env->fcsr0_mask = 0x1f1f031f; + env->fcsr0 = 0x0; + + cs->exception_index = EXCP_NONE; +} + +static void loongarch_cpu_disas_set_info(CPUState *s, disassemble_info *info) +{ + info->print_insn = print_insn_loongarch; +} + +static void loongarch_cpu_realizefn(DeviceState *dev, Error **errp) +{ + CPUState *cs = CPU(dev); + LoongArchCPUClass *lacc = LOONGARCH_CPU_GET_CLASS(dev); + Error *local_err = NULL; + + cpu_exec_realizefn(cs, &local_err); + if (local_err != NULL) { + error_propagate(errp, local_err); + return; + } + + cpu_reset(cs); + qemu_init_vcpu(cs); + + lacc->parent_realize(dev, errp); +} + +static void loongarch_cpu_initfn(Object *obj) +{ + LoongArchCPU *cpu = LOONGARCH_CPU(obj); + + cpu_set_cpustate_pointers(cpu); +} + +static ObjectClass *loongarch_cpu_class_by_name(const char *cpu_model) +{ + ObjectClass *oc; + char *typename; + + typename = g_strdup_printf(LOONGARCH_CPU_TYPE_NAME("%s"), cpu_model); + oc = object_class_by_name(typename); + g_free(typename); + return oc; +} + +void loongarch_cpu_dump_state(CPUState *cs, FILE *f, int flags) +{ + LoongArchCPU *cpu = LOONGARCH_CPU(cs); + CPULoongArchState *env = &cpu->env; + int i; + + qemu_fprintf(f, " PC=%016" PRIx64 " ", env->pc); + qemu_fprintf(f, " FCSR0 0x%08x fp_status 0x%02x\n", env->fcsr0, + get_float_exception_flags(&env->fp_status)); + + /* gpr */ + for (i = 0; i < 32; i++) { + if ((i & 3) == 0) { + qemu_fprintf(f, " GPR%02d:", i); + } + qemu_fprintf(f, " %s %016" PRIx64, regnames[i], env->gpr[i]); + if ((i & 3) == 3) { + qemu_fprintf(f, "\n"); + } + } + + /* fpr */ + if (flags & CPU_DUMP_FPU) { + for (i = 0; i < 32; i++) { + qemu_fprintf(f, " %s %016" PRIx64, fregnames[i], env->fpr[i]); + if ((i & 3) == 3) { + qemu_fprintf(f, "\n"); + } + } + } +} + +#ifdef CONFIG_TCG +#include "hw/core/tcg-cpu-ops.h" + +static struct TCGCPUOps loongarch_tcg_ops = { + .initialize = loongarch_translate_init, + .synchronize_from_tb = loongarch_cpu_synchronize_from_tb, +}; +#endif /* CONFIG_TCG */ + +static void loongarch_cpu_class_init(ObjectClass *c, void *data) +{ + LoongArchCPUClass *lacc = LOONGARCH_CPU_CLASS(c); + CPUClass *cc = CPU_CLASS(c); + DeviceClass *dc = DEVICE_CLASS(c); + + device_class_set_parent_realize(dc, loongarch_cpu_realizefn, + &lacc->parent_realize); + device_class_set_parent_reset(dc, loongarch_cpu_reset, &lacc->parent_reset); + + cc->class_by_name = loongarch_cpu_class_by_name; + cc->has_work = loongarch_cpu_has_work; + cc->dump_state = loongarch_cpu_dump_state; + cc->set_pc = loongarch_cpu_set_pc; + cc->disas_set_info = loongarch_cpu_disas_set_info; +#ifdef CONFIG_TCG + cc->tcg_ops = &loongarch_tcg_ops; +#endif +} + +#define DEFINE_LOONGARCH_CPU_TYPE(model, initfn) \ + { \ + .parent = TYPE_LOONGARCH_CPU, \ + .instance_init = initfn, \ + .name = LOONGARCH_CPU_TYPE_NAME(model), \ + } + +static const TypeInfo loongarch_cpu_type_infos[] = { + { + .name = TYPE_LOONGARCH_CPU, + .parent = TYPE_CPU, + .instance_size = sizeof(LoongArchCPU), + .instance_init = loongarch_cpu_initfn, + + .abstract = true, + .class_size = sizeof(LoongArchCPUClass), + .class_init = loongarch_cpu_class_init, + }, + DEFINE_LOONGARCH_CPU_TYPE("Loongson-3A5000", loongarch_3a5000_initfn), +}; + +DEFINE_TYPES(loongarch_cpu_type_infos) diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h new file mode 100644 index 0000000..7509c77 --- /dev/null +++ b/target/loongarch/cpu.h @@ -0,0 +1,253 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * QEMU LoongArch CPU + * + * Copyright (c) 2021 Loongson Technology Corporation Limited + */ + +#ifndef LOONGARCH_CPU_H +#define LOONGARCH_CPU_H + +#include "exec/cpu-defs.h" +#include "fpu/softfloat-types.h" +#include "hw/registerfields.h" + +#define TCG_GUEST_DEFAULT_MO (0) + +#define FCSR0_M1 0x1f /* FCSR1 mask, Enables */ +#define FCSR0_M2 0x1f1f0000 /* FCSR2 mask, Cause and Flags */ +#define FCSR0_M3 0x300 /* FCSR3 mask, Round Mode */ +#define FCSR0_RM 8 /* Round Mode bit num on fcsr0 */ + +FIELD(FCSR0, ENABLES, 0, 5) +FIELD(FCSR0, RM, 8, 2) +FIELD(FCSR0, FLAGS, 16, 5) +FIELD(FCSR0, CAUSE, 24, 5) + +#define GET_FP_CAUSE(REG) FIELD_EX32(REG, FCSR0, CAUSE) +#define SET_FP_CAUSE(REG, V) FIELD_DP32(REG, FCSR0, CAUSE, V) +#define GET_FP_ENABLES(REG) FIELD_EX32(REG, FCSR0, ENABLES) +#define SET_FP_ENABLES(REG, V) FIELD_DP32(REG, FCSR0, ENABLES, V) +#define GET_FP_FLAGS(REG) FIELD_EX32(REG, FCSR0, FLAGS) +#define SET_FP_FLAGS(REG, V) FIELD_DP32(REG, FCSR0, FLAGS, V) +#define UPDATE_FP_FLAGS(REG, V) \ + do { \ + (REG) |= FIELD_DP32(0, FCSR0, FLAGS, V); \ + } while (0) + +#define FP_INEXACT 1 +#define FP_UNDERFLOW 2 +#define FP_OVERFLOW 4 +#define FP_DIV0 8 +#define FP_INVALID 16 + +/* cpucfg[0] bits */ +FIELD(CPUCFG0, PRID, 0, 32) + +/* cpucfg[1] bits */ +FIELD(CPUCFG1, ARCH, 0, 2) +FIELD(CPUCFG1, PGMMU, 2, 1) +FIELD(CPUCFG1, IOCSR, 3, 1) +FIELD(CPUCFG1, PALEN, 4, 8) +FIELD(CPUCFG1, VALEN, 12, 8) +FIELD(CPUCFG1, UAL, 20, 1) +FIELD(CPUCFG1, RI, 21, 1) +FIELD(CPUCFG1, EP, 22, 1) +FIELD(CPUCFG1, RPLV, 23, 1) +FIELD(CPUCFG1, HP, 24, 1) +FIELD(CPUCFG1, IOCSR_BRD, 25, 1) +FIELD(CPUCFG1, MSG_INT, 26, 1) + +/* cpucfg[2] bits */ +FIELD(CPUCFG2, FP, 0, 1) +FIELD(CPUCFG2, FP_SP, 1, 1) +FIELD(CPUCFG2, FP_DP, 2, 1) +FIELD(CPUCFG2, FP_VER, 3, 3) +FIELD(CPUCFG2, LSX, 6, 1) +FIELD(CPUCFG2, LASX, 7, 1) +FIELD(CPUCFG2, COMPLEX, 8, 1) +FIELD(CPUCFG2, CRYPTO, 9, 1) +FIELD(CPUCFG2, LVZ, 10, 1) +FIELD(CPUCFG2, LVZ_VER, 11, 3) +FIELD(CPUCFG2, LLFTP, 14, 1) +FIELD(CPUCFG2, LLFTP_VER, 15, 3) +FIELD(CPUCFG2, LBT_X86, 18, 1) +FIELD(CPUCFG2, LBT_ARM, 19, 1) +FIELD(CPUCFG2, LBT_MIPS, 20, 1) +FIELD(CPUCFG2, LSPW, 21, 1) +FIELD(CPUCFG2, LAM, 22, 1) + +/* cpucfg[3] bits */ +FIELD(CPUCFG3, CCDMA, 0, 1) +FIELD(CPUCFG3, SFB, 1, 1) +FIELD(CPUCFG3, UCACC, 2, 1) +FIELD(CPUCFG3, LLEXC, 3, 1) +FIELD(CPUCFG3, SCDLY, 4, 1) +FIELD(CPUCFG3, LLDBAR, 5, 1) +FIELD(CPUCFG3, ITLBHMC, 6, 1) +FIELD(CPUCFG3, ICHMC, 7, 1) +FIELD(CPUCFG3, SPW_LVL, 8, 3) +FIELD(CPUCFG3, SPW_HP_HF, 11, 1) +FIELD(CPUCFG3, RVA, 12, 1) +FIELD(CPUCFG3, RVAMAX, 13, 4) + +/* cpucfg[4] bits */ +FIELD(CPUCFG4, CC_FREQ, 0, 32) + +/* cpucfg[5] bits */ +FIELD(CPUCFG5, CC_MUL, 0, 16) +FIELD(CPUCFG5, CC_DIV, 16, 16) + +/* cpucfg[6] bits */ +FIELD(CPUCFG6, PMP, 0, 1) +FIELD(CPUCFG6, PMVER, 1, 3) +FIELD(CPUCFG6, PMNUM, 4, 4) +FIELD(CPUCFG6, PMBITS, 8, 6) +FIELD(CPUCFG6, UPM, 14, 1) + +/* cpucfg[16] bits */ +FIELD(CPUCFG16, L1_IUPRE, 0, 1) +FIELD(CPUCFG16, L1_IUUNIFY, 1, 1) +FIELD(CPUCFG16, L1_DPRE, 2, 1) +FIELD(CPUCFG16, L2_IUPRE, 3, 1) +FIELD(CPUCFG16, L2_IUUNIFY, 4, 1) +FIELD(CPUCFG16, L2_IUPRIV, 5, 1) +FIELD(CPUCFG16, L2_IUINCL, 6, 1) +FIELD(CPUCFG16, L2_DPRE, 7, 1) +FIELD(CPUCFG16, L2_DPRIV, 8, 1) +FIELD(CPUCFG16, L2_DINCL, 9, 1) +FIELD(CPUCFG16, L3_IUPRE, 10, 1) +FIELD(CPUCFG16, L3_IUUNIFY, 11, 1) +FIELD(CPUCFG16, L3_IUPRIV, 12, 1) +FIELD(CPUCFG16, L3_IUINCL, 13, 1) +FIELD(CPUCFG16, L3_DPRE, 14, 1) +FIELD(CPUCFG16, L3_DPRIV, 15, 1) +FIELD(CPUCFG16, L3_DINCL, 16, 1) + +/* cpucfg[17] bits */ +FIELD(CPUCFG17, L1IU_WAYS, 0, 16) +FIELD(CPUCFG17, L1IU_SETS, 16, 8) +FIELD(CPUCFG17, L1IU_SIZE, 24, 7) + +/* cpucfg[18] bits */ +FIELD(CPUCFG18, L1D_WAYS, 0, 16) +FIELD(CPUCFG18, L1D_SETS, 16, 8) +FIELD(CPUCFG18, L1D_SIZE, 24, 7) + +/* cpucfg[19] bits */ +FIELD(CPUCFG19, L2IU_WAYS, 0, 16) +FIELD(CPUCFG19, L2IU_SETS, 16, 8) +FIELD(CPUCFG19, L2IU_SIZE, 24, 7) + +/* cpucfg[20] bits */ +FIELD(CPUCFG20, L3IU_WAYS, 0, 16) +FIELD(CPUCFG20, L3IU_SETS, 16, 8) +FIELD(CPUCFG20, L3IU_SIZE, 24, 7) + +extern const char * const regnames[]; +extern const char * const fregnames[]; + +typedef struct CPULoongArchState CPULoongArchState; +struct CPULoongArchState { + uint64_t gpr[32]; + uint64_t pc; + + uint64_t fpr[32]; + float_status fp_status; + bool cf[8]; + + /* + * fcsr0 + * 31:29 |28:24 |23:21 |20:16 |15:10 |9:8 |7:5 |4:0 + * Cause Flags RM Enables + */ + uint32_t fcsr0; + uint32_t fcsr0_mask; + + uint32_t cpucfg[21]; + + uint64_t lladdr; /* LL virtual address compared against SC */ + uint64_t llval; + + uint64_t badaddr; +}; + +/** + * LoongArchCPU: + * @env: #CPULoongArchState + * + * A LoongArch CPU. + */ +struct LoongArchCPU { + /*< private >*/ + CPUState parent_obj; + /*< public >*/ + + CPUNegativeOffsetState neg; + CPULoongArchState env; +}; + +#define TYPE_LOONGARCH_CPU "loongarch-cpu" + +OBJECT_DECLARE_TYPE(LoongArchCPU, LoongArchCPUClass, + LOONGARCH_CPU) + +/** + * LoongArchCPUClass: + * @parent_realize: The parent class' realize handler. + * @parent_reset: The parent class' reset handler. + * + * A LoongArch CPU model. + */ +struct LoongArchCPUClass { + /*< private >*/ + CPUClass parent_class; + /*< public >*/ + + DeviceRealize parent_realize; + DeviceReset parent_reset; +}; + +#define MMU_USER_IDX 3 + +static inline int cpu_mmu_index(CPULoongArchState *env, bool ifetch) +{ + return MMU_USER_IDX; +} + +static inline void cpu_get_tb_cpu_state(CPULoongArchState *env, + target_ulong *pc, + target_ulong *cs_base, + uint32_t *flags) +{ + *pc = env->pc; + *cs_base = 0; + *flags = cpu_mmu_index(env, false); +} + +void loongarch_cpu_list(void); + +#define cpu_list loongarch_cpu_list + +typedef CPULoongArchState CPUArchState; +typedef LoongArchCPU ArchCPU; + +#include "exec/cpu-all.h" + +/* Exceptions */ +enum { + EXCP_NONE = -1, + EXCP_ADE = 0, + EXCP_SYSCALL, + EXCP_BREAK, + EXCP_INE, + EXCP_FPE, + + EXCP_LAST = EXCP_FPE, +}; + +#define LOONGARCH_CPU_TYPE_SUFFIX "-" TYPE_LOONGARCH_CPU +#define LOONGARCH_CPU_TYPE_NAME(model) model LOONGARCH_CPU_TYPE_SUFFIX +#define CPU_RESOLVING_TYPE TYPE_LOONGARCH_CPU + +#endif /* LOONGARCH_CPU_H */ diff --git a/target/loongarch/internals.h b/target/loongarch/internals.h new file mode 100644 index 0000000..1e69e7d --- /dev/null +++ b/target/loongarch/internals.h @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * QEMU LoongArch CPU -- internal functions and types + * + * Copyright (c) 2021 Loongson Technology Corporation Limited + */ + +#ifndef LOONGARCH_INTERNALS_H +#define LOONGARCH_INTERNALS_H + +void loongarch_translate_init(void); + +void loongarch_cpu_dump_state(CPUState *cpu, FILE *f, int flags); + +void QEMU_NORETURN do_raise_exception(CPULoongArchState *env, + uint32_t exception, + uintptr_t pc); + +const char *loongarch_exception_name(int32_t exception); + +#endif From patchwork Fri Nov 19 06:13:07 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: gaosong X-Patchwork-Id: 1556919 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4HwRXr18BJz9sXN for ; Fri, 19 Nov 2021 17:27:22 +1100 (AEDT) Received: from localhost ([::1]:59080 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mnxMf-00077p-GB for incoming@patchwork.ozlabs.org; Fri, 19 Nov 2021 01:27:18 -0500 Received: from eggs.gnu.org ([209.51.188.92]:46262) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mnx9i-0003ra-4N for qemu-devel@nongnu.org; Fri, 19 Nov 2021 01:13:50 -0500 Received: from mail.loongson.cn ([114.242.206.163]:46558 helo=loongson.cn) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mnx9Z-0004Wd-FI for qemu-devel@nongnu.org; Fri, 19 Nov 2021 01:13:46 -0500 Received: from kvm-dev1.localdomain (unknown [10.2.5.134]) by mail.loongson.cn (Coremail) with SMTP id AQAAf9Dxj8+KQJdhSG0AAA--.1952S5; Fri, 19 Nov 2021 14:13:35 +0800 (CST) From: Song Gao To: qemu-devel@nongnu.org Subject: [PATCH v11 03/26] target/loongarch: Add main translation routines Date: Fri, 19 Nov 2021 14:13:07 +0800 Message-Id: <1637302410-24632-4-git-send-email-gaosong@loongson.cn> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1637302410-24632-1-git-send-email-gaosong@loongson.cn> References: <1637302410-24632-1-git-send-email-gaosong@loongson.cn> X-CM-TRANSID: AQAAf9Dxj8+KQJdhSG0AAA--.1952S5 X-Coremail-Antispam: 1UD129KBjvJXoW3Xr4DJrW3Gr47KryxtFW5ZFb_yoW3XrWfpF 17Cry3Kr48Ja43Z3Z3G3yYqr15Aa1fGry2qa4Ikws5Cr42qrykZryktrZrKFWUC3y8WFyj vFsxA3WY9F48XaDanT9S1TB71UUUUUUqnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnUUvcSsGvfC2KfnxnUUI43ZEXa7xR_UUUUUUUUU== X-CM-SenderInfo: 5jdr20tqj6z05rqj20fqof0/ Received-SPF: pass client-ip=114.242.206.163; envelope-from=gaosong@loongson.cn; helo=loongson.cn X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Xiaojuan Yang , richard.henderson@linaro.org, laurent@vivier.eu Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" This patch adds main translation routines and basic functions for translation. Signed-off-by: Song Gao Signed-off-by: Xiaojuan Yang Reviewed-by: Richard Henderson --- target/loongarch/helper.h | 6 ++ target/loongarch/op_helper.c | 21 ++++++ target/loongarch/translate.c | 159 +++++++++++++++++++++++++++++++++++++++++++ target/loongarch/translate.h | 26 +++++++ 4 files changed, 212 insertions(+) create mode 100644 target/loongarch/helper.h create mode 100644 target/loongarch/op_helper.c create mode 100644 target/loongarch/translate.c create mode 100644 target/loongarch/translate.h diff --git a/target/loongarch/helper.h b/target/loongarch/helper.h new file mode 100644 index 0000000..eb771c0 --- /dev/null +++ b/target/loongarch/helper.h @@ -0,0 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (c) 2021 Loongson Technology Corporation Limited + */ + +DEF_HELPER_2(raise_exception, noreturn, env, i32) diff --git a/target/loongarch/op_helper.c b/target/loongarch/op_helper.c new file mode 100644 index 0000000..9038109 --- /dev/null +++ b/target/loongarch/op_helper.c @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * LoongArch emulation helpers for QEMU. + * + * Copyright (c) 2021 Loongson Technology Corporation Limited + */ + +#include "qemu/osdep.h" +#include "qemu/main-loop.h" +#include "cpu.h" +#include "qemu/host-utils.h" +#include "exec/helper-proto.h" +#include "exec/exec-all.h" +#include "exec/cpu_ldst.h" +#include "internals.h" + +/* Exceptions helpers */ +void helper_raise_exception(CPULoongArchState *env, uint32_t exception) +{ + do_raise_exception(env, exception, GETPC()); +} diff --git a/target/loongarch/translate.c b/target/loongarch/translate.c new file mode 100644 index 0000000..048c895 --- /dev/null +++ b/target/loongarch/translate.c @@ -0,0 +1,159 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * LoongArch emulation for QEMU - main translation routines. + * + * Copyright (c) 2021 Loongson Technology Corporation Limited + */ + +#include "qemu/osdep.h" +#include "cpu.h" +#include "tcg/tcg-op.h" +#include "exec/translator.h" +#include "exec/helper-proto.h" +#include "exec/helper-gen.h" + +#include "exec/translator.h" +#include "exec/log.h" +#include "qemu/qemu-print.h" +#include "translate.h" +#include "internals.h" + +/* Global register indices */ +TCGv cpu_gpr[32], cpu_pc; +static TCGv cpu_lladdr, cpu_llval; +TCGv_i32 cpu_fcsr0; +TCGv_i64 cpu_fpr[32]; + +#define DISAS_STOP DISAS_TARGET_0 + +void generate_exception(DisasContext *ctx, int excp) +{ + tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next); + gen_helper_raise_exception(cpu_env, tcg_constant_i32(excp)); + ctx->base.is_jmp = DISAS_NORETURN; +} + +static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest) +{ + if (translator_use_goto_tb(&ctx->base, dest)) { + tcg_gen_goto_tb(n); + tcg_gen_movi_tl(cpu_pc, dest); + tcg_gen_exit_tb(ctx->base.tb, n); + } else { + tcg_gen_movi_tl(cpu_pc, dest); + tcg_gen_lookup_and_goto_ptr(); + } +} + +static void loongarch_tr_init_disas_context(DisasContextBase *dcbase, + CPUState *cs) +{ + int64_t bound; + DisasContext *ctx = container_of(dcbase, DisasContext, base); + + ctx->page_start = ctx->base.pc_first & TARGET_PAGE_MASK; + ctx->mem_idx = ctx->base.tb->flags; + + /* Bound the number of insns to execute to those left on the page. */ + bound = -(ctx->base.pc_first | TARGET_PAGE_MASK) / 4; + ctx->base.max_insns = MIN(ctx->base.max_insns, bound); +} + +static void loongarch_tr_tb_start(DisasContextBase *dcbase, CPUState *cs) +{ +} + +static void loongarch_tr_insn_start(DisasContextBase *dcbase, CPUState *cs) +{ + DisasContext *ctx = container_of(dcbase, DisasContext, base); + + tcg_gen_insn_start(ctx->base.pc_next); +} + +static void loongarch_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs) +{ + CPULoongArchState *env = cs->env_ptr; + DisasContext *ctx = container_of(dcbase, DisasContext, base); + + ctx->opcode = cpu_ldl_code(env, ctx->base.pc_next); + + if (!decode(ctx, ctx->opcode)) { + qemu_log_mask(LOG_UNIMP, "Error: unkown opcode. 0x%lx: 0x%x\n", + ctx->base.pc_next, ctx->opcode); + generate_exception(ctx, EXCP_INE); + } + + ctx->base.pc_next += 4; +} + +static void loongarch_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs) +{ + DisasContext *ctx = container_of(dcbase, DisasContext, base); + + switch (ctx->base.is_jmp) { + case DISAS_STOP: + tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next); + tcg_gen_lookup_and_goto_ptr(); + break; + case DISAS_TOO_MANY: + gen_goto_tb(ctx, 0, ctx->base.pc_next); + break; + case DISAS_NORETURN: + break; + default: + g_assert_not_reached(); + } +} + +static void loongarch_tr_disas_log(const DisasContextBase *dcbase, CPUState *cs) +{ + qemu_log("IN: %s\n", lookup_symbol(dcbase->pc_first)); + log_target_disas(cs, dcbase->pc_first, dcbase->tb->size); +} + +static const TranslatorOps loongarch_tr_ops = { + .init_disas_context = loongarch_tr_init_disas_context, + .tb_start = loongarch_tr_tb_start, + .insn_start = loongarch_tr_insn_start, + .translate_insn = loongarch_tr_translate_insn, + .tb_stop = loongarch_tr_tb_stop, + .disas_log = loongarch_tr_disas_log, +}; + +void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns) +{ + DisasContext ctx; + + translator_loop(&loongarch_tr_ops, &ctx.base, cs, tb, max_insns); +} + +void loongarch_translate_init(void) +{ + int i; + + cpu_gpr[0] = NULL; + for (i = 1; i < 32; i++) { + cpu_gpr[i] = tcg_global_mem_new(cpu_env, + offsetof(CPULoongArchState, gpr[i]), + regnames[i]); + } + + for (i = 0; i < 32; i++) { + int off = offsetof(CPULoongArchState, fpr[i]); + cpu_fpr[i] = tcg_global_mem_new_i64(cpu_env, off, fregnames[i]); + } + + cpu_pc = tcg_global_mem_new(cpu_env, offsetof(CPULoongArchState, pc), "pc"); + cpu_fcsr0 = tcg_global_mem_new_i32(cpu_env, + offsetof(CPULoongArchState, fcsr0), "fcsr0"); + cpu_lladdr = tcg_global_mem_new(cpu_env, + offsetof(CPULoongArchState, lladdr), "lladdr"); + cpu_llval = tcg_global_mem_new(cpu_env, + offsetof(CPULoongArchState, llval), "llval"); +} + +void restore_state_to_opc(CPULoongArchState *env, TranslationBlock *tb, + target_ulong *data) +{ + env->pc = data[0]; +} diff --git a/target/loongarch/translate.h b/target/loongarch/translate.h new file mode 100644 index 0000000..6cc7f1a --- /dev/null +++ b/target/loongarch/translate.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * LoongArch translation routines. + * + * Copyright (c) 2021 Loongson Technology Corporation Limited + */ + +#ifndef TARGET_LOONGARCH_TRANSLATE_H +#define TARGET_LOONGARCH_TRANSLATE_H + +#include "exec/translator.h" + +typedef struct DisasContext { + DisasContextBase base; + target_ulong page_start; + uint32_t opcode; + int mem_idx; +} DisasContext; + +void generate_exception(DisasContext *ctx, int excp); + +extern TCGv cpu_gpr[32], cpu_pc; +extern TCGv_i32 cpu_fscr0; +extern TCGv_i64 cpu_fpr[32]; + +#endif From patchwork Fri Nov 19 06:13:08 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: gaosong X-Patchwork-Id: 1556915 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4HwRQ153k3z9sXN for ; Fri, 19 Nov 2021 17:21:28 +1100 (AEDT) Received: from localhost ([::1]:50638 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mnxH2-0001GX-5w for incoming@patchwork.ozlabs.org; Fri, 19 Nov 2021 01:21:24 -0500 Received: from eggs.gnu.org ([209.51.188.92]:46266) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mnx9i-0003rc-1S for qemu-devel@nongnu.org; Fri, 19 Nov 2021 01:13:50 -0500 Received: from mail.loongson.cn ([114.242.206.163]:46572 helo=loongson.cn) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mnx9Z-0004Wh-E6 for qemu-devel@nongnu.org; Fri, 19 Nov 2021 01:13:46 -0500 Received: from kvm-dev1.localdomain (unknown [10.2.5.134]) by mail.loongson.cn (Coremail) with SMTP id AQAAf9Dxj8+KQJdhSG0AAA--.1952S6; Fri, 19 Nov 2021 14:13:36 +0800 (CST) From: Song Gao To: qemu-devel@nongnu.org Subject: [PATCH v11 04/26] target/loongarch: Add fixed point arithmetic instruction translation Date: Fri, 19 Nov 2021 14:13:08 +0800 Message-Id: <1637302410-24632-5-git-send-email-gaosong@loongson.cn> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1637302410-24632-1-git-send-email-gaosong@loongson.cn> References: <1637302410-24632-1-git-send-email-gaosong@loongson.cn> X-CM-TRANSID: AQAAf9Dxj8+KQJdhSG0AAA--.1952S6 X-Coremail-Antispam: 1UD129KBjvAXoWfGrW5GF43AF43tw4xAw4xZwb_yoW8Aw48to W7GF1UJr48Gry2vF15C3WvqFy7JF1j9an7JrWru3WUWF4kJry7tr1rKwn5ZayrXw1UKryr GF1SgFyfJ3yrXrn7n29KB7ZKAUJUUUUU529EdanIXcx71UUUUU7v73VFW2AGmfu7bjvjm3 AaLaJ3UjIYCTnIWjDUYxBIdaVFxhVjvjDU0xZFpf9x0zRUUUUUUUUU= X-CM-SenderInfo: 5jdr20tqj6z05rqj20fqof0/ Received-SPF: pass client-ip=114.242.206.163; envelope-from=gaosong@loongson.cn; helo=loongson.cn X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Xiaojuan Yang , richard.henderson@linaro.org, laurent@vivier.eu Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" This includes: - ADD.{W/D}, SUB.{W/D} - ADDI.{W/D}, ADDU16ID - ALSL.{W[U]/D} - LU12I.W, LU32I.D LU52I.D - SLT[U], SLT[U]I - PCADDI, PCADDU12I, PCADDU18I, PCALAU12I - AND, OR, NOR, XOR, ANDN, ORN - MUL.{W/D}, MULH.{W[U]/D[U]} - MULW.D.W[U] - DIV.{W[U]/D[U]}, MOD.{W[U]/D[U]} - ANDI, ORI, XORI Signed-off-by: Song Gao Signed-off-by: Xiaojuan Yang Reviewed-by: Richard Henderson --- target/loongarch/insn_trans/trans_arith.c.inc | 309 ++++++++++++++++++++++++++ target/loongarch/insns.decode | 79 +++++++ target/loongarch/translate.c | 83 +++++++ target/loongarch/translate.h | 19 ++ 4 files changed, 490 insertions(+) create mode 100644 target/loongarch/insn_trans/trans_arith.c.inc create mode 100644 target/loongarch/insns.decode diff --git a/target/loongarch/insn_trans/trans_arith.c.inc b/target/loongarch/insn_trans/trans_arith.c.inc new file mode 100644 index 0000000..ae1e113 --- /dev/null +++ b/target/loongarch/insn_trans/trans_arith.c.inc @@ -0,0 +1,309 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (c) 2021 Loongson Technology Corporation Limited + */ + +static bool gen_rrr(DisasContext *ctx, arg_rrr *a, + DisasExtend src1_ext, DisasExtend src2_ext, + DisasExtend dst_ext, void (*func)(TCGv, TCGv, TCGv)) +{ + TCGv dest = gpr_dst(ctx, a->rd, dst_ext); + TCGv src1 = gpr_src(ctx, a->rj, src1_ext); + TCGv src2 = gpr_src(ctx, a->rk, src2_ext); + + func(dest, src1, src2); + + /* dst_ext is EXT_NONE and input is dest, We don't run gen_set_gpr. */ + if (dst_ext) { + gen_set_gpr(a->rd, dest, dst_ext); + } + return true; +} + +static bool gen_rr_i(DisasContext *ctx, arg_rr_i *a, + DisasExtend src_ext, DisasExtend dst_ext, + void (*func)(TCGv, TCGv, TCGv)) +{ + TCGv dest = gpr_dst(ctx, a->rd, dst_ext); + TCGv src1 = gpr_src(ctx, a->rj, src_ext); + TCGv src2 = tcg_constant_tl(a->imm); + + func(dest, src1, src2); + + if (dst_ext) { + gen_set_gpr(a->rd, dest, dst_ext); + } + return true; +} + +static bool gen_rrr_sa(DisasContext *ctx, arg_rrr_sa *a, + DisasExtend src_ext, DisasExtend dst_ext, + void (*func)(TCGv, TCGv, TCGv, TCGv, target_long)) +{ + TCGv dest = gpr_dst(ctx, a->rd, dst_ext); + TCGv src1 = gpr_src(ctx, a->rj, src_ext); + TCGv src2 = gpr_src(ctx, a->rk, src_ext); + TCGv temp = tcg_temp_new(); + + func(dest, src1, src2, temp, a->sa); + + if (dst_ext) { + gen_set_gpr(a->rd, dest, dst_ext); + } + tcg_temp_free(temp); + return true; +} + +static bool trans_lu12i_w(DisasContext *ctx, arg_lu12i_w *a) +{ + TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE); + + tcg_gen_movi_tl(dest, a->imm << 12); + return true; +} + +static bool gen_pc(DisasContext *ctx, arg_r_i *a, + target_ulong (*func)(target_ulong, int)) +{ + TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE); + target_ulong addr = func(ctx->base.pc_next, a->imm); + + tcg_gen_movi_tl(dest, addr); + return true; +} + +static void gen_slt(TCGv dest, TCGv src1, TCGv src2) +{ + tcg_gen_setcond_tl(TCG_COND_LT, dest, src1, src2); +} + +static void gen_sltu(TCGv dest, TCGv src1, TCGv src2) +{ + tcg_gen_setcond_tl(TCG_COND_LTU, dest, src1, src2); +} + +static void gen_mulh_w(TCGv dest, TCGv src1, TCGv src2) +{ + tcg_gen_mul_i64(dest, src1, src2); + tcg_gen_sari_i64(dest, dest, 32); +} + +static void gen_mulh_wu(TCGv dest, TCGv src1, TCGv src2) +{ + tcg_gen_mul_i64(dest, src1, src2); + tcg_gen_sari_i64(dest, dest, 32); +} + +static void gen_mulh_d(TCGv dest, TCGv src1, TCGv src2) +{ + TCGv discard = tcg_temp_new(); + tcg_gen_muls2_tl(discard, dest, src1, src2); + tcg_temp_free(discard); +} + +static void gen_mulh_du(TCGv dest, TCGv src1, TCGv src2) +{ + TCGv discard = tcg_temp_new(); + tcg_gen_mulu2_tl(discard, dest, src1, src2); + tcg_temp_free(discard); +} + +static void prep_divisor_d(TCGv ret, TCGv src1, TCGv src2) +{ + TCGv t0 = tcg_temp_new(); + TCGv t1 = tcg_temp_new(); + TCGv zero = tcg_constant_tl(0); + + /* + * If min / -1, set the divisor to 1. + * This avoids potential host overflow trap and produces min. + * If x / 0, set the divisor to 1. + * This avoids potential host overflow trap; + * the required result is undefined. + */ + tcg_gen_setcondi_tl(TCG_COND_EQ, ret, src1, INT64_MIN); + tcg_gen_setcondi_tl(TCG_COND_EQ, t0, src2, -1); + tcg_gen_setcondi_tl(TCG_COND_EQ, t1, src2, 0); + tcg_gen_and_tl(ret, ret, t0); + tcg_gen_or_tl(ret, ret, t1); + tcg_gen_movcond_tl(TCG_COND_NE, ret, ret, zero, ret, src2); + + tcg_temp_free(t0); + tcg_temp_free(t1); +} + +static void prep_divisor_du(TCGv ret, TCGv src2) +{ + TCGv zero = tcg_constant_tl(0); + TCGv one = tcg_constant_tl(1); + + /* + * If x / 0, set the divisor to 1. + * This avoids potential host overflow trap; + * the required result is undefined. + */ + tcg_gen_movcond_tl(TCG_COND_EQ, ret, src2, zero, one, src2); +} + +static void gen_div_d(TCGv dest, TCGv src1, TCGv src2) +{ + TCGv t0 = tcg_temp_new(); + prep_divisor_d(t0, src1, src2); + tcg_gen_div_tl(dest, src1, t0); + tcg_temp_free(t0); +} + +static void gen_rem_d(TCGv dest, TCGv src1, TCGv src2) +{ + TCGv t0 = tcg_temp_new(); + prep_divisor_d(t0, src1, src2); + tcg_gen_rem_tl(dest, src1, t0); + tcg_temp_free(t0); +} + +static void gen_div_du(TCGv dest, TCGv src1, TCGv src2) +{ + TCGv t0 = tcg_temp_new(); + prep_divisor_du(t0, src2); + tcg_gen_divu_tl(dest, src1, t0); + tcg_temp_free(t0); +} + +static void gen_rem_du(TCGv dest, TCGv src1, TCGv src2) +{ + TCGv t0 = tcg_temp_new(); + prep_divisor_du(t0, src2); + tcg_gen_remu_tl(dest, src1, t0); + tcg_temp_free(t0); +} + +static void gen_div_w(TCGv dest, TCGv src1, TCGv src2) +{ + TCGv t0 = tcg_temp_new(); + /* We need not check for integer overflow for div_w. */ + prep_divisor_du(t0, src2); + tcg_gen_div_tl(dest, src1, t0); + tcg_temp_free(t0); +} + +static void gen_rem_w(TCGv dest, TCGv src1, TCGv src2) +{ + TCGv t0 = tcg_temp_new(); + /* We need not check for integer overflow for rem_w. */ + prep_divisor_du(t0, src2); + tcg_gen_rem_tl(dest, src1, t0); + tcg_temp_free(t0); +} + +static void gen_alsl_w(TCGv dest, TCGv src1, TCGv src2, + TCGv temp, target_long sa) +{ + tcg_gen_shli_tl(temp, src1, sa); + tcg_gen_add_tl(dest, temp, src2); +} + +static void gen_alsl_wu(TCGv dest, TCGv src1, TCGv src2, + TCGv temp, target_long sa) +{ + tcg_gen_shli_tl(temp, src1, sa); + tcg_gen_add_tl(dest, temp, src2); +} + +static void gen_alsl_d(TCGv dest, TCGv src1, TCGv src2, + TCGv temp, target_long sa) +{ + tcg_gen_shli_tl(temp, src1, sa); + tcg_gen_add_tl(dest, temp, src2); +} + +static bool trans_lu32i_d(DisasContext *ctx, arg_lu32i_d *a) +{ + TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE); + TCGv src1 = gpr_src(ctx, a->rd, EXT_NONE); + TCGv src2 = tcg_constant_tl(a->imm); + + tcg_gen_deposit_tl(dest, src1, src2, 32, 32); + return true; +} + +static bool trans_lu52i_d(DisasContext *ctx, arg_lu52i_d *a) +{ + TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE); + TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE); + TCGv src2 = tcg_constant_tl(a->imm); + + tcg_gen_deposit_tl(dest, src1, src2, 52, 12); + return true; +} + +static target_ulong gen_pcaddi(target_ulong pc, int imm) +{ + return pc + (imm << 2); +} + +static target_ulong gen_pcalau12i(target_ulong pc, int imm) +{ + return (pc + (imm << 12)) & ~0xfff; +} + +static target_ulong gen_pcaddu12i(target_ulong pc, int imm) +{ + return pc + (imm << 12); +} + +static target_ulong gen_pcaddu18i(target_ulong pc, int imm) +{ + return pc + ((target_ulong)(imm) << 18); +} + +static bool trans_addu16i_d(DisasContext *ctx, arg_addu16i_d *a) +{ + TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE); + TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE); + + tcg_gen_addi_tl(dest, src1, a->imm << 16); + return true; +} + +TRANS(add_w, gen_rrr, EXT_NONE, EXT_NONE, EXT_SIGN, tcg_gen_add_tl) +TRANS(add_d, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, tcg_gen_add_tl) +TRANS(sub_w, gen_rrr, EXT_NONE, EXT_NONE, EXT_SIGN, tcg_gen_sub_tl) +TRANS(sub_d, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, tcg_gen_sub_tl) +TRANS(and, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, tcg_gen_and_tl) +TRANS(or, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, tcg_gen_or_tl) +TRANS(xor, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, tcg_gen_xor_tl) +TRANS(nor, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, tcg_gen_nor_tl) +TRANS(andn, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, tcg_gen_andc_tl) +TRANS(orn, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, tcg_gen_orc_tl) +TRANS(slt, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, gen_slt) +TRANS(sltu, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, gen_sltu) +TRANS(mul_w, gen_rrr, EXT_SIGN, EXT_SIGN, EXT_SIGN, tcg_gen_mul_tl) +TRANS(mul_d, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, tcg_gen_mul_tl) +TRANS(mulh_w, gen_rrr, EXT_SIGN, EXT_SIGN, EXT_NONE, gen_mulh_w) +TRANS(mulh_wu, gen_rrr, EXT_ZERO, EXT_ZERO, EXT_NONE, gen_mulh_wu) +TRANS(mulh_d, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, gen_mulh_d) +TRANS(mulh_du, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, gen_mulh_du) +TRANS(mulw_d_w, gen_rrr, EXT_SIGN, EXT_SIGN, EXT_NONE, tcg_gen_mul_tl) +TRANS(mulw_d_wu, gen_rrr, EXT_ZERO, EXT_ZERO, EXT_NONE, tcg_gen_mul_tl) +TRANS(div_w, gen_rrr, EXT_SIGN, EXT_SIGN, EXT_SIGN, gen_div_w) +TRANS(mod_w, gen_rrr, EXT_SIGN, EXT_SIGN, EXT_SIGN, gen_rem_w) +TRANS(div_wu, gen_rrr, EXT_ZERO, EXT_ZERO, EXT_SIGN, gen_div_du) +TRANS(mod_wu, gen_rrr, EXT_ZERO, EXT_ZERO, EXT_SIGN, gen_rem_du) +TRANS(div_d, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, gen_div_d) +TRANS(mod_d, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, gen_rem_d) +TRANS(div_du, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, gen_div_du) +TRANS(mod_du, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, gen_rem_du) +TRANS(slti, gen_rr_i, EXT_NONE, EXT_NONE, gen_slt) +TRANS(sltui, gen_rr_i, EXT_NONE, EXT_NONE, gen_sltu) +TRANS(addi_w, gen_rr_i, EXT_NONE, EXT_SIGN, tcg_gen_add_tl) +TRANS(addi_d, gen_rr_i, EXT_NONE, EXT_NONE, tcg_gen_add_tl) +TRANS(alsl_w, gen_rrr_sa, EXT_NONE, EXT_SIGN, gen_alsl_w) +TRANS(alsl_wu, gen_rrr_sa, EXT_NONE, EXT_ZERO, gen_alsl_wu) +TRANS(alsl_d, gen_rrr_sa, EXT_NONE, EXT_NONE, gen_alsl_d) +TRANS(pcaddi, gen_pc, gen_pcaddi) +TRANS(pcalau12i, gen_pc, gen_pcalau12i) +TRANS(pcaddu12i, gen_pc, gen_pcaddu12i) +TRANS(pcaddu18i, gen_pc, gen_pcaddu18i) +TRANS(andi, gen_rr_i, EXT_NONE, EXT_NONE, tcg_gen_and_tl) +TRANS(ori, gen_rr_i, EXT_NONE, EXT_NONE, tcg_gen_or_tl) +TRANS(xori, gen_rr_i, EXT_NONE, EXT_NONE, tcg_gen_xor_tl) diff --git a/target/loongarch/insns.decode b/target/loongarch/insns.decode new file mode 100644 index 0000000..8579c11 --- /dev/null +++ b/target/loongarch/insns.decode @@ -0,0 +1,79 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# +# LoongArch instruction decode definitions. +# +# Copyright (c) 2021 Loongson Technology Corporation Limited +# + +# +# Fields +# +%sa2p1 15:2 !function=plus_1 + +# +# Argument sets +# +&r_i rd imm +&rrr rd rj rk +&rr_i rd rj imm +&rrr_sa rd rj rk sa + +# +# Formats +# +@rrr .... ........ ..... rk:5 rj:5 rd:5 &rrr +@r_i20 .... ... imm:s20 rd:5 &r_i +@rr_i12 .... ...... imm:s12 rj:5 rd:5 &rr_i +@rr_ui12 .... ...... imm:12 rj:5 rd:5 &rr_i +@rr_i16 .... .. imm:s16 rj:5 rd:5 &rr_i +@rrr_sa2p1 .... ........ ... .. rk:5 rj:5 rd:5 &rrr_sa sa=%sa2p1 + +# +# Fixed point arithmetic operation instruction +# +add_w 0000 00000001 00000 ..... ..... ..... @rrr +add_d 0000 00000001 00001 ..... ..... ..... @rrr +sub_w 0000 00000001 00010 ..... ..... ..... @rrr +sub_d 0000 00000001 00011 ..... ..... ..... @rrr +slt 0000 00000001 00100 ..... ..... ..... @rrr +sltu 0000 00000001 00101 ..... ..... ..... @rrr +slti 0000 001000 ............ ..... ..... @rr_i12 +sltui 0000 001001 ............ ..... ..... @rr_i12 +nor 0000 00000001 01000 ..... ..... ..... @rrr +and 0000 00000001 01001 ..... ..... ..... @rrr +or 0000 00000001 01010 ..... ..... ..... @rrr +xor 0000 00000001 01011 ..... ..... ..... @rrr +orn 0000 00000001 01100 ..... ..... ..... @rrr +andn 0000 00000001 01101 ..... ..... ..... @rrr +mul_w 0000 00000001 11000 ..... ..... ..... @rrr +mulh_w 0000 00000001 11001 ..... ..... ..... @rrr +mulh_wu 0000 00000001 11010 ..... ..... ..... @rrr +mul_d 0000 00000001 11011 ..... ..... ..... @rrr +mulh_d 0000 00000001 11100 ..... ..... ..... @rrr +mulh_du 0000 00000001 11101 ..... ..... ..... @rrr +mulw_d_w 0000 00000001 11110 ..... ..... ..... @rrr +mulw_d_wu 0000 00000001 11111 ..... ..... ..... @rrr +div_w 0000 00000010 00000 ..... ..... ..... @rrr +mod_w 0000 00000010 00001 ..... ..... ..... @rrr +div_wu 0000 00000010 00010 ..... ..... ..... @rrr +mod_wu 0000 00000010 00011 ..... ..... ..... @rrr +div_d 0000 00000010 00100 ..... ..... ..... @rrr +mod_d 0000 00000010 00101 ..... ..... ..... @rrr +div_du 0000 00000010 00110 ..... ..... ..... @rrr +mod_du 0000 00000010 00111 ..... ..... ..... @rrr +alsl_w 0000 00000000 010 .. ..... ..... ..... @rrr_sa2p1 +alsl_wu 0000 00000000 011 .. ..... ..... ..... @rrr_sa2p1 +alsl_d 0000 00000010 110 .. ..... ..... ..... @rrr_sa2p1 +lu12i_w 0001 010 .................... ..... @r_i20 +lu32i_d 0001 011 .................... ..... @r_i20 +lu52i_d 0000 001100 ............ ..... ..... @rr_i12 +pcaddi 0001 100 .................... ..... @r_i20 +pcalau12i 0001 101 .................... ..... @r_i20 +pcaddu12i 0001 110 .................... ..... @r_i20 +pcaddu18i 0001 111 .................... ..... @r_i20 +addi_w 0000 001010 ............ ..... ..... @rr_i12 +addi_d 0000 001011 ............ ..... ..... @rr_i12 +addu16i_d 0001 00 ................ ..... ..... @rr_i16 +andi 0000 001101 ............ ..... ..... @rr_ui12 +ori 0000 001110 ............ ..... ..... @rr_ui12 +xori 0000 001111 ............ ..... ..... @rr_ui12 diff --git a/target/loongarch/translate.c b/target/loongarch/translate.c index 048c895..3de18ef 100644 --- a/target/loongarch/translate.c +++ b/target/loongarch/translate.c @@ -26,6 +26,11 @@ TCGv_i64 cpu_fpr[32]; #define DISAS_STOP DISAS_TARGET_0 +static inline int plus_1(DisasContext *ctx, int x) +{ + return x + 1; +} + void generate_exception(DisasContext *ctx, int excp) { tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next); @@ -57,6 +62,11 @@ static void loongarch_tr_init_disas_context(DisasContextBase *dcbase, /* Bound the number of insns to execute to those left on the page. */ bound = -(ctx->base.pc_first | TARGET_PAGE_MASK) / 4; ctx->base.max_insns = MIN(ctx->base.max_insns, bound); + + ctx->ntemp = 0; + memset(ctx->temp, 0, sizeof(ctx->temp)); + + ctx->zero = tcg_constant_tl(0); } static void loongarch_tr_tb_start(DisasContextBase *dcbase, CPUState *cs) @@ -70,6 +80,73 @@ static void loongarch_tr_insn_start(DisasContextBase *dcbase, CPUState *cs) tcg_gen_insn_start(ctx->base.pc_next); } +/* + * Wrappers for getting reg values. + * + * The $zero register does not have cpu_gpr[0] allocated -- we supply the + * constant zero as a source, and an uninitialized sink as destination. + * + * Further, we may provide an extension for word operations. + */ +static TCGv temp_new(DisasContext *ctx) +{ + assert(ctx->ntemp < ARRAY_SIZE(ctx->temp)); + return ctx->temp[ctx->ntemp++] = tcg_temp_new(); +} + +static TCGv gpr_src(DisasContext *ctx, int reg_num, DisasExtend src_ext) +{ + TCGv t; + + if (reg_num == 0) { + return ctx->zero; + } + + switch (src_ext) { + case EXT_NONE: + return cpu_gpr[reg_num]; + case EXT_SIGN: + t = temp_new(ctx); + tcg_gen_ext32s_tl(t, cpu_gpr[reg_num]); + return t; + case EXT_ZERO: + t = temp_new(ctx); + tcg_gen_ext32u_tl(t, cpu_gpr[reg_num]); + return t; + } + g_assert_not_reached(); +} + +static TCGv gpr_dst(DisasContext *ctx, int reg_num, DisasExtend dst_ext) +{ + if (reg_num == 0 || dst_ext) { + return temp_new(ctx); + } + return cpu_gpr[reg_num]; +} + +static void gen_set_gpr(int reg_num, TCGv t, DisasExtend dst_ext) +{ + if (reg_num != 0) { + switch (dst_ext) { + case EXT_NONE: + tcg_gen_mov_tl(cpu_gpr[reg_num], t); + break; + case EXT_SIGN: + tcg_gen_ext32s_tl(cpu_gpr[reg_num], t); + break; + case EXT_ZERO: + tcg_gen_ext32u_tl(cpu_gpr[reg_num], t); + break; + default: + g_assert_not_reached(); + } + } +} + +#include "decode-insns.c.inc" +#include "insn_trans/trans_arith.c.inc" + static void loongarch_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs) { CPULoongArchState *env = cs->env_ptr; @@ -83,6 +160,12 @@ static void loongarch_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs) generate_exception(ctx, EXCP_INE); } + for (int i = ctx->ntemp - 1; i >= 0; --i) { + tcg_temp_free(ctx->temp[i]); + ctx->temp[i] = NULL; + } + ctx->ntemp = 0; + ctx->base.pc_next += 4; } diff --git a/target/loongarch/translate.h b/target/loongarch/translate.h index 6cc7f1a..9cc1251 100644 --- a/target/loongarch/translate.h +++ b/target/loongarch/translate.h @@ -10,11 +10,30 @@ #include "exec/translator.h" +#define TRANS(NAME, FUNC, ...) \ + static bool trans_##NAME(DisasContext *ctx, arg_##NAME * a) \ + { return FUNC(ctx, a, __VA_ARGS__); } + +/* + * If an operation is being performed on less than TARGET_LONG_BITS, + * it may require the inputs to be sign- or zero-extended; which will + * depend on the exact operation being performed. + */ +typedef enum { + EXT_NONE, + EXT_SIGN, + EXT_ZERO, +} DisasExtend; + typedef struct DisasContext { DisasContextBase base; target_ulong page_start; uint32_t opcode; int mem_idx; + TCGv zero; + /* Space for 3 operands plus 1 extra for address computation. */ + TCGv temp[4]; + uint8_t ntemp; } DisasContext; void generate_exception(DisasContext *ctx, int excp); From patchwork Fri Nov 19 06:13:09 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: gaosong X-Patchwork-Id: 1556912 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4HwRHM1k65z9sWJ for ; Fri, 19 Nov 2021 17:15:41 +1100 (AEDT) Received: from localhost ([::1]:42524 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mnxBR-0003qt-UM for incoming@patchwork.ozlabs.org; Fri, 19 Nov 2021 01:15:37 -0500 Received: from eggs.gnu.org ([209.51.188.92]:46192) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mnx9c-0003qV-Gy for qemu-devel@nongnu.org; Fri, 19 Nov 2021 01:13:44 -0500 Received: from mail.loongson.cn ([114.242.206.163]:46590 helo=loongson.cn) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mnx9Y-0004X8-U1 for qemu-devel@nongnu.org; Fri, 19 Nov 2021 01:13:44 -0500 Received: from kvm-dev1.localdomain (unknown [10.2.5.134]) by mail.loongson.cn (Coremail) with SMTP id AQAAf9Dxj8+KQJdhSG0AAA--.1952S7; Fri, 19 Nov 2021 14:13:36 +0800 (CST) From: Song Gao To: qemu-devel@nongnu.org Subject: [PATCH v11 05/26] target/loongarch: Add fixed point shift instruction translation Date: Fri, 19 Nov 2021 14:13:09 +0800 Message-Id: <1637302410-24632-6-git-send-email-gaosong@loongson.cn> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1637302410-24632-1-git-send-email-gaosong@loongson.cn> References: <1637302410-24632-1-git-send-email-gaosong@loongson.cn> X-CM-TRANSID: AQAAf9Dxj8+KQJdhSG0AAA--.1952S7 X-Coremail-Antispam: 1UD129KBjvJXoW3Wry3Cr4rKFWUGF17Aw47Jwb_yoWxCr1Dpr 1UCryUGr48XrnxAr1Svw45uFyDXwnrCa1jg3yftr15Ar4UXF1DJr4qk39I9rW7twn3XrW8 ZFZ5urWjgryrJaUanT9S1TB71UUUUUUqnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnUUvcSsGvfC2KfnxnUUI43ZEXa7xR_UUUUUUUUU== X-CM-SenderInfo: 5jdr20tqj6z05rqj20fqof0/ Received-SPF: pass client-ip=114.242.206.163; envelope-from=gaosong@loongson.cn; helo=loongson.cn X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Xiaojuan Yang , richard.henderson@linaro.org, laurent@vivier.eu Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" This includes: - SLL.W, SRL.W, SRA.W, ROTR.W - SLLI.W, SRLI.W, SRAI.W, ROTRI.W - SLL.D, SRL.D, SRA.D, ROTR.D - SLLI.D, SRLI.D, SRAI.D, ROTRI.D Signed-off-by: Song Gao Signed-off-by: Xiaojuan Yang Reviewed-by: Richard Henderson --- target/loongarch/insn_trans/trans_shift.c.inc | 128 ++++++++++++++++++++++++++ target/loongarch/insns.decode | 22 +++++ target/loongarch/translate.c | 1 + 3 files changed, 151 insertions(+) create mode 100644 target/loongarch/insn_trans/trans_shift.c.inc diff --git a/target/loongarch/insn_trans/trans_shift.c.inc b/target/loongarch/insn_trans/trans_shift.c.inc new file mode 100644 index 0000000..ea2a612 --- /dev/null +++ b/target/loongarch/insn_trans/trans_shift.c.inc @@ -0,0 +1,128 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (c) 2021 Loongson Technology Corporation Limited + */ + +static bool gen_shift(DisasContext *ctx, arg_rr_i *a, + void(*func)(TCGv, TCGv, TCGv)) +{ + TCGv dest = gpr_dst(ctx, a->rd, EXT_SIGN); + TCGv src1 = gpr_src(ctx, a->rj, EXT_ZERO); + TCGv src2 = tcg_constant_tl(a->imm); + + func(dest, src1, src2); + gen_set_gpr(a->rd, dest, EXT_SIGN); + + return true; +} + +static bool gen_shift_i(DisasContext *ctx, arg_rr_i *a, + void(*func)(TCGv, TCGv, target_long)) +{ + TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE); + TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE); + + func(dest, src1, a->imm); + + return true; +} + +static void gen_sll_w(TCGv dest, TCGv src1, TCGv src2) +{ + TCGv t0 = tcg_temp_new(); + tcg_gen_andi_tl(t0, src2, 0x1f); + tcg_gen_shl_tl(dest, src1, t0); + tcg_temp_free(t0); +} + +static void gen_srl_w(TCGv dest, TCGv src1, TCGv src2) +{ + TCGv t0 = tcg_temp_new(); + tcg_gen_andi_tl(t0, src2, 0x1f); + tcg_gen_shr_tl(dest, src1, t0); + tcg_temp_free(t0); +} + +static void gen_sra_w(TCGv dest, TCGv src1, TCGv src2) +{ + TCGv t0 = tcg_temp_new(); + tcg_gen_andi_tl(t0, src2, 0x1f); + tcg_gen_sar_tl(dest, src1, t0); + tcg_temp_free(t0); +} + +static void gen_sll_d(TCGv dest, TCGv src1, TCGv src2) +{ + TCGv t0 = tcg_temp_new(); + tcg_gen_andi_tl(t0, src2, 0x3f); + tcg_gen_shl_tl(dest, src1, t0); + tcg_temp_free(t0); +} + +static void gen_srl_d(TCGv dest, TCGv src1, TCGv src2) +{ + TCGv t0 = tcg_temp_new(); + tcg_gen_andi_tl(t0, src2, 0x3f); + tcg_gen_shr_tl(dest, src1, t0); + tcg_temp_free(t0); +} + +static void gen_sra_d(TCGv dest, TCGv src1, TCGv src2) +{ + TCGv t0 = tcg_temp_new(); + tcg_gen_andi_tl(t0, src2, 0x3f); + tcg_gen_sar_tl(dest, src1, t0); + tcg_temp_free(t0); +} + +static void gen_rotr_w(TCGv dest, TCGv src1, TCGv src2) +{ + TCGv_i32 t1 = tcg_temp_new_i32(); + TCGv_i32 t2 = tcg_temp_new_i32(); + TCGv t0 = tcg_temp_new(); + + tcg_gen_andi_tl(t0, src2, 0x1f); + + tcg_gen_trunc_tl_i32(t1, src1); + tcg_gen_trunc_tl_i32(t2, t0); + + tcg_gen_rotr_i32(t1, t1, t2); + tcg_gen_ext_i32_tl(dest, t1); + + tcg_temp_free_i32(t1); + tcg_temp_free_i32(t2); + tcg_temp_free(t0); +} + +static void gen_rotr_d(TCGv dest, TCGv src1, TCGv src2) +{ + TCGv t0 = tcg_temp_new(); + tcg_gen_andi_tl(t0, src2, 0x3f); + tcg_gen_rotr_tl(dest, src1, t0); + tcg_temp_free(t0); +} + +static bool trans_srai_w(DisasContext *ctx, arg_srai_w *a) +{ + TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE); + TCGv src1 = gpr_src(ctx, a->rj, EXT_ZERO); + + tcg_gen_sextract_tl(dest, src1, a->imm, 32 - a->imm); + return true; +} + +TRANS(sll_w, gen_rrr, EXT_ZERO, EXT_NONE, EXT_SIGN, gen_sll_w) +TRANS(srl_w, gen_rrr, EXT_ZERO, EXT_NONE, EXT_SIGN, gen_srl_w) +TRANS(sra_w, gen_rrr, EXT_SIGN, EXT_NONE, EXT_SIGN, gen_sra_w) +TRANS(sll_d, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, gen_sll_d) +TRANS(srl_d, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, gen_srl_d) +TRANS(sra_d, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, gen_sra_d) +TRANS(rotr_w, gen_rrr, EXT_ZERO, EXT_NONE, EXT_SIGN, gen_rotr_w) +TRANS(rotr_d, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, gen_rotr_d) +TRANS(slli_w, gen_shift, tcg_gen_shl_tl) +TRANS(slli_d, gen_shift_i, tcg_gen_shli_tl) +TRANS(srli_w, gen_shift, tcg_gen_shr_tl) +TRANS(srli_d, gen_shift_i, tcg_gen_shri_tl) +TRANS(srai_d, gen_shift_i, tcg_gen_sari_tl) +TRANS(rotri_w, gen_shift, gen_rotr_w) +TRANS(rotri_d, gen_shift_i, tcg_gen_rotri_tl) diff --git a/target/loongarch/insns.decode b/target/loongarch/insns.decode index 8579c11..673aee4 100644 --- a/target/loongarch/insns.decode +++ b/target/loongarch/insns.decode @@ -23,6 +23,8 @@ # @rrr .... ........ ..... rk:5 rj:5 rd:5 &rrr @r_i20 .... ... imm:s20 rd:5 &r_i +@rr_ui5 .... ........ ..... imm:5 rj:5 rd:5 &rr_i +@rr_ui6 .... ........ .... imm:6 rj:5 rd:5 &rr_i @rr_i12 .... ...... imm:s12 rj:5 rd:5 &rr_i @rr_ui12 .... ...... imm:12 rj:5 rd:5 &rr_i @rr_i16 .... .. imm:s16 rj:5 rd:5 &rr_i @@ -77,3 +79,23 @@ addu16i_d 0001 00 ................ ..... ..... @rr_i16 andi 0000 001101 ............ ..... ..... @rr_ui12 ori 0000 001110 ............ ..... ..... @rr_ui12 xori 0000 001111 ............ ..... ..... @rr_ui12 + +# +# Fixed point shift operation instruction +# +sll_w 0000 00000001 01110 ..... ..... ..... @rrr +srl_w 0000 00000001 01111 ..... ..... ..... @rrr +sra_w 0000 00000001 10000 ..... ..... ..... @rrr +sll_d 0000 00000001 10001 ..... ..... ..... @rrr +srl_d 0000 00000001 10010 ..... ..... ..... @rrr +sra_d 0000 00000001 10011 ..... ..... ..... @rrr +rotr_w 0000 00000001 10110 ..... ..... ..... @rrr +rotr_d 0000 00000001 10111 ..... ..... ..... @rrr +slli_w 0000 00000100 00001 ..... ..... ..... @rr_ui5 +slli_d 0000 00000100 0001 ...... ..... ..... @rr_ui6 +srli_w 0000 00000100 01001 ..... ..... ..... @rr_ui5 +srli_d 0000 00000100 0101 ...... ..... ..... @rr_ui6 +srai_w 0000 00000100 10001 ..... ..... ..... @rr_ui5 +srai_d 0000 00000100 1001 ...... ..... ..... @rr_ui6 +rotri_w 0000 00000100 11001 ..... ..... ..... @rr_ui5 +rotri_d 0000 00000100 1101 ...... ..... ..... @rr_ui6 diff --git a/target/loongarch/translate.c b/target/loongarch/translate.c index 3de18ef..f90b63a 100644 --- a/target/loongarch/translate.c +++ b/target/loongarch/translate.c @@ -146,6 +146,7 @@ static void gen_set_gpr(int reg_num, TCGv t, DisasExtend dst_ext) #include "decode-insns.c.inc" #include "insn_trans/trans_arith.c.inc" +#include "insn_trans/trans_shift.c.inc" static void loongarch_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs) { From patchwork Fri Nov 19 06:13:10 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: gaosong X-Patchwork-Id: 1556917 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4HwRQ61wj5z9sXN for ; Fri, 19 Nov 2021 17:21:34 +1100 (AEDT) Received: from localhost ([::1]:51020 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mnxHA-0001W3-3Q for incoming@patchwork.ozlabs.org; Fri, 19 Nov 2021 01:21:32 -0500 Received: from eggs.gnu.org ([209.51.188.92]:46268) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mnx9i-0003rd-8S for qemu-devel@nongnu.org; Fri, 19 Nov 2021 01:13:50 -0500 Received: from mail.loongson.cn ([114.242.206.163]:46602 helo=loongson.cn) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mnx9Z-0004XA-2g for qemu-devel@nongnu.org; Fri, 19 Nov 2021 01:13:46 -0500 Received: from kvm-dev1.localdomain (unknown [10.2.5.134]) by mail.loongson.cn (Coremail) with SMTP id AQAAf9Dxj8+KQJdhSG0AAA--.1952S8; Fri, 19 Nov 2021 14:13:38 +0800 (CST) From: Song Gao To: qemu-devel@nongnu.org Subject: [PATCH v11 06/26] target/loongarch: Add fixed point bit instruction translation Date: Fri, 19 Nov 2021 14:13:10 +0800 Message-Id: <1637302410-24632-7-git-send-email-gaosong@loongson.cn> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1637302410-24632-1-git-send-email-gaosong@loongson.cn> References: <1637302410-24632-1-git-send-email-gaosong@loongson.cn> X-CM-TRANSID: AQAAf9Dxj8+KQJdhSG0AAA--.1952S8 X-Coremail-Antispam: 1UD129KBjvAXoW3Kw15ZF4xtFy5uFWDZw1xAFb_yoW8JF1kCo W7GF1UJr48GryY9FyUCa4kXrWxtF1jka1xJ3s3uw1UW3W8Jry7try8KFs8Z3y8Jr1qgFyr JF9agFyrJ3yrXrn7n29KB7ZKAUJUUUUU529EdanIXcx71UUUUU7v73VFW2AGmfu7bjvjm3 AaLaJ3UjIYCTnIWjDUYxBIdaVFxhVjvjDU0xZFpf9x0zRUUUUUUUUU= X-CM-SenderInfo: 5jdr20tqj6z05rqj20fqof0/ Received-SPF: pass client-ip=114.242.206.163; envelope-from=gaosong@loongson.cn; helo=loongson.cn X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Xiaojuan Yang , richard.henderson@linaro.org, laurent@vivier.eu Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" This includes: - EXT.W.{B/H} - CL{O/Z}.{W/D}, CT{O/Z}.{W/D} - BYTEPICK.{W/D} - REVB.{2H/4H/2W/D} - REVH.{2W/D} - BITREV.{4B/8B}, BITREV.{W/D} - BSTRINS.{W/D}, BSTRPICK.{W/D} - MASKEQZ, MASKNEZ Signed-off-by: Song Gao Signed-off-by: Xiaojuan Yang Reviewed-by: Richard Henderson --- target/loongarch/helper.h | 4 + target/loongarch/insn_trans/trans_bit.c.inc | 252 ++++++++++++++++++++++++++++ target/loongarch/insns.decode | 40 +++++ target/loongarch/op_helper.c | 22 +++ target/loongarch/translate.c | 1 + 5 files changed, 319 insertions(+) create mode 100644 target/loongarch/insn_trans/trans_bit.c.inc diff --git a/target/loongarch/helper.h b/target/loongarch/helper.h index eb771c0..04e0245 100644 --- a/target/loongarch/helper.h +++ b/target/loongarch/helper.h @@ -4,3 +4,7 @@ */ DEF_HELPER_2(raise_exception, noreturn, env, i32) + +DEF_HELPER_FLAGS_1(bitrev_w, TCG_CALL_NO_RWG_SE, tl, tl) +DEF_HELPER_FLAGS_1(bitrev_d, TCG_CALL_NO_RWG_SE, tl, tl) +DEF_HELPER_FLAGS_1(bitswap, TCG_CALL_NO_RWG_SE, tl, tl) diff --git a/target/loongarch/insn_trans/trans_bit.c.inc b/target/loongarch/insn_trans/trans_bit.c.inc new file mode 100644 index 0000000..5063773 --- /dev/null +++ b/target/loongarch/insn_trans/trans_bit.c.inc @@ -0,0 +1,252 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (c) 2021 Loongson Technology Corporation Limited + */ + +static bool gen_rr(DisasContext *ctx, arg_rr *a, + DisasExtend src_ext, DisasExtend dst_ext, + void (*func)(TCGv, TCGv)) +{ + TCGv dest = gpr_dst(ctx, a->rd, dst_ext); + TCGv src1 = gpr_src(ctx, a->rj, src_ext); + + func(dest, src1); + + if (dst_ext) { + gen_set_gpr(a->rd, dest, dst_ext); + } + return true; +} + +static bool trans_bytepick_w(DisasContext *ctx, arg_bytepick_w *a) +{ + TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE); + TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE); + TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE); + + tcg_gen_concat_tl_i64(dest, src1, src2); + tcg_gen_sextract_i64(dest, dest, (32 - (a->sa) * 8), 32); + + return true; +} + +static bool trans_bytepick_d(DisasContext *ctx, arg_bytepick_d *a) +{ + TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE); + TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE); + TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE); + + tcg_gen_extract2_i64(dest, src1, src2, (64 - (a->sa) * 8)); + return true; +} + +static bool trans_bstrins_w(DisasContext *ctx, arg_bstrins_w *a) +{ + TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE); + TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE); + + if (a->lsbw > a->msbw) { + return false; + } + + tcg_gen_deposit_tl(dest, dest, src1, a->lsbw, a->msbw - a->lsbw + 1); + tcg_gen_ext32s_tl(dest, dest); + + return true; +} + +static bool trans_bstrins_d(DisasContext *ctx, arg_bstrins_d *a) +{ + TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE); + TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE); + + if (a->lsbd > a->msbd) { + return false; + } + + tcg_gen_deposit_tl(dest, dest, src1, a->lsbd, a->msbd - a->lsbd + 1); + return true; +} + +static bool trans_bstrpick_w(DisasContext *ctx, arg_bstrpick_w *a) +{ + TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE); + TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE); + + if (a->lsbw > a->msbw) { + return false; + } + + tcg_gen_extract_tl(dest, src1, a->lsbw, a->msbw - a->lsbw + 1); + tcg_gen_ext32s_tl(dest, dest); + return true; +} + +static bool trans_bstrpick_d(DisasContext *ctx, arg_bstrpick_d *a) +{ + TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE); + TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE); + + if (a->lsbd > a->msbd) { + return false; + } + + tcg_gen_extract_tl(dest, src1, a->lsbd, a->msbd - a->lsbd + 1); + return true; +} + +static void gen_clz_w(TCGv dest, TCGv src1) +{ + tcg_gen_clzi_tl(dest, src1, TARGET_LONG_BITS); + tcg_gen_subi_tl(dest, dest, TARGET_LONG_BITS - 32); +} + +static void gen_clo_w(TCGv dest, TCGv src1) +{ + tcg_gen_not_tl(dest, src1); + tcg_gen_ext32u_tl(dest, dest); + gen_clz_w(dest, dest); +} + +static void gen_ctz_w(TCGv dest, TCGv src1) +{ + tcg_gen_ori_tl(dest, src1, (target_ulong)MAKE_64BIT_MASK(32, 32)); + tcg_gen_ctzi_tl(dest, dest, 32); +} + +static void gen_cto_w(TCGv dest, TCGv src1) +{ + tcg_gen_not_tl(dest, src1); + tcg_gen_ext32u_tl(dest, dest); + gen_ctz_w(dest, dest); +} + +static void gen_clz_d(TCGv dest, TCGv src1) +{ + tcg_gen_clzi_i64(dest, src1, TARGET_LONG_BITS); +} + +static void gen_clo_d(TCGv dest, TCGv src1) +{ + tcg_gen_not_tl(dest, src1); + gen_clz_d(dest, dest); +} + +static void gen_ctz_d(TCGv dest, TCGv src1) +{ + tcg_gen_ctzi_tl(dest, src1, TARGET_LONG_BITS); +} + +static void gen_cto_d(TCGv dest, TCGv src1) +{ + tcg_gen_not_tl(dest, src1); + gen_ctz_d(dest, dest); +} + +static void gen_revb_2w(TCGv dest, TCGv src1) +{ + tcg_gen_bswap64_i64(dest, src1); + tcg_gen_rotri_i64(dest, dest, 32); +} + +static void gen_revb_2h(TCGv dest, TCGv src1) +{ + TCGv mask = tcg_constant_tl(0x00FF00FF); + TCGv t0 = tcg_temp_new(); + TCGv t1 = tcg_temp_new(); + + tcg_gen_shri_tl(t0, src1, 8); + tcg_gen_and_tl(t0, t0, mask); + tcg_gen_and_tl(t1, src1, mask); + tcg_gen_shli_tl(t1, t1, 8); + tcg_gen_or_tl(dest, t0, t1); + + tcg_temp_free(t0); + tcg_temp_free(t1); +} + +static void gen_revb_4h(TCGv dest, TCGv src1) +{ + TCGv mask = tcg_constant_tl(0x00FF00FF00FF00FFULL); + TCGv t0 = tcg_temp_new(); + TCGv t1 = tcg_temp_new(); + + tcg_gen_shri_tl(t0, src1, 8); + tcg_gen_and_tl(t0, t0, mask); + tcg_gen_and_tl(t1, src1, mask); + tcg_gen_shli_tl(t1, t1, 8); + tcg_gen_or_tl(dest, t0, t1); + + tcg_temp_free(t0); + tcg_temp_free(t1); +} + +static void gen_revh_2w(TCGv dest, TCGv src1) +{ + TCGv_i64 t0 = tcg_temp_new_i64(); + TCGv_i64 t1 = tcg_temp_new_i64(); + TCGv_i64 mask = tcg_constant_i64(0x0000ffff0000ffffull); + + tcg_gen_shri_i64(t0, src1, 16); + tcg_gen_and_i64(t1, src1, mask); + tcg_gen_and_i64(t0, t0, mask); + tcg_gen_shli_i64(t1, t1, 16); + tcg_gen_or_i64(dest, t1, t0); + + tcg_temp_free_i64(t0); + tcg_temp_free_i64(t1); +} + +static void gen_revh_d(TCGv dest, TCGv src1) +{ + TCGv t0 = tcg_temp_new(); + TCGv t1 = tcg_temp_new(); + TCGv mask = tcg_constant_tl(0x0000FFFF0000FFFFULL); + + tcg_gen_shri_tl(t1, src1, 16); + tcg_gen_and_tl(t1, t1, mask); + tcg_gen_and_tl(t0, src1, mask); + tcg_gen_shli_tl(t0, t0, 16); + tcg_gen_or_tl(t0, t0, t1); + tcg_gen_rotri_tl(dest, t0, 32); + + tcg_temp_free(t0); + tcg_temp_free(t1); +} + +static void gen_maskeqz(TCGv dest, TCGv src1, TCGv src2) +{ + TCGv zero = tcg_constant_tl(0); + + tcg_gen_movcond_tl(TCG_COND_EQ, dest, src2, zero, zero, src1); +} + +static void gen_masknez(TCGv dest, TCGv src1, TCGv src2) +{ + TCGv zero = tcg_constant_tl(0); + + tcg_gen_movcond_tl(TCG_COND_NE, dest, src2, zero, zero, src1); +} + +TRANS(ext_w_h, gen_rr, EXT_NONE, EXT_NONE, tcg_gen_ext16s_tl) +TRANS(ext_w_b, gen_rr, EXT_NONE, EXT_NONE, tcg_gen_ext8s_tl) +TRANS(clo_w, gen_rr, EXT_NONE, EXT_NONE, gen_clo_w) +TRANS(clz_w, gen_rr, EXT_ZERO, EXT_NONE, gen_clz_w) +TRANS(cto_w, gen_rr, EXT_NONE, EXT_NONE, gen_cto_w) +TRANS(ctz_w, gen_rr, EXT_NONE, EXT_NONE, gen_ctz_w) +TRANS(clo_d, gen_rr, EXT_NONE, EXT_NONE, gen_clo_d) +TRANS(clz_d, gen_rr, EXT_NONE, EXT_NONE, gen_clz_d) +TRANS(cto_d, gen_rr, EXT_NONE, EXT_NONE, gen_cto_d) +TRANS(ctz_d, gen_rr, EXT_NONE, EXT_NONE, gen_ctz_d) +TRANS(revb_2h, gen_rr, EXT_NONE, EXT_SIGN, gen_revb_2h) +TRANS(revb_4h, gen_rr, EXT_NONE, EXT_NONE, gen_revb_4h) +TRANS(revb_2w, gen_rr, EXT_NONE, EXT_NONE, gen_revb_2w) +TRANS(revb_d, gen_rr, EXT_NONE, EXT_NONE, tcg_gen_bswap64_i64) +TRANS(revh_2w, gen_rr, EXT_NONE, EXT_NONE, gen_revh_2w) +TRANS(revh_d, gen_rr, EXT_NONE, EXT_NONE, gen_revh_d) +TRANS(bitrev_4b, gen_rr, EXT_ZERO, EXT_SIGN, gen_helper_bitswap) +TRANS(bitrev_8b, gen_rr, EXT_NONE, EXT_NONE, gen_helper_bitswap) +TRANS(bitrev_w, gen_rr, EXT_NONE, EXT_SIGN, gen_helper_bitrev_w) +TRANS(bitrev_d, gen_rr, EXT_NONE, EXT_NONE, gen_helper_bitrev_d) +TRANS(maskeqz, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, gen_maskeqz) +TRANS(masknez, gen_rrr, EXT_NONE, EXT_NONE, EXT_NONE, gen_masknez) diff --git a/target/loongarch/insns.decode b/target/loongarch/insns.decode index 673aee4..4533706 100644 --- a/target/loongarch/insns.decode +++ b/target/loongarch/insns.decode @@ -14,13 +14,17 @@ # Argument sets # &r_i rd imm +&rr rd rj &rrr rd rj rk &rr_i rd rj imm &rrr_sa rd rj rk sa +&rr_2bw rd rj msbw lsbw +&rr_2bd rd rj msbd lsbd # # Formats # +@rr .... ........ ..... ..... rj:5 rd:5 &rr @rrr .... ........ ..... rk:5 rj:5 rd:5 &rrr @r_i20 .... ... imm:s20 rd:5 &r_i @rr_ui5 .... ........ ..... imm:5 rj:5 rd:5 &rr_i @@ -29,6 +33,10 @@ @rr_ui12 .... ...... imm:12 rj:5 rd:5 &rr_i @rr_i16 .... .. imm:s16 rj:5 rd:5 &rr_i @rrr_sa2p1 .... ........ ... .. rk:5 rj:5 rd:5 &rrr_sa sa=%sa2p1 +@rrr_sa2 .... ........ ... sa:2 rk:5 rj:5 rd:5 &rrr_sa +@rrr_sa3 .... ........ .. sa:3 rk:5 rj:5 rd:5 &rrr_sa +@rr_2bw .... ....... msbw:5 . lsbw:5 rj:5 rd:5 &rr_2bw +@rr_2bd .... ...... msbd:6 lsbd:6 rj:5 rd:5 &rr_2bd # # Fixed point arithmetic operation instruction @@ -99,3 +107,35 @@ srai_w 0000 00000100 10001 ..... ..... ..... @rr_ui5 srai_d 0000 00000100 1001 ...... ..... ..... @rr_ui6 rotri_w 0000 00000100 11001 ..... ..... ..... @rr_ui5 rotri_d 0000 00000100 1101 ...... ..... ..... @rr_ui6 + +# +# Fixed point bit operation instruction +# +ext_w_h 0000 00000000 00000 10110 ..... ..... @rr +ext_w_b 0000 00000000 00000 10111 ..... ..... @rr +clo_w 0000 00000000 00000 00100 ..... ..... @rr +clz_w 0000 00000000 00000 00101 ..... ..... @rr +cto_w 0000 00000000 00000 00110 ..... ..... @rr +ctz_w 0000 00000000 00000 00111 ..... ..... @rr +clo_d 0000 00000000 00000 01000 ..... ..... @rr +clz_d 0000 00000000 00000 01001 ..... ..... @rr +cto_d 0000 00000000 00000 01010 ..... ..... @rr +ctz_d 0000 00000000 00000 01011 ..... ..... @rr +revb_2h 0000 00000000 00000 01100 ..... ..... @rr +revb_4h 0000 00000000 00000 01101 ..... ..... @rr +revb_2w 0000 00000000 00000 01110 ..... ..... @rr +revb_d 0000 00000000 00000 01111 ..... ..... @rr +revh_2w 0000 00000000 00000 10000 ..... ..... @rr +revh_d 0000 00000000 00000 10001 ..... ..... @rr +bitrev_4b 0000 00000000 00000 10010 ..... ..... @rr +bitrev_8b 0000 00000000 00000 10011 ..... ..... @rr +bitrev_w 0000 00000000 00000 10100 ..... ..... @rr +bitrev_d 0000 00000000 00000 10101 ..... ..... @rr +bytepick_w 0000 00000000 100 .. ..... ..... ..... @rrr_sa2 +bytepick_d 0000 00000000 11 ... ..... ..... ..... @rrr_sa3 +maskeqz 0000 00000001 00110 ..... ..... ..... @rrr +masknez 0000 00000001 00111 ..... ..... ..... @rrr +bstrins_w 0000 0000011 ..... 0 ..... ..... ..... @rr_2bw +bstrpick_w 0000 0000011 ..... 1 ..... ..... ..... @rr_2bw +bstrins_d 0000 000010 ...... ...... ..... ..... @rr_2bd +bstrpick_d 0000 000011 ...... ...... ..... ..... @rr_2bd diff --git a/target/loongarch/op_helper.c b/target/loongarch/op_helper.c index 9038109..1fc9d81 100644 --- a/target/loongarch/op_helper.c +++ b/target/loongarch/op_helper.c @@ -19,3 +19,25 @@ void helper_raise_exception(CPULoongArchState *env, uint32_t exception) { do_raise_exception(env, exception, GETPC()); } + + +target_ulong helper_bitrev_w(target_ulong rj) +{ + return (int32_t)revbit32(rj); +} + +target_ulong helper_bitrev_d(target_ulong rj) +{ + return revbit64(rj); +} + +target_ulong helper_bitswap(target_ulong v) +{ + v = ((v >> 1) & (target_ulong)0x5555555555555555ULL) | + ((v & (target_ulong)0x5555555555555555ULL) << 1); + v = ((v >> 2) & (target_ulong)0x3333333333333333ULL) | + ((v & (target_ulong)0x3333333333333333ULL) << 2); + v = ((v >> 4) & (target_ulong)0x0F0F0F0F0F0F0F0FULL) | + ((v & (target_ulong)0x0F0F0F0F0F0F0F0FULL) << 4); + return v; +} diff --git a/target/loongarch/translate.c b/target/loongarch/translate.c index f90b63a..c0875db 100644 --- a/target/loongarch/translate.c +++ b/target/loongarch/translate.c @@ -147,6 +147,7 @@ static void gen_set_gpr(int reg_num, TCGv t, DisasExtend dst_ext) #include "decode-insns.c.inc" #include "insn_trans/trans_arith.c.inc" #include "insn_trans/trans_shift.c.inc" +#include "insn_trans/trans_bit.c.inc" static void loongarch_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs) { From patchwork Fri Nov 19 06:13:11 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: gaosong X-Patchwork-Id: 1556913 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4HwRHW50NLz9sWJ for ; Fri, 19 Nov 2021 17:15:51 +1100 (AEDT) Received: from localhost ([::1]:42602 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mnxBd-0003wx-2M for incoming@patchwork.ozlabs.org; Fri, 19 Nov 2021 01:15:49 -0500 Received: from eggs.gnu.org ([209.51.188.92]:46264) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mnx9i-0003rb-0x for qemu-devel@nongnu.org; Fri, 19 Nov 2021 01:13:50 -0500 Received: from mail.loongson.cn ([114.242.206.163]:46616 helo=loongson.cn) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mnx9Z-0004XD-NA for qemu-devel@nongnu.org; Fri, 19 Nov 2021 01:13:46 -0500 Received: from kvm-dev1.localdomain (unknown [10.2.5.134]) by mail.loongson.cn (Coremail) with SMTP id AQAAf9Dxj8+KQJdhSG0AAA--.1952S9; Fri, 19 Nov 2021 14:13:39 +0800 (CST) From: Song Gao To: qemu-devel@nongnu.org Subject: [PATCH v11 07/26] target/loongarch: Add fixed point load/store instruction translation Date: Fri, 19 Nov 2021 14:13:11 +0800 Message-Id: <1637302410-24632-8-git-send-email-gaosong@loongson.cn> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1637302410-24632-1-git-send-email-gaosong@loongson.cn> References: <1637302410-24632-1-git-send-email-gaosong@loongson.cn> X-CM-TRANSID: AQAAf9Dxj8+KQJdhSG0AAA--.1952S9 X-Coremail-Antispam: 1UD129KBjvAXoW3Zw15Wr18Aw4rAryfGr4DJwb_yoW8Gr4UWo WUA3WUJr48Gr15AFyqkwnYqrW2yryj9an3J398uw1UGa4xAry7JryUGrn5ZayfJryjgryr Ga4fJF15Jw4fXrnrn29KB7ZKAUJUUUUU529EdanIXcx71UUUUU7v73VFW2AGmfu7bjvjm3 AaLaJ3UjIYCTnIWjDUYxBIdaVFxhVjvjDU0xZFpf9x0zRUUUUUUUUU= X-CM-SenderInfo: 5jdr20tqj6z05rqj20fqof0/ Received-SPF: pass client-ip=114.242.206.163; envelope-from=gaosong@loongson.cn; helo=loongson.cn X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Xiaojuan Yang , richard.henderson@linaro.org, laurent@vivier.eu Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" This includes: - LD.{B[U]/H[U]/W[U]/D}, ST.{B/H/W/D} - LDX.{B[U]/H[U]/W[U]/D}, STX.{B/H/W/D} - LDPTR.{W/D}, STPTR.{W/D} - PRELD - LD{GT/LE}.{B/H/W/D}, ST{GT/LE}.{B/H/W/D} - DBAR, IBAR Signed-off-by: Song Gao Signed-off-by: Xiaojuan Yang Reviewed-by: Richard Henderson --- target/loongarch/helper.h | 3 + target/loongarch/insn_trans/trans_memory.c.inc | 232 +++++++++++++++++++++++++ target/loongarch/insns.decode | 54 ++++++ target/loongarch/op_helper.c | 15 ++ target/loongarch/translate.c | 30 ++++ 5 files changed, 334 insertions(+) create mode 100644 target/loongarch/insn_trans/trans_memory.c.inc diff --git a/target/loongarch/helper.h b/target/loongarch/helper.h index 04e0245..2fe4e63 100644 --- a/target/loongarch/helper.h +++ b/target/loongarch/helper.h @@ -8,3 +8,6 @@ DEF_HELPER_2(raise_exception, noreturn, env, i32) DEF_HELPER_FLAGS_1(bitrev_w, TCG_CALL_NO_RWG_SE, tl, tl) DEF_HELPER_FLAGS_1(bitrev_d, TCG_CALL_NO_RWG_SE, tl, tl) DEF_HELPER_FLAGS_1(bitswap, TCG_CALL_NO_RWG_SE, tl, tl) + +DEF_HELPER_3(asrtle_d, void, env, tl, tl) +DEF_HELPER_3(asrtgt_d, void, env, tl, tl) diff --git a/target/loongarch/insn_trans/trans_memory.c.inc b/target/loongarch/insn_trans/trans_memory.c.inc new file mode 100644 index 0000000..1dd7deb --- /dev/null +++ b/target/loongarch/insn_trans/trans_memory.c.inc @@ -0,0 +1,232 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (c) 2021 Loongson Technology Corporation Limited + */ + +static bool gen_load(DisasContext *ctx, arg_rr_i *a, MemOp mop) +{ + TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE); + TCGv addr = gpr_src(ctx, a->rj, EXT_NONE); + TCGv temp = NULL; + + if (a->imm) { + temp = tcg_temp_new(); + tcg_gen_addi_tl(temp, addr, a->imm); + addr = temp; + } + + tcg_gen_qemu_ld_tl(dest, addr, ctx->mem_idx, mop); + + if (temp) { + tcg_temp_free(temp); + } + return true; +} + +static bool gen_store(DisasContext *ctx, arg_rr_i *a, MemOp mop) +{ + TCGv data = gpr_src(ctx, a->rd, EXT_NONE); + TCGv addr = gpr_src(ctx, a->rj, EXT_NONE); + TCGv temp = NULL; + + if (a->imm) { + temp = tcg_temp_new(); + tcg_gen_addi_tl(temp, addr, a->imm); + addr = temp; + } + + tcg_gen_qemu_st_tl(data, addr, ctx->mem_idx, mop); + + if (temp) { + tcg_temp_free(temp); + } + return true; +} + +static bool gen_loadx(DisasContext *ctx, arg_rrr *a, MemOp mop) +{ + TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE); + TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE); + TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE); + TCGv addr = tcg_temp_new(); + + tcg_gen_add_tl(addr, src1, src2); + tcg_gen_qemu_ld_tl(dest, addr, ctx->mem_idx, mop); + + tcg_temp_free(addr); + return true; +} + +static bool gen_storex(DisasContext *ctx, arg_rrr *a, MemOp mop) +{ + TCGv data = gpr_src(ctx, a->rd, EXT_NONE); + TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE); + TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE); + TCGv addr = tcg_temp_new(); + + tcg_gen_add_tl(addr, src1, src2); + tcg_gen_qemu_st_tl(data, addr, ctx->mem_idx, mop); + + tcg_temp_free(addr); + return true; +} + +static bool gen_load_gt(DisasContext *ctx, arg_rrr *a, MemOp mop) +{ + TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE); + TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE); + TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE); + TCGv addr = tcg_temp_new(); + + gen_helper_asrtgt_d(cpu_env, src1, src2); + tcg_gen_add_tl(addr, src1, src2); + tcg_gen_qemu_ld_tl(dest, addr, ctx->mem_idx, mop); + + tcg_temp_free(addr); + return true; +} + +static bool gen_load_le(DisasContext *ctx, arg_rrr *a, MemOp mop) +{ + TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE); + TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE); + TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE); + TCGv addr = tcg_temp_new(); + + gen_helper_asrtle_d(cpu_env, src1, src2); + tcg_gen_add_tl(addr, src1, src2); + tcg_gen_qemu_ld_tl(dest, addr, ctx->mem_idx, mop); + + tcg_temp_free(addr); + return true; +} + +static bool gen_store_gt(DisasContext *ctx, arg_rrr *a, MemOp mop) +{ + TCGv data = gpr_src(ctx, a->rd, EXT_NONE); + TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE); + TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE); + TCGv addr = tcg_temp_new(); + + gen_helper_asrtgt_d(cpu_env, src1, src2); + tcg_gen_add_tl(addr, src1, src2); + tcg_gen_qemu_st_tl(data, addr, ctx->mem_idx, mop); + + tcg_temp_free(addr); + return true; +} + +static bool gen_store_le(DisasContext *ctx, arg_rrr *a, MemOp mop) +{ + TCGv data = gpr_src(ctx, a->rd, EXT_NONE); + TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE); + TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE); + TCGv addr = tcg_temp_new(); + + gen_helper_asrtle_d(cpu_env, src1, src2); + tcg_gen_add_tl(addr, src1, src2); + tcg_gen_qemu_st_tl(data, addr, ctx->mem_idx, mop); + + tcg_temp_free(addr); + return true; +} + +static bool trans_preld(DisasContext *ctx, arg_preld *a) +{ + return true; +} + +static bool trans_dbar(DisasContext *ctx, arg_dbar * a) +{ + gen_loongarch_sync(a->imm); + return true; +} + +static bool trans_ibar(DisasContext *ctx, arg_ibar *a) +{ + ctx->base.is_jmp = DISAS_STOP; + return true; +} + +static bool gen_ldptr(DisasContext *ctx, arg_rr_i *a, MemOp mop) +{ + TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE); + TCGv addr = gpr_src(ctx, a->rj, EXT_NONE); + TCGv temp = NULL; + + if (a->imm) { + temp = tcg_temp_new(); + tcg_gen_addi_tl(temp, addr, a->imm << 2); + addr = temp; + } + + tcg_gen_qemu_ld_tl(dest, addr, ctx->mem_idx, mop); + + if (temp) { + tcg_temp_free(temp); + } + return true; +} + +static bool gen_stptr(DisasContext *ctx, arg_rr_i *a, MemOp mop) +{ + TCGv data = gpr_src(ctx, a->rd, EXT_NONE); + TCGv addr = gpr_src(ctx, a->rj, EXT_NONE); + TCGv temp = NULL; + + if (a->imm) { + temp = tcg_temp_new(); + tcg_gen_addi_tl(temp, addr, a->imm << 2); + addr = temp; + } + + tcg_gen_qemu_st_tl(data, addr, ctx->mem_idx, mop); + + if (temp) { + tcg_temp_free(temp); + } + return true; +} + +TRANS(ld_b, gen_load, MO_SB) +TRANS(ld_h, gen_load, MO_TESW) +TRANS(ld_w, gen_load, MO_TESL) +TRANS(ld_d, gen_load, MO_TEQ) +TRANS(st_b, gen_store, MO_SB) +TRANS(st_h, gen_store, MO_TESW) +TRANS(st_w, gen_store, MO_TESL) +TRANS(st_d, gen_store, MO_TEQ) +TRANS(ld_bu, gen_load, MO_UB) +TRANS(ld_hu, gen_load, MO_TEUW) +TRANS(ld_wu, gen_load, MO_TEUL) +TRANS(ldx_b, gen_loadx, MO_SB) +TRANS(ldx_h, gen_loadx, MO_TESW) +TRANS(ldx_w, gen_loadx, MO_TESL) +TRANS(ldx_d, gen_loadx, MO_TEQ) +TRANS(stx_b, gen_storex, MO_SB) +TRANS(stx_h, gen_storex, MO_TESW) +TRANS(stx_w, gen_storex, MO_TESL) +TRANS(stx_d, gen_storex, MO_TEQ) +TRANS(ldx_bu, gen_loadx, MO_UB) +TRANS(ldx_hu, gen_loadx, MO_TEUW) +TRANS(ldx_wu, gen_loadx, MO_TEUL) +TRANS(ldptr_w, gen_ldptr, MO_TESL) +TRANS(stptr_w, gen_stptr, MO_TESL) +TRANS(ldptr_d, gen_ldptr, MO_TEQ) +TRANS(stptr_d, gen_stptr, MO_TEQ) +TRANS(ldgt_b, gen_load_gt, MO_SB) +TRANS(ldgt_h, gen_load_gt, MO_TESW) +TRANS(ldgt_w, gen_load_gt, MO_TESL) +TRANS(ldgt_d, gen_load_gt, MO_TEQ) +TRANS(ldle_b, gen_load_le, MO_SB) +TRANS(ldle_h, gen_load_le, MO_TESW) +TRANS(ldle_w, gen_load_le, MO_TESL) +TRANS(ldle_d, gen_load_le, MO_TEQ) +TRANS(stgt_b, gen_store_gt, MO_SB) +TRANS(stgt_h, gen_store_gt, MO_TESW) +TRANS(stgt_w, gen_store_gt, MO_TESL) +TRANS(stgt_d, gen_store_gt, MO_TEQ) +TRANS(stle_b, gen_store_le, MO_SB) +TRANS(stle_h, gen_store_le, MO_TESW) +TRANS(stle_w, gen_store_le, MO_TESL) +TRANS(stle_d, gen_store_le, MO_TEQ) diff --git a/target/loongarch/insns.decode b/target/loongarch/insns.decode index 4533706..3f4ac76 100644 --- a/target/loongarch/insns.decode +++ b/target/loongarch/insns.decode @@ -13,10 +13,12 @@ # # Argument sets # +&i imm &r_i rd imm &rr rd rj &rrr rd rj rk &rr_i rd rj imm +&hint_r_i hint rj imm &rrr_sa rd rj rk sa &rr_2bw rd rj msbw lsbw &rr_2bd rd rj msbd lsbd @@ -24,6 +26,7 @@ # # Formats # +@i15 .... ........ ..... imm:15 &i @rr .... ........ ..... ..... rj:5 rd:5 &rr @rrr .... ........ ..... rk:5 rj:5 rd:5 &rrr @r_i20 .... ... imm:s20 rd:5 &r_i @@ -31,7 +34,9 @@ @rr_ui6 .... ........ .... imm:6 rj:5 rd:5 &rr_i @rr_i12 .... ...... imm:s12 rj:5 rd:5 &rr_i @rr_ui12 .... ...... imm:12 rj:5 rd:5 &rr_i +@rr_i14 .... .... imm:s14 rj:5 rd:5 &rr_i @rr_i16 .... .. imm:s16 rj:5 rd:5 &rr_i +@hint_r_i12 .... ...... imm:s12 rj:5 hint:5 &hint_r_i @rrr_sa2p1 .... ........ ... .. rk:5 rj:5 rd:5 &rrr_sa sa=%sa2p1 @rrr_sa2 .... ........ ... sa:2 rk:5 rj:5 rd:5 &rrr_sa @rrr_sa3 .... ........ .. sa:3 rk:5 rj:5 rd:5 &rrr_sa @@ -139,3 +144,52 @@ bstrins_w 0000 0000011 ..... 0 ..... ..... ..... @rr_2bw bstrpick_w 0000 0000011 ..... 1 ..... ..... ..... @rr_2bw bstrins_d 0000 000010 ...... ...... ..... ..... @rr_2bd bstrpick_d 0000 000011 ...... ...... ..... ..... @rr_2bd + +# +# Fixed point load/store instruction +# +ld_b 0010 100000 ............ ..... ..... @rr_i12 +ld_h 0010 100001 ............ ..... ..... @rr_i12 +ld_w 0010 100010 ............ ..... ..... @rr_i12 +ld_d 0010 100011 ............ ..... ..... @rr_i12 +st_b 0010 100100 ............ ..... ..... @rr_i12 +st_h 0010 100101 ............ ..... ..... @rr_i12 +st_w 0010 100110 ............ ..... ..... @rr_i12 +st_d 0010 100111 ............ ..... ..... @rr_i12 +ld_bu 0010 101000 ............ ..... ..... @rr_i12 +ld_hu 0010 101001 ............ ..... ..... @rr_i12 +ld_wu 0010 101010 ............ ..... ..... @rr_i12 +ldx_b 0011 10000000 00000 ..... ..... ..... @rrr +ldx_h 0011 10000000 01000 ..... ..... ..... @rrr +ldx_w 0011 10000000 10000 ..... ..... ..... @rrr +ldx_d 0011 10000000 11000 ..... ..... ..... @rrr +stx_b 0011 10000001 00000 ..... ..... ..... @rrr +stx_h 0011 10000001 01000 ..... ..... ..... @rrr +stx_w 0011 10000001 10000 ..... ..... ..... @rrr +stx_d 0011 10000001 11000 ..... ..... ..... @rrr +ldx_bu 0011 10000010 00000 ..... ..... ..... @rrr +ldx_hu 0011 10000010 01000 ..... ..... ..... @rrr +ldx_wu 0011 10000010 10000 ..... ..... ..... @rrr +preld 0010 101011 ............ ..... ..... @hint_r_i12 +dbar 0011 10000111 00100 ............... @i15 +ibar 0011 10000111 00101 ............... @i15 +ldptr_w 0010 0100 .............. ..... ..... @rr_i14 +stptr_w 0010 0101 .............. ..... ..... @rr_i14 +ldptr_d 0010 0110 .............. ..... ..... @rr_i14 +stptr_d 0010 0111 .............. ..... ..... @rr_i14 +ldgt_b 0011 10000111 10000 ..... ..... ..... @rrr +ldgt_h 0011 10000111 10001 ..... ..... ..... @rrr +ldgt_w 0011 10000111 10010 ..... ..... ..... @rrr +ldgt_d 0011 10000111 10011 ..... ..... ..... @rrr +ldle_b 0011 10000111 10100 ..... ..... ..... @rrr +ldle_h 0011 10000111 10101 ..... ..... ..... @rrr +ldle_w 0011 10000111 10110 ..... ..... ..... @rrr +ldle_d 0011 10000111 10111 ..... ..... ..... @rrr +stgt_b 0011 10000111 11000 ..... ..... ..... @rrr +stgt_h 0011 10000111 11001 ..... ..... ..... @rrr +stgt_w 0011 10000111 11010 ..... ..... ..... @rrr +stgt_d 0011 10000111 11011 ..... ..... ..... @rrr +stle_b 0011 10000111 11100 ..... ..... ..... @rrr +stle_h 0011 10000111 11101 ..... ..... ..... @rrr +stle_w 0011 10000111 11110 ..... ..... ..... @rrr +stle_d 0011 10000111 11111 ..... ..... ..... @rrr diff --git a/target/loongarch/op_helper.c b/target/loongarch/op_helper.c index 1fc9d81..53ee9ff 100644 --- a/target/loongarch/op_helper.c +++ b/target/loongarch/op_helper.c @@ -41,3 +41,18 @@ target_ulong helper_bitswap(target_ulong v) ((v & (target_ulong)0x0F0F0F0F0F0F0F0FULL) << 4); return v; } + +/* loongarch assert op */ +void helper_asrtle_d(CPULoongArchState *env, target_ulong rj, target_ulong rk) +{ + if (rj > rk) { + do_raise_exception(env, EXCP_ADE, GETPC()); + } +} + +void helper_asrtgt_d(CPULoongArchState *env, target_ulong rj, target_ulong rk) +{ + if (rj <= rk) { + do_raise_exception(env, EXCP_ADE, GETPC()); + } +} diff --git a/target/loongarch/translate.c b/target/loongarch/translate.c index c0875db..9ff83cf 100644 --- a/target/loongarch/translate.c +++ b/target/loongarch/translate.c @@ -69,6 +69,35 @@ static void loongarch_tr_init_disas_context(DisasContextBase *dcbase, ctx->zero = tcg_constant_tl(0); } +/* loongarch sync */ +static void gen_loongarch_sync(int stype) +{ + TCGBar tcg_mo = TCG_BAR_SC; + + switch (stype) { + case 0x4: /* SYNC_WMB */ + tcg_mo |= TCG_MO_ST_ST; + break; + case 0x10: /* SYNC_MB */ + tcg_mo |= TCG_MO_ALL; + break; + case 0x11: /* SYNC_ACQUIRE */ + tcg_mo |= TCG_MO_LD_LD | TCG_MO_LD_ST; + break; + case 0x12: /* SYNC_RELEASE */ + tcg_mo |= TCG_MO_ST_ST | TCG_MO_LD_ST; + break; + case 0x13: /* SYNC_RMB */ + tcg_mo |= TCG_MO_LD_LD; + break; + default: + tcg_mo |= TCG_MO_ALL; + break; + } + + tcg_gen_mb(tcg_mo); +} + static void loongarch_tr_tb_start(DisasContextBase *dcbase, CPUState *cs) { } @@ -148,6 +177,7 @@ static void gen_set_gpr(int reg_num, TCGv t, DisasExtend dst_ext) #include "insn_trans/trans_arith.c.inc" #include "insn_trans/trans_shift.c.inc" #include "insn_trans/trans_bit.c.inc" +#include "insn_trans/trans_memory.c.inc" static void loongarch_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs) { From patchwork Fri Nov 19 06:13:12 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: gaosong X-Patchwork-Id: 1556920 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4HwRYb4W7Bz9sXN for ; Fri, 19 Nov 2021 17:28:03 +1100 (AEDT) Received: from localhost ([::1]:59414 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mnxNR-0007LV-D3 for incoming@patchwork.ozlabs.org; Fri, 19 Nov 2021 01:28:01 -0500 Received: from eggs.gnu.org ([209.51.188.92]:46270) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mnx9i-0003ri-CR for qemu-devel@nongnu.org; Fri, 19 Nov 2021 01:13:50 -0500 Received: from mail.loongson.cn ([114.242.206.163]:46644 helo=loongson.cn) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mnx9b-0004XP-Ii for qemu-devel@nongnu.org; Fri, 19 Nov 2021 01:13:48 -0500 Received: from kvm-dev1.localdomain (unknown [10.2.5.134]) by mail.loongson.cn (Coremail) with SMTP id AQAAf9Dxj8+KQJdhSG0AAA--.1952S10; Fri, 19 Nov 2021 14:13:39 +0800 (CST) From: Song Gao To: qemu-devel@nongnu.org Subject: [PATCH v11 08/26] target/loongarch: Add fixed point atomic instruction translation Date: Fri, 19 Nov 2021 14:13:12 +0800 Message-Id: <1637302410-24632-9-git-send-email-gaosong@loongson.cn> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1637302410-24632-1-git-send-email-gaosong@loongson.cn> References: <1637302410-24632-1-git-send-email-gaosong@loongson.cn> X-CM-TRANSID: AQAAf9Dxj8+KQJdhSG0AAA--.1952S10 X-Coremail-Antispam: 1UD129KBjvJXoW3Xr4kZr1DAF47CFWxtFW5Jrb_yoWftFy5pr 42yr18Xr40qry5Ar1ktws8Ww17CFnFy3yUWry3tr18ZF47GF15XF18J39IkFW7Xan5Zry8 KFW2y3yjkFyrJaUanT9S1TB71UUUUUUqnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnUUvcSsGvfC2KfnxnUUI43ZEXa7xR_UUUUUUUUU== X-CM-SenderInfo: 5jdr20tqj6z05rqj20fqof0/ Received-SPF: pass client-ip=114.242.206.163; envelope-from=gaosong@loongson.cn; helo=loongson.cn X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Xiaojuan Yang , richard.henderson@linaro.org, laurent@vivier.eu Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" This includes: - LL.{W/D}, SC.{W/D} - AM{SWAP/ADD/AND/OR/XOR/MAX/MIN}[_DB].{W/D} - AM{MAX/MIN}[_DB].{WU/DU} Signed-off-by: Song Gao Signed-off-by: Xiaojuan Yang Reviewed-by: Richard Henderson --- target/loongarch/insn_trans/trans_atomic.c.inc | 130 +++++++++++++++++++++++++ target/loongarch/insns.decode | 44 +++++++++ target/loongarch/translate.c | 1 + 3 files changed, 175 insertions(+) create mode 100644 target/loongarch/insn_trans/trans_atomic.c.inc diff --git a/target/loongarch/insn_trans/trans_atomic.c.inc b/target/loongarch/insn_trans/trans_atomic.c.inc new file mode 100644 index 0000000..96957bb --- /dev/null +++ b/target/loongarch/insn_trans/trans_atomic.c.inc @@ -0,0 +1,130 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (c) 2021 Loongson Technology Corporation Limited + */ + +static bool gen_ll(DisasContext *ctx, arg_rr_i *a, + void (*func)(TCGv, TCGv, int)) +{ + TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE); + TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE); + TCGv t0 = tcg_temp_new(); + + tcg_gen_addi_tl(t0, src1, a->imm << 2); + func(dest, t0, ctx->mem_idx); + tcg_gen_st_tl(t0, cpu_env, offsetof(CPULoongArchState, lladdr)); + tcg_gen_st_tl(dest, cpu_env, offsetof(CPULoongArchState, llval)); + tcg_temp_free(t0); + return true; +} + +static bool gen_sc(DisasContext *ctx, arg_rr_i *a, MemOp mop) +{ + TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE); + TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE); + TCGv src2 = gpr_src(ctx, a->rd, EXT_NONE); + TCGv t0 = tcg_temp_new(); + TCGv val = tcg_temp_new(); + + TCGLabel *l1 = gen_new_label(); + TCGLabel *done = gen_new_label(); + + tcg_gen_addi_tl(t0, src1, a->imm << 2); + tcg_gen_brcond_tl(TCG_COND_EQ, t0, cpu_lladdr, l1); + tcg_gen_movi_tl(dest, 0); + tcg_gen_br(done); + + gen_set_label(l1); + tcg_gen_mov_tl(val, src2); + /* generate cmpxchg */ + tcg_gen_atomic_cmpxchg_tl(t0, cpu_lladdr, cpu_llval, + val, ctx->mem_idx, mop); + tcg_gen_setcond_tl(TCG_COND_EQ, dest, t0, cpu_llval); + gen_set_label(done); + tcg_temp_free(t0); + tcg_temp_free(val); + return true; +} + +static bool gen_am(DisasContext *ctx, arg_rrr *a, + void (*func)(TCGv, TCGv, TCGv, TCGArg, MemOp), + MemOp mop) +{ + TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE); + TCGv addr = gpr_src(ctx, a->rj, EXT_NONE); + TCGv val = gpr_src(ctx, a->rk, EXT_NONE); + + if ((a->rd != 0) && ((a->rj == a->rd) || (a->rk == a->rd))) { + qemu_log_mask(LOG_GUEST_ERROR, + "Warning: source register overlaps destination register" + "in atomic insn at pc=0x" TARGET_FMT_lx "\n", + ctx->base.pc_next - 4); + return false; + } + + func(dest, addr, val, ctx->mem_idx, mop); + return true; +} + +static bool gen_am_db(DisasContext *ctx, arg_rrr *a, + void (*func)(TCGv, TCGv, TCGv, TCGArg, MemOp), + MemOp mop) +{ + TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE); + TCGv addr = gpr_src(ctx, a->rj, EXT_NONE); + TCGv val = gpr_src(ctx, a->rk, EXT_NONE); + + if ((a->rd != 0) && ((a->rj == a->rd) || (a->rk == a->rd))) { + qemu_log_mask(LOG_GUEST_ERROR, + "Warning: source register overlaps destination register" + "in atomic insn at pc=0x" TARGET_FMT_lx "\n", + ctx->base.pc_next - 4); + return false; + } + + gen_loongarch_sync(0x10); + func(dest, addr, val, ctx->mem_idx, mop); + + return true; +} + +TRANS(ll_w, gen_ll, tcg_gen_qemu_ld32s) +TRANS(sc_w, gen_sc, MO_TESL) +TRANS(ll_d, gen_ll, tcg_gen_qemu_ld64) +TRANS(sc_d, gen_sc, MO_TEQ) +TRANS(amswap_w, gen_am, tcg_gen_atomic_xchg_tl, MO_TESL) +TRANS(amswap_d, gen_am, tcg_gen_atomic_xchg_tl, MO_TEQ) +TRANS(amadd_w, gen_am, tcg_gen_atomic_fetch_add_tl, MO_TESL) +TRANS(amadd_d, gen_am, tcg_gen_atomic_fetch_add_tl, MO_TEQ) +TRANS(amand_w, gen_am, tcg_gen_atomic_fetch_and_tl, MO_TESL) +TRANS(amand_d, gen_am, tcg_gen_atomic_fetch_and_tl, MO_TEQ) +TRANS(amor_w, gen_am, tcg_gen_atomic_fetch_or_tl, MO_TESL) +TRANS(amor_d, gen_am, tcg_gen_atomic_fetch_or_tl, MO_TEQ) +TRANS(amxor_w, gen_am, tcg_gen_atomic_fetch_xor_tl, MO_TESL) +TRANS(amxor_d, gen_am, tcg_gen_atomic_fetch_xor_tl, MO_TEQ) +TRANS(ammax_w, gen_am, tcg_gen_atomic_fetch_smax_tl, MO_TESL) +TRANS(ammax_d, gen_am, tcg_gen_atomic_fetch_smax_tl, MO_TEQ) +TRANS(ammin_w, gen_am, tcg_gen_atomic_fetch_smin_tl, MO_TESL) +TRANS(ammin_d, gen_am, tcg_gen_atomic_fetch_smin_tl, MO_TEQ) +TRANS(ammax_wu, gen_am, tcg_gen_atomic_fetch_umax_tl, MO_TESL) +TRANS(ammax_du, gen_am, tcg_gen_atomic_fetch_umax_tl, MO_TEQ) +TRANS(ammin_wu, gen_am, tcg_gen_atomic_fetch_umin_tl, MO_TESL) +TRANS(ammin_du, gen_am, tcg_gen_atomic_fetch_umin_tl, MO_TEQ) +TRANS(amswap_db_w, gen_am_db, tcg_gen_atomic_xchg_tl, MO_TESL) +TRANS(amswap_db_d, gen_am_db, tcg_gen_atomic_xchg_tl, MO_TEQ) +TRANS(amadd_db_w, gen_am_db, tcg_gen_atomic_fetch_add_tl, MO_TESL) +TRANS(amadd_db_d, gen_am_db, tcg_gen_atomic_fetch_add_tl, MO_TEQ) +TRANS(amand_db_w, gen_am_db, tcg_gen_atomic_fetch_and_tl, MO_TESL) +TRANS(amand_db_d, gen_am_db, tcg_gen_atomic_fetch_and_tl, MO_TEQ) +TRANS(amor_db_w, gen_am_db, tcg_gen_atomic_fetch_or_tl, MO_TESL) +TRANS(amor_db_d, gen_am_db, tcg_gen_atomic_fetch_or_tl, MO_TEQ) +TRANS(amxor_db_w, gen_am_db, tcg_gen_atomic_fetch_xor_tl, MO_TESL) +TRANS(amxor_db_d, gen_am_db, tcg_gen_atomic_fetch_xor_tl, MO_TEQ) +TRANS(ammax_db_w, gen_am_db, tcg_gen_atomic_fetch_smax_tl, MO_TESL) +TRANS(ammax_db_d, gen_am_db, tcg_gen_atomic_fetch_smax_tl, MO_TEQ) +TRANS(ammin_db_w, gen_am_db, tcg_gen_atomic_fetch_smin_tl, MO_TESL) +TRANS(ammin_db_d, gen_am_db, tcg_gen_atomic_fetch_smin_tl, MO_TEQ) +TRANS(ammax_db_wu, gen_am_db, tcg_gen_atomic_fetch_umax_tl, MO_TESL) +TRANS(ammax_db_du, gen_am_db, tcg_gen_atomic_fetch_umax_tl, MO_TEQ) +TRANS(ammin_db_wu, gen_am_db, tcg_gen_atomic_fetch_umin_tl, MO_TESL) +TRANS(ammin_db_du, gen_am_db, tcg_gen_atomic_fetch_umin_tl, MO_TEQ) diff --git a/target/loongarch/insns.decode b/target/loongarch/insns.decode index 3f4ac76..c222c4a 100644 --- a/target/loongarch/insns.decode +++ b/target/loongarch/insns.decode @@ -193,3 +193,47 @@ stle_b 0011 10000111 11100 ..... ..... ..... @rrr stle_h 0011 10000111 11101 ..... ..... ..... @rrr stle_w 0011 10000111 11110 ..... ..... ..... @rrr stle_d 0011 10000111 11111 ..... ..... ..... @rrr + +# +# Fixed point atomic instruction +# +ll_w 0010 0000 .............. ..... ..... @rr_i14 +sc_w 0010 0001 .............. ..... ..... @rr_i14 +ll_d 0010 0010 .............. ..... ..... @rr_i14 +sc_d 0010 0011 .............. ..... ..... @rr_i14 +amswap_w 0011 10000110 00000 ..... ..... ..... @rrr +amswap_d 0011 10000110 00001 ..... ..... ..... @rrr +amadd_w 0011 10000110 00010 ..... ..... ..... @rrr +amadd_d 0011 10000110 00011 ..... ..... ..... @rrr +amand_w 0011 10000110 00100 ..... ..... ..... @rrr +amand_d 0011 10000110 00101 ..... ..... ..... @rrr +amor_w 0011 10000110 00110 ..... ..... ..... @rrr +amor_d 0011 10000110 00111 ..... ..... ..... @rrr +amxor_w 0011 10000110 01000 ..... ..... ..... @rrr +amxor_d 0011 10000110 01001 ..... ..... ..... @rrr +ammax_w 0011 10000110 01010 ..... ..... ..... @rrr +ammax_d 0011 10000110 01011 ..... ..... ..... @rrr +ammin_w 0011 10000110 01100 ..... ..... ..... @rrr +ammin_d 0011 10000110 01101 ..... ..... ..... @rrr +ammax_wu 0011 10000110 01110 ..... ..... ..... @rrr +ammax_du 0011 10000110 01111 ..... ..... ..... @rrr +ammin_wu 0011 10000110 10000 ..... ..... ..... @rrr +ammin_du 0011 10000110 10001 ..... ..... ..... @rrr +amswap_db_w 0011 10000110 10010 ..... ..... ..... @rrr +amswap_db_d 0011 10000110 10011 ..... ..... ..... @rrr +amadd_db_w 0011 10000110 10100 ..... ..... ..... @rrr +amadd_db_d 0011 10000110 10101 ..... ..... ..... @rrr +amand_db_w 0011 10000110 10110 ..... ..... ..... @rrr +amand_db_d 0011 10000110 10111 ..... ..... ..... @rrr +amor_db_w 0011 10000110 11000 ..... ..... ..... @rrr +amor_db_d 0011 10000110 11001 ..... ..... ..... @rrr +amxor_db_w 0011 10000110 11010 ..... ..... ..... @rrr +amxor_db_d 0011 10000110 11011 ..... ..... ..... @rrr +ammax_db_w 0011 10000110 11100 ..... ..... ..... @rrr +ammax_db_d 0011 10000110 11101 ..... ..... ..... @rrr +ammin_db_w 0011 10000110 11110 ..... ..... ..... @rrr +ammin_db_d 0011 10000110 11111 ..... ..... ..... @rrr +ammax_db_wu 0011 10000111 00000 ..... ..... ..... @rrr +ammax_db_du 0011 10000111 00001 ..... ..... ..... @rrr +ammin_db_wu 0011 10000111 00010 ..... ..... ..... @rrr +ammin_db_du 0011 10000111 00011 ..... ..... ..... @rrr diff --git a/target/loongarch/translate.c b/target/loongarch/translate.c index 9ff83cf..1be899f 100644 --- a/target/loongarch/translate.c +++ b/target/loongarch/translate.c @@ -178,6 +178,7 @@ static void gen_set_gpr(int reg_num, TCGv t, DisasExtend dst_ext) #include "insn_trans/trans_shift.c.inc" #include "insn_trans/trans_bit.c.inc" #include "insn_trans/trans_memory.c.inc" +#include "insn_trans/trans_atomic.c.inc" static void loongarch_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs) { From patchwork Fri Nov 19 06:13:13 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: gaosong X-Patchwork-Id: 1556923 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4HwRg82zf3z9sPf for ; Fri, 19 Nov 2021 17:32:50 +1100 (AEDT) Received: from localhost ([::1]:39268 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mnxS3-0004o1-5N for incoming@patchwork.ozlabs.org; Fri, 19 Nov 2021 01:32:47 -0500 Received: from eggs.gnu.org ([209.51.188.92]:46306) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mnx9k-0003vl-Gx for qemu-devel@nongnu.org; Fri, 19 Nov 2021 01:13:52 -0500 Received: from mail.loongson.cn ([114.242.206.163]:46666 helo=loongson.cn) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mnx9g-0004Xb-Ov for qemu-devel@nongnu.org; Fri, 19 Nov 2021 01:13:51 -0500 Received: from kvm-dev1.localdomain (unknown [10.2.5.134]) by mail.loongson.cn (Coremail) with SMTP id AQAAf9Dxj8+KQJdhSG0AAA--.1952S11; Fri, 19 Nov 2021 14:13:41 +0800 (CST) From: Song Gao To: qemu-devel@nongnu.org Subject: [PATCH v11 09/26] target/loongarch: Add fixed point extra instruction translation Date: Fri, 19 Nov 2021 14:13:13 +0800 Message-Id: <1637302410-24632-10-git-send-email-gaosong@loongson.cn> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1637302410-24632-1-git-send-email-gaosong@loongson.cn> References: <1637302410-24632-1-git-send-email-gaosong@loongson.cn> X-CM-TRANSID: AQAAf9Dxj8+KQJdhSG0AAA--.1952S11 X-Coremail-Antispam: 1UD129KBjvJXoW3Xr4DJF18GrWxGr13Ary7Wrg_yoW3Gry7pF 12yryUGr48Jry3Zwn7tw45tr15Zrs3Ca17Xayftw1rZF47XF1DXr48t39IkFW5Jr1DXryj vanxA34DKFy5XaUanT9S1TB71UUUUUUqnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnUUvcSsGvfC2KfnxnUUI43ZEXa7xR_UUUUUUUUU== X-CM-SenderInfo: 5jdr20tqj6z05rqj20fqof0/ Received-SPF: pass client-ip=114.242.206.163; envelope-from=gaosong@loongson.cn; helo=loongson.cn X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Xiaojuan Yang , richard.henderson@linaro.org, laurent@vivier.eu Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" This includes: - CRC[C].W.{B/H/W/D}.W - SYSCALL - BREAK - ASRT{LE/GT}.D - RDTIME{L/H}.W, RDTIME.D - CPUCFG Signed-off-by: Song Gao Signed-off-by: Xiaojuan Yang Reviewed-by: Richard Henderson --- target/loongarch/helper.h | 4 ++ target/loongarch/insn_trans/trans_extra.c.inc | 84 +++++++++++++++++++++++++++ target/loongarch/insns.decode | 22 +++++++ target/loongarch/op_helper.c | 26 +++++++++ target/loongarch/translate.c | 1 + 5 files changed, 137 insertions(+) create mode 100644 target/loongarch/insn_trans/trans_extra.c.inc diff --git a/target/loongarch/helper.h b/target/loongarch/helper.h index 2fe4e63..ec6760d 100644 --- a/target/loongarch/helper.h +++ b/target/loongarch/helper.h @@ -11,3 +11,7 @@ DEF_HELPER_FLAGS_1(bitswap, TCG_CALL_NO_RWG_SE, tl, tl) DEF_HELPER_3(asrtle_d, void, env, tl, tl) DEF_HELPER_3(asrtgt_d, void, env, tl, tl) + +DEF_HELPER_3(crc32, tl, tl, tl, tl) +DEF_HELPER_3(crc32c, tl, tl, tl, tl) +DEF_HELPER_2(cpucfg, tl, env, tl) diff --git a/target/loongarch/insn_trans/trans_extra.c.inc b/target/loongarch/insn_trans/trans_extra.c.inc new file mode 100644 index 0000000..8c2d482 --- /dev/null +++ b/target/loongarch/insn_trans/trans_extra.c.inc @@ -0,0 +1,84 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (c) 2021 Loongson Technology Corporation Limited + */ + +static bool trans_break(DisasContext *ctx, arg_break *a) +{ + generate_exception(ctx, EXCP_BREAK); + return true; +} + +static bool trans_syscall(DisasContext *ctx, arg_syscall *a) +{ + generate_exception(ctx, EXCP_SYSCALL); + return true; +} + +static bool trans_asrtle_d(DisasContext *ctx, arg_asrtle_d * a) +{ + TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE); + TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE); + + gen_helper_asrtle_d(cpu_env, src1, src2); + return true; +} + +static bool trans_asrtgt_d(DisasContext *ctx, arg_asrtgt_d * a) +{ + TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE); + TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE); + + gen_helper_asrtgt_d(cpu_env, src1, src2); + return true; +} + +static bool trans_rdtimel_w(DisasContext *ctx, arg_rdtimel_w *a) +{ + tcg_gen_movi_tl(cpu_gpr[a->rd], 0); + return true; +} + +static bool trans_rdtimeh_w(DisasContext *ctx, arg_rdtimeh_w *a) +{ + tcg_gen_movi_tl(cpu_gpr[a->rd], 0); + return true; +} + +static bool trans_rdtime_d(DisasContext *ctx, arg_rdtime_d *a) +{ + tcg_gen_movi_tl(cpu_gpr[a->rd], 0); + return true; +} + +static bool trans_cpucfg(DisasContext *ctx, arg_cpucfg *a) +{ + TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE); + TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE); + + gen_helper_cpucfg(dest, cpu_env, src1); + return true; +} + +static bool gen_crc(DisasContext *ctx, arg_rrr *a, + void (*func)(TCGv, TCGv, TCGv, TCGv), + TCGv tsz) +{ + TCGv dest = gpr_dst(ctx, a->rd, EXT_SIGN); + TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE); + TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE); + + func(dest, src2, src1, tsz); + + gen_set_gpr(a->rd, dest, EXT_SIGN); + return true; +} + +TRANS(crc_w_b_w, gen_crc, gen_helper_crc32, tcg_constant_tl(1)) +TRANS(crc_w_h_w, gen_crc, gen_helper_crc32, tcg_constant_tl(2)) +TRANS(crc_w_w_w, gen_crc, gen_helper_crc32, tcg_constant_tl(4)) +TRANS(crc_w_d_w, gen_crc, gen_helper_crc32, tcg_constant_tl(8)) +TRANS(crcc_w_b_w, gen_crc, gen_helper_crc32c, tcg_constant_tl(1)) +TRANS(crcc_w_h_w, gen_crc, gen_helper_crc32c, tcg_constant_tl(2)) +TRANS(crcc_w_w_w, gen_crc, gen_helper_crc32c, tcg_constant_tl(4)) +TRANS(crcc_w_d_w, gen_crc, gen_helper_crc32c, tcg_constant_tl(8)) diff --git a/target/loongarch/insns.decode b/target/loongarch/insns.decode index c222c4a..8dca6f2 100644 --- a/target/loongarch/insns.decode +++ b/target/loongarch/insns.decode @@ -16,6 +16,7 @@ &i imm &r_i rd imm &rr rd rj +&rr_jk rj rk &rrr rd rj rk &rr_i rd rj imm &hint_r_i hint rj imm @@ -28,6 +29,7 @@ # @i15 .... ........ ..... imm:15 &i @rr .... ........ ..... ..... rj:5 rd:5 &rr +@rr_jk .... ........ ..... rk:5 rj:5 ..... &rr_jk @rrr .... ........ ..... rk:5 rj:5 rd:5 &rrr @r_i20 .... ... imm:s20 rd:5 &r_i @rr_ui5 .... ........ ..... imm:5 rj:5 rd:5 &rr_i @@ -237,3 +239,23 @@ ammax_db_wu 0011 10000111 00000 ..... ..... ..... @rrr ammax_db_du 0011 10000111 00001 ..... ..... ..... @rrr ammin_db_wu 0011 10000111 00010 ..... ..... ..... @rrr ammin_db_du 0011 10000111 00011 ..... ..... ..... @rrr + +# +# Fixed point extra instruction +# +crc_w_b_w 0000 00000010 01000 ..... ..... ..... @rrr +crc_w_h_w 0000 00000010 01001 ..... ..... ..... @rrr +crc_w_w_w 0000 00000010 01010 ..... ..... ..... @rrr +crc_w_d_w 0000 00000010 01011 ..... ..... ..... @rrr +crcc_w_b_w 0000 00000010 01100 ..... ..... ..... @rrr +crcc_w_h_w 0000 00000010 01101 ..... ..... ..... @rrr +crcc_w_w_w 0000 00000010 01110 ..... ..... ..... @rrr +crcc_w_d_w 0000 00000010 01111 ..... ..... ..... @rrr +break 0000 00000010 10100 ............... @i15 +syscall 0000 00000010 10110 ............... @i15 +asrtle_d 0000 00000000 00010 ..... ..... 00000 @rr_jk +asrtgt_d 0000 00000000 00011 ..... ..... 00000 @rr_jk +rdtimel_w 0000 00000000 00000 11000 ..... ..... @rr +rdtimeh_w 0000 00000000 00000 11001 ..... ..... @rr +rdtime_d 0000 00000000 00000 11010 ..... ..... @rr +cpucfg 0000 00000000 00000 11011 ..... ..... @rr diff --git a/target/loongarch/op_helper.c b/target/loongarch/op_helper.c index 53ee9ff..fdd4303 100644 --- a/target/loongarch/op_helper.c +++ b/target/loongarch/op_helper.c @@ -13,6 +13,8 @@ #include "exec/exec-all.h" #include "exec/cpu_ldst.h" #include "internals.h" +#include "qemu/crc32c.h" +#include /* Exceptions helpers */ void helper_raise_exception(CPULoongArchState *env, uint32_t exception) @@ -56,3 +58,27 @@ void helper_asrtgt_d(CPULoongArchState *env, target_ulong rj, target_ulong rk) do_raise_exception(env, EXCP_ADE, GETPC()); } } + +target_ulong helper_crc32(target_ulong val, target_ulong m, uint64_t sz) +{ + uint8_t buf[8]; + target_ulong mask = ((sz * 8) == 64) ? -1ULL : ((1ULL << (sz * 8)) - 1); + + m &= mask; + stq_le_p(buf, m); + return (int32_t) (crc32(val ^ 0xffffffff, buf, sz) ^ 0xffffffff); +} + +target_ulong helper_crc32c(target_ulong val, target_ulong m, uint64_t sz) +{ + uint8_t buf[8]; + target_ulong mask = ((sz * 8) == 64) ? -1ULL : ((1ULL << (sz * 8)) - 1); + m &= mask; + stq_le_p(buf, m); + return (int32_t) (crc32c(val, buf, sz) ^ 0xffffffff); +} + +target_ulong helper_cpucfg(CPULoongArchState *env, target_ulong rj) +{ + return env->cpucfg[rj]; +} diff --git a/target/loongarch/translate.c b/target/loongarch/translate.c index 1be899f..ca3ee23 100644 --- a/target/loongarch/translate.c +++ b/target/loongarch/translate.c @@ -179,6 +179,7 @@ static void gen_set_gpr(int reg_num, TCGv t, DisasExtend dst_ext) #include "insn_trans/trans_bit.c.inc" #include "insn_trans/trans_memory.c.inc" #include "insn_trans/trans_atomic.c.inc" +#include "insn_trans/trans_extra.c.inc" static void loongarch_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs) { From patchwork Fri Nov 19 06:13:14 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: gaosong X-Patchwork-Id: 1556914 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4HwRHk14YYz9sWJ for ; Fri, 19 Nov 2021 17:16:02 +1100 (AEDT) Received: from localhost ([::1]:43060 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mnxBn-0004Ig-Tx for incoming@patchwork.ozlabs.org; Fri, 19 Nov 2021 01:15:59 -0500 Received: from eggs.gnu.org ([209.51.188.92]:46398) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mnx9v-0004FH-KL for qemu-devel@nongnu.org; Fri, 19 Nov 2021 01:14:03 -0500 Received: from mail.loongson.cn ([114.242.206.163]:46680 helo=loongson.cn) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mnx9s-0004Xr-0r for qemu-devel@nongnu.org; Fri, 19 Nov 2021 01:14:03 -0500 Received: from kvm-dev1.localdomain (unknown [10.2.5.134]) by mail.loongson.cn (Coremail) with SMTP id AQAAf9Dxj8+KQJdhSG0AAA--.1952S12; Fri, 19 Nov 2021 14:13:43 +0800 (CST) From: Song Gao To: qemu-devel@nongnu.org Subject: [PATCH v11 10/26] target/loongarch: Add floating point arithmetic instruction translation Date: Fri, 19 Nov 2021 14:13:14 +0800 Message-Id: <1637302410-24632-11-git-send-email-gaosong@loongson.cn> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1637302410-24632-1-git-send-email-gaosong@loongson.cn> References: <1637302410-24632-1-git-send-email-gaosong@loongson.cn> X-CM-TRANSID: AQAAf9Dxj8+KQJdhSG0AAA--.1952S12 X-Coremail-Antispam: 1UD129KBjvAXoWfXw43uw1Utr4DAFyxJry8AFb_yoW8tF13Go W5W3W5Ar48G3yfuF98Kwn0vr47XryUA3ZxJrWrZr13Ka4xGry7K3W5GwnYya1fKr1rtrW5 Xrn2yw15JwnIvr93n29KB7ZKAUJUUUUU529EdanIXcx71UUUUU7v73VFW2AGmfu7bjvjm3 AaLaJ3UjIYCTnIWjDUYxBIdaVFxhVjvjDU0xZFpf9x0zRUUUUUUUUU= X-CM-SenderInfo: 5jdr20tqj6z05rqj20fqof0/ Received-SPF: pass client-ip=114.242.206.163; envelope-from=gaosong@loongson.cn; helo=loongson.cn X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Xiaojuan Yang , richard.henderson@linaro.org, laurent@vivier.eu Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" This includes: - F{ADD/SUB/MUL/DIV}.{S/D} - F{MADD/MSUB/NMADD/NMSUB}.{S/D} - F{MAX/MIN}.{S/D} - F{MAXA/MINA}.{S/D} - F{ABS/NEG}.{S/D} - F{SQRT/RECIP/RSQRT}.{S/D} - F{SCALEB/LOGB/COPYSIGN}.{S/D} - FCLASS.{S/D} Signed-off-by: Song Gao Signed-off-by: Xiaojuan Yang Reviewed-by: Richard Henderson --- target/loongarch/cpu.c | 1 + target/loongarch/fpu_helper.c | 405 +++++++++++++++++++++++++ target/loongarch/helper.h | 37 +++ target/loongarch/insn_trans/trans_farith.c.inc | 105 +++++++ target/loongarch/insns.decode | 52 ++++ target/loongarch/internals.h | 2 + target/loongarch/translate.c | 11 + 7 files changed, 613 insertions(+) create mode 100644 target/loongarch/fpu_helper.c create mode 100644 target/loongarch/insn_trans/trans_farith.c.inc diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c index b3f4444..ad11b98 100644 --- a/target/loongarch/cpu.c +++ b/target/loongarch/cpu.c @@ -185,6 +185,7 @@ static void loongarch_cpu_reset(DeviceState *dev) env->fcsr0_mask = 0x1f1f031f; env->fcsr0 = 0x0; + restore_fp_status(env); cs->exception_index = EXCP_NONE; } diff --git a/target/loongarch/fpu_helper.c b/target/loongarch/fpu_helper.c new file mode 100644 index 0000000..d0ef675 --- /dev/null +++ b/target/loongarch/fpu_helper.c @@ -0,0 +1,405 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * LoongArch float point emulation helpers for QEMU + * + * Copyright (c) 2021 Loongson Technology Corporation Limited + */ + +#include "qemu/osdep.h" +#include "cpu.h" +#include "exec/helper-proto.h" +#include "exec/exec-all.h" +#include "exec/cpu_ldst.h" +#include "fpu/softfloat.h" +#include "internals.h" + +#define FLOAT_TO_INT32_OVERFLOW 0x7fffffff +#define FLOAT_TO_INT64_OVERFLOW 0x7fffffffffffffffULL + +static inline uint64_t nanbox_s(float32 fp) +{ + return fp | MAKE_64BIT_MASK(32, 32); +} + +/* Convert loongarch rounding mode in fcsr0 to IEEE library */ +static const FloatRoundMode ieee_rm[4] = { + float_round_nearest_even, + float_round_to_zero, + float_round_up, + float_round_down +}; + +void restore_fp_status(CPULoongArchState *env) +{ + set_float_rounding_mode(ieee_rm[(env->fcsr0 >> FCSR0_RM) & 0x3], + &env->fp_status); + set_flush_to_zero(0, &env->fp_status); +} + +static int ieee_ex_to_loongarch(int xcpt) +{ + int ret = 0; + if (xcpt & float_flag_invalid) { + ret |= FP_INVALID; + } + if (xcpt & float_flag_overflow) { + ret |= FP_OVERFLOW; + } + if (xcpt & float_flag_underflow) { + ret |= FP_UNDERFLOW; + } + if (xcpt & float_flag_divbyzero) { + ret |= FP_DIV0; + } + if (xcpt & float_flag_inexact) { + ret |= FP_INEXACT; + } + return ret; +} + +static void update_fcsr0_mask(CPULoongArchState *env, uintptr_t pc, int mask) +{ + int flags = get_float_exception_flags(&env->fp_status); + + set_float_exception_flags(0, &env->fp_status); + + if (~mask) { + flags = flags & (~mask); + } + + if (!flags) { + SET_FP_CAUSE(env->fcsr0, flags); + return; + } + + flags = ieee_ex_to_loongarch(flags); + SET_FP_CAUSE(env->fcsr0, flags); + + if (GET_FP_ENABLES(env->fcsr0) & flags) { + do_raise_exception(env, EXCP_FPE, pc); + } else { + UPDATE_FP_FLAGS(env->fcsr0, flags); + } +} + +static void update_fcsr0(CPULoongArchState *env, uintptr_t pc) +{ + update_fcsr0_mask(env, pc, 0); +} + +uint64_t helper_fadd_s(CPULoongArchState *env, uint64_t fj, uint64_t fk) +{ + uint64_t fd; + + fd = nanbox_s(float32_add((uint32_t)fj, (uint32_t)fk, &env->fp_status)); + update_fcsr0(env, GETPC()); + return fd; +} + +uint64_t helper_fadd_d(CPULoongArchState *env, uint64_t fj, uint64_t fk) +{ + uint64_t fd; + + fd = float64_add(fj, fk, &env->fp_status); + update_fcsr0(env, GETPC()); + return fd; +} + +uint64_t helper_fsub_s(CPULoongArchState *env, uint64_t fj, uint64_t fk) +{ + uint64_t fd; + + fd = nanbox_s(float32_sub((uint32_t)fj, (uint32_t)fk, &env->fp_status)); + update_fcsr0(env, GETPC()); + return fd; +} + +uint64_t helper_fsub_d(CPULoongArchState *env, uint64_t fj, uint64_t fk) +{ + uint64_t fd; + + fd = float64_sub(fj, fk, &env->fp_status); + update_fcsr0(env, GETPC()); + return fd; +} + +uint64_t helper_fmul_s(CPULoongArchState *env, uint64_t fj, uint64_t fk) +{ + uint64_t fd; + + fd = nanbox_s(float32_mul((uint32_t)fj, (uint32_t)fk, &env->fp_status)); + update_fcsr0(env, GETPC()); + return fd; +} + +uint64_t helper_fmul_d(CPULoongArchState *env, uint64_t fj, uint64_t fk) +{ + uint64_t fd; + + fd = float64_mul(fj, fk, &env->fp_status); + update_fcsr0(env, GETPC()); + return fd; +} + +uint64_t helper_fdiv_s(CPULoongArchState *env, uint64_t fj, uint64_t fk) +{ + uint64_t fd; + + fd = nanbox_s(float32_div((uint32_t)fj, (uint32_t)fk, &env->fp_status)); + update_fcsr0(env, GETPC()); + return fd; +} + +uint64_t helper_fdiv_d(CPULoongArchState *env, uint64_t fj, uint64_t fk) +{ + uint64_t fd; + + fd = float64_div(fj, fk, &env->fp_status); + update_fcsr0(env, GETPC()); + return fd; +} + +uint64_t helper_fmax_s(CPULoongArchState *env, uint64_t fj, uint64_t fk) +{ + uint64_t fd; + + fd = nanbox_s(float32_maxnum((uint32_t)fj, (uint32_t)fk, &env->fp_status)); + update_fcsr0(env, GETPC()); + return fd; +} + +uint64_t helper_fmax_d(CPULoongArchState *env, uint64_t fj, uint64_t fk) +{ + uint64_t fd; + + fd = float64_maxnum(fj, fk, &env->fp_status); + update_fcsr0(env, GETPC()); + return fd; +} + +uint64_t helper_fmin_s(CPULoongArchState *env, uint64_t fj, uint64_t fk) +{ + uint64_t fd; + + fd = nanbox_s(float32_minnum((uint32_t)fj, (uint32_t)fk, &env->fp_status)); + update_fcsr0(env, GETPC()); + return fd; +} + +uint64_t helper_fmin_d(CPULoongArchState *env, uint64_t fj, uint64_t fk) +{ + uint64_t fd; + + fd = float64_minnum(fj, fk, &env->fp_status); + update_fcsr0(env, GETPC()); + return fd; +} + +uint64_t helper_fmaxa_s(CPULoongArchState *env, uint64_t fj, uint64_t fk) +{ + uint64_t fd; + + fd = nanbox_s(float32_maxnummag((uint32_t)fj, + (uint32_t)fk, &env->fp_status)); + update_fcsr0(env, GETPC()); + return fd; +} + +uint64_t helper_fmaxa_d(CPULoongArchState *env, uint64_t fj, uint64_t fk) +{ + uint64_t fd; + + fd = float64_maxnummag(fj, fk, &env->fp_status); + update_fcsr0(env, GETPC()); + return fd; +} + +uint64_t helper_fmina_s(CPULoongArchState *env, uint64_t fj, uint64_t fk) +{ + uint64_t fd; + + fd = nanbox_s(float32_minnummag((uint32_t)fj, + (uint32_t)fk, &env->fp_status)); + update_fcsr0(env, GETPC()); + return fd; +} + +uint64_t helper_fmina_d(CPULoongArchState *env, uint64_t fj, uint64_t fk) +{ + uint64_t fd; + + fd = float64_minnummag(fj, fk, &env->fp_status); + update_fcsr0(env, GETPC()); + return fd; +} + +uint64_t helper_fscaleb_s(CPULoongArchState *env, uint64_t fj, uint64_t fk) +{ + uint64_t fd; + int32_t n = (int32_t)fk; + + fd = nanbox_s(float32_scalbn((uint32_t)fj, + n > 0x200 ? 0x200 : + n < -0x200 ? -0x200 : n, + &env->fp_status)); + update_fcsr0(env, GETPC()); + return fd; +} + +uint64_t helper_fscaleb_d(CPULoongArchState *env, uint64_t fj, uint64_t fk) +{ + uint64_t fd; + int64_t n = (int64_t)fk; + + fd = float64_scalbn(fj, + n > 0x1000 ? 0x1000 : + n < -0x1000 ? -0x1000 : n, + &env->fp_status); + update_fcsr0(env, GETPC()); + return fd; +} + +uint64_t helper_fsqrt_s(CPULoongArchState *env, uint64_t fj) +{ + uint64_t fd; + + fd = nanbox_s(float32_sqrt((uint32_t)fj, &env->fp_status)); + update_fcsr0(env, GETPC()); + return fd; +} + +uint64_t helper_fsqrt_d(CPULoongArchState *env, uint64_t fj) +{ + uint64_t fd; + + fd = float64_sqrt(fj, &env->fp_status); + update_fcsr0(env, GETPC()); + return fd; +} + +uint64_t helper_frecip_s(CPULoongArchState *env, uint64_t fj) +{ + uint64_t fd; + + fd = nanbox_s(float32_div(float32_one, (uint32_t)fj, &env->fp_status)); + update_fcsr0(env, GETPC()); + return fd; +} + +uint64_t helper_frecip_d(CPULoongArchState *env, uint64_t fj) +{ + uint64_t fd; + + fd = float64_div(float64_one, fj, &env->fp_status); + update_fcsr0(env, GETPC()); + return fd; +} + +uint64_t helper_frsqrt_s(CPULoongArchState *env, uint64_t fj) +{ + uint64_t fd; + uint32_t fp; + + fp = float32_sqrt((uint32_t)fj, &env->fp_status); + fd = nanbox_s(float32_div(float32_one, fp, &env->fp_status)); + update_fcsr0(env, GETPC()); + return fd; +} + +uint64_t helper_frsqrt_d(CPULoongArchState *env, uint64_t fj) +{ + uint64_t fp, fd; + + fp = float64_sqrt(fj, &env->fp_status); + fd = float64_div(float64_one, fp, &env->fp_status); + update_fcsr0(env, GETPC()); + return fd; +} + +uint64_t helper_flogb_s(CPULoongArchState *env, uint64_t fj) +{ + uint64_t fd; + uint32_t fp; + float_status *status = &env->fp_status; + FloatRoundMode old_mode = get_float_rounding_mode(status); + + set_float_rounding_mode(float_round_down, status); + fp = float32_log2((uint32_t)fj, status); + fd = nanbox_s(float32_round_to_int(fp, status)); + set_float_rounding_mode(old_mode, status); + update_fcsr0_mask(env, GETPC(), float_flag_inexact); + return fd; +} + +uint64_t helper_flogb_d(CPULoongArchState *env, uint64_t fj) +{ + uint64_t fd; + float_status *status = &env->fp_status; + FloatRoundMode old_mode = get_float_rounding_mode(status); + + set_float_rounding_mode(float_round_down, status); + fd = float64_log2(fj, status); + fd = float64_round_to_int(fd, status); + set_float_rounding_mode(old_mode, status); + update_fcsr0_mask(env, GETPC(), float_flag_inexact); + return fd; +} + +uint64_t helper_fclass_s(CPULoongArchState *env, uint64_t fj) +{ + float32 f = fj; + bool sign = float32_is_neg(f); + + if (float32_is_infinity(f)) { + return sign ? 1 << 0 : 1 << 7; + } else if (float32_is_zero(f)) { + return sign ? 1 << 3 : 1 << 4; + } else if (float32_is_zero_or_denormal(f)) { + return sign ? 1 << 2 : 1 << 5; + } else if (float32_is_any_nan(f)) { + float_status s = { }; /* for snan_bit_is_one */ + return float32_is_quiet_nan(f, &s) ? 1 << 9 : 1 << 8; + } else { + return sign ? 1 << 1 : 1 << 6; + } +} + +uint64_t helper_fclass_d(CPULoongArchState *env, uint64_t fj) +{ + float64 f = fj; + bool sign = float64_is_neg(f); + + if (float64_is_infinity(f)) { + return sign ? 1 << 0 : 1 << 7; + } else if (float64_is_zero(f)) { + return sign ? 1 << 3 : 1 << 4; + } else if (float64_is_zero_or_denormal(f)) { + return sign ? 1 << 2 : 1 << 5; + } else if (float64_is_any_nan(f)) { + float_status s = { }; /* for snan_bit_is_one */ + return float64_is_quiet_nan(f, &s) ? 1 << 9 : 1 << 8; + } else { + return sign ? 1 << 1 : 1 << 6; + } +} + +uint64_t helper_fmuladd_s(CPULoongArchState *env, uint64_t fj, + uint64_t fk, uint64_t fa, uint32_t flag) +{ + uint64_t fd; + + fd = nanbox_s(float32_muladd((uint32_t)fj, (uint32_t)fk, + (uint32_t)fa, flag, &env->fp_status)); + update_fcsr0(env, GETPC()); + return fd; +} + +uint64_t helper_fmuladd_d(CPULoongArchState *env, uint64_t fj, + uint64_t fk, uint64_t fa, uint32_t flag) +{ + uint64_t fd; + + fd = float64_muladd(fj, fk, fa, flag, &env->fp_status); + update_fcsr0(env, GETPC()); + return fd; +} diff --git a/target/loongarch/helper.h b/target/loongarch/helper.h index ec6760d..d6bb412 100644 --- a/target/loongarch/helper.h +++ b/target/loongarch/helper.h @@ -15,3 +15,40 @@ DEF_HELPER_3(asrtgt_d, void, env, tl, tl) DEF_HELPER_3(crc32, tl, tl, tl, tl) DEF_HELPER_3(crc32c, tl, tl, tl, tl) DEF_HELPER_2(cpucfg, tl, env, tl) + +/* Floating-point helper */ +DEF_HELPER_3(fadd_s, i64, env, i64, i64) +DEF_HELPER_3(fadd_d, i64, env, i64, i64) +DEF_HELPER_3(fsub_s, i64, env, i64, i64) +DEF_HELPER_3(fsub_d, i64, env, i64, i64) +DEF_HELPER_3(fmul_s, i64, env, i64, i64) +DEF_HELPER_3(fmul_d, i64, env, i64, i64) +DEF_HELPER_3(fdiv_s, i64, env, i64, i64) +DEF_HELPER_3(fdiv_d, i64, env, i64, i64) +DEF_HELPER_3(fmax_s, i64, env, i64, i64) +DEF_HELPER_3(fmax_d, i64, env, i64, i64) +DEF_HELPER_3(fmin_s, i64, env, i64, i64) +DEF_HELPER_3(fmin_d, i64, env, i64, i64) +DEF_HELPER_3(fmaxa_s, i64, env, i64, i64) +DEF_HELPER_3(fmaxa_d, i64, env, i64, i64) +DEF_HELPER_3(fmina_s, i64, env, i64, i64) +DEF_HELPER_3(fmina_d, i64, env, i64, i64) + +DEF_HELPER_5(fmuladd_s, i64, env, i64, i64, i64, i32) +DEF_HELPER_5(fmuladd_d, i64, env, i64, i64, i64, i32) + +DEF_HELPER_3(fscaleb_s, i64, env, i64, i64) +DEF_HELPER_3(fscaleb_d, i64, env, i64, i64) + +DEF_HELPER_2(flogb_s, i64, env, i64) +DEF_HELPER_2(flogb_d, i64, env, i64) + +DEF_HELPER_2(fsqrt_s, i64, env, i64) +DEF_HELPER_2(fsqrt_d, i64, env, i64) +DEF_HELPER_2(frsqrt_s, i64, env, i64) +DEF_HELPER_2(frsqrt_d, i64, env, i64) +DEF_HELPER_2(frecip_s, i64, env, i64) +DEF_HELPER_2(frecip_d, i64, env, i64) + +DEF_HELPER_FLAGS_2(fclass_s, TCG_CALL_NO_RWG_SE, i64, env, i64) +DEF_HELPER_FLAGS_2(fclass_d, TCG_CALL_NO_RWG_SE, i64, env, i64) diff --git a/target/loongarch/insn_trans/trans_farith.c.inc b/target/loongarch/insn_trans/trans_farith.c.inc new file mode 100644 index 0000000..a2bdf33 --- /dev/null +++ b/target/loongarch/insn_trans/trans_farith.c.inc @@ -0,0 +1,105 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (c) 2021 Loongson Technology Corporation Limited + */ + +static bool gen_fff(DisasContext *ctx, arg_fff *a, + void (*func)(TCGv, TCGv_env, TCGv, TCGv)) +{ + func(cpu_fpr[a->fd], cpu_env, cpu_fpr[a->fj], cpu_fpr[a->fk]); + return true; +} + +static bool gen_ff(DisasContext *ctx, arg_ff *a, + void (*func)(TCGv, TCGv_env, TCGv)) +{ + func(cpu_fpr[a->fd], cpu_env, cpu_fpr[a->fj]); + return true; +} + +static bool gen_muladd(DisasContext *ctx, arg_ffff *a, + void (*func)(TCGv, TCGv_env, TCGv, TCGv, TCGv, TCGv_i32), + int flag) +{ + TCGv_i32 tflag = tcg_constant_i32(flag); + func(cpu_fpr[a->fd], cpu_env, cpu_fpr[a->fj], + cpu_fpr[a->fk], cpu_fpr[a->fa], tflag); + return true; +} + +static bool trans_fcopysign_s(DisasContext *ctx, arg_fff *a) +{ + tcg_gen_deposit_i64(cpu_fpr[a->fd], cpu_fpr[a->fk], cpu_fpr[a->fj], 0, 31); + return true; +} + +static bool trans_fcopysign_d(DisasContext *ctx, arg_fff *a) +{ + tcg_gen_deposit_i64(cpu_fpr[a->fd], cpu_fpr[a->fk], cpu_fpr[a->fj], 0, 63); + return true; +} + +static bool trans_fabs_s(DisasContext *ctx, arg_ff *a) +{ + tcg_gen_andi_i64(cpu_fpr[a->fd], cpu_fpr[a->fj], MAKE_64BIT_MASK(0, 31)); + gen_nanbox_s(cpu_fpr[a->fd], cpu_fpr[a->fd]); + return true; +} + +static bool trans_fabs_d(DisasContext *ctx, arg_ff *a) +{ + tcg_gen_andi_i64(cpu_fpr[a->fd], cpu_fpr[a->fj], MAKE_64BIT_MASK(0, 63)); + return true; +} + +static bool trans_fneg_s(DisasContext *ctx, arg_ff *a) +{ + tcg_gen_xori_i64(cpu_fpr[a->fd], cpu_fpr[a->fj], 0x80000000); + gen_nanbox_s(cpu_fpr[a->fd], cpu_fpr[a->fd]); + return true; +} + +static bool trans_fneg_d(DisasContext *ctx, arg_ff *a) +{ + tcg_gen_xori_i64(cpu_fpr[a->fd], cpu_fpr[a->fj], 0x8000000000000000LL); + return true; +} + +TRANS(fadd_s, gen_fff, gen_helper_fadd_s) +TRANS(fadd_d, gen_fff, gen_helper_fadd_d) +TRANS(fsub_s, gen_fff, gen_helper_fsub_s) +TRANS(fsub_d, gen_fff, gen_helper_fsub_d) +TRANS(fmul_s, gen_fff, gen_helper_fmul_s) +TRANS(fmul_d, gen_fff, gen_helper_fmul_d) +TRANS(fdiv_s, gen_fff, gen_helper_fdiv_s) +TRANS(fdiv_d, gen_fff, gen_helper_fdiv_d) +TRANS(fmax_s, gen_fff, gen_helper_fmax_s) +TRANS(fmax_d, gen_fff, gen_helper_fmax_d) +TRANS(fmin_s, gen_fff, gen_helper_fmin_s) +TRANS(fmin_d, gen_fff, gen_helper_fmin_d) +TRANS(fmaxa_s, gen_fff, gen_helper_fmaxa_s) +TRANS(fmaxa_d, gen_fff, gen_helper_fmaxa_d) +TRANS(fmina_s, gen_fff, gen_helper_fmina_s) +TRANS(fmina_d, gen_fff, gen_helper_fmina_d) +TRANS(fscaleb_s, gen_fff, gen_helper_fscaleb_s) +TRANS(fscaleb_d, gen_fff, gen_helper_fscaleb_d) +TRANS(fsqrt_s, gen_ff, gen_helper_fsqrt_s) +TRANS(fsqrt_d, gen_ff, gen_helper_fsqrt_d) +TRANS(frecip_s, gen_ff, gen_helper_frecip_s) +TRANS(frecip_d, gen_ff, gen_helper_frecip_d) +TRANS(frsqrt_s, gen_ff, gen_helper_frsqrt_s) +TRANS(frsqrt_d, gen_ff, gen_helper_frsqrt_d) +TRANS(flogb_s, gen_ff, gen_helper_flogb_s) +TRANS(flogb_d, gen_ff, gen_helper_flogb_d) +TRANS(fclass_s, gen_ff, gen_helper_fclass_s) +TRANS(fclass_d, gen_ff, gen_helper_fclass_d) +TRANS(fmadd_s, gen_muladd, gen_helper_fmuladd_s, 0) +TRANS(fmadd_d, gen_muladd, gen_helper_fmuladd_d, 0) +TRANS(fmsub_s, gen_muladd, gen_helper_fmuladd_s, float_muladd_negate_c) +TRANS(fmsub_d, gen_muladd, gen_helper_fmuladd_d, float_muladd_negate_c) +TRANS(fnmadd_s, gen_muladd, gen_helper_fmuladd_s, + float_muladd_negate_product | float_muladd_negate_c) +TRANS(fnmadd_d, gen_muladd, gen_helper_fmuladd_d, + float_muladd_negate_product | float_muladd_negate_c) +TRANS(fnmsub_s, gen_muladd, gen_helper_fmuladd_s, float_muladd_negate_product) +TRANS(fnmsub_d, gen_muladd, gen_helper_fmuladd_d, float_muladd_negate_product) diff --git a/target/loongarch/insns.decode b/target/loongarch/insns.decode index 8dca6f2..28a2f5e 100644 --- a/target/loongarch/insns.decode +++ b/target/loongarch/insns.decode @@ -23,6 +23,9 @@ &rrr_sa rd rj rk sa &rr_2bw rd rj msbw lsbw &rr_2bd rd rj msbd lsbd +&ff fd fj +&fff fd fj fk +&ffff fd fj fk fa # # Formats @@ -44,6 +47,9 @@ @rrr_sa3 .... ........ .. sa:3 rk:5 rj:5 rd:5 &rrr_sa @rr_2bw .... ....... msbw:5 . lsbw:5 rj:5 rd:5 &rr_2bw @rr_2bd .... ...... msbd:6 lsbd:6 rj:5 rd:5 &rr_2bd +@ff .... ........ ..... ..... fj:5 fd:5 &ff +@fff .... ........ ..... fk:5 fj:5 fd:5 &fff +@ffff .... ........ fa:5 fk:5 fj:5 fd:5 &ffff # # Fixed point arithmetic operation instruction @@ -259,3 +265,49 @@ rdtimel_w 0000 00000000 00000 11000 ..... ..... @rr rdtimeh_w 0000 00000000 00000 11001 ..... ..... @rr rdtime_d 0000 00000000 00000 11010 ..... ..... @rr cpucfg 0000 00000000 00000 11011 ..... ..... @rr + +# +# Floating point arithmetic operation instruction +# +fadd_s 0000 00010000 00001 ..... ..... ..... @fff +fadd_d 0000 00010000 00010 ..... ..... ..... @fff +fsub_s 0000 00010000 00101 ..... ..... ..... @fff +fsub_d 0000 00010000 00110 ..... ..... ..... @fff +fmul_s 0000 00010000 01001 ..... ..... ..... @fff +fmul_d 0000 00010000 01010 ..... ..... ..... @fff +fdiv_s 0000 00010000 01101 ..... ..... ..... @fff +fdiv_d 0000 00010000 01110 ..... ..... ..... @fff +fmadd_s 0000 10000001 ..... ..... ..... ..... @ffff +fmadd_d 0000 10000010 ..... ..... ..... ..... @ffff +fmsub_s 0000 10000101 ..... ..... ..... ..... @ffff +fmsub_d 0000 10000110 ..... ..... ..... ..... @ffff +fnmadd_s 0000 10001001 ..... ..... ..... ..... @ffff +fnmadd_d 0000 10001010 ..... ..... ..... ..... @ffff +fnmsub_s 0000 10001101 ..... ..... ..... ..... @ffff +fnmsub_d 0000 10001110 ..... ..... ..... ..... @ffff +fmax_s 0000 00010000 10001 ..... ..... ..... @fff +fmax_d 0000 00010000 10010 ..... ..... ..... @fff +fmin_s 0000 00010000 10101 ..... ..... ..... @fff +fmin_d 0000 00010000 10110 ..... ..... ..... @fff +fmaxa_s 0000 00010000 11001 ..... ..... ..... @fff +fmaxa_d 0000 00010000 11010 ..... ..... ..... @fff +fmina_s 0000 00010000 11101 ..... ..... ..... @fff +fmina_d 0000 00010000 11110 ..... ..... ..... @fff +fabs_s 0000 00010001 01000 00001 ..... ..... @ff +fabs_d 0000 00010001 01000 00010 ..... ..... @ff +fneg_s 0000 00010001 01000 00101 ..... ..... @ff +fneg_d 0000 00010001 01000 00110 ..... ..... @ff +fsqrt_s 0000 00010001 01000 10001 ..... ..... @ff +fsqrt_d 0000 00010001 01000 10010 ..... ..... @ff +frecip_s 0000 00010001 01000 10101 ..... ..... @ff +frecip_d 0000 00010001 01000 10110 ..... ..... @ff +frsqrt_s 0000 00010001 01000 11001 ..... ..... @ff +frsqrt_d 0000 00010001 01000 11010 ..... ..... @ff +fscaleb_s 0000 00010001 00001 ..... ..... ..... @fff +fscaleb_d 0000 00010001 00010 ..... ..... ..... @fff +flogb_s 0000 00010001 01000 01001 ..... ..... @ff +flogb_d 0000 00010001 01000 01010 ..... ..... @ff +fcopysign_s 0000 00010001 00101 ..... ..... ..... @fff +fcopysign_d 0000 00010001 00110 ..... ..... ..... @fff +fclass_s 0000 00010001 01000 01101 ..... ..... @ff +fclass_d 0000 00010001 01000 01110 ..... ..... @ff diff --git a/target/loongarch/internals.h b/target/loongarch/internals.h index 1e69e7d..17219d4 100644 --- a/target/loongarch/internals.h +++ b/target/loongarch/internals.h @@ -18,4 +18,6 @@ void QEMU_NORETURN do_raise_exception(CPULoongArchState *env, const char *loongarch_exception_name(int32_t exception); +void restore_fp_status(CPULoongArchState *env); + #endif diff --git a/target/loongarch/translate.c b/target/loongarch/translate.c index ca3ee23..b7ace9e 100644 --- a/target/loongarch/translate.c +++ b/target/loongarch/translate.c @@ -15,6 +15,7 @@ #include "exec/translator.h" #include "exec/log.h" #include "qemu/qemu-print.h" +#include "fpu/softfloat.h" #include "translate.h" #include "internals.h" @@ -31,6 +32,15 @@ static inline int plus_1(DisasContext *ctx, int x) return x + 1; } +/* + * LoongArch the upper 32 bits are undefined ("can be any value"). + * QEMU chooses to nanbox, because it is most likely to show guest bugs early. + */ +static void gen_nanbox_s(TCGv_i64 out, TCGv_i64 in) +{ + tcg_gen_ori_i64(out, in, MAKE_64BIT_MASK(32, 32)); +} + void generate_exception(DisasContext *ctx, int excp) { tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next); @@ -180,6 +190,7 @@ static void gen_set_gpr(int reg_num, TCGv t, DisasExtend dst_ext) #include "insn_trans/trans_memory.c.inc" #include "insn_trans/trans_atomic.c.inc" #include "insn_trans/trans_extra.c.inc" +#include "insn_trans/trans_farith.c.inc" static void loongarch_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs) { From patchwork Fri Nov 19 06:13:15 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: gaosong X-Patchwork-Id: 1556922 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4HwRbN07rTz9sXN for ; Fri, 19 Nov 2021 17:29:36 +1100 (AEDT) Received: from localhost ([::1]:33912 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mnxOv-0000zc-Qc for incoming@patchwork.ozlabs.org; Fri, 19 Nov 2021 01:29:33 -0500 Received: from eggs.gnu.org ([209.51.188.92]:46312) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mnx9k-0003wQ-TC for qemu-devel@nongnu.org; Fri, 19 Nov 2021 01:13:52 -0500 Received: from mail.loongson.cn ([114.242.206.163]:46702 helo=loongson.cn) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mnx9h-0004Xz-WC for qemu-devel@nongnu.org; Fri, 19 Nov 2021 01:13:52 -0500 Received: from kvm-dev1.localdomain (unknown [10.2.5.134]) by mail.loongson.cn (Coremail) with SMTP id AQAAf9Dxj8+KQJdhSG0AAA--.1952S13; Fri, 19 Nov 2021 14:13:43 +0800 (CST) From: Song Gao To: qemu-devel@nongnu.org Subject: [PATCH v11 11/26] target/loongarch: Add floating point comparison instruction translation Date: Fri, 19 Nov 2021 14:13:15 +0800 Message-Id: <1637302410-24632-12-git-send-email-gaosong@loongson.cn> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1637302410-24632-1-git-send-email-gaosong@loongson.cn> References: <1637302410-24632-1-git-send-email-gaosong@loongson.cn> X-CM-TRANSID: AQAAf9Dxj8+KQJdhSG0AAA--.1952S13 X-Coremail-Antispam: 1UD129KBjvJXoW3Xr4DWrWrJr4fZF1kKr1fXrb_yoWxuFW3pF W7Zry3KF48WFWfZ3Z2va98KFn8Wr48Ka129a4ft34kAF45XFn7Zrykta429FWUG34kZryx X3Way34UWFy7XaUanT9S1TB71UUUUUUqnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnUUvcSsGvfC2KfnxnUUI43ZEXa7xR_UUUUUUUUU== X-CM-SenderInfo: 5jdr20tqj6z05rqj20fqof0/ Received-SPF: pass client-ip=114.242.206.163; envelope-from=gaosong@loongson.cn; helo=loongson.cn X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Xiaojuan Yang , richard.henderson@linaro.org, laurent@vivier.eu Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" This includes: - FCMP.cond.{S/D} Signed-off-by: Song Gao Signed-off-by: Xiaojuan Yang Reviewed-by: Richard Henderson --- target/loongarch/fpu_helper.c | 60 ++++++++++++++++++++++++++++ target/loongarch/helper.h | 9 +++++ target/loongarch/insn_trans/trans_fcmp.c.inc | 56 ++++++++++++++++++++++++++ target/loongarch/insns.decode | 8 ++++ target/loongarch/internals.h | 5 +++ target/loongarch/translate.c | 1 + 6 files changed, 139 insertions(+) create mode 100644 target/loongarch/insn_trans/trans_fcmp.c.inc diff --git a/target/loongarch/fpu_helper.c b/target/loongarch/fpu_helper.c index d0ef675..807ffd0 100644 --- a/target/loongarch/fpu_helper.c +++ b/target/loongarch/fpu_helper.c @@ -403,3 +403,63 @@ uint64_t helper_fmuladd_d(CPULoongArchState *env, uint64_t fj, update_fcsr0(env, GETPC()); return fd; } + +static uint64_t fcmp_common(CPULoongArchState *env, FloatRelation cmp, + uint32_t flags) +{ + bool ret; + + switch (cmp) { + case float_relation_less: + ret = (flags & FCMP_LT); + break; + case float_relation_equal: + ret = (flags & FCMP_EQ); + break; + case float_relation_greater: + ret = (flags & FCMP_GT); + break; + case float_relation_unordered: + ret = (flags & FCMP_UN); + break; + default: + g_assert_not_reached(); + } + update_fcsr0(env, GETPC()); + + return ret; +} + +/* fcmp_cXXX_s */ +uint64_t helper_fcmp_c_s(CPULoongArchState *env, uint64_t fj, + uint64_t fk, uint32_t flags) +{ + FloatRelation cmp = float32_compare_quiet((uint32_t)fj, + (uint32_t)fk, &env->fp_status); + return fcmp_common(env, cmp, flags); +} + +/* fcmp_sXXX_s */ +uint64_t helper_fcmp_s_s(CPULoongArchState *env, uint64_t fj, + uint64_t fk, uint32_t flags) +{ + FloatRelation cmp = float32_compare((uint32_t)fj, + (uint32_t)fk, &env->fp_status); + return fcmp_common(env, cmp, flags); +} + +/* fcmp_cXXX_d */ +uint64_t helper_fcmp_c_d(CPULoongArchState *env, uint64_t fj, + uint64_t fk, uint32_t flags) +{ + FloatRelation cmp = float64_compare_quiet(fj, fk, &env->fp_status); + return fcmp_common(env, cmp, flags); +} + +/* fcmp_sXXX_d */ +uint64_t helper_fcmp_s_d(CPULoongArchState *env, uint64_t fj, + uint64_t fk, uint32_t flags) +{ + FloatRelation cmp = float64_compare(fj, fk, &env->fp_status); + return fcmp_common(env, cmp, flags); +} diff --git a/target/loongarch/helper.h b/target/loongarch/helper.h index d6bb412..30b270a 100644 --- a/target/loongarch/helper.h +++ b/target/loongarch/helper.h @@ -52,3 +52,12 @@ DEF_HELPER_2(frecip_d, i64, env, i64) DEF_HELPER_FLAGS_2(fclass_s, TCG_CALL_NO_RWG_SE, i64, env, i64) DEF_HELPER_FLAGS_2(fclass_d, TCG_CALL_NO_RWG_SE, i64, env, i64) + +/* fcmp.cXXX.s */ +DEF_HELPER_4(fcmp_c_s, i64, env, i64, i64, i32) +/* fcmp.sXXX.s */ +DEF_HELPER_4(fcmp_s_s, i64, env, i64, i64, i32) +/* fcmp.cXXX.d */ +DEF_HELPER_4(fcmp_c_d, i64, env, i64, i64, i32) +/* fcmp.sXXX.d */ +DEF_HELPER_4(fcmp_s_d, i64, env, i64, i64, i32) diff --git a/target/loongarch/insn_trans/trans_fcmp.c.inc b/target/loongarch/insn_trans/trans_fcmp.c.inc new file mode 100644 index 0000000..ce39c07 --- /dev/null +++ b/target/loongarch/insn_trans/trans_fcmp.c.inc @@ -0,0 +1,56 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (c) 2021 Loongson Technology Corporation Limited + */ + +/* bit0(signaling/quiet) bit1(lt) bit2(eq) bit3(un) bit4(neq) */ +static uint32_t get_fcmp_flags(int cond) +{ + uint32_t flags = 0; + + if (cond & 0x1) { + flags |= FCMP_LT; + } + if (cond & 0x2) { + flags |= FCMP_EQ; + } + if (cond & 0x4) { + flags |= FCMP_UN; + } + if (cond & 0x8) { + flags |= FCMP_GT | FCMP_LT; + } + return flags; +} + +static bool trans_fcmp_cond_s(DisasContext *ctx, arg_fcmp_cond_s *a) +{ + TCGv var = tcg_temp_new(); + uint32_t flags; + void (*fn)(TCGv, TCGv_env, TCGv, TCGv, TCGv_i32); + + fn = (a->fcond & 1 ? gen_helper_fcmp_s_s : gen_helper_fcmp_c_s); + flags = get_fcmp_flags(a->fcond >> 1); + + fn(var, cpu_env, cpu_fpr[a->fj], cpu_fpr[a->fk], tcg_constant_i32(flags)); + + tcg_gen_st8_tl(var, cpu_env, offsetof(CPULoongArchState, cf[a->cd & 0x7])); + tcg_temp_free(var); + return true; +} + +static bool trans_fcmp_cond_d(DisasContext *ctx, arg_fcmp_cond_d *a) +{ + TCGv var = tcg_temp_new(); + uint32_t flags; + void (*fn)(TCGv, TCGv_env, TCGv, TCGv, TCGv_i32); + fn = (a->fcond & 1 ? gen_helper_fcmp_s_d : gen_helper_fcmp_c_d); + flags = get_fcmp_flags(a->fcond >> 1); + + fn(var, cpu_env, cpu_fpr[a->fj], cpu_fpr[a->fk], tcg_constant_i32(flags)); + + tcg_gen_st8_tl(var, cpu_env, offsetof(CPULoongArchState, cf[a->cd & 0x7])); + + tcg_temp_free(var); + return true; +} diff --git a/target/loongarch/insns.decode b/target/loongarch/insns.decode index 28a2f5e..17e1df8 100644 --- a/target/loongarch/insns.decode +++ b/target/loongarch/insns.decode @@ -26,6 +26,7 @@ &ff fd fj &fff fd fj fk &ffff fd fj fk fa +&cff_fcond cd fj fk fcond # # Formats @@ -50,6 +51,7 @@ @ff .... ........ ..... ..... fj:5 fd:5 &ff @fff .... ........ ..... fk:5 fj:5 fd:5 &fff @ffff .... ........ fa:5 fk:5 fj:5 fd:5 &ffff +@cff_fcond .... ........ fcond:5 fk:5 fj:5 .. cd:3 &cff_fcond # # Fixed point arithmetic operation instruction @@ -311,3 +313,9 @@ fcopysign_s 0000 00010001 00101 ..... ..... ..... @fff fcopysign_d 0000 00010001 00110 ..... ..... ..... @fff fclass_s 0000 00010001 01000 01101 ..... ..... @ff fclass_d 0000 00010001 01000 01110 ..... ..... @ff + +# +# Floating point compare instruction +# +fcmp_cond_s 0000 11000001 ..... ..... ..... 00 ... @cff_fcond +fcmp_cond_d 0000 11000010 ..... ..... ..... 00 ... @cff_fcond diff --git a/target/loongarch/internals.h b/target/loongarch/internals.h index 17219d4..e9e6374 100644 --- a/target/loongarch/internals.h +++ b/target/loongarch/internals.h @@ -8,6 +8,11 @@ #ifndef LOONGARCH_INTERNALS_H #define LOONGARCH_INTERNALS_H +#define FCMP_LT 0x0001 /* fp0 < fp1 */ +#define FCMP_EQ 0x0010 /* fp0 = fp1 */ +#define FCMP_UN 0x0100 /* unordered */ +#define FCMP_GT 0x1000 /* fp0 > fp1 */ + void loongarch_translate_init(void); void loongarch_cpu_dump_state(CPUState *cpu, FILE *f, int flags); diff --git a/target/loongarch/translate.c b/target/loongarch/translate.c index b7ace9e..fd43e1b 100644 --- a/target/loongarch/translate.c +++ b/target/loongarch/translate.c @@ -191,6 +191,7 @@ static void gen_set_gpr(int reg_num, TCGv t, DisasExtend dst_ext) #include "insn_trans/trans_atomic.c.inc" #include "insn_trans/trans_extra.c.inc" #include "insn_trans/trans_farith.c.inc" +#include "insn_trans/trans_fcmp.c.inc" static void loongarch_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs) { From patchwork Fri Nov 19 06:13:16 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: gaosong X-Patchwork-Id: 1556936 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4HwSBp2X5dz9sPf for ; Fri, 19 Nov 2021 17:56:50 +1100 (AEDT) Received: from localhost ([::1]:44894 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mnxpI-00038V-1K for incoming@patchwork.ozlabs.org; Fri, 19 Nov 2021 01:56:48 -0500 Received: from eggs.gnu.org ([209.51.188.92]:48236) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mnxHj-00042d-Dz for qemu-devel@nongnu.org; Fri, 19 Nov 2021 01:22:11 -0500 Received: from mail.loongson.cn ([114.242.206.163]:49384 helo=loongson.cn) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mnxHf-0006BT-Fx for qemu-devel@nongnu.org; Fri, 19 Nov 2021 01:22:07 -0500 Received: from kvm-dev1.localdomain (unknown [10.2.5.134]) by mail.loongson.cn (Coremail) with SMTP id AQAAf9Dxj8+KQJdhSG0AAA--.1952S14; Fri, 19 Nov 2021 14:13:44 +0800 (CST) From: Song Gao To: qemu-devel@nongnu.org Subject: [PATCH v11 12/26] target/loongarch: Add floating point conversion instruction translation Date: Fri, 19 Nov 2021 14:13:16 +0800 Message-Id: <1637302410-24632-13-git-send-email-gaosong@loongson.cn> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1637302410-24632-1-git-send-email-gaosong@loongson.cn> References: <1637302410-24632-1-git-send-email-gaosong@loongson.cn> X-CM-TRANSID: AQAAf9Dxj8+KQJdhSG0AAA--.1952S14 X-Coremail-Antispam: 1UD129KBjvAXoW3Zr47Ww17Kr4UtrWxGrWUtwb_yoW8CFW3Wo Z8uF1rXr4rG3yfuFZIkwnYqF1xXry8ArnxCF4rZryaga4xA34xKFWrCrn5AFyrKrWYqry5 Xrn3Z3W5Aw43Xr93n29KB7ZKAUJUUUUU529EdanIXcx71UUUUU7v73VFW2AGmfu7bjvjm3 AaLaJ3UjIYCTnIWjDUYxBIdaVFxhVjvjDU0xZFpf9x0zRUUUUUUUUU= X-CM-SenderInfo: 5jdr20tqj6z05rqj20fqof0/ Received-SPF: pass client-ip=114.242.206.163; envelope-from=gaosong@loongson.cn; helo=loongson.cn X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Xiaojuan Yang , richard.henderson@linaro.org, laurent@vivier.eu Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" This includes: - FCVT.S.D, FCVT.D.S - FFINT.{S/D}.{W/L}, FTINT.{W/L}.{S/D} - FTINT{RM/RP/RZ/RNE}.{W/L}.{S/D} - FRINT.{S/D} Signed-off-by: Song Gao Signed-off-by: Xiaojuan Yang Reviewed-by: Richard Henderson --- target/loongarch/fpu_helper.c | 393 +++++++++++++++++++++++++++ target/loongarch/helper.h | 29 ++ target/loongarch/insn_trans/trans_fcnv.c.inc | 33 +++ target/loongarch/insns.decode | 32 +++ target/loongarch/translate.c | 1 + 5 files changed, 488 insertions(+) create mode 100644 target/loongarch/insn_trans/trans_fcnv.c.inc diff --git a/target/loongarch/fpu_helper.c b/target/loongarch/fpu_helper.c index 807ffd0..4799b47 100644 --- a/target/loongarch/fpu_helper.c +++ b/target/loongarch/fpu_helper.c @@ -463,3 +463,396 @@ uint64_t helper_fcmp_s_d(CPULoongArchState *env, uint64_t fj, FloatRelation cmp = float64_compare(fj, fk, &env->fp_status); return fcmp_common(env, cmp, flags); } + +/* floating point conversion */ +uint64_t helper_fcvt_s_d(CPULoongArchState *env, uint64_t fj) +{ + uint64_t fd; + + fd = nanbox_s(float64_to_float32(fj, &env->fp_status)); + update_fcsr0(env, GETPC()); + return fd; +} + +uint64_t helper_fcvt_d_s(CPULoongArchState *env, uint64_t fj) +{ + uint64_t fd; + + fd = float32_to_float64((uint32_t)fj, &env->fp_status); + update_fcsr0(env, GETPC()); + return fd; +} + +uint64_t helper_ffint_s_w(CPULoongArchState *env, uint64_t fj) +{ + uint64_t fd; + + fd = nanbox_s(int32_to_float32((int32_t)fj, &env->fp_status)); + update_fcsr0(env, GETPC()); + return fd; +} + +uint64_t helper_ffint_s_l(CPULoongArchState *env, uint64_t fj) +{ + uint64_t fd; + + fd = nanbox_s(int64_to_float32(fj, &env->fp_status)); + update_fcsr0(env, GETPC()); + return fd; +} + +uint64_t helper_ffint_d_w(CPULoongArchState *env, uint64_t fj) +{ + uint64_t fd; + + fd = int32_to_float64((int32_t)fj, &env->fp_status); + update_fcsr0(env, GETPC()); + return fd; +} + +uint64_t helper_ffint_d_l(CPULoongArchState *env, uint64_t fj) +{ + uint64_t fd; + + fd = int64_to_float64(fj, &env->fp_status); + update_fcsr0(env, GETPC()); + return fd; +} + +uint64_t helper_frint_s(CPULoongArchState *env, uint64_t fj) +{ + uint64_t fd; + + fd = (uint64_t)(float32_round_to_int((uint32_t)fj, &env->fp_status)); + update_fcsr0(env, GETPC()); + return fd; +} + +uint64_t helper_frint_d(CPULoongArchState *env, uint64_t fj) +{ + uint64_t fd; + + fd = float64_round_to_int(fj, &env->fp_status); + update_fcsr0(env, GETPC()); + return fd; +} + +uint64_t helper_ftintrm_l_d(CPULoongArchState *env, uint64_t fj) +{ + uint64_t fd; + FloatRoundMode old_mode = get_float_rounding_mode(&env->fp_status); + + set_float_rounding_mode(float_round_down, &env->fp_status); + fd = float64_to_int64(fj, &env->fp_status); + set_float_rounding_mode(old_mode, &env->fp_status); + + if (get_float_exception_flags(&env->fp_status) & + (float_flag_invalid | float_flag_overflow)) { + fd = FLOAT_TO_INT64_OVERFLOW; + } + update_fcsr0(env, GETPC()); + return fd; +} + +uint64_t helper_ftintrm_l_s(CPULoongArchState *env, uint64_t fj) +{ + uint64_t fd; + FloatRoundMode old_mode = get_float_rounding_mode(&env->fp_status); + + set_float_rounding_mode(float_round_down, &env->fp_status); + fd = float32_to_int64((uint32_t)fj, &env->fp_status); + set_float_rounding_mode(old_mode, &env->fp_status); + + if (get_float_exception_flags(&env->fp_status) & + (float_flag_invalid | float_flag_overflow)) { + fd = FLOAT_TO_INT64_OVERFLOW; + } + update_fcsr0(env, GETPC()); + return fd; +} + +uint64_t helper_ftintrm_w_d(CPULoongArchState *env, uint64_t fj) +{ + uint64_t fd; + FloatRoundMode old_mode = get_float_rounding_mode(&env->fp_status); + + set_float_rounding_mode(float_round_down, &env->fp_status); + fd = (uint64_t)float64_to_int32(fj, &env->fp_status); + set_float_rounding_mode(old_mode, &env->fp_status); + + if (get_float_exception_flags(&env->fp_status) & + (float_flag_invalid | float_flag_overflow)) { + fd = FLOAT_TO_INT32_OVERFLOW; + } + update_fcsr0(env, GETPC()); + return fd; +} + +uint64_t helper_ftintrm_w_s(CPULoongArchState *env, uint64_t fj) +{ + uint64_t fd; + FloatRoundMode old_mode = get_float_rounding_mode(&env->fp_status); + + set_float_rounding_mode(float_round_down, &env->fp_status); + fd = (uint64_t)float32_to_int32((uint32_t)fj, &env->fp_status); + set_float_rounding_mode(old_mode, &env->fp_status); + + if (get_float_exception_flags(&env->fp_status) & + (float_flag_invalid | float_flag_overflow)) { + fd = FLOAT_TO_INT32_OVERFLOW; + } + update_fcsr0(env, GETPC()); + return fd; +} + +uint64_t helper_ftintrp_l_d(CPULoongArchState *env, uint64_t fj) +{ + uint64_t fd; + FloatRoundMode old_mode = get_float_rounding_mode(&env->fp_status); + + set_float_rounding_mode(float_round_up, &env->fp_status); + fd = float64_to_int64(fj, &env->fp_status); + set_float_rounding_mode(old_mode, &env->fp_status); + + if (get_float_exception_flags(&env->fp_status) & + (float_flag_invalid | float_flag_overflow)) { + fd = FLOAT_TO_INT64_OVERFLOW; + } + update_fcsr0(env, GETPC()); + return fd; +} + +uint64_t helper_ftintrp_l_s(CPULoongArchState *env, uint64_t fj) +{ + uint64_t fd; + FloatRoundMode old_mode = get_float_rounding_mode(&env->fp_status); + + set_float_rounding_mode(float_round_up, &env->fp_status); + fd = float32_to_int64((uint32_t)fj, &env->fp_status); + set_float_rounding_mode(old_mode, &env->fp_status); + + if (get_float_exception_flags(&env->fp_status) & + (float_flag_invalid | float_flag_overflow)) { + fd = FLOAT_TO_INT64_OVERFLOW; + } + update_fcsr0(env, GETPC()); + return fd; +} + +uint64_t helper_ftintrp_w_d(CPULoongArchState *env, uint64_t fj) +{ + uint64_t fd; + FloatRoundMode old_mode = get_float_rounding_mode(&env->fp_status); + + set_float_rounding_mode(float_round_up, &env->fp_status); + fd = (uint64_t)float64_to_int32(fj, &env->fp_status); + set_float_rounding_mode(old_mode, &env->fp_status); + + if (get_float_exception_flags(&env->fp_status) & + (float_flag_invalid | float_flag_overflow)) { + fd = FLOAT_TO_INT32_OVERFLOW; + } + update_fcsr0(env, GETPC()); + return fd; +} + +uint64_t helper_ftintrp_w_s(CPULoongArchState *env, uint64_t fj) +{ + uint64_t fd; + FloatRoundMode old_mode = get_float_rounding_mode(&env->fp_status); + + set_float_rounding_mode(float_round_up, &env->fp_status); + fd = (uint64_t)float32_to_int32((uint32_t)fj, &env->fp_status); + set_float_rounding_mode(old_mode, &env->fp_status); + + if (get_float_exception_flags(&env->fp_status) & + (float_flag_invalid | float_flag_overflow)) { + fd = FLOAT_TO_INT32_OVERFLOW; + } + update_fcsr0(env, GETPC()); + return fd; +} + +uint64_t helper_ftintrz_l_d(CPULoongArchState *env, uint64_t fj) +{ + uint64_t fd; + FloatRoundMode old_mode = get_float_rounding_mode(&env->fp_status); + + fd = float64_to_int64_round_to_zero(fj, &env->fp_status); + set_float_rounding_mode(old_mode, &env->fp_status); + + if (get_float_exception_flags(&env->fp_status) & + (float_flag_invalid | float_flag_overflow)) { + fd = FLOAT_TO_INT64_OVERFLOW; + } + update_fcsr0(env, GETPC()); + return fd; +} + +uint64_t helper_ftintrz_l_s(CPULoongArchState *env, uint64_t fj) +{ + uint64_t fd; + FloatRoundMode old_mode = get_float_rounding_mode(&env->fp_status); + + fd = float32_to_int64_round_to_zero((uint32_t)fj, &env->fp_status); + set_float_rounding_mode(old_mode, &env->fp_status); + + if (get_float_exception_flags(&env->fp_status) & + (float_flag_invalid | float_flag_overflow)) { + fd = FLOAT_TO_INT64_OVERFLOW; + } + update_fcsr0(env, GETPC()); + return fd; +} + +uint64_t helper_ftintrz_w_d(CPULoongArchState *env, uint64_t fj) +{ + uint64_t fd; + FloatRoundMode old_mode = get_float_rounding_mode(&env->fp_status); + + fd = (uint64_t)float64_to_int32_round_to_zero(fj, &env->fp_status); + set_float_rounding_mode(old_mode, &env->fp_status); + + if (get_float_exception_flags(&env->fp_status) & + (float_flag_invalid | float_flag_overflow)) { + fd = FLOAT_TO_INT32_OVERFLOW; + } + update_fcsr0(env, GETPC()); + return fd; +} + +uint64_t helper_ftintrz_w_s(CPULoongArchState *env, uint64_t fj) +{ + uint32_t fd; + FloatRoundMode old_mode = get_float_rounding_mode(&env->fp_status); + + fd = float32_to_int32_round_to_zero((uint32_t)fj, &env->fp_status); + set_float_rounding_mode(old_mode, &env->fp_status); + + if (get_float_exception_flags(&env->fp_status) & + (float_flag_invalid | float_flag_overflow)) { + fd = FLOAT_TO_INT32_OVERFLOW; + } + update_fcsr0(env, GETPC()); + return (uint64_t)fd; +} + +uint64_t helper_ftintrne_l_d(CPULoongArchState *env, uint64_t fj) +{ + uint64_t fd; + FloatRoundMode old_mode = get_float_rounding_mode(&env->fp_status); + + set_float_rounding_mode(float_round_nearest_even, &env->fp_status); + fd = float64_to_int64(fj, &env->fp_status); + set_float_rounding_mode(old_mode, &env->fp_status); + + if (get_float_exception_flags(&env->fp_status) & + (float_flag_invalid | float_flag_overflow)) { + fd = FLOAT_TO_INT64_OVERFLOW; + } + update_fcsr0(env, GETPC()); + return fd; +} + +uint64_t helper_ftintrne_l_s(CPULoongArchState *env, uint64_t fj) +{ + uint64_t fd; + FloatRoundMode old_mode = get_float_rounding_mode(&env->fp_status); + + set_float_rounding_mode(float_round_nearest_even, &env->fp_status); + fd = float32_to_int64((uint32_t)fj, &env->fp_status); + set_float_rounding_mode(old_mode, &env->fp_status); + + if (get_float_exception_flags(&env->fp_status) & + (float_flag_invalid | float_flag_overflow)) { + fd = FLOAT_TO_INT64_OVERFLOW; + } + update_fcsr0(env, GETPC()); + return fd; +} + +uint64_t helper_ftintrne_w_d(CPULoongArchState *env, uint64_t fj) +{ + uint64_t fd; + FloatRoundMode old_mode = get_float_rounding_mode(&env->fp_status); + + set_float_rounding_mode(float_round_nearest_even, &env->fp_status); + fd = (uint64_t)float64_to_int32(fj, &env->fp_status); + set_float_rounding_mode(old_mode, &env->fp_status); + + if (get_float_exception_flags(&env->fp_status) & + (float_flag_invalid | float_flag_overflow)) { + fd = FLOAT_TO_INT32_OVERFLOW; + } + update_fcsr0(env, GETPC()); + return fd; +} + +uint64_t helper_ftintrne_w_s(CPULoongArchState *env, uint64_t fj) +{ + uint32_t fd; + FloatRoundMode old_mode = get_float_rounding_mode(&env->fp_status); + + set_float_rounding_mode(float_round_nearest_even, &env->fp_status); + fd = float32_to_int32((uint32_t)fj, &env->fp_status); + set_float_rounding_mode(old_mode, &env->fp_status); + + if (get_float_exception_flags(&env->fp_status) & + (float_flag_invalid | float_flag_overflow)) { + fd = FLOAT_TO_INT32_OVERFLOW; + } + update_fcsr0(env, GETPC()); + return (uint64_t)fd; +} + +uint64_t helper_ftint_l_d(CPULoongArchState *env, uint64_t fj) +{ + uint64_t fd; + + fd = float64_to_int64(fj, &env->fp_status); + if (get_float_exception_flags(&env->fp_status) & + (float_flag_invalid | float_flag_overflow)) { + fd = FLOAT_TO_INT64_OVERFLOW; + } + update_fcsr0(env, GETPC()); + return fd; +} + +uint64_t helper_ftint_l_s(CPULoongArchState *env, uint64_t fj) +{ + uint64_t fd; + + fd = float32_to_int64((uint32_t)fj, &env->fp_status); + if (get_float_exception_flags(&env->fp_status) & + (float_flag_invalid | float_flag_overflow)) { + fd = FLOAT_TO_INT64_OVERFLOW; + } + update_fcsr0(env, GETPC()); + return fd; +} + +uint64_t helper_ftint_w_s(CPULoongArchState *env, uint64_t fj) +{ + uint64_t fd; + + fd = (uint64_t)float32_to_int32((uint32_t)fj, &env->fp_status); + if (get_float_exception_flags(&env->fp_status) + & (float_flag_invalid | float_flag_overflow)) { + fd = FLOAT_TO_INT32_OVERFLOW; + } + update_fcsr0(env, GETPC()); + return fd; +} + +uint64_t helper_ftint_w_d(CPULoongArchState *env, uint64_t fj) +{ + uint64_t fd; + + fd = (uint64_t)float64_to_int32(fj, &env->fp_status); + if (get_float_exception_flags(&env->fp_status) + & (float_flag_invalid | float_flag_overflow)) { + fd = FLOAT_TO_INT32_OVERFLOW; + } + update_fcsr0(env, GETPC()); + return fd; +} diff --git a/target/loongarch/helper.h b/target/loongarch/helper.h index 30b270a..51bbf25 100644 --- a/target/loongarch/helper.h +++ b/target/loongarch/helper.h @@ -61,3 +61,32 @@ DEF_HELPER_4(fcmp_s_s, i64, env, i64, i64, i32) DEF_HELPER_4(fcmp_c_d, i64, env, i64, i64, i32) /* fcmp.sXXX.d */ DEF_HELPER_4(fcmp_s_d, i64, env, i64, i64, i32) + +DEF_HELPER_2(fcvt_d_s, i64, env, i64) +DEF_HELPER_2(fcvt_s_d, i64, env, i64) +DEF_HELPER_2(ffint_d_w, i64, env, i64) +DEF_HELPER_2(ffint_d_l, i64, env, i64) +DEF_HELPER_2(ffint_s_w, i64, env, i64) +DEF_HELPER_2(ffint_s_l, i64, env, i64) +DEF_HELPER_2(ftintrm_l_s, i64, env, i64) +DEF_HELPER_2(ftintrm_l_d, i64, env, i64) +DEF_HELPER_2(ftintrm_w_s, i64, env, i64) +DEF_HELPER_2(ftintrm_w_d, i64, env, i64) +DEF_HELPER_2(ftintrp_l_s, i64, env, i64) +DEF_HELPER_2(ftintrp_l_d, i64, env, i64) +DEF_HELPER_2(ftintrp_w_s, i64, env, i64) +DEF_HELPER_2(ftintrp_w_d, i64, env, i64) +DEF_HELPER_2(ftintrz_l_s, i64, env, i64) +DEF_HELPER_2(ftintrz_l_d, i64, env, i64) +DEF_HELPER_2(ftintrz_w_s, i64, env, i64) +DEF_HELPER_2(ftintrz_w_d, i64, env, i64) +DEF_HELPER_2(ftintrne_l_s, i64, env, i64) +DEF_HELPER_2(ftintrne_l_d, i64, env, i64) +DEF_HELPER_2(ftintrne_w_s, i64, env, i64) +DEF_HELPER_2(ftintrne_w_d, i64, env, i64) +DEF_HELPER_2(ftint_l_s, i64, env, i64) +DEF_HELPER_2(ftint_l_d, i64, env, i64) +DEF_HELPER_2(ftint_w_s, i64, env, i64) +DEF_HELPER_2(ftint_w_d, i64, env, i64) +DEF_HELPER_2(frint_s, i64, env, i64) +DEF_HELPER_2(frint_d, i64, env, i64) diff --git a/target/loongarch/insn_trans/trans_fcnv.c.inc b/target/loongarch/insn_trans/trans_fcnv.c.inc new file mode 100644 index 0000000..c1c6918 --- /dev/null +++ b/target/loongarch/insn_trans/trans_fcnv.c.inc @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (c) 2021 Loongson Technology Corporation Limited + */ + +TRANS(fcvt_s_d, gen_ff, gen_helper_fcvt_s_d) +TRANS(fcvt_d_s, gen_ff, gen_helper_fcvt_d_s) +TRANS(ftintrm_w_s, gen_ff, gen_helper_ftintrm_w_s) +TRANS(ftintrm_w_d, gen_ff, gen_helper_ftintrm_w_d) +TRANS(ftintrm_l_s, gen_ff, gen_helper_ftintrm_l_s) +TRANS(ftintrm_l_d, gen_ff, gen_helper_ftintrm_l_d) +TRANS(ftintrp_w_s, gen_ff, gen_helper_ftintrp_w_s) +TRANS(ftintrp_w_d, gen_ff, gen_helper_ftintrp_w_d) +TRANS(ftintrp_l_s, gen_ff, gen_helper_ftintrp_l_s) +TRANS(ftintrp_l_d, gen_ff, gen_helper_ftintrp_l_d) +TRANS(ftintrz_w_s, gen_ff, gen_helper_ftintrz_w_s) +TRANS(ftintrz_w_d, gen_ff, gen_helper_ftintrz_w_d) +TRANS(ftintrz_l_s, gen_ff, gen_helper_ftintrz_l_s) +TRANS(ftintrz_l_d, gen_ff, gen_helper_ftintrz_l_d) +TRANS(ftintrne_w_s, gen_ff, gen_helper_ftintrne_w_s) +TRANS(ftintrne_w_d, gen_ff, gen_helper_ftintrne_w_d) +TRANS(ftintrne_l_s, gen_ff, gen_helper_ftintrne_l_s) +TRANS(ftintrne_l_d, gen_ff, gen_helper_ftintrne_l_d) +TRANS(ftint_w_s, gen_ff, gen_helper_ftint_w_s) +TRANS(ftint_w_d, gen_ff, gen_helper_ftint_w_d) +TRANS(ftint_l_s, gen_ff, gen_helper_ftint_l_s) +TRANS(ftint_l_d, gen_ff, gen_helper_ftint_l_d) +TRANS(ffint_s_w, gen_ff, gen_helper_ffint_s_w) +TRANS(ffint_s_l, gen_ff, gen_helper_ffint_s_l) +TRANS(ffint_d_w, gen_ff, gen_helper_ffint_d_w) +TRANS(ffint_d_l, gen_ff, gen_helper_ffint_d_l) +TRANS(frint_s, gen_ff, gen_helper_frint_s) +TRANS(frint_d, gen_ff, gen_helper_frint_d) diff --git a/target/loongarch/insns.decode b/target/loongarch/insns.decode index 17e1df8..a7e0a7e 100644 --- a/target/loongarch/insns.decode +++ b/target/loongarch/insns.decode @@ -319,3 +319,35 @@ fclass_d 0000 00010001 01000 01110 ..... ..... @ff # fcmp_cond_s 0000 11000001 ..... ..... ..... 00 ... @cff_fcond fcmp_cond_d 0000 11000010 ..... ..... ..... 00 ... @cff_fcond + +# +# Floating point conversion instruction +# +fcvt_s_d 0000 00010001 10010 00110 ..... ..... @ff +fcvt_d_s 0000 00010001 10010 01001 ..... ..... @ff +ftintrm_w_s 0000 00010001 10100 00001 ..... ..... @ff +ftintrm_w_d 0000 00010001 10100 00010 ..... ..... @ff +ftintrm_l_s 0000 00010001 10100 01001 ..... ..... @ff +ftintrm_l_d 0000 00010001 10100 01010 ..... ..... @ff +ftintrp_w_s 0000 00010001 10100 10001 ..... ..... @ff +ftintrp_w_d 0000 00010001 10100 10010 ..... ..... @ff +ftintrp_l_s 0000 00010001 10100 11001 ..... ..... @ff +ftintrp_l_d 0000 00010001 10100 11010 ..... ..... @ff +ftintrz_w_s 0000 00010001 10101 00001 ..... ..... @ff +ftintrz_w_d 0000 00010001 10101 00010 ..... ..... @ff +ftintrz_l_s 0000 00010001 10101 01001 ..... ..... @ff +ftintrz_l_d 0000 00010001 10101 01010 ..... ..... @ff +ftintrne_w_s 0000 00010001 10101 10001 ..... ..... @ff +ftintrne_w_d 0000 00010001 10101 10010 ..... ..... @ff +ftintrne_l_s 0000 00010001 10101 11001 ..... ..... @ff +ftintrne_l_d 0000 00010001 10101 11010 ..... ..... @ff +ftint_w_s 0000 00010001 10110 00001 ..... ..... @ff +ftint_w_d 0000 00010001 10110 00010 ..... ..... @ff +ftint_l_s 0000 00010001 10110 01001 ..... ..... @ff +ftint_l_d 0000 00010001 10110 01010 ..... ..... @ff +ffint_s_w 0000 00010001 11010 00100 ..... ..... @ff +ffint_s_l 0000 00010001 11010 00110 ..... ..... @ff +ffint_d_w 0000 00010001 11010 01000 ..... ..... @ff +ffint_d_l 0000 00010001 11010 01010 ..... ..... @ff +frint_s 0000 00010001 11100 10001 ..... ..... @ff +frint_d 0000 00010001 11100 10010 ..... ..... @ff diff --git a/target/loongarch/translate.c b/target/loongarch/translate.c index fd43e1b..8da4e12 100644 --- a/target/loongarch/translate.c +++ b/target/loongarch/translate.c @@ -192,6 +192,7 @@ static void gen_set_gpr(int reg_num, TCGv t, DisasExtend dst_ext) #include "insn_trans/trans_extra.c.inc" #include "insn_trans/trans_farith.c.inc" #include "insn_trans/trans_fcmp.c.inc" +#include "insn_trans/trans_fcnv.c.inc" static void loongarch_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs) { From patchwork Fri Nov 19 06:13:17 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: gaosong X-Patchwork-Id: 1556928 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4HwRm248gSz9sPf for ; Fri, 19 Nov 2021 17:37:06 +1100 (AEDT) Received: from localhost ([::1]:48754 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mnxWB-0002rc-C3 for incoming@patchwork.ozlabs.org; Fri, 19 Nov 2021 01:37:03 -0500 Received: from eggs.gnu.org ([209.51.188.92]:46422) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mnx9w-0004Fy-St for qemu-devel@nongnu.org; Fri, 19 Nov 2021 01:14:04 -0500 Received: from mail.loongson.cn ([114.242.206.163]:46758 helo=loongson.cn) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mnx9t-0004YN-6y for qemu-devel@nongnu.org; Fri, 19 Nov 2021 01:14:04 -0500 Received: from kvm-dev1.localdomain (unknown [10.2.5.134]) by mail.loongson.cn (Coremail) with SMTP id AQAAf9Dxj8+KQJdhSG0AAA--.1952S15; Fri, 19 Nov 2021 14:13:45 +0800 (CST) From: Song Gao To: qemu-devel@nongnu.org Subject: [PATCH v11 13/26] target/loongarch: Add floating point move instruction translation Date: Fri, 19 Nov 2021 14:13:17 +0800 Message-Id: <1637302410-24632-14-git-send-email-gaosong@loongson.cn> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1637302410-24632-1-git-send-email-gaosong@loongson.cn> References: <1637302410-24632-1-git-send-email-gaosong@loongson.cn> X-CM-TRANSID: AQAAf9Dxj8+KQJdhSG0AAA--.1952S15 X-Coremail-Antispam: 1UD129KBjvJXoWxuw1DKr1rXw4DJF43ZF4UXFb_yoWfGF13pr 4jyryUCr48XF13Z3s7tw4YgFs8ZFn7Ca4jq3sayr1rAF4xXF1DArykJ3y29rW5Xws7XryU ZFn8AFyjgFy8XaUanT9S1TB71UUUUUUqnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnUUvcSsGvfC2KfnxnUUI43ZEXa7xR_UUUUUUUUU== X-CM-SenderInfo: 5jdr20tqj6z05rqj20fqof0/ Received-SPF: pass client-ip=114.242.206.163; envelope-from=gaosong@loongson.cn; helo=loongson.cn X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Xiaojuan Yang , richard.henderson@linaro.org, laurent@vivier.eu Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" This includes: - FMOV.{S/D} - FSEL - MOVGR2FR.{W/D}, MOVGR2FRH.W - MOVFR2GR.{S/D}, MOVFRH2GR.S - MOVGR2FCSR, MOVFCSR2GR - MOVFR2CF, MOVCF2FR - MOVGR2CF, MOVCF2GR Signed-off-by: Song Gao Signed-off-by: Xiaojuan Yang Reviewed-by: Richard Henderson --- target/loongarch/fpu_helper.c | 6 ++ target/loongarch/helper.h | 2 + target/loongarch/insn_trans/trans_fmov.c.inc | 150 +++++++++++++++++++++++++++ target/loongarch/insns.decode | 37 +++++++ target/loongarch/translate.c | 1 + 5 files changed, 196 insertions(+) create mode 100644 target/loongarch/insn_trans/trans_fmov.c.inc diff --git a/target/loongarch/fpu_helper.c b/target/loongarch/fpu_helper.c index 4799b47..babaa16 100644 --- a/target/loongarch/fpu_helper.c +++ b/target/loongarch/fpu_helper.c @@ -856,3 +856,9 @@ uint64_t helper_ftint_w_d(CPULoongArchState *env, uint64_t fj) update_fcsr0(env, GETPC()); return fd; } + +void helper_set_rounding_mode(CPULoongArchState *env, uint32_t fcsr0) +{ + set_float_rounding_mode(ieee_rm[(fcsr0 >> FCSR0_RM) & 0x3], + &env->fp_status); +} diff --git a/target/loongarch/helper.h b/target/loongarch/helper.h index 51bbf25..26ca6d2 100644 --- a/target/loongarch/helper.h +++ b/target/loongarch/helper.h @@ -90,3 +90,5 @@ DEF_HELPER_2(ftint_w_s, i64, env, i64) DEF_HELPER_2(ftint_w_d, i64, env, i64) DEF_HELPER_2(frint_s, i64, env, i64) DEF_HELPER_2(frint_d, i64, env, i64) + +DEF_HELPER_FLAGS_2(set_rounding_mode, TCG_CALL_NO_RWG, void, env, i32) diff --git a/target/loongarch/insn_trans/trans_fmov.c.inc b/target/loongarch/insn_trans/trans_fmov.c.inc new file mode 100644 index 0000000..8acf49e --- /dev/null +++ b/target/loongarch/insn_trans/trans_fmov.c.inc @@ -0,0 +1,150 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (c) 2021 Loongson Technology Corporation Limited + */ + +static const uint32_t fcsr_mask[4] = { + UINT32_MAX, FCSR0_M1, FCSR0_M2, FCSR0_M3 +}; + +static bool trans_fsel(DisasContext *ctx, arg_fsel *a) +{ + TCGv zero = tcg_constant_tl(0); + TCGv cond = tcg_temp_new(); + + tcg_gen_ld8u_tl(cond, cpu_env, offsetof(CPULoongArchState, cf[a->ca])); + tcg_gen_movcond_tl(TCG_COND_EQ, cpu_fpr[a->fd], cond, zero, + cpu_fpr[a->fj], cpu_fpr[a->fk]); + tcg_temp_free(cond); + return true; +} + +static bool gen_f2f(DisasContext *ctx, arg_ff *a, + void (*func)(TCGv, TCGv), bool nanbox) +{ + TCGv dest = cpu_fpr[a->fd]; + TCGv src = cpu_fpr[a->fj]; + + func(dest, src); + if (nanbox) { + gen_nanbox_s(cpu_fpr[a->fd], cpu_fpr[a->fd]); + } + return true; +} + +static bool gen_r2f(DisasContext *ctx, arg_fr *a, + void (*func)(TCGv, TCGv)) +{ + TCGv src = gpr_src(ctx, a->rj, EXT_NONE); + + func(cpu_fpr[a->fd], src); + return true; +} + +static bool gen_f2r(DisasContext *ctx, arg_rf *a, + void (*func)(TCGv, TCGv)) +{ + TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE); + + func(dest, cpu_fpr[a->fj]); + return true; +} + +static bool trans_movgr2fcsr(DisasContext *ctx, arg_movgr2fcsr *a) +{ + uint32_t mask = fcsr_mask[a->fcsrd]; + TCGv Rj = gpr_src(ctx, a->rj, EXT_NONE); + + if (mask == UINT32_MAX) { + tcg_gen_extrl_i64_i32(cpu_fcsr0, Rj); + } else { + TCGv_i32 temp = tcg_temp_new_i32(); + + tcg_gen_extrl_i64_i32(temp, Rj); + tcg_gen_andi_i32(temp, temp, mask); + tcg_gen_andi_i32(cpu_fcsr0, cpu_fcsr0, ~mask); + tcg_gen_or_i32(cpu_fcsr0, cpu_fcsr0, temp); + tcg_temp_free_i32(temp); + + /* + * Install the new rounding mode to fpu_status, if changed. + * Note that FCSR3 is exactly the rounding mode field. + */ + if (mask != FCSR0_M3) { + return true; + } + } + gen_helper_set_rounding_mode(cpu_env, cpu_fcsr0); + return true; +} + +static bool trans_movfcsr2gr(DisasContext *ctx, arg_movfcsr2gr *a) +{ + TCGv_i32 temp = tcg_temp_new_i32(); + TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE); + + tcg_gen_andi_i32(temp, cpu_fcsr0, fcsr_mask[a->fcsrs]); + tcg_gen_ext_i32_i64(dest, temp); + tcg_temp_free_i32(temp); + return true; +} + +static void gen_movgr2fr_w(TCGv dest, TCGv src) +{ + tcg_gen_deposit_i64(dest, dest, src, 0, 32); +} + +static void gen_movgr2frh_w(TCGv dest, TCGv src) +{ + tcg_gen_deposit_i64(dest, dest, src, 32, 32); +} + +static void gen_movfrh2gr_s(TCGv dest, TCGv src) +{ + tcg_gen_sextract_tl(dest, src, 32, 32); +} + +static bool trans_movfr2cf(DisasContext *ctx, arg_movfr2cf *a) +{ + TCGv t0 = tcg_temp_new(); + + tcg_gen_andi_tl(t0, cpu_fpr[a->fj], 0x1); + tcg_gen_st8_tl(t0, cpu_env, offsetof(CPULoongArchState, cf[a->cd & 0x7])); + + tcg_temp_free(t0); + return true; +} + +static bool trans_movcf2fr(DisasContext *ctx, arg_movcf2fr *a) +{ + tcg_gen_ld8u_tl(cpu_fpr[a->fd], cpu_env, + offsetof(CPULoongArchState, cf[a->cj & 0x7])); + return true; +} + +static bool trans_movgr2cf(DisasContext *ctx, arg_movgr2cf *a) +{ + TCGv t0 = tcg_temp_new(); + + tcg_gen_andi_tl(t0, gpr_src(ctx, a->rj, EXT_NONE), 0x1); + tcg_gen_st8_tl(t0, cpu_env, offsetof(CPULoongArchState, cf[a->cd & 0x7])); + + tcg_temp_free(t0); + return true; +} + +static bool trans_movcf2gr(DisasContext *ctx, arg_movcf2gr *a) +{ + tcg_gen_ld8u_tl(gpr_dst(ctx, a->rd, EXT_NONE), cpu_env, + offsetof(CPULoongArchState, cf[a->cj & 0x7])); + return true; +} + +TRANS(fmov_s, gen_f2f, tcg_gen_mov_tl, true) +TRANS(fmov_d, gen_f2f, tcg_gen_mov_tl, false) +TRANS(movgr2fr_w, gen_r2f, gen_movgr2fr_w) +TRANS(movgr2fr_d, gen_r2f, tcg_gen_mov_tl) +TRANS(movgr2frh_w, gen_r2f, gen_movgr2frh_w) +TRANS(movfr2gr_s, gen_f2r, tcg_gen_ext32s_tl) +TRANS(movfr2gr_d, gen_f2r, tcg_gen_mov_tl) +TRANS(movfrh2gr_s, gen_f2r, gen_movfrh2gr_s) diff --git a/target/loongarch/insns.decode b/target/loongarch/insns.decode index a7e0a7e..86f7284 100644 --- a/target/loongarch/insns.decode +++ b/target/loongarch/insns.decode @@ -27,6 +27,15 @@ &fff fd fj fk &ffff fd fj fk fa &cff_fcond cd fj fk fcond +&fffc fd fj fk ca +&fr fd rj +&rf rd fj +&fcsrd_r fcsrd rj +&r_fcsrs rd fcsrs +&cf cd fj +&fc fd cj +&cr cd rj +&rc rd cj # # Formats @@ -52,6 +61,15 @@ @fff .... ........ ..... fk:5 fj:5 fd:5 &fff @ffff .... ........ fa:5 fk:5 fj:5 fd:5 &ffff @cff_fcond .... ........ fcond:5 fk:5 fj:5 .. cd:3 &cff_fcond +@fffc .... ........ .. ca:3 fk:5 fj:5 fd:5 &fffc +@fr .... ........ ..... ..... rj:5 fd:5 &fr +@rf .... ........ ..... ..... fj:5 rd:5 &rf +@fcsrd_r .... ........ ..... ..... rj:5 fcsrd:5 &fcsrd_r +@r_fcsrs .... ........ ..... ..... fcsrs:5 rd:5 &r_fcsrs +@cf .... ........ ..... ..... fj:5 .. cd:3 &cf +@fc .... ........ ..... ..... .. cj:3 fd:5 &fc +@cr .... ........ ..... ..... rj:5 .. cd:3 &cr +@rc .... ........ ..... ..... .. cj:3 rd:5 &rc # # Fixed point arithmetic operation instruction @@ -351,3 +369,22 @@ ffint_d_w 0000 00010001 11010 01000 ..... ..... @ff ffint_d_l 0000 00010001 11010 01010 ..... ..... @ff frint_s 0000 00010001 11100 10001 ..... ..... @ff frint_d 0000 00010001 11100 10010 ..... ..... @ff + +# +# Floating point move instruction +# +fmov_s 0000 00010001 01001 00101 ..... ..... @ff +fmov_d 0000 00010001 01001 00110 ..... ..... @ff +fsel 0000 11010000 00 ... ..... ..... ..... @fffc +movgr2fr_w 0000 00010001 01001 01001 ..... ..... @fr +movgr2fr_d 0000 00010001 01001 01010 ..... ..... @fr +movgr2frh_w 0000 00010001 01001 01011 ..... ..... @fr +movfr2gr_s 0000 00010001 01001 01101 ..... ..... @rf +movfr2gr_d 0000 00010001 01001 01110 ..... ..... @rf +movfrh2gr_s 0000 00010001 01001 01111 ..... ..... @rf +movgr2fcsr 0000 00010001 01001 10000 ..... ..... @fcsrd_r +movfcsr2gr 0000 00010001 01001 10010 ..... ..... @r_fcsrs +movfr2cf 0000 00010001 01001 10100 ..... 00 ... @cf +movcf2fr 0000 00010001 01001 10101 00 ... ..... @fc +movgr2cf 0000 00010001 01001 10110 ..... 00 ... @cr +movcf2gr 0000 00010001 01001 10111 00 ... ..... @rc diff --git a/target/loongarch/translate.c b/target/loongarch/translate.c index 8da4e12..f3e590c 100644 --- a/target/loongarch/translate.c +++ b/target/loongarch/translate.c @@ -193,6 +193,7 @@ static void gen_set_gpr(int reg_num, TCGv t, DisasExtend dst_ext) #include "insn_trans/trans_farith.c.inc" #include "insn_trans/trans_fcmp.c.inc" #include "insn_trans/trans_fcnv.c.inc" +#include "insn_trans/trans_fmov.c.inc" static void loongarch_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs) { From patchwork Fri Nov 19 06:13:18 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: gaosong X-Patchwork-Id: 1556930 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4HwRyJ2F0qz9sPf for ; Fri, 19 Nov 2021 17:45:58 +1100 (AEDT) Received: from localhost ([::1]:55244 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mnxek-0007Zu-Fv for incoming@patchwork.ozlabs.org; Fri, 19 Nov 2021 01:45:54 -0500 Received: from eggs.gnu.org ([209.51.188.92]:46430) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mnx9x-0004Gn-EM for qemu-devel@nongnu.org; Fri, 19 Nov 2021 01:14:07 -0500 Received: from mail.loongson.cn ([114.242.206.163]:46820 helo=loongson.cn) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mnx9u-0004ZA-PI for qemu-devel@nongnu.org; Fri, 19 Nov 2021 01:14:05 -0500 Received: from kvm-dev1.localdomain (unknown [10.2.5.134]) by mail.loongson.cn (Coremail) with SMTP id AQAAf9Dxj8+KQJdhSG0AAA--.1952S16; Fri, 19 Nov 2021 14:13:48 +0800 (CST) From: Song Gao To: qemu-devel@nongnu.org Subject: [PATCH v11 14/26] target/loongarch: Add floating point load/store instruction translation Date: Fri, 19 Nov 2021 14:13:18 +0800 Message-Id: <1637302410-24632-15-git-send-email-gaosong@loongson.cn> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1637302410-24632-1-git-send-email-gaosong@loongson.cn> References: <1637302410-24632-1-git-send-email-gaosong@loongson.cn> X-CM-TRANSID: AQAAf9Dxj8+KQJdhSG0AAA--.1952S16 X-Coremail-Antispam: 1UD129KBjvJXoW3Jw4xur17Aw1kXF18uFW3ZFb_yoW3AF4rpr 4jyr1UGr48XF1fAr97Kw45WF1DZFnxCayjga4Svr1Iyr18XFyDJr4kJ39FkrWUXF4kXFW5 tF4DAFyUtFyrX3JanT9S1TB71UUUUUUqnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnUUvcSsGvfC2KfnxnUUI43ZEXa7xR_UUUUUUUUU== X-CM-SenderInfo: 5jdr20tqj6z05rqj20fqof0/ Received-SPF: pass client-ip=114.242.206.163; envelope-from=gaosong@loongson.cn; helo=loongson.cn X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Xiaojuan Yang , richard.henderson@linaro.org, laurent@vivier.eu Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" This includes: - FLD.{S/D}, FST.{S/D} - FLDX.{S/D}, FSTX.{S/D} - FLD{GT/LE}.{S/D}, FST{GT/LE}.{S/D} Signed-off-by: Song Gao Signed-off-by: Xiaojuan Yang Reviewed-by: Richard Henderson --- target/loongarch/insn_trans/trans_fmemory.c.inc | 184 ++++++++++++++++++++++++ target/loongarch/insns.decode | 24 ++++ target/loongarch/translate.c | 1 + 3 files changed, 209 insertions(+) create mode 100644 target/loongarch/insn_trans/trans_fmemory.c.inc diff --git a/target/loongarch/insn_trans/trans_fmemory.c.inc b/target/loongarch/insn_trans/trans_fmemory.c.inc new file mode 100644 index 0000000..a9c66b2 --- /dev/null +++ b/target/loongarch/insn_trans/trans_fmemory.c.inc @@ -0,0 +1,184 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (c) 2021 Loongson Technology Corporation Limited + */ + +static bool gen_fload_imm(DisasContext *ctx, arg_fr_i *a, + MemOp mop, bool nanbox) +{ + TCGv addr = gpr_src(ctx, a->rj, EXT_NONE); + TCGv temp = NULL; + + if (a->imm) { + temp = tcg_temp_new(); + tcg_gen_addi_tl(temp, addr, a->imm); + addr = temp; + } + + tcg_gen_qemu_ld_tl(cpu_fpr[a->fd], addr, ctx->mem_idx, mop); + + if (nanbox) { + gen_nanbox_s(cpu_fpr[a->fd], cpu_fpr[a->fd]); + } + + if (temp) { + tcg_temp_free(temp); + } + return true; +} + +static bool gen_fstore_imm(DisasContext *ctx, arg_fr_i *a, + MemOp mop, bool nanbox) +{ + TCGv addr = gpr_src(ctx, a->rj, EXT_NONE); + TCGv temp = NULL; + + if (a->imm) { + temp = tcg_temp_new(); + tcg_gen_addi_tl(temp, addr, a->imm); + addr = temp; + } + + if (nanbox) { + gen_nanbox_s(cpu_fpr[a->fd], cpu_fpr[a->fd]); + } + + tcg_gen_qemu_st_tl(cpu_fpr[a->fd], addr, ctx->mem_idx, mop); + + if (temp) { + tcg_temp_free(temp); + } + return true; +} + +static bool gen_fload_tl(DisasContext *ctx, arg_frr *a, + MemOp mop, bool nanbox) +{ + TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE); + TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE); + TCGv addr = tcg_temp_new(); + + tcg_gen_add_tl(addr, src1, src2); + tcg_gen_qemu_ld_tl(cpu_fpr[a->fd], addr, ctx->mem_idx, mop); + + if (nanbox) { + gen_nanbox_s(cpu_fpr[a->fd], cpu_fpr[a->fd]); + } + + tcg_temp_free(addr); + return true; +} + +static bool gen_fstore_tl(DisasContext *ctx, arg_frr *a, + MemOp mop, bool nanbox) +{ + TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE); + TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE); + TCGv addr = tcg_temp_new(); + + tcg_gen_add_tl(addr, src1, src2); + + if (nanbox) { + gen_nanbox_s(cpu_fpr[a->fd], cpu_fpr[a->fd]); + } + + tcg_gen_qemu_st_tl(cpu_fpr[a->fd], addr, ctx->mem_idx, mop); + + tcg_temp_free(addr); + return true; +} + +static bool gen_fload_gt(DisasContext *ctx, arg_frr *a, + MemOp mop, bool nanbox) +{ + TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE); + TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE); + TCGv addr = tcg_temp_new(); + + gen_helper_asrtgt_d(cpu_env, src1, src2); + tcg_gen_add_tl(addr, src1, src2); + tcg_gen_qemu_ld_tl(cpu_fpr[a->fd], addr, ctx->mem_idx, mop); + + if (nanbox) { + gen_nanbox_s(cpu_fpr[a->fd], cpu_fpr[a->fd]); + } + + tcg_temp_free(addr); + return true; +} + +static bool gen_fstore_gt(DisasContext *ctx, arg_frr *a, + MemOp mop, bool nanbox) +{ + TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE); + TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE); + TCGv addr = tcg_temp_new(); + + gen_helper_asrtgt_d(cpu_env, src1, src2); + tcg_gen_add_tl(addr, src1, src2); + + if (nanbox) { + gen_nanbox_s(cpu_fpr[a->fd], cpu_fpr[a->fd]); + } + + tcg_gen_qemu_st_tl(cpu_fpr[a->fd], addr, ctx->mem_idx, mop); + + tcg_temp_free(addr); + return true; +} + +static bool gen_fload_le(DisasContext *ctx, arg_frr *a, + MemOp mop, bool nanbox) +{ + TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE); + TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE); + TCGv addr = tcg_temp_new(); + + gen_helper_asrtle_d(cpu_env, src1, src2); + tcg_gen_add_tl(addr, src1, src2); + tcg_gen_qemu_ld_tl(cpu_fpr[a->fd], addr, ctx->mem_idx, mop); + + if (nanbox) { + gen_nanbox_s(cpu_fpr[a->fd], cpu_fpr[a->fd]); + } + + tcg_temp_free(addr); + return true; +} + +static bool gen_fstore_le(DisasContext *ctx, arg_frr *a, + MemOp mop, bool nanbox) +{ + TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE); + TCGv src2 = gpr_src(ctx, a->rk, EXT_NONE); + TCGv addr = tcg_temp_new(); + + gen_helper_asrtle_d(cpu_env, src1, src2); + tcg_gen_add_tl(addr, src1, src2); + + if (nanbox) { + gen_nanbox_s(cpu_fpr[a->fd], cpu_fpr[a->fd]); + } + + tcg_gen_qemu_st_tl(cpu_fpr[a->fd], addr, ctx->mem_idx, mop); + + tcg_temp_free(addr); + return true; +} + +TRANS(fld_s, gen_fload_imm, MO_TESL, true) +TRANS(fst_s, gen_fstore_imm, MO_TEUL, true) +TRANS(fld_d, gen_fload_imm, MO_TEQ, false) +TRANS(fst_d, gen_fstore_imm, MO_TEQ, false) +TRANS(fldx_s, gen_fload_tl, MO_TESL, true) +TRANS(fldx_d, gen_fload_tl, MO_TEQ, false) +TRANS(fstx_s, gen_fstore_tl, MO_TEUL, true) +TRANS(fstx_d, gen_fstore_tl, MO_TEQ, false) +TRANS(fldgt_s, gen_fload_gt, MO_TESL, true) +TRANS(fldgt_d, gen_fload_gt, MO_TEQ, false) +TRANS(fldle_s, gen_fload_le, MO_TESL, true) +TRANS(fldle_d, gen_fload_le, MO_TEQ, false) +TRANS(fstgt_s, gen_fstore_gt, MO_TEUL, true) +TRANS(fstgt_d, gen_fstore_gt, MO_TEQ, false) +TRANS(fstle_s, gen_fstore_le, MO_TEUL, true) +TRANS(fstle_d, gen_fstore_le, MO_TEQ, false) diff --git a/target/loongarch/insns.decode b/target/loongarch/insns.decode index 86f7284..2560c24 100644 --- a/target/loongarch/insns.decode +++ b/target/loongarch/insns.decode @@ -36,6 +36,8 @@ &fc fd cj &cr cd rj &rc rd cj +&frr fd rj rk +&fr_i fd rj imm # # Formats @@ -70,6 +72,8 @@ @fc .... ........ ..... ..... .. cj:3 fd:5 &fc @cr .... ........ ..... ..... rj:5 .. cd:3 &cr @rc .... ........ ..... ..... .. cj:3 rd:5 &rc +@frr .... ........ ..... rk:5 rj:5 fd:5 &frr +@fr_i12 .... ...... imm:s12 rj:5 fd:5 &fr_i # # Fixed point arithmetic operation instruction @@ -388,3 +392,23 @@ movfr2cf 0000 00010001 01001 10100 ..... 00 ... @cf movcf2fr 0000 00010001 01001 10101 00 ... ..... @fc movgr2cf 0000 00010001 01001 10110 ..... 00 ... @cr movcf2gr 0000 00010001 01001 10111 00 ... ..... @rc + +# +# Floating point load/store instruction +# +fld_s 0010 101100 ............ ..... ..... @fr_i12 +fst_s 0010 101101 ............ ..... ..... @fr_i12 +fld_d 0010 101110 ............ ..... ..... @fr_i12 +fst_d 0010 101111 ............ ..... ..... @fr_i12 +fldx_s 0011 10000011 00000 ..... ..... ..... @frr +fldx_d 0011 10000011 01000 ..... ..... ..... @frr +fstx_s 0011 10000011 10000 ..... ..... ..... @frr +fstx_d 0011 10000011 11000 ..... ..... ..... @frr +fldgt_s 0011 10000111 01000 ..... ..... ..... @frr +fldgt_d 0011 10000111 01001 ..... ..... ..... @frr +fldle_s 0011 10000111 01010 ..... ..... ..... @frr +fldle_d 0011 10000111 01011 ..... ..... ..... @frr +fstgt_s 0011 10000111 01100 ..... ..... ..... @frr +fstgt_d 0011 10000111 01101 ..... ..... ..... @frr +fstle_s 0011 10000111 01110 ..... ..... ..... @frr +fstle_d 0011 10000111 01111 ..... ..... ..... @frr diff --git a/target/loongarch/translate.c b/target/loongarch/translate.c index f3e590c..5be5e26 100644 --- a/target/loongarch/translate.c +++ b/target/loongarch/translate.c @@ -194,6 +194,7 @@ static void gen_set_gpr(int reg_num, TCGv t, DisasExtend dst_ext) #include "insn_trans/trans_fcmp.c.inc" #include "insn_trans/trans_fcnv.c.inc" #include "insn_trans/trans_fmov.c.inc" +#include "insn_trans/trans_fmemory.c.inc" static void loongarch_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs) { From patchwork Fri Nov 19 06:13:19 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: gaosong X-Patchwork-Id: 1556927 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4HwRld2hZHz9sPf for ; Fri, 19 Nov 2021 17:36:45 +1100 (AEDT) Received: from localhost ([::1]:48018 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mnxVq-0002Hb-OA for incoming@patchwork.ozlabs.org; Fri, 19 Nov 2021 01:36:42 -0500 Received: from eggs.gnu.org ([209.51.188.92]:46448) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mnx9z-0004HF-B3 for qemu-devel@nongnu.org; Fri, 19 Nov 2021 01:14:07 -0500 Received: from mail.loongson.cn ([114.242.206.163]:46850 helo=loongson.cn) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mnx9x-0004Zn-0e for qemu-devel@nongnu.org; Fri, 19 Nov 2021 01:14:06 -0500 Received: from kvm-dev1.localdomain (unknown [10.2.5.134]) by mail.loongson.cn (Coremail) with SMTP id AQAAf9Dxj8+KQJdhSG0AAA--.1952S17; Fri, 19 Nov 2021 14:13:50 +0800 (CST) From: Song Gao To: qemu-devel@nongnu.org Subject: [PATCH v11 15/26] target/loongarch: Add branch instruction translation Date: Fri, 19 Nov 2021 14:13:19 +0800 Message-Id: <1637302410-24632-16-git-send-email-gaosong@loongson.cn> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1637302410-24632-1-git-send-email-gaosong@loongson.cn> References: <1637302410-24632-1-git-send-email-gaosong@loongson.cn> X-CM-TRANSID: AQAAf9Dxj8+KQJdhSG0AAA--.1952S17 X-Coremail-Antispam: 1UD129KBjvJXoW3Xr4DJF1xtF1furWxCryrtFb_yoWxGryrpr 1UCr1UKrW8JryfAr9Yqw45JF13ZrsxG3y7Gws3twn5Jr42qF1DJr48trWUKr4UXrWkXr40 vF4rAryUWFy0qwUanT9S1TB71UUUUUUqnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnUUvcSsGvfC2KfnxnUUI43ZEXa7xR_UUUUUUUUU== X-CM-SenderInfo: 5jdr20tqj6z05rqj20fqof0/ Received-SPF: pass client-ip=114.242.206.163; envelope-from=gaosong@loongson.cn; helo=loongson.cn X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Xiaojuan Yang , richard.henderson@linaro.org, laurent@vivier.eu Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" This includes: - BEQ, BNE, BLT[U], BGE[U] - BEQZ, BNEZ - B - BL - JIRL - BCEQZ, BCNEZ Signed-off-by: Song Gao Signed-off-by: Xiaojuan Yang Reviewed-by: Richard Henderson --- target/loongarch/insn_trans/trans_branch.c.inc | 82 ++++++++++++++++++++++++++ target/loongarch/insns.decode | 30 ++++++++++ target/loongarch/translate.c | 6 ++ 3 files changed, 118 insertions(+) create mode 100644 target/loongarch/insn_trans/trans_branch.c.inc diff --git a/target/loongarch/insn_trans/trans_branch.c.inc b/target/loongarch/insn_trans/trans_branch.c.inc new file mode 100644 index 0000000..73fd048 --- /dev/null +++ b/target/loongarch/insn_trans/trans_branch.c.inc @@ -0,0 +1,82 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (c) 2021 Loongson Technology Corporation Limited + */ + +static bool trans_b(DisasContext *ctx, arg_b *a) +{ + gen_goto_tb(ctx, 0, ctx->base.pc_next + a->offs); + ctx->base.is_jmp = DISAS_NORETURN; + return true; +} + +static bool trans_bl(DisasContext *ctx, arg_bl *a) +{ + tcg_gen_movi_tl(cpu_gpr[1], ctx->base.pc_next + 4); + gen_goto_tb(ctx, 0, ctx->base.pc_next + a->offs); + ctx->base.is_jmp = DISAS_NORETURN; + return true; +} + +static bool trans_jirl(DisasContext *ctx, arg_jirl *a) +{ + TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE); + TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE); + + tcg_gen_addi_tl(cpu_pc, src1, a->offs); + tcg_gen_movi_tl(dest, ctx->base.pc_next + 4); + tcg_gen_lookup_and_goto_ptr(); + ctx->base.is_jmp = DISAS_NORETURN; + return true; +} + +static void gen_bc(DisasContext *ctx, TCGv src1, TCGv src2, + target_long offs, TCGCond cond) +{ + TCGLabel *l = gen_new_label(); + tcg_gen_brcond_tl(cond, src1, src2, l); + gen_goto_tb(ctx, 1, ctx->base.pc_next + 4); + gen_set_label(l); + gen_goto_tb(ctx, 0, ctx->base.pc_next + offs); + ctx->base.is_jmp = DISAS_NORETURN; +} + +static bool gen_rr_bc(DisasContext *ctx, arg_rr_offs *a, TCGCond cond) +{ + TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE); + TCGv src2 = gpr_src(ctx, a->rd, EXT_NONE); + + gen_bc(ctx, src1, src2, a->offs, cond); + return true; +} + +static bool gen_rz_bc(DisasContext *ctx, arg_r_offs *a, TCGCond cond) +{ + TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE); + TCGv src2 = tcg_constant_tl(0); + + gen_bc(ctx, src1, src2, a->offs, cond); + return true; +} + +static bool gen_cz_bc(DisasContext *ctx, arg_c_offs *a, TCGCond cond) +{ + TCGv src1 = tcg_temp_new(); + TCGv src2 = tcg_constant_tl(0); + + tcg_gen_ld8u_tl(src1, cpu_env, + offsetof(CPULoongArchState, cf[a->cj & 0x7])); + gen_bc(ctx, src1, src2, a->offs, cond); + return true; +} + +TRANS(beq, gen_rr_bc, TCG_COND_EQ) +TRANS(bne, gen_rr_bc, TCG_COND_NE) +TRANS(blt, gen_rr_bc, TCG_COND_LT) +TRANS(bge, gen_rr_bc, TCG_COND_GE) +TRANS(bltu, gen_rr_bc, TCG_COND_LTU) +TRANS(bgeu, gen_rr_bc, TCG_COND_GEU) +TRANS(beqz, gen_rz_bc, TCG_COND_EQ) +TRANS(bnez, gen_rz_bc, TCG_COND_NE) +TRANS(bceqz, gen_cz_bc, TCG_COND_EQ) +TRANS(bcnez, gen_cz_bc, TCG_COND_NE) diff --git a/target/loongarch/insns.decode b/target/loongarch/insns.decode index 2560c24..5118a1e 100644 --- a/target/loongarch/insns.decode +++ b/target/loongarch/insns.decode @@ -9,6 +9,9 @@ # Fields # %sa2p1 15:2 !function=plus_1 +%offs21 0:s5 10:16 !function=times_4 +%offs16 10:s16 !function=times_4 +%offs26 0:s10 10:16 !function=times_4 # # Argument sets @@ -38,6 +41,11 @@ &rc rd cj &frr fd rj rk &fr_i fd rj imm +&r_offs rj offs +&c_offs cj offs +&rr_dj_offs rd rj offs +&offs offs +&rr_offs rj rd offs # # Formats @@ -74,6 +82,11 @@ @rc .... ........ ..... ..... .. cj:3 rd:5 &rc @frr .... ........ ..... rk:5 rj:5 fd:5 &frr @fr_i12 .... ...... imm:s12 rj:5 fd:5 &fr_i +@r_offs21 .... .. ................ rj:5 ..... &r_offs offs=%offs21 +@c_offs21 .... .. ................ .. cj:3 ..... &c_offs offs=%offs21 +@rr_dj_offs16 .... .. ................ rj:5 rd:5 &rr_dj_offs offs=%offs16 +@offs26 .... .. .......................... &offs offs=%offs26 +@rr_offs16 .... .. ................ rj:5 rd:5 &rr_offs offs=%offs16 # # Fixed point arithmetic operation instruction @@ -412,3 +425,20 @@ fstgt_s 0011 10000111 01100 ..... ..... ..... @frr fstgt_d 0011 10000111 01101 ..... ..... ..... @frr fstle_s 0011 10000111 01110 ..... ..... ..... @frr fstle_d 0011 10000111 01111 ..... ..... ..... @frr + +# +# Branch instructions +# +beqz 0100 00 ................ ..... ..... @r_offs21 +bnez 0100 01 ................ ..... ..... @r_offs21 +bceqz 0100 10 ................ 00 ... ..... @c_offs21 +bcnez 0100 10 ................ 01 ... ..... @c_offs21 +jirl 0100 11 ................ ..... ..... @rr_dj_offs16 +b 0101 00 .......................... @offs26 +bl 0101 01 .......................... @offs26 +beq 0101 10 ................ ..... ..... @rr_offs16 +bne 0101 11 ................ ..... ..... @rr_offs16 +blt 0110 00 ................ ..... ..... @rr_offs16 +bge 0110 01 ................ ..... ..... @rr_offs16 +bltu 0110 10 ................ ..... ..... @rr_offs16 +bgeu 0110 11 ................ ..... ..... @rr_offs16 diff --git a/target/loongarch/translate.c b/target/loongarch/translate.c index 5be5e26..9a491d2 100644 --- a/target/loongarch/translate.c +++ b/target/loongarch/translate.c @@ -32,6 +32,11 @@ static inline int plus_1(DisasContext *ctx, int x) return x + 1; } +static inline int times_4(DisasContext *ctx, int x) +{ + return x * 4; +} + /* * LoongArch the upper 32 bits are undefined ("can be any value"). * QEMU chooses to nanbox, because it is most likely to show guest bugs early. @@ -195,6 +200,7 @@ static void gen_set_gpr(int reg_num, TCGv t, DisasExtend dst_ext) #include "insn_trans/trans_fcnv.c.inc" #include "insn_trans/trans_fmov.c.inc" #include "insn_trans/trans_fmemory.c.inc" +#include "insn_trans/trans_branch.c.inc" static void loongarch_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs) { From patchwork Fri Nov 19 06:13:20 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: gaosong X-Patchwork-Id: 1556933 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4HwS6144wcz9sPf for ; Fri, 19 Nov 2021 17:52:40 +1100 (AEDT) Received: from localhost ([::1]:34220 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mnxlD-0004NQ-Rc for incoming@patchwork.ozlabs.org; Fri, 19 Nov 2021 01:52:35 -0500 Received: from eggs.gnu.org ([209.51.188.92]:46568) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mnxA3-0004KN-FL for qemu-devel@nongnu.org; Fri, 19 Nov 2021 01:14:11 -0500 Received: from mail.loongson.cn ([114.242.206.163]:46868 helo=loongson.cn) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mnx9y-0004a0-Rl for qemu-devel@nongnu.org; Fri, 19 Nov 2021 01:14:10 -0500 Received: from kvm-dev1.localdomain (unknown [10.2.5.134]) by mail.loongson.cn (Coremail) with SMTP id AQAAf9Dxj8+KQJdhSG0AAA--.1952S18; Fri, 19 Nov 2021 14:13:53 +0800 (CST) From: Song Gao To: qemu-devel@nongnu.org Subject: [PATCH v11 16/26] target/loongarch: Add disassembler Date: Fri, 19 Nov 2021 14:13:20 +0800 Message-Id: <1637302410-24632-17-git-send-email-gaosong@loongson.cn> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1637302410-24632-1-git-send-email-gaosong@loongson.cn> References: <1637302410-24632-1-git-send-email-gaosong@loongson.cn> X-CM-TRANSID: AQAAf9Dxj8+KQJdhSG0AAA--.1952S18 X-Coremail-Antispam: 1UD129KBjvAXoW3urW5urWDJryrWF4rAryUtrb_yoW8WF1fKo Wrtw4UXa1UGrnF9390v3yqqFWjq3Wktw42qwsYv3Z5G3Wayrn8Kr93Z3W5J3WUtr4UGw1x A3Wvqr4kGrnrCFn8n29KB7ZKAUJUUUUU529EdanIXcx71UUUUU7v73VFW2AGmfu7bjvjm3 AaLaJ3UjIYCTnIWjDUYxBIdaVFxhVjvjDU0xZFpf9x0zRUUUUUUUUU= X-CM-SenderInfo: 5jdr20tqj6z05rqj20fqof0/ Received-SPF: pass client-ip=114.242.206.163; envelope-from=gaosong@loongson.cn; helo=loongson.cn X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Xiaojuan Yang , richard.henderson@linaro.org, laurent@vivier.eu Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" This patch adds support for disassembling via option '-d in_asm'. Signed-off-by: Song Gao Signed-off-by: Xiaojuan Yang --- include/disas/dis-asm.h | 2 + meson.build | 1 + target/loongarch/disas.c | 625 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 628 insertions(+) create mode 100644 target/loongarch/disas.c diff --git a/include/disas/dis-asm.h b/include/disas/dis-asm.h index 08e1bee..aeab30f 100644 --- a/include/disas/dis-asm.h +++ b/include/disas/dis-asm.h @@ -253,6 +253,7 @@ enum bfd_architecture #define bfd_mach_rx 0x75 #define bfd_mach_rx_v2 0x76 #define bfd_mach_rx_v3 0x77 + bfd_arch_loongarch, bfd_arch_last }; #define bfd_mach_s390_31 31 @@ -461,6 +462,7 @@ int print_insn_riscv32 (bfd_vma, disassemble_info*); int print_insn_riscv64 (bfd_vma, disassemble_info*); int print_insn_rx(bfd_vma, disassemble_info *); int print_insn_hexagon(bfd_vma, disassemble_info *); +int print_insn_loongarch(bfd_vma, disassemble_info *); #ifdef CONFIG_CAPSTONE bool cap_disas_target(disassemble_info *info, uint64_t pc, size_t size); diff --git a/meson.build b/meson.build index e2d38a4..d03fec6 100644 --- a/meson.build +++ b/meson.build @@ -1807,6 +1807,7 @@ disassemblers = { 'sh4' : ['CONFIG_SH4_DIS'], 'sparc' : ['CONFIG_SPARC_DIS'], 'xtensa' : ['CONFIG_XTENSA_DIS'], + 'loongarch' : ['CONFIG_LOONGARCH_DIS'], } if link_language == 'cpp' disassemblers += { diff --git a/target/loongarch/disas.c b/target/loongarch/disas.c new file mode 100644 index 0000000..4748d0d --- /dev/null +++ b/target/loongarch/disas.c @@ -0,0 +1,625 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * QEMU LoongArch Disassembler + * + * Copyright (c) 2021 Loongson Technology Corporation Limited. + */ + +#include "qemu/osdep.h" +#include "disas/dis-asm.h" +#include "qemu/bitops.h" + +typedef struct { + disassemble_info *info; + uint64_t pc; + uint32_t insn; +} DisasContext; + +static inline int plus_1(DisasContext *ctx, int x) +{ + return x + 1; +} + +static inline int times_4(DisasContext *ctx, int x) +{ + return x * 4; +} + +#define output(C, INSN, FMT, ...) \ +{ \ + (C)->info->fprintf_func((C)->info->stream, "%08x %-9s\t" FMT, \ + (C)->insn, INSN, ##__VA_ARGS__); \ +} + +#include "decode-insns.c.inc" + +int print_insn_loongarch(bfd_vma memaddr, struct disassemble_info *info) +{ + bfd_byte buffer[4]; + uint32_t insn; + int status; + + status = (*info->read_memory_func)(memaddr, buffer, 4, info); + if (status != 0) { + (*info->memory_error_func)(status, memaddr, info); + return -1; + } + insn = bfd_getl32(buffer); + DisasContext ctx = { + .info = info, + .pc = memaddr, + .insn = insn + }; + + if (!decode(&ctx, insn)) { + output(&ctx, "illegal", ""); + } + return 4; +} + +static void output_r_i(DisasContext *ctx, arg_r_i *a, const char *mnemonic) +{ + output(ctx, mnemonic, "r%d, %d", a->rd, a->imm); +} + +static void output_rrr(DisasContext *ctx, arg_rrr *a, const char *mnemonic) +{ + output(ctx, mnemonic, "r%d, r%d, r%d", a->rd, a->rj, a->rk); +} + +static void output_rr_i(DisasContext *ctx, arg_rr_i *a, const char *mnemonic) +{ + output(ctx, mnemonic, "r%d, r%d, %d", a->rd, a->rj, a->imm); +} + +static void output_rrr_sa(DisasContext *ctx, arg_rrr_sa *a, + const char *mnemonic) +{ + output(ctx, mnemonic, "r%d, r%d, r%d, %d", a->rd, a->rj, a->rk, a->sa); +} + +static void output_rr(DisasContext *ctx, arg_rr *a, const char *mnemonic) +{ + output(ctx, mnemonic, "r%d, r%d", a->rd, a->rj); +} + +static void output_rr_2bw(DisasContext *ctx, arg_rr_2bw *a, + const char *mnemonic) +{ + output(ctx, mnemonic, "r%d, r%d, %d, %d", a->rd, a->rj, a->msbw, a->lsbw); +} + +static void output_rr_2bd(DisasContext *ctx, arg_rr_2bd *a, + const char *mnemonic) +{ + output(ctx, mnemonic, "r%d, r%d, %d, %d", a->rd, a->rj, a->msbd, a->lsbd); +} + +static void output_hint_r_i(DisasContext *ctx, arg_hint_r_i *a, + const char *mnemonic) +{ + output(ctx, mnemonic, "%d, r%d, %d", a->hint, a->rj, a->imm); +} + +static void output_i(DisasContext *ctx, arg_i *a, const char *mnemonic) +{ + output(ctx, mnemonic, "%d", a->imm); +} + +static void output_rr_jk(DisasContext *ctx, arg_rr_jk *a, + const char *mnemonic) +{ + output(ctx, mnemonic, "r%d, r%d", a->rj, a->rk); +} + +static void output_ff(DisasContext *ctx, arg_ff *a, const char *mnemonic) +{ + output(ctx, mnemonic, "f%d, f%d", a->fd, a->fj); +} + +static void output_fff(DisasContext *ctx, arg_fff *a, const char *mnemonic) +{ + output(ctx, mnemonic, "f%d, f%d, f%d", a->fd, a->fj, a->fk); +} + +static void output_ffff(DisasContext *ctx, arg_ffff *a, const char *mnemonic) +{ + output(ctx, mnemonic, "f%d, f%d, f%d, f%d", a->fd, a->fj, a->fk, a->fa); +} + +static void output_fffc(DisasContext *ctx, arg_fffc *a, const char *mnemonic) +{ + output(ctx, mnemonic, "f%d, f%d, f%d, %d", a->fd, a->fj, a->fk, a->ca); +} + +static void output_fr(DisasContext *ctx, arg_fr *a, const char *mnemonic) +{ + output(ctx, mnemonic, "f%d, r%d", a->fd, a->rj); +} + +static void output_rf(DisasContext *ctx, arg_rf *a, const char *mnemonic) +{ + output(ctx, mnemonic, "r%d, f%d", a->rd, a->fj); +} + +static void output_fcsrd_r(DisasContext *ctx, arg_fcsrd_r *a, + const char *mnemonic) +{ + output(ctx, mnemonic, "fcsr%d, r%d", a->fcsrd, a->rj); +} + +static void output_r_fcsrs(DisasContext *ctx, arg_r_fcsrs *a, + const char *mnemonic) +{ + output(ctx, mnemonic, "r%d, fcsr%d", a->rd, a->fcsrs); +} + +static void output_cf(DisasContext *ctx, arg_cf *a, const char *mnemonic) +{ + output(ctx, mnemonic, "fcc%d, f%d", a->cd, a->fj); +} + +static void output_fc(DisasContext *ctx, arg_fc *a, const char *mnemonic) +{ + output(ctx, mnemonic, "f%d, fcc%d", a->fd, a->cj); +} + +static void output_cr(DisasContext *ctx, arg_cr *a, const char *mnemonic) +{ + output(ctx, mnemonic, "fcc%d, r%d", a->cd, a->rj); +} + +static void output_rc(DisasContext *ctx, arg_rc *a, const char *mnemonic) +{ + output(ctx, mnemonic, "r%d, fcc%d", a->rd, a->cj); +} + +static void output_frr(DisasContext *ctx, arg_frr *a, const char *mnemonic) +{ + output(ctx, mnemonic, "f%d, r%d, r%d", a->fd, a->rj, a->rk); +} + +static void output_fr_i(DisasContext *ctx, arg_fr_i *a, const char *mnemonic) +{ + output(ctx, mnemonic, "f%d, r%d, %d", a->fd, a->rj, a->imm); +} + +static void output_r_offs(DisasContext *ctx, arg_r_offs *a, + const char *mnemonic) +{ + output(ctx, mnemonic, "r%d, %d # 0x%lx", a->rj, a->offs, + ctx->pc + a->offs); +} + +static void output_c_offs(DisasContext *ctx, arg_c_offs *a, + const char *mnemonic) +{ + output(ctx, mnemonic, "fcc%d, %d # 0x%lx", a->cj, a->offs, + ctx->pc + a->offs); +} + +static void output_rr_dj_offs(DisasContext *ctx, arg_rr_dj_offs *a, + const char *mnemonic) +{ + output(ctx, mnemonic, "r%d, r%d, %d # 0x%lx", a->rd, a->rj, + a->offs, ctx->pc + a->offs); +} + +static void output_offs(DisasContext *ctx, arg_offs *a, + const char *mnemonic) +{ + output(ctx, mnemonic, "%d # 0x%lx", a->offs, ctx->pc + a->offs); +} + +static void output_rr_offs(DisasContext *ctx, arg_rr_offs *a, + const char *mnemonic) +{ + output(ctx, mnemonic, "r%d, r%d, %d", a->rj, a->rd, a->offs); +} + +#define INSN(insn, type) \ +static bool trans_##insn(DisasContext *ctx, arg_##type * a) \ +{ \ + output_##type(ctx, a, #insn); \ + return true; \ +} + +INSN(clo_w, rr) +INSN(clz_w, rr) +INSN(cto_w, rr) +INSN(ctz_w, rr) +INSN(clo_d, rr) +INSN(clz_d, rr) +INSN(cto_d, rr) +INSN(ctz_d, rr) +INSN(revb_2h, rr) +INSN(revb_4h, rr) +INSN(revb_2w, rr) +INSN(revb_d, rr) +INSN(revh_2w, rr) +INSN(revh_d, rr) +INSN(bitrev_4b, rr) +INSN(bitrev_8b, rr) +INSN(bitrev_w, rr) +INSN(bitrev_d, rr) +INSN(ext_w_h, rr) +INSN(ext_w_b, rr) +INSN(rdtime_d, rr) +INSN(cpucfg, rr) +INSN(asrtle_d, rr_jk) +INSN(asrtgt_d, rr_jk) +INSN(alsl_w, rrr_sa) +INSN(alsl_wu, rrr_sa) +INSN(bytepick_w, rrr_sa) +INSN(bytepick_d, rrr_sa) +INSN(add_w, rrr) +INSN(add_d, rrr) +INSN(sub_w, rrr) +INSN(sub_d, rrr) +INSN(slt, rrr) +INSN(sltu, rrr) +INSN(maskeqz, rrr) +INSN(masknez, rrr) +INSN(nor, rrr) +INSN(and, rrr) +INSN(or, rrr) +INSN(xor, rrr) +INSN(orn, rrr) +INSN(andn, rrr) +INSN(sll_w, rrr) +INSN(srl_w, rrr) +INSN(sra_w, rrr) +INSN(sll_d, rrr) +INSN(srl_d, rrr) +INSN(sra_d, rrr) +INSN(rotr_w, rrr) +INSN(rotr_d, rrr) +INSN(mul_w, rrr) +INSN(mulh_w, rrr) +INSN(mulh_wu, rrr) +INSN(mul_d, rrr) +INSN(mulh_d, rrr) +INSN(mulh_du, rrr) +INSN(mulw_d_w, rrr) +INSN(mulw_d_wu, rrr) +INSN(div_w, rrr) +INSN(mod_w, rrr) +INSN(div_wu, rrr) +INSN(mod_wu, rrr) +INSN(div_d, rrr) +INSN(mod_d, rrr) +INSN(div_du, rrr) +INSN(mod_du, rrr) +INSN(crc_w_b_w, rrr) +INSN(crc_w_h_w, rrr) +INSN(crc_w_w_w, rrr) +INSN(crc_w_d_w, rrr) +INSN(crcc_w_b_w, rrr) +INSN(crcc_w_h_w, rrr) +INSN(crcc_w_w_w, rrr) +INSN(crcc_w_d_w, rrr) +INSN(break, i) +INSN(syscall, i) +INSN(alsl_d, rrr_sa) +INSN(slli_w, rr_i) +INSN(slli_d, rr_i) +INSN(srli_w, rr_i) +INSN(srli_d, rr_i) +INSN(srai_w, rr_i) +INSN(srai_d, rr_i) +INSN(rotri_w, rr_i) +INSN(rotri_d, rr_i) +INSN(bstrins_w, rr_2bw) +INSN(bstrpick_w, rr_2bw) +INSN(bstrins_d, rr_2bd) +INSN(bstrpick_d, rr_2bd) +INSN(fadd_s, fff) +INSN(fadd_d, fff) +INSN(fsub_s, fff) +INSN(fsub_d, fff) +INSN(fmul_s, fff) +INSN(fmul_d, fff) +INSN(fdiv_s, fff) +INSN(fdiv_d, fff) +INSN(fmax_s, fff) +INSN(fmax_d, fff) +INSN(fmin_s, fff) +INSN(fmin_d, fff) +INSN(fmaxa_s, fff) +INSN(fmaxa_d, fff) +INSN(fmina_s, fff) +INSN(fmina_d, fff) +INSN(fscaleb_s, fff) +INSN(fscaleb_d, fff) +INSN(fcopysign_s, fff) +INSN(fcopysign_d, fff) +INSN(fabs_s, ff) +INSN(fabs_d, ff) +INSN(fneg_s, ff) +INSN(fneg_d, ff) +INSN(flogb_s, ff) +INSN(flogb_d, ff) +INSN(fclass_s, ff) +INSN(fclass_d, ff) +INSN(fsqrt_s, ff) +INSN(fsqrt_d, ff) +INSN(frecip_s, ff) +INSN(frecip_d, ff) +INSN(frsqrt_s, ff) +INSN(frsqrt_d, ff) +INSN(fmov_s, ff) +INSN(fmov_d, ff) +INSN(movgr2fr_w, fr) +INSN(movgr2fr_d, fr) +INSN(movgr2frh_w, fr) +INSN(movfr2gr_s, rf) +INSN(movfr2gr_d, rf) +INSN(movfrh2gr_s, rf) +INSN(movgr2fcsr, fcsrd_r) +INSN(movfcsr2gr, r_fcsrs) +INSN(movfr2cf, cf) +INSN(movcf2fr, fc) +INSN(movgr2cf, cr) +INSN(movcf2gr, rc) +INSN(fcvt_s_d, ff) +INSN(fcvt_d_s, ff) +INSN(ftintrm_w_s, ff) +INSN(ftintrm_w_d, ff) +INSN(ftintrm_l_s, ff) +INSN(ftintrm_l_d, ff) +INSN(ftintrp_w_s, ff) +INSN(ftintrp_w_d, ff) +INSN(ftintrp_l_s, ff) +INSN(ftintrp_l_d, ff) +INSN(ftintrz_w_s, ff) +INSN(ftintrz_w_d, ff) +INSN(ftintrz_l_s, ff) +INSN(ftintrz_l_d, ff) +INSN(ftintrne_w_s, ff) +INSN(ftintrne_w_d, ff) +INSN(ftintrne_l_s, ff) +INSN(ftintrne_l_d, ff) +INSN(ftint_w_s, ff) +INSN(ftint_w_d, ff) +INSN(ftint_l_s, ff) +INSN(ftint_l_d, ff) +INSN(ffint_s_w, ff) +INSN(ffint_s_l, ff) +INSN(ffint_d_w, ff) +INSN(ffint_d_l, ff) +INSN(frint_s, ff) +INSN(frint_d, ff) +INSN(slti, rr_i) +INSN(sltui, rr_i) +INSN(addi_w, rr_i) +INSN(addi_d, rr_i) +INSN(lu52i_d, rr_i) +INSN(andi, rr_i) +INSN(ori, rr_i) +INSN(xori, rr_i) +INSN(rdtimel_w, rr) +INSN(rdtimeh_w, rr) +INSN(fmadd_s, ffff) +INSN(fmadd_d, ffff) +INSN(fmsub_s, ffff) +INSN(fmsub_d, ffff) +INSN(fnmadd_s, ffff) +INSN(fnmadd_d, ffff) +INSN(fnmsub_s, ffff) +INSN(fnmsub_d, ffff) +INSN(fsel, fffc) +INSN(addu16i_d, rr_i) +INSN(lu12i_w, r_i) +INSN(lu32i_d, r_i) +INSN(pcaddi, r_i) +INSN(pcalau12i, r_i) +INSN(pcaddu12i, r_i) +INSN(pcaddu18i, r_i) +INSN(ll_w, rr_i) +INSN(sc_w, rr_i) +INSN(ll_d, rr_i) +INSN(sc_d, rr_i) +INSN(ldptr_w, rr_i) +INSN(stptr_w, rr_i) +INSN(ldptr_d, rr_i) +INSN(stptr_d, rr_i) +INSN(ld_b, rr_i) +INSN(ld_h, rr_i) +INSN(ld_w, rr_i) +INSN(ld_d, rr_i) +INSN(st_b, rr_i) +INSN(st_h, rr_i) +INSN(st_w, rr_i) +INSN(st_d, rr_i) +INSN(ld_bu, rr_i) +INSN(ld_hu, rr_i) +INSN(ld_wu, rr_i) +INSN(preld, hint_r_i) +INSN(fld_s, fr_i) +INSN(fst_s, fr_i) +INSN(fld_d, fr_i) +INSN(fst_d, fr_i) +INSN(ldx_b, rrr) +INSN(ldx_h, rrr) +INSN(ldx_w, rrr) +INSN(ldx_d, rrr) +INSN(stx_b, rrr) +INSN(stx_h, rrr) +INSN(stx_w, rrr) +INSN(stx_d, rrr) +INSN(ldx_bu, rrr) +INSN(ldx_hu, rrr) +INSN(ldx_wu, rrr) +INSN(fldx_s, frr) +INSN(fldx_d, frr) +INSN(fstx_s, frr) +INSN(fstx_d, frr) +INSN(amswap_w, rrr) +INSN(amswap_d, rrr) +INSN(amadd_w, rrr) +INSN(amadd_d, rrr) +INSN(amand_w, rrr) +INSN(amand_d, rrr) +INSN(amor_w, rrr) +INSN(amor_d, rrr) +INSN(amxor_w, rrr) +INSN(amxor_d, rrr) +INSN(ammax_w, rrr) +INSN(ammax_d, rrr) +INSN(ammin_w, rrr) +INSN(ammin_d, rrr) +INSN(ammax_wu, rrr) +INSN(ammax_du, rrr) +INSN(ammin_wu, rrr) +INSN(ammin_du, rrr) +INSN(amswap_db_w, rrr) +INSN(amswap_db_d, rrr) +INSN(amadd_db_w, rrr) +INSN(amadd_db_d, rrr) +INSN(amand_db_w, rrr) +INSN(amand_db_d, rrr) +INSN(amor_db_w, rrr) +INSN(amor_db_d, rrr) +INSN(amxor_db_w, rrr) +INSN(amxor_db_d, rrr) +INSN(ammax_db_w, rrr) +INSN(ammax_db_d, rrr) +INSN(ammin_db_w, rrr) +INSN(ammin_db_d, rrr) +INSN(ammax_db_wu, rrr) +INSN(ammax_db_du, rrr) +INSN(ammin_db_wu, rrr) +INSN(ammin_db_du, rrr) +INSN(dbar, i) +INSN(ibar, i) +INSN(fldgt_s, frr) +INSN(fldgt_d, frr) +INSN(fldle_s, frr) +INSN(fldle_d, frr) +INSN(fstgt_s, frr) +INSN(fstgt_d, frr) +INSN(fstle_s, frr) +INSN(fstle_d, frr) +INSN(ldgt_b, rrr) +INSN(ldgt_h, rrr) +INSN(ldgt_w, rrr) +INSN(ldgt_d, rrr) +INSN(ldle_b, rrr) +INSN(ldle_h, rrr) +INSN(ldle_w, rrr) +INSN(ldle_d, rrr) +INSN(stgt_b, rrr) +INSN(stgt_h, rrr) +INSN(stgt_w, rrr) +INSN(stgt_d, rrr) +INSN(stle_b, rrr) +INSN(stle_h, rrr) +INSN(stle_w, rrr) +INSN(stle_d, rrr) +INSN(beqz, r_offs) +INSN(bnez, r_offs) +INSN(bceqz, c_offs) +INSN(bcnez, c_offs) +INSN(jirl, rr_dj_offs) +INSN(b, offs) +INSN(bl, offs) +INSN(beq, rr_offs) +INSN(bne, rr_offs) +INSN(blt, rr_offs) +INSN(bge, rr_offs) +INSN(bltu, rr_offs) +INSN(bgeu, rr_offs) + +#define output_fcmp(C, PREFIX, SUFFIX) \ +{ \ + (C)->info->fprintf_func((C)->info->stream, "%08x %s%s\tfcc%d, f%d, f%d", \ + (C)->insn, PREFIX, SUFFIX, a->cd, \ + a->fj, a->fk); \ +} + +static bool output_cff_fcond(DisasContext *ctx, arg_cff_fcond * a, + const char *suffix) +{ + bool ret = true; + switch (a->fcond) { + case 0x0: + output_fcmp(ctx, "fcmp_caf_", suffix); + break; + case 0x1: + output_fcmp(ctx, "fcmp_saf_", suffix); + break; + case 0x2: + output_fcmp(ctx, "fcmp_clt_", suffix); + break; + case 0x3: + output_fcmp(ctx, "fcmp_slt_", suffix); + break; + case 0x4: + output_fcmp(ctx, "fcmp_ceq_", suffix); + break; + case 0x5: + output_fcmp(ctx, "fcmp_seq_", suffix); + break; + case 0x6: + output_fcmp(ctx, "fcmp_cle_", suffix); + break; + case 0x7: + output_fcmp(ctx, "fcmp_sle_", suffix); + break; + case 0x8: + output_fcmp(ctx, "fcmp_cun_", suffix); + break; + case 0x9: + output_fcmp(ctx, "fcmp_sun_", suffix); + break; + case 0xA: + output_fcmp(ctx, "fcmp_cult_", suffix); + break; + case 0xB: + output_fcmp(ctx, "fcmp_sult_", suffix); + break; + case 0xC: + output_fcmp(ctx, "fcmp_cueq_", suffix); + break; + case 0xD: + output_fcmp(ctx, "fcmp_sueq_", suffix); + break; + case 0xE: + output_fcmp(ctx, "fcmp_cule_", suffix); + break; + case 0xF: + output_fcmp(ctx, "fcmp_sule_", suffix); + break; + case 0x10: + output_fcmp(ctx, "fcmp_cne_", suffix); + break; + case 0x11: + output_fcmp(ctx, "fcmp_sne_", suffix); + break; + case 0x14: + output_fcmp(ctx, "fcmp_cor_", suffix); + break; + case 0x15: + output_fcmp(ctx, "fcmp_sor_", suffix); + break; + case 0x18: + output_fcmp(ctx, "fcmp_cune_", suffix); + break; + case 0x19: + output_fcmp(ctx, "fcmp_sune_", suffix); + break; + default: + ret = false; + } + return ret; +} + +#define FCMP_INSN(suffix) \ +static bool trans_fcmp_cond_##suffix(DisasContext *ctx, \ + arg_cff_fcond * a) \ +{ \ + return output_cff_fcond(ctx, a, #suffix); \ +} + +FCMP_INSN(s) +FCMP_INSN(d) From patchwork Fri Nov 19 06:13:21 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: gaosong X-Patchwork-Id: 1556925 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4HwRh33Zqxz9sPf for ; Fri, 19 Nov 2021 17:33:39 +1100 (AEDT) Received: from localhost ([::1]:42450 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mnxSr-0006yp-4u for incoming@patchwork.ozlabs.org; Fri, 19 Nov 2021 01:33:37 -0500 Received: from eggs.gnu.org ([209.51.188.92]:46480) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mnxA0-0004Il-KB for qemu-devel@nongnu.org; Fri, 19 Nov 2021 01:14:09 -0500 Received: from mail.loongson.cn ([114.242.206.163]:46890 helo=loongson.cn) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mnx9y-0004a3-D9 for qemu-devel@nongnu.org; Fri, 19 Nov 2021 01:14:08 -0500 Received: from kvm-dev1.localdomain (unknown [10.2.5.134]) by mail.loongson.cn (Coremail) with SMTP id AQAAf9Dxj8+KQJdhSG0AAA--.1952S19; Fri, 19 Nov 2021 14:13:53 +0800 (CST) From: Song Gao To: qemu-devel@nongnu.org Subject: [PATCH v11 17/26] linux-user: Add LoongArch generic header files Date: Fri, 19 Nov 2021 14:13:21 +0800 Message-Id: <1637302410-24632-18-git-send-email-gaosong@loongson.cn> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1637302410-24632-1-git-send-email-gaosong@loongson.cn> References: <1637302410-24632-1-git-send-email-gaosong@loongson.cn> X-CM-TRANSID: AQAAf9Dxj8+KQJdhSG0AAA--.1952S19 X-Coremail-Antispam: 1UD129KBjvJXoWxXrWUGr1DAr43JrW8Aw1UWrg_yoW5XFW7pF Wrur1fGr4xXrWxt3s8XFy5ZF15Xa1v9Fy7uayxWry8Jr97C348ZwnFgr9rWay7Xw1jkrW0 gr909a1jkF4xXFJanT9S1TB71UUUUUUqnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnUUvcSsGvfC2KfnxnUUI43ZEXa7xR_UUUUUUUUU== X-CM-SenderInfo: 5jdr20tqj6z05rqj20fqof0/ Received-SPF: pass client-ip=114.242.206.163; envelope-from=gaosong@loongson.cn; helo=loongson.cn X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Xiaojuan Yang , richard.henderson@linaro.org, laurent@vivier.eu Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" This includes: - sockbits.h - target_errno_defs.h - target_fcntl.h - termbits.h Signed-off-by: Song Gao Signed-off-by: Xiaojuan Yang Reviewed-by: Richard Henderson --- linux-user/loongarch64/sockbits.h | 11 +++++++++++ linux-user/loongarch64/target_errno_defs.h | 12 ++++++++++++ linux-user/loongarch64/target_fcntl.h | 11 +++++++++++ linux-user/loongarch64/termbits.h | 11 +++++++++++ 4 files changed, 45 insertions(+) create mode 100644 linux-user/loongarch64/sockbits.h create mode 100644 linux-user/loongarch64/target_errno_defs.h create mode 100644 linux-user/loongarch64/target_fcntl.h create mode 100644 linux-user/loongarch64/termbits.h diff --git a/linux-user/loongarch64/sockbits.h b/linux-user/loongarch64/sockbits.h new file mode 100644 index 0000000..1cffcae --- /dev/null +++ b/linux-user/loongarch64/sockbits.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (c) 2021 Loongson Technology Corporation Limited + */ + +#ifndef LOONGARCH_TARGET_SOCKBITS_H +#define LOONGARCH_TARGET_SOCKBITS_H + +#include "../generic/sockbits.h" + +#endif diff --git a/linux-user/loongarch64/target_errno_defs.h b/linux-user/loongarch64/target_errno_defs.h new file mode 100644 index 0000000..c198b8a --- /dev/null +++ b/linux-user/loongarch64/target_errno_defs.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (c) 2021 Loongson Technology Corporation Limited + */ + +#ifndef LOONGARCH_TARGET_ERRNO_DEFS_H +#define LOONGARCH_TARGET_ERRNO_DEFS_H + +/* Target uses generic errno */ +#include "../generic/target_errno_defs.h" + +#endif diff --git a/linux-user/loongarch64/target_fcntl.h b/linux-user/loongarch64/target_fcntl.h new file mode 100644 index 0000000..99bf586 --- /dev/null +++ b/linux-user/loongarch64/target_fcntl.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (c) 2021 Loongson Technology Corporation Limited + */ + +#ifndef LOONGARCH_TARGET_FCNTL_H +#define LOONGARCH_TARGET_FCNTL_H + +#include "../generic/fcntl.h" + +#endif diff --git a/linux-user/loongarch64/termbits.h b/linux-user/loongarch64/termbits.h new file mode 100644 index 0000000..d425db8 --- /dev/null +++ b/linux-user/loongarch64/termbits.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (c) 2021 Loongson Technology Corporation Limited + */ + +#ifndef LOONGARCH_TARGET_TERMBITS_H +#define LOONGARCH_TARGET_TERMBITS_H + +#include "../generic/termbits.h" + +#endif From patchwork Fri Nov 19 06:13:22 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: gaosong X-Patchwork-Id: 1556929 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4HwRnF1bGcz9sPf for ; Fri, 19 Nov 2021 17:38:07 +1100 (AEDT) Received: from localhost ([::1]:50578 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mnxXA-000485-6P for incoming@patchwork.ozlabs.org; Fri, 19 Nov 2021 01:38:04 -0500 Received: from eggs.gnu.org ([209.51.188.92]:46522) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mnxA2-0004JT-4e for qemu-devel@nongnu.org; Fri, 19 Nov 2021 01:14:10 -0500 Received: from mail.loongson.cn ([114.242.206.163]:46904 helo=loongson.cn) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mnx9z-0004a7-05 for qemu-devel@nongnu.org; Fri, 19 Nov 2021 01:14:09 -0500 Received: from kvm-dev1.localdomain (unknown [10.2.5.134]) by mail.loongson.cn (Coremail) with SMTP id AQAAf9Dxj8+KQJdhSG0AAA--.1952S20; Fri, 19 Nov 2021 14:13:54 +0800 (CST) From: Song Gao To: qemu-devel@nongnu.org Subject: [PATCH v11 18/26] linux-user: Add LoongArch specific structures Date: Fri, 19 Nov 2021 14:13:22 +0800 Message-Id: <1637302410-24632-19-git-send-email-gaosong@loongson.cn> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1637302410-24632-1-git-send-email-gaosong@loongson.cn> References: <1637302410-24632-1-git-send-email-gaosong@loongson.cn> X-CM-TRANSID: AQAAf9Dxj8+KQJdhSG0AAA--.1952S20 X-Coremail-Antispam: 1UD129KBjvJXoW7Zw4xCw4DXFy5WrWkCryUJrb_yoW8Zr13pF 4rA3Z8Ar47JrWIqwn3GFWUXryaq3W8CFW7XayfAry8Aw4xt3yrZF15KrW7Aa9xXw1UGry3 ZFyktr1UCa1UGFJanT9S1TB71UUUUUUqnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnUUvcSsGvfC2KfnxnUUI43ZEXa7xR_UUUUUUUUU== X-CM-SenderInfo: 5jdr20tqj6z05rqj20fqof0/ Received-SPF: pass client-ip=114.242.206.163; envelope-from=gaosong@loongson.cn; helo=loongson.cn X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Xiaojuan Yang , richard.henderson@linaro.org, laurent@vivier.eu Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Signed-off-by: Song Gao Signed-off-by: Xiaojuan Yang --- linux-user/loongarch64/target_structs.h | 48 +++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 linux-user/loongarch64/target_structs.h diff --git a/linux-user/loongarch64/target_structs.h b/linux-user/loongarch64/target_structs.h new file mode 100644 index 0000000..cc7928a --- /dev/null +++ b/linux-user/loongarch64/target_structs.h @@ -0,0 +1,48 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * LoongArch specific structures for linux-user + * + * Copyright (c) 2021 Loongson Technology Corporation Limited + */ + +#ifndef LOONGARCH_TARGET_STRUCTS_H +#define LOONGARCH_TARGET_STRUCTS_H + +struct target_ipc_perm { + abi_int __key; /* Key. */ + abi_uint uid; /* Owner's user ID. */ + abi_uint gid; /* Owner's group ID. */ + abi_uint cuid; /* Creator's user ID. */ + abi_uint cgid; /* Creator's group ID. */ + abi_uint mode; /* Read/write permission. */ + abi_ushort __seq; /* Sequence number. */ + abi_ushort __pad1; + abi_ulong __unused1; + abi_ulong __unused2; +}; + +struct target_shmid_ds { + struct target_ipc_perm shm_perm; /* operation permission struct */ + abi_long shm_segsz; /* size of segment in bytes */ + abi_ulong shm_atime; /* time of last shmat() */ + abi_ulong shm_dtime; /* time of last shmdt() */ + abi_ulong shm_ctime; /* time of last change by shmctl() */ + abi_int shm_cpid; /* pid of creator */ + abi_int shm_lpid; /* pid of last shmop */ + abi_ulong shm_nattch; /* number of current attaches */ + abi_ulong __unused1; + abi_ulong __unused2; +}; + +#define TARGET_SEMID64_DS + +struct target_semid64_ds { + struct target_ipc_perm sem_perm; + abi_ulong sem_otime; + abi_ulong sem_ctime; + abi_ulong sem_nsems; + abi_ulong __unused1; + abi_ulong __unused2; +}; + +#endif From patchwork Fri Nov 19 06:13:23 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: gaosong X-Patchwork-Id: 1556918 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4HwRQS1nmTz9sXN for ; Fri, 19 Nov 2021 17:21:52 +1100 (AEDT) Received: from localhost ([::1]:51968 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mnxHR-0002FP-TG for incoming@patchwork.ozlabs.org; Fri, 19 Nov 2021 01:21:49 -0500 Received: from eggs.gnu.org ([209.51.188.92]:46566) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mnxA3-0004KB-DT for qemu-devel@nongnu.org; Fri, 19 Nov 2021 01:14:11 -0500 Received: from mail.loongson.cn ([114.242.206.163]:46920 helo=loongson.cn) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mnxA0-0004aF-DI for qemu-devel@nongnu.org; Fri, 19 Nov 2021 01:14:11 -0500 Received: from kvm-dev1.localdomain (unknown [10.2.5.134]) by mail.loongson.cn (Coremail) with SMTP id AQAAf9Dxj8+KQJdhSG0AAA--.1952S21; Fri, 19 Nov 2021 14:13:54 +0800 (CST) From: Song Gao To: qemu-devel@nongnu.org Subject: [PATCH v11 19/26] linux-user: Add LoongArch signal support Date: Fri, 19 Nov 2021 14:13:23 +0800 Message-Id: <1637302410-24632-20-git-send-email-gaosong@loongson.cn> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1637302410-24632-1-git-send-email-gaosong@loongson.cn> References: <1637302410-24632-1-git-send-email-gaosong@loongson.cn> X-CM-TRANSID: AQAAf9Dxj8+KQJdhSG0AAA--.1952S21 X-Coremail-Antispam: 1UD129KBjvJXoW3Xr4DZr47CFWDKF4DKF45KFg_yoW7Zw1fpF 4xuw1kGrWUJrWS93s3G3WFqFyrWw1kGryUKFWxGw1rAwn8JryF9as7trZrtF1UAw1DGFnF 9F9093WYkF48WFJanT9S1TB71UUUUUUqnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnUUvcSsGvfC2KfnxnUUI43ZEXa7xR_UUUUUUUUU== X-CM-SenderInfo: 5jdr20tqj6z05rqj20fqof0/ Received-SPF: pass client-ip=114.242.206.163; envelope-from=gaosong@loongson.cn; helo=loongson.cn X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Xiaojuan Yang , richard.henderson@linaro.org, laurent@vivier.eu Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Signed-off-by: Song Gao Signed-off-by: Xiaojuan Yang --- linux-user/loongarch64/signal.c | 162 +++++++++++++++++++++++++++++++++ linux-user/loongarch64/target_signal.h | 29 ++++++ 2 files changed, 191 insertions(+) create mode 100644 linux-user/loongarch64/signal.c create mode 100644 linux-user/loongarch64/target_signal.h diff --git a/linux-user/loongarch64/signal.c b/linux-user/loongarch64/signal.c new file mode 100644 index 0000000..8fbc827 --- /dev/null +++ b/linux-user/loongarch64/signal.c @@ -0,0 +1,162 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * LoongArch emulation of Linux signals + * + * Copyright (c) 2021 Loongson Technology Corporation Limited + */ + +#include "qemu/osdep.h" +#include "qemu.h" +#include "signal-common.h" +#include "user-internals.h" +#include "linux-user/trace.h" + +struct target_sigcontext { + uint64_t sc_pc; + uint64_t sc_gpr[32]; + uint64_t sc_fpr[32]; + uint64_t sc_fcc; + uint32_t sc_fcsr; + uint32_t sc_flags; +}; + +struct target_ucontext { + target_ulong tuc_flags; + target_ulong tuc_link; + target_stack_t tuc_stack; + target_ulong pad0; + struct target_sigcontext tuc_mcontext; + target_sigset_t tuc_sigmask; +}; + +struct target_rt_sigframe { + struct target_siginfo rs_info; + struct target_ucontext rs_uc; +}; + +static inline void setup_sigcontext(CPULoongArchState *env, + struct target_sigcontext *sc) +{ + int i; + + __put_user(env->pc, &sc->sc_pc); + + __put_user(0, &sc->sc_gpr[0]); + for (i = 1; i < 32; ++i) { + __put_user(env->gpr[i], &sc->sc_gpr[i]); + } + + for (i = 0; i < 32; ++i) { + __put_user(env->fpr[i], &sc->sc_fpr[i]); + } +} + +static inline void +restore_sigcontext(CPULoongArchState *env, struct target_sigcontext *sc) +{ + int i; + + __get_user(env->pc, &sc->sc_pc); + + for (i = 1; i < 32; ++i) { + __get_user(env->gpr[i], &sc->sc_gpr[i]); + } + + for (i = 0; i < 32; ++i) { + __get_user(env->fpr[i], &sc->sc_fpr[i]); + } +} + +/* + * Determine which stack to use.. + */ +static inline abi_ulong +get_sigframe(struct target_sigaction *ka, CPULoongArchState *env, + size_t frame_size) +{ + unsigned long sp; + + sp = target_sigsp(get_sp_from_cpustate(env) - 32, ka); + + return (sp - frame_size) & ~7; +} + +void setup_rt_frame(int sig, struct target_sigaction *ka, + target_siginfo_t *info, + target_sigset_t *set, CPULoongArchState *env) +{ + struct target_rt_sigframe *frame; + abi_ulong frame_addr; + int i; + + frame_addr = get_sigframe(ka, env, sizeof(*frame)); + trace_user_setup_rt_frame(env, frame_addr); + if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) { + goto give_sigsegv; + } + + tswap_siginfo(&frame->rs_info, info); + + __put_user(0, &frame->rs_uc.tuc_flags); + __put_user(0, &frame->rs_uc.tuc_link); + target_save_altstack(&frame->rs_uc.tuc_stack, env); + + setup_sigcontext(env, &frame->rs_uc.tuc_mcontext); + + for (i = 0; i < TARGET_NSIG_WORDS; i++) { + __put_user(set->sig[i], &frame->rs_uc.tuc_sigmask.sig[i]); + } + + env->gpr[4] = sig; + env->gpr[5] = frame_addr + offsetof(struct target_rt_sigframe, rs_info); + env->gpr[6] = frame_addr + offsetof(struct target_rt_sigframe, rs_uc); + env->gpr[3] = frame_addr; + env->gpr[1] = default_rt_sigreturn; + + env->pc = env->gpr[20] = ka->_sa_handler; + unlock_user_struct(frame, frame_addr, 1); + return; + +give_sigsegv: + unlock_user_struct(frame, frame_addr, 1); + force_sigsegv(sig); +} + +long do_rt_sigreturn(CPULoongArchState *env) +{ + struct target_rt_sigframe *frame; + abi_ulong frame_addr; + sigset_t blocked; + + frame_addr = env->gpr[3]; + trace_user_do_rt_sigreturn(env, frame_addr); + if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) { + goto badframe; + } + + target_to_host_sigset(&blocked, &frame->rs_uc.tuc_sigmask); + set_sigmask(&blocked); + + restore_sigcontext(env, &frame->rs_uc.tuc_mcontext); + target_restore_altstack(&frame->rs_uc.tuc_stack, env); + + unlock_user_struct(frame, frame_addr, 0); + return -TARGET_QEMU_ESIGRETURN; + +badframe: + unlock_user_struct(frame, frame_addr, 0); + force_sig(TARGET_SIGSEGV); + return -TARGET_QEMU_ESIGRETURN; +} + +void setup_sigtramp(abi_ulong sigtramp_page) +{ + uint32_t *tramp = lock_user(VERIFY_WRITE, sigtramp_page, 8, 0); + assert(tramp != NULL); + + __put_user(0x03822c0b, tramp + 0); /* ori a7, a7, 0x8b */ + __put_user(0x002b0000, tramp + 1); /* syscall 0 */ + + default_rt_sigreturn = sigtramp_page; + unlock_user(tramp, sigtramp_page, 8); +} diff --git a/linux-user/loongarch64/target_signal.h b/linux-user/loongarch64/target_signal.h new file mode 100644 index 0000000..c5f467b --- /dev/null +++ b/linux-user/loongarch64/target_signal.h @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (c) 2021 Loongson Technology Corporation Limited + */ + +#ifndef LOONGARCH_TARGET_SIGNAL_H +#define LOONGARCH_TARGET_SIGNAL_H + +/* this struct defines a stack used during syscall handling */ +typedef struct target_sigaltstack { + abi_long ss_sp; + abi_int ss_flags; + abi_ulong ss_size; +} target_stack_t; + +/* + * sigaltstack controls + */ +#define TARGET_SS_ONSTACK 1 +#define TARGET_SS_DISABLE 2 + +#define TARGET_MINSIGSTKSZ 2048 +#define TARGET_SIGSTKSZ 8192 + +#include "../generic/signal.h" + +#define TARGET_ARCH_HAS_SIGTRAMP_PAGE 1 + +#endif /* LOONGARCH_TARGET_SIGNAL_H */ From patchwork Fri Nov 19 06:13:24 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: gaosong X-Patchwork-Id: 1556931 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4HwS0z3kdLz9sPf for ; Fri, 19 Nov 2021 17:48:19 +1100 (AEDT) Received: from localhost ([::1]:56958 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mnxh3-0000MU-AS for incoming@patchwork.ozlabs.org; Fri, 19 Nov 2021 01:48:17 -0500 Received: from eggs.gnu.org ([209.51.188.92]:46542) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mnxA2-0004JW-KE for qemu-devel@nongnu.org; Fri, 19 Nov 2021 01:14:11 -0500 Received: from mail.loongson.cn ([114.242.206.163]:46934 helo=loongson.cn) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mnx9z-0004aI-RV for qemu-devel@nongnu.org; Fri, 19 Nov 2021 01:14:10 -0500 Received: from kvm-dev1.localdomain (unknown [10.2.5.134]) by mail.loongson.cn (Coremail) with SMTP id AQAAf9Dxj8+KQJdhSG0AAA--.1952S22; Fri, 19 Nov 2021 14:13:55 +0800 (CST) From: Song Gao To: qemu-devel@nongnu.org Subject: [PATCH v11 20/26] linux-user: Add LoongArch elf support Date: Fri, 19 Nov 2021 14:13:24 +0800 Message-Id: <1637302410-24632-21-git-send-email-gaosong@loongson.cn> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1637302410-24632-1-git-send-email-gaosong@loongson.cn> References: <1637302410-24632-1-git-send-email-gaosong@loongson.cn> X-CM-TRANSID: AQAAf9Dxj8+KQJdhSG0AAA--.1952S22 X-Coremail-Antispam: 1UD129KBjvJXoWxXrWUGr1xKr47uF15Kr45Jrb_yoW5CF18pF WUCay5GF4rtFZxKw1ftFyUGF15Zw18ur17C34xWFWrAwsxJ348Wr1kKrWqyFy3Za9Ygayj vr90yw1jkr47XaUanT9S1TB71UUUUUUqnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnUUvcSsGvfC2KfnxnUUI43ZEXa7xR_UUUUUUUUU== X-CM-SenderInfo: 5jdr20tqj6z05rqj20fqof0/ Received-SPF: pass client-ip=114.242.206.163; envelope-from=gaosong@loongson.cn; helo=loongson.cn X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Xiaojuan Yang , richard.henderson@linaro.org, laurent@vivier.eu Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Signed-off-by: Song Gao Signed-off-by: Xiaojuan Yang Reviewed-by: Richard Henderson --- include/elf.h | 2 ++ linux-user/elfload.c | 58 +++++++++++++++++++++++++++++++++++++ linux-user/loongarch64/target_elf.h | 12 ++++++++ 3 files changed, 72 insertions(+) create mode 100644 linux-user/loongarch64/target_elf.h diff --git a/include/elf.h b/include/elf.h index 811bf4a..3a4bcb6 100644 --- a/include/elf.h +++ b/include/elf.h @@ -182,6 +182,8 @@ typedef struct mips_elf_abiflags_v0 { #define EM_NANOMIPS 249 /* Wave Computing nanoMIPS */ +#define EM_LOONGARCH 258 /* LoongArch */ + /* * This is an interim value that we will use until the committee comes * up with a final number. diff --git a/linux-user/elfload.c b/linux-user/elfload.c index 5da8c02..7827e25 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -914,6 +914,64 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs, const CPUPPCState *en #endif +#ifdef TARGET_LOONGARCH64 + +#define ELF_START_MMAP 0x80000000 + +#define ELF_CLASS ELFCLASS64 +#define ELF_ARCH EM_LOONGARCH + +#define elf_check_arch(x) ((x) == EM_LOONGARCH) +static inline void init_thread(struct target_pt_regs *regs, + struct image_info *infop) +{ + regs->csr_crmd = 2 << 3; + regs->csr_era = infop->entry; + regs->regs[3] = infop->start_stack; +} + +/* See linux kernel: arch/loongarch/include/asm/elf.h. */ +#define ELF_NREG 45 +typedef target_elf_greg_t target_elf_gregset_t[ELF_NREG]; + +/* See linux kernel: arch/loongarch/include/asm/reg.h. */ +enum { + TARGET_EF_R0 = 0, + TARGET_EF_CSR_ERA = TARGET_EF_R0 + 32, + TARGET_EF_CSR_BADVADDR = TARGET_EF_R0 + 33, +}; + +/* See linux kernel: arch/loongarch/kernel/process.c:loongarch_dump_regs64. */ +static void elf_core_copy_regs(target_elf_gregset_t *regs, + const CPULoongArchState *env) +{ + int i; + + for (i = 0; i < TARGET_EF_R0; i++) { + (*regs)[i] = 0; + } + (*regs)[TARGET_EF_R0] = 0; + + for (i = 1; i < ARRAY_SIZE(env->gpr); i++) { + (*regs)[TARGET_EF_R0 + i] = tswapreg(env->gpr[i]); + } + + (*regs)[TARGET_EF_CSR_ERA] = tswapreg(env->pc); + (*regs)[TARGET_EF_CSR_BADVADDR] = tswapreg(env->badaddr); +} + +#define USE_ELF_CORE_DUMP +#define ELF_EXEC_PAGESIZE 4096 + +#define ELF_HWCAP get_elf_hwcap() + +static uint32_t get_elf_hwcap(void) +{ + return 0; +} + +#endif /* TARGET_LOONGARCH64 */ + #ifdef TARGET_MIPS #define ELF_START_MMAP 0x80000000 diff --git a/linux-user/loongarch64/target_elf.h b/linux-user/loongarch64/target_elf.h new file mode 100644 index 0000000..3c690bb --- /dev/null +++ b/linux-user/loongarch64/target_elf.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (c) 2021 Loongson Technology Corporation Limited + */ + +#ifndef LOONGARCH_TARGET_ELF_H +#define LOONGARCH_TARGET_ELF_H +static inline const char *cpu_get_model(uint32_t eflags) +{ + return "Loongson-3A5000"; +} +#endif From patchwork Fri Nov 19 06:13:25 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: gaosong X-Patchwork-Id: 1556921 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4HwRZD5Cy3z9sXN for ; Fri, 19 Nov 2021 17:28:36 +1100 (AEDT) Received: from localhost ([::1]:60414 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mnxNy-0008Bd-7d for incoming@patchwork.ozlabs.org; Fri, 19 Nov 2021 01:28:34 -0500 Received: from eggs.gnu.org ([209.51.188.92]:46582) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mnxA4-0004La-5c for qemu-devel@nongnu.org; Fri, 19 Nov 2021 01:14:12 -0500 Received: from mail.loongson.cn ([114.242.206.163]:46948 helo=loongson.cn) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mnxA0-0004aN-L0 for qemu-devel@nongnu.org; Fri, 19 Nov 2021 01:14:11 -0500 Received: from kvm-dev1.localdomain (unknown [10.2.5.134]) by mail.loongson.cn (Coremail) with SMTP id AQAAf9Dxj8+KQJdhSG0AAA--.1952S23; Fri, 19 Nov 2021 14:13:55 +0800 (CST) From: Song Gao To: qemu-devel@nongnu.org Subject: [PATCH v11 21/26] linux-user: Add LoongArch syscall support Date: Fri, 19 Nov 2021 14:13:25 +0800 Message-Id: <1637302410-24632-22-git-send-email-gaosong@loongson.cn> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1637302410-24632-1-git-send-email-gaosong@loongson.cn> References: <1637302410-24632-1-git-send-email-gaosong@loongson.cn> X-CM-TRANSID: AQAAf9Dxj8+KQJdhSG0AAA--.1952S23 X-Coremail-Antispam: 1UD129KBjvAXoWfGw1xKw18AFyfAryrJFyxZrb_yoW8Xw1xKo WxJF1aqwn7Jr1xua1kWw17Wr1UZF9rJr18Jr4UAFy8GFnFqr1DWr13tay8WFn5CrySgFy5 tFyjqr1qyFZ0yF1Dn29KB7ZKAUJUUUUU529EdanIXcx71UUUUU7v73VFW2AGmfu7bjvjm3 AaLaJ3UjIYCTnIWjDUYxBIdaVFxhVjvjDU0xZFpf9x0zRUUUUUUUUU= X-CM-SenderInfo: 5jdr20tqj6z05rqj20fqof0/ Received-SPF: pass client-ip=114.242.206.163; envelope-from=gaosong@loongson.cn; helo=loongson.cn X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Xiaojuan Yang , richard.henderson@linaro.org, laurent@vivier.eu Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" We should disable '__BITS_PER_LONG' at [1] before run gensyscalls.sh [1] arch/loongarch/include/uapi/asm/bitsperlong.h Signed-off-by: Song Gao Signed-off-by: Xiaojuan Yang Reviewed-by: Richard Henderson --- linux-user/loongarch64/syscall_nr.h | 312 ++++++++++++++++++++++++++++++++ linux-user/loongarch64/target_syscall.h | 45 +++++ linux-user/syscall_defs.h | 10 +- scripts/gensyscalls.sh | 1 + 4 files changed, 364 insertions(+), 4 deletions(-) create mode 100644 linux-user/loongarch64/syscall_nr.h create mode 100644 linux-user/loongarch64/target_syscall.h diff --git a/linux-user/loongarch64/syscall_nr.h b/linux-user/loongarch64/syscall_nr.h new file mode 100644 index 0000000..8fbf287 --- /dev/null +++ b/linux-user/loongarch64/syscall_nr.h @@ -0,0 +1,312 @@ +/* + * This file contains the system call numbers. + * Do not modify. + * This file is generated by scripts/gensyscalls.sh + */ +#ifndef LINUX_USER_LOONGARCH_SYSCALL_NR_H +#define LINUX_USER_LOONGARCH_SYSCALL_NR_H + +#define TARGET_NR_io_setup 0 +#define TARGET_NR_io_destroy 1 +#define TARGET_NR_io_submit 2 +#define TARGET_NR_io_cancel 3 +#define TARGET_NR_io_getevents 4 +#define TARGET_NR_setxattr 5 +#define TARGET_NR_lsetxattr 6 +#define TARGET_NR_fsetxattr 7 +#define TARGET_NR_getxattr 8 +#define TARGET_NR_lgetxattr 9 +#define TARGET_NR_fgetxattr 10 +#define TARGET_NR_listxattr 11 +#define TARGET_NR_llistxattr 12 +#define TARGET_NR_flistxattr 13 +#define TARGET_NR_removexattr 14 +#define TARGET_NR_lremovexattr 15 +#define TARGET_NR_fremovexattr 16 +#define TARGET_NR_getcwd 17 +#define TARGET_NR_lookup_dcookie 18 +#define TARGET_NR_eventfd2 19 +#define TARGET_NR_epoll_create1 20 +#define TARGET_NR_epoll_ctl 21 +#define TARGET_NR_epoll_pwait 22 +#define TARGET_NR_dup 23 +#define TARGET_NR_dup3 24 +#define TARGET_NR_fcntl 25 +#define TARGET_NR_inotify_init1 26 +#define TARGET_NR_inotify_add_watch 27 +#define TARGET_NR_inotify_rm_watch 28 +#define TARGET_NR_ioctl 29 +#define TARGET_NR_ioprio_set 30 +#define TARGET_NR_ioprio_get 31 +#define TARGET_NR_flock 32 +#define TARGET_NR_mknodat 33 +#define TARGET_NR_mkdirat 34 +#define TARGET_NR_unlinkat 35 +#define TARGET_NR_symlinkat 36 +#define TARGET_NR_linkat 37 +#define TARGET_NR_umount2 39 +#define TARGET_NR_mount 40 +#define TARGET_NR_pivot_root 41 +#define TARGET_NR_nfsservctl 42 +#define TARGET_NR_statfs 43 +#define TARGET_NR_fstatfs 44 +#define TARGET_NR_truncate 45 +#define TARGET_NR_ftruncate 46 +#define TARGET_NR_fallocate 47 +#define TARGET_NR_faccessat 48 +#define TARGET_NR_chdir 49 +#define TARGET_NR_fchdir 50 +#define TARGET_NR_chroot 51 +#define TARGET_NR_fchmod 52 +#define TARGET_NR_fchmodat 53 +#define TARGET_NR_fchownat 54 +#define TARGET_NR_fchown 55 +#define TARGET_NR_openat 56 +#define TARGET_NR_close 57 +#define TARGET_NR_vhangup 58 +#define TARGET_NR_pipe2 59 +#define TARGET_NR_quotactl 60 +#define TARGET_NR_getdents64 61 +#define TARGET_NR_lseek 62 +#define TARGET_NR_read 63 +#define TARGET_NR_write 64 +#define TARGET_NR_readv 65 +#define TARGET_NR_writev 66 +#define TARGET_NR_pread64 67 +#define TARGET_NR_pwrite64 68 +#define TARGET_NR_preadv 69 +#define TARGET_NR_pwritev 70 +#define TARGET_NR_sendfile 71 +#define TARGET_NR_pselect6 72 +#define TARGET_NR_ppoll 73 +#define TARGET_NR_signalfd4 74 +#define TARGET_NR_vmsplice 75 +#define TARGET_NR_splice 76 +#define TARGET_NR_tee 77 +#define TARGET_NR_readlinkat 78 +#define TARGET_NR_newfstatat 79 +#define TARGET_NR_fstat 80 +#define TARGET_NR_sync 81 +#define TARGET_NR_fsync 82 +#define TARGET_NR_fdatasync 83 +#define TARGET_NR_sync_file_range 84 +#define TARGET_NR_timerfd_create 85 +#define TARGET_NR_timerfd_settime 86 +#define TARGET_NR_timerfd_gettime 87 +#define TARGET_NR_utimensat 88 +#define TARGET_NR_acct 89 +#define TARGET_NR_capget 90 +#define TARGET_NR_capset 91 +#define TARGET_NR_personality 92 +#define TARGET_NR_exit 93 +#define TARGET_NR_exit_group 94 +#define TARGET_NR_waitid 95 +#define TARGET_NR_set_tid_address 96 +#define TARGET_NR_unshare 97 +#define TARGET_NR_futex 98 +#define TARGET_NR_set_robust_list 99 +#define TARGET_NR_get_robust_list 100 +#define TARGET_NR_nanosleep 101 +#define TARGET_NR_getitimer 102 +#define TARGET_NR_setitimer 103 +#define TARGET_NR_kexec_load 104 +#define TARGET_NR_init_module 105 +#define TARGET_NR_delete_module 106 +#define TARGET_NR_timer_create 107 +#define TARGET_NR_timer_gettime 108 +#define TARGET_NR_timer_getoverrun 109 +#define TARGET_NR_timer_settime 110 +#define TARGET_NR_timer_delete 111 +#define TARGET_NR_clock_settime 112 +#define TARGET_NR_clock_gettime 113 +#define TARGET_NR_clock_getres 114 +#define TARGET_NR_clock_nanosleep 115 +#define TARGET_NR_syslog 116 +#define TARGET_NR_ptrace 117 +#define TARGET_NR_sched_setparam 118 +#define TARGET_NR_sched_setscheduler 119 +#define TARGET_NR_sched_getscheduler 120 +#define TARGET_NR_sched_getparam 121 +#define TARGET_NR_sched_setaffinity 122 +#define TARGET_NR_sched_getaffinity 123 +#define TARGET_NR_sched_yield 124 +#define TARGET_NR_sched_get_priority_max 125 +#define TARGET_NR_sched_get_priority_min 126 +#define TARGET_NR_sched_rr_get_interval 127 +#define TARGET_NR_restart_syscall 128 +#define TARGET_NR_kill 129 +#define TARGET_NR_tkill 130 +#define TARGET_NR_tgkill 131 +#define TARGET_NR_sigaltstack 132 +#define TARGET_NR_rt_sigsuspend 133 +#define TARGET_NR_rt_sigaction 134 +#define TARGET_NR_rt_sigprocmask 135 +#define TARGET_NR_rt_sigpending 136 +#define TARGET_NR_rt_sigtimedwait 137 +#define TARGET_NR_rt_sigqueueinfo 138 +#define TARGET_NR_rt_sigreturn 139 +#define TARGET_NR_setpriority 140 +#define TARGET_NR_getpriority 141 +#define TARGET_NR_reboot 142 +#define TARGET_NR_setregid 143 +#define TARGET_NR_setgid 144 +#define TARGET_NR_setreuid 145 +#define TARGET_NR_setuid 146 +#define TARGET_NR_setresuid 147 +#define TARGET_NR_getresuid 148 +#define TARGET_NR_setresgid 149 +#define TARGET_NR_getresgid 150 +#define TARGET_NR_setfsuid 151 +#define TARGET_NR_setfsgid 152 +#define TARGET_NR_times 153 +#define TARGET_NR_setpgid 154 +#define TARGET_NR_getpgid 155 +#define TARGET_NR_getsid 156 +#define TARGET_NR_setsid 157 +#define TARGET_NR_getgroups 158 +#define TARGET_NR_setgroups 159 +#define TARGET_NR_uname 160 +#define TARGET_NR_sethostname 161 +#define TARGET_NR_setdomainname 162 +#define TARGET_NR_getrusage 165 +#define TARGET_NR_umask 166 +#define TARGET_NR_prctl 167 +#define TARGET_NR_getcpu 168 +#define TARGET_NR_gettimeofday 169 +#define TARGET_NR_settimeofday 170 +#define TARGET_NR_adjtimex 171 +#define TARGET_NR_getpid 172 +#define TARGET_NR_getppid 173 +#define TARGET_NR_getuid 174 +#define TARGET_NR_geteuid 175 +#define TARGET_NR_getgid 176 +#define TARGET_NR_getegid 177 +#define TARGET_NR_gettid 178 +#define TARGET_NR_sysinfo 179 +#define TARGET_NR_mq_open 180 +#define TARGET_NR_mq_unlink 181 +#define TARGET_NR_mq_timedsend 182 +#define TARGET_NR_mq_timedreceive 183 +#define TARGET_NR_mq_notify 184 +#define TARGET_NR_mq_getsetattr 185 +#define TARGET_NR_msgget 186 +#define TARGET_NR_msgctl 187 +#define TARGET_NR_msgrcv 188 +#define TARGET_NR_msgsnd 189 +#define TARGET_NR_semget 190 +#define TARGET_NR_semctl 191 +#define TARGET_NR_semtimedop 192 +#define TARGET_NR_semop 193 +#define TARGET_NR_shmget 194 +#define TARGET_NR_shmctl 195 +#define TARGET_NR_shmat 196 +#define TARGET_NR_shmdt 197 +#define TARGET_NR_socket 198 +#define TARGET_NR_socketpair 199 +#define TARGET_NR_bind 200 +#define TARGET_NR_listen 201 +#define TARGET_NR_accept 202 +#define TARGET_NR_connect 203 +#define TARGET_NR_getsockname 204 +#define TARGET_NR_getpeername 205 +#define TARGET_NR_sendto 206 +#define TARGET_NR_recvfrom 207 +#define TARGET_NR_setsockopt 208 +#define TARGET_NR_getsockopt 209 +#define TARGET_NR_shutdown 210 +#define TARGET_NR_sendmsg 211 +#define TARGET_NR_recvmsg 212 +#define TARGET_NR_readahead 213 +#define TARGET_NR_brk 214 +#define TARGET_NR_munmap 215 +#define TARGET_NR_mremap 216 +#define TARGET_NR_add_key 217 +#define TARGET_NR_request_key 218 +#define TARGET_NR_keyctl 219 +#define TARGET_NR_clone 220 +#define TARGET_NR_execve 221 +#define TARGET_NR_mmap 222 +#define TARGET_NR_fadvise64 223 +#define TARGET_NR_swapon 224 +#define TARGET_NR_swapoff 225 +#define TARGET_NR_mprotect 226 +#define TARGET_NR_msync 227 +#define TARGET_NR_mlock 228 +#define TARGET_NR_munlock 229 +#define TARGET_NR_mlockall 230 +#define TARGET_NR_munlockall 231 +#define TARGET_NR_mincore 232 +#define TARGET_NR_madvise 233 +#define TARGET_NR_remap_file_pages 234 +#define TARGET_NR_mbind 235 +#define TARGET_NR_get_mempolicy 236 +#define TARGET_NR_set_mempolicy 237 +#define TARGET_NR_migrate_pages 238 +#define TARGET_NR_move_pages 239 +#define TARGET_NR_rt_tgsigqueueinfo 240 +#define TARGET_NR_perf_event_open 241 +#define TARGET_NR_accept4 242 +#define TARGET_NR_recvmmsg 243 +#define TARGET_NR_arch_specific_syscall 244 +#define TARGET_NR_wait4 260 +#define TARGET_NR_prlimit64 261 +#define TARGET_NR_fanotify_init 262 +#define TARGET_NR_fanotify_mark 263 +#define TARGET_NR_name_to_handle_at 264 +#define TARGET_NR_open_by_handle_at 265 +#define TARGET_NR_clock_adjtime 266 +#define TARGET_NR_syncfs 267 +#define TARGET_NR_setns 268 +#define TARGET_NR_sendmmsg 269 +#define TARGET_NR_process_vm_readv 270 +#define TARGET_NR_process_vm_writev 271 +#define TARGET_NR_kcmp 272 +#define TARGET_NR_finit_module 273 +#define TARGET_NR_sched_setattr 274 +#define TARGET_NR_sched_getattr 275 +#define TARGET_NR_renameat2 276 +#define TARGET_NR_seccomp 277 +#define TARGET_NR_getrandom 278 +#define TARGET_NR_memfd_create 279 +#define TARGET_NR_bpf 280 +#define TARGET_NR_execveat 281 +#define TARGET_NR_userfaultfd 282 +#define TARGET_NR_membarrier 283 +#define TARGET_NR_mlock2 284 +#define TARGET_NR_copy_file_range 285 +#define TARGET_NR_preadv2 286 +#define TARGET_NR_pwritev2 287 +#define TARGET_NR_pkey_mprotect 288 +#define TARGET_NR_pkey_alloc 289 +#define TARGET_NR_pkey_free 290 +#define TARGET_NR_statx 291 +#define TARGET_NR_io_pgetevents 292 +#define TARGET_NR_rseq 293 +#define TARGET_NR_kexec_file_load 294 +#define TARGET_NR_pidfd_send_signal 424 +#define TARGET_NR_io_uring_setup 425 +#define TARGET_NR_io_uring_enter 426 +#define TARGET_NR_io_uring_register 427 +#define TARGET_NR_open_tree 428 +#define TARGET_NR_move_mount 429 +#define TARGET_NR_fsopen 430 +#define TARGET_NR_fsconfig 431 +#define TARGET_NR_fsmount 432 +#define TARGET_NR_fspick 433 +#define TARGET_NR_pidfd_open 434 +#define TARGET_NR_clone3 435 +#define TARGET_NR_close_range 436 +#define TARGET_NR_openat2 437 +#define TARGET_NR_pidfd_getfd 438 +#define TARGET_NR_faccessat2 439 +#define TARGET_NR_process_madvise 440 +#define TARGET_NR_epoll_pwait2 441 +#define TARGET_NR_mount_setattr 442 +#define TARGET_NR_quotactl_fd 443 +#define TARGET_NR_landlock_create_ruleset 444 +#define TARGET_NR_landlock_add_rule 445 +#define TARGET_NR_landlock_restrict_self 446 +#define TARGET_NR_process_mrelease 448 +#define TARGET_NR_syscalls 449 + +#endif /* LINUX_USER_LOONGARCH_SYSCALL_NR_H */ diff --git a/linux-user/loongarch64/target_syscall.h b/linux-user/loongarch64/target_syscall.h new file mode 100644 index 0000000..b1d2a39 --- /dev/null +++ b/linux-user/loongarch64/target_syscall.h @@ -0,0 +1,45 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (c) 2021 Loongson Technology Corporation Limited + */ + +#ifndef LOONGARCH_TARGET_SYSCALL_H +#define LOONGARCH_TARGET_SYSCALL_H + +/* + * this struct defines the way the registers are stored on the + * stack during a system call. + */ + +struct target_pt_regs { + /* Saved main processor registers. */ + target_ulong regs[32]; + + /* Saved special registers. */ + target_ulong csr_crmd; + target_ulong csr_prmd; + target_ulong csr_euen; + target_ulong csr_ecfg; + target_ulong csr_estat; + target_ulong csr_era; + target_ulong csr_badvaddr; + target_ulong orig_a0; + target_ulong __last[0]; +}; + +#define UNAME_MACHINE "loongarch64" +#define UNAME_MINIMUM_RELEASE "5.16.0" + +#define TARGET_MINSIGSTKSZ 2048 +#define TARGET_MCL_CURRENT 1 +#define TARGET_MCL_FUTURE 2 +#define TARGET_MCL_ONFAULT 4 + +#define TARGET_FORCE_SHMLBA + +static inline abi_ulong target_shmlba(CPULoongArchState *env) +{ + return 0x40000; +} + +#endif diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h index a5ce487..bec125f 100644 --- a/linux-user/syscall_defs.h +++ b/linux-user/syscall_defs.h @@ -74,7 +74,7 @@ || defined(TARGET_M68K) || defined(TARGET_CRIS) \ || defined(TARGET_S390X) || defined(TARGET_OPENRISC) \ || defined(TARGET_NIOS2) || defined(TARGET_RISCV) \ - || defined(TARGET_XTENSA) + || defined(TARGET_XTENSA) || defined(TARGET_LOONGARCH64) #define TARGET_IOC_SIZEBITS 14 #define TARGET_IOC_DIRBITS 2 @@ -2129,7 +2129,8 @@ struct target_stat64 { abi_ulong __unused5; }; -#elif defined(TARGET_OPENRISC) || defined(TARGET_NIOS2) || defined(TARGET_RISCV) +#elif defined(TARGET_OPENRISC) || defined(TARGET_NIOS2) || \ + defined(TARGET_RISCV) || defined(TARGET_LOONGARCH64) /* These are the asm-generic versions of the stat and stat64 structures */ @@ -2157,7 +2158,7 @@ struct target_stat { unsigned int __unused5; }; -#if !defined(TARGET_RISCV64) +#if !defined(TARGET_RISCV64) && !defined(TARGET_LOONGARCH64) #define TARGET_HAS_STRUCT_STAT64 struct target_stat64 { uint64_t st_dev; @@ -2327,7 +2328,8 @@ struct target_statfs64 { }; #elif (defined(TARGET_PPC64) || defined(TARGET_X86_64) || \ defined(TARGET_SPARC64) || defined(TARGET_AARCH64) || \ - defined(TARGET_RISCV)) && !defined(TARGET_ABI32) + defined(TARGET_RISCV) || defined(TARGET_LOONGARCH64)) && \ + !defined(TARGET_ABI32) struct target_statfs { abi_long f_type; abi_long f_bsize; diff --git a/scripts/gensyscalls.sh b/scripts/gensyscalls.sh index 8fb450e..b69e193 100755 --- a/scripts/gensyscalls.sh +++ b/scripts/gensyscalls.sh @@ -99,4 +99,5 @@ generate_syscall_nr openrisc 32 "$output/linux-user/openrisc/syscall_nr.h" generate_syscall_nr riscv 32 "$output/linux-user/riscv/syscall32_nr.h" generate_syscall_nr riscv 64 "$output/linux-user/riscv/syscall64_nr.h" generate_syscall_nr hexagon 32 "$output/linux-user/hexagon/syscall_nr.h" +generate_syscall_nr loongarch 64 "$output/linux-user/loongarch64/syscall_nr.h" rm -fr "$TMP" From patchwork Fri Nov 19 06:13:26 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: gaosong X-Patchwork-Id: 1556932 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4HwS1m24nKz9sPf for ; Fri, 19 Nov 2021 17:49:00 +1100 (AEDT) Received: from localhost ([::1]:57212 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mnxhh-0000Z8-GO for incoming@patchwork.ozlabs.org; Fri, 19 Nov 2021 01:48:57 -0500 Received: from eggs.gnu.org ([209.51.188.92]:46572) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mnxA3-0004Kn-Is for qemu-devel@nongnu.org; Fri, 19 Nov 2021 01:14:12 -0500 Received: from mail.loongson.cn ([114.242.206.163]:46960 helo=loongson.cn) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mnxA1-0004aU-4m for qemu-devel@nongnu.org; Fri, 19 Nov 2021 01:14:11 -0500 Received: from kvm-dev1.localdomain (unknown [10.2.5.134]) by mail.loongson.cn (Coremail) with SMTP id AQAAf9Dxj8+KQJdhSG0AAA--.1952S24; Fri, 19 Nov 2021 14:13:56 +0800 (CST) From: Song Gao To: qemu-devel@nongnu.org Subject: [PATCH v11 22/26] linux-user: Add LoongArch cpu_loop support Date: Fri, 19 Nov 2021 14:13:26 +0800 Message-Id: <1637302410-24632-23-git-send-email-gaosong@loongson.cn> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1637302410-24632-1-git-send-email-gaosong@loongson.cn> References: <1637302410-24632-1-git-send-email-gaosong@loongson.cn> X-CM-TRANSID: AQAAf9Dxj8+KQJdhSG0AAA--.1952S24 X-Coremail-Antispam: 1UD129KBjvJXoWxXrWUGr17Kr4UXFyUtryrJFb_yoWruF1xpF 1fCr13Kr4kX3y2gws3J3s8uF15Zr4I9rZrGaySkFWrAay7Jry8ur1qgr9rtFy7C3yUWFyx ur9Iv3ZF9F45ZF7anT9S1TB71UUUUUUqnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnUUvcSsGvfC2KfnxnUUI43ZEXa7xR_UUUUUUUUU== X-CM-SenderInfo: 5jdr20tqj6z05rqj20fqof0/ Received-SPF: pass client-ip=114.242.206.163; envelope-from=gaosong@loongson.cn; helo=loongson.cn X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Xiaojuan Yang , richard.henderson@linaro.org, laurent@vivier.eu Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Signed-off-by: Song Gao Signed-off-by: Xiaojuan Yang Reviewed-by: Richard Henderson --- configure | 5 ++ linux-user/loongarch64/cpu_loop.c | 97 +++++++++++++++++++++++++++++++++++++ linux-user/loongarch64/target_cpu.h | 34 +++++++++++++ 3 files changed, 136 insertions(+) create mode 100644 linux-user/loongarch64/cpu_loop.c create mode 100644 linux-user/loongarch64/target_cpu.h diff --git a/configure b/configure index 48c2177..9df99f6 100755 --- a/configure +++ b/configure @@ -581,6 +581,8 @@ elif check_define __arm__ ; then cpu="arm" elif check_define __aarch64__ ; then cpu="aarch64" +elif check_define __loongarch64__ ; then + cpu="loongarch64" else cpu=$(uname -m) fi @@ -612,6 +614,9 @@ case "$cpu" in sparc|sun4[cdmuv]) cpu="sparc" ;; + loongarch) + cpu="loongarch" + ;; *) # This will result in either an error or falling back to TCI later ARCH=unknown diff --git a/linux-user/loongarch64/cpu_loop.c b/linux-user/loongarch64/cpu_loop.c new file mode 100644 index 0000000..f211304 --- /dev/null +++ b/linux-user/loongarch64/cpu_loop.c @@ -0,0 +1,97 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * QEMU LoongArch user cpu_loop. + * + * Copyright (c) 2021 Loongson Technology Corporation Limited + */ + +#include "qemu/osdep.h" +#include "qemu.h" +#include "qemu-common.h" +#include "user-internals.h" +#include "cpu_loop-common.h" +#include "signal-common.h" + +void cpu_loop(CPULoongArchState *env) +{ + CPUState *cs = env_cpu(env); + int trapnr, si_code; + abi_long ret; + + for (;;) { + cpu_exec_start(cs); + trapnr = cpu_exec(cs); + cpu_exec_end(cs); + process_queued_cpu_work(cs); + + switch (trapnr) { + case EXCP_INTERRUPT: + /* just indicate that signals should be handled asap */ + break; + case EXCP_SYSCALL: + env->pc += 4; + ret = do_syscall(env, env->gpr[11], + env->gpr[4], env->gpr[5], + env->gpr[6], env->gpr[7], + env->gpr[8], env->gpr[9], + -1, -1); + if (ret == -TARGET_ERESTARTSYS) { + env->pc -= 4; + break; + } + if (ret == -TARGET_QEMU_ESIGRETURN) { + /* + * Returning from a successful sigreturn syscall. + * Avoid clobbering register state. + */ + break; + } + env->gpr[4] = ret; + break; + case EXCP_ADE: + force_sig_fault(TARGET_SIGSEGV, TARGET_SEGV_MAPERR, env->badaddr); + break; + case EXCP_INE: + force_sig_fault(TARGET_SIGILL, 0, env->pc); + break; + case EXCP_FPE: + si_code = TARGET_FPE_FLTUNK; + if (GET_FP_CAUSE(env->fcsr0) & FP_INVALID) { + si_code = TARGET_FPE_FLTINV; + } else if (GET_FP_CAUSE(env->fcsr0) & FP_DIV0) { + si_code = TARGET_FPE_FLTDIV; + } else if (GET_FP_CAUSE(env->fcsr0) & FP_OVERFLOW) { + si_code = TARGET_FPE_FLTOVF; + } else if (GET_FP_CAUSE(env->fcsr0) & FP_UNDERFLOW) { + si_code = TARGET_FPE_FLTUND; + } else if (GET_FP_CAUSE(env->fcsr0) & FP_INEXACT) { + si_code = TARGET_FPE_FLTRES; + } + force_sig_fault(TARGET_SIGFPE, si_code, env->pc); + break; + case EXCP_DEBUG: + case EXCP_BREAK: + force_sig_fault(TARGET_SIGTRAP, TARGET_TRAP_BRKPT, env->pc); + break; + case EXCP_ATOMIC: + cpu_exec_step_atomic(cs); + break; + default: + EXCP_DUMP(env, "qemu: unhandled CPU exception 0x%x - aborting\n", + trapnr); + exit(EXIT_FAILURE); + } + process_pending_signals(env); + } +} + +void target_cpu_copy_regs(CPUArchState *env, struct target_pt_regs *regs) +{ + int i; + + for (i = 0; i < 32; i++) { + env->gpr[i] = regs->regs[i]; + } + env->pc = regs->csr_era; + +} diff --git a/linux-user/loongarch64/target_cpu.h b/linux-user/loongarch64/target_cpu.h new file mode 100644 index 0000000..a29af66 --- /dev/null +++ b/linux-user/loongarch64/target_cpu.h @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * LoongArch specific CPU ABI and functions for linux-user + * + * Copyright (c) 2021 Loongson Technology Corporation Limited + */ + +#ifndef LOONGARCH_TARGET_CPU_H +#define LOONGARCH_TARGET_CPU_H + +static inline void cpu_clone_regs_child(CPULoongArchState *env, + target_ulong newsp, unsigned flags) +{ + if (newsp) { + env->gpr[3] = newsp; + } + env->gpr[4] = 0; +} + +static inline void cpu_clone_regs_parent(CPULoongArchState *env, + unsigned flags) +{ +} + +static inline void cpu_set_tls(CPULoongArchState *env, target_ulong newtls) +{ + env->gpr[2] = newtls; +} + +static inline abi_ulong get_sp_from_cpustate(CPULoongArchState *state) +{ + return state->gpr[3]; +} +#endif From patchwork Fri Nov 19 06:13:27 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: gaosong X-Patchwork-Id: 1556938 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4HwSKW00Vhz9sRN for ; Fri, 19 Nov 2021 18:02:37 +1100 (AEDT) Received: from localhost ([::1]:52932 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mnxur-0000J4-Fr for incoming@patchwork.ozlabs.org; Fri, 19 Nov 2021 02:02:33 -0500 Received: from eggs.gnu.org ([209.51.188.92]:48242) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mnxHk-00042j-Ik for qemu-devel@nongnu.org; Fri, 19 Nov 2021 01:22:11 -0500 Received: from mail.loongson.cn ([114.242.206.163]:49382 helo=loongson.cn) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mnxHf-0006BS-G7 for qemu-devel@nongnu.org; Fri, 19 Nov 2021 01:22:08 -0500 Received: from kvm-dev1.localdomain (unknown [10.2.5.134]) by mail.loongson.cn (Coremail) with SMTP id AQAAf9Dxj8+KQJdhSG0AAA--.1952S25; Fri, 19 Nov 2021 14:13:57 +0800 (CST) From: Song Gao To: qemu-devel@nongnu.org Subject: [PATCH v11 23/26] default-configs: Add loongarch linux-user support Date: Fri, 19 Nov 2021 14:13:27 +0800 Message-Id: <1637302410-24632-24-git-send-email-gaosong@loongson.cn> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1637302410-24632-1-git-send-email-gaosong@loongson.cn> References: <1637302410-24632-1-git-send-email-gaosong@loongson.cn> X-CM-TRANSID: AQAAf9Dxj8+KQJdhSG0AAA--.1952S25 X-Coremail-Antispam: 1UD129KBjvdXoWrZry3Cw13tryUtFWxtw48Xrb_yoW3Crg_uF y3Jr4kKFWUZryUCw10v3y5Ar4ru3W8AF1ruF4DKw4xXwsFqr43t34vva18Za4ay393urnx XrWkJr15Cr10qjkaLaAFLSUrUUUUUb8apTn2vfkv8UJUUUU8Yxn0WfASr-VFAUDa7-sFnT 9fnUUIcSsGvfJ3UbIYCTnIWIevJa73UjIFyTuYvj4RJUUUUUUUU X-CM-SenderInfo: 5jdr20tqj6z05rqj20fqof0/ Received-SPF: pass client-ip=114.242.206.163; envelope-from=gaosong@loongson.cn; helo=loongson.cn X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Xiaojuan Yang , richard.henderson@linaro.org, laurent@vivier.eu Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" This patch adds loongarch64 linux-user default configs file. Signed-off-by: Song Gao Signed-off-by: Xiaojuan Yang Reviewed-by: Richard Henderson --- configs/targets/loongarch64-linux-user.mak | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 configs/targets/loongarch64-linux-user.mak diff --git a/configs/targets/loongarch64-linux-user.mak b/configs/targets/loongarch64-linux-user.mak new file mode 100644 index 0000000..5b0acfa --- /dev/null +++ b/configs/targets/loongarch64-linux-user.mak @@ -0,0 +1,3 @@ +# Default configuration for loongson64-linux-user +TARGET_ARCH=loongarch64 +TARGET_BASE_ARCH=loongarch From patchwork Fri Nov 19 06:13:28 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: gaosong X-Patchwork-Id: 1556934 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4HwS6r42TJz9sPf for ; Fri, 19 Nov 2021 17:53:24 +1100 (AEDT) Received: from localhost ([::1]:36450 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mnxlx-0005t5-Mu for incoming@patchwork.ozlabs.org; Fri, 19 Nov 2021 01:53:21 -0500 Received: from eggs.gnu.org ([209.51.188.92]:46584) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mnxA4-0004M7-L6 for qemu-devel@nongnu.org; Fri, 19 Nov 2021 01:14:12 -0500 Received: from mail.loongson.cn ([114.242.206.163]:47002 helo=loongson.cn) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mnxA1-0004ac-Rd for qemu-devel@nongnu.org; Fri, 19 Nov 2021 01:14:12 -0500 Received: from kvm-dev1.localdomain (unknown [10.2.5.134]) by mail.loongson.cn (Coremail) with SMTP id AQAAf9Dxj8+KQJdhSG0AAA--.1952S26; Fri, 19 Nov 2021 14:13:57 +0800 (CST) From: Song Gao To: qemu-devel@nongnu.org Subject: [PATCH v11 24/26] target/loongarch: Add target build suport Date: Fri, 19 Nov 2021 14:13:28 +0800 Message-Id: <1637302410-24632-25-git-send-email-gaosong@loongson.cn> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1637302410-24632-1-git-send-email-gaosong@loongson.cn> References: <1637302410-24632-1-git-send-email-gaosong@loongson.cn> X-CM-TRANSID: AQAAf9Dxj8+KQJdhSG0AAA--.1952S26 X-Coremail-Antispam: 1UD129KBjvJXoW7Zw4xCw4fGw1fKrWDAFWDJwb_yoW8ZrWkp3 y7Aw15KFW8XF93J3s3Ja4FqFZ5Jw1DGw47XanxKrWxCrZxtay8Zw1rKFZ8GF17X3W0kFyF gFn3C34rWF48Ja7anT9S1TB71UUUUUUqnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnUUvcSsGvfC2KfnxnUUI43ZEXa7xR_UUUUUUUUU== X-CM-SenderInfo: 5jdr20tqj6z05rqj20fqof0/ Received-SPF: pass client-ip=114.242.206.163; envelope-from=gaosong@loongson.cn; helo=loongson.cn X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Xiaojuan Yang , richard.henderson@linaro.org, laurent@vivier.eu Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" This patch adds build loongarch-linux-user target support. Signed-off-by: Song Gao Signed-off-by: Xiaojuan Yang Reviewed-by: Richard Henderson --- meson.build | 2 +- target/loongarch/meson.build | 19 +++++++++++++++++++ target/meson.build | 1 + 3 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 target/loongarch/meson.build diff --git a/meson.build b/meson.build index d03fec6..7ba3aeb 100644 --- a/meson.build +++ b/meson.build @@ -56,7 +56,7 @@ python = import('python').find_installation() supported_oses = ['windows', 'freebsd', 'netbsd', 'openbsd', 'darwin', 'sunos', 'linux'] supported_cpus = ['ppc', 'ppc64', 's390x', 'riscv', 'x86', 'x86_64', - 'arm', 'aarch64', 'mips', 'mips64', 'sparc', 'sparc64'] + 'arm', 'aarch64', 'mips', 'mips64', 'sparc', 'sparc64', 'loongarch64'] cpu = host_machine.cpu_family() diff --git a/target/loongarch/meson.build b/target/loongarch/meson.build new file mode 100644 index 0000000..bcb076e --- /dev/null +++ b/target/loongarch/meson.build @@ -0,0 +1,19 @@ +gen = decodetree.process('insns.decode') + +loongarch_ss = ss.source_set() +loongarch_ss.add(files( + 'cpu.c', + 'disas.c', +)) +loongarch_tcg_ss = ss.source_set() +loongarch_tcg_ss.add(gen) +loongarch_tcg_ss.add(files( + 'fpu_helper.c', + 'op_helper.c', + 'translate.c', +)) +loongarch_tcg_ss.add(zlib) + +loongarch_ss.add_all(when: 'CONFIG_TCG', if_true: [loongarch_tcg_ss]) + +target_arch += {'loongarch': loongarch_ss} diff --git a/target/meson.build b/target/meson.build index 2f69402..a53a604 100644 --- a/target/meson.build +++ b/target/meson.build @@ -5,6 +5,7 @@ subdir('cris') subdir('hexagon') subdir('hppa') subdir('i386') +subdir('loongarch') subdir('m68k') subdir('microblaze') subdir('mips') From patchwork Fri Nov 19 06:13:29 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: gaosong X-Patchwork-Id: 1556935 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4HwS6z0RmFz9sPf for ; Fri, 19 Nov 2021 17:53:31 +1100 (AEDT) Received: from localhost ([::1]:36938 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mnxm4-0006Dc-JS for incoming@patchwork.ozlabs.org; Fri, 19 Nov 2021 01:53:28 -0500 Received: from eggs.gnu.org ([209.51.188.92]:46616) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mnxA8-0004VT-Iv for qemu-devel@nongnu.org; Fri, 19 Nov 2021 01:14:16 -0500 Received: from mail.loongson.cn ([114.242.206.163]:47026 helo=loongson.cn) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mnxA5-0004aq-St for qemu-devel@nongnu.org; Fri, 19 Nov 2021 01:14:16 -0500 Received: from kvm-dev1.localdomain (unknown [10.2.5.134]) by mail.loongson.cn (Coremail) with SMTP id AQAAf9Dxj8+KQJdhSG0AAA--.1952S27; Fri, 19 Nov 2021 14:13:57 +0800 (CST) From: Song Gao To: qemu-devel@nongnu.org Subject: [PATCH v11 25/26] target/loongarch: 'make check-tcg' support Date: Fri, 19 Nov 2021 14:13:29 +0800 Message-Id: <1637302410-24632-26-git-send-email-gaosong@loongson.cn> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1637302410-24632-1-git-send-email-gaosong@loongson.cn> References: <1637302410-24632-1-git-send-email-gaosong@loongson.cn> MIME-Version: 1.0 X-CM-TRANSID: AQAAf9Dxj8+KQJdhSG0AAA--.1952S27 X-Coremail-Antispam: 1UD129KBjvdXoWrZry3Cw13trW5KFWkJF43ZFb_yoWfXrc_A3 WSkr1kCF4YyF1xGr1rWFs5Gr1rW3y2vFyagF1DAw1fX39Fvan8ta1xAFsrXF15Zw45ZrnI qa97Aw4I9w18AjkaLaAFLSUrUUUUUb8apTn2vfkv8UJUUUU8Yxn0WfASr-VFAUDa7-sFnT 9fnUUIcSsGvfJ3UbIYCTnIWIevJa73UjIFyTuYvj4RJUUUUUUUU X-CM-SenderInfo: 5jdr20tqj6z05rqj20fqof0/ Received-SPF: pass client-ip=114.242.206.163; envelope-from=gaosong@loongson.cn; helo=loongson.cn X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Xiaojuan Yang , richard.henderson@linaro.org, laurent@vivier.eu Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Signed-off-by: Song Gao Signed-off-by: Xiaojuan Yang Reviewed-by: Richard Henderson Acked-by: Alex Bennée --- tests/tcg/configure.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/tcg/configure.sh b/tests/tcg/configure.sh index 9b76f58..49a05ec 100755 --- a/tests/tcg/configure.sh +++ b/tests/tcg/configure.sh @@ -51,6 +51,7 @@ fi : ${cross_cc_cflags_armeb="-mbig-endian"} : ${cross_cc_hexagon="hexagon-unknown-linux-musl-clang"} : ${cross_cc_cflags_hexagon="-mv67 -O2 -static"} +: ${cross_cc_loongarch64="loongarch64-unknown-linux-gnu-gcc"} : ${cross_cc_hppa="hppa-linux-gnu-gcc"} : ${cross_cc_i386="i686-linux-gnu-gcc"} : ${cross_cc_cflags_i386="-m32"} From patchwork Fri Nov 19 06:13:30 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: gaosong X-Patchwork-Id: 1556937 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4HwSCB1bSXz9s1l for ; Fri, 19 Nov 2021 17:57:10 +1100 (AEDT) Received: from localhost ([::1]:45364 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mnxpb-0003Vd-UH for incoming@patchwork.ozlabs.org; Fri, 19 Nov 2021 01:57:08 -0500 Received: from eggs.gnu.org ([209.51.188.92]:48214) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mnxHi-00042b-6v for qemu-devel@nongnu.org; Fri, 19 Nov 2021 01:22:08 -0500 Received: from mail.loongson.cn ([114.242.206.163]:49386 helo=loongson.cn) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mnxHf-0006BU-F5 for qemu-devel@nongnu.org; Fri, 19 Nov 2021 01:22:05 -0500 Received: from kvm-dev1.localdomain (unknown [10.2.5.134]) by mail.loongson.cn (Coremail) with SMTP id AQAAf9Dxj8+KQJdhSG0AAA--.1952S28; Fri, 19 Nov 2021 14:13:59 +0800 (CST) From: Song Gao To: qemu-devel@nongnu.org Subject: [PATCH v11 26/26] scripts: add loongarch64 binfmt config Date: Fri, 19 Nov 2021 14:13:30 +0800 Message-Id: <1637302410-24632-27-git-send-email-gaosong@loongson.cn> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1637302410-24632-1-git-send-email-gaosong@loongson.cn> References: <1637302410-24632-1-git-send-email-gaosong@loongson.cn> X-CM-TRANSID: AQAAf9Dxj8+KQJdhSG0AAA--.1952S28 X-Coremail-Antispam: 1UD129KBjvJXoW7Zw4xCw4fGw47uw48uFWfXwb_yoW8WF4Dpr 15A3W8CF4jg3WUA3WkXw13Gr1DJr1Ykas7Xr43tr1UAF15tw1rZr1fJr18J3WDJF4UJF1j 9F95Ja1DJF4IkF7anT9S1TB71UUUUUUqnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnUUvcSsGvfC2KfnxnUUI43ZEXa7xR_UUUUUUUUU== X-CM-SenderInfo: 5jdr20tqj6z05rqj20fqof0/ Received-SPF: pass client-ip=114.242.206.163; envelope-from=gaosong@loongson.cn; helo=loongson.cn X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Xiaojuan Yang , richard.henderson@linaro.org, laurent@vivier.eu Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Signed-off-by: Song Gao Signed-off-by: Xiaojuan Yang Reviewed-by: Richard Henderson --- scripts/qemu-binfmt-conf.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/scripts/qemu-binfmt-conf.sh b/scripts/qemu-binfmt-conf.sh index 7de996d..da6a937 100755 --- a/scripts/qemu-binfmt-conf.sh +++ b/scripts/qemu-binfmt-conf.sh @@ -4,7 +4,7 @@ qemu_target_list="i386 i486 alpha arm armeb sparc sparc32plus sparc64 \ ppc ppc64 ppc64le m68k mips mipsel mipsn32 mipsn32el mips64 mips64el \ sh4 sh4eb s390x aarch64 aarch64_be hppa riscv32 riscv64 xtensa xtensaeb \ -microblaze microblazeel or1k x86_64 hexagon" +microblaze microblazeel or1k x86_64 hexagon loongarch64" i386_magic='\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x03\x00' i386_mask='\xff\xff\xff\xff\xff\xfe\xfe\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff' @@ -140,6 +140,10 @@ hexagon_magic='\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x hexagon_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff' hexagon_family=hexagon +loongarch64_magic='\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x02\x01' +loongarch64_mask='\xff\xff\xff\xff\xff\xff\xff\xfc\x00\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff' +loongarch64_family=loongarch + qemu_get_family() { cpu=${HOST_ARCH:-$(uname -m)} case "$cpu" in