Skip to content

Commit

Permalink
[RISCV] Support hypervisor extention instructions
Browse files Browse the repository at this point in the history
    According to privileged spec version-20211203

    Add the following hypervisor instructions:
        - HLV.B HLV.BU
        - HLV.H HLV.HU HLVX.HU
        - HLV.W HLV.WU HLVX.WU
        - HLV.D
        - HSV.B HSV.H HSV.W HSV.D

Signed-off-by: eric.tang <eric.tang@starfivetech.com>

Differential Revision: https://reviews.llvm.org/D117733
  • Loading branch information
eric-xtang1008 committed Feb 28, 2022
1 parent 386c5be commit b496a17
Show file tree
Hide file tree
Showing 6 changed files with 241 additions and 2 deletions.
36 changes: 34 additions & 2 deletions llvm/lib/Target/RISCV/RISCVInstrInfo.td
Expand Up @@ -450,20 +450,35 @@ class BranchCC_rri<bits<3> funct3, string opcodestr>
let isTerminator = 1;
}

let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in
let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in {
class Load_ri<bits<3> funct3, string opcodestr>
: RVInstI<funct3, OPC_LOAD, (outs GPR:$rd), (ins GPR:$rs1, simm12:$imm12),
opcodestr, "$rd, ${imm12}(${rs1})">;

class HLoad_r<bits<7> funct7, bits<5> funct5, string opcodestr>
: RVInstR<funct7, 0b100, OPC_SYSTEM, (outs GPR:$rd),
(ins GPRMemZeroOffset:$rs1), opcodestr, "$rd, $rs1"> {
let rs2 = funct5;
}
}

// Operands for stores are in the order srcreg, base, offset rather than
// reflecting the order these fields are specified in the instruction
// encoding.
let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in
let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in {
class Store_rri<bits<3> funct3, string opcodestr>
: RVInstS<funct3, OPC_STORE, (outs),
(ins GPR:$rs2, GPR:$rs1, simm12:$imm12),
opcodestr, "$rs2, ${imm12}(${rs1})">;

class HStore_rr<bits<7> funct7, string opcodestr>
: RVInstR<funct7, 0b100, OPC_SYSTEM, (outs),
(ins GPR:$rs2, GPRMemZeroOffset:$rs1),
opcodestr, "$rs2, $rs1"> {
let rd = 0;
}
}

let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
class ALU_ri<bits<3> funct3, string opcodestr>
: RVInstI<funct3, OPC_OP_IMM, (outs GPR:$rd), (ins GPR:$rs1, simm12:$imm12),
Expand Down Expand Up @@ -723,6 +738,23 @@ def HFENCE_GVMA : Priv_rr<"hfence.gvma", 0b0110001>, Sched<[]>;
def HINVAL_VVMA : Priv_rr<"hinval.vvma", 0b0010011>, Sched<[]>;
def HINVAL_GVMA : Priv_rr<"hinval.gvma", 0b0110011>, Sched<[]>;

def HLV_B : HLoad_r<0b0110000, 0b00000, "hlv.b">, Sched<[]>;
def HLV_BU : HLoad_r<0b0110000, 0b00001, "hlv.bu">, Sched<[]>;
def HLV_H : HLoad_r<0b0110010, 0b00000, "hlv.h">, Sched<[]>;
def HLV_HU : HLoad_r<0b0110010, 0b00001, "hlv.hu">, Sched<[]>;
def HLVX_HU : HLoad_r<0b0110010, 0b00011, "hlvx.hu">, Sched<[]>;
def HLV_W : HLoad_r<0b0110100, 0b00000, "hlv.w">, Sched<[]>;
def HLVX_WU : HLoad_r<0b0110100, 0b00011, "hlvx.wu">, Sched<[]>;
def HSV_B : HStore_rr<0b0110001, "hsv.b">, Sched<[]>;
def HSV_H : HStore_rr<0b0110011, "hsv.h">, Sched<[]>;
def HSV_W : HStore_rr<0b0110101, "hsv.w">, Sched<[]>;

let Predicates = [IsRV64] in {
def HLV_WU : HLoad_r<0b0110100, 0b00001, "hlv.wu">, Sched<[]>;
def HLV_D : HLoad_r<0b0110110, 0b00000, "hlv.d">, Sched<[]>;
def HSV_D : HStore_rr<0b0110111, "hsv.d">, Sched<[]>;
}

//===----------------------------------------------------------------------===//
// Debug instructions
//===----------------------------------------------------------------------===//
Expand Down
50 changes: 50 additions & 0 deletions llvm/test/MC/RISCV/priv-aliases-valid.s
@@ -0,0 +1,50 @@
# RUN: llvm-mc %s -triple=riscv32 -riscv-no-aliases -show-encoding \
# RUN: | FileCheck -check-prefixes=CHECK,CHECK-INST %s
# RUN: llvm-mc %s -triple=riscv64 -riscv-no-aliases -show-encoding \
# RUN: | FileCheck -check-prefixes=CHECK,CHECK-INST %s
# RUN: llvm-mc -filetype=obj -triple riscv32 < %s \
# RUN: | llvm-objdump -M no-aliases -d - \
# RUN: | FileCheck -check-prefix=CHECK-INST %s
# RUN: llvm-mc -filetype=obj -triple riscv64 < %s \
# RUN: | llvm-objdump -M no-aliases -d - \
# RUN: | FileCheck -check-prefix=CHECK-INST %s

# CHECK-INST: hlv.b a0, (a1)
# CHECK: encoding: [0x73,0xc5,0x05,0x60]
hlv.b a0, 0(a1)

# CHECK-INST: hlv.bu a0, (a1)
# CHECK: encoding: [0x73,0xc5,0x15,0x60]
hlv.bu a0, 0(a1)

# CHECK-INST: hlv.h a1, (a2)
# CHECK: encoding: [0xf3,0x45,0x06,0x64]
hlv.h a1, 0(a2)

# CHECK-INST: hlv.hu a1, (a1)
# CHECK: encoding: [0xf3,0xc5,0x15,0x64]
hlv.hu a1, 0(a1)

# CHECK-INST: hlvx.hu a1, (a2)
# CHECK: encoding: [0xf3,0x45,0x36,0x64]
hlvx.hu a1, 0(a2)

# CHECK-INST: hlv.w a2, (a2)
# CHECK: encoding: [0x73,0x46,0x06,0x68]
hlv.w a2, 0(a2)

# CHECK-INST: hlvx.wu a2, (a3)
# CHECK: encoding: [0x73,0xc6,0x36,0x68]
hlvx.wu a2, 0(a3)

# CHECK-INST: hsv.b a0, (a1)
# CHECK: encoding: [0x73,0xc0,0xa5,0x62]
hsv.b a0, 0(a1)

# CHECK-INST: hsv.h a0, (a1)
# CHECK: encoding: [0x73,0xc0,0xa5,0x66]
hsv.h a0, 0(a1)

# CHECK-INST: hsv.w a0, (a1)
# CHECK: encoding: [0x73,0xc0,0xa5,0x6a]
hsv.w a0, 0(a1)
60 changes: 60 additions & 0 deletions llvm/test/MC/RISCV/priv-invalid.s
Expand Up @@ -29,3 +29,63 @@ hinval.vvma a0, 0x10 # CHECK: :[[@LINE]]:17: error: invalid operand for instruct
hinval.gvma zero, a1, a2 # CHECK: :[[@LINE]]:23: error: invalid operand for instruction

hinval.gvma a0, 0x10 # CHECK: :[[@LINE]]:17: error: invalid operand for instruction

hlv.b a0, 0x10 # CHECK: :[[@LINE]]:16: error: expected '(' after optional integer offset

hlv.b a0, a1 # CHECK: :[[@LINE]]:11: error: expected '(' or optional integer offset

hlv.b a0, 1(a1) # CHECK: :[[@LINE]]:11: error: optional integer offset must be 0

hlv.bu a0, 0x10 # CHECK: :[[@LINE]]:17: error: expected '(' after optional integer offset

hlv.bu a0, a1 # CHECK: :[[@LINE]]:12: error: expected '(' or optional integer offset

hlv.bu a0, 1(a1) # CHECK: :[[@LINE]]:12: error: optional integer offset must be 0

hlv.h a0, 0x10 # CHECK: :[[@LINE]]:16: error: expected '(' after optional integer offset

hlv.h a0, a1 # CHECK: :[[@LINE]]:11: error: expected '(' or optional integer offset

hlv.h a0, 1(a1) # CHECK: :[[@LINE]]:11: error: optional integer offset must be 0

hlv.hu a0, 0x10 # CHECK: :[[@LINE]]:17: error: expected '(' after optional integer offset

hlv.hu a0, a1 # CHECK: :[[@LINE]]:12: error: expected '(' or optional integer offset

hlv.hu a0, 1(a1) # CHECK: :[[@LINE]]:12: error: optional integer offset must be 0

hlvx.hu a0, 0x10 # CHECK: :[[@LINE]]:18: error: expected '(' after optional integer offset

hlvx.hu a0, a1 # CHECK: :[[@LINE]]:13: error: expected '(' or optional integer offset

hlvx.hu a0, 1(a1) # CHECK: :[[@LINE]]:13: error: optional integer offset must be 0

hlv.w a0, 0x10 # CHECK: :[[@LINE]]:16: error: expected '(' after optional integer offset

hlv.w a0, a1 # CHECK: :[[@LINE]]:11: error: expected '(' or optional integer offset

hlv.w a0, 1(a1) # CHECK: :[[@LINE]]:11: error: optional integer offset must be 0

hlvx.wu a0, 0x10 # CHECK: :[[@LINE]]:18: error: expected '(' after optional integer offset

hlvx.wu a0, a1 # CHECK: :[[@LINE]]:13: error: expected '(' or optional integer offset

hlvx.wu a0, 1(a1) # CHECK: :[[@LINE]]:13: error: optional integer offset must be 0

hsv.b a0, 0x10 # CHECK: :[[@LINE]]:16: error: expected '(' after optional integer offset

hsv.b a0, a1 # CHECK: :[[@LINE]]:11: error: expected '(' or optional integer offset

hsv.b a0, 1(a1) # CHECK: :[[@LINE]]:11: error: optional integer offset must be 0

hsv.h a0, 0x10 # CHECK: :[[@LINE]]:16: error: expected '(' after optional integer offset

hsv.h a0, a1 # CHECK: :[[@LINE]]:11: error: expected '(' or optional integer offset

hsv.h a0, 1(a1) # CHECK: :[[@LINE]]:11: error: optional integer offset must be 0

hsv.w a0, 0x10 # CHECK: :[[@LINE]]:16: error: expected '(' after optional integer offset

hsv.w a0, a1 # CHECK: :[[@LINE]]:11: error: expected '(' or optional integer offset

hsv.w a0, 1(a1) # CHECK: :[[@LINE]]:11: error: optional integer offset must be 0
19 changes: 19 additions & 0 deletions llvm/test/MC/RISCV/priv-rv64-invalid.s
@@ -0,0 +1,19 @@
# RUN: not llvm-mc -triple riscv64 < %s 2>&1 | FileCheck %s

hlv.wu a0, 0x10 # CHECK: :[[@LINE]]:17: error: expected '(' after optional integer offset

hlv.wu a0, a1 # CHECK: :[[@LINE]]:12: error: expected '(' or optional integer offset

hlv.wu a0, 1(a1) # CHECK: :[[@LINE]]:12: error: optional integer offset must be 0

hlv.d a0, 0x10 # CHECK: :[[@LINE]]:16: error: expected '(' after optional integer offset

hlv.d a0, a1 # CHECK: :[[@LINE]]:11: error: expected '(' or optional integer offset

hlv.d a0, 1(a1) # CHECK: :[[@LINE]]:11: error: optional integer offset must be 0

hsv.d a0, 0x10 # CHECK: :[[@LINE]]:16: error: expected '(' after optional integer offset

hsv.d a0, a1 # CHECK: :[[@LINE]]:11: error: expected '(' or optional integer offset

hsv.d a0, 1(a1) # CHECK: :[[@LINE]]:11: error: optional integer offset must be 0
38 changes: 38 additions & 0 deletions llvm/test/MC/RISCV/priv-rv64-valid.s
@@ -0,0 +1,38 @@
# RUN: llvm-mc %s -triple=riscv64 -riscv-no-aliases -show-encoding \
# RUN: | FileCheck -check-prefixes=CHECK,CHECK-INST %s
# RUN: llvm-mc -filetype=obj -triple riscv64 < %s \
# RUN: | llvm-objdump -M no-aliases -d - \
# RUN: | FileCheck -check-prefix=CHECK-INST %s

# RUN: not llvm-mc -triple riscv32 < %s 2>&1 \
# RUN: | FileCheck -check-prefix=CHECK-RV32 %s

# CHECK-INST: hlv.wu a0, (a1)
# CHECK: encoding: [0x73,0xc5,0x15,0x68]
# CHECK-RV32: :[[@LINE+1]]:1: error: instruction requires the following: RV64I Base Instruction Set
hlv.wu a0, (a1)

# CHECK-INST: hlv.wu a0, (a1)
# CHECK: encoding: [0x73,0xc5,0x15,0x68]
# CHECK-RV32: :[[@LINE+1]]:1: error: instruction requires the following: RV64I Base Instruction Set
hlv.wu a0, 0(a1)

# CHECK-INST: hlv.d a0, (a1)
# CHECK: encoding: [0x73,0xc5,0x05,0x6c]
# CHECK-RV32: :[[@LINE+1]]:1: error: instruction requires the following: RV64I Base Instruction Set
hlv.d a0, (a1)

# CHECK-INST: hlv.d a0, (a1)
# CHECK: encoding: [0x73,0xc5,0x05,0x6c]
# CHECK-RV32: :[[@LINE+1]]:1: error: instruction requires the following: RV64I Base Instruction Set
hlv.d a0, 0(a1)

# CHECK-INST: hsv.d a0, (a1)
# CHECK: encoding: [0x73,0xc0,0xa5,0x6e]
# CHECK-RV32: :[[@LINE+1]]:1: error: instruction requires the following: RV64I Base Instruction Set
hsv.d a0, (a1)

# CHECK-INST: hsv.d a0, (a1)
# CHECK: encoding: [0x73,0xc0,0xa5,0x6e]
# CHECK-RV32: :[[@LINE+1]]:1: error: instruction requires the following: RV64I Base Instruction Set
hsv.d a0, 0(a1)
40 changes: 40 additions & 0 deletions llvm/test/MC/RISCV/priv-valid.s
Expand Up @@ -80,3 +80,43 @@ hinval.gvma zero, zero
# CHECK-INST: hinval.gvma a0, a1
# CHECK: encoding: [0x73,0x00,0xb5,0x66]
hinval.gvma a0, a1

# CHECK-INST: hlv.b a0, (a1)
# CHECK: encoding: [0x73,0xc5,0x05,0x60]
hlv.b a0, (a1)

# CHECK-INST: hlv.bu a0, (a1)
# CHECK: encoding: [0x73,0xc5,0x15,0x60]
hlv.bu a0, (a1)

# CHECK-INST: hlv.h a1, (a2)
# CHECK: encoding: [0xf3,0x45,0x06,0x64]
hlv.h a1, (a2)

# CHECK-INST: hlv.hu a1, (a1)
# CHECK: encoding: [0xf3,0xc5,0x15,0x64]
hlv.hu a1, (a1)

# CHECK-INST: hlvx.hu a1, (a2)
# CHECK: encoding: [0xf3,0x45,0x36,0x64]
hlvx.hu a1, (a2)

# CHECK-INST: hlv.w a2, (a2)
# CHECK: encoding: [0x73,0x46,0x06,0x68]
hlv.w a2, (a2)

# CHECK-INST: hlvx.wu a2, (a3)
# CHECK: encoding: [0x73,0xc6,0x36,0x68]
hlvx.wu a2, (a3)

# CHECK-INST: hsv.b a0, (a1)
# CHECK: encoding: [0x73,0xc0,0xa5,0x62]
hsv.b a0, (a1)

# CHECK-INST: hsv.h a0, (a1)
# CHECK: encoding: [0x73,0xc0,0xa5,0x66]
hsv.h a0, (a1)

# CHECK-INST: hsv.w a0, (a1)
# CHECK: encoding: [0x73,0xc0,0xa5,0x6a]
hsv.w a0, (a1)

0 comments on commit b496a17

Please sign in to comment.