122 lines · plain
1//===-- RISCVInstrInfoM.td - RISC-V 'M' instructions -------*- tablegen -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file describes the RISC-V instructions from the standard 'M', Integer10// Multiplication and Division instruction set extension.11//12//===----------------------------------------------------------------------===//13 14//===----------------------------------------------------------------------===//15// RISC-V specific DAG Nodes.16//===----------------------------------------------------------------------===//17 18// Multiply high for signedxunsigned.19def riscv_mulhsu : RVSDNode<"MULHSU", SDTIntBinOp>;20 21// 32-bit operations from RV64M that can't be simply matched with a pattern22// at instruction selection time. These have undefined behavior for division23// by 0 or overflow (divw) like their target independent counterparts.24def riscv_divw : RVSDNode<"DIVW", SDT_RISCVIntBinOpW>;25def riscv_divuw : RVSDNode<"DIVUW", SDT_RISCVIntBinOpW>;26def riscv_remuw : RVSDNode<"REMUW", SDT_RISCVIntBinOpW>;27 28//===----------------------------------------------------------------------===//29// Instructions30//===----------------------------------------------------------------------===//31 32let Predicates = [HasStdExtZmmul] in {33def MUL : ALU_rr<0b0000001, 0b000, "mul", Commutable=1>,34 Sched<[WriteIMul, ReadIMul, ReadIMul]>;35def MULH : ALU_rr<0b0000001, 0b001, "mulh", Commutable=1>,36 Sched<[WriteIMul, ReadIMul, ReadIMul]>;37def MULHSU : ALU_rr<0b0000001, 0b010, "mulhsu">,38 Sched<[WriteIMul, ReadIMul, ReadIMul]>;39def MULHU : ALU_rr<0b0000001, 0b011, "mulhu", Commutable=1>,40 Sched<[WriteIMul, ReadIMul, ReadIMul]>;41} // Predicates = [HasStdExtZmmul]42 43let Predicates = [HasStdExtM] in {44def DIV : ALU_rr<0b0000001, 0b100, "div">,45 Sched<[WriteIDiv, ReadIDiv, ReadIDiv]>;46def DIVU : ALU_rr<0b0000001, 0b101, "divu">,47 Sched<[WriteIDiv, ReadIDiv, ReadIDiv]>;48def REM : ALU_rr<0b0000001, 0b110, "rem">,49 Sched<[WriteIRem, ReadIRem, ReadIRem]>;50def REMU : ALU_rr<0b0000001, 0b111, "remu">,51 Sched<[WriteIRem, ReadIRem, ReadIRem]>;52} // Predicates = [HasStdExtM]53 54let Predicates = [HasStdExtZmmul, IsRV64], IsSignExtendingOpW = 1 in {55def MULW : ALUW_rr<0b0000001, 0b000, "mulw", Commutable=1>,56 Sched<[WriteIMul32, ReadIMul32, ReadIMul32]>;57} // Predicates = [HasStdExtZmmul, IsRV64]58 59let Predicates = [HasStdExtM, IsRV64], IsSignExtendingOpW = 1 in {60def DIVW : ALUW_rr<0b0000001, 0b100, "divw">,61 Sched<[WriteIDiv32, ReadIDiv32, ReadIDiv32]>;62def DIVUW : ALUW_rr<0b0000001, 0b101, "divuw">,63 Sched<[WriteIDiv32, ReadIDiv32, ReadIDiv32]>;64def REMW : ALUW_rr<0b0000001, 0b110, "remw">,65 Sched<[WriteIRem32, ReadIRem32, ReadIRem32]>;66def REMUW : ALUW_rr<0b0000001, 0b111, "remuw">,67 Sched<[WriteIRem32, ReadIRem32, ReadIRem32]>;68} // Predicates = [HasStdExtM, IsRV64]69 70//===----------------------------------------------------------------------===//71// Pseudo-instructions and codegen patterns72//===----------------------------------------------------------------------===//73 74let Predicates = [HasStdExtZmmul] in {75def : PatGprGpr<mul, MUL>;76def : PatGprGpr<mulhs, MULH>;77def : PatGprGpr<mulhu, MULHU>;78def : PatGprGpr<riscv_mulhsu, MULHSU>;79} // Predicates = [HasStdExtZmmul]80 81let Predicates = [HasStdExtM] in {82def : PatGprGpr<sdiv, DIV>;83def : PatGprGpr<udiv, DIVU>;84def : PatGprGpr<srem, REM>;85def : PatGprGpr<urem, REMU>;86} // Predicates = [HasStdExtM]87 88// Select W instructions if only the lower 32-bits of the result are used.89let Predicates = [HasStdExtZmmul, IsRV64] in90def : PatGprGpr<binop_allwusers<mul>, MULW>;91 92let Predicates = [HasStdExtM, IsRV64] in {93def : PatGprGpr<riscv_divw, DIVW>;94def : PatGprGpr<riscv_divuw, DIVUW>;95def : PatGprGpr<riscv_remuw, REMUW>;96 97// Handle the specific cases where using DIVU/REMU would be correct and result98// in fewer instructions than emitting DIVUW/REMUW then zero-extending the99// result.100def : Pat<(and (riscv_divuw (assertzexti32 GPR:$rs1),101 (assertzexti32 GPR:$rs2)), 0xffffffff),102 (DIVU GPR:$rs1, GPR:$rs2)>;103def : Pat<(and (riscv_remuw (assertzexti32 GPR:$rs1),104 (assertzexti32 GPR:$rs2)), 0xffffffff),105 (REMU GPR:$rs1, GPR:$rs2)>;106 107// Although the sexti32 operands may not have originated from an i32 srem,108// this pattern is safe as it is impossible for two sign extended inputs to109// produce a result where res[63:32]=0 and res[31]=1.110def : Pat<(srem (sexti32 (i64 GPR:$rs1)), (sexti32 (i64 GPR:$rs2))),111 (REMW GPR:$rs1, GPR:$rs2)>;112} // Predicates = [HasStdExtM, IsRV64]113 114let Predicates = [HasStdExtZmmul, IsRV64, NoStdExtZba] in {115// Special case for calculating the full 64-bit product of a 32x32 unsigned116// multiply where the inputs aren't known to be zero extended. We can shift the117// inputs left by 32 and use a MULHU. This saves two SRLIs needed to finish118// zeroing the upper 32 bits.119def : Pat<(i64 (mul (and GPR:$rs1, 0xffffffff), (and GPR:$rs2, 0xffffffff))),120 (MULHU (i64 (SLLI GPR:$rs1, 32)), (i64 (SLLI GPR:$rs2, 32)))>;121} // Predicates = [HasStdExtZmmul, IsRV64, NoStdExtZba]122