From patchwork Mon Feb 26 14:22:24 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bhushan Attarde X-Patchwork-Id: 86379 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 16CED38582AC for ; Mon, 26 Feb 2024 14:23:49 +0000 (GMT) X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from mx08-00376f01.pphosted.com (mx08-00376f01.pphosted.com [91.207.212.86]) by sourceware.org (Postfix) with ESMTPS id EBB693858C55 for ; Mon, 26 Feb 2024 14:23:01 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org EBB693858C55 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=imgtec.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=imgtec.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org EBB693858C55 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=91.207.212.86 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1708957386; cv=none; b=ShzMUn6Ogb/9Xa1Rz41Lk8Ki2l9qZ40rNOd1d+MCHZjZ3JLZxT71Lp5xkV+cN1NPa6EQsLEA5rQj9x0lGj8j1G51WufErAawoxOh3ecwubLbdXygkSLEdIuEYTcyyODUXTeH9U4cTMfHTYAe56Sew5GFTmiWMX9/eIbV47lFncw= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1708957386; c=relaxed/simple; bh=5E/UTWrOZZP2dvQnbfFMmID1S1ebiRK+R+FzKg2fYmc=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=wW565lugU4v8+I2IFbuQ/WNb1cAijnBEl3PFNPoZ5O6pym19BRTteJnO5EVmDCGzTXeS6yYlFOH0PyV0O4sHxPpgMykAu4lNTa7yiT2VD/zmZL2V+DjGd+LVsI8pkoRdmM8rK7O2AKyHVUa3ZWLQsTaCi58pR5wyApz8dx8WuI8= ARC-Authentication-Results: i=1; server2.sourceware.org Received: from pps.filterd (m0168888.ppops.net [127.0.0.1]) by mx08-00376f01.pphosted.com (8.17.1.24/8.17.1.24) with ESMTP id 41Q8CPdI013671; Mon, 26 Feb 2024 14:22:50 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=imgtec.com; h= from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding:content-type; s= dk201812; bh=N/FcUTpJ098zIX9GuyoR99MMDIecEv9slbxJGY8GhIM=; b=mzU zyk/uQgcpyvcQU6IwcSE8wQwU3KQljREl5BHJzCnZQTBO7u6Z9Oilh91lbGcr992 FyLa5UmwSu3JiDPe8Q/zW2eLG6SanwXpl+HRxYerpD2ege/MeWGf2QaVCdwqFtGd SqCIfx5csylPrRCDqn7HOFr30oS57vOc/MlqalAHjZvaE1imf2/1zpowq1I6nvCf +3nU5fFYQ+9BmoTbaVZIJXWAlAznNGeS+fjVPO6c4+/A2oIWdWIAqcOS/nPsG2Wv sWu+t1Csu4AOT4kH/z4prAK4F7Ujg2lgsaQLxz1yz5ItYe0bd0iEgwc6NXv7Jwxt rANnyanpHNG1JGUsfkA== Received: from hhmail05.hh.imgtec.org ([217.156.249.195]) by mx08-00376f01.pphosted.com (PPS) with ESMTPS id 3wf7kssr3e-2 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Mon, 26 Feb 2024 14:22:50 +0000 (GMT) Received: from hhbattarde.hh.imgtec.org (10.100.136.78) by HHMAIL05.hh.imgtec.org (10.100.10.120) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.35; Mon, 26 Feb 2024 14:22:48 +0000 From: To: CC: , , , Bhushan Attarde Subject: [PATCH 01/11] sim: riscv: Add single precision floating-point load-store, move, compare and classify instructions Date: Mon, 26 Feb 2024 14:22:24 +0000 Message-ID: <20240226142234.1628932-2-bhushan.attarde@imgtec.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20240226142234.1628932-1-bhushan.attarde@imgtec.com> References: <20240226142234.1628932-1-bhushan.attarde@imgtec.com> MIME-Version: 1.0 X-Originating-IP: [10.100.136.78] X-ClientProxiedBy: HHMAIL05.hh.imgtec.org (10.100.10.120) To HHMAIL05.hh.imgtec.org (10.100.10.120) X-EXCLAIMER-MD-CONFIG: 15a78312-3e47-46eb-9010-2e54d84a9631 X-Proofpoint-GUID: 3D-hVF74KzcPSJaA0OjEv_AvCqd7ESRz X-Proofpoint-ORIG-GUID: 3D-hVF74KzcPSJaA0OjEv_AvCqd7ESRz X-Spam-Status: No, score=-12.8 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_LOW, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org From: Bhushan Attarde Added simulation of following single precision floating-point instructions flw, fsw, fmv.x.w, fmv.w.x, fsgnj.s, feq.s, flt.s, fle.s and fclass.s. Added test files s-fp-compare.s, s-fp-load-store.s and s-fp-sign-inject.s in sim/testsuite/riscv/ to test these instructions. --- sim/riscv/model_list.def | 4 + sim/riscv/sim-main.c | 214 +++++++++++++++++++++++++ sim/testsuite/riscv/s-fp-compare.s | 75 +++++++++ sim/testsuite/riscv/s-fp-load-store.s | 62 +++++++ sim/testsuite/riscv/s-fp-sign-inject.s | 52 ++++++ 5 files changed, 407 insertions(+) create mode 100644 sim/testsuite/riscv/s-fp-compare.s create mode 100644 sim/testsuite/riscv/s-fp-load-store.s create mode 100644 sim/testsuite/riscv/s-fp-sign-inject.s diff --git a/sim/riscv/model_list.def b/sim/riscv/model_list.def index b83557e5539..265b1714faf 100644 --- a/sim/riscv/model_list.def +++ b/sim/riscv/model_list.def @@ -5,6 +5,8 @@ M(IMA) M(IA) M(GC) M(IC) +M(IF) +M(ID) M(IMC) M(IMAC) M(IAC) @@ -13,6 +15,8 @@ M(EM) M(EMA) M(EA) M(EC) +M(EF) +M(ED) M(EMC) M(EMAC) M(EAC) diff --git a/sim/riscv/sim-main.c b/sim/riscv/sim-main.c index adff99921c6..d3a07585944 100644 --- a/sim/riscv/sim-main.c +++ b/sim/riscv/sim-main.c @@ -24,6 +24,7 @@ /* This must come before any other includes. */ #include "defs.h" +#include #include #include @@ -64,6 +65,17 @@ static const struct riscv_opcode *riscv_hash[OP_MASK_OP + 1]; } \ } while (0) +#define FCSR_NX 0x1 /* Inexact. */ +#define FCSR_UF 0x2 /* Underflow. */ +#define FCSR_OF 0x4 /* Overflow. */ +#define FCSR_DZ 0x8 /* Divide by zero. */ +#define FCSR_NV 0x10 /* Invalid Operation. */ + +#define FEQ 1 +#define FLT 2 +#define FLE 3 +#define FCLASS 4 + static INLINE void store_rd (SIM_CPU *cpu, int rd, unsigned_word val) { @@ -76,6 +88,16 @@ store_rd (SIM_CPU *cpu, int rd, unsigned_word val) } } +/* Store a value into floating point register. */ +static INLINE void +store_fp (SIM_CPU *cpu, int rd, unsigned_word val) +{ + struct riscv_sim_cpu *riscv_cpu = RISCV_SIM_CPU (cpu); + + riscv_cpu->fpregs[rd] = val; + TRACE_REG (cpu, rd); +} + static INLINE unsigned_word fetch_csr (SIM_CPU *cpu, const char *name, int csr, unsigned_word *reg) { @@ -682,6 +704,195 @@ mulhsu (int64_t a, uint64_t b) return negate ? ~res + (a * b == 0) : res; } +/* Handle single precision floating point compare instructions. */ +static void +float32_compare (SIM_CPU *cpu, int rd, int rs1, int rs2, int flags) +{ + struct riscv_sim_cpu *riscv_cpu = RISCV_SIM_CPU (cpu); + float a, b = .0f; + uint32_t result = 0, exception = 0, sign = 0, bit_pos; + uint32_t rs1_bits, rs2_bits; + const char *rd_name = riscv_gpr_names_abi[rd]; + const char *frs1_name = riscv_fpr_names_abi[rs1]; + const char *frs2_name = riscv_fpr_names_abi[rs2]; + + rs1_bits = (uint32_t) riscv_cpu->fpregs[rs1]; + memcpy (&a, &rs1_bits, sizeof (a)); + + if (flags != FCLASS) + { + rs2_bits = (uint32_t) riscv_cpu->fpregs[rs2]; + memcpy (&b, &rs2_bits, sizeof (b)); + } + + switch (flags) + { + case FEQ: + TRACE_INSN (cpu, "feq.s %s, %s, %s;", rd_name, frs1_name, frs2_name); + if (__isnanf (a) || __isnanf (b)) + { + result = 0; + if (__issignalingf (a) || __issignalingf (b)) + exception = 1; + } + else + result = (a == b); + break; + case FLT: + TRACE_INSN (cpu, "flt.s %s, %s, %s;", rd_name, frs1_name, frs2_name); + if (__isnanf (a) || __isnanf (b)) + { + result = 0; + exception = 1; + } + else + result = (a < b); + break; + case FLE: + TRACE_INSN (cpu, "fle.s %s, %s, %s;", rd_name, frs1_name, frs2_name); + if (__isnanf (a) || __isnanf (b)) + { + result = 0; + exception = 1; + } + else + result = (a <= b); + break; + case FCLASS: + TRACE_INSN (cpu, "fclass.s %s, %s;", rd_name, frs1_name); + bit_pos = 0; + exception = 0; + result = riscv_cpu->regs[rd]; + sign = __signbitf (a); + if (__isinff (a)) + { + if (sign) + bit_pos = 0; /* -INF. */ + else + bit_pos = 7; /* +INF. */ + } + else if (fpclassify (a) == FP_SUBNORMAL) + { + if (sign) + bit_pos = 2; /* -SUBNORMAL. */ + else + bit_pos = 5; /* +SUBNORMAL. */ + } + else if (fpclassify (a) == FP_ZERO) + { + if (sign) + bit_pos = 3; /* -ZERO. */ + else + bit_pos = 4; /* +ZERO. */ + } + else if (__issignalingf (a)) + bit_pos = 8; /* signaling NaN. */ + else if (__isnanf (a)) + bit_pos = 9; /* quiet NaN. */ + else + { + if (sign) + bit_pos = 1; /* -NORMAL. */ + else + bit_pos = 6; /* +NORMAL. */ + } + result |= (1 << bit_pos); + break; + } + + store_rd (cpu, rd, result); + + if (exception) + { + riscv_cpu->csr.fcsr |= FCSR_NV; + riscv_cpu->csr.fflags |= FCSR_NV; + TRACE_REGISTER (cpu, "wrote CSR fcsr |= NV"); + } +} + +/* Simulate single precision floating point instructions. */ +static sim_cia +execute_f (SIM_CPU *cpu, unsigned_word iw, const struct riscv_opcode *op) +{ + struct riscv_sim_cpu *riscv_cpu = RISCV_SIM_CPU (cpu); + SIM_DESC sd = CPU_STATE (cpu); + int rd = (iw >> OP_SH_RD) & OP_MASK_RD; + int rs1 = (iw >> OP_SH_RS1) & OP_MASK_RS1; + int rs2 = (iw >> OP_SH_RS2) & OP_MASK_RS2; + const char *frd_name = riscv_fpr_names_abi[rd]; + const char *rd_name = riscv_gpr_names_abi[rd]; + const char *frs1_name = riscv_fpr_names_abi[rs1]; + const char *frs2_name = riscv_fpr_names_abi[rs2]; + const char *rs1_name = riscv_gpr_names_abi[rs1]; + signed_word i_imm = EXTRACT_ITYPE_IMM (iw); + signed_word s_imm = EXTRACT_STYPE_IMM (iw); + int is_32bit = (RISCV_XLEN (cpu) == 32); + + sim_cia pc = riscv_cpu->pc + 4; + + switch (op->match) + { + case MATCH_FLW: + TRACE_INSN (cpu, "flw %s, %" PRIiTW "(%s);", + frd_name, i_imm, rs1_name); + store_fp (cpu, rd, sim_core_read_unaligned_4 (cpu, riscv_cpu->pc, + read_map, riscv_cpu->regs[rs1] + i_imm)); + break; + case MATCH_FSW: + TRACE_INSN (cpu, "fsw %s, %" PRIiTW "(%s);", + frs2_name, s_imm, rs1_name); + sim_core_write_unaligned_4 (cpu, riscv_cpu->pc, write_map, + riscv_cpu->regs[rs1] + s_imm, + riscv_cpu->fpregs[rs2]); + break; + case MATCH_FMV_X_S: + TRACE_INSN (cpu, "fmv.x.w %s, %s;", rd_name, frs1_name); + if (is_32bit) + store_rd (cpu, rd, riscv_cpu->fpregs[rs1]); + else + { + uint64_t f64bits; + f64bits = (uint64_t) ((uint32_t) riscv_cpu->fpregs[rs1]); + if (f64bits & 0x80000000) + f64bits = (uint64_t) (0xffffffff00000000ull | (uint32_t) f64bits); + store_rd (cpu, rd, f64bits); + } + break; + case MATCH_FMV_S_X: + TRACE_INSN (cpu, "fmv.w.x %s, %s;", frd_name, rs1_name); + store_fp (cpu, rd, riscv_cpu->regs[rs1]); + break; + case MATCH_FSGNJ_S: + { + uint32_t rs1_bits, rs2_bits; + TRACE_INSN (cpu, "fsgnj.s %s, %s, %s;", + frd_name, frs1_name, frs2_name); + rs1_bits = (uint32_t) riscv_cpu->fpregs[rs1]; + rs2_bits = (uint32_t) riscv_cpu->fpregs[rs2]; + rs1_bits = (rs2_bits & 0x80000000) | (rs1_bits & 0x7fffffff); + store_fp (cpu, rd, rs1_bits); + break; + } + case MATCH_FEQ_S: + float32_compare (cpu, rd, rs1, rs2, FEQ); + break; + case MATCH_FLT_S: + float32_compare (cpu, rd, rs1, rs2, FLT); + break; + case MATCH_FLE_S: + float32_compare (cpu, rd, rs1, rs2, FLE); + break; + case MATCH_FCLASS_S: + float32_compare (cpu, rd, rs1, 0, FCLASS); + break; + default: + TRACE_INSN (cpu, "UNHANDLED INSN: %s", op->name); + sim_engine_halt (sd, cpu, NULL, riscv_cpu->pc, sim_signalled, SIM_SIGILL); + } + + return pc; +} + static sim_cia execute_m (SIM_CPU *cpu, unsigned_word iw, const struct riscv_opcode *op) { @@ -1313,6 +1524,9 @@ execute_one (SIM_CPU *cpu, unsigned_word iw, const struct riscv_opcode *op) sim_engine_halt (sd, cpu, NULL, riscv_cpu->pc, sim_signalled, SIM_SIGILL); } + case INSN_CLASS_F: + case INSN_CLASS_F_INX: + return execute_f (cpu, iw, op); case INSN_CLASS_I: return execute_i (cpu, iw, op); case INSN_CLASS_M: diff --git a/sim/testsuite/riscv/s-fp-compare.s b/sim/testsuite/riscv/s-fp-compare.s new file mode 100644 index 00000000000..d5b98b30233 --- /dev/null +++ b/sim/testsuite/riscv/s-fp-compare.s @@ -0,0 +1,75 @@ +# Single precision compare and classify tests. +# mach: riscv32 riscv64 +# sim(riscv32): --model RV32IF +# sim(riscv64): --model RV64ID +# ld(riscv32): -m elf32lriscv +# ld(riscv64): -m elf64lriscv +# as(riscv32): -march=rv32if +# as(riscv64): -march=rv64id + +.include "testutils.inc" + + .section .data + .align 2 + +_arg1: + .float 0.5 + .float 1.1 + .word 0xff800000 # -INF + .word 0x7faaaaaa # sNAN + .word 0x7feaaaaa # qNAN + +_arg2: + .float 0.5 + .float 2.2 + + start + .option push + .option norelax + la a0,_arg1 + la a1,_arg2 + li a3,1 + .option pop + + # Test feq instruction. + flw fa0,0(a0) + flw fa1,0(a1) + feq.s a4,fa0,fa1 + bne a4,a3,test_fail + + # Test flt instruction. + flw fa0,4(a0) + flw fa1,4(a1) + mv a4,x0 + flt.s a4,fa0,fa1 + bne a4,a3,test_fail + + # Test fle instruction. + flw fa0,4(a0) + flw fa1,4(a1) + mv a4,x0 + fle.s a4,fa0,fa1 + bne a4,a3,test_fail + + # Test fclass instruction. + flw fa0,8(a0) + mv a4,x0 + li a3,0x1 # 1 << 0 + fclass.s a4,fa0 + bne a3,a4,test_fail + flw fa0,12(a0) + mv a4,x0 + li a3,0x100 # 1 << 8 + fclass.s a4,fa0 + bne a3,a4,test_fail + flw fa0,16(a0) + mv a4,x0 + li a3,0x200 # 1 << 9 + fclass.s a4,fa0 + bne a3,a4,test_fail + +test_pass: + pass + +test_fail: + fail diff --git a/sim/testsuite/riscv/s-fp-load-store.s b/sim/testsuite/riscv/s-fp-load-store.s new file mode 100644 index 00000000000..0a979d10e70 --- /dev/null +++ b/sim/testsuite/riscv/s-fp-load-store.s @@ -0,0 +1,62 @@ +# Single precision load-store and move tests. +# mach: riscv32 riscv64 +# sim(riscv32): --model RV32IF +# sim(riscv64): --model RV64ID +# ld(riscv32): -m elf32lriscv +# ld(riscv64): -m elf64lriscv +# as(riscv32): -march=rv32if +# as(riscv64): -march=rv64id + +.include "testutils.inc" + + .section .data + .align 2 + +_src: + .float 0.5 + +_dst: + .float 0.5 + .float 0 + .word 0x3f000000 # 0.5 + + start + .option push + .option norelax + la a0,_src + la a1,_dst + li a3,1 + .option pop + + # Test load instruction. + flw fa0,0(a0) + flw fa1,0(a1) + feq.s a4,fa0,fa1 + bne a4,a3,test_fail + + # Test store instruction. + flw fa0,0(a0) + fsw fa0,4(a1) + flw fa1,4(a1) + feq.s a4,fa0,fa1 + bne a4,a3,test_fail + + # Test convert float value to integer encoding instruction. + flw fa0,0(a0) # load float value. + lw a4,8(a1) # load expected result. + fmv.x.w a2,fa0 # convert bit pattern into integer register. + bne a4,a2,test_fail # compare result with expected. + + # Test convert integer encoding to float value instruction. + lw a4,8(a1) # load integer encoding. + fmv.w.x fa1,a4 # convert encoding into float value. + flw fa0,0(a0) # load expected float value. + feq.s a5,fa0,fa1 # compare result with expected. + bne a5,a3,test_fail + + +test_pass: + pass + +test_fail: + fail diff --git a/sim/testsuite/riscv/s-fp-sign-inject.s b/sim/testsuite/riscv/s-fp-sign-inject.s new file mode 100644 index 00000000000..733756a2197 --- /dev/null +++ b/sim/testsuite/riscv/s-fp-sign-inject.s @@ -0,0 +1,52 @@ +# Single precision sign-injection instructions. +# mach: riscv32 riscv64 +# sim(riscv32): --model RV32IF +# sim(riscv64): --model RV64ID +# ld(riscv32): -m elf32lriscv +# ld(riscv64): -m elf64lriscv +# as(riscv32): -march=rv32if +# as(riscv64): -march=rv64id + +.include "testutils.inc" + + .section .data + .align 2 + +_arg1: + .float 2.0 + +_arg2: + .float 1.0 + .float -1.0 + +_expected: + .float 2.0 + .float -2.0 + + start + .option push + .option norelax + la a0,_arg1 + la a1,_arg2 + la a2,_expected + li a3,1 + .option pop + + # Test fsgnj.s instruction. + flw fa0,0(a0) + flw fa1,0(a1) + flw fa2,0(a2) + fsgnj.s fa3,fa0,fa1 + feq.s a4,fa3,fa2 + bne a4,a3,test_fail + flw fa1,4(a1) + flw fa2,4(a2) + fsgnj.s fa3,fa0,fa1 + feq.s a4,fa3,fa2 + bne a4,a3,test_fail + +test_pass: + pass + +test_fail: + fail From patchwork Mon Feb 26 14:22:25 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bhushan Attarde X-Patchwork-Id: 86380 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 53BEE3858409 for ; Mon, 26 Feb 2024 14:25:11 +0000 (GMT) X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from mx08-00376f01.pphosted.com (mx08-00376f01.pphosted.com [91.207.212.86]) by sourceware.org (Postfix) with ESMTPS id E455A3858432 for ; Mon, 26 Feb 2024 14:23:01 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org E455A3858432 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=imgtec.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=imgtec.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org E455A3858432 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=91.207.212.86 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1708957385; cv=none; b=DCTtaPoSQy6XsQh2Pp9wp0IABHHHXZJF+iQCtxKgL37vlwMl4L6KRAMYTTkunwdA5SfmToPhDsjyldt7gd3NZf8YiR8AWu9BmyFRPHIcS6rA6hwi/4zzupceMqaGSQzczX7zvicPBgx/nbJ8aZ9PKBJd2egEOeslyYQgmpZmWb8= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1708957385; c=relaxed/simple; bh=1gu19hOOl9a1hUJ4poTKqXe9j3GaXrnjZE0nxiP+46c=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=HCspOZd3cpyn4BT8xchopSMXR9Q7bYkCHXj6EBHrQTOGTRQd7NkMO0Kq/NKbvFk08WyVvd5scyReIG0ApPrbk0Wxu8YN9rxIt+SYxqUfmYGQR2B1JYtgXcAAD9Hjjbr3ICDwDbisDd+36IcuoHFZEk4WESPP8f+U/x7ocwr2VDQ= ARC-Authentication-Results: i=1; server2.sourceware.org Received: from pps.filterd (m0168888.ppops.net [127.0.0.1]) by mx08-00376f01.pphosted.com (8.17.1.24/8.17.1.24) with ESMTP id 41Q8CPdJ013671; Mon, 26 Feb 2024 14:22:50 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=imgtec.com; h= from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding:content-type; s= dk201812; bh=NyU3Gh+LoVmr6MJOBTRqKdZrVn2Tq3XVkAvqMP75ZcU=; b=w2f m1osseK0MBuhrlyuFnGCcpo6oVES+8qmDw4WCgyMowSZARQyP49772UfIyjUbJM+ ESHqDkQ1Ksv4gA6buiJOw/y2vMkHHBlKJWBp3WNNYvtjhkxC6VoWb6rEexe1t835 FIfFFmHBFULNVVFImkNNgVa8Z0/u1fu+nyES3EMivaKkbrp/1i3X7H4TMZPCkkq3 KsD9NLQIogTO6wMT4ZT7Xj9hhw5lxaw9p4ikfwieZs+2o1n6jhQpRxhYGWmOuOa5 Dz+e3yIWEuT+PAbYkFJc+XoTEEFxSzurX5IWp0JZ5ikfG49vAgfy5TTBvhBEC/3X vLIZCIlnDc08O3zs/Yg== Received: from hhmail05.hh.imgtec.org ([217.156.249.195]) by mx08-00376f01.pphosted.com (PPS) with ESMTPS id 3wf7kssr3e-3 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Mon, 26 Feb 2024 14:22:50 +0000 (GMT) Received: from hhbattarde.hh.imgtec.org (10.100.136.78) by HHMAIL05.hh.imgtec.org (10.100.10.120) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.35; Mon, 26 Feb 2024 14:22:48 +0000 From: To: CC: , , , Bhushan Attarde Subject: [PATCH 02/11] sim: riscv: Add single precision floating-point sign injection, min and max instructions Date: Mon, 26 Feb 2024 14:22:25 +0000 Message-ID: <20240226142234.1628932-3-bhushan.attarde@imgtec.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20240226142234.1628932-1-bhushan.attarde@imgtec.com> References: <20240226142234.1628932-1-bhushan.attarde@imgtec.com> MIME-Version: 1.0 X-Originating-IP: [10.100.136.78] X-ClientProxiedBy: HHMAIL05.hh.imgtec.org (10.100.10.120) To HHMAIL05.hh.imgtec.org (10.100.10.120) X-EXCLAIMER-MD-CONFIG: 15a78312-3e47-46eb-9010-2e54d84a9631 X-Proofpoint-GUID: lPwOXfOzb0FYuxxrN3paqxqLKV8Y1GJ1 X-Proofpoint-ORIG-GUID: lPwOXfOzb0FYuxxrN3paqxqLKV8Y1GJ1 X-Spam-Status: No, score=-12.7 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_LOW, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org From: Bhushan Attarde Added simulation of following single precision floating-point instructions sgnjn.s (fneg.s), fsgnjx.s (fabs.s), fmin.s and fmax.s. Updated test files s-fp-compare.s and s-fp-sign-inject.s in sim/testsuite/riscv/ to test these instructions --- sim/riscv/sim-main.c | 64 ++++++++++++++++++++++++++ sim/testsuite/riscv/s-fp-compare.s | 22 +++++++++ sim/testsuite/riscv/s-fp-sign-inject.s | 38 +++++++++++++++ 3 files changed, 124 insertions(+) diff --git a/sim/riscv/sim-main.c b/sim/riscv/sim-main.c index d3a07585944..9c132d9a448 100644 --- a/sim/riscv/sim-main.c +++ b/sim/riscv/sim-main.c @@ -75,6 +75,8 @@ static const struct riscv_opcode *riscv_hash[OP_MASK_OP + 1]; #define FLT 2 #define FLE 3 #define FCLASS 4 +#define FMIN 5 +#define FMAX 6 static INLINE void store_rd (SIM_CPU *cpu, int rd, unsigned_word val) @@ -810,6 +812,39 @@ float32_compare (SIM_CPU *cpu, int rd, int rs1, int rs2, int flags) } } +/* Handle single precision floating point math instructions. */ +static void +float32_math (SIM_CPU *cpu, int rd, int rs1, int rs2, int flags) +{ + struct riscv_sim_cpu *riscv_cpu = RISCV_SIM_CPU (cpu); + float a, b, result = 0; + uint32_t rs1_bits, rs2_bits, rd_bits; + const char *frd_name = riscv_fpr_names_abi[rd]; + const char *frs1_name = riscv_fpr_names_abi[rs1]; + const char *frs2_name = riscv_fpr_names_abi[rs2]; + + rs1_bits = (uint32_t) riscv_cpu->fpregs[rs1]; + memcpy (&a, &rs1_bits, sizeof (a)); + rs2_bits = (uint32_t) riscv_cpu->fpregs[rs2]; + memcpy (&b, &rs2_bits, sizeof (b)); + + switch (flags) + { + case FMAX: + TRACE_INSN (cpu, "fmax.s %s, %s, %s;", frd_name, frs1_name, frs2_name); + result = fmaxf (a, b); + break; + case FMIN: + TRACE_INSN (cpu, "fmin.s %s, %s, %s;", frd_name, frs1_name, frs2_name); + result = fminf (a, b); + break; + } + + /* Store result. */ + memcpy (&rd_bits, &result, sizeof (result)); + store_fp (cpu, rd, rd_bits); +} + /* Simulate single precision floating point instructions. */ static sim_cia execute_f (SIM_CPU *cpu, unsigned_word iw, const struct riscv_opcode *op) @@ -885,6 +920,35 @@ execute_f (SIM_CPU *cpu, unsigned_word iw, const struct riscv_opcode *op) case MATCH_FCLASS_S: float32_compare (cpu, rd, rs1, 0, FCLASS); break; + case MATCH_FSGNJN_S: + { + uint32_t rs1_bits, rs2_bits; + TRACE_INSN (cpu, "fsgnjn.s %s, %s, %s;", frd_name, frs1_name, + frs2_name); + rs1_bits = (uint32_t) riscv_cpu->fpregs[rs1]; + rs2_bits = ~((uint32_t) riscv_cpu->fpregs[rs2]); + rs1_bits = (rs2_bits & 0x80000000) | (rs1_bits & 0x7fffffff); + store_fp (cpu, rd, rs1_bits); + break; + } + case MATCH_FSGNJX_S: + { + uint32_t rs1_bits, rs2_bits; + TRACE_INSN (cpu, "fsgnjx.s %s, %s, %s;", frd_name, frs1_name, + frs2_name); + rs1_bits = (uint32_t) riscv_cpu->fpregs[rs1]; + rs2_bits = (uint32_t) riscv_cpu->fpregs[rs2]; + rs1_bits = ((rs1_bits & 0x80000000) ^ (rs2_bits & 0x80000000)) + | (rs1_bits & 0x7fffffff); + store_fp (cpu, rd, rs1_bits); + break; + } + case MATCH_FMIN_S: + float32_math (cpu, rd, rs1, rs2, FMIN); + break; + case MATCH_FMAX_S: + float32_math (cpu, rd, rs1, rs2, FMAX); + break; default: TRACE_INSN (cpu, "UNHANDLED INSN: %s", op->name); sim_engine_halt (sd, cpu, NULL, riscv_cpu->pc, sim_signalled, SIM_SIGILL); diff --git a/sim/testsuite/riscv/s-fp-compare.s b/sim/testsuite/riscv/s-fp-compare.s index d5b98b30233..7aef3ce51c2 100644 --- a/sim/testsuite/riscv/s-fp-compare.s +++ b/sim/testsuite/riscv/s-fp-compare.s @@ -23,11 +23,16 @@ _arg2: .float 0.5 .float 2.2 +_expected: + .float 0.5 + .float 2.2 + start .option push .option norelax la a0,_arg1 la a1,_arg2 + la a2,_expected li a3,1 .option pop @@ -68,6 +73,23 @@ _arg2: fclass.s a4,fa0 bne a3,a4,test_fail + # Test fmin.s instruction. + flw fa0,0(a0) + flw fa1,4(a1) + flw fa2,0(a2) + fmin.s fa3,fa0,fa1 + feq.s a4,fa3,fa2 + li a3,1 + bne a4,a3,test_fail + + # Test fmax.s instruction. + flw fa0,0(a0) + flw fa1,4(a1) + flw fa2,4(a2) + fmax.s fa3,fa0,fa1 + feq.s a4,fa3,fa2 + bne a4,a3,test_fail + test_pass: pass diff --git a/sim/testsuite/riscv/s-fp-sign-inject.s b/sim/testsuite/riscv/s-fp-sign-inject.s index 733756a2197..e4efbaaf29e 100644 --- a/sim/testsuite/riscv/s-fp-sign-inject.s +++ b/sim/testsuite/riscv/s-fp-sign-inject.s @@ -14,6 +14,7 @@ _arg1: .float 2.0 + .float -2.0 _arg2: .float 1.0 @@ -45,6 +46,43 @@ _expected: feq.s a4,fa3,fa2 bne a4,a3,test_fail + # Test fsgnjn.s (fneg.s) instruction. + flw fa0,0(a0) + flw fa1,0(a1) + flw fa2,4(a2) + fsgnjn.s fa3,fa0,fa1 + feq.s a4,fa3,fa2 + bne a4,a3,test_fail + flw fa1,4(a1) + flw fa2,0(a2) + fsgnjn.s fa3,fa0,fa1 + feq.s a4,fa3,fa2 + bne a4,a3,test_fail + flw fa0,0(a0) + flw fa2,4(a2) + fneg.s fa3,fa0 + feq.s a4,fa3,fa2 + bne a4,a3,test_fail + + # Test fsgnjx.s (fabs.s) instruction. + flw fa0,0(a0) + flw fa1,4(a1) + flw fa2,4(a2) + fsgnjx.s fa3,fa0,fa1 + feq.s a4,fa3,fa2 + bne a4,a3,test_fail + flw fa0,4(a0) + flw fa1,4(a1) + flw fa2,0(a2) + fsgnjx.s fa3,fa0,fa1 + feq.s a4,fa3,fa2 + bne a4,a3,test_fail + flw fa0,4(a0) + flw fa2,0(a2) + fabs.s fa3,fa0 + feq.s a4,fa3,fa2 + bne a4,a3,test_fail + test_pass: pass From patchwork Mon Feb 26 14:22:26 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bhushan Attarde X-Patchwork-Id: 86381 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id D1B6E3858427 for ; Mon, 26 Feb 2024 14:25:18 +0000 (GMT) X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from mx08-00376f01.pphosted.com (mx08-00376f01.pphosted.com [91.207.212.86]) by sourceware.org (Postfix) with ESMTPS id DAA8A3858431 for ; Mon, 26 Feb 2024 14:23:01 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org DAA8A3858431 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=imgtec.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=imgtec.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org DAA8A3858431 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=91.207.212.86 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1708957386; cv=none; b=WsZgswFJ9zhpWwtORHWOJ5L4p3xT4nVZT4aY/cJ8fLUGYHf+i7aLWzjQvNX/SsYr004xUo0i60p8dN2DJCYTYyg/xsIW1B42uTVvEZv8X9I1DlYhjETGfXGMj03lBtmFEbL5DxQtYGdTJq0bA2xqPryxAxse+Cja/HgjjJbrUlg= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1708957386; c=relaxed/simple; bh=xdM1vxdC3Txoow5cCOdKFa59CJ1GkM06XQGWd/4jty0=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=uE/JLxuVgq9m4jZ/CoHjplun5Ch5aQkloz4AfRI8jfrYIRkjJORM004A1KZEWfKAkknC+kLpr4tEU6cqH4gC37dqVAlYGt2xO4+FISGMC/VjyCxkSNRZeSywJ2s0ocO1fj47EcoUpSfsVm8nymwIDATM1SgQg8hGTmSdSlh55uY= ARC-Authentication-Results: i=1; server2.sourceware.org Received: from pps.filterd (m0168888.ppops.net [127.0.0.1]) by mx08-00376f01.pphosted.com (8.17.1.24/8.17.1.24) with ESMTP id 41Q8CPdL013671; Mon, 26 Feb 2024 14:22:51 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=imgtec.com; h= from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding:content-type; s= dk201812; bh=COouRicamEJ6ua3hjVy6M0FKBD+/jmx8JvnZnUNp0GE=; b=Xbh fYDOo3faDx2XExJhkKsKzlre8uPjG93KRE/4N46ovjkWRi8kAzE2xloPynOddnyb o2tR5L5Ktj6pl/085jm2Fg0VlQWdbUFX+a0q0hdBWZ0YDW5WQLzR6dN4ZG2dG5j3 C9kNPkpZuc8jvnwKS2r2+yQOz+AZSmQkRZVk6XaSLXqjTOJvW1jnfyzqlDZMSPfJ LjCwkQyXCsYC5AoHYIw9yhhIWzgRi6LJFI5mQetCNQ21pV3jpW/o/koOYGk4IqCC aolFVUuugqSxXEkxqbzLDlBefzdWkyjPKX0Tf4uHTKnTZd9yDLhMjn0cA1zGoiQ8 JsbvIR/Tnu3MAn/Zpfg== Received: from hhmail05.hh.imgtec.org ([217.156.249.195]) by mx08-00376f01.pphosted.com (PPS) with ESMTPS id 3wf7kssr3e-4 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Mon, 26 Feb 2024 14:22:51 +0000 (GMT) Received: from hhbattarde.hh.imgtec.org (10.100.136.78) by HHMAIL05.hh.imgtec.org (10.100.10.120) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.35; Mon, 26 Feb 2024 14:22:49 +0000 From: To: CC: , , , Bhushan Attarde Subject: [PATCH 03/11] sim: riscv: Add floating-point CSR instructions Date: Mon, 26 Feb 2024 14:22:26 +0000 Message-ID: <20240226142234.1628932-4-bhushan.attarde@imgtec.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20240226142234.1628932-1-bhushan.attarde@imgtec.com> References: <20240226142234.1628932-1-bhushan.attarde@imgtec.com> MIME-Version: 1.0 X-Originating-IP: [10.100.136.78] X-ClientProxiedBy: HHMAIL05.hh.imgtec.org (10.100.10.120) To HHMAIL05.hh.imgtec.org (10.100.10.120) X-EXCLAIMER-MD-CONFIG: 15a78312-3e47-46eb-9010-2e54d84a9631 X-Proofpoint-GUID: rtQ8-bfw_16XbQr8AE8m5hsTn4z49qmH X-Proofpoint-ORIG-GUID: rtQ8-bfw_16XbQr8AE8m5hsTn4z49qmH X-Spam-Status: No, score=-12.8 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_LOW, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org From: Bhushan Attarde Added simulation of following single precision floating-point instructions frcsr, fscsr, frrm, fsrm, fsrmi, frflags, fsflags and fsflagsi. Added test file sim/testsuite/riscv/f-csr.s to test these instructions. --- sim/riscv/sim-main.c | 64 +++++++++++++++++++++++++++++++++++++ sim/testsuite/riscv/f-csr.s | 56 ++++++++++++++++++++++++++++++++ 2 files changed, 120 insertions(+) create mode 100644 sim/testsuite/riscv/f-csr.s diff --git a/sim/riscv/sim-main.c b/sim/riscv/sim-main.c index 9c132d9a448..0e873895f76 100644 --- a/sim/riscv/sim-main.c +++ b/sim/riscv/sim-main.c @@ -599,6 +599,21 @@ execute_i (SIM_CPU *cpu, unsigned_word iw, const struct riscv_opcode *op) riscv_cpu->regs[rs1]); \ break; #include "opcode/riscv-opc.h" +#undef DECLARE_CSR + } + break; + case MATCH_CSRRWI: + TRACE_INSN (cpu, "csrrwi"); + switch (csr) + { +#define DECLARE_CSR(name, num, ...) \ + case num: \ + store_rd (cpu, rd, \ + fetch_csr (cpu, #name, num, &riscv_cpu->csr.name)); \ + store_csr (cpu, #name, num, &riscv_cpu->csr.name, \ + rs1); \ + break; +#include "opcode/riscv-opc.h" #undef DECLARE_CSR } break; @@ -949,6 +964,54 @@ execute_f (SIM_CPU *cpu, unsigned_word iw, const struct riscv_opcode *op) case MATCH_FMAX_S: float32_math (cpu, rd, rs1, rs2, FMAX); break; + case MATCH_FRCSR: + TRACE_INSN (cpu, "frcsr %s;", rd_name); + store_rd (cpu, rd, riscv_cpu->csr.fcsr); + break; + case MATCH_FSCSR: + TRACE_INSN (cpu, "fscsr %s, %s;", rd_name, rs1_name); + store_rd (cpu, rd, riscv_cpu->csr.fcsr); + riscv_cpu->csr.fcsr = riscv_cpu->regs[rs1] & 0xff; + riscv_cpu->csr.frm = (riscv_cpu->regs[rs1] >> 5) & 0x7; + riscv_cpu->csr.fflags = riscv_cpu->regs[rs1] & 0x1f; + TRACE_REGISTER (cpu, "wrote CSR fcsr = %#" PRIxTW, riscv_cpu->regs[rs1]); + break; + case MATCH_FRRM: + TRACE_INSN (cpu, "frrm %s;", rd_name); + store_rd (cpu, rd, riscv_cpu->csr.frm); + break; + case MATCH_FSRM: + TRACE_INSN (cpu, "fsrm %s, %s;", rd_name, rs1_name); + store_rd (cpu, rd, riscv_cpu->csr.frm); + riscv_cpu->csr.frm = riscv_cpu->regs[rs1] & 0x7; + riscv_cpu->csr.fcsr |= (riscv_cpu->regs[rs1] & 0x7) << 5; + TRACE_REGISTER (cpu, "wrote CSR fcsr = %#" PRIxTW, riscv_cpu->csr.fcsr); + break; + case MATCH_FSRMI: + TRACE_INSN (cpu, "fsrmi %s, %x;", rd_name, rs1); + store_rd (cpu, rd, riscv_cpu->csr.frm); + riscv_cpu->csr.frm = rs1 & 0x7; + riscv_cpu->csr.fcsr |= (rs1 & 0x7) << 5; + TRACE_REGISTER (cpu, "wrote CSR fcsr = %#" PRIxTW, riscv_cpu->csr.fcsr); + break; + case MATCH_FRFLAGS: + TRACE_INSN (cpu, "frflags %s;", rd_name); + store_rd (cpu, rd, riscv_cpu->csr.fflags); + break; + case MATCH_FSFLAGS: + TRACE_INSN (cpu, "fsflags %s, %s;", rd_name, rs1_name); + store_rd (cpu, rd, riscv_cpu->csr.fflags); + riscv_cpu->csr.fflags = riscv_cpu->regs[rs1] & 0x1f; + riscv_cpu->csr.fcsr |= riscv_cpu->regs[rs1] & 0x1f; + TRACE_REGISTER (cpu, "wrote CSR fcsr = %#" PRIxTW, riscv_cpu->csr.fcsr); + break; + case MATCH_FSFLAGSI: + TRACE_INSN (cpu, "fsflagsi %s, %x;", rd_name, rs1); + store_rd (cpu, rd, riscv_cpu->csr.fflags); + riscv_cpu->csr.fflags = rs1 & 0x1f; + riscv_cpu->csr.fcsr |= rs1 & 0x1f; + TRACE_REGISTER (cpu, "wrote CSR fcsr = %#" PRIxTW, riscv_cpu->csr.fcsr); + break; default: TRACE_INSN (cpu, "UNHANDLED INSN: %s", op->name); sim_engine_halt (sd, cpu, NULL, riscv_cpu->pc, sim_signalled, SIM_SIGILL); @@ -1592,6 +1655,7 @@ execute_one (SIM_CPU *cpu, unsigned_word iw, const struct riscv_opcode *op) case INSN_CLASS_F_INX: return execute_f (cpu, iw, op); case INSN_CLASS_I: + case INSN_CLASS_ZICSR: return execute_i (cpu, iw, op); case INSN_CLASS_M: case INSN_CLASS_ZMMUL: diff --git a/sim/testsuite/riscv/f-csr.s b/sim/testsuite/riscv/f-csr.s new file mode 100644 index 00000000000..c8f930b0d86 --- /dev/null +++ b/sim/testsuite/riscv/f-csr.s @@ -0,0 +1,56 @@ +# Floating-point CSR instructions tests +# mach: riscv32 riscv64 +# sim(riscv32): --model RV32IF +# sim(riscv64): --model RV64ID +# ld(riscv32): -m elf32lriscv +# ld(riscv64): -m elf64lriscv +# as(riscv32): -march=rv32if +# as(riscv64): -march=rv64id + +.include "testutils.inc" + + start + # Test fscsr and frcsr instruction. + li a4,0x44 # mode:RDN, exception flags:OF + fscsr a5,a4 + frcsr a6 + bne a4,a6,test_fail + + # Test rounding mode and flags read instruction. + li a4,0x2 # mode:RDN + frrm a5 + bne a4,a5,test_fail + frflags a5 + li a6,0x4 # exception flags:OF + bne a6,a5,test_fail + + # Test swap rounding mode instruction. + li a6,0x7 # mode:Dynamic + fsrm a5,a6 + bne a4,a5,test_fail # earlier mode should be RDN + frrm a5 + bne a6,a5,test_fail # new mode should be Dynamic + + # Test swap rounding mode with immediate value instruction. + fsrmi a5,0x2 # set new mode RDN (0x2) + frrm a5 # read the mode + li a6,0x2 + bne a6,a5,test_fail # should be RDN (0x2) + + # Test swap exception flags instruction. + li a6,0x8 # flag:Divide by zero + fsflags a5,a6 + frflags a5 + bne a5,a6,test_fail + + # Test swap exception flags with immediate value instruction. + fsflagsi a5,0x2 # set new flag to underflow (0x2) + frflags a5 # read the flag + li a6,0x2 + bne a5,a6,test_fail # should be underflow (0x2) + +test_pass: + pass + +test_fail: + fail From patchwork Mon Feb 26 14:26:21 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bhushan Attarde X-Patchwork-Id: 86382 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 801943858429 for ; Mon, 26 Feb 2024 14:27:28 +0000 (GMT) X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from mx08-00376f01.pphosted.com (mx08-00376f01.pphosted.com [91.207.212.86]) by sourceware.org (Postfix) with ESMTPS id 7BA3C3858D28 for ; Mon, 26 Feb 2024 14:26:47 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 7BA3C3858D28 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=imgtec.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=imgtec.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 7BA3C3858D28 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=91.207.212.86 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1708957610; cv=none; b=CGUBmvNNYife/KL5icand4Re+hDZIoF4azbCmAvwdACWtyc2lp3dZYXNW+MLSJd5E0HbbuogWbpinmKM7Nol7C/leSrockCoxxi04lp5M33mT8PwPpPRj5JFoxqQekI0Nc9c0qZ+dAlhqjtNPt65T+7c+EmuCcFpad16tYvLcIo= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1708957610; c=relaxed/simple; bh=igwUGyVdw/xWvxmH2E/ZtsfQxW6UTyjCSc+l5/yXhDA=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=cdFVTKRp2yJpZhCD4ZHPOcJ6kcyIKV9SMMlj3lfuDWSuxYDs1AiDcP48B0I46e2VZRfK7mt7GvHIQRLtdaCDEkll+rQ1YOzJ/VmwdsNO+FF9E548adXLQrTxyrp14LBQ0/kyDWlFnXLGuxTV5DbWarLtpAWwJUDL7Nunk7dMn9o= ARC-Authentication-Results: i=1; server2.sourceware.org Received: from pps.filterd (m0168888.ppops.net [127.0.0.1]) by mx08-00376f01.pphosted.com (8.17.1.24/8.17.1.24) with ESMTP id 41Q86eF5005999; Mon, 26 Feb 2024 14:26:42 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=imgtec.com; h= from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding:content-type; s=dk201812; bh=GNPJRUu9 pW8DXYa+Vh/aYrLX2HIsg3gESwkUJh8zdaM=; b=uGTICBrMbvvNDTEH9vz2SsKK 8Awa6sOjEk5GMzAfy04TyIBd2JQoBd7Bc5rCe8Ci4o4aCi9z73A4CtjmZczz1vL1 P65P2w08MRG21xWERYOoIYNsCp5bSyIkBOZMF7Elc1lK1RILbsb34FLAeyhl9Ero vUM7WaCYu2yKoM56fYb41Esf1xyyiI2sUePG9VeJx6zsEoZpivuzYlAR2awQU1je mWcmLtXx0y1mnBGXiut4j194NBz+rC7Pt005Ej5SFAMt9igQaH21wDM+lobmSeos cE/Tg5yIeaOYh/oInFTtnrViQanUZTqn+oOHFlL0URNQi+w5M48YEaF0pD7jRQ== Received: from hhmail05.hh.imgtec.org ([217.156.249.195]) by mx08-00376f01.pphosted.com (PPS) with ESMTPS id 3wf7kssr69-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Mon, 26 Feb 2024 14:26:42 +0000 (GMT) Received: from hhbattarde.hh.imgtec.org (10.100.136.78) by HHMAIL05.hh.imgtec.org (10.100.10.120) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.35; Mon, 26 Feb 2024 14:26:41 +0000 From: To: CC: , , , Bhushan Attarde Subject: [PATCH 04/11] sim: riscv: Add single precision floating-point MAC instructions Date: Mon, 26 Feb 2024 14:26:21 +0000 Message-ID: <20240226142628.1629048-1-bhushan.attarde@imgtec.com> X-Mailer: git-send-email 2.25.1 MIME-Version: 1.0 X-Originating-IP: [10.100.136.78] X-ClientProxiedBy: HHMAIL05.hh.imgtec.org (10.100.10.120) To HHMAIL05.hh.imgtec.org (10.100.10.120) X-EXCLAIMER-MD-CONFIG: 15a78312-3e47-46eb-9010-2e54d84a9631 X-Proofpoint-GUID: YLR_MtrpW4FAQb9_3i7Gz89Eko4OIRIH X-Proofpoint-ORIG-GUID: YLR_MtrpW4FAQb9_3i7Gz89Eko4OIRIH X-Spam-Status: No, score=-12.8 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_LOW, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org From: Bhushan Attarde Added simulation of following single precision floating-point instructions fmadd.s, fnmadd.s, fmsub.s and fnmsub.s. Added test file sim/testsuite/riscv/s-basic-arith.s to test these instructions. --- sim/riscv/sim-main.c | 171 +++++++++++++++++++++++++++- sim/testsuite/riscv/s-basic-arith.s | 80 +++++++++++++ 2 files changed, 246 insertions(+), 5 deletions(-) create mode 100644 sim/testsuite/riscv/s-basic-arith.s diff --git a/sim/riscv/sim-main.c b/sim/riscv/sim-main.c index 0e873895f76..dd91431ad12 100644 --- a/sim/riscv/sim-main.c +++ b/sim/riscv/sim-main.c @@ -25,6 +25,7 @@ #include "defs.h" #include +#include #include #include @@ -71,12 +72,25 @@ static const struct riscv_opcode *riscv_hash[OP_MASK_OP + 1]; #define FCSR_DZ 0x8 /* Divide by zero. */ #define FCSR_NV 0x10 /* Invalid Operation. */ +#define RNE 0x000 +#define RTZ 0x001 +#define RDN 0x002 +#define RUP 0x003 +#define RMM 0x004 +#define DYN 0x007 + +#define MASK_RM (OP_MASK_RM << OP_SH_RM) + #define FEQ 1 #define FLT 2 #define FLE 3 #define FCLASS 4 #define FMIN 5 #define FMAX 6 +#define FMADD 7 +#define FMSUB 8 +#define FNMADD 9 +#define FNMSUB 10 static INLINE void store_rd (SIM_CPU *cpu, int rd, unsigned_word val) @@ -721,6 +735,45 @@ mulhsu (int64_t a, uint64_t b) return negate ? ~res + (a * b == 0) : res; } +/* Handle the rounding modes. */ +static int +set_riscv_rounding_mode (int rm) +{ + int old_rm = fegetround (); + + /* Instruction does not set rm. */ + if (rm == -1) + return old_rm; + + if (rm == RNE) + fesetround (FE_TONEAREST); + else if (rm == RTZ) + fesetround (FE_TOWARDZERO); + else if (rm == RDN) + fesetround (FE_DOWNWARD); + else if (rm == RUP) + fesetround (FE_UPWARD); + else + { + /* No direct match for RMM. Simulate it. */ + } + + return old_rm; +} + +/* Checks whether the fractional part of a floating-point number is + exactly 0.5. If the fractional part is 0.5, the function returns 1; + otherwise, it returns 0. */ +static int +is_float_halfway (float value) +{ + float frac_part, int_part; + frac_part = modff (value, &int_part); + if (fabsf (frac_part) == 0.5f) + return 1; + return 0; +} + /* Handle single precision floating point compare instructions. */ static void float32_compare (SIM_CPU *cpu, int rd, int rs1, int rs2, int flags) @@ -829,22 +882,58 @@ float32_compare (SIM_CPU *cpu, int rd, int rs1, int rs2, int flags) /* Handle single precision floating point math instructions. */ static void -float32_math (SIM_CPU *cpu, int rd, int rs1, int rs2, int flags) +float32_math (SIM_CPU *cpu, int rd, int rs1, int rs2, + int rs3, int rm, int flags) { struct riscv_sim_cpu *riscv_cpu = RISCV_SIM_CPU (cpu); - float a, b, result = 0; - uint32_t rs1_bits, rs2_bits, rd_bits; + float a, b, c, result = 0; + int old_rm, old_except, new_except; + uint32_t rs1_bits, rs2_bits, rs3_bits, rd_bits; const char *frd_name = riscv_fpr_names_abi[rd]; const char *frs1_name = riscv_fpr_names_abi[rs1]; const char *frs2_name = riscv_fpr_names_abi[rs2]; + const char *frs3_name = riscv_fpr_names_abi[rs3]; + + if (rm == DYN) + rm = riscv_cpu->csr.frm; + + old_rm = set_riscv_rounding_mode (rm); + old_except = fetestexcept (FE_ALL_EXCEPT); rs1_bits = (uint32_t) riscv_cpu->fpregs[rs1]; memcpy (&a, &rs1_bits, sizeof (a)); rs2_bits = (uint32_t) riscv_cpu->fpregs[rs2]; memcpy (&b, &rs2_bits, sizeof (b)); + if (flags == FMADD || flags == FNMADD + || flags == FMSUB || flags == FNMSUB) + { + rs3_bits = (uint32_t) riscv_cpu->fpregs[rs3]; + memcpy (&c, &rs3_bits, sizeof (c)); + } + switch (flags) { + case FMADD: + TRACE_INSN (cpu, "fmadd.s %s, %s, %s, %s, rm=%d;", + frd_name, frs1_name, frs2_name, frs3_name, rm); + result = (a * b) + c; + break; + case FNMADD: + TRACE_INSN (cpu, "fnmadd.s %s, %s, %s, %s, rm=%d;", + frd_name, frs1_name, frs2_name, frs3_name, rm); + result = -((a * b) - c); + break; + case FMSUB: + TRACE_INSN (cpu, "fmsub.s %s, %s, %s, %s, rm=%d;", + frd_name, frs1_name, frs2_name, frs3_name, rm); + result = (a * b) - c; + break; + case FNMSUB: + TRACE_INSN (cpu, "fnmsub.s %s, %s, %s, %s, rm=%d;", + frd_name, frs1_name, frs2_name, frs3_name, rm); + result = -((a * b) + c); + break; case FMAX: TRACE_INSN (cpu, "fmax.s %s, %s, %s;", frd_name, frs1_name, frs2_name); result = fmaxf (a, b); @@ -855,9 +944,63 @@ float32_math (SIM_CPU *cpu, int rd, int rs1, int rs2, int flags) break; } + if (rm == RMM) + { + if (is_float_halfway (result)) + { + if (result > 0) + result = nextafterf (result, INFINITY); + else + result = nextafterf (result, -INFINITY); + } + } + /* Store result. */ memcpy (&rd_bits, &result, sizeof (result)); store_fp (cpu, rd, rd_bits); + + /* Restore rounding mode. */ + fesetround (old_rm); + + /* Set exception. */ + new_except = fetestexcept (FE_ALL_EXCEPT); + + if (old_except != new_except) + { + if (new_except & FE_OVERFLOW) + { + riscv_cpu->csr.fcsr |= FCSR_OF; + riscv_cpu->csr.fflags |= FCSR_OF; + TRACE_REGISTER (cpu, "wrote CSR fcsr |= OF"); + } + else if (new_except & FE_UNDERFLOW) + { + riscv_cpu->csr.fcsr |= FCSR_UF; + riscv_cpu->csr.fflags |= FCSR_UF; + TRACE_REGISTER (cpu, "wrote CSR fcsr |= UF"); + } + else if (new_except & FE_INEXACT) + { + riscv_cpu->csr.fcsr |= FCSR_NX; + riscv_cpu->csr.fflags |= FCSR_NX; + TRACE_REGISTER (cpu, "wrote CSR fcsr |= NX"); + } + else if (new_except & FE_DIVBYZERO) + { + riscv_cpu->csr.fcsr |= FCSR_DZ; + riscv_cpu->csr.fflags |= FCSR_DZ; + TRACE_REGISTER (cpu, "wrote CSR fcsr |= DZ"); + } + else if (new_except & FE_INVALID) + { + riscv_cpu->csr.fcsr |= FCSR_NV; + riscv_cpu->csr.fflags |= FCSR_NV; + TRACE_REGISTER (cpu, "wrote CSR fcsr |= NV"); + } + + feclearexcept (FE_ALL_EXCEPT); + feraiseexcept (old_except); + } } /* Simulate single precision floating point instructions. */ @@ -869,6 +1012,8 @@ execute_f (SIM_CPU *cpu, unsigned_word iw, const struct riscv_opcode *op) int rd = (iw >> OP_SH_RD) & OP_MASK_RD; int rs1 = (iw >> OP_SH_RS1) & OP_MASK_RS1; int rs2 = (iw >> OP_SH_RS2) & OP_MASK_RS2; + int rs3 = (iw >> OP_SH_RS3) & OP_MASK_RS3; + int rm = (iw >> OP_SH_RM) & OP_MASK_RM; const char *frd_name = riscv_fpr_names_abi[rd]; const char *rd_name = riscv_gpr_names_abi[rd]; const char *frs1_name = riscv_fpr_names_abi[rs1]; @@ -959,10 +1104,10 @@ execute_f (SIM_CPU *cpu, unsigned_word iw, const struct riscv_opcode *op) break; } case MATCH_FMIN_S: - float32_math (cpu, rd, rs1, rs2, FMIN); + float32_math (cpu, rd, rs1, rs2, 0, -1, FMIN); break; case MATCH_FMAX_S: - float32_math (cpu, rd, rs1, rs2, FMAX); + float32_math (cpu, rd, rs1, rs2, 0, -1, FMAX); break; case MATCH_FRCSR: TRACE_INSN (cpu, "frcsr %s;", rd_name); @@ -1012,6 +1157,22 @@ execute_f (SIM_CPU *cpu, unsigned_word iw, const struct riscv_opcode *op) riscv_cpu->csr.fcsr |= rs1 & 0x1f; TRACE_REGISTER (cpu, "wrote CSR fcsr = %#" PRIxTW, riscv_cpu->csr.fcsr); break; + case MATCH_FMADD_S: + case MATCH_FMADD_S | MASK_RM: + float32_math (cpu, rd, rs1, rs2, rs3, rm, FMADD); + break; + case MATCH_FNMADD_S: + case MATCH_FNMADD_S | MASK_RM: + float32_math (cpu, rd, rs1, rs2, rs3, rm, FNMADD); + break; + case MATCH_FMSUB_S: + case MATCH_FMSUB_S | MASK_RM: + float32_math (cpu, rd, rs1, rs2, rs3, rm, FMSUB); + break; + case MATCH_FNMSUB_S: + case MATCH_FNMSUB_S | MASK_RM: + float32_math (cpu, rd, rs1, rs2, rs3, rm, FNMSUB); + break; default: TRACE_INSN (cpu, "UNHANDLED INSN: %s", op->name); sim_engine_halt (sd, cpu, NULL, riscv_cpu->pc, sim_signalled, SIM_SIGILL); diff --git a/sim/testsuite/riscv/s-basic-arith.s b/sim/testsuite/riscv/s-basic-arith.s new file mode 100644 index 00000000000..a05a0d0a2c3 --- /dev/null +++ b/sim/testsuite/riscv/s-basic-arith.s @@ -0,0 +1,80 @@ +# Single precision basic arithmetic tests. +# mach: riscv32 riscv64 +# sim(riscv32): --model RV32IF +# sim(riscv64): --model RV64ID +# ld(riscv32): -m elf32lriscv +# ld(riscv64): -m elf64lriscv +# as(riscv32): -march=rv32if +# as(riscv64): -march=rv64id + +.include "testutils.inc" + + .section .data + .align 2 + +_arg1: + .float -12.5 + +_arg2: + .float 2.5 + +_arg3: + .float 7.45 + +_result: + .float -23.799999 + .float 38.7000008 + .float -38.7000008 + .float 23.7999992 + + start + .option push + .option norelax + la a0,_arg1 + la a1,_arg2 + la a2,_arg3 + la a3,_result + li a4,1 + .option pop + + # Test fmadd instruction. + flw fa0,0(a0) + flw fa1,0(a1) + flw fa2,0(a2) + flw fa3,0(a3) + fmadd.s fa4,fa0,fa1,fa0,rne + feq.s a5,fa4,fa4 + bne a5,a4,test_fail + + # Test fnmadd instruction. + flw fa0,0(a0) + flw fa1,0(a1) + flw fa2,0(a2) + flw fa3,4(a3) + fnmadd.s fa4,fa0,fa1,fa0,rne + feq.s a5,fa4,fa4 + bne a5,a4,test_fail + + # Test fmsub instruction. + flw fa0,0(a0) + flw fa1,0(a1) + flw fa2,0(a2) + flw fa3,8(a3) + fmsub.s fa4,fa0,fa1,fa0,rne + feq.s a5,fa4,fa4 + bne a5,a4,test_fail + + # Test fnmsub instruction. + flw fa0,0(a0) + flw fa1,0(a1) + flw fa2,0(a2) + flw fa3,12(a3) + fmsub.s fa4,fa0,fa1,fa0,rne + feq.s a5,fa4,fa4 + bne a5,a4,test_fail + +test_pass: + pass + +test_fail: + fail From patchwork Mon Feb 26 14:26:22 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bhushan Attarde X-Patchwork-Id: 86386 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 709CB3858415 for ; Mon, 26 Feb 2024 14:28:07 +0000 (GMT) X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from mx08-00376f01.pphosted.com (mx08-00376f01.pphosted.com [91.207.212.86]) by sourceware.org (Postfix) with ESMTPS id 7CB1B3858C54 for ; Mon, 26 Feb 2024 14:26:48 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 7CB1B3858C54 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=imgtec.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=imgtec.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 7CB1B3858C54 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=91.207.212.86 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1708957610; cv=none; b=JDvkNwXRAG5t3Qie1vuqCi7PamvVAXaZcW94v+XPU1dTx4/QIAwUAJcFvPbwUN2kVOKRcws6dhU4+ynziubQhaZw6g7jarkUZuooK2wjFL1nBwghjjTIhYyU3Ti1Pr9TeApfmwFaK7tuRU9cy++lmRPuKEKdK6kHA8mCwGu6/vI= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1708957610; c=relaxed/simple; bh=Lx7QBA5VoVRXFLPoBPnQa1qZxW+FM7SW9VE8RXctlIM=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=Jt2MBxu3Q7Iw86L3y1pdR5+k6otmDfAQOOP+RXafQNU3u4/L6xVTKl80+H9XP8lolMJrn1IqETcEEu0mlYutfYi4sFBc11hIGjCLiudLis4X3Kf4tEw2ExthM0BylcEBkSIG2v8mkvchrKYLHy+fRnb3X4v+0X74rschY7UjT/U= ARC-Authentication-Results: i=1; server2.sourceware.org Received: from pps.filterd (m0168888.ppops.net [127.0.0.1]) by mx08-00376f01.pphosted.com (8.17.1.24/8.17.1.24) with ESMTP id 41Q86eF6005999; Mon, 26 Feb 2024 14:26:42 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=imgtec.com; h= from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding:content-type; s= dk201812; bh=OiI8mtrBIYmmIxfclv0nUKKfKNvhlyw/W9jRYFtOgtg=; b=kko ZKFuvkeJoF0iqgH42EDkbdKd8gHpMeFgXgquykSwR4h2PENxZsD42uGUYcKtGClI CH9V7mzqlA8Dp5IU6opAttV6Ud0zvXevzUdsTHxQHvzrMgONKu5UCJzjZUWqo5X6 TvddjsAurv/1ow2sIjOKwHSlZH4TRkPpUJJvt9irrT69eZfVM1IVlBobUs+r60/c 7DPIKNYP1JYJdCeZJufTHj6fQAKXAUyeMwieNfnPieGXnSmBkiS6UAOyCv1rTWn/ OxGWsqhLDvBx3ysLqJ6G1Ly01rq6Pw5Avmbiztvg1xVoddAVnnRatOSWHWXB1m4m wkwgJV5Lqv4gxbipXrw== Received: from hhmail05.hh.imgtec.org ([217.156.249.195]) by mx08-00376f01.pphosted.com (PPS) with ESMTPS id 3wf7kssr69-2 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Mon, 26 Feb 2024 14:26:42 +0000 (GMT) Received: from hhbattarde.hh.imgtec.org (10.100.136.78) by HHMAIL05.hh.imgtec.org (10.100.10.120) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.35; Mon, 26 Feb 2024 14:26:41 +0000 From: To: CC: , , , Bhushan Attarde Subject: [PATCH 05/11] sim: riscv: Add single precision floating-point basic arithmetic instructions Date: Mon, 26 Feb 2024 14:26:22 +0000 Message-ID: <20240226142628.1629048-2-bhushan.attarde@imgtec.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20240226142628.1629048-1-bhushan.attarde@imgtec.com> References: <20240226142628.1629048-1-bhushan.attarde@imgtec.com> MIME-Version: 1.0 X-Originating-IP: [10.100.136.78] X-ClientProxiedBy: HHMAIL05.hh.imgtec.org (10.100.10.120) To HHMAIL05.hh.imgtec.org (10.100.10.120) X-EXCLAIMER-MD-CONFIG: 15a78312-3e47-46eb-9010-2e54d84a9631 X-Proofpoint-GUID: 055ZiPXJhh4jKy9DOMUtTk2qXQDuVbnj X-Proofpoint-ORIG-GUID: 055ZiPXJhh4jKy9DOMUtTk2qXQDuVbnj X-Spam-Status: No, score=-2.8 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_LOW, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE, UNWANTED_LANGUAGE_BODY autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org From: Bhushan Attarde Added simulation of following single precision floating-point instructions fadd.s, fsub.s, fmul.s, fdiv.s and fsqrt.s. Updated test file sim/testsuite/riscv/s-basic-arith.s to test these instructions. --- sim/riscv/sim-main.c | 50 ++++++++++++++++++++++++++++ sim/testsuite/riscv/s-basic-arith.s | 51 +++++++++++++++++++++++++++++ 2 files changed, 101 insertions(+) diff --git a/sim/riscv/sim-main.c b/sim/riscv/sim-main.c index dd91431ad12..5d8ff9dc6ee 100644 --- a/sim/riscv/sim-main.c +++ b/sim/riscv/sim-main.c @@ -91,6 +91,11 @@ static const struct riscv_opcode *riscv_hash[OP_MASK_OP + 1]; #define FMSUB 8 #define FNMADD 9 #define FNMSUB 10 +#define FADD 11 +#define FSUB 12 +#define FMUL 13 +#define FDIV 14 +#define FSQRT 15 static INLINE void store_rd (SIM_CPU *cpu, int rd, unsigned_word val) @@ -942,6 +947,31 @@ float32_math (SIM_CPU *cpu, int rd, int rs1, int rs2, TRACE_INSN (cpu, "fmin.s %s, %s, %s;", frd_name, frs1_name, frs2_name); result = fminf (a, b); break; + case FADD: + TRACE_INSN (cpu, "fadd.s %s, %s, %s, rm=%d;", + frd_name, frs1_name, frs2_name, rm); + result = a + b; + break; + case FSUB: + TRACE_INSN (cpu, "fsub.s %s, %s, %s, rm=%d;", + frd_name, frs1_name, frs2_name, rm); + result = a - b; + break; + case FMUL: + TRACE_INSN (cpu, "fmul.s %s, %s, %s, rm=%d;", + frd_name, frs1_name, frs2_name, rm); + result = a * b; + break; + case FDIV: + TRACE_INSN (cpu, "fdiv.s %s, %s, %s, rm=%d;", + frd_name, frs1_name, frs2_name, rm); + result = a / b; + break; + case FSQRT: + TRACE_INSN (cpu, "fsqrt.s %s, %s, rm=%d;", + frd_name, frs1_name, rm); + result = sqrtf (a); + break; } if (rm == RMM) @@ -1173,6 +1203,26 @@ execute_f (SIM_CPU *cpu, unsigned_word iw, const struct riscv_opcode *op) case MATCH_FNMSUB_S | MASK_RM: float32_math (cpu, rd, rs1, rs2, rs3, rm, FNMSUB); break; + case MATCH_FADD_S: + case MATCH_FADD_S | MASK_RM: + float32_math (cpu, rd, rs1, rs2, rs3, rm, FADD); + break; + case MATCH_FSUB_S: + case MATCH_FSUB_S | MASK_RM: + float32_math (cpu, rd, rs1, rs2, rs3, rm, FSUB); + break; + case MATCH_FMUL_S: + case MATCH_FMUL_S | MASK_RM: + float32_math (cpu, rd, rs1, rs2, rs3, rm, FMUL); + break; + case MATCH_FDIV_S: + case MATCH_FDIV_S | MASK_RM: + float32_math (cpu, rd, rs1, rs2, rs3, rm, FDIV); + break; + case MATCH_FSQRT_S: + case MATCH_FSQRT_S | MASK_RM: + float32_math (cpu, rd, rs1, rs2, rs3, rm, FSQRT); + break; default: TRACE_INSN (cpu, "UNHANDLED INSN: %s", op->name); sim_engine_halt (sd, cpu, NULL, riscv_cpu->pc, sim_signalled, SIM_SIGILL); diff --git a/sim/testsuite/riscv/s-basic-arith.s b/sim/testsuite/riscv/s-basic-arith.s index a05a0d0a2c3..15d07f9e6cd 100644 --- a/sim/testsuite/riscv/s-basic-arith.s +++ b/sim/testsuite/riscv/s-basic-arith.s @@ -14,9 +14,16 @@ _arg1: .float -12.5 + .float 1.5 + .float 2.2 + .float 1.75 + .float 5.0 _arg2: .float 2.5 + .float 0.5 + .float 1.1 + .float 0.1 _arg3: .float 7.45 @@ -26,6 +33,11 @@ _result: .float 38.7000008 .float -38.7000008 .float 23.7999992 + .float 2.0 + .float 1.1 + .float 0.175 + .float 17.5 + .float 2.23606801 start .option push @@ -73,6 +85,45 @@ _result: feq.s a5,fa4,fa4 bne a5,a4,test_fail + # Test fadd instruction. + flw fa0,4(a0) + flw fa1,4(a1) + flw fa2,16(a3) + fadd.s fa4,fa0,fa1,rne + feq.s a5,fa4,fa2 + bne a5,a4,test_fail + + # Test fsub instruction. + flw fa0,8(a0) + flw fa1,8(a1) + flw fa2,20(a3) + fsub.s fa4,fa0,fa1,rne + feq.s a5,fa4,fa2 + bne a5,a4,test_fail + + # Test fmul instruction. + flw fa0,12(a0) + flw fa1,12(a1) + flw fa2,24(a3) + fmul.s fa4,fa0,fa1,rne + feq.s a5,fa4,fa2 + bne a5,a4,test_fail + + # Test fdiv instruction. + flw fa0,12(a0) # Use same input values as of fmul + flw fa1,12(a1) + flw fa2,28(a3) + fdiv.s fa4,fa0,fa1,rne + feq.s a5,fa4,fa2 + bne a5,a4,test_fail + + # Test fsqrt instruction. + flw fa0,16(a0) + flw fa2,32(a3) + fsqrt.s fa4,fa0,rne + feq.s a5,fa4,fa2 + bne a5,a4,test_fail + test_pass: pass From patchwork Mon Feb 26 14:26:23 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bhushan Attarde X-Patchwork-Id: 86384 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id DA92E3858295 for ; Mon, 26 Feb 2024 14:27:43 +0000 (GMT) X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from mx08-00376f01.pphosted.com (mx08-00376f01.pphosted.com [91.207.212.86]) by sourceware.org (Postfix) with ESMTPS id 3CA023858CDB for ; Mon, 26 Feb 2024 14:26:48 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 3CA023858CDB Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=imgtec.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=imgtec.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 3CA023858CDB Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=91.207.212.86 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1708957611; cv=none; b=q0BQ8YXiqQTo4NbBZVMU5U1qs8nWlws2ba8SlS5DTNJg+qLcReQHOZV7d21XBZpK6tTGEEHNaL4jcR12qM+tTvgrFZV02aV27QaCrNL5nnlIi4ITdLMIaHED8sNS82ADYVgbc4Vmda8HwClDxqo6UeZDFp2w3PARbvEEHtvVRDw= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1708957611; c=relaxed/simple; bh=7+zfq/x9hj6sqAAjTes7yPFzaIOvHWVodw/eKdKKnjI=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=rCOE1CZEG/mT6ZWbMZxBSGxJSsX++J4vZhSsBaCdJjgt+S124ZDoY5s69AQPCjC8fTvZqvtOEidrnUZ8Yxjv0KHzzuQVT8odFRKX5V9kTmny+snErK7l9hzu/oLPs4cTdpWP8CdbYucEuZAyUQLMQzIEz1dV3AK/9Np67wAV+NQ= ARC-Authentication-Results: i=1; server2.sourceware.org Received: from pps.filterd (m0168888.ppops.net [127.0.0.1]) by mx08-00376f01.pphosted.com (8.17.1.24/8.17.1.24) with ESMTP id 41Q86eF7005999; Mon, 26 Feb 2024 14:26:43 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=imgtec.com; h= from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding:content-type; s= dk201812; bh=62jYI+AR61uzw1nk41//VvptZ1hXw32zEMLeDZPqXqE=; b=IBZ oKnEcXoLwr2W44EyQZavPzRkhMSJ/+ykmKvoFMogXIG0KJHxRuKHJ+hR4ufz+AfU PzZbMqxltPXgg8LZSdHHoSAUdSFPUHVn5OYUt3K9VSnzk4ESe000d/xsIsX4s8vX Mg/DhKQOJvlZ6J/7PINb9lxvzwaQ/IVvMsQyz1d1AJci1ugW7ODBytHKnDC84OOw OPBqYQGkbrrKhfhbg5sD2AHrsXkvlGysVFJqEiwrUUqvgRwLnCfTtYJMrmkEu22U 1mHMGS6HHJs2oB/MV+Gv2VJ/yUNClH6eNvA+HGqLbQ9AWUvuYD1jIYgJqsoujUqf E1UXKrZZz21QlBQtILg== Received: from hhmail05.hh.imgtec.org ([217.156.249.195]) by mx08-00376f01.pphosted.com (PPS) with ESMTPS id 3wf7kssr69-3 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Mon, 26 Feb 2024 14:26:42 +0000 (GMT) Received: from hhbattarde.hh.imgtec.org (10.100.136.78) by HHMAIL05.hh.imgtec.org (10.100.10.120) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.35; Mon, 26 Feb 2024 14:26:41 +0000 From: To: CC: , , , Bhushan Attarde Subject: [PATCH 06/11] sim: riscv: Add single-precision floating-point conversion instructions Date: Mon, 26 Feb 2024 14:26:23 +0000 Message-ID: <20240226142628.1629048-3-bhushan.attarde@imgtec.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20240226142628.1629048-1-bhushan.attarde@imgtec.com> References: <20240226142628.1629048-1-bhushan.attarde@imgtec.com> MIME-Version: 1.0 X-Originating-IP: [10.100.136.78] X-ClientProxiedBy: HHMAIL05.hh.imgtec.org (10.100.10.120) To HHMAIL05.hh.imgtec.org (10.100.10.120) X-EXCLAIMER-MD-CONFIG: 15a78312-3e47-46eb-9010-2e54d84a9631 X-Proofpoint-GUID: 7KiQgf3IV_Yvm5rlQ3fNJK2vVaiNKF_D X-Proofpoint-ORIG-GUID: 7KiQgf3IV_Yvm5rlQ3fNJK2vVaiNKF_D X-Spam-Status: No, score=-12.8 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_LOW, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org From: Bhushan Attarde Added simulation of following single precision floating-point instructions fcvt.w.s, fcvt.wu.s, fcvt.s.w, fcvt.s.wu, fcvt.l.s, fcvt.lu.s, fcvt.s.l and fcvt.s.lu. Added test files s-conversion.s and s-conversion-l.s in sim/testsuite/riscv/s-conversion.s to test these instructions. --- sim/riscv/sim-main.c | 265 +++++++++++++++++++++++++++ sim/testsuite/riscv/s-conversion-l.s | 60 ++++++ sim/testsuite/riscv/s-conversion.s | 61 ++++++ 3 files changed, 386 insertions(+) create mode 100644 sim/testsuite/riscv/s-conversion-l.s create mode 100644 sim/testsuite/riscv/s-conversion.s diff --git a/sim/riscv/sim-main.c b/sim/riscv/sim-main.c index 5d8ff9dc6ee..4d4ad82cce9 100644 --- a/sim/riscv/sim-main.c +++ b/sim/riscv/sim-main.c @@ -97,6 +97,9 @@ static const struct riscv_opcode *riscv_hash[OP_MASK_OP + 1]; #define FDIV 14 #define FSQRT 15 +#define UNSIGNED 0 +#define SIGNED 1 + static INLINE void store_rd (SIM_CPU *cpu, int rd, unsigned_word val) { @@ -1033,6 +1036,224 @@ float32_math (SIM_CPU *cpu, int rd, int rs1, int rs2, } } +/* Round and return the float value. This function is used before we + perform any operation on the input float value. */ +static float +round_float_input (float value, int rm) +{ + float result = value; + if (rm == RNE) + { + float fractional_part = value - truncf (value); + /* Check if the number is halfway between two values. */ + if (fractional_part == 0.5 || fractional_part == -0.5) + { + result = floorf (value); + if (fmod (result, 2.0) != 0) + result += (value > 0) ? 1.0 : -1.0; + } + else + result = roundf (value); + } + else if (rm == RTZ) + result = truncf (value); + else if (rm == RDN) + result = floorf (value); + else if (rm == RUP) + result = ceilf (value); + else + { + /* No direct match for RMM. Simulate it. */ + float fracPart = value - (int) value; + if (fracPart > 0.5f || fracPart < -0.5f) + result = roundf (value); + else if (fracPart == 0.5f) + result = ceilf (value); + else if (fracPart == -0.5f) + result = floorf (value); + else + result = value; + } + return result; +} + +/* Round and return the float value. This function is used after we + perform the operation to get the result rounded. */ +static float +round_float_output (float value, int rm) +{ + float result; + if (rm == RNE) + result = value; + else if (rm == RTZ) + result = truncf (value); + else if (rm == RDN) + result = floorf (value); + else if (rm == RUP) + result = ceilf (value); + else + { + /* No direct match for RMM. Simulate it. */ + float fracPart = value - (int) value; + if (fracPart > 0.5f || fracPart < -0.5f) + result = roundf (value); + else if (fracPart == 0.5f) + result = ceilf (value); + else if (fracPart == -0.5f) + result = floorf (value); + else + result = value; + } + return result; +} + +static void +convert_float_to_int (SIM_CPU *cpu, int rd, int rs1, int sign, + int rm, int is_32bit) +{ + struct riscv_sim_cpu *riscv_cpu = RISCV_SIM_CPU (cpu); + float src, rounded; + uint32_t rs1_bits; + rs1_bits = (uint32_t) riscv_cpu->fpregs[rs1]; + memcpy (&src, &rs1_bits, sizeof (src)); + + if (rm == DYN) + rm = riscv_cpu->csr.frm; + + /* Get the input rounded. */ + rounded = round_float_input (src, rm); + + if (sign == SIGNED) + { + if (is_32bit) + store_rd (cpu, rd, (int) rounded); + else + store_rd (cpu, rd, (int64_t) rounded); + } + else + { + if (is_32bit) + store_rd (cpu, rd, (uint32_t) rounded); + else + store_rd (cpu, rd, (uint64_t) rounded); + } +} + +static void +convert_int_to_float (SIM_CPU *cpu, int rd, int rs1, int sign, + int rm) +{ + struct riscv_sim_cpu *riscv_cpu = RISCV_SIM_CPU (cpu); + uint32_t rd_bits; + uint32_t usrc = (uint32_t) riscv_cpu->regs[rs1]; + int32_t isrc = (int32_t) riscv_cpu->regs[rs1]; + float result = .0f; + int old_rm; + if (rm == DYN) + rm = riscv_cpu->csr.frm; + + if (rm == RMM) + { + if (sign == SIGNED) + { + if (isrc >= 0) + { + fesetround (FE_UPWARD); + result = (float) isrc; + result = ceilf (result); + } + else + { + fesetround (FE_DOWNWARD); + result = (float) isrc; + result = floorf (result); + } + } + else + { + /* Since it's unsigned, it's always positive. */ + fesetround (FE_UPWARD); + result = (float) usrc; + result = ceilf (result); + } + } + else + { + old_rm = set_riscv_rounding_mode (rm); + + if (sign == SIGNED) + result = (float) isrc; + else + result = (float) usrc; + + /* Get the result rounded. */ + result = round_float_output (result, rm); + /* Restore rounding mode. */ + fesetround (old_rm); + } + /* Store the result. */ + memcpy (&rd_bits, &result, sizeof (result)); + store_fp (cpu, rd, rd_bits); +} + +static void +convert_long_to_float (SIM_CPU *cpu, int rd, int rs1, int sign, + int rm) +{ + struct riscv_sim_cpu *riscv_cpu = RISCV_SIM_CPU (cpu); + uint32_t rd_bits; + uint64_t usrc = (uint64_t) riscv_cpu->regs[rs1]; + int64_t isrc = (int64_t) riscv_cpu->regs[rs1]; + float result = .0f; + int old_rm; + + if (rm == DYN) + rm = riscv_cpu->csr.frm; + + if (rm == RMM) + { + if (sign == SIGNED) + { + if (isrc > 0) + { + fesetround (FE_UPWARD); + result = (float) isrc; + result = ceilf (result); + } + else + { + fesetround (FE_DOWNWARD); + result = (float) isrc; + result = floorf (result); + } + } + else + { + /* Since it's unsigned, it's always positive. */ + fesetround (FE_UPWARD); + result = (float) usrc; + result = ceilf (result); + } + } + else + { + old_rm = set_riscv_rounding_mode (rm); + + if (sign == SIGNED) + result = (float) isrc; + else + result = (float) usrc; + + /* Get the result rounded. */ + result = round_float_output (result, rm); + /* Restore rounding mode. */ + fesetround (old_rm); + } + /* Store the result. */ + memcpy (&rd_bits, &result, sizeof (result)); + store_fp (cpu, rd, rd_bits); +} + /* Simulate single precision floating point instructions. */ static sim_cia execute_f (SIM_CPU *cpu, unsigned_word iw, const struct riscv_opcode *op) @@ -1223,6 +1444,50 @@ execute_f (SIM_CPU *cpu, unsigned_word iw, const struct riscv_opcode *op) case MATCH_FSQRT_S | MASK_RM: float32_math (cpu, rd, rs1, rs2, rs3, rm, FSQRT); break; + case MATCH_FCVT_W_S: + case MATCH_FCVT_W_S | MASK_RM: + TRACE_INSN (cpu, "fcvt.w.s %s, %s, rm=%d;", rd_name, rs1_name, rm); + convert_float_to_int (cpu, rd, rs1, SIGNED, rm, is_32bit); + break; + case MATCH_FCVT_WU_S: + case MATCH_FCVT_WU_S | MASK_RM: + TRACE_INSN (cpu, "fcvt.wu.s %s, %s, rm=%d;", rd_name, rs1_name, rm); + convert_float_to_int (cpu, rd, rs1, UNSIGNED, rm, is_32bit); + break; + case MATCH_FCVT_S_W: + case MATCH_FCVT_S_W | MASK_RM: + TRACE_INSN (cpu, "fcvt.s.w %s, %s, rm=%d;", rd_name, rs1_name, rm); + convert_int_to_float (cpu, rd, rs1, SIGNED, rm); + break; + case MATCH_FCVT_S_WU: + case MATCH_FCVT_S_WU | MASK_RM: + TRACE_INSN (cpu, "fcvt.s.wu %s, %s, rm=%d;", rd_name, rs1_name, rm); + convert_int_to_float (cpu, rd, rs1, UNSIGNED, rm); + break; + case MATCH_FCVT_L_S: + case MATCH_FCVT_L_S | MASK_RM: + TRACE_INSN (cpu, "fcvt.l.s %s, %s, rm=%d;", rd_name, rs1_name, rm); + RISCV_ASSERT_RV64 (cpu, "insn: %s", op->name); + convert_float_to_int (cpu, rd, rs1, SIGNED, rm, is_32bit); + break; + case MATCH_FCVT_LU_S: + case MATCH_FCVT_LU_S | MASK_RM: + TRACE_INSN (cpu, "fcvt.lu.s %s, %s, rm=%d;", rd_name, rs1_name, rm); + RISCV_ASSERT_RV64 (cpu, "insn: %s", op->name); + convert_float_to_int (cpu, rd, rs1, UNSIGNED, rm, is_32bit); + break; + case MATCH_FCVT_S_L: + case MATCH_FCVT_S_L | MASK_RM: + TRACE_INSN (cpu, "fcvt.s.l %s, %s, rm=%d;", rd_name, rs1_name, rm); + RISCV_ASSERT_RV64 (cpu, "insn: %s", op->name); + convert_long_to_float (cpu, rd, rs1, SIGNED, rm); + break; + case MATCH_FCVT_S_LU: + case MATCH_FCVT_S_LU | MASK_RM: + TRACE_INSN (cpu, "fcvt.s.lu %s, %s, rm=%d;", rd_name, rs1_name, rm); + RISCV_ASSERT_RV64 (cpu, "insn: %s", op->name); + convert_long_to_float (cpu, rd, rs1, UNSIGNED, rm); + break; default: TRACE_INSN (cpu, "UNHANDLED INSN: %s", op->name); sim_engine_halt (sd, cpu, NULL, riscv_cpu->pc, sim_signalled, SIM_SIGILL); diff --git a/sim/testsuite/riscv/s-conversion-l.s b/sim/testsuite/riscv/s-conversion-l.s new file mode 100644 index 00000000000..a3b0f264d47 --- /dev/null +++ b/sim/testsuite/riscv/s-conversion-l.s @@ -0,0 +1,60 @@ +# Single precision conversion tests only for RV64. +# mach: riscv64 +# sim(riscv64): --model RV64ID +# ld(riscv64): -m elf64lriscv +# as(riscv64): -march=rv64id + +.include "testutils.inc" + + .section .rodata + .align 2 + +_arg1: + .float -3e9 + .float 3e9 + .dword 16777217 + +_result: + .dword -3000000000 + .dword 3000000000 + .float 16777216 + + start + .option push + .option norelax + la a0,_arg1 + la a1,_result + li a2,1 + .option pop + + # Test fcvt.l.s instruction. + flw fa0,0(a0) + ld a3,0(a1) + fcvt.l.s a5,fa0,rne + bne a5,a3,test_fail + + # Test fcvt.lu.s instruction. + flw fa0,4(a0) + ld a3,8(a1) + fcvt.lu.s a5,fa0,rne + bne a5,a3,test_fail + + # Test fcvt.s.l instruction. + ld a3,8(a0) + flw fa0,16(a1) + fcvt.s.l fa1,a3,rne + feq.s a4,fa0,fa1 + bne a4,a2,test_fail + + # Test fcvt.s.lu instruction. + ld a3,8(a0) + flw fa0,16(a1) + fcvt.s.l fa1,a3,rne + feq.s a4,fa0,fa1 + bne a4,a2,test_fail + +test_pass: + pass + +test_fail: + fail diff --git a/sim/testsuite/riscv/s-conversion.s b/sim/testsuite/riscv/s-conversion.s new file mode 100644 index 00000000000..e87059c1d2f --- /dev/null +++ b/sim/testsuite/riscv/s-conversion.s @@ -0,0 +1,61 @@ +# Single precision conversion tests. +# mach: riscv32 riscv64 +# sim(riscv32): --model RV32IF +# sim(riscv64): --model RV64ID +# ld(riscv32): -m elf32lriscv +# ld(riscv64): -m elf64lriscv +# as(riscv32): -march=rv32if +# as(riscv64): -march=rv64id + +.include "testutils.inc" + + .section .rodata + .align 2 + +_arg1: + .float 123.49 + .word 123 + +_result: + .word 123 + .float 123.0 + + start + .option push + .option norelax + la a0,_arg1 + la a1,_result + li a2,1 + .option pop + + # Test fcvt.w.s instruction. + flw fa0,0(a0) + lw a3,0(a1) + fcvt.w.s a5,fa0,rne + bne a3,a5,test_fail + + # Test fcvt.wu.s instruction. + flw fa0,0(a0) + lw a3,0(a1) + fcvt.wu.s a5,fa0,rne + bne a3,a5,test_fail + + # Test fcvt.s.w instruction. + lw a3,4(a0) + flw fa0,4(a1) + fcvt.s.w fa1,a3,rne + feq.s a4,fa0,fa1 + bne a4,a2,test_fail + + # Test fcvt.s.wu instruction. + lw a3,4(a0) + flw fa0,4(a1) + fcvt.s.wu fa1,a3,rne + feq.s a4,fa0,fa1 + bne a4,a2,test_fail + +test_pass: + pass + +test_fail: + fail From patchwork Mon Feb 26 14:26:24 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bhushan Attarde X-Patchwork-Id: 86385 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id BBAEF385829E for ; Mon, 26 Feb 2024 14:27:46 +0000 (GMT) X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from mx08-00376f01.pphosted.com (mx08-00376f01.pphosted.com [91.207.212.86]) by sourceware.org (Postfix) with ESMTPS id CCF163858C62 for ; Mon, 26 Feb 2024 14:26:48 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org CCF163858C62 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=imgtec.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=imgtec.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org CCF163858C62 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=91.207.212.86 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1708957611; cv=none; b=QThFLxq6HoQ3gre6nYxgGsI48yYFuBbsr/tqJ1QBVCs/0WknWEApIixLkfuK4+2u1dY0Nz63uVyStkTDLjnEe6Tud9OZGaiE6BidW3ZUnst2LPozJ0CKCeYS7NKvlFxThA124JEQYoRG1LTKWlbWVu19zh1U3CEqByRmuW2SsSI= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1708957611; c=relaxed/simple; bh=G9URGoJxCozmRHhzwy9+RAEr7GHW2IZcyGkqziSY6zM=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=fwA/eARNbSjkjAqqWpUpP5jNMEPIlQXGMkj2Ii8rTa+cWKtJXWgyAbZMLhlFFBdWxTRK9ojyOpI5iinqVlPm8LAIQxoQo90wE/88PaheE4SRJKKhqcDgeWrFwHseU3hHj/ehQrgq4kEZ1gws6mvCZs0tli21Q/LAATw7CBToClg= ARC-Authentication-Results: i=1; server2.sourceware.org Received: from pps.filterd (m0168888.ppops.net [127.0.0.1]) by mx08-00376f01.pphosted.com (8.17.1.24/8.17.1.24) with ESMTP id 41Q86eF8005999; Mon, 26 Feb 2024 14:26:43 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=imgtec.com; h= from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding:content-type; s= dk201812; bh=EH/mp1vIGfn2whQ3tMpMwnhktz+64xvzskW7G8jYIPA=; b=eWq ZkHtJqlblX8yw8TeIWFcHtIp8clIQdf946MD1igBY60ZMj5JoWt0aHyUmGT7WTxF 4CNYL3jaXcTowN7NYpzT2Hu3Clfj+1oDdgiaAQzpzcMIuA/QY8JBZsqzfVs+iosm T7aKer+B1MhdvxqKdCu86gBojItXjTDHXgVzdtknfIhM2HYZQxElis3GGd1KIzH5 FPgpK0QxQllvPDUjtN+ZspoL0mTFgzPsoPSaahqxPW2+yvIFLcE7SvMxDuLT2cda qtmhvGRK8RK29ZH3ovUhFw1cLVLoVSvhCdwVGZSE3Avf4yyZT4bMTnCSXYmw/vg8 xz/6q7bJV982uVFwjfw== Received: from hhmail05.hh.imgtec.org ([217.156.249.195]) by mx08-00376f01.pphosted.com (PPS) with ESMTPS id 3wf7kssr69-4 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Mon, 26 Feb 2024 14:26:43 +0000 (GMT) Received: from hhbattarde.hh.imgtec.org (10.100.136.78) by HHMAIL05.hh.imgtec.org (10.100.10.120) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.35; Mon, 26 Feb 2024 14:26:41 +0000 From: To: CC: , , , Bhushan Attarde Subject: [PATCH 07/11] sim: riscv: Add double precision floating-point load-store, move, compare and classify instructions Date: Mon, 26 Feb 2024 14:26:24 +0000 Message-ID: <20240226142628.1629048-4-bhushan.attarde@imgtec.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20240226142628.1629048-1-bhushan.attarde@imgtec.com> References: <20240226142628.1629048-1-bhushan.attarde@imgtec.com> MIME-Version: 1.0 X-Originating-IP: [10.100.136.78] X-ClientProxiedBy: HHMAIL05.hh.imgtec.org (10.100.10.120) To HHMAIL05.hh.imgtec.org (10.100.10.120) X-EXCLAIMER-MD-CONFIG: 15a78312-3e47-46eb-9010-2e54d84a9631 X-Proofpoint-GUID: MGuKWAlIR_biIgqqgQt69Oaxcmkguojs X-Proofpoint-ORIG-GUID: MGuKWAlIR_biIgqqgQt69Oaxcmkguojs X-Spam-Status: No, score=-12.8 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_LOW, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org From: Bhushan Attarde Added simulation of following single precision floating-point instructions fld, fsd, fmv.x.d, fmv.d.x, fsgnj.d, feq.d, flt.d, fle.d and fclass.d. Added test files d-fp-compare.s and d-fp-load-store.s in sim/testsuite/riscv/ to test these instructions. --- sim/riscv/sim-main.c | 183 ++++++++++++++++++++++++++ sim/testsuite/riscv/d-fp-compare.s | 72 ++++++++++ sim/testsuite/riscv/d-fp-load-store.s | 58 ++++++++ 3 files changed, 313 insertions(+) create mode 100755 sim/testsuite/riscv/d-fp-compare.s create mode 100755 sim/testsuite/riscv/d-fp-load-store.s diff --git a/sim/riscv/sim-main.c b/sim/riscv/sim-main.c index 4d4ad82cce9..4313516b8b7 100644 --- a/sim/riscv/sim-main.c +++ b/sim/riscv/sim-main.c @@ -1254,6 +1254,111 @@ convert_long_to_float (SIM_CPU *cpu, int rd, int rs1, int sign, store_fp (cpu, rd, rd_bits); } +/* Handle double precision floating point compare instructions. */ +static void +float64_compare (SIM_CPU *cpu, int rd, int rs1, int rs2, int flags) +{ + struct riscv_sim_cpu *riscv_cpu = RISCV_SIM_CPU (cpu); + double a, b = .0f; + uint64_t result = 0, exception = 0, sign = 0, bit_pos; + uint64_t rs1_bits, rs2_bits; + const char *rd_name = riscv_gpr_names_abi[rd]; + const char *frs1_name = riscv_fpr_names_abi[rs1]; + const char *frs2_name = riscv_fpr_names_abi[rs2]; + + rs1_bits = (uint64_t) riscv_cpu->fpregs[rs1]; + memcpy (&a, &rs1_bits, sizeof (a)); + if (flags != FCLASS) + { + rs2_bits = (uint64_t) riscv_cpu->fpregs[rs2]; + memcpy (&b, &rs2_bits, sizeof (b)); + } + + switch (flags) + { + case FEQ: + TRACE_INSN (cpu, "feq.d %s, %s, %s;", rd_name, frs1_name, frs2_name); + if (__isnan (a) || __isnan (b)) + { + result = 0; + if (__issignaling (a) || __issignaling (b)) + exception = 1; + } + else + result = (a == b); + break; + case FLT: + TRACE_INSN (cpu, "flt.d %s, %s, %s;", rd_name, frs1_name, frs2_name); + if (__isnan (a) || __isnan (b)) + { + result = 0; + exception = 1; + } + else + result = (a < b); + break; + case FLE: + TRACE_INSN (cpu, "fle.d %s, %s, %s;", rd_name, frs1_name, frs2_name); + if (__isnan (a) || __isnan (b)) + { + result = 0; + exception = 1; + } + else + result = (a <= b); + break; + case FCLASS: + TRACE_INSN (cpu, "fclass.d %s, %s;", rd_name, frs1_name); + bit_pos = 0; + exception = 0; + result = riscv_cpu->regs[rd]; + sign = __signbit (a); + if (__isinf (a)) + { + if (sign) + bit_pos = 0; /* -INF. */ + else + bit_pos = 7; /* +INF. */ + } + else if (fpclassify (a) == FP_SUBNORMAL) + { + if (sign) + bit_pos = 2; /* -SUBNORMAL. */ + else + bit_pos = 5; /* +SUBNORMAL. */ + } + else if (fpclassify (a) == FP_ZERO) + { + if (sign) + bit_pos = 3; /* -ZERO. */ + else + bit_pos = 4; /* +ZERO. */ + } + else if (__issignaling (a)) + bit_pos = 8; /* signaling NaN. */ + else if (__isnan (a)) + bit_pos = 9; /* quiet NaN. */ + else + { + if (sign) + bit_pos = 1; /* -NORMAL. */ + else + bit_pos = 6; /* +NORMAL. */ + } + result |= (1 << bit_pos); + break; + } + + store_rd (cpu, rd, result); + + if (exception) + { + riscv_cpu->csr.fcsr |= FCSR_NV; + riscv_cpu->csr.fflags |= FCSR_NV; + TRACE_REGISTER (cpu, "wrote CSR fcsr |= NV"); + } +} + /* Simulate single precision floating point instructions. */ static sim_cia execute_f (SIM_CPU *cpu, unsigned_word iw, const struct riscv_opcode *op) @@ -1496,6 +1601,81 @@ execute_f (SIM_CPU *cpu, unsigned_word iw, const struct riscv_opcode *op) return pc; } +/* Simulate double precision floating point instructions. */ +static sim_cia +execute_d (SIM_CPU *cpu, unsigned_word iw, const struct riscv_opcode *op) +{ + struct riscv_sim_cpu *riscv_cpu = RISCV_SIM_CPU (cpu); + SIM_DESC sd = CPU_STATE (cpu); + int rd = (iw >> OP_SH_RD) & OP_MASK_RD; + int rs1 = (iw >> OP_SH_RS1) & OP_MASK_RS1; + int rs2 = (iw >> OP_SH_RS2) & OP_MASK_RS2; + const char *frd_name = riscv_fpr_names_abi[rd]; + const char *rd_name = riscv_gpr_names_abi[rd]; + const char *frs1_name = riscv_fpr_names_abi[rs1]; + const char *frs2_name = riscv_fpr_names_abi[rs2]; + const char *rs1_name = riscv_gpr_names_abi[rs1]; + signed_word i_imm = EXTRACT_ITYPE_IMM (iw); + signed_word s_imm = EXTRACT_STYPE_IMM (iw); + + sim_cia pc = riscv_cpu->pc + 4; + + switch (op->match) + { + case MATCH_FLD: + TRACE_INSN (cpu, "fld %s, %" PRIiTW "(%s);", + frd_name, i_imm, rs1_name); + store_fp (cpu, rd, sim_core_read_unaligned_8 + (cpu, riscv_cpu->pc, read_map, + riscv_cpu->regs[rs1] + i_imm)); + break; + case MATCH_FSD: + TRACE_INSN (cpu, "fsd %s, %" PRIiTW "(%s);", + frs2_name, s_imm, rs1_name); + sim_core_write_unaligned_8 + (cpu, riscv_cpu->pc, write_map, + riscv_cpu->regs[rs1] + s_imm, riscv_cpu->fpregs[rs2]); + break; + case MATCH_FMV_X_D: + TRACE_INSN (cpu, "fmv.x.d %s, %s;", rd_name, frs1_name); + store_rd (cpu, rd, riscv_cpu->fpregs[rs1]); + break; + case MATCH_FMV_D_X: + TRACE_INSN (cpu, "fmv.d.x %s, %s;", frd_name, rs1_name); + store_fp (cpu, rd, riscv_cpu->regs[rs1]); + break; + case MATCH_FEQ_D: + float64_compare (cpu, rd, rs1, rs2, FEQ); + break; + case MATCH_FLT_D: + float64_compare (cpu, rd, rs1, rs2, FLT); + break; + case MATCH_FLE_D: + float64_compare (cpu, rd, rs1, rs2, FLE); + break; + case MATCH_FCLASS_D: + float64_compare (cpu, rd, rs1, 0, FCLASS); + break; + case MATCH_FSGNJ_D: + { + uint64_t rs1_bits, rs2_bits; + TRACE_INSN (cpu, "fsgnj.d %s, %s, %s;", + frd_name, frs1_name, frs2_name); + rs1_bits = (uint64_t) riscv_cpu->fpregs[rs1]; + rs2_bits = (uint64_t) riscv_cpu->fpregs[rs2]; + rs1_bits = (rs2_bits & 0x8000000000000000ull) + | (rs1_bits & 0x7fffffffffffffffull); + store_fp (cpu, rd, rs1_bits); + break; + } + default: + TRACE_INSN (cpu, "UNHANDLED INSN: %s", op->name); + sim_engine_halt (sd, cpu, NULL, riscv_cpu->pc, sim_signalled, SIM_SIGILL); + } + + return pc; +} + static sim_cia execute_m (SIM_CPU *cpu, unsigned_word iw, const struct riscv_opcode *op) { @@ -2127,6 +2307,9 @@ execute_one (SIM_CPU *cpu, unsigned_word iw, const struct riscv_opcode *op) sim_engine_halt (sd, cpu, NULL, riscv_cpu->pc, sim_signalled, SIM_SIGILL); } + case INSN_CLASS_D: + case INSN_CLASS_D_INX: + return execute_d (cpu, iw, op); case INSN_CLASS_F: case INSN_CLASS_F_INX: return execute_f (cpu, iw, op); diff --git a/sim/testsuite/riscv/d-fp-compare.s b/sim/testsuite/riscv/d-fp-compare.s new file mode 100755 index 00000000000..0e168fed9de --- /dev/null +++ b/sim/testsuite/riscv/d-fp-compare.s @@ -0,0 +1,72 @@ +# Double precision compare and classify tests. +# mach: riscv64 +# sim(riscv64): --model RV64ID +# ld(riscv64): -m elf64lriscv +# as(riscv64): -march=rv64id + +.include "testutils.inc" + + .section .data + .align 3 + +_arg1: + .double 0.5 + .double 1.1 + .dword 0xfff0000000000000 # -INF + .dword 0x7ff4000000000000 # sNAN + .dword 0x7ff8000000000000 # qNAN + +_arg2: + .double 0.5 + .double 2.2 + + start + .option push + .option norelax + la a0,_arg1 + la a1,_arg2 + li a3,1 + .option pop + + # Test feq instruction. + fld fa0,0(a0) + fld fa1,0(a1) + feq.d a4,fa0,fa1 + bne a4,a3,test_fail + + # Test flt instruction. + fld fa0,8(a0) + fld fa1,8(a1) + mv a4,x0 + flt.d a4,fa0,fa1 + bne a4,a3,test_fail + + # Test fle instruction. + fld fa0,8(a0) + fld fa1,8(a1) + mv a4,x0 + fle.d a4,fa0,fa1 + bne a4,a3,test_fail + + # Test fclass instruction. + fld fa0,16(a0) + mv a4,x0 + li a3,0x1 # 1 << 0 + fclass.d a4,fa0 + bne a3,a4,test_fail + fld fa0,24(a0) + mv a4,x0 + li a3,0x100 # 1 << 8 + fclass.d a4,fa0 + bne a3,a4,test_fail + fld fa0,32(a0) + mv a4,x0 + li a3,0x200 # 1 << 9 + fclass.d a4,fa0 + bne a3,a4,test_fail + +test_pass: + pass + +test_fail: + fail diff --git a/sim/testsuite/riscv/d-fp-load-store.s b/sim/testsuite/riscv/d-fp-load-store.s new file mode 100755 index 00000000000..1eccf5720a9 --- /dev/null +++ b/sim/testsuite/riscv/d-fp-load-store.s @@ -0,0 +1,58 @@ +# Double precision load-store and move tests. +# mach: riscv64 +# sim(riscv64): --model RV64ID +# ld(riscv64): -m elf64lriscv +# as(riscv64): -march=rv64id + +.include "testutils.inc" + + .section .data + .align 3 + +_src: + .double 0.5 + +_dst: + .double 0.5 + .double 0 + .dword 0x3FE0000000000000 # 0.5 + + start + .option push + .option norelax + la a0,_src + la a1,_dst + li a3,1 + .option pop + + # Test load instruction. + fld fa0,0(a0) + fld fa1,0(a1) + feq.d a4,fa0,fa1 + bne a4,a3,test_fail + + # Test store instruction. + fld fa0,0(a0) + fsd fa0,8(a1) + fld fa1,8(a1) + feq.d a4,fa0,fa1 + bne a4,a3,test_fail + + # Test convert double value to integer encoding instruction. + fld fa0,0(a0) # load double value. + ld a4,16(a1) # load expected result. + fmv.x.d a2,fa0 # convert bit pattern into integer register. + bne a4,a2,test_fail # compare result with expected. + + # Test convert integer encoding to double value instruction. + lw a4,16(a1) # load integer encoding. + fmv.d.x fa1,a4 # convert encoding into double value. + flw fa0,0(a0) # load expected double value. + feq.d a5,fa0,fa1 # compare result with expected. + bne a5,a3,test_fail + +test_pass: + pass + +test_fail: + fail From patchwork Mon Feb 26 14:26:25 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bhushan Attarde X-Patchwork-Id: 86383 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 8BBBC385829E for ; Mon, 26 Feb 2024 14:27:37 +0000 (GMT) X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from mx08-00376f01.pphosted.com (mx08-00376f01.pphosted.com [91.207.212.86]) by sourceware.org (Postfix) with ESMTPS id 917753858C55 for ; Mon, 26 Feb 2024 14:26:48 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 917753858C55 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=imgtec.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=imgtec.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 917753858C55 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=91.207.212.86 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1708957610; cv=none; b=KnFuHfvZGOdy9FbQrauGbAqmfgC5Jf7o0WZNnTi3S+Q7G1CHifs49FfYLVK9SWp+lER1hmHZU02zUk3hKegXmTxKBuQYURqoCnWv3I4A5UYuc6bzOsccWBiNeixMKEKFWw7PbkFM6G3tNfTaD9w9n44L8LfFg8+qfRvLWw6hHwM= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1708957610; c=relaxed/simple; bh=5FfjP2yV8M+rW2jBSUkJz2GZPr9ge3gdctwJ5cJ+I0E=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=mY4ZZo2x0dPXaJtnHNuz8ppcqkwKmRrlRU728GiGn9MWJVZXxnkPLMghTRGdn5gDaaG8X8u6AzMLG7vWa82hy+PuV1MsC80KZInebqEGiHwmJe1shQ5gYrc7TziOY1K0DmaC70cv7cBjJ1VKaE8WfJr4PbVIxzFdkReoY/Ukxgw= ARC-Authentication-Results: i=1; server2.sourceware.org Received: from pps.filterd (m0168888.ppops.net [127.0.0.1]) by mx08-00376f01.pphosted.com (8.17.1.24/8.17.1.24) with ESMTP id 41Q86eF9005999; Mon, 26 Feb 2024 14:26:43 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=imgtec.com; h= from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding:content-type; s= dk201812; bh=DEhc93K/fSE+h0AHHjPyqDxTCebbJV7jw4R1ePcXPco=; b=tuB Z9PmzmI+tWfgOHLXDWiQ153RuBMHSCF9TOjGLBByLmR/SqDOnn+h0j/HqxbE3vv4 JNBjUO2cxpUKCUni2KlSpfWO01otdEr5KmlQUScpAnpJMt1TSM626udmffYnFqOb Fhd5okr8apl3eiP7o1HiE6XzI6UJzTzgCbq6pGSZujMYG+YLxyNT32lzy8pAF29U G1zHN3XUR2TiI2ZdAu29wQiuJsr++Ckll7o2LAfUvgwbRph8aKIPTxdOKnXTaV+h PFKK72XW9qiTVGzTBM6IVokZ2hHC0HJ1jqUQ83CqYKX/wNxdB+n4DtnLvQXfnrae 2nbHCwO9W+6+RwNqmqg== Received: from hhmail05.hh.imgtec.org ([217.156.249.195]) by mx08-00376f01.pphosted.com (PPS) with ESMTPS id 3wf7kssr69-5 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Mon, 26 Feb 2024 14:26:43 +0000 (GMT) Received: from hhbattarde.hh.imgtec.org (10.100.136.78) by HHMAIL05.hh.imgtec.org (10.100.10.120) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.35; Mon, 26 Feb 2024 14:26:42 +0000 From: To: CC: , , , Bhushan Attarde Subject: [PATCH 08/11] sim: riscv: Add double precision floating-point sign-injection, min and max instructions Date: Mon, 26 Feb 2024 14:26:25 +0000 Message-ID: <20240226142628.1629048-5-bhushan.attarde@imgtec.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20240226142628.1629048-1-bhushan.attarde@imgtec.com> References: <20240226142628.1629048-1-bhushan.attarde@imgtec.com> MIME-Version: 1.0 X-Originating-IP: [10.100.136.78] X-ClientProxiedBy: HHMAIL05.hh.imgtec.org (10.100.10.120) To HHMAIL05.hh.imgtec.org (10.100.10.120) X-EXCLAIMER-MD-CONFIG: 15a78312-3e47-46eb-9010-2e54d84a9631 X-Proofpoint-GUID: Lkb1YKxGdDm28Kdcd0w4sY1aUWwZB8vN X-Proofpoint-ORIG-GUID: Lkb1YKxGdDm28Kdcd0w4sY1aUWwZB8vN X-Spam-Status: No, score=-12.8 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_LOW, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org From: Bhushan Attarde Added simulation of following single precision floating-point instructions fsgnjn.d, fsgnjx.d, fmin.d and fmax.d. Updated test file d-fp-compare.s and added d-fp-sign-inject.s in sim/testsuite/riscv/ to test these instructions. --- sim/riscv/sim-main.c | 65 +++++++++++++++++++ sim/testsuite/riscv/d-fp-compare.s | 22 +++++++ sim/testsuite/riscv/d-fp-sign-inject.s | 87 ++++++++++++++++++++++++++ 3 files changed, 174 insertions(+) create mode 100644 sim/testsuite/riscv/d-fp-sign-inject.s diff --git a/sim/riscv/sim-main.c b/sim/riscv/sim-main.c index 4313516b8b7..4f347fbfc5e 100644 --- a/sim/riscv/sim-main.c +++ b/sim/riscv/sim-main.c @@ -1359,6 +1359,40 @@ float64_compare (SIM_CPU *cpu, int rd, int rs1, int rs2, int flags) } } +/* Handle double precision floating point math instructions. */ +static void +float64_math (SIM_CPU *cpu, int rd, int rs1, int rs2, int flags) +{ + struct riscv_sim_cpu *riscv_cpu = RISCV_SIM_CPU (cpu); + double a, b, result = 0; + uint64_t rs1_bits, rs2_bits, rd_bits; + const char *frd_name = riscv_fpr_names_abi[rd]; + const char *frs1_name = riscv_fpr_names_abi[rs1]; + const char *frs2_name = riscv_fpr_names_abi[rs2]; + + rs1_bits = (uint64_t) riscv_cpu->fpregs[rs1]; + memcpy (&a, &rs1_bits, sizeof (a)); + rs2_bits = (uint64_t) riscv_cpu->fpregs[rs2]; + memcpy (&b, &rs2_bits, sizeof (b)); + + switch (flags) + { + case FMAX: + TRACE_INSN (cpu, "fmax.d %s, %s, %s;", frd_name, frs1_name, frs2_name); + result = fmax (a, b); + break; + case FMIN: + TRACE_INSN (cpu, "fmin.d %s, %s, %s;", frd_name, frs1_name, frs2_name); + result = fmin (a, b); + break; + } + + /* Store result. */ + memcpy (&rd_bits, &result, sizeof (result)); + store_fp (cpu, rd, rd_bits); + +} + /* Simulate single precision floating point instructions. */ static sim_cia execute_f (SIM_CPU *cpu, unsigned_word iw, const struct riscv_opcode *op) @@ -1668,6 +1702,37 @@ execute_d (SIM_CPU *cpu, unsigned_word iw, const struct riscv_opcode *op) store_fp (cpu, rd, rs1_bits); break; } + case MATCH_FSGNJN_D: + { + uint64_t rs1_bits, rs2_bits; + TRACE_INSN (cpu, "fsgnjn.d %s, %s, %s;", frd_name, frs1_name, + frs2_name); + rs1_bits = (uint64_t) riscv_cpu->fpregs[rs1]; + rs2_bits = ~((uint64_t) riscv_cpu->fpregs[rs2]); + rs1_bits = (rs2_bits & 0x8000000000000000ull) + | (rs1_bits & 0x7fffffffffffffffull); + store_fp (cpu, rd, rs1_bits); + break; + } + case MATCH_FSGNJX_D: + { + uint64_t rs1_bits, rs2_bits; + TRACE_INSN (cpu, "fsgnjx.d %s, %s, %s;", frd_name, frs1_name, + frs2_name); + rs1_bits = (uint64_t) riscv_cpu->fpregs[rs1]; + rs2_bits = (uint64_t) riscv_cpu->fpregs[rs2]; + rs1_bits = ((rs1_bits & 0x8000000000000000ull) + ^ (rs2_bits & 0x8000000000000000ull)) + | (rs1_bits & 0x7fffffffffffffffull); + store_fp (cpu, rd, rs1_bits); + break; + } + case MATCH_FMIN_D: + float64_math (cpu, rd, rs1, rs2, FMIN); + break; + case MATCH_FMAX_D: + float64_math (cpu, rd, rs1, rs2, FMAX); + break; default: TRACE_INSN (cpu, "UNHANDLED INSN: %s", op->name); sim_engine_halt (sd, cpu, NULL, riscv_cpu->pc, sim_signalled, SIM_SIGILL); diff --git a/sim/testsuite/riscv/d-fp-compare.s b/sim/testsuite/riscv/d-fp-compare.s index 0e168fed9de..1a926211216 100755 --- a/sim/testsuite/riscv/d-fp-compare.s +++ b/sim/testsuite/riscv/d-fp-compare.s @@ -20,11 +20,16 @@ _arg2: .double 0.5 .double 2.2 +_expected: + .double 0.5 + .double 2.2 + start .option push .option norelax la a0,_arg1 la a1,_arg2 + la a2,_expected li a3,1 .option pop @@ -65,6 +70,23 @@ _arg2: fclass.d a4,fa0 bne a3,a4,test_fail + # Test fmin.d instruction. + fld fa0,0(a0) + fld fa1,8(a1) + fld fa2,0(a2) + fmin.d fa3,fa0,fa1 + feq.d a4,fa3,fa2 + li a3,1 + bne a4,a3,test_fail + + # Test fmax.d instruction. + fld fa0,0(a0) + fld fa1,8(a1) + fld fa2,8(a2) + fmax.d fa3,fa0,fa1 + feq.d a4,fa3,fa2 + bne a4,a3,test_fail + test_pass: pass diff --git a/sim/testsuite/riscv/d-fp-sign-inject.s b/sim/testsuite/riscv/d-fp-sign-inject.s new file mode 100644 index 00000000000..c2f61ba3cdd --- /dev/null +++ b/sim/testsuite/riscv/d-fp-sign-inject.s @@ -0,0 +1,87 @@ +# Double precision sign-injection instructions. +# mach: riscv64 +# sim(riscv64): --model RV64ID +# ld(riscv64): -m elf64lriscv +# as(riscv64): -march=rv64id + +.include "testutils.inc" + + .section .data + .align 3 + +_arg1: + .double 2.0 + .double -2.0 + +_arg2: + .double 1.0 + .double -1.0 + +_expected: + .double 2.0 + .double -2.0 + + start + .option push + .option norelax + la a0,_arg1 + la a1,_arg2 + la a2,_expected + li a3,1 + .option pop + + # Test fsgnj.d instruction. + fld fa0,0(a0) + fld fa1,0(a1) + fld fa2,0(a2) + fsgnj.d fa3,fa0,fa1 + feq.d a4,fa3,fa2 + bne a4,a3,test_fail + fld fa1,8(a1) + fld fa2,8(a2) + fsgnj.d fa3,fa0,fa1 + feq.d a4,fa3,fa2 + bne a4,a3,test_fail + + # Test fsgnjn.d (fneg.d) instruction. + fld fa0,0(a0) + fld fa1,0(a1) + fld fa2,8(a2) + fsgnjn.d fa3,fa0,fa1 + feq.d a4,fa3,fa2 + bne a4,a3,test_fail + fld fa1,8(a1) + fld fa2,0(a2) + fsgnjn.d fa3,fa0,fa1 + feq.d a4,fa3,fa2 + bne a4,a3,test_fail + fld fa0,0(a0) + fld fa2,8(a2) + fneg.d fa3,fa0 + feq.d a4,fa3,fa2 + bne a4,a3,test_fail + + # Test fsgnjx.d (fabs.d) instruction. + fld fa0,0(a0) + fld fa1,8(a1) + fld fa2,8(a2) + fsgnjx.d fa3,fa0,fa1 + feq.d a4,fa3,fa2 + bne a4,a3,test_fail + fld fa0,8(a0) + fld fa1,8(a1) + fld fa2,0(a2) + fsgnjx.d fa3,fa0,fa1 + feq.d a4,fa3,fa2 + bne a4,a3,test_fail + fld fa0,8(a0) + fld fa2,0(a2) + fabs.d fa3,fa0 + feq.d a4,fa3,fa2 + bne a4,a3,test_fail + +test_pass: + pass + +test_fail: + fail From patchwork Mon Feb 26 14:28:43 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bhushan Attarde X-Patchwork-Id: 86387 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 417CB385843B for ; Mon, 26 Feb 2024 14:29:39 +0000 (GMT) X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from mx08-00376f01.pphosted.com (mx08-00376f01.pphosted.com [91.207.212.86]) by sourceware.org (Postfix) with ESMTPS id AE73D3858D28 for ; Mon, 26 Feb 2024 14:29:02 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org AE73D3858D28 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=imgtec.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=imgtec.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org AE73D3858D28 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=91.207.212.86 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1708957744; cv=none; b=WaMBqUH81KbwvYeQ4xTUphXqq0I9SGRjWxKh/uSO9AufXKWJi7xn4d5yZgGoBOnXNi1klBGHmpTupIgvRxdFITz3YyfjbjR2WEzU1hsEqZSw1bzxaccQrTxriS6muqR39r4SF6644SzEsaEoWFqfMEfX46569BHFl+22l2dMZrE= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1708957744; c=relaxed/simple; bh=ePmZyDZQxiRFpB4hn8YvUWqpQK47x7xtLPIyZqvUU50=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=Rik2kpj7GOgoPqsWJttzpLPq9Ovo9eprtDJ5stX9L8k+1Ucrmjr/DOTPbyVNm1U2eQInm9qEszUu7FYbmweaSrKScMtoV0nzyyuMEZwEQH7/0KyOh/ZcpX2GNoptT6GablBQSHUnINEAGo/b9xLAVxxlaZSAUwsiur907gGUEgw= ARC-Authentication-Results: i=1; server2.sourceware.org Received: from pps.filterd (m0168888.ppops.net [127.0.0.1]) by mx08-00376f01.pphosted.com (8.17.1.24/8.17.1.24) with ESMTP id 41Q8K02l021970; Mon, 26 Feb 2024 14:28:57 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=imgtec.com; h= from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding:content-type; s=dk201812; bh=DXZaPo/1 HNX1dbk6MP84OQUvcykF4WjW8T1BUJ96QBE=; b=ADqKyD/Eo0/piJywsAhz/6z8 Jxj7tO0yGX8kTdCIZeYeL14SKw8KxNwDswXKLtL+kUdPD1CgwROgJqCVdDB/WPyl ymsu5e/l+HajqjO2za75BQGhn5NQBSQMefqjGGGbLLKuepOncmtXWx5Ipg0h7K1P uPYhV7xhG3SUO4VIcck+lw6y96gFvF2lXRd5rkRPh1ALRHLCgBevAih60zUXvdbw srDfB8DUMzQzHE6re+f8iNG1ATPVZvNQ6Yp97vtPeDFdp7OG1fLb7KeCWmybVv+L FmFZxdndTEfR9B/MqpEfMusJOclK3c0RQo0VZq4Xmd2xDxZcPQ3KPJ8HGOWWNQ== Received: from hhmail05.hh.imgtec.org ([217.156.249.195]) by mx08-00376f01.pphosted.com (PPS) with ESMTPS id 3wf7kssr7v-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Mon, 26 Feb 2024 14:28:57 +0000 (GMT) Received: from hhbattarde.hh.imgtec.org (10.100.136.78) by HHMAIL05.hh.imgtec.org (10.100.10.120) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.35; Mon, 26 Feb 2024 14:28:56 +0000 From: To: CC: , , , Bhushan Attarde Subject: [PATCH 09/11] sim: riscv: Add double precision floating-point MAC instructions Date: Mon, 26 Feb 2024 14:28:43 +0000 Message-ID: <20240226142845.1629113-1-bhushan.attarde@imgtec.com> X-Mailer: git-send-email 2.25.1 MIME-Version: 1.0 X-Originating-IP: [10.100.136.78] X-ClientProxiedBy: HHMAIL05.hh.imgtec.org (10.100.10.120) To HHMAIL05.hh.imgtec.org (10.100.10.120) X-EXCLAIMER-MD-CONFIG: 15a78312-3e47-46eb-9010-2e54d84a9631 X-Proofpoint-GUID: mBm4GoxjLR9Oa0QYqoqEw_IjaQ8oOqCx X-Proofpoint-ORIG-GUID: mBm4GoxjLR9Oa0QYqoqEw_IjaQ8oOqCx X-Spam-Status: No, score=-12.8 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_LOW, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org From: Bhushan Attarde Added simulation of following single precision floating-point instructions fmadd.d, fnmadd.d, fmsub.d and fnmsub.d. Added test file sim/testsuite/riscv/d-basic-arith.s to test these instructions. --- sim/riscv/sim-main.c | 117 ++++++++++++++++++++++++++-- sim/testsuite/riscv/d-basic-arith.s | 78 +++++++++++++++++++ 2 files changed, 190 insertions(+), 5 deletions(-) create mode 100644 sim/testsuite/riscv/d-basic-arith.s diff --git a/sim/riscv/sim-main.c b/sim/riscv/sim-main.c index 4f347fbfc5e..4a102df74e0 100644 --- a/sim/riscv/sim-main.c +++ b/sim/riscv/sim-main.c @@ -1361,20 +1361,36 @@ float64_compare (SIM_CPU *cpu, int rd, int rs1, int rs2, int flags) /* Handle double precision floating point math instructions. */ static void -float64_math (SIM_CPU *cpu, int rd, int rs1, int rs2, int flags) +float64_math (SIM_CPU *cpu, int rd, int rs1, int rs2, int rs3, int rm, + int flags) { struct riscv_sim_cpu *riscv_cpu = RISCV_SIM_CPU (cpu); - double a, b, result = 0; - uint64_t rs1_bits, rs2_bits, rd_bits; + double a, b, c, result = 0; + int old_rm, old_except, new_except; + uint64_t rs1_bits, rs2_bits, rs3_bits, rd_bits; const char *frd_name = riscv_fpr_names_abi[rd]; const char *frs1_name = riscv_fpr_names_abi[rs1]; const char *frs2_name = riscv_fpr_names_abi[rs2]; + const char *frs3_name = riscv_fpr_names_abi[rs3]; + + if (rm == DYN) + rm = riscv_cpu->csr.frm; + + old_rm = set_riscv_rounding_mode (rm); + old_except = fetestexcept (FE_ALL_EXCEPT); rs1_bits = (uint64_t) riscv_cpu->fpregs[rs1]; memcpy (&a, &rs1_bits, sizeof (a)); rs2_bits = (uint64_t) riscv_cpu->fpregs[rs2]; memcpy (&b, &rs2_bits, sizeof (b)); + if (flags == FMADD || flags == FNMADD + || flags == FMSUB || flags == FNMSUB) + { + rs3_bits = (uint64_t) riscv_cpu->fpregs[rs3]; + memcpy (&c, &rs3_bits, sizeof (c)); + } + switch (flags) { case FMAX: @@ -1385,12 +1401,85 @@ float64_math (SIM_CPU *cpu, int rd, int rs1, int rs2, int flags) TRACE_INSN (cpu, "fmin.d %s, %s, %s;", frd_name, frs1_name, frs2_name); result = fmin (a, b); break; + case FMADD: + TRACE_INSN (cpu, "fmadd.d %s, %s, %s, %s, rm=%d;", + frd_name, frs1_name, frs2_name, frs3_name, rm); + result = (a * b) + c; + break; + case FNMADD: + TRACE_INSN (cpu, "fnmadd.d %s, %s, %s, %s, rm=%d;", + frd_name, frs1_name, frs2_name, frs3_name, rm); + result = -((a * b) - c); + break; + case FMSUB: + TRACE_INSN (cpu, "fmsub.d %s, %s, %s, %s, rm=%d;", + frd_name, frs1_name, frs2_name, frs3_name, rm); + result = (a * b) - c; + break; + case FNMSUB: + TRACE_INSN (cpu, "fnmsub.d %s, %s, %s, %s, rm=%d;", + frd_name, frs1_name, frs2_name, frs3_name, rm); + result = -((a * b) + c); + break; + } + + if (rm == RMM) + { + if (is_float_halfway (result)) + { + if (result > 0) + result = nextafterf (result, INFINITY); + else + result = nextafterf (result, -INFINITY); + } } /* Store result. */ memcpy (&rd_bits, &result, sizeof (result)); store_fp (cpu, rd, rd_bits); + /* Restore rounding mode. */ + fesetround (old_rm); + + /* Set exception. */ + new_except = fetestexcept (FE_ALL_EXCEPT); + + if (old_except != new_except) + { + if (new_except & FE_OVERFLOW) + { + riscv_cpu->csr.fcsr |= FCSR_OF; + riscv_cpu->csr.fflags |= FCSR_OF; + TRACE_REGISTER (cpu, "wrote CSR fcsr |= OF"); + } + else if (new_except & FE_UNDERFLOW) + { + riscv_cpu->csr.fcsr |= FCSR_UF; + riscv_cpu->csr.fflags |= FCSR_UF; + TRACE_REGISTER (cpu, "wrote CSR fcsr |= UF"); + } + else if (new_except & FE_INEXACT) + { + riscv_cpu->csr.fcsr |= FCSR_NX; + riscv_cpu->csr.fflags |= FCSR_NX; + TRACE_REGISTER (cpu, "wrote CSR fcsr |= NX"); + } + else if (new_except & FE_DIVBYZERO) + { + riscv_cpu->csr.fcsr |= FCSR_DZ; + riscv_cpu->csr.fflags |= FCSR_DZ; + TRACE_REGISTER (cpu, "wrote CSR fcsr |= DZ"); + } + else if (new_except & FE_INVALID) + { + riscv_cpu->csr.fcsr |= FCSR_NV; + riscv_cpu->csr.fflags |= FCSR_NV; + TRACE_REGISTER (cpu, "wrote CSR fcsr |= NV"); + } + + feclearexcept (FE_ALL_EXCEPT); + feraiseexcept (old_except); + } } /* Simulate single precision floating point instructions. */ @@ -1644,6 +1733,8 @@ execute_d (SIM_CPU *cpu, unsigned_word iw, const struct riscv_opcode *op) int rd = (iw >> OP_SH_RD) & OP_MASK_RD; int rs1 = (iw >> OP_SH_RS1) & OP_MASK_RS1; int rs2 = (iw >> OP_SH_RS2) & OP_MASK_RS2; + int rs3 = (iw >> OP_SH_RS3) & OP_MASK_RS3; + int rm = (iw >> OP_SH_RM) & OP_MASK_RM; const char *frd_name = riscv_fpr_names_abi[rd]; const char *rd_name = riscv_gpr_names_abi[rd]; const char *frs1_name = riscv_fpr_names_abi[rs1]; @@ -1728,10 +1819,26 @@ execute_d (SIM_CPU *cpu, unsigned_word iw, const struct riscv_opcode *op) break; } case MATCH_FMIN_D: - float64_math (cpu, rd, rs1, rs2, FMIN); + float64_math (cpu, rd, rs1, rs2, 0, -1, FMIN); break; case MATCH_FMAX_D: - float64_math (cpu, rd, rs1, rs2, FMAX); + float64_math (cpu, rd, rs1, rs2, 0, -1, FMAX); + break; + case MATCH_FMADD_D: + case MATCH_FMADD_D | MASK_RM: + float64_math (cpu, rd, rs1, rs2, rs3, rm, FMADD); + break; + case MATCH_FNMADD_D: + case MATCH_FNMADD_D | MASK_RM: + float64_math (cpu, rd, rs1, rs2, rs3, rm, FNMADD); + break; + case MATCH_FMSUB_D: + case MATCH_FMSUB_D | MASK_RM: + float64_math (cpu, rd, rs1, rs2, rs3, rm, FMSUB); + break; + case MATCH_FNMSUB_D: + case MATCH_FNMSUB_D | MASK_RM: + float64_math (cpu, rd, rs1, rs2, rs3, rm, FNMSUB); break; default: TRACE_INSN (cpu, "UNHANDLED INSN: %s", op->name); diff --git a/sim/testsuite/riscv/d-basic-arith.s b/sim/testsuite/riscv/d-basic-arith.s new file mode 100644 index 00000000000..996f603e91d --- /dev/null +++ b/sim/testsuite/riscv/d-basic-arith.s @@ -0,0 +1,78 @@ +# Double precision basic arithmetic tests. +# mach: riscv64 +# sim(riscv64): --model RV64ID +# ld(riscv64): -m elf64lriscv +# as(riscv64): -march=rv64id + +.include "testutils.inc" + + .section .data + .align 3 + +_arg1: + .double -12.5 + +_arg2: + .double 2.5 + +_arg3: + .double 7.45 + +_result: + .double -23.799999 + .double 38.7000008 + .double -38.7000008 + .double 23.7999992 + + start + .option push + .option norelax + la a0,_arg1 + la a1,_arg2 + la a2,_arg3 + la a3,_result + li a4,1 + .option pop + + # Test fmadd instruction. + fld fa0,0(a0) + fld fa1,0(a1) + fld fa2,0(a2) + fld fa3,0(a3) + fmadd.d fa4,fa0,fa1,fa0,rne + feq.d a5,fa4,fa4 + bne a5,a4,test_fail + + # Test fnmadd instruction. + fld fa0,0(a0) + fld fa1,0(a1) + fld fa2,0(a2) + fld fa3,8(a3) + fnmadd.d fa4,fa0,fa1,fa0,rne + feq.d a5,fa4,fa4 + bne a5,a4,test_fail + + # Test fmsub instruction. + fld fa0,0(a0) + fld fa1,0(a1) + fld fa2,0(a2) + fld fa3,16(a3) + fmsub.d fa4,fa0,fa1,fa0,rne + feq.d a5,fa4,fa4 + bne a5,a4,test_fail + + # Test fnmsub instruction. + fld fa0,0(a0) + fld fa1,0(a1) + fld fa2,0(a2) + fld fa3,24(a3) + fmsub.d fa4,fa0,fa1,fa0,rne + feq.d a5,fa4,fa4 + bne a5,a4,test_fail + + +test_pass: + pass + +test_fail: + fail From patchwork Mon Feb 26 14:28:44 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bhushan Attarde X-Patchwork-Id: 86388 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 997F13858285 for ; Mon, 26 Feb 2024 14:29:39 +0000 (GMT) X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from mx08-00376f01.pphosted.com (mx08-00376f01.pphosted.com [91.207.212.86]) by sourceware.org (Postfix) with ESMTPS id 395403858CDB for ; Mon, 26 Feb 2024 14:29:03 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 395403858CDB Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=imgtec.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=imgtec.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 395403858CDB Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=91.207.212.86 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1708957746; cv=none; b=VAMYltyjEcLFvh88NsaLpITqGHbP+0VmOKgjelQrmL6umFv2+6bWAXRJsm+dxKhSUv8zN4FU7Yb+fNxDb7hC/tWkihgTZyG/GUkp0FXs604CyrMfCKn+yPwA+sB672yI5blHLrPIlHKELtzYm2by6RjoGpYe+vSNdmryZ83odhY= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1708957746; c=relaxed/simple; bh=Y70M3kbHuuu4GyWuOktZyyO6WeY+s5pSJqeNjBN85xk=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=AykVtWnLNedp/TDcFOyV2/V6ZpVOOp5qqdfuQOGJ8bXALBMMCVW1JdUO7QouhIi0kRKZxZgD3u8SQEh+EwgVFWBcqJ31X53DrPsi/crd4QRctNTuIUy5qMz4xOs49Kaj1r11FK88pAgSHxSG+REb0uzgdIB6+x4TxmnAeyONvNU= ARC-Authentication-Results: i=1; server2.sourceware.org Received: from pps.filterd (m0168888.ppops.net [127.0.0.1]) by mx08-00376f01.pphosted.com (8.17.1.24/8.17.1.24) with ESMTP id 41Q8K02m021970; Mon, 26 Feb 2024 14:28:58 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=imgtec.com; h= from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding:content-type; s= dk201812; bh=SABZYEzUWg4k4jEWV8rlRD6iDjpnuBpZJO7xDIjHMbc=; b=qjP 2ib6pNjpqzLsPh1bWfFN9wHluiReghEwuvCiSUWfRH0nVncS7TKAa2CLfLAjFsBm tQSeaqZ2p9caia7EX9xhHAFcKafz3y9c2rFOQhzZh5OF+BwW/+xi4OEWiueqt+Ed cp0Td9IaLuor+lVkYkrTuwAN4WT2xsUZuWcedKSMick+mDDPxe5h1o7TBnOSJXba M9pt664RAl/AQ1pgiEDHjHzhdQ/2oXyuqY1VFYu/E0fo2VuiWNocwoU8WwdFSU7m VkhygMYhcsB6Ri+cNpHn6kF+hUCgXPx4U5KvtDw4cfxTBolGcdQxp7Fj1+69lnIM t38EwPXyOistKmJus+A== Received: from hhmail05.hh.imgtec.org ([217.156.249.195]) by mx08-00376f01.pphosted.com (PPS) with ESMTPS id 3wf7kssr7v-2 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Mon, 26 Feb 2024 14:28:57 +0000 (GMT) Received: from hhbattarde.hh.imgtec.org (10.100.136.78) by HHMAIL05.hh.imgtec.org (10.100.10.120) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.35; Mon, 26 Feb 2024 14:28:57 +0000 From: To: CC: , , , Bhushan Attarde Subject: [PATCH 10/11] sim: riscv: Add double precision floating-point basic arithmetic instructions Date: Mon, 26 Feb 2024 14:28:44 +0000 Message-ID: <20240226142845.1629113-2-bhushan.attarde@imgtec.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20240226142845.1629113-1-bhushan.attarde@imgtec.com> References: <20240226142845.1629113-1-bhushan.attarde@imgtec.com> MIME-Version: 1.0 X-Originating-IP: [10.100.136.78] X-ClientProxiedBy: HHMAIL05.hh.imgtec.org (10.100.10.120) To HHMAIL05.hh.imgtec.org (10.100.10.120) X-EXCLAIMER-MD-CONFIG: 15a78312-3e47-46eb-9010-2e54d84a9631 X-Proofpoint-GUID: iSfXkAahJZRy7d1xum1HM1xW6m-lkPru X-Proofpoint-ORIG-GUID: iSfXkAahJZRy7d1xum1HM1xW6m-lkPru X-Spam-Status: No, score=-2.8 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_LOW, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE, UNWANTED_LANGUAGE_BODY autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org From: Bhushan Attarde Added simulation of following single precision floating-point instructions fadd.d, fsub.d, fmul.d, fdiv.d and fsqrt.d. Update test file sim/testsuite/riscv/d-basic-arith.s to test these instructions. --- sim/riscv/sim-main.c | 45 ++++++++++++++++++++++++++ sim/testsuite/riscv/d-basic-arith.s | 50 +++++++++++++++++++++++++++++ 2 files changed, 95 insertions(+) diff --git a/sim/riscv/sim-main.c b/sim/riscv/sim-main.c index 4a102df74e0..e715ca2501e 100644 --- a/sim/riscv/sim-main.c +++ b/sim/riscv/sim-main.c @@ -1421,6 +1421,31 @@ float64_math (SIM_CPU *cpu, int rd, int rs1, int rs2, int rs3, int rm, frd_name, frs1_name, frs2_name, frs3_name, rm); result = -((a * b) + c); break; + case FADD: + TRACE_INSN (cpu, "fadd.d %s, %s, %s, rm=%d;", + frd_name, frs1_name, frs2_name, rm); + result = a + b; + break; + case FSUB: + TRACE_INSN (cpu, "fsub.d %s, %s, %s, rm=%d;", + frd_name, frs1_name, frs2_name, rm); + result = a - b; + break; + case FMUL: + TRACE_INSN (cpu, "fmul.d %s, %s, %s, rm=%d;", + frd_name, frs1_name, frs2_name, rm); + result = a * b; + break; + case FDIV: + TRACE_INSN (cpu, "fdiv.d %s, %s, %s, rm=%d;", + frd_name, frs1_name, frs2_name, rm); + result = a / b; + break; + case FSQRT: + TRACE_INSN (cpu, "fsqrt.d %s, %s, rm=%d;", + frd_name, frs1_name, rm); + result = sqrtf (a); + break; } if (rm == RMM) @@ -1840,6 +1865,26 @@ execute_d (SIM_CPU *cpu, unsigned_word iw, const struct riscv_opcode *op) case MATCH_FNMSUB_D | MASK_RM: float64_math (cpu, rd, rs1, rs2, rs3, rm, FNMSUB); break; + case MATCH_FADD_D: + case MATCH_FADD_D | MASK_RM: + float64_math (cpu, rd, rs1, rs2, 0, rm, FADD); + break; + case MATCH_FSUB_D: + case MATCH_FSUB_D | MASK_RM: + float64_math (cpu, rd, rs1, rs2, 0, rm, FSUB); + break; + case MATCH_FMUL_D: + case MATCH_FMUL_D | MASK_RM: + float64_math (cpu, rd, rs1, rs2, 0, rm, FMUL); + break; + case MATCH_FDIV_D: + case MATCH_FDIV_D | MASK_RM: + float64_math (cpu, rd, rs1, rs2, 0, rm, FDIV); + break; + case MATCH_FSQRT_D: + case MATCH_FSQRT_D | MASK_RM: + float64_math (cpu, rd, rs1, rs2, 0, rm, FSQRT); + break; default: TRACE_INSN (cpu, "UNHANDLED INSN: %s", op->name); sim_engine_halt (sd, cpu, NULL, riscv_cpu->pc, sim_signalled, SIM_SIGILL); diff --git a/sim/testsuite/riscv/d-basic-arith.s b/sim/testsuite/riscv/d-basic-arith.s index 996f603e91d..2f529c68f47 100644 --- a/sim/testsuite/riscv/d-basic-arith.s +++ b/sim/testsuite/riscv/d-basic-arith.s @@ -11,9 +11,16 @@ _arg1: .double -12.5 + .double 1.5 + .double 2.2 + .double 18.5 + .double 5.0 _arg2: .double 2.5 + .double 0.5 + .double 1.1 + .double 0.1 _arg3: .double 7.45 @@ -23,6 +30,11 @@ _result: .double 38.7000008 .double -38.7000008 .double 23.7999992 + .double 2.0 + .double 1.1 + .double 1.85 + .double 185 + .double 2.2360680103302002 start .option push @@ -70,6 +82,44 @@ _result: feq.d a5,fa4,fa4 bne a5,a4,test_fail + # Test fadd instruction. + fld fa0,8(a0) + fld fa1,8(a1) + fld fa2,32(a3) + fadd.d fa4,fa0,fa1,rne + feq.d a5,fa4,fa2 + bne a5,a4,test_fail + + # Test fsub instruction. + fld fa0,16(a0) + fld fa1,16(a1) + fld fa2,40(a3) + fsub.d fa4,fa0,fa1,rne + feq.d a5,fa4,fa2 + bne a5,a4,test_fail + + # Test fmul instruction. + fld fa0,24(a0) + fld fa1,24(a1) + fld fa2,48(a3) + fmul.d fa4,fa0,fa1,rne + feq.d a5,fa4,fa2 + bne a5,a4,test_fail + + # Test fdiv instruction. + fld fa0,24(a0) # Use same input values as of fmul + fld fa1,24(a1) + fld fa2,56(a3) + fdiv.d fa4,fa0,fa1,rne + feq.d a5,fa4,fa2 + bne a5,a4,test_fail + + # Test fsqrt instruction. + fld fa0,32(a0) + fld fa2,64(a3) + fsqrt.d fa4,fa0,rne + feq.d a5,fa4,fa2 + bne a5,a4,test_fail test_pass: pass From patchwork Mon Feb 26 14:28:45 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bhushan Attarde X-Patchwork-Id: 86389 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id DDF8B3858C33 for ; Mon, 26 Feb 2024 14:30:09 +0000 (GMT) X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from mx08-00376f01.pphosted.com (mx08-00376f01.pphosted.com [91.207.212.86]) by sourceware.org (Postfix) with ESMTPS id 68E5B3858C5E for ; Mon, 26 Feb 2024 14:29:03 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 68E5B3858C5E Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=imgtec.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=imgtec.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 68E5B3858C5E Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=91.207.212.86 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1708957746; cv=none; b=GL+cey61asiD6qDAMuTUvDulrTDxs6g0GA31rxXptXZ0lfBg1MIBlGM13ujAPl9Nn4GW3fIKn1BrNuBWLWwZxv2rM5rse1wIo1khkSRtgrhbiW1WDKGyq9aWq2+/lar7YTruecZ/fWFZPlfEKSKSmInYWoAkibBZvkC0Tly7WBE= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1708957746; c=relaxed/simple; bh=XI9GjWCBhAkBx6JfVnERlIab9hyPvtquo98CspQwB+Q=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=Pgt4t1AF1d/QvB04uxBuFuUM77mGcoRcn5F+l9HLbtxgz20QcGixnpA0psiJoGmMyMwTJFZeDZTUJXu4823uAjcp5SeB8syEUPfeZtXEVFezPN7b0kuVtBQlpsTRewpJEkkAwkc4Oz6z5wmpiolHbBwvdGyPeOc47FIm9bYEPjM= ARC-Authentication-Results: i=1; server2.sourceware.org Received: from pps.filterd (m0168888.ppops.net [127.0.0.1]) by mx08-00376f01.pphosted.com (8.17.1.24/8.17.1.24) with ESMTP id 41Q8K02n021970; Mon, 26 Feb 2024 14:28:58 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=imgtec.com; h= from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding:content-type; s= dk201812; bh=AzKudNCveKfq+8h2QEsH26Ufg4jNkQllaywXOKxIlnI=; b=MvP p7LdncdYC/Y+fsZ+9i3HSCboehzIR0gHp5joDeW14AMFvDM7O5Se556bj9V8QmZr SKWtbPHXe8MRvPVTXn2m8n031Rq+cJPksYW68Sl7qlrd2y5MXdgi0Hbt7mIOus/V uwkzr+7ftFZuR9WiSWwnzh/4LZTCTSqDYewBVQC1tgujAzb9y3xS35Un3RAYjnfn I1oaAR0uD8f1Fi26hfhku6Ss9IJo7zlq3C5IMY+K9xCcYyCOzXsAyg41ZP6P464a aVYTepiUjSjx6w42sJrfEziHKwIBIjI3EnHwxkZFCQKEjtfCzC703SOm558QT3Vo 8F04nwWHoL1MNUvckRA== Received: from hhmail05.hh.imgtec.org ([217.156.249.195]) by mx08-00376f01.pphosted.com (PPS) with ESMTPS id 3wf7kssr7v-3 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Mon, 26 Feb 2024 14:28:58 +0000 (GMT) Received: from hhbattarde.hh.imgtec.org (10.100.136.78) by HHMAIL05.hh.imgtec.org (10.100.10.120) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.35; Mon, 26 Feb 2024 14:28:57 +0000 From: To: CC: , , , Bhushan Attarde Subject: [PATCH 11/11] sim: riscv: Add double precision floating-point conversion instructions Date: Mon, 26 Feb 2024 14:28:45 +0000 Message-ID: <20240226142845.1629113-3-bhushan.attarde@imgtec.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20240226142845.1629113-1-bhushan.attarde@imgtec.com> References: <20240226142845.1629113-1-bhushan.attarde@imgtec.com> MIME-Version: 1.0 X-Originating-IP: [10.100.136.78] X-ClientProxiedBy: HHMAIL05.hh.imgtec.org (10.100.10.120) To HHMAIL05.hh.imgtec.org (10.100.10.120) X-EXCLAIMER-MD-CONFIG: 15a78312-3e47-46eb-9010-2e54d84a9631 X-Proofpoint-GUID: -hcoJn_F2XhoQzxTzZ-MR5dXqqOUVp0k X-Proofpoint-ORIG-GUID: -hcoJn_F2XhoQzxTzZ-MR5dXqqOUVp0k X-Spam-Status: No, score=-12.8 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_LOW, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org From: Bhushan Attarde Added simulation of following single precision floating-point instructions fcvt.w.d, fcvt.wu.d, fcvt.d.w, fcvt.d.wu, fcvt.l.d, fcvt.lu.d, fcvt.d.l, fcvt.d.lu, fcvt.d.s and fcvt.s.d. Added test file sim/testsuite/riscv/d-conversion.s to test these instructions. --- sim/riscv/sim-main.c | 326 +++++++++++++++++++++++++++++ sim/testsuite/riscv/d-conversion.s | 111 ++++++++++ 2 files changed, 437 insertions(+) create mode 100755 sim/testsuite/riscv/d-conversion.s diff --git a/sim/riscv/sim-main.c b/sim/riscv/sim-main.c index e715ca2501e..66e0610c246 100644 --- a/sim/riscv/sim-main.c +++ b/sim/riscv/sim-main.c @@ -1036,6 +1036,77 @@ float32_math (SIM_CPU *cpu, int rd, int rs1, int rs2, } } +/* Round and return the double value. This function is used before we + perform any operation on the input double value. */ +static double +round_double_input (double value, int rm) +{ + double result = value; + if (rm == RNE) + { + double fractional_part = value - trunc (value); + /* Check if the number is halfway between two values. */ + if (fractional_part == 0.5 || fractional_part == -0.5) + { + result = floor (value); + if (fmod (result, 2.0) != 0) + result += (value > 0) ? 1.0 : -1.0; + } + else + result = round (value); + } + else if (rm == RTZ) + result = trunc (value); + else if (rm == RDN) + result = floor (value); + else if (rm == RUP) + result = ceil (value); + else + { + /* No direct match for RMM. Simulate it. */ + double fracPart = value - (int64_t) value; + if (fracPart > 0.5 || fracPart < -0.5) + result = round (value); + else if (fracPart == 0.5) + result = ceil (value); + else if (fracPart == -0.5) + result = floor (value); + else + result = value; + } + return result; +} + +/* Round and return the double value. This function is used after we + perform the operation to get the result rounded. */ +static double +round_double_output (double value, int rm) +{ + double result; + if (rm == RNE) + result = value; + else if (rm == RTZ) + result = trunc (value); + else if (rm == RDN) + result = floor (value); + else if (rm == RUP) + result = ceil (value); + else + { + /* No direct match for RMM. Simulate it. */ + double fracPart = value - (int64_t) value; + if (fracPart > 0.5 || fracPart < -0.5) + result = round (value); + else if (fracPart == 0.5) + result = ceil (value); + else if (fracPart == -0.5) + result = floor (value); + else + result = value; + } + return result; +} + /* Round and return the float value. This function is used before we perform any operation on the input float value. */ static float @@ -1107,6 +1178,183 @@ round_float_output (float value, int rm) return result; } +/* Convert the double precision floating point value into integer. */ +static void +convert_double_to_int (SIM_CPU *cpu, int rd, int rs1, int sign, + int rm, int is_32bit) +{ + struct riscv_sim_cpu *riscv_cpu = RISCV_SIM_CPU (cpu); + double src, rounded; + uint64_t rs1_bits; + int iclamp; + uint32_t uclamp; + rs1_bits = (uint64_t) riscv_cpu->fpregs[rs1]; + memcpy (&src, &rs1_bits, sizeof (src)); + + if (rm == DYN) + rm = riscv_cpu->csr.frm; + + /* Get the input rounded. */ + rounded = round_double_input (src, rm); + + if (sign == SIGNED) + { + /* Clamp the input to int32_t range. */ + iclamp = min (max ((int64_t) rounded, INT_MIN), INT_MAX); + if (is_32bit) + store_rd (cpu, rd, (int) iclamp); + else + store_rd (cpu, rd, (int64_t) iclamp); + } + else + { + /* Clamp the input to uint32_t range. */ + uclamp = min (max ((uint64_t) rounded, 0), UINT_MAX); + if (rounded < 0.0f) + uclamp = 0; + if (is_32bit) + store_rd (cpu, rd, (uint32_t) uclamp); + else + store_rd (cpu, rd, (uint64_t) uclamp); + } +} + +/* Convert the double precision floating point value into long integer. */ +static void +convert_double_to_long (SIM_CPU *cpu, int rd, int rs1, int sign, + int rm) +{ + struct riscv_sim_cpu *riscv_cpu = RISCV_SIM_CPU (cpu); + double src, rounded; + uint64_t rs1_bits; + int64_t lclamp; + uint64_t luclamp; + rs1_bits = (uint64_t) riscv_cpu->fpregs[rs1]; + memcpy (&src, &rs1_bits, sizeof (src)); + + if (rm == DYN) + rm = riscv_cpu->csr.frm; + + /* Get the input rounded. */ + rounded = round_double_input (src, rm); + + if (sign == SIGNED) + { + /* Clamp the input to int64_t range. */ + lclamp = min (max ((int64_t) rounded, LONG_MIN), LONG_MAX); + store_rd (cpu, rd, (int64_t) lclamp); + } + else + { + /* Clamp the input to uint64_t range. */ + luclamp = min (max ((uint64_t) rounded, 0), ULONG_MAX); + if (rounded < 0.0f) + luclamp = 0; + store_rd (cpu, rd, (uint64_t) luclamp); + } +} + +/* Convert the long integer value into double precision floating point. */ +static void +convert_long_to_double (SIM_CPU *cpu, int rd, int rs1, int sign, + int rm) +{ + struct riscv_sim_cpu *riscv_cpu = RISCV_SIM_CPU (cpu); + uint64_t rd_bits; + uint64_t usrc = (uint64_t) riscv_cpu->regs[rs1]; + int64_t isrc = (int64_t) riscv_cpu->regs[rs1]; + double result = .0; + int old_rm; + + if (rm == DYN) + rm = riscv_cpu->csr.frm; + + old_rm = set_riscv_rounding_mode (rm); + + if (rm == RMM) + { + if (sign == SIGNED) + { + if (isrc > 0) + { + fesetround (FE_UPWARD); + result = (double) isrc; + result = ceil (result); + } + else + { + fesetround (FE_DOWNWARD); + result = (double) isrc; + result = floor (result); + } + } + else + { + /* Since it's unsigned, it's always positive. */ + fesetround (FE_UPWARD); + result = (double) usrc; + result = ceil (result); + } + } + else + { + if (sign == SIGNED) + result = (double) isrc; + else + result = (double) usrc; + + /* Get the result rounded. */ + result = round_double_output (result, rm); + } + + /* Restore rounding mode. */ + fesetround (old_rm); + + /* Store the result. */ + memcpy (&rd_bits, &result, sizeof (result)); + store_fp (cpu, rd, rd_bits); +} + +/* Convert the double precision floating point value into single precision. */ +static void +double_to_float (SIM_CPU *cpu, int rd, int rs1, int rm) +{ + struct riscv_sim_cpu *riscv_cpu = RISCV_SIM_CPU (cpu); + double src; + float result = 0; + int old_rm; + uint64_t rs1_bits; + uint32_t rd_bits; + + if (rm == DYN) + rm = riscv_cpu->csr.frm; + + old_rm = set_riscv_rounding_mode (rm); + + rs1_bits = (uint64_t) riscv_cpu->fpregs[rs1]; + memcpy (&src, &rs1_bits, sizeof (src)); + + result = (float) src; + + if (rm == RMM) + { + if (is_float_halfway (result)) + { + if (result > 0) + result = nextafterf (result, INFINITY); + else + result = nextafterf (result, -INFINITY); + } + } + + /* Store result. */ + memcpy (&rd_bits, &result, sizeof (result)); + store_fp (cpu, rd, rd_bits); + + /* Restore rounding mode. */ + fesetround (old_rm); +} + static void convert_float_to_int (SIM_CPU *cpu, int rd, int rs1, int sign, int rm, int is_32bit) @@ -1885,6 +2133,84 @@ execute_d (SIM_CPU *cpu, unsigned_word iw, const struct riscv_opcode *op) case MATCH_FSQRT_D | MASK_RM: float64_math (cpu, rd, rs1, rs2, 0, rm, FSQRT); break; + case MATCH_FCVT_W_D: + case MATCH_FCVT_W_D | MASK_RM: + TRACE_INSN (cpu, "fcvt.w.d %s, %s, rm=%d;", rd_name, rs1_name, rm); + convert_double_to_int (cpu, rd, rs1, SIGNED, rm, 1); + break; + case MATCH_FCVT_WU_D: + case MATCH_FCVT_WU_D | MASK_RM: + TRACE_INSN (cpu, "fcvt.wu.d %s, %s, rm=%d;", rd_name, rs1_name, rm); + convert_double_to_int (cpu, rd, rs1, UNSIGNED, rm, 1); + break; + case MATCH_FCVT_D_W: + case MATCH_FCVT_D_W | MASK_RM: + { + double d; + uint64_t rd_bits; + int32_t isrc; + TRACE_INSN (cpu, "fcvt.d.w %s, %s, rm=%d;", rd_name, rs1_name, rm); + isrc = (int32_t) riscv_cpu->regs[rs1]; + d = (double) isrc; + memcpy (&rd_bits, &d, sizeof (d)); + store_fp (cpu, rd, rd_bits); + break; + } + case MATCH_FCVT_D_WU: + case MATCH_FCVT_D_WU | MASK_RM: + { + double d; + uint64_t rd_bits; + uint32_t usrc; + TRACE_INSN (cpu, "fcvt.d.wu %s, %s, rm=%d;", rd_name, rs1_name, rm); + usrc = (uint32_t) riscv_cpu->regs[rs1]; + d = (double) usrc; + memcpy (&rd_bits, &d, sizeof (d)); + store_fp (cpu, rd, rd_bits); + break; + } + case MATCH_FCVT_L_D: + case MATCH_FCVT_L_D | MASK_RM: + TRACE_INSN (cpu, "fcvt.l.d %s, %s, rm=%d;", rd_name, rs1_name, rm); + RISCV_ASSERT_RV64 (cpu, "insn: %s", op->name); + convert_double_to_long (cpu, rd, rs1, SIGNED, rm); + break; + case MATCH_FCVT_LU_D: + case MATCH_FCVT_LU_D | MASK_RM: + TRACE_INSN (cpu, "fcvt.lu.d %s, %s, rm=%d;", rd_name, rs1_name, rm); + RISCV_ASSERT_RV64 (cpu, "insn: %s", op->name); + convert_double_to_long (cpu, rd, rs1, UNSIGNED, rm); + break; + case MATCH_FCVT_D_L: + case MATCH_FCVT_D_L | MASK_RM: + TRACE_INSN (cpu, "fcvt.d.l %s, %s, rm=%d;", rd_name, rs1_name, rm); + RISCV_ASSERT_RV64 (cpu, "insn: %s", op->name); + convert_long_to_double (cpu, rd, rs1, SIGNED, rm); + break; + case MATCH_FCVT_D_LU: + case MATCH_FCVT_D_LU | MASK_RM: + TRACE_INSN (cpu, "fcvt.d.lu %s, %s, rm=%d;", rd_name, rs1_name, rm); + RISCV_ASSERT_RV64 (cpu, "insn: %s", op->name); + convert_long_to_double (cpu, rd, rs1, UNSIGNED, rm); + break; + case MATCH_FCVT_S_D: + case MATCH_FCVT_S_D | MASK_RM: + double_to_float (cpu, rd, rs1, rm); + break; + case MATCH_FCVT_D_S: + { + float f; + double d; + uint64_t rd_bits; + uint32_t rs1_bits; + TRACE_INSN (cpu, "fcvt.d.s %s, %s;", frd_name, frs1_name); + rs1_bits = (uint32_t) riscv_cpu->fpregs[rs1]; + memcpy (&f, &rs1_bits, sizeof (f)); + d = (double) f; + memcpy (&rd_bits, &d, sizeof (d)); + store_fp (cpu, rd, rd_bits); + break; + } default: TRACE_INSN (cpu, "UNHANDLED INSN: %s", op->name); sim_engine_halt (sd, cpu, NULL, riscv_cpu->pc, sim_signalled, SIM_SIGILL); diff --git a/sim/testsuite/riscv/d-conversion.s b/sim/testsuite/riscv/d-conversion.s new file mode 100755 index 00000000000..e2ca0a3e1c7 --- /dev/null +++ b/sim/testsuite/riscv/d-conversion.s @@ -0,0 +1,111 @@ +# Double precision conversion tests. +# mach: riscv32 riscv64 +# sim(riscv64): --model RV64ID +# ld(riscv64): -m elf64lriscv +# as(riscv64): -march=rv64id + +.include "testutils.inc" + + .section .rodata + .align 3 + +_arg1: + .double 123.49 + .word 123 + .word 0 + .double -3e9 + .double 2147483648.5 + .dword 2147483647 + .float -12.5 + .float .0 + .double -12.5 + +_result: + .word 123 + .word 0 + .double 123.0 + .dword -3000000000 + .dword 2147483648 + .double 2147483647 + .double -12.5 + .float -12.5 + + start + .option push + .option norelax + la a0,_arg1 + la a1,_result + li a2,1 + .option pop + + # Test fcvt.w.d instruction. + fld fa0,0(a0) + lw a3,0(a1) + fcvt.w.d a5,fa0,rne + bne a3,a5,test_fail + + # Test fcvt.wu.d instruction. + fld fa0,0(a0) + lw a3,0(a1) + fcvt.wu.d a5,fa0,rne + bne a3,a5,test_fail + + # Test fcvt.d.w instruction. + lw a3,8(a0) + fld fa0,8(a1) + fcvt.d.w fa1,a3 + feq.d a4,fa0,fa1 + bne a4,a2,test_fail + + # Test fcvt.d.wu instruction. + lw a3,8(a0) + fld fa0,8(a1) + fcvt.d.wu fa1,a3 + feq.d a4,fa0,fa1 + bne a4,a2,test_fail + + # Test fcvt.l.d instruction. + fld fa0,16(a0) + ld a3,16(a1) + fcvt.l.d a5,fa0,rne + bne a5,a3,test_fail + + # Test fcvt.lu.d instruction. + fld fa0,24(a0) + ld a3,24(a1) + fcvt.lu.d a5,fa0,rne + bne a5,a3,test_fail + + # Test fcvt.d.l instruction. + ld a3,32(a0) + fld fa0,32(a1) + fcvt.d.l fa1,a3,rne + feq.d a4,fa0,fa1 + bne a4,a2,test_fail + + # Test fcvt.d.lu instruction. + ld a3,32(a0) + fld fa0,32(a1) + fcvt.d.lu fa1,a3,rne + feq.d a4,fa0,fa1 + bne a4,a2,test_fail + + # Test fcvt.d.s instruction. + flw fa0,40(a0) + fld fa1,40(a1) + fcvt.d.s fa2,fa0 + feq.d a4,fa2,fa1 + bne a4,a2,test_fail + + # Test fcvt.s.d instruction. + fld fa0,48(a0) + flw fa1,48(a1) + fcvt.s.d fa2,fa0 + feq.s a4,fa2,fa1 + bne a4,a2,test_fail + +test_pass: + pass + +test_fail: + fail