Commit 3d5e5f18 authored by Lu Yahan's avatar Lu Yahan Committed by V8 LUCI CQ

[riscv64] Add macro to control disassemble rvv

Change-Id: Iad4b34b1c4a85800e8e1d6c01b686dd19e8116a6
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3600532
Auto-Submit: Yahan Lu <yahan@iscas.ac.cn>
Reviewed-by: 's avatarji qiu <qiuji@iscas.ac.cn>
Commit-Queue: ji qiu <qiuji@iscas.ac.cn>
Cr-Commit-Position: refs/heads/main@{#80508}
parent ee1a364f
......@@ -59,7 +59,7 @@ static unsigned CpuFeaturesImpliedByCompiler() {
#if (defined CAN_USE_RVV_INSTRUCTIONS)
answer |= 1u << RISCV_SIMD;
#endif // def CAN_USE_RVV_INSTRUCTIONS || USE_SIMULATOR
#endif // def CAN_USE_RVV_INSTRUCTIONS
return answer;
}
......@@ -2913,6 +2913,7 @@ uint8_t vsew_switch(VSew vsew) {
void Assembler::vl(VRegister vd, Register rs1, uint8_t lumop, VSew vsew,
MaskType mask) {
std::cout << "vl" << std::endl;
uint8_t width = vsew_switch(vsew);
GenInstrV(LOAD_FP, width, vd, rs1, lumop, mask, 0b00, 0, 0b000);
}
......
......@@ -1412,265 +1412,271 @@ void Decoder::DecodeR4Type(Instruction* instr) {
}
void Decoder::DecodeIType(Instruction* instr) {
if (instr->vl_vs_width() != -1) {
DecodeRvvVL(instr);
} else {
switch (instr->InstructionBits() & kITypeMask) {
case RO_JALR:
if (instr->RdValue() == zero_reg.code() &&
instr->Rs1Value() == ra.code() && instr->Imm12Value() == 0)
Format(instr, "ret");
else if (instr->RdValue() == zero_reg.code() &&
instr->Imm12Value() == 0)
Format(instr, "jr 'rs1");
else if (instr->RdValue() == ra.code() && instr->Imm12Value() == 0)
Format(instr, "jalr 'rs1");
else
Format(instr, "jalr 'rd, 'imm12('rs1)");
break;
case RO_LB:
Format(instr, "lb 'rd, 'imm12('rs1)");
break;
case RO_LH:
Format(instr, "lh 'rd, 'imm12('rs1)");
break;
case RO_LW:
Format(instr, "lw 'rd, 'imm12('rs1)");
break;
case RO_LBU:
Format(instr, "lbu 'rd, 'imm12('rs1)");
break;
case RO_LHU:
Format(instr, "lhu 'rd, 'imm12('rs1)");
break;
switch (instr->InstructionBits() & kITypeMask) {
case RO_JALR:
if (instr->RdValue() == zero_reg.code() &&
instr->Rs1Value() == ra.code() && instr->Imm12Value() == 0)
Format(instr, "ret");
else if (instr->RdValue() == zero_reg.code() && instr->Imm12Value() == 0)
Format(instr, "jr 'rs1");
else if (instr->RdValue() == ra.code() && instr->Imm12Value() == 0)
Format(instr, "jalr 'rs1");
else
Format(instr, "jalr 'rd, 'imm12('rs1)");
break;
case RO_LB:
Format(instr, "lb 'rd, 'imm12('rs1)");
break;
case RO_LH:
Format(instr, "lh 'rd, 'imm12('rs1)");
break;
case RO_LW:
Format(instr, "lw 'rd, 'imm12('rs1)");
break;
case RO_LBU:
Format(instr, "lbu 'rd, 'imm12('rs1)");
break;
case RO_LHU:
Format(instr, "lhu 'rd, 'imm12('rs1)");
break;
#ifdef V8_TARGET_ARCH_64_BIT
case RO_LWU:
Format(instr, "lwu 'rd, 'imm12('rs1)");
break;
case RO_LD:
Format(instr, "ld 'rd, 'imm12('rs1)");
break;
case RO_LWU:
Format(instr, "lwu 'rd, 'imm12('rs1)");
break;
case RO_LD:
Format(instr, "ld 'rd, 'imm12('rs1)");
break;
#endif /*V8_TARGET_ARCH_64_BIT*/
case RO_ADDI:
if (instr->Imm12Value() == 0) {
if (instr->RdValue() == zero_reg.code() &&
instr->Rs1Value() == zero_reg.code())
Format(instr, "nop");
else
Format(instr, "mv 'rd, 'rs1");
} else if (instr->Rs1Value() == zero_reg.code()) {
Format(instr, "li 'rd, 'imm12");
} else {
Format(instr, "addi 'rd, 'rs1, 'imm12");
}
break;
case RO_SLTI:
Format(instr, "slti 'rd, 'rs1, 'imm12");
break;
case RO_SLTIU:
if (instr->Imm12Value() == 1)
Format(instr, "seqz 'rd, 'rs1");
else
Format(instr, "sltiu 'rd, 'rs1, 'imm12");
break;
case RO_XORI:
if (instr->Imm12Value() == -1)
Format(instr, "not 'rd, 'rs1");
case RO_ADDI:
if (instr->Imm12Value() == 0) {
if (instr->RdValue() == zero_reg.code() &&
instr->Rs1Value() == zero_reg.code())
Format(instr, "nop");
else
Format(instr, "xori 'rd, 'rs1, 'imm12x");
break;
case RO_ORI:
Format(instr, "ori 'rd, 'rs1, 'imm12x");
break;
case RO_ANDI:
Format(instr, "andi 'rd, 'rs1, 'imm12x");
break;
case RO_SLLI:
Format(instr, "slli 'rd, 'rs1, 's64");
break;
case RO_SRLI: { // RO_SRAI
if (!instr->IsArithShift()) {
Format(instr, "srli 'rd, 'rs1, 's64");
} else {
Format(instr, "srai 'rd, 'rs1, 's64");
}
break;
Format(instr, "mv 'rd, 'rs1");
} else if (instr->Rs1Value() == zero_reg.code()) {
Format(instr, "li 'rd, 'imm12");
} else {
Format(instr, "addi 'rd, 'rs1, 'imm12");
}
break;
case RO_SLTI:
Format(instr, "slti 'rd, 'rs1, 'imm12");
break;
case RO_SLTIU:
if (instr->Imm12Value() == 1)
Format(instr, "seqz 'rd, 'rs1");
else
Format(instr, "sltiu 'rd, 'rs1, 'imm12");
break;
case RO_XORI:
if (instr->Imm12Value() == -1)
Format(instr, "not 'rd, 'rs1");
else
Format(instr, "xori 'rd, 'rs1, 'imm12x");
break;
case RO_ORI:
Format(instr, "ori 'rd, 'rs1, 'imm12x");
break;
case RO_ANDI:
Format(instr, "andi 'rd, 'rs1, 'imm12x");
break;
case RO_SLLI:
Format(instr, "slli 'rd, 'rs1, 's64");
break;
case RO_SRLI: { // RO_SRAI
if (!instr->IsArithShift()) {
Format(instr, "srli 'rd, 'rs1, 's64");
} else {
Format(instr, "srai 'rd, 'rs1, 's64");
}
break;
}
#ifdef V8_TARGET_ARCH_64_BIT
case RO_ADDIW:
if (instr->Imm12Value() == 0)
Format(instr, "sext.w 'rd, 'rs1");
else
Format(instr, "addiw 'rd, 'rs1, 'imm12");
break;
case RO_SLLIW:
Format(instr, "slliw 'rd, 'rs1, 's32");
break;
case RO_SRLIW: { // RO_SRAIW
if (!instr->IsArithShift()) {
Format(instr, "srliw 'rd, 'rs1, 's32");
} else {
Format(instr, "sraiw 'rd, 'rs1, 's32");
}
break;
case RO_ADDIW:
if (instr->Imm12Value() == 0)
Format(instr, "sext.w 'rd, 'rs1");
else
Format(instr, "addiw 'rd, 'rs1, 'imm12");
break;
case RO_SLLIW:
Format(instr, "slliw 'rd, 'rs1, 's32");
break;
case RO_SRLIW: { // RO_SRAIW
if (!instr->IsArithShift()) {
Format(instr, "srliw 'rd, 'rs1, 's32");
} else {
Format(instr, "sraiw 'rd, 'rs1, 's32");
}
break;
}
#endif /*V8_TARGET_ARCH_64_BIT*/
case RO_FENCE:
if (instr->MemoryOrder(true) == PSIORW &&
instr->MemoryOrder(false) == PSIORW)
Format(instr, "fence");
else
Format(instr, "fence 'pre, 'suc");
break;
case RO_ECALL: { // RO_EBREAK
if (instr->Imm12Value() == 0) { // ECALL
Format(instr, "ecall");
} else if (instr->Imm12Value() == 1) { // EBREAK
Format(instr, "ebreak");
} else {
UNSUPPORTED_RISCV();
}
break;
case RO_FENCE:
if (instr->MemoryOrder(true) == PSIORW &&
instr->MemoryOrder(false) == PSIORW)
Format(instr, "fence");
else
Format(instr, "fence 'pre, 'suc");
break;
case RO_ECALL: { // RO_EBREAK
if (instr->Imm12Value() == 0) { // ECALL
Format(instr, "ecall");
} else if (instr->Imm12Value() == 1) { // EBREAK
Format(instr, "ebreak");
} else {
UNSUPPORTED_RISCV();
}
// TODO(riscv): use Zifencei Standard Extension macro block
case RO_FENCE_I:
Format(instr, "fence.i");
break;
// TODO(riscv): use Zicsr Standard Extension macro block
// FIXME(RISC-V): Add special formatting for CSR registers
case RO_CSRRW:
if (instr->CsrValue() == csr_fcsr) {
if (instr->RdValue() == zero_reg.code())
Format(instr, "fscsr 'rs1");
else
Format(instr, "fscsr 'rd, 'rs1");
} else if (instr->CsrValue() == csr_frm) {
if (instr->RdValue() == zero_reg.code())
Format(instr, "fsrm 'rs1");
else
Format(instr, "fsrm 'rd, 'rs1");
} else if (instr->CsrValue() == csr_fflags) {
if (instr->RdValue() == zero_reg.code())
Format(instr, "fsflags 'rs1");
else
Format(instr, "fsflags 'rd, 'rs1");
} else if (instr->RdValue() == zero_reg.code()) {
Format(instr, "csrw 'csr, 'rs1");
} else {
Format(instr, "csrrw 'rd, 'csr, 'rs1");
}
break;
case RO_CSRRS:
if (instr->Rs1Value() == zero_reg.code()) {
switch (instr->CsrValue()) {
case csr_instret:
Format(instr, "rdinstret 'rd");
break;
case csr_instreth:
Format(instr, "rdinstreth 'rd");
break;
case csr_time:
Format(instr, "rdtime 'rd");
break;
case csr_timeh:
Format(instr, "rdtimeh 'rd");
break;
case csr_cycle:
Format(instr, "rdcycle 'rd");
break;
case csr_cycleh:
Format(instr, "rdcycleh 'rd");
break;
case csr_fflags:
Format(instr, "frflags 'rd");
break;
case csr_frm:
Format(instr, "frrm 'rd");
break;
case csr_fcsr:
Format(instr, "frcsr 'rd");
break;
default:
UNREACHABLE();
}
} else if (instr->Rs1Value() == zero_reg.code()) {
Format(instr, "csrr 'rd, 'csr");
} else if (instr->RdValue() == zero_reg.code()) {
Format(instr, "csrs 'csr, 'rs1");
} else {
Format(instr, "csrrs 'rd, 'csr, 'rs1");
}
break;
case RO_CSRRC:
if (instr->RdValue() == zero_reg.code())
Format(instr, "csrc 'csr, 'rs1");
else
Format(instr, "csrrc 'rd, 'csr, 'rs1");
break;
case RO_CSRRWI:
break;
}
// TODO(riscv): use Zifencei Standard Extension macro block
case RO_FENCE_I:
Format(instr, "fence.i");
break;
// TODO(riscv): use Zicsr Standard Extension macro block
// FIXME(RISC-V): Add special formatting for CSR registers
case RO_CSRRW:
if (instr->CsrValue() == csr_fcsr) {
if (instr->RdValue() == zero_reg.code())
Format(instr, "csrwi 'csr, 'uimm");
Format(instr, "fscsr 'rs1");
else
Format(instr, "csrrwi 'rd, 'csr, 'uimm");
break;
case RO_CSRRSI:
Format(instr, "fscsr 'rd, 'rs1");
} else if (instr->CsrValue() == csr_frm) {
if (instr->RdValue() == zero_reg.code())
Format(instr, "csrsi 'csr, 'uimm");
Format(instr, "fsrm 'rs1");
else
Format(instr, "csrrsi 'rd, 'csr, 'uimm");
break;
case RO_CSRRCI:
Format(instr, "fsrm 'rd, 'rs1");
} else if (instr->CsrValue() == csr_fflags) {
if (instr->RdValue() == zero_reg.code())
Format(instr, "csrci 'csr, 'uimm");
Format(instr, "fsflags 'rs1");
else
Format(instr, "csrrci 'rd, 'csr, 'uimm");
break;
// TODO(riscv): use F Extension macro block
case RO_FLW:
Format(instr, "flw 'fd, 'imm12('rs1)");
break;
// TODO(riscv): use D Extension macro block
case RO_FLD:
Format(instr, "fld 'fd, 'imm12('rs1)");
break;
default:
Format(instr, "fsflags 'rd, 'rs1");
} else if (instr->RdValue() == zero_reg.code()) {
Format(instr, "csrw 'csr, 'rs1");
} else {
Format(instr, "csrrw 'rd, 'csr, 'rs1");
}
break;
case RO_CSRRS:
if (instr->Rs1Value() == zero_reg.code()) {
switch (instr->CsrValue()) {
case csr_instret:
Format(instr, "rdinstret 'rd");
break;
case csr_instreth:
Format(instr, "rdinstreth 'rd");
break;
case csr_time:
Format(instr, "rdtime 'rd");
break;
case csr_timeh:
Format(instr, "rdtimeh 'rd");
break;
case csr_cycle:
Format(instr, "rdcycle 'rd");
break;
case csr_cycleh:
Format(instr, "rdcycleh 'rd");
break;
case csr_fflags:
Format(instr, "frflags 'rd");
break;
case csr_frm:
Format(instr, "frrm 'rd");
break;
case csr_fcsr:
Format(instr, "frcsr 'rd");
break;
default:
UNREACHABLE();
}
} else if (instr->Rs1Value() == zero_reg.code()) {
Format(instr, "csrr 'rd, 'csr");
} else if (instr->RdValue() == zero_reg.code()) {
Format(instr, "csrs 'csr, 'rs1");
} else {
Format(instr, "csrrs 'rd, 'csr, 'rs1");
}
break;
case RO_CSRRC:
if (instr->RdValue() == zero_reg.code())
Format(instr, "csrc 'csr, 'rs1");
else
Format(instr, "csrrc 'rd, 'csr, 'rs1");
break;
case RO_CSRRWI:
if (instr->RdValue() == zero_reg.code())
Format(instr, "csrwi 'csr, 'uimm");
else
Format(instr, "csrrwi 'rd, 'csr, 'uimm");
break;
case RO_CSRRSI:
if (instr->RdValue() == zero_reg.code())
Format(instr, "csrsi 'csr, 'uimm");
else
Format(instr, "csrrsi 'rd, 'csr, 'uimm");
break;
case RO_CSRRCI:
if (instr->RdValue() == zero_reg.code())
Format(instr, "csrci 'csr, 'uimm");
else
Format(instr, "csrrci 'rd, 'csr, 'uimm");
break;
// TODO(riscv): use F Extension macro block
case RO_FLW:
Format(instr, "flw 'fd, 'imm12('rs1)");
break;
// TODO(riscv): use D Extension macro block
case RO_FLD:
Format(instr, "fld 'fd, 'imm12('rs1)");
break;
default:
#ifdef CAN_USE_RVV_INSTRUCTIONS
if (!DecodeRvvVL()) {
UNSUPPORTED_RISCV();
}
}
break;
#else
UNSUPPORTED_RISCV();
#endif
}
}
void Decoder::DecodeSType(Instruction* instr) {
if (instr->vl_vs_width() != -1) {
DecodeRvvVS(instr);
} else {
switch (instr->InstructionBits() & kSTypeMask) {
case RO_SB:
Format(instr, "sb 'rs2, 'offS('rs1)");
break;
case RO_SH:
Format(instr, "sh 'rs2, 'offS('rs1)");
break;
case RO_SW:
Format(instr, "sw 'rs2, 'offS('rs1)");
break;
switch (instr->InstructionBits() & kSTypeMask) {
case RO_SB:
Format(instr, "sb 'rs2, 'offS('rs1)");
break;
case RO_SH:
Format(instr, "sh 'rs2, 'offS('rs1)");
break;
case RO_SW:
Format(instr, "sw 'rs2, 'offS('rs1)");
break;
#ifdef V8_TARGET_ARCH_64_BIT
case RO_SD:
Format(instr, "sd 'rs2, 'offS('rs1)");
break;
case RO_SD:
Format(instr, "sd 'rs2, 'offS('rs1)");
break;
#endif /*V8_TARGET_ARCH_64_BIT*/
// TODO(riscv): use F Extension macro block
case RO_FSW:
Format(instr, "fsw 'fs2, 'offS('rs1)");
break;
// TODO(riscv): use D Extension macro block
case RO_FSD:
Format(instr, "fsd 'fs2, 'offS('rs1)");
break;
default:
// TODO(riscv): use F Extension macro block
case RO_FSW:
Format(instr, "fsw 'fs2, 'offS('rs1)");
break;
// TODO(riscv): use D Extension macro block
case RO_FSD:
Format(instr, "fsd 'fs2, 'offS('rs1)");
break;
default:
#ifdef CAN_USE_RVV_INSTRUCTIONS
if (!DecodeRvvVS()) {
UNSUPPORTED_RISCV();
}
}
break;
#else
UNSUPPORTED_RISCV();
#endif
}
}
void Decoder::DecodeBType(Instruction* instr) {
switch (instr->InstructionBits() & kBTypeMask) {
case RO_BEQ:
......@@ -2867,9 +2873,11 @@ int Decoder::InstructionDecode(byte* instr_ptr) {
case Instruction::kCBType:
DecodeCBType(instr);
break;
#ifdef CAN_USE_RVV_INSTRUCTIONS
case Instruction::kVType:
DecodeVType(instr);
break;
#endif
default:
Format(instr, "UNSUPPORTED");
UNSUPPORTED_RISCV();
......
......@@ -88,6 +88,7 @@
// PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED
// HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE
// MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
#ifdef CAN_USE_RVV_INSTRUCTIONS
static inline bool is_aligned(const unsigned val, const unsigned pos) {
return pos ? (val & (pos - 1)) == 0 : true;
}
......@@ -155,7 +156,6 @@ static inline bool is_overlapped_widen(const int astart, int asize,
// PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED
// HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE
// MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
#ifdef CAN_USE_RVV_INSTRUCTIONS
template <uint64_t N>
struct type_usew_t;
template <>
......@@ -4635,10 +4635,10 @@ void Simulator::DecodeRVIType() {
if (!DecodeRvvVL()) {
UNSUPPORTED();
}
break;
#else
UNSUPPORTED();
#endif
break;
}
}
}
......@@ -4676,10 +4676,10 @@ void Simulator::DecodeRVSType() {
if (!DecodeRvvVS()) {
UNSUPPORTED();
}
break;
#else
UNSUPPORTED();
#endif
break;
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment