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-exception 6// 7//===----------------------------------------------------------------------===// 8// 9// This file describes the RISC-V instructions from the standard 'M', Integer 10// Multiplication and Division instruction set extension. 11// 12//===----------------------------------------------------------------------===// 13 14//===----------------------------------------------------------------------===// 15// RISC-V specific DAG Nodes. 16//===----------------------------------------------------------------------===// 17 18def riscv_divw : SDNode<"RISCVISD::DIVW", SDTIntBinOp>; 19def riscv_divuw : SDNode<"RISCVISD::DIVUW", SDTIntBinOp>; 20def riscv_remuw : SDNode<"RISCVISD::REMUW", SDTIntBinOp>; 21 22//===----------------------------------------------------------------------===// 23// Instructions 24//===----------------------------------------------------------------------===// 25 26let Predicates = [HasStdExtM] in { 27def MUL : ALU_rr<0b0000001, 0b000, "mul">; 28def MULH : ALU_rr<0b0000001, 0b001, "mulh">; 29def MULHSU : ALU_rr<0b0000001, 0b010, "mulhsu">; 30def MULHU : ALU_rr<0b0000001, 0b011, "mulhu">; 31def DIV : ALU_rr<0b0000001, 0b100, "div">; 32def DIVU : ALU_rr<0b0000001, 0b101, "divu">; 33def REM : ALU_rr<0b0000001, 0b110, "rem">; 34def REMU : ALU_rr<0b0000001, 0b111, "remu">; 35} // Predicates = [HasStdExtM] 36 37let Predicates = [HasStdExtM, IsRV64] in { 38def MULW : ALUW_rr<0b0000001, 0b000, "mulw">; 39def DIVW : ALUW_rr<0b0000001, 0b100, "divw">; 40def DIVUW : ALUW_rr<0b0000001, 0b101, "divuw">; 41def REMW : ALUW_rr<0b0000001, 0b110, "remw">; 42def REMUW : ALUW_rr<0b0000001, 0b111, "remuw">; 43} // Predicates = [HasStdExtM, IsRV64] 44 45//===----------------------------------------------------------------------===// 46// Pseudo-instructions and codegen patterns 47//===----------------------------------------------------------------------===// 48 49let Predicates = [HasStdExtM] in { 50def : PatGprGpr<mul, MUL>; 51def : PatGprGpr<mulhs, MULH>; 52def : PatGprGpr<mulhu, MULHU>; 53// No ISDOpcode for mulhsu 54def : PatGprGpr<sdiv, DIV>; 55def : PatGprGpr<udiv, DIVU>; 56def : PatGprGpr<srem, REM>; 57def : PatGprGpr<urem, REMU>; 58} // Predicates = [HasStdExtM] 59 60let Predicates = [HasStdExtM, IsRV64] in { 61def : Pat<(sext_inreg (mul GPR:$rs1, GPR:$rs2), i32), 62 (MULW GPR:$rs1, GPR:$rs2)>; 63 64def : PatGprGpr<riscv_divw, DIVW>; 65def : PatGprGpr<riscv_divuw, DIVUW>; 66def : PatGprGpr<riscv_remuw, REMUW>; 67 68// Handle the specific cases where using DIVU/REMU would be correct and result 69// in fewer instructions than emitting DIVUW/REMUW then zero-extending the 70// result. 71def : Pat<(zexti32 (riscv_divuw (zexti32 GPR:$rs1), (zexti32 GPR:$rs2))), 72 (DIVU GPR:$rs1, GPR:$rs2)>; 73def : Pat<(zexti32 (riscv_remuw (zexti32 GPR:$rs1), (zexti32 GPR:$rs2))), 74 (REMU GPR:$rs1, GPR:$rs2)>; 75 76// Although the sexti32 operands may not have originated from an i32 srem, 77// this pattern is safe as it is impossible for two sign extended inputs to 78// produce a result where res[63:32]=0 and res[31]=1. 79def : Pat<(srem (sexti32 GPR:$rs1), (sexti32 GPR:$rs2)), 80 (REMW GPR:$rs1, GPR:$rs2)>; 81def : Pat<(sext_inreg (srem (sexti32 GPR:$rs1), 82 (sexti32 GPR:$rs2)), i32), 83 (REMW GPR:$rs1, GPR:$rs2)>; 84} // Predicates = [HasStdExtM, IsRV64] 85