brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.4 KiB · fdf0195 Raw
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