Skip to content

[RISCV][MC] Support Base P non-GPR pair instructions #137927

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -908,6 +908,8 @@ struct RISCVOperand final : public MCParsedAsmOperand {
VK == RISCVMCExpr::VK_QC_ABS20;
}

bool isSImm10Unsigned() const { return isSImm<10>() || isUImm<10>(); }

bool isUImm20LUI() const {
if (!isImm())
return false;
Expand Down Expand Up @@ -1538,6 +1540,9 @@ bool RISCVAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
return generateImmOutOfRangeError(
Operands, ErrorInfo, 0, (1 << 9) - 8,
"immediate must be a multiple of 8 bytes in the range");
case Match_InvalidSImm10Unsigned:
return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 9),
(1 << 10) - 1);
case Match_InvalidUImm10Lsb00NonZero:
return generateImmOutOfRangeError(
Operands, ErrorInfo, 4, (1 << 10) - 4,
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,7 @@ enum OperandType : unsigned {
OPERAND_SIMM5_PLUS1,
OPERAND_SIMM6,
OPERAND_SIMM6_NONZERO,
OPERAND_SIMM10_UNSIGNED,
OPERAND_SIMM10_LSB0000_NONZERO,
OPERAND_SIMM11,
OPERAND_SIMM12,
Expand Down
3 changes: 3 additions & 0 deletions llvm/lib/Target/RISCV/RISCVInstrInfo.td
Original file line number Diff line number Diff line change
Expand Up @@ -2251,6 +2251,9 @@ include "RISCVInstrInfoV.td"
include "RISCVInstrInfoZvk.td"
include "RISCVInstrInfoZvqdotq.td"

// Packed SIMD
include "RISCVInstrInfoP.td"

// Compressed
include "RISCVInstrInfoC.td"
include "RISCVInstrInfoZc.td"
Expand Down
159 changes: 159 additions & 0 deletions llvm/lib/Target/RISCV/RISCVInstrInfoP.td
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
//===-- RISCVInstrInfoP.td - RISC-V 'P' instructions -------*- tablegen -*-===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// This file describes the RISC-V instructions from the standard 'Base P'
// Packed SIMD instruction set extension.
//
// This version is still experimental as the 'P' extension hasn't been
// ratified yet.
//
//===----------------------------------------------------------------------===//

//===----------------------------------------------------------------------===//
// Operand and SDNode transformation definitions.
//===----------------------------------------------------------------------===//

// A 10-bit signed immediate allowing range [-512, 1023]
// but will decode to [-512, 511].
def simm10_unsigned : RISCVOp {
let ParserMatchClass = SImmAsmOperand<10, "Unsigned">;
let EncoderMethod = "getImmOpValue";
let DecoderMethod = "decodeSImmOperand<10>";
let OperandType = "OPERAND_SIMM10_UNSIGNED";
let MCOperandPredicate = [{
int64_t Imm;
if (!MCOp.evaluateAsConstantImm(Imm))
return false;
return isInt<10>(Imm) || isUInt<10>(Imm);
}];
}

//===----------------------------------------------------------------------===//
// Instruction class templates
//===----------------------------------------------------------------------===//

let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
class RVPUnaryImm10<bits<7> funct7, string opcodestr>
: RVInstIBase<0b010, OPC_OP_IMM_32, (outs GPR:$rd), (ins simm10_unsigned:$simm10u),
opcodestr, "$rd, $simm10u"> {
bits<10> simm10u;

let Inst{31-25} = funct7;
let Inst{24-16} = simm10u{8-0};
let Inst{15} = simm10u{9};
}

let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
class RVPUnaryImm8<bits<8> funct8, string opcodestr>
: RVInstIBase<0b010, OPC_OP_IMM_32, (outs GPR:$rd), (ins uimm8:$uimm8),
opcodestr, "$rd, $uimm8"> {
bits<8> uimm8;

let Inst{31-24} = funct8;
let Inst{23-16} = uimm8;
let Inst{15} = 0b0;
}

let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
class RVPUnaryImm5<bits<3> f, string opcodestr>
: RVInstIBase<0b010, OPC_OP_IMM_32, (outs GPR:$rd),
(ins GPR:$rs1, uimm5:$uimm5), opcodestr, "$rd, $rs1, $uimm5"> {
bits<5> uimm5;
let Inst{31} = 0b1;
let Inst{30-28} = f;
let Inst{27} = 0b0;
let Inst{26-25} = 0b01;
let Inst{24-20} = uimm5;
}

let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
class RVPUnaryImm4<bits<3> f, string opcodestr>
: RVInstIBase<0b010, OPC_OP_IMM_32, (outs GPR:$rd),
(ins GPR:$rs1, uimm4:$uimm4), opcodestr, "$rd, $rs1, $uimm4"> {
bits<4> uimm4;
let Inst{31} = 0b1;
let Inst{30-28} = f;
let Inst{27} = 0b0;
let Inst{26-24} = 0b001;
let Inst{23-20} = uimm4;
}

let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
class RVPUnaryImm3<bits<3> f, string opcodestr>
: RVInstIBase<0b010, OPC_OP_IMM_32, (outs GPR:$rd),
(ins GPR:$rs1, uimm3:$uimm3), opcodestr, "$rd, $rs1, $uimm3"> {
bits<3> uimm3;
let Inst{31} = 0b1;
let Inst{30-28} = f;
let Inst{27} = 0b0;
let Inst{26-23} = 0b0001;
let Inst{22-20} = uimm3;
}

let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
class RVPUnaryWUF<bits<2> w, bits<5> uf, string opcodestr>
: RVInstIBase<0b010, OPC_OP_IMM_32, (outs GPR:$rd), (ins GPR:$rs1),
opcodestr, "$rd, $rs1"> {
let Inst{31-27} = 0b11100;
let Inst{26-25} = w;
let Inst{24-20} = uf;
}

//===----------------------------------------------------------------------===//
// Instructions
//===----------------------------------------------------------------------===//

let Predicates = [HasStdExtP] in {
def CLS : Unary_r<0b011000000011, 0b001, "cls">;
def ABS : Unary_r<0b011000000111, 0b001, "abs">;
} // Predicates = [HasStdExtP]
let Predicates = [HasStdExtP, IsRV32] in
def REV_RV32 : Unary_r<0b011010011111, 0b101, "rev">;

let Predicates = [HasStdExtP, IsRV64] in {
def REV16 : Unary_r<0b011010110000, 0b101, "rev16">;
def REV_RV64 : Unary_r<0b011010111111, 0b101, "rev">;

def CLSW : UnaryW_r<0b011000000011, 0b001, "clsw">;
def ABSW : UnaryW_r<0b011000000111, 0b001, "absw">;
} // Predicates = [HasStdExtP, IsRV64]

let Predicates = [HasStdExtP] in {
def PSLLI_B : RVPUnaryImm3<0b000, "pslli.b">;
def PSLLI_H : RVPUnaryImm4<0b000, "pslli.h">;
def PSSLAI_H : RVPUnaryImm4<0b101, "psslai.h">;
} // Predicates = [HasStdExtP]
let DecoderNamespace = "RV32Only",
Predicates = [HasStdExtP, IsRV32] in
def SSLAI : RVPUnaryImm5<0b101, "sslai">;
let Predicates = [HasStdExtP, IsRV64] in {
def PSLLI_W : RVPUnaryImm5<0b000, "pslli.w">;
def PSSLAI_W : RVPUnaryImm5<0b101, "psslai.w">;
} // Predicates = [HasStdExtP, IsRV64]

let Predicates = [HasStdExtP] in
def PLI_H : RVPUnaryImm10<0b1011000, "pli.h">;
let Predicates = [HasStdExtP, IsRV64] in
def PLI_W : RVPUnaryImm10<0b1011001, "pli.w">;
let Predicates = [HasStdExtP] in
def PLI_B : RVPUnaryImm8<0b10110100, "pli.b">;

let Predicates = [HasStdExtP] in {
def PSEXT_H_B : RVPUnaryWUF<0b00, 0b00100, "psext.h.b">;
def PSABS_H : RVPUnaryWUF<0b00, 0b00111, "psabs.h">;
def PSABS_B : RVPUnaryWUF<0b10, 0b00111, "psabs.b">;
} // Predicates = [HasStdExtP]
let Predicates = [HasStdExtP, IsRV64] in {
def PSEXT_W_B : RVPUnaryWUF<0b01, 0b00100, "psext.w.b">;
def PSEXT_W_H : RVPUnaryWUF<0b01, 0b00101, "psext.w.h">;
} // Predicates = [HasStdExtP, IsRV64]

let Predicates = [HasStdExtP] in
def PLUI_H : RVPUnaryImm10<0b1111000, "plui.h">;
let Predicates = [HasStdExtP, IsRV64] in
def PLUI_W : RVPUnaryImm10<0b1111001, "plui.w">;
3 changes: 3 additions & 0 deletions llvm/test/CodeGen/RISCV/attributes.ll
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,7 @@
; RUN: llc -mtriple=riscv64 -mattr=+sdext %s -o - | FileCheck --check-prefix=RV64SDEXT %s
; RUN: llc -mtriple=riscv64 -mattr=+sdtrig %s -o - | FileCheck --check-prefix=RV64SDTRIG %s
; RUN: llc -mtriple=riscv64 -mattr=+experimental-xqccmp %s -o - | FileCheck --check-prefix=RV64XQCCMP %s
; RUN: llc -mtriple=riscv64 -mattr=+experimental-p %s -o - | FileCheck --check-prefix=RV64P %s


; Tests for profile features.
Expand Down Expand Up @@ -520,6 +521,7 @@
; RV32SUPM: .attribute 5, "rv32i2p1_supm1p0"
; RV32SMCTR: .attribute 5, "rv32i2p1_smctr1p0_sscsrind1p0"
; RV32SSCTR: .attribute 5, "rv32i2p1_sscsrind1p0_ssctr1p0"
; RV32P: .attribute 5, "rv32i2p1_p0p14"

; RV64M: .attribute 5, "rv64i2p1_m2p0_zmmul1p0"
; RV64ZMMUL: .attribute 5, "rv64i2p1_zmmul1p0"
Expand Down Expand Up @@ -680,6 +682,7 @@
; RV64SDEXT: .attribute 5, "rv64i2p1_sdext1p0"
; RV64SDTRIG: .attribute 5, "rv64i2p1_sdtrig1p0"
; RV64XQCCMP: .attribute 5, "rv64i2p1_zca1p0_xqccmp0p1"
; RV64P: .attribute 5, "rv64i2p1_p0p14"

; RVI20U32: .attribute 5, "rv32i2p1"
; RVI20U64: .attribute 5, "rv64i2p1"
Expand Down
17 changes: 17 additions & 0 deletions llvm/test/MC/RISCV/rv32p-invalid.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# RUN: not llvm-mc -triple=riscv32 --mattr=+experimental-p %s 2>&1 \
# RUN: | FileCheck %s --check-prefixes=CHECK-ERROR

# Imm overflow
pli.h a0, 0x400
# CHECK-ERROR: immediate must be an integer in the range [-512, 1023]
pli.b a0, 0x200
# CHECK-ERROR: immediate must be an integer in the range [0, 255]

pslli.b a6, a7, 100
# CHECK-ERROR: immediate must be an integer in the range [0, 7]
pslli.h ra, sp, 100
# CHECK-ERROR: immediate must be an integer in the range [0, 15]
psslai.h t0, t1, 100
# CHECK-ERROR: immediate must be an integer in the range [0, 15]
sslai a4, a5, -1
# CHECK-ERROR: immediate must be an integer in the range [0, 31]
65 changes: 52 additions & 13 deletions llvm/test/MC/RISCV/rv32p-valid.s
Original file line number Diff line number Diff line change
@@ -1,36 +1,75 @@
# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-p -M no-aliases -show-encoding \
# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+experimental-p < %s \
# RUN: | llvm-objdump --mattr=+experimental-p -M no-aliases -d -r - \
# RUN: | llvm-objdump --mattr=+experimental-p -M no-aliases -d -r --no-print-imm-hex - \
# RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s

# CHECK-ASM-AND-OBJ: sh1add a0, a1, a2
# CHECK-ASM: encoding: [0x33,0xa5,0xc5,0x20]
sh1add a0, a1, a2
# CHECK-ASM-AND-OBJ: clz a0, a1
# CHECK-ASM: encoding: [0x13,0x95,0x05,0x60]
clz a0, a1
# CHECK-ASM-AND-OBJ: cls a1, a2
# CHECK-ASM: encoding: [0x93,0x15,0x36,0x60]
cls a1, a2
# CHECK-ASM-AND-OBJ: sext.b a2, a3
# CHECK-ASM: encoding: [0x13,0x96,0x46,0x60]
sext.b a2, a3
# CHECK-ASM-AND-OBJ: sext.h t0, t1
# CHECK-ASM: encoding: [0x93,0x12,0x53,0x60]
sext.h t0, t1
# CHECK-ASM-AND-OBJ: abs a4, a5
# CHECK-ASM: encoding: [0x13,0x97,0x77,0x60]
abs a4, a5
# CHECK-ASM-AND-OBJ: rev8 s0, s1
# CHECK-ASM: encoding: [0x13,0xd4,0x84,0x69]
rev8 s0, s1
# CHECK-ASM-AND-OBJ: rev s2, s3
# CHECK-ASM: encoding: [0x13,0xd9,0xf9,0x69]
rev s2, s3
# CHECK-ASM-AND-OBJ: sh1add a0, a1, a2
# CHECK-ASM: encoding: [0x33,0xa5,0xc5,0x20]
sh1add a0, a1, a2
# CHECK-ASM-AND-OBJ: pack s0, s1, s2
# CHECK-ASM: encoding: [0x33,0xc4,0x24,0x09]
pack s0, s1, s2
# CHECK-ASM-AND-OBJ: min t0, t1, t2
# CHECK-ASM: encoding: [0xb3,0x42,0x73,0x0a]
min t0, t1, t2
# CHECK-ASM-AND-OBJ: minu t0, t1, t2
# CHECK-ASM: encoding: [0xb3,0x52,0x73,0x0a]
minu t0, t1, t2
# CHECK-ASM-AND-OBJ: minu ra, sp, gp
# CHECK-ASM: encoding: [0xb3,0x50,0x31,0x0a]
minu ra, sp, gp
# CHECK-ASM-AND-OBJ: max t3, t4, t5
# CHECK-ASM: encoding: [0x33,0xee,0xee,0x0b]
max t3, t4, t5
# CHECK-ASM-AND-OBJ: maxu a4, a5, a6
# CHECK-ASM: encoding: [0x33,0xf7,0x07,0x0b]
maxu a4, a5, a6
# CHECK-ASM-AND-OBJ: pack s0, s1, s2
# CHECK-ASM: encoding: [0x33,0xc4,0x24,0x09]
pack s0, s1, s2
# CHECK-ASM-AND-OBJ: rev8 s0, s1
# CHECK-ASM: encoding: [0x13,0xd4,0x84,0x69]
rev8 s0, s1
# CHECK-ASM-AND-OBJ: pslli.b a6, a7, 0
# CHECK-ASM: encoding: [0x1b,0xa8,0x88,0x80]
pslli.b a6, a7, 0
# CHECK-ASM-AND-OBJ: pslli.h ra, sp, 1
# CHECK-ASM: encoding: [0x9b,0x20,0x11,0x81]
pslli.h ra, sp, 1
# CHECK-ASM-AND-OBJ: psslai.h t0, t1, 2
# CHECK-ASM: encoding: [0x9b,0x22,0x23,0xd1]
psslai.h t0, t1, 2
# CHECK-ASM-AND-OBJ: sslai a4, a5, 3
# CHECK-ASM: encoding: [0x1b,0xa7,0x37,0xd2]
sslai a4, a5, 3
# CHECK-ASM-AND-OBJ: pli.h a5, 16
# CHECK-ASM: encoding: [0x9b,0x27,0x10,0xb0]
pli.h a5, 16
# CHECK-ASM-AND-OBJ: pli.b a6, 16
# CHECK-ASM: encoding: [0x1b,0x28,0x10,0xb4]
pli.b a6, 16
# CHECK-ASM-AND-OBJ: psext.h.b a7, a0
# CHECK-ASM: encoding: [0x9b,0x28,0x45,0xe0]
psext.h.b a7, a0
# CHECK-ASM-AND-OBJ: psabs.h a1, a2
# CHECK-ASM: encoding: [0x9b,0x25,0x76,0xe0]
psabs.h a1, a2
# CHECK-ASM-AND-OBJ: psabs.b t0, t1
# CHECK-ASM: encoding: [0x9b,0x22,0x73,0xe4]
psabs.b t0, t1
# CHECK-ASM-AND-OBJ: plui.h gp, 32
# CHECK-ASM: encoding: [0x9b,0x21,0x20,0xf0]
plui.h gp, 32
19 changes: 19 additions & 0 deletions llvm/test/MC/RISCV/rv64p-invalid.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# RUN: not llvm-mc -triple=riscv64 --mattr=+experimental-p %s 2>&1 \
# RUN: | FileCheck %s --check-prefixes=CHECK-ERROR

# Imm overflow
pli.h a0, 0x400
# CHECK-ERROR: immediate must be an integer in the range [-512, 1023]
pli.w a1, -0x201
# CHECK-ERROR: immediate must be an integer in the range [-512, 1023]

pslli.b a6, a7, 100
# CHECK-ERROR: immediate must be an integer in the range [0, 7]
pslli.h ra, sp, 100
# CHECK-ERROR: immediate must be an integer in the range [0, 15]
pslli.w ra, sp, 100
# CHECK-ERROR: immediate must be an integer in the range [0, 31]
psslai.h t0, t1, 100
# CHECK-ERROR: immediate must be an integer in the range [0, 15]
psslai.w a4, a5, -1
# CHECK-ERROR: error: immediate must be an integer in the range [0, 31]
Loading