diff options
Diffstat (limited to 'contrib/llvm/lib/Target/RISCV/RISCVInstrInfoD.td')
-rw-r--r-- | contrib/llvm/lib/Target/RISCV/RISCVInstrInfoD.td | 41 |
1 files changed, 35 insertions, 6 deletions
diff --git a/contrib/llvm/lib/Target/RISCV/RISCVInstrInfoD.td b/contrib/llvm/lib/Target/RISCV/RISCVInstrInfoD.td index 9f1cd50de595..fe38c4ff02d3 100644 --- a/contrib/llvm/lib/Target/RISCV/RISCVInstrInfoD.td +++ b/contrib/llvm/lib/Target/RISCV/RISCVInstrInfoD.td @@ -1,9 +1,8 @@ //===-- RISCVInstrInfoD.td - RISC-V 'D' instructions -------*- tablegen -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -179,8 +178,8 @@ def FMV_D_X : FPUnaryOp_r<0b1111001, 0b000, FPR64, GPR, "fmv.d.x"> { //===----------------------------------------------------------------------===// let Predicates = [HasStdExtD] in { -// TODO fld -// TODO fsd +def : InstAlias<"fld $rd, (${rs1})", (FLD FPR64:$rd, GPR:$rs1, 0), 0>; +def : InstAlias<"fsd $rs2, (${rs1})", (FSD FPR64:$rs2, GPR:$rs1, 0), 0>; def : InstAlias<"fmv.d $rd, $rs", (FSGNJ_D FPR64:$rd, FPR64:$rs, FPR64:$rs)>; def : InstAlias<"fabs.d $rd, $rs", (FSGNJX_D FPR64:$rd, FPR64:$rs, FPR64:$rs)>; @@ -192,6 +191,9 @@ def : InstAlias<"fgt.d $rd, $rs, $rt", (FLT_D GPR:$rd, FPR64:$rt, FPR64:$rs), 0>; def : InstAlias<"fge.d $rd, $rs, $rt", (FLE_D GPR:$rd, FPR64:$rt, FPR64:$rs), 0>; + +def PseudoFLD : PseudoFloatLoad<"fld", FPR64>; +def PseudoFSD : PseudoStore<"fsd", FPR64>; } // Predicates = [HasStdExtD] //===----------------------------------------------------------------------===// @@ -268,6 +270,10 @@ def : PatFpr64Fpr64<setole, FLE_D>; // handled by a RISC-V instruction and aren't expanded in the SelectionDAG // Legalizer. +def : Pat<(seto FPR64:$rs1, FPR64:$rs2), + (AND (FEQ_D FPR64:$rs1, FPR64:$rs1), + (FEQ_D FPR64:$rs2, FPR64:$rs2))>; + def : Pat<(setuo FPR64:$rs1, FPR64:$rs2), (SLTIU (AND (FEQ_D FPR64:$rs1, FPR64:$rs1), (FEQ_D FPR64:$rs2, FPR64:$rs2)), @@ -308,3 +314,26 @@ def : Pat<(fp_to_uint FPR64:$rs1), (FCVT_WU_D FPR64:$rs1, 0b001)>; def : Pat<(sint_to_fp GPR:$rs1), (FCVT_D_W GPR:$rs1)>; def : Pat<(uint_to_fp GPR:$rs1), (FCVT_D_WU GPR:$rs1)>; } // Predicates = [HasStdExtD, IsRV32] + +let Predicates = [HasStdExtD, IsRV64] in { +def : Pat<(bitconvert GPR:$rs1), (FMV_D_X GPR:$rs1)>; +def : Pat<(bitconvert FPR64:$rs1), (FMV_X_D FPR64:$rs1)>; + +// FP->[u]int32 is mostly handled by the FP->[u]int64 patterns. This is safe +// because fpto[u|s]i produce poison if the value can't fit into the target. +// We match the single case below because fcvt.wu.d sign-extends its result so +// is cheaper than fcvt.lu.d+sext.w. +def : Pat<(sext_inreg (zexti32 (fp_to_uint FPR64:$rs1)), i32), + (FCVT_WU_D $rs1, 0b001)>; + +// [u]int32->fp +def : Pat<(sint_to_fp (sext_inreg GPR:$rs1, i32)), (FCVT_D_W $rs1)>; +def : Pat<(uint_to_fp (zexti32 GPR:$rs1)), (FCVT_D_WU $rs1)>; + +def : Pat<(fp_to_sint FPR64:$rs1), (FCVT_L_D FPR64:$rs1, 0b001)>; +def : Pat<(fp_to_uint FPR64:$rs1), (FCVT_LU_D FPR64:$rs1, 0b001)>; + +// [u]int64->fp. Match GCC and default to using dynamic rounding mode. +def : Pat<(sint_to_fp GPR:$rs1), (FCVT_D_L GPR:$rs1, 0b111)>; +def : Pat<(uint_to_fp GPR:$rs1), (FCVT_D_LU GPR:$rs1, 0b111)>; +} // Predicates = [HasStdExtD, IsRV64] |