Commit 942a67ca authored by Lu Yahan's avatar Lu Yahan Committed by V8 LUCI CQ

Reland "[riscv32] Add RISCV32 backend"

This is a reland of commit 491de34b

co-authors: Ji Qiu <qiuji@iscas.ac.cn>
            Alvise De Faveri Tron <elvisilde@gmail.com>
            Usman Zain <uszain@gmail.com>
            Zheng Quan <vitalyankh@gmail.com>

Original change's description:
> [riscv32] Add RISCV32 backend
>
> This very large changeset adds support for RISCV32.
>
> Bug: v8:13025
> Change-Id: Ieacc857131e6620f0fcfd7daa88a0f8d77056aa9
> Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3736732
> Reviewed-by: Michael Achenbach <machenbach@chromium.org>
> Commit-Queue: Yahan Lu <yahan@iscas.ac.cn>
> Reviewed-by: ji qiu <qiuji@iscas.ac.cn>
> Reviewed-by: Andreas Haas <ahaas@chromium.org>
> Reviewed-by: Hannes Payer <hpayer@chromium.org>
> Reviewed-by: Nico Hartmann <nicohartmann@chromium.org>
> Cr-Commit-Position: refs/heads/main@{#82053}

Bug: v8:13025
Change-Id: I220fae4b8e2679bdc111724e08817b079b373bd5
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3807124
Commit-Queue: Yahan Lu <yahan@iscas.ac.cn>
Reviewed-by: 's avatarMichael Achenbach <machenbach@chromium.org>
Reviewed-by: 's avatarji qiu <qiuji@iscas.ac.cn>
Reviewed-by: 's avatarHannes Payer <hpayer@chromium.org>
Reviewed-by: 's avatarAndreas Haas <ahaas@chromium.org>
Cr-Commit-Position: refs/heads/main@{#82198}
parent 7c64e5b4
This diff is collapsed.
......@@ -27,5 +27,5 @@ per-file ...-loong64*=file:LOONG_OWNERS
per-file ...-mips*=file:MIPS_OWNERS
per-file ...-mips64*=file:MIPS_OWNERS
per-file ...-ppc*=file:PPC_OWNERS
per-file ...-riscv64*=file:RISCV_OWNERS
per-file ...-riscv*=file:RISCV_OWNERS
per-file ...-s390*=file:S390_OWNERS
......@@ -96,7 +96,8 @@ if (v8_snapshot_toolchain == "") {
} else {
_cpus = "x64_v8_${v8_current_cpu}"
}
} else if (v8_current_cpu == "arm" || v8_current_cpu == "mipsel") {
} else if (v8_current_cpu == "arm" || v8_current_cpu == "mipsel" ||
v8_current_cpu == "riscv32") {
_cpus = "x86_v8_${v8_current_cpu}"
} else {
# This branch should not be reached; leave _cpus blank so the assert
......
......@@ -20,7 +20,7 @@ struct CalleeSavedRegisters {
#elif V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_ARM64 || \
V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64 || V8_TARGET_ARCH_PPC || \
V8_TARGET_ARCH_PPC64 || V8_TARGET_ARCH_RISCV64 || V8_TARGET_ARCH_S390 || \
V8_TARGET_ARCH_LOONG64
V8_TARGET_ARCH_LOONG64 || V8_TARGET_ARCH_RISCV32
struct CalleeSavedRegisters {};
#else
#error Target architecture was not detected as supported by v8
......
......@@ -674,6 +674,9 @@ V8 shared library set USING_V8_SHARED.
#if __riscv_xlen == 64
#define V8_HOST_ARCH_RISCV64 1
#define V8_HOST_ARCH_64_BIT 1
#elif __riscv_xlen == 32
#define V8_HOST_ARCH_RISCV32 1
#define V8_HOST_ARCH_32_BIT 1
#else
#error "Cannot detect Riscv's bitwidth"
#endif
......@@ -689,7 +692,8 @@ V8 shared library set USING_V8_SHARED.
#if !V8_TARGET_ARCH_X64 && !V8_TARGET_ARCH_IA32 && !V8_TARGET_ARCH_ARM && \
!V8_TARGET_ARCH_ARM64 && !V8_TARGET_ARCH_MIPS && !V8_TARGET_ARCH_MIPS64 && \
!V8_TARGET_ARCH_PPC && !V8_TARGET_ARCH_PPC64 && !V8_TARGET_ARCH_S390 && \
!V8_TARGET_ARCH_RISCV64 && !V8_TARGET_ARCH_LOONG64
!V8_TARGET_ARCH_RISCV64 && !V8_TARGET_ARCH_LOONG64 && \
!V8_TARGET_ARCH_RISCV32
#if defined(_M_X64) || defined(__x86_64__)
#define V8_TARGET_ARCH_X64 1
#elif defined(_M_IX86) || defined(__i386__)
......@@ -714,6 +718,8 @@ V8 shared library set USING_V8_SHARED.
#elif defined(__riscv) || defined(__riscv__)
#if __riscv_xlen == 64
#define V8_TARGET_ARCH_RISCV64 1
#elif __riscv_xlen == 32
#define V8_TARGET_ARCH_RISCV32 1
#endif
#else
#error Target architecture was not detected as supported by v8
......@@ -753,6 +759,8 @@ V8 shared library set USING_V8_SHARED.
#endif
#elif V8_TARGET_ARCH_RISCV64
#define V8_TARGET_ARCH_64_BIT 1
#elif V8_TARGET_ARCH_RISCV32
#define V8_TARGET_ARCH_32_BIT 1
#else
#error Unknown target architecture pointer size
#endif
......@@ -784,6 +792,9 @@ V8 shared library set USING_V8_SHARED.
#if (V8_TARGET_ARCH_RISCV64 && !(V8_HOST_ARCH_X64 || V8_HOST_ARCH_RISCV64))
#error Target architecture riscv64 is only supported on riscv64 and x64 host
#endif
#if (V8_TARGET_ARCH_RISCV32 && !(V8_HOST_ARCH_IA32 || V8_HOST_ARCH_RISCV32))
#error Target architecture riscv32 is only supported on riscv32 and ia32 host
#endif
#if (V8_TARGET_ARCH_LOONG64 && !(V8_HOST_ARCH_X64 || V8_HOST_ARCH_LOONG64))
#error Target architecture loong64 is only supported on loong64 and x64 host
#endif
......@@ -823,7 +834,7 @@ V8 shared library set USING_V8_SHARED.
#else
#define V8_TARGET_BIG_ENDIAN 1
#endif
#elif V8_TARGET_ARCH_RISCV64
#elif V8_TARGET_ARCH_RISCV32 || V8_TARGET_ARCH_RISCV64
#define V8_TARGET_LITTLE_ENDIAN 1
#elif defined(__BYTE_ORDER__)
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
......
......@@ -98,10 +98,10 @@
// do not support adding noexcept to default members.
// Disabled on MSVC because constructors of standard containers are not noexcept
// there.
#if ((!defined(V8_CC_GNU) && !defined(V8_CC_MSVC) && \
!defined(V8_TARGET_ARCH_MIPS) && !defined(V8_TARGET_ARCH_MIPS64) && \
!defined(V8_TARGET_ARCH_PPC) && !defined(V8_TARGET_ARCH_PPC64) && \
!defined(V8_TARGET_ARCH_RISCV64)) || \
#if ((!defined(V8_CC_GNU) && !defined(V8_CC_MSVC) && \
!defined(V8_TARGET_ARCH_MIPS) && !defined(V8_TARGET_ARCH_MIPS64) && \
!defined(V8_TARGET_ARCH_PPC) && !defined(V8_TARGET_ARCH_PPC64) && \
!defined(V8_TARGET_ARCH_RISCV64) && !defined(V8_TARGET_ARCH_RISCV32)) || \
(defined(__clang__) && __cplusplus > 201300L))
#define V8_NOEXCEPT noexcept
#else
......
......@@ -354,6 +354,10 @@ void* OS::GetRandomMmapAddr() {
// TODO(RISCV): We need more information from the kernel to correctly mask
// this address for RISC-V. https://github.com/v8-riscv/v8/issues/375
raw_addr &= uint64_t{0xFFFFFF0000};
#elif V8_TARGET_ARCH_RISCV32
// TODO(RISCV): We need more information from the kernel to correctly mask
// this address for RISC-V. https://github.com/v8-riscv/v8/issues/375
raw_addr &= 0x3FFFF000;
#elif V8_TARGET_ARCH_LOONG64
// 42 bits of virtual addressing. Truncate to 40 bits to allow kernel chance
// to fulfill request.
......@@ -685,6 +689,8 @@ void OS::DebugBreak() {
asm volatile(".word 0x0001");
#elif V8_HOST_ARCH_RISCV64
asm("ebreak");
#elif V8_HOST_ARCH_RISCV32
asm("ebreak");
#else
#error Unsupported host architecture.
#endif
......
......@@ -32,8 +32,8 @@
#include "src/baseline/ppc/baseline-assembler-ppc-inl.h"
#elif V8_TARGET_ARCH_S390X
#include "src/baseline/s390/baseline-assembler-s390-inl.h"
#elif V8_TARGET_ARCH_RISCV64
#include "src/baseline/riscv64/baseline-assembler-riscv64-inl.h"
#elif V8_TARGET_ARCH_RISCV32 || V8_TARGET_ARCH_RISCV64
#include "src/baseline/riscv/baseline-assembler-riscv-inl.h"
#elif V8_TARGET_ARCH_MIPS64
#include "src/baseline/mips64/baseline-assembler-mips64-inl.h"
#elif V8_TARGET_ARCH_MIPS
......
......@@ -48,7 +48,9 @@
#elif V8_TARGET_ARCH_S390X
#include "src/baseline/s390/baseline-compiler-s390-inl.h"
#elif V8_TARGET_ARCH_RISCV64
#include "src/baseline/riscv64/baseline-compiler-riscv64-inl.h"
#include "src/baseline/riscv/baseline-compiler-riscv-inl.h"
#elif V8_TARGET_ARCH_RISCV32
#include "src/baseline/riscv/baseline-compiler-riscv-inl.h"
#elif V8_TARGET_ARCH_MIPS64
#include "src/baseline/mips64/baseline-compiler-mips64-inl.h"
#elif V8_TARGET_ARCH_MIPS
......
......@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_BASELINE_RISCV64_BASELINE_ASSEMBLER_RISCV64_INL_H_
#define V8_BASELINE_RISCV64_BASELINE_ASSEMBLER_RISCV64_INL_H_
#ifndef V8_BASELINE_RISCV_BASELINE_ASSEMBLER_RISCV_INL_H_
#define V8_BASELINE_RISCV_BASELINE_ASSEMBLER_RISCV_INL_H_
#include "src/baseline/baseline-assembler.h"
#include "src/codegen/assembler-inl.h"
......@@ -79,8 +79,8 @@ MemOperand BaselineAssembler::RegisterFrameOperand(
}
void BaselineAssembler::RegisterFrameAddress(
interpreter::Register interpreter_register, Register rscratch) {
return __ Add64(rscratch, fp,
interpreter_register.ToOperand() * kSystemPointerSize);
return __ AddWord(rscratch, fp,
interpreter_register.ToOperand() * kSystemPointerSize);
}
MemOperand BaselineAssembler::FeedbackVectorOperand() {
return MemOperand(fp, BaselineFrameConstants::kFeedbackVectorFromFp);
......@@ -163,7 +163,7 @@ void BaselineAssembler::JumpIfInstanceType(Condition cc, Register map,
__ GetObjectType(map, type, type);
__ Assert(eq, AbortReason::kUnexpectedValue, type, Operand(MAP_TYPE));
}
__ Ld(type, FieldMemOperand(map, Map::kInstanceTypeOffset));
__ LoadWord(type, FieldMemOperand(map, Map::kInstanceTypeOffset));
__ Branch(target, AsMasmCondition(cc), type, Operand(instance_type));
}
void BaselineAssembler::JumpIfPointer(Condition cc, Register value,
......@@ -171,7 +171,7 @@ void BaselineAssembler::JumpIfPointer(Condition cc, Register value,
Label::Distance) {
ScratchRegisterScope temps(this);
Register temp = temps.AcquireScratch();
__ Ld(temp, operand);
__ LoadWord(temp, operand);
__ Branch(target, AsMasmCondition(cc), value, Operand(temp));
}
void BaselineAssembler::JumpIfSmi(Condition cc, Register value, Smi smi,
......@@ -195,7 +195,7 @@ void BaselineAssembler::JumpIfTagged(Condition cc, Register value,
// todo: compress pointer
ScratchRegisterScope temps(this);
Register scratch = temps.AcquireScratch();
__ Ld(scratch, operand);
__ LoadWord(scratch, operand);
__ Branch(target, AsMasmCondition(cc), value, Operand(scratch));
}
void BaselineAssembler::JumpIfTagged(Condition cc, MemOperand operand,
......@@ -204,7 +204,7 @@ void BaselineAssembler::JumpIfTagged(Condition cc, MemOperand operand,
// todo: compress pointer
ScratchRegisterScope temps(this);
Register scratch = temps.AcquireScratch();
__ Ld(scratch, operand);
__ LoadWord(scratch, operand);
__ Branch(target, AsMasmCondition(cc), scratch, Operand(value));
}
void BaselineAssembler::JumpIfByte(Condition cc, Register value, int32_t byte,
......@@ -219,7 +219,7 @@ void BaselineAssembler::Move(Register output, TaggedIndex value) {
__ li(output, Operand(value.ptr()));
}
void BaselineAssembler::Move(MemOperand output, Register source) {
__ Sd(source, output);
__ StoreWord(source, output);
}
void BaselineAssembler::Move(Register output, ExternalReference reference) {
__ li(output, Operand(reference));
......@@ -446,8 +446,9 @@ void BaselineAssembler::AddToInterruptBudgetAndJumpIfNotExceeded(
__ Add32(interrupt_budget, interrupt_budget, weight);
__ Sw(interrupt_budget,
FieldMemOperand(feedback_cell, FeedbackCell::kInterruptBudgetOffset));
if (skip_interrupt_label)
if (skip_interrupt_label) {
__ Branch(skip_interrupt_label, ge, interrupt_budget, Operand(zero_reg));
}
}
void BaselineAssembler::LdaContextSlot(Register context, uint32_t index,
......@@ -510,27 +511,26 @@ void BaselineAssembler::AddSmi(Register lhs, Smi rhs) {
if (SmiValuesAre31Bits()) {
__ Add32(lhs, lhs, Operand(rhs));
} else {
__ Add64(lhs, lhs, Operand(rhs));
__ AddWord(lhs, lhs, Operand(rhs));
}
}
void BaselineAssembler::Word32And(Register output, Register lhs, int rhs) {
__ And(output, lhs, Operand(rhs));
}
void BaselineAssembler::Switch(Register reg, int case_value_base,
Label** labels, int num_labels) {
ASM_CODE_COMMENT(masm_);
Label fallthrough;
if (case_value_base != 0) {
__ Sub64(reg, reg, Operand(case_value_base));
__ SubWord(reg, reg, Operand(case_value_base));
}
// Mostly copied from code-generator-riscv64.cc
ScratchRegisterScope scope(this);
Label table;
__ Branch(&fallthrough, AsMasmCondition(Condition::kUnsignedGreaterThanEqual),
reg, Operand(int64_t(num_labels)));
reg, Operand(num_labels));
int64_t imm64;
imm64 = __ branch_long_offset(&table);
CHECK(is_int32(imm64 + 0x800));
......@@ -619,4 +619,4 @@ inline void EnsureAccumulatorPreservedScope::AssertEqualToAccumulator(
} // namespace internal
} // namespace v8
#endif // V8_BASELINE_RISCV64_BASELINE_ASSEMBLER_RISCV64_INL_H_
#endif // V8_BASELINE_RISCV_BASELINE_ASSEMBLER_RISCV_INL_H_
......@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_BASELINE_RISCV64_BASELINE_COMPILER_RISCV64_INL_H_
#define V8_BASELINE_RISCV64_BASELINE_COMPILER_RISCV64_INL_H_
#ifndef V8_BASELINE_RISCV_BASELINE_COMPILER_RISCV_INL_H_
#define V8_BASELINE_RISCV_BASELINE_COMPILER_RISCV_INL_H_
#include "src/baseline/baseline-compiler.h"
......@@ -39,10 +39,10 @@ void BaselineCompiler::PrologueFillFrame() {
const bool has_new_target = new_target_index != kMaxInt;
if (has_new_target) {
DCHECK_LE(new_target_index, register_count);
__ masm()->Add64(sp, sp, Operand(-(kPointerSize * new_target_index)));
__ masm()->AddWord(sp, sp, Operand(-(kPointerSize * new_target_index)));
for (int i = 0; i < new_target_index; i++) {
__ masm()->Sd(kInterpreterAccumulatorRegister,
MemOperand(sp, i * kSystemPointerSize));
__ masm()->StoreWord(kInterpreterAccumulatorRegister,
MemOperand(sp, i * kSystemPointerSize));
}
// Push new_target_or_generator.
__ Push(kJavaScriptCallNewTargetRegister);
......@@ -50,25 +50,25 @@ void BaselineCompiler::PrologueFillFrame() {
}
if (register_count < 2 * kLoopUnrollSize) {
// If the frame is small enough, just unroll the frame fill completely.
__ masm()->Add64(sp, sp, Operand(-(kPointerSize * register_count)));
__ masm()->AddWord(sp, sp, Operand(-(kPointerSize * register_count)));
for (int i = 0; i < register_count; ++i) {
__ masm()->Sd(kInterpreterAccumulatorRegister,
MemOperand(sp, i * kSystemPointerSize));
__ masm()->StoreWord(kInterpreterAccumulatorRegister,
MemOperand(sp, i * kSystemPointerSize));
}
} else {
__ masm()->Add64(sp, sp, Operand(-(kPointerSize * register_count)));
__ masm()->AddWord(sp, sp, Operand(-(kPointerSize * register_count)));
for (int i = 0; i < register_count; ++i) {
__ masm()->Sd(kInterpreterAccumulatorRegister,
MemOperand(sp, i * kSystemPointerSize));
__ masm()->StoreWord(kInterpreterAccumulatorRegister,
MemOperand(sp, i * kSystemPointerSize));
}
}
}
void BaselineCompiler::VerifyFrameSize() {
ASM_CODE_COMMENT(&masm_);
__ masm()->Add64(kScratchReg, sp,
Operand(InterpreterFrameConstants::kFixedFrameSizeFromFp +
bytecode_->frame_size()));
__ masm()->AddWord(kScratchReg, sp,
Operand(InterpreterFrameConstants::kFixedFrameSizeFromFp +
bytecode_->frame_size()));
__ masm()->Assert(eq, AbortReason::kUnexpectedStackPointer, kScratchReg,
Operand(fp));
}
......@@ -79,4 +79,4 @@ void BaselineCompiler::VerifyFrameSize() {
} // namespace internal
} // namespace v8
#endif // V8_BASELINE_RISCV64_BASELINE_COMPILER_RISCV64_INL_H_
#endif // V8_BASELINE_RISCV_BASELINE_COMPILER_RISCV_INL_H_
......@@ -251,7 +251,7 @@ TF_BUILTIN(AtomicsLoad, SharedArrayBufferBuiltinsAssembler) {
BIND(&u32);
Return(ChangeUint32ToTagged(AtomicLoad<Uint32T>(
AtomicMemoryOrder::kSeqCst, backing_store, WordShl(index_word, 2))));
#if V8_TARGET_ARCH_MIPS && !_MIPS_ARCH_MIPS32R6
#if (V8_TARGET_ARCH_MIPS && !_MIPS_ARCH_MIPS32R6) || V8_TARGET_ARCH_RISCV32
BIND(&i64);
Goto(&u64);
......@@ -268,7 +268,8 @@ TF_BUILTIN(AtomicsLoad, SharedArrayBufferBuiltinsAssembler) {
BIND(&u64);
Return(BigIntFromUnsigned64(AtomicLoad64<AtomicUint64>(
AtomicMemoryOrder::kSeqCst, backing_store, WordShl(index_word, 3))));
#endif
#endif //(V8_TARGET_ARCH_MIPS && !_MIPS_ARCH_MIPS32R6) ||
// V8_TARGET_ARCH_RISCV32
// This shouldn't happen, we've already validated the type.
BIND(&other);
......@@ -523,8 +524,7 @@ TF_BUILTIN(AtomicsExchange, SharedArrayBufferBuiltinsAssembler) {
// This shouldn't happen, we've already validated the type.
BIND(&other);
Unreachable();
#endif // V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64 ||
// V8_TARGET_ARCH_RISCV64
#endif // V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64
BIND(&detached_or_out_of_bounds);
{
......
......@@ -25,8 +25,8 @@
#include "src/codegen/loong64/assembler-loong64.h"
#elif V8_TARGET_ARCH_S390
#include "src/codegen/s390/assembler-s390.h"
#elif V8_TARGET_ARCH_RISCV64
#include "src/codegen/riscv64/assembler-riscv64.h"
#elif V8_TARGET_ARCH_RISCV32 || V8_TARGET_ARCH_RISCV64
#include "src/codegen/riscv/assembler-riscv.h"
#else
#error Unknown architecture.
#endif
......
......@@ -25,8 +25,8 @@
#include "src/codegen/loong64/assembler-loong64-inl.h"
#elif V8_TARGET_ARCH_S390
#include "src/codegen/s390/assembler-s390-inl.h"
#elif V8_TARGET_ARCH_RISCV64
#include "src/codegen/riscv64/assembler-riscv64-inl.h"
#elif V8_TARGET_ARCH_RISCV32 || V8_TARGET_ARCH_RISCV64
#include "src/codegen/riscv/assembler-riscv-inl.h"
#else
#error Unknown architecture.
#endif
......
......@@ -459,7 +459,7 @@ void ConstantPool::MaybeCheck() {
#endif // defined(V8_TARGET_ARCH_ARM64)
#if defined(V8_TARGET_ARCH_RISCV64)
#if defined(V8_TARGET_ARCH_RISCV64) || defined(V8_TARGET_ARCH_RISCV32)
// Constant Pool.
......@@ -706,7 +706,7 @@ void ConstantPool::MaybeCheck() {
}
}
#endif // defined(V8_TARGET_ARCH_RISCV64)
#endif // defined(V8_TARGET_ARCH_RISCV64) || defined(V8_TARGET_ARCH_RISCV32)
} // namespace internal
} // namespace v8
......@@ -163,7 +163,8 @@ class ConstantPoolBuilder {
#endif // defined(V8_TARGET_ARCH_PPC) || defined(V8_TARGET_ARCH_PPC64)
#if defined(V8_TARGET_ARCH_ARM64) || defined(V8_TARGET_ARCH_RISCV64)
#if defined(V8_TARGET_ARCH_ARM64) || defined(V8_TARGET_ARCH_RISCV64) || \
defined(V8_TARGET_ARCH_RISCV32)
class ConstantPoolKey {
public:
......@@ -345,7 +346,8 @@ class ConstantPool {
int blocked_nesting_ = 0;
};
#endif // defined(V8_TARGET_ARCH_ARM64)
#endif // defined(V8_TARGET_ARCH_ARM64) || defined(V8_TARGET_ARCH_RISCV64) ||
// defined(V8_TARGET_ARCH_RISCV32)
} // namespace internal
} // namespace v8
......
......@@ -23,8 +23,8 @@
#include "src/codegen/s390/constants-s390.h"
#elif V8_TARGET_ARCH_X64
#include "src/codegen/x64/constants-x64.h"
#elif V8_TARGET_ARCH_RISCV64
#include "src/codegen/riscv64/constants-riscv64.h"
#elif V8_TARGET_ARCH_RISCV32 || V8_TARGET_ARCH_RISCV64
#include "src/codegen/riscv/constants-riscv.h"
#else
#error Unsupported target architecture.
#endif
......
......@@ -76,6 +76,10 @@ enum CpuFeature {
FPU,
FP64FPU,
RISCV_SIMD,
#elif V8_TARGET_ARCH_RISCV32
FPU,
FP64FPU,
RISCV_SIMD,
#endif
NUMBER_OF_CPU_FEATURES
......
......@@ -757,7 +757,7 @@ ExternalReference ExternalReference::invoke_accessor_getter_callback() {
#define re_stack_check_func RegExpMacroAssemblerLOONG64::CheckStackGuardState
#elif V8_TARGET_ARCH_S390
#define re_stack_check_func RegExpMacroAssemblerS390::CheckStackGuardState
#elif V8_TARGET_ARCH_RISCV64
#elif V8_TARGET_ARCH_RISCV32 || V8_TARGET_ARCH_RISCV64
#define re_stack_check_func RegExpMacroAssemblerRISCV::CheckStackGuardState
#else
UNREACHABLE();
......
......@@ -29,8 +29,8 @@
#include "src/codegen/mips/interface-descriptors-mips-inl.h"
#elif V8_TARGET_ARCH_LOONG64
#include "src/codegen/loong64/interface-descriptors-loong64-inl.h"
#elif V8_TARGET_ARCH_RISCV64
#include "src/codegen/riscv64/interface-descriptors-riscv64-inl.h"
#elif V8_TARGET_ARCH_RISCV32 || V8_TARGET_ARCH_RISCV64
#include "src/codegen/riscv/interface-descriptors-riscv-inl.h"
#else
#error Unsupported target architecture.
#endif
......@@ -336,7 +336,7 @@ constexpr auto BaselineOutOfLinePrologueDescriptor::registers() {
#if V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_ARM || \
V8_TARGET_ARCH_PPC || V8_TARGET_ARCH_PPC64 || V8_TARGET_ARCH_S390 || \
V8_TARGET_ARCH_RISCV64 || V8_TARGET_ARCH_MIPS64 || V8_TARGET_ARCH_MIPS || \
V8_TARGET_ARCH_LOONG64
V8_TARGET_ARCH_LOONG64 || V8_TARGET_ARCH_RISCV32
return RegisterArray(
kContextRegister, kJSFunctionRegister, kJavaScriptCallArgCountRegister,
kJavaScriptCallExtraArg1Register, kJavaScriptCallNewTargetRegister,
......@@ -357,7 +357,7 @@ constexpr auto BaselineLeaveFrameDescriptor::registers() {
#if V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM64 || \
V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_PPC || V8_TARGET_ARCH_PPC64 || \
V8_TARGET_ARCH_S390 || V8_TARGET_ARCH_RISCV64 || V8_TARGET_ARCH_MIPS64 || \
V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_LOONG64
V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_LOONG64 || V8_TARGET_ARCH_RISCV32
return RegisterArray(ParamsSizeRegister(), WeightRegister());
#else
return DefaultRegisterArray();
......
......@@ -63,9 +63,9 @@ enum class SmiCheck { kOmit, kInline };
#elif V8_TARGET_ARCH_S390
#include "src/codegen/s390/constants-s390.h"
#include "src/codegen/s390/macro-assembler-s390.h"
#elif V8_TARGET_ARCH_RISCV64
#include "src/codegen/riscv64/constants-riscv64.h"
#include "src/codegen/riscv64/macro-assembler-riscv64.h"
#elif V8_TARGET_ARCH_RISCV32 || V8_TARGET_ARCH_RISCV64
#include "src/codegen/riscv/constants-riscv.h"
#include "src/codegen/riscv/macro-assembler-riscv.h"
#else
#error Unsupported target architecture.
#endif
......
......@@ -25,8 +25,8 @@
#include "src/codegen/loong64/register-loong64.h"
#elif V8_TARGET_ARCH_S390
#include "src/codegen/s390/register-s390.h"
#elif V8_TARGET_ARCH_RISCV64
#include "src/codegen/riscv64/register-riscv64.h"
#elif V8_TARGET_ARCH_RISCV32 || V8_TARGET_ARCH_RISCV64
#include "src/codegen/riscv/register-riscv.h"
#else
#error Unknown architecture.
#endif
......
......@@ -19,7 +19,7 @@ static const int kMaxAllocatableGeneralRegisterCount =
ALLOCATABLE_GENERAL_REGISTERS(REGISTER_COUNT) 0;
static const int kMaxAllocatableDoubleRegisterCount =
ALLOCATABLE_DOUBLE_REGISTERS(REGISTER_COUNT) 0;
#if V8_TARGET_ARCH_RISCV64 || V8_TARGET_ARCH_PPC64
#if V8_TARGET_ARCH_RISCV32 || V8_TARGET_ARCH_RISCV64 || V8_TARGET_ARCH_PPC64
static const int kMaxAllocatableSIMD128RegisterCount =
ALLOCATABLE_SIMD128_REGISTERS(REGISTER_COUNT) 0;
#endif
......@@ -38,16 +38,17 @@ static const int kAllocatableNoVFP32DoubleCodes[] = {
#endif // V8_TARGET_ARCH_ARM
#undef REGISTER_CODE
#if V8_TARGET_ARCH_RISCV64 || V8_TARGET_ARCH_PPC64
#if V8_TARGET_ARCH_RISCV32 || V8_TARGET_ARCH_RISCV64 || V8_TARGET_ARCH_PPC64
static const int kAllocatableSIMD128Codes[] = {
#if V8_TARGET_ARCH_RISCV64
#if V8_TARGET_ARCH_RISCV64 || V8_TARGET_ARCH_RISCV32
#define REGISTER_CODE(R) kVRCode_##R,
#else
#define REGISTER_CODE(R) kSimd128Code_##R,
#endif
ALLOCATABLE_SIMD128_REGISTERS(REGISTER_CODE)};
#undef REGISTER_CODE
#endif // V8_TARGET_ARCH_RISCV64 || V8_TARGET_ARCH_PPC64
#endif // V8_TARGET_ARCH_RISCV32 || V8_TARGET_ARCH_RISCV64 ||
// V8_TARGET_ARCH_PPC64
static_assert(RegisterConfiguration::kMaxGeneralRegisters >=
Register::kNumRegisters);
......@@ -95,6 +96,8 @@ static int get_num_allocatable_double_registers() {
kMaxAllocatableDoubleRegisterCount;
#elif V8_TARGET_ARCH_RISCV64
kMaxAllocatableDoubleRegisterCount;
#elif V8_TARGET_ARCH_RISCV32
kMaxAllocatableDoubleRegisterCount;
#else
#error Unsupported target architecture.
#endif
......@@ -104,7 +107,7 @@ static int get_num_allocatable_double_registers() {
static int get_num_allocatable_simd128_registers() {
return
#if V8_TARGET_ARCH_RISCV64 || V8_TARGET_ARCH_PPC64
#if V8_TARGET_ARCH_RISCV32 || V8_TARGET_ARCH_RISCV64 || V8_TARGET_ARCH_PPC64
kMaxAllocatableSIMD128RegisterCount;
#else
0;
......@@ -125,7 +128,7 @@ static const int* get_allocatable_double_codes() {
static const int* get_allocatable_simd128_codes() {
return
#if V8_TARGET_ARCH_RISCV64 || V8_TARGET_ARCH_PPC64
#if V8_TARGET_ARCH_RISCV32 || V8_TARGET_ARCH_RISCV64 || V8_TARGET_ARCH_PPC64
kAllocatableSIMD128Codes;
#else
kAllocatableDoubleCodes;
......
......@@ -23,8 +23,8 @@
#include "src/codegen/loong64/reglist-loong64.h"
#elif V8_TARGET_ARCH_S390
#include "src/codegen/s390/reglist-s390.h"
#elif V8_TARGET_ARCH_RISCV64
#include "src/codegen/riscv64/reglist-riscv64.h"
#elif V8_TARGET_ARCH_RISCV32 || V8_TARGET_ARCH_RISCV64
#include "src/codegen/riscv/reglist-riscv.h"
#else
#error Unknown architecture.
#endif
......
......@@ -309,10 +309,11 @@ bool RelocInfo::OffHeapTargetIsCodedSpecially() {
#if defined(V8_TARGET_ARCH_ARM) || defined(V8_TARGET_ARCH_ARM64) || \
defined(V8_TARGET_ARCH_X64)
return false;
#elif defined(V8_TARGET_ARCH_IA32) || defined(V8_TARGET_ARCH_MIPS) || \
defined(V8_TARGET_ARCH_MIPS64) || defined(V8_TARGET_ARCH_PPC) || \
defined(V8_TARGET_ARCH_PPC64) || defined(V8_TARGET_ARCH_S390) || \
defined(V8_TARGET_ARCH_RISCV64) || defined(V8_TARGET_ARCH_LOONG64)
#elif defined(V8_TARGET_ARCH_IA32) || defined(V8_TARGET_ARCH_MIPS) || \
defined(V8_TARGET_ARCH_MIPS64) || defined(V8_TARGET_ARCH_PPC) || \
defined(V8_TARGET_ARCH_PPC64) || defined(V8_TARGET_ARCH_S390) || \
defined(V8_TARGET_ARCH_RISCV64) || defined(V8_TARGET_ARCH_LOONG64) || \
defined(V8_TARGET_ARCH_RISCV32)
return true;
#endif
}
......
......@@ -72,7 +72,8 @@ class RelocInfo {
EXTERNAL_REFERENCE, // The address of an external C++ function.
INTERNAL_REFERENCE, // An address inside the same function.
// Encoded internal reference, used only on RISCV64, MIPS, MIPS64 and PPC.
// Encoded internal reference, used only on RISCV64, RISCV32, MIPS, MIPS64
// and PPC.
INTERNAL_REFERENCE_ENCODED,
// An off-heap instruction stream target. See http://goo.gl/Z2HUiM.
......
......@@ -32,11 +32,11 @@
// modified significantly by Google Inc.
// Copyright 2021 the V8 project authors. All rights reserved.
#ifndef V8_CODEGEN_RISCV64_ASSEMBLER_RISCV64_INL_H_
#define V8_CODEGEN_RISCV64_ASSEMBLER_RISCV64_INL_H_
#ifndef V8_CODEGEN_RISCV_ASSEMBLER_RISCV_INL_H_
#define V8_CODEGEN_RISCV_ASSEMBLER_RISCV_INL_H_
#include "src/codegen/assembler-arch.h"
#include "src/codegen/assembler.h"
#include "src/codegen/riscv64/assembler-riscv64.h"
#include "src/debug/debug.h"
#include "src/objects/objects-inl.h"
......@@ -45,15 +45,10 @@ namespace internal {
bool CpuFeatures::SupportsOptimizer() { return IsSupported(FPU); }
// -----------------------------------------------------------------------------
// Operand and MemOperand.
bool Operand::is_reg() const { return rm_.is_valid(); }
int64_t Operand::immediate() const {
DCHECK(!is_reg());
DCHECK(!IsHeapObjectRequest());
return value_.immediate;
void Assembler::CheckBuffer() {
if (buffer_space() <= kGap) {
GrowBuffer();
}
}
// -----------------------------------------------------------------------------
......@@ -91,7 +86,11 @@ Address RelocInfo::target_address_address() {
// place, ready to be patched with the target. After jump optimization,
// that is the address of the instruction that follows J/JAL/JR/JALR
// instruction.
#ifdef V8_TARGET_ARCH_RISCV64
return pc_ + Assembler::kInstructionsFor64BitConstant * kInstrSize;
#elif defined(V8_TARGET_ARCH_RISCV32)
return pc_ + Assembler::kInstructionsFor32BitConstant * kInstrSize;
#endif
}
Address RelocInfo::constant_pool_entry_address() { UNREACHABLE(); }
......@@ -142,7 +141,11 @@ int Assembler::deserialization_special_target_size(
void Assembler::set_target_internal_reference_encoded_at(Address pc,
Address target) {
#ifdef V8_TARGET_ARCH_RISCV64
set_target_value_at(pc, static_cast<uint64_t>(target));
#elif defined(V8_TARGET_ARCH_RISCV32)
set_target_value_at(pc, static_cast<uint32_t>(target));
#endif
}
void Assembler::deserialization_set_target_internal_reference_at(
......@@ -279,49 +282,9 @@ void RelocInfo::WipeOut() {
}
}
// -----------------------------------------------------------------------------
// Assembler.
void Assembler::CheckBuffer() {
if (buffer_space() <= kGap) {
GrowBuffer();
}
}
template <typename T>
void Assembler::EmitHelper(T x) {
*reinterpret_cast<T*>(pc_) = x;
pc_ += sizeof(x);
}
void Assembler::emit(Instr x) {
if (!is_buffer_growth_blocked()) {
CheckBuffer();
}
DEBUG_PRINTF("%p: ", pc_);
disassembleInstr(x);
EmitHelper(x);
CheckTrampolinePoolQuick();
}
void Assembler::emit(ShortInstr x) {
if (!is_buffer_growth_blocked()) {
CheckBuffer();
}
DEBUG_PRINTF("%p: ", pc_);
disassembleInstr(x);
EmitHelper(x);
CheckTrampolinePoolQuick();
}
void Assembler::emit(uint64_t data) {
if (!is_buffer_growth_blocked()) CheckBuffer();
EmitHelper(data);
}
EnsureSpace::EnsureSpace(Assembler* assembler) { assembler->CheckBuffer(); }
} // namespace internal
} // namespace v8
#endif // V8_CODEGEN_RISCV64_ASSEMBLER_RISCV64_INL_H_
#endif // V8_CODEGEN_RISCV_ASSEMBLER_RISCV_INL_H_
This diff is collapsed.
// Copyright (c) 1994-2006 Sun Microsystems Inc.
// All Rights Reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// - Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// - Redistribution in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// - Neither the name of Sun Microsystems or the names of contributors may
// be used to endorse or promote products derived from this software without
// specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// The original source code covered by the above license above has been
// modified significantly by Google Inc.
// Copyright 2021 the V8 project authors. All rights reserved.
#ifndef V8_CODEGEN_RISCV_BASE_ASSEMBLER_RISCV_H_
#define V8_CODEGEN_RISCV_BASE_ASSEMBLER_RISCV_H_
#include <stdio.h>
#include <memory>
#include <set>
#include "src/codegen/assembler.h"
#include "src/codegen/constant-pool.h"
#include "src/codegen/external-reference.h"
#include "src/codegen/label.h"
#include "src/codegen/riscv/constants-riscv.h"
#include "src/codegen/riscv/register-riscv.h"
#include "src/objects/contexts.h"
#include "src/objects/smi.h"
namespace v8 {
namespace internal {
#define DEBUG_PRINTF(...) \
if (FLAG_riscv_debug) { \
printf(__VA_ARGS__); \
}
class SafepointTableBuilder;
class AssemblerRiscvBase {
protected:
// Returns the branch offset to the given label from the current code
// position. Links the label to the current position if it is still unbound.
// Manages the jump elimination optimization if the second parameter is true.
enum OffsetSize : int {
kOffset21 = 21, // RISCV jal
kOffset12 = 12, // RISCV imm12
kOffset20 = 20, // RISCV imm20
kOffset13 = 13, // RISCV branch
kOffset32 = 32, // RISCV auipc + instr_I
kOffset11 = 11, // RISCV C_J
kOffset9 = 9 // RISCV compressed branch
};
virtual int32_t branch_offset_helper(Label* L, OffsetSize bits) = 0;
virtual void emit(Instr x) = 0;
virtual void emit(ShortInstr x) = 0;
virtual void emit(uint64_t x) = 0;
// Instruction generation.
// ----- Top-level instruction formats match those in the ISA manual
// (R, I, S, B, U, J). These match the formats defined in LLVM's
// RISCVInstrFormats.td.
void GenInstrR(uint8_t funct7, uint8_t funct3, BaseOpcode opcode, Register rd,
Register rs1, Register rs2);
void GenInstrR(uint8_t funct7, uint8_t funct3, BaseOpcode opcode,
FPURegister rd, FPURegister rs1, FPURegister rs2);
void GenInstrR(uint8_t funct7, uint8_t funct3, BaseOpcode opcode, Register rd,
FPURegister rs1, Register rs2);
void GenInstrR(uint8_t funct7, uint8_t funct3, BaseOpcode opcode,
FPURegister rd, Register rs1, Register rs2);
void GenInstrR(uint8_t funct7, uint8_t funct3, BaseOpcode opcode,
FPURegister rd, FPURegister rs1, Register rs2);
void GenInstrR(uint8_t funct7, uint8_t funct3, BaseOpcode opcode, Register rd,
FPURegister rs1, FPURegister rs2);
void GenInstrR4(uint8_t funct2, BaseOpcode opcode, Register rd, Register rs1,
Register rs2, Register rs3, FPURoundingMode frm);
void GenInstrR4(uint8_t funct2, BaseOpcode opcode, FPURegister rd,
FPURegister rs1, FPURegister rs2, FPURegister rs3,
FPURoundingMode frm);
void GenInstrRAtomic(uint8_t funct5, bool aq, bool rl, uint8_t funct3,
Register rd, Register rs1, Register rs2);
void GenInstrRFrm(uint8_t funct7, BaseOpcode opcode, Register rd,
Register rs1, Register rs2, FPURoundingMode frm);
void GenInstrI(uint8_t funct3, BaseOpcode opcode, Register rd, Register rs1,
int16_t imm12);
void GenInstrI(uint8_t funct3, BaseOpcode opcode, FPURegister rd,
Register rs1, int16_t imm12);
void GenInstrIShift(bool arithshift, uint8_t funct3, BaseOpcode opcode,
Register rd, Register rs1, uint8_t shamt);
void GenInstrIShiftW(bool arithshift, uint8_t funct3, BaseOpcode opcode,
Register rd, Register rs1, uint8_t shamt);
void GenInstrS(uint8_t funct3, BaseOpcode opcode, Register rs1, Register rs2,
int16_t imm12);
void GenInstrS(uint8_t funct3, BaseOpcode opcode, Register rs1,
FPURegister rs2, int16_t imm12);
void GenInstrB(uint8_t funct3, BaseOpcode opcode, Register rs1, Register rs2,
int16_t imm12);
void GenInstrU(BaseOpcode opcode, Register rd, int32_t imm20);
void GenInstrJ(BaseOpcode opcode, Register rd, int32_t imm20);
void GenInstrCR(uint8_t funct4, BaseOpcode opcode, Register rd, Register rs2);
void GenInstrCA(uint8_t funct6, BaseOpcode opcode, Register rd, uint8_t funct,
Register rs2);
void GenInstrCI(uint8_t funct3, BaseOpcode opcode, Register rd, int8_t imm6);
void GenInstrCIU(uint8_t funct3, BaseOpcode opcode, Register rd,
uint8_t uimm6);
void GenInstrCIU(uint8_t funct3, BaseOpcode opcode, FPURegister rd,
uint8_t uimm6);
void GenInstrCIW(uint8_t funct3, BaseOpcode opcode, Register rd,
uint8_t uimm8);
void GenInstrCSS(uint8_t funct3, BaseOpcode opcode, FPURegister rs2,
uint8_t uimm6);
void GenInstrCSS(uint8_t funct3, BaseOpcode opcode, Register rs2,
uint8_t uimm6);
void GenInstrCL(uint8_t funct3, BaseOpcode opcode, Register rd, Register rs1,
uint8_t uimm5);
void GenInstrCL(uint8_t funct3, BaseOpcode opcode, FPURegister rd,
Register rs1, uint8_t uimm5);
void GenInstrCS(uint8_t funct3, BaseOpcode opcode, Register rs2, Register rs1,
uint8_t uimm5);
void GenInstrCS(uint8_t funct3, BaseOpcode opcode, FPURegister rs2,
Register rs1, uint8_t uimm5);
void GenInstrCJ(uint8_t funct3, BaseOpcode opcode, uint16_t uint11);
void GenInstrCB(uint8_t funct3, BaseOpcode opcode, Register rs1,
uint8_t uimm8);
void GenInstrCBA(uint8_t funct3, uint8_t funct2, BaseOpcode opcode,
Register rs1, int8_t imm6);
// ----- Instruction class templates match those in LLVM's RISCVInstrInfo.td
void GenInstrBranchCC_rri(uint8_t funct3, Register rs1, Register rs2,
int16_t imm12);
void GenInstrLoad_ri(uint8_t funct3, Register rd, Register rs1,
int16_t imm12);
void GenInstrStore_rri(uint8_t funct3, Register rs1, Register rs2,
int16_t imm12);
void GenInstrALU_ri(uint8_t funct3, Register rd, Register rs1, int16_t imm12);
void GenInstrShift_ri(bool arithshift, uint8_t funct3, Register rd,
Register rs1, uint8_t shamt);
void GenInstrALU_rr(uint8_t funct7, uint8_t funct3, Register rd, Register rs1,
Register rs2);
void GenInstrCSR_ir(uint8_t funct3, Register rd, ControlStatusReg csr,
Register rs1);
void GenInstrCSR_ii(uint8_t funct3, Register rd, ControlStatusReg csr,
uint8_t rs1);
void GenInstrShiftW_ri(bool arithshift, uint8_t funct3, Register rd,
Register rs1, uint8_t shamt);
void GenInstrALUW_rr(uint8_t funct7, uint8_t funct3, Register rd,
Register rs1, Register rs2);
void GenInstrPriv(uint8_t funct7, Register rs1, Register rs2);
void GenInstrLoadFP_ri(uint8_t funct3, FPURegister rd, Register rs1,
int16_t imm12);
void GenInstrStoreFP_rri(uint8_t funct3, Register rs1, FPURegister rs2,
int16_t imm12);
void GenInstrALUFP_rr(uint8_t funct7, uint8_t funct3, FPURegister rd,
FPURegister rs1, FPURegister rs2);
void GenInstrALUFP_rr(uint8_t funct7, uint8_t funct3, FPURegister rd,
Register rs1, Register rs2);
void GenInstrALUFP_rr(uint8_t funct7, uint8_t funct3, FPURegister rd,
FPURegister rs1, Register rs2);
void GenInstrALUFP_rr(uint8_t funct7, uint8_t funct3, Register rd,
FPURegister rs1, Register rs2);
void GenInstrALUFP_rr(uint8_t funct7, uint8_t funct3, Register rd,
FPURegister rs1, FPURegister rs2);
virtual void BlockTrampolinePoolFor(int instructions) = 0;
};
} // namespace internal
} // namespace v8
#endif // V8_CODEGEN_RISCV_BASE_ASSEMBLER_RISCV_H_
// Copyright 2021 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#if V8_TARGET_ARCH_RISCV64
#include "src/codegen/riscv64/constants-riscv64.h"
#include "src/codegen/riscv/constants-riscv.h"
#include "src/execution/simulator.h"
namespace v8 {
namespace internal {
......@@ -144,6 +142,95 @@ int VRegisters::Number(const char* name) {
return kInvalidVRegister;
}
bool InstructionBase::IsShortInstruction() const {
uint8_t FirstByte = *reinterpret_cast<const uint8_t*>(this);
return (FirstByte & 0x03) <= C2;
}
template <class T>
int InstructionGetters<T>::RvcRdValue() const {
DCHECK(this->IsShortInstruction());
return this->Bits(kRvcRdShift + kRvcRdBits - 1, kRvcRdShift);
}
template <class T>
int InstructionGetters<T>::RvcRs2Value() const {
DCHECK(this->IsShortInstruction());
return this->Bits(kRvcRs2Shift + kRvcRs2Bits - 1, kRvcRs2Shift);
}
template <class T>
int InstructionGetters<T>::RvcRs1sValue() const {
DCHECK(this->IsShortInstruction());
return 0b1000 + this->Bits(kRvcRs1sShift + kRvcRs1sBits - 1, kRvcRs1sShift);
}
template <class T>
int InstructionGetters<T>::RvcRs2sValue() const {
DCHECK(this->IsShortInstruction());
return 0b1000 + this->Bits(kRvcRs2sShift + kRvcRs2sBits - 1, kRvcRs2sShift);
}
template <class T>
inline int InstructionGetters<T>::RvcFunct6Value() const {
DCHECK(this->IsShortInstruction());
return this->Bits(kRvcFunct6Shift + kRvcFunct6Bits - 1, kRvcFunct6Shift);
}
template <class T>
inline int InstructionGetters<T>::RvcFunct4Value() const {
DCHECK(this->IsShortInstruction());
return this->Bits(kRvcFunct4Shift + kRvcFunct4Bits - 1, kRvcFunct4Shift);
}
template <class T>
inline int InstructionGetters<T>::RvcFunct3Value() const {
DCHECK(this->IsShortInstruction());
return this->Bits(kRvcFunct3Shift + kRvcFunct3Bits - 1, kRvcFunct3Shift);
}
template <class T>
inline int InstructionGetters<T>::RvcFunct2Value() const {
DCHECK(this->IsShortInstruction());
return this->Bits(kRvcFunct2Shift + kRvcFunct2Bits - 1, kRvcFunct2Shift);
}
template <class T>
inline int InstructionGetters<T>::RvcFunct2BValue() const {
DCHECK(this->IsShortInstruction());
return this->Bits(kRvcFunct2BShift + kRvcFunct2Bits - 1, kRvcFunct2BShift);
}
template <class T>
uint32_t InstructionGetters<T>::Rvvzimm() const {
if ((this->InstructionBits() &
(kBaseOpcodeMask | kFunct3Mask | 0x80000000)) == RO_V_VSETVLI) {
uint32_t Bits = this->InstructionBits();
uint32_t zimm = Bits & kRvvZimmMask;
return zimm >> kRvvZimmShift;
} else {
DCHECK_EQ(
this->InstructionBits() & (kBaseOpcodeMask | kFunct3Mask | 0xC0000000),
RO_V_VSETIVLI);
uint32_t Bits = this->InstructionBits();
uint32_t zimm = Bits & kRvvZimmMask;
return (zimm >> kRvvZimmShift) & 0x3FF;
}
}
template <class T>
uint32_t InstructionGetters<T>::Rvvuimm() const {
DCHECK_EQ(
this->InstructionBits() & (kBaseOpcodeMask | kFunct3Mask | 0xC0000000),
RO_V_VSETIVLI);
uint32_t Bits = this->InstructionBits();
uint32_t uimm = Bits & kRvvUimmMask;
return uimm >> kRvvUimmShift;
}
template class InstructionGetters<InstructionBase>;
template class InstructionGetters<SimInstructionBase>;
InstructionBase::Type InstructionBase::InstructionType() const {
if (IsIllegalInstruction()) {
return kUnsupported;
......@@ -155,15 +242,21 @@ InstructionBase::Type InstructionBase::InstructionType() const {
return kCIWType;
case RO_C_FLD:
case RO_C_LW:
#ifdef V8_TARGET_ARCH_RISCV64
case RO_C_LD:
#endif
return kCLType;
case RO_C_FSD:
case RO_C_SW:
#ifdef V8_TARGET_ARCH_RISCV64
case RO_C_SD:
#endif
return kCSType;
case RO_C_NOP_ADDI:
case RO_C_ADDIW:
case RO_C_LI:
#ifdef V8_TARGET_ARCH_RISCV64
case RO_C_ADDIW:
#endif
case RO_C_LUI_ADD:
return kCIType;
case RO_C_MISC_ALU:
......@@ -179,13 +272,17 @@ InstructionBase::Type InstructionBase::InstructionType() const {
case RO_C_SLLI:
case RO_C_FLDSP:
case RO_C_LWSP:
#ifdef V8_TARGET_ARCH_RISCV64
case RO_C_LDSP:
#endif
return kCIType;
case RO_C_JR_MV_ADD:
return kCRType;
case RO_C_FSDSP:
case RO_C_SWSP:
#ifdef V8_TARGET_ARCH_RISCV64
case RO_C_SDSP:
#endif
return kCSSType;
default:
break;
......@@ -241,5 +338,3 @@ InstructionBase::Type InstructionBase::InstructionType() const {
} // namespace internal
} // namespace v8
#endif // V8_TARGET_ARCH_RISCV64
// Copyright 2022 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/codegen/riscv/base-riscv-i.h"
namespace v8 {
namespace internal {
void AssemblerRISCVI::lui(Register rd, int32_t imm20) {
GenInstrU(LUI, rd, imm20);
}
void AssemblerRISCVI::auipc(Register rd, int32_t imm20) {
GenInstrU(AUIPC, rd, imm20);
}
// Jumps
void AssemblerRISCVI::jal(Register rd, int32_t imm21) {
GenInstrJ(JAL, rd, imm21);
BlockTrampolinePoolFor(1);
}
void AssemblerRISCVI::jalr(Register rd, Register rs1, int16_t imm12) {
GenInstrI(0b000, JALR, rd, rs1, imm12);
BlockTrampolinePoolFor(1);
}
// Branches
void AssemblerRISCVI::beq(Register rs1, Register rs2, int16_t imm13) {
GenInstrBranchCC_rri(0b000, rs1, rs2, imm13);
}
void AssemblerRISCVI::bne(Register rs1, Register rs2, int16_t imm13) {
GenInstrBranchCC_rri(0b001, rs1, rs2, imm13);
}
void AssemblerRISCVI::blt(Register rs1, Register rs2, int16_t imm13) {
GenInstrBranchCC_rri(0b100, rs1, rs2, imm13);
}
void AssemblerRISCVI::bge(Register rs1, Register rs2, int16_t imm13) {
GenInstrBranchCC_rri(0b101, rs1, rs2, imm13);
}
void AssemblerRISCVI::bltu(Register rs1, Register rs2, int16_t imm13) {
GenInstrBranchCC_rri(0b110, rs1, rs2, imm13);
}
void AssemblerRISCVI::bgeu(Register rs1, Register rs2, int16_t imm13) {
GenInstrBranchCC_rri(0b111, rs1, rs2, imm13);
}
// Loads
void AssemblerRISCVI::lb(Register rd, Register rs1, int16_t imm12) {
GenInstrLoad_ri(0b000, rd, rs1, imm12);
}
void AssemblerRISCVI::lh(Register rd, Register rs1, int16_t imm12) {
GenInstrLoad_ri(0b001, rd, rs1, imm12);
}
void AssemblerRISCVI::lw(Register rd, Register rs1, int16_t imm12) {
GenInstrLoad_ri(0b010, rd, rs1, imm12);
}
void AssemblerRISCVI::lbu(Register rd, Register rs1, int16_t imm12) {
GenInstrLoad_ri(0b100, rd, rs1, imm12);
}
void AssemblerRISCVI::lhu(Register rd, Register rs1, int16_t imm12) {
GenInstrLoad_ri(0b101, rd, rs1, imm12);
}
// Stores
void AssemblerRISCVI::sb(Register source, Register base, int16_t imm12) {
GenInstrStore_rri(0b000, base, source, imm12);
}
void AssemblerRISCVI::sh(Register source, Register base, int16_t imm12) {
GenInstrStore_rri(0b001, base, source, imm12);
}
void AssemblerRISCVI::sw(Register source, Register base, int16_t imm12) {
GenInstrStore_rri(0b010, base, source, imm12);
}
// Arithmetic with immediate
void AssemblerRISCVI::addi(Register rd, Register rs1, int16_t imm12) {
GenInstrALU_ri(0b000, rd, rs1, imm12);
}
void AssemblerRISCVI::slti(Register rd, Register rs1, int16_t imm12) {
GenInstrALU_ri(0b010, rd, rs1, imm12);
}
void AssemblerRISCVI::sltiu(Register rd, Register rs1, int16_t imm12) {
GenInstrALU_ri(0b011, rd, rs1, imm12);
}
void AssemblerRISCVI::xori(Register rd, Register rs1, int16_t imm12) {
GenInstrALU_ri(0b100, rd, rs1, imm12);
}
void AssemblerRISCVI::ori(Register rd, Register rs1, int16_t imm12) {
GenInstrALU_ri(0b110, rd, rs1, imm12);
}
void AssemblerRISCVI::andi(Register rd, Register rs1, int16_t imm12) {
GenInstrALU_ri(0b111, rd, rs1, imm12);
}
void AssemblerRISCVI::slli(Register rd, Register rs1, uint8_t shamt) {
GenInstrShift_ri(0, 0b001, rd, rs1, shamt & 0x3f);
}
void AssemblerRISCVI::srli(Register rd, Register rs1, uint8_t shamt) {
GenInstrShift_ri(0, 0b101, rd, rs1, shamt & 0x3f);
}
void AssemblerRISCVI::srai(Register rd, Register rs1, uint8_t shamt) {
GenInstrShift_ri(1, 0b101, rd, rs1, shamt & 0x3f);
}
// Arithmetic
void AssemblerRISCVI::add(Register rd, Register rs1, Register rs2) {
GenInstrALU_rr(0b0000000, 0b000, rd, rs1, rs2);
}
void AssemblerRISCVI::sub(Register rd, Register rs1, Register rs2) {
GenInstrALU_rr(0b0100000, 0b000, rd, rs1, rs2);
}
void AssemblerRISCVI::sll(Register rd, Register rs1, Register rs2) {
GenInstrALU_rr(0b0000000, 0b001, rd, rs1, rs2);
}
void AssemblerRISCVI::slt(Register rd, Register rs1, Register rs2) {
GenInstrALU_rr(0b0000000, 0b010, rd, rs1, rs2);
}
void AssemblerRISCVI::sltu(Register rd, Register rs1, Register rs2) {
GenInstrALU_rr(0b0000000, 0b011, rd, rs1, rs2);
}
void AssemblerRISCVI::xor_(Register rd, Register rs1, Register rs2) {
GenInstrALU_rr(0b0000000, 0b100, rd, rs1, rs2);
}
void AssemblerRISCVI::srl(Register rd, Register rs1, Register rs2) {
GenInstrALU_rr(0b0000000, 0b101, rd, rs1, rs2);
}
void AssemblerRISCVI::sra(Register rd, Register rs1, Register rs2) {
GenInstrALU_rr(0b0100000, 0b101, rd, rs1, rs2);
}
void AssemblerRISCVI::or_(Register rd, Register rs1, Register rs2) {
GenInstrALU_rr(0b0000000, 0b110, rd, rs1, rs2);
}
void AssemblerRISCVI::and_(Register rd, Register rs1, Register rs2) {
GenInstrALU_rr(0b0000000, 0b111, rd, rs1, rs2);
}
// Memory fences
void AssemblerRISCVI::fence(uint8_t pred, uint8_t succ) {
DCHECK(is_uint4(pred) && is_uint4(succ));
uint16_t imm12 = succ | (pred << 4) | (0b0000 << 8);
GenInstrI(0b000, MISC_MEM, ToRegister(0), ToRegister(0), imm12);
}
void AssemblerRISCVI::fence_tso() {
uint16_t imm12 = (0b0011) | (0b0011 << 4) | (0b1000 << 8);
GenInstrI(0b000, MISC_MEM, ToRegister(0), ToRegister(0), imm12);
}
// Environment call / break
void AssemblerRISCVI::ecall() {
GenInstrI(0b000, SYSTEM, ToRegister(0), ToRegister(0), 0);
}
void AssemblerRISCVI::ebreak() {
GenInstrI(0b000, SYSTEM, ToRegister(0), ToRegister(0), 1);
}
// This is a de facto standard (as set by GNU binutils) 32-bit unimplemented
// instruction (i.e., it should always trap, if your implementation has invalid
// instruction traps).
void AssemblerRISCVI::unimp() {
GenInstrI(0b001, SYSTEM, ToRegister(0), ToRegister(0), 0b110000000000);
}
bool AssemblerRISCVI::IsBranch(Instr instr) {
return (instr & kBaseOpcodeMask) == BRANCH;
}
bool AssemblerRISCVI::IsJump(Instr instr) {
int Op = instr & kBaseOpcodeMask;
return Op == JAL || Op == JALR;
}
bool AssemblerRISCVI::IsNop(Instr instr) { return instr == kNopByte; }
bool AssemblerRISCVI::IsJal(Instr instr) {
return (instr & kBaseOpcodeMask) == JAL;
}
bool AssemblerRISCVI::IsJalr(Instr instr) {
return (instr & kBaseOpcodeMask) == JALR;
}
bool AssemblerRISCVI::IsLui(Instr instr) {
return (instr & kBaseOpcodeMask) == LUI;
}
bool AssemblerRISCVI::IsAuipc(Instr instr) {
return (instr & kBaseOpcodeMask) == AUIPC;
}
bool AssemblerRISCVI::IsAddi(Instr instr) {
return (instr & (kBaseOpcodeMask | kFunct3Mask)) == RO_ADDI;
}
bool AssemblerRISCVI::IsOri(Instr instr) {
return (instr & (kBaseOpcodeMask | kFunct3Mask)) == RO_ORI;
}
bool AssemblerRISCVI::IsSlli(Instr instr) {
return (instr & (kBaseOpcodeMask | kFunct3Mask)) == RO_SLLI;
}
int AssemblerRISCVI::JumpOffset(Instr instr) {
int32_t imm21 = ((instr & 0x7fe00000) >> 20) | ((instr & 0x100000) >> 9) |
(instr & 0xff000) | ((instr & 0x80000000) >> 11);
imm21 = imm21 << 11 >> 11;
return imm21;
}
int AssemblerRISCVI::JalrOffset(Instr instr) {
DCHECK(IsJalr(instr));
int32_t imm12 = static_cast<int32_t>(instr & kImm12Mask) >> 20;
return imm12;
}
int AssemblerRISCVI::AuipcOffset(Instr instr) {
DCHECK(IsAuipc(instr));
int32_t imm20 = static_cast<int32_t>(instr & kImm20Mask);
return imm20;
}
bool AssemblerRISCVI::IsLw(Instr instr) {
return (instr & (kBaseOpcodeMask | kFunct3Mask)) == RO_LW;
}
int AssemblerRISCVI::LoadOffset(Instr instr) {
#if V8_TARGET_ARCH_RISCV64
DCHECK(IsLd(instr));
#elif V8_TARGET_ARCH_RISCV32
DCHECK(IsLw(instr));
#endif
int32_t imm12 = static_cast<int32_t>(instr & kImm12Mask) >> 20;
return imm12;
}
#ifdef V8_TARGET_ARCH_RISCV64
bool AssemblerRISCVI::IsAddiw(Instr instr) {
return (instr & (kBaseOpcodeMask | kFunct3Mask)) == RO_ADDIW;
}
bool AssemblerRISCVI::IsLd(Instr instr) {
return (instr & (kBaseOpcodeMask | kFunct3Mask)) == RO_LD;
}
void AssemblerRISCVI::lwu(Register rd, Register rs1, int16_t imm12) {
GenInstrLoad_ri(0b110, rd, rs1, imm12);
}
void AssemblerRISCVI::ld(Register rd, Register rs1, int16_t imm12) {
GenInstrLoad_ri(0b011, rd, rs1, imm12);
}
void AssemblerRISCVI::sd(Register source, Register base, int16_t imm12) {
GenInstrStore_rri(0b011, base, source, imm12);
}
void AssemblerRISCVI::addiw(Register rd, Register rs1, int16_t imm12) {
GenInstrI(0b000, OP_IMM_32, rd, rs1, imm12);
}
void AssemblerRISCVI::slliw(Register rd, Register rs1, uint8_t shamt) {
GenInstrShiftW_ri(0, 0b001, rd, rs1, shamt & 0x1f);
}
void AssemblerRISCVI::srliw(Register rd, Register rs1, uint8_t shamt) {
GenInstrShiftW_ri(0, 0b101, rd, rs1, shamt & 0x1f);
}
void AssemblerRISCVI::sraiw(Register rd, Register rs1, uint8_t shamt) {
GenInstrShiftW_ri(1, 0b101, rd, rs1, shamt & 0x1f);
}
void AssemblerRISCVI::addw(Register rd, Register rs1, Register rs2) {
GenInstrALUW_rr(0b0000000, 0b000, rd, rs1, rs2);
}
void AssemblerRISCVI::subw(Register rd, Register rs1, Register rs2) {
GenInstrALUW_rr(0b0100000, 0b000, rd, rs1, rs2);
}
void AssemblerRISCVI::sllw(Register rd, Register rs1, Register rs2) {
GenInstrALUW_rr(0b0000000, 0b001, rd, rs1, rs2);
}
void AssemblerRISCVI::srlw(Register rd, Register rs1, Register rs2) {
GenInstrALUW_rr(0b0000000, 0b101, rd, rs1, rs2);
}
void AssemblerRISCVI::sraw(Register rd, Register rs1, Register rs2) {
GenInstrALUW_rr(0b0100000, 0b101, rd, rs1, rs2);
}
#endif
} // namespace internal
} // namespace v8
// Copyright 2022 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/codegen/assembler.h"
#include "src/codegen/riscv/base-assembler-riscv.h"
#include "src/codegen/riscv/constant-riscv-i.h"
#include "src/codegen/riscv/register-riscv.h"
#ifndef V8_CODEGEN_RISCV_BASE_RISCV_I_H_
#define V8_CODEGEN_RISCV_BASE_RISCV_I_H_
namespace v8 {
namespace internal {
class AssemblerRISCVI : public AssemblerRiscvBase {
public:
void lui(Register rd, int32_t imm20);
void auipc(Register rd, int32_t imm20);
// Jumps
void jal(Register rd, int32_t imm20);
void jalr(Register rd, Register rs1, int16_t imm12);
// Branches
void beq(Register rs1, Register rs2, int16_t imm12);
void bne(Register rs1, Register rs2, int16_t imm12);
void blt(Register rs1, Register rs2, int16_t imm12);
void bge(Register rs1, Register rs2, int16_t imm12);
void bltu(Register rs1, Register rs2, int16_t imm12);
void bgeu(Register rs1, Register rs2, int16_t imm12);
// Loads
void lb(Register rd, Register rs1, int16_t imm12);
void lh(Register rd, Register rs1, int16_t imm12);
void lw(Register rd, Register rs1, int16_t imm12);
void lbu(Register rd, Register rs1, int16_t imm12);
void lhu(Register rd, Register rs1, int16_t imm12);
// Stores
void sb(Register source, Register base, int16_t imm12);
void sh(Register source, Register base, int16_t imm12);
void sw(Register source, Register base, int16_t imm12);
// Arithmetic with immediate
void addi(Register rd, Register rs1, int16_t imm12);
void slti(Register rd, Register rs1, int16_t imm12);
void sltiu(Register rd, Register rs1, int16_t imm12);
void xori(Register rd, Register rs1, int16_t imm12);
void ori(Register rd, Register rs1, int16_t imm12);
void andi(Register rd, Register rs1, int16_t imm12);
void slli(Register rd, Register rs1, uint8_t shamt);
void srli(Register rd, Register rs1, uint8_t shamt);
void srai(Register rd, Register rs1, uint8_t shamt);
// Arithmetic
void add(Register rd, Register rs1, Register rs2);
void sub(Register rd, Register rs1, Register rs2);
void sll(Register rd, Register rs1, Register rs2);
void slt(Register rd, Register rs1, Register rs2);
void sltu(Register rd, Register rs1, Register rs2);
void xor_(Register rd, Register rs1, Register rs2);
void srl(Register rd, Register rs1, Register rs2);
void sra(Register rd, Register rs1, Register rs2);
void or_(Register rd, Register rs1, Register rs2);
void and_(Register rd, Register rs1, Register rs2);
// Other pseudo instructions that are not part of RISCV pseudo assemly
void nor(Register rd, Register rs, Register rt) {
or_(rd, rs, rt);
not_(rd, rd);
}
// Memory fences
void fence(uint8_t pred, uint8_t succ);
void fence_tso();
// Environment call / break
void ecall();
void ebreak();
void sync() { fence(0b1111, 0b1111); }
// This is a de facto standard (as set by GNU binutils) 32-bit unimplemented
// instruction (i.e., it should always trap, if your implementation has
// invalid instruction traps).
void unimp();
static int JumpOffset(Instr instr);
static int AuipcOffset(Instr instr);
static int JalrOffset(Instr instr);
static int LoadOffset(Instr instr);
// Check if an instruction is a branch of some kind.
static bool IsBranch(Instr instr);
static bool IsNop(Instr instr);
static bool IsJump(Instr instr);
static bool IsJal(Instr instr);
static bool IsJalr(Instr instr);
static bool IsLui(Instr instr);
static bool IsAuipc(Instr instr);
static bool IsAddi(Instr instr);
static bool IsOri(Instr instr);
static bool IsSlli(Instr instr);
static bool IsLw(Instr instr);
inline int32_t branch_offset(Label* L) {
return branch_offset_helper(L, OffsetSize::kOffset13);
}
inline int32_t jump_offset(Label* L) {
return branch_offset_helper(L, OffsetSize::kOffset21);
}
// Branches
void beq(Register rs1, Register rs2, Label* L) {
beq(rs1, rs2, branch_offset(L));
}
void bne(Register rs1, Register rs2, Label* L) {
bne(rs1, rs2, branch_offset(L));
}
void blt(Register rs1, Register rs2, Label* L) {
blt(rs1, rs2, branch_offset(L));
}
void bge(Register rs1, Register rs2, Label* L) {
bge(rs1, rs2, branch_offset(L));
}
void bltu(Register rs1, Register rs2, Label* L) {
bltu(rs1, rs2, branch_offset(L));
}
void bgeu(Register rs1, Register rs2, Label* L) {
bgeu(rs1, rs2, branch_offset(L));
}
void beqz(Register rs, int16_t imm13) { beq(rs, zero_reg, imm13); }
void beqz(Register rs1, Label* L) { beqz(rs1, branch_offset(L)); }
void bnez(Register rs, int16_t imm13) { bne(rs, zero_reg, imm13); }
void bnez(Register rs1, Label* L) { bnez(rs1, branch_offset(L)); }
void blez(Register rs, int16_t imm13) { bge(zero_reg, rs, imm13); }
void blez(Register rs1, Label* L) { blez(rs1, branch_offset(L)); }
void bgez(Register rs, int16_t imm13) { bge(rs, zero_reg, imm13); }
void bgez(Register rs1, Label* L) { bgez(rs1, branch_offset(L)); }
void bltz(Register rs, int16_t imm13) { blt(rs, zero_reg, imm13); }
void bltz(Register rs1, Label* L) { bltz(rs1, branch_offset(L)); }
void bgtz(Register rs, int16_t imm13) { blt(zero_reg, rs, imm13); }
void bgtz(Register rs1, Label* L) { bgtz(rs1, branch_offset(L)); }
void bgt(Register rs1, Register rs2, int16_t imm13) { blt(rs2, rs1, imm13); }
void bgt(Register rs1, Register rs2, Label* L) {
bgt(rs1, rs2, branch_offset(L));
}
void ble(Register rs1, Register rs2, int16_t imm13) { bge(rs2, rs1, imm13); }
void ble(Register rs1, Register rs2, Label* L) {
ble(rs1, rs2, branch_offset(L));
}
void bgtu(Register rs1, Register rs2, int16_t imm13) {
bltu(rs2, rs1, imm13);
}
void bgtu(Register rs1, Register rs2, Label* L) {
bgtu(rs1, rs2, branch_offset(L));
}
void bleu(Register rs1, Register rs2, int16_t imm13) {
bgeu(rs2, rs1, imm13);
}
void bleu(Register rs1, Register rs2, Label* L) {
bleu(rs1, rs2, branch_offset(L));
}
void j(int32_t imm21) { jal(zero_reg, imm21); }
void j(Label* L) { j(jump_offset(L)); }
void b(Label* L) { j(L); }
void jal(int32_t imm21) { jal(ra, imm21); }
void jal(Label* L) { jal(jump_offset(L)); }
void jr(Register rs) { jalr(zero_reg, rs, 0); }
void jr(Register rs, int32_t imm12) { jalr(zero_reg, rs, imm12); }
void jalr(Register rs, int32_t imm12) { jalr(ra, rs, imm12); }
void jalr(Register rs) { jalr(ra, rs, 0); }
void ret() { jalr(zero_reg, ra, 0); }
void call(int32_t offset) {
auipc(ra, (offset >> 12) + ((offset & 0x800) >> 11));
jalr(ra, ra, offset << 20 >> 20);
}
void mv(Register rd, Register rs) { addi(rd, rs, 0); }
void not_(Register rd, Register rs) { xori(rd, rs, -1); }
void neg(Register rd, Register rs) { sub(rd, zero_reg, rs); }
void seqz(Register rd, Register rs) { sltiu(rd, rs, 1); }
void snez(Register rd, Register rs) { sltu(rd, zero_reg, rs); }
void sltz(Register rd, Register rs) { slt(rd, rs, zero_reg); }
void sgtz(Register rd, Register rs) { slt(rd, zero_reg, rs); }
#if V8_TARGET_ARCH_RISCV64
void lwu(Register rd, Register rs1, int16_t imm12);
void ld(Register rd, Register rs1, int16_t imm12);
void sd(Register source, Register base, int16_t imm12);
void addiw(Register rd, Register rs1, int16_t imm12);
void slliw(Register rd, Register rs1, uint8_t shamt);
void srliw(Register rd, Register rs1, uint8_t shamt);
void sraiw(Register rd, Register rs1, uint8_t shamt);
void addw(Register rd, Register rs1, Register rs2);
void subw(Register rd, Register rs1, Register rs2);
void sllw(Register rd, Register rs1, Register rs2);
void srlw(Register rd, Register rs1, Register rs2);
void sraw(Register rd, Register rs1, Register rs2);
void negw(Register rd, Register rs) { subw(rd, zero_reg, rs); }
void sext_w(Register rd, Register rs) { addiw(rd, rs, 0); }
static bool IsAddiw(Instr instr);
static bool IsLd(Instr instr);
#endif
};
} // namespace internal
} // namespace v8
#endif // V8_CODEGEN_RISCV_BASE_RISCV_I_H_
// Copyright 2022 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_CODEGEN_RISCV_CONSTANT_RISCV_A_H_
#define V8_CODEGEN_RISCV_CONSTANT_RISCV_A_H_
#include "src/codegen/riscv/base-constants-riscv.h"
namespace v8 {
namespace internal {
enum OpcodeRISCVA : uint32_t {
// RV32A Standard Extension
RO_LR_W = AMO | (0b010 << kFunct3Shift) | (0b00010 << kFunct5Shift),
RO_SC_W = AMO | (0b010 << kFunct3Shift) | (0b00011 << kFunct5Shift),
RO_AMOSWAP_W = AMO | (0b010 << kFunct3Shift) | (0b00001 << kFunct5Shift),
RO_AMOADD_W = AMO | (0b010 << kFunct3Shift) | (0b00000 << kFunct5Shift),
RO_AMOXOR_W = AMO | (0b010 << kFunct3Shift) | (0b00100 << kFunct5Shift),
RO_AMOAND_W = AMO | (0b010 << kFunct3Shift) | (0b01100 << kFunct5Shift),
RO_AMOOR_W = AMO | (0b010 << kFunct3Shift) | (0b01000 << kFunct5Shift),
RO_AMOMIN_W = AMO | (0b010 << kFunct3Shift) | (0b10000 << kFunct5Shift),
RO_AMOMAX_W = AMO | (0b010 << kFunct3Shift) | (0b10100 << kFunct5Shift),
RO_AMOMINU_W = AMO | (0b010 << kFunct3Shift) | (0b11000 << kFunct5Shift),
RO_AMOMAXU_W = AMO | (0b010 << kFunct3Shift) | (0b11100 << kFunct5Shift),
#ifdef V8_TARGET_ARCH_RISCV64
// RV64A Standard Extension (in addition to RV32A)
RO_LR_D = AMO | (0b011 << kFunct3Shift) | (0b00010 << kFunct5Shift),
RO_SC_D = AMO | (0b011 << kFunct3Shift) | (0b00011 << kFunct5Shift),
RO_AMOSWAP_D = AMO | (0b011 << kFunct3Shift) | (0b00001 << kFunct5Shift),
RO_AMOADD_D = AMO | (0b011 << kFunct3Shift) | (0b00000 << kFunct5Shift),
RO_AMOXOR_D = AMO | (0b011 << kFunct3Shift) | (0b00100 << kFunct5Shift),
RO_AMOAND_D = AMO | (0b011 << kFunct3Shift) | (0b01100 << kFunct5Shift),
RO_AMOOR_D = AMO | (0b011 << kFunct3Shift) | (0b01000 << kFunct5Shift),
RO_AMOMIN_D = AMO | (0b011 << kFunct3Shift) | (0b10000 << kFunct5Shift),
RO_AMOMAX_D = AMO | (0b011 << kFunct3Shift) | (0b10100 << kFunct5Shift),
RO_AMOMINU_D = AMO | (0b011 << kFunct3Shift) | (0b11000 << kFunct5Shift),
RO_AMOMAXU_D = AMO | (0b011 << kFunct3Shift) | (0b11100 << kFunct5Shift),
#endif // V8_TARGET_ARCH_RISCV64
};
} // namespace internal
} // namespace v8
#endif // V8_CODEGEN_RISCV_CONSTANT_RISCV_A_H_
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
// Copyright 2022 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_CODEGEN_RISCV_CONSTANT_RISCV_ZIFENCEI_H_
#define V8_CODEGEN_RISCV_CONSTANT_RISCV_ZIFENCEI_H_
#include "src/codegen/riscv/base-constants-riscv.h"
namespace v8 {
namespace internal {
enum OpcodeRISCVIFENCEI : uint32_t {
RO_FENCE_I = MISC_MEM | (0b001 << kFunct3Shift),
};
}
} // namespace v8
#endif // V8_CODEGEN_RISCV_CONSTANT_RISCV_ZIFENCEI_H_
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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