Skip to content

Commit c3dee3c

Browse files
authored
Merge pull request #313 from tactcomplabs/Zaamo_Zalrsc
Fix LR/SC and split A into Zaamo and Zalrsc
2 parents 16e65f1 + 18a7c54 commit c3dee3c

17 files changed

+431
-504
lines changed

include/AllRevInstTables.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,17 @@
1919
// and implementation for each block of RISC-V isntructions
2020
//
2121

22-
#include "insns/RV32A.h"
2322
#include "insns/RV32D.h"
2423
#include "insns/RV32F.h"
2524
#include "insns/RV32I.h"
2625
#include "insns/RV32M.h"
27-
#include "insns/RV64A.h"
2826
#include "insns/RV64D.h"
2927
#include "insns/RV64F.h"
3028
#include "insns/RV64I.h"
3129
#include "insns/RV64M.h"
3230
#include "insns/RV64P.h"
31+
#include "insns/Zaamo.h"
32+
#include "insns/Zalrsc.h"
3333
#include "insns/Zfa.h"
3434
#include "insns/Zicbom.h"
3535
#include "insns/Zicsr.h"

include/RevCore.h

-3
Original file line numberDiff line numberDiff line change
@@ -105,9 +105,6 @@ class RevCore {
105105
/// RevCore: Debug mode write a register
106106
bool DebugWriteReg( unsigned Idx, uint64_t Value ) const;
107107

108-
/// RevCore: Is this an RV32 machine?
109-
bool DebugIsRV32() { return feature->IsRV32(); }
110-
111108
/// RevCore: Set an optional tracer
112109
void SetTracer( RevTracer* T ) { Tracer = T; }
113110

include/RevFeature.h

+19-21
Original file line numberDiff line numberDiff line change
@@ -26,23 +26,24 @@ enum RevFeatureType : uint32_t {
2626
RV_I = 1 << 0, ///< RevFeatureType: I-extension
2727
RV_E = 1 << 1, ///< RevFeatureType: E-extension
2828
RV_M = 1 << 2, ///< RevFeatureType: M-extension
29-
RV_A = 1 << 3, ///< RevFeatureType: A-extension
30-
RV_F = 1 << 4, ///< RevFeatureType: F-extension
31-
RV_D = 1 << 5, ///< RevFeatureType: D-extension
32-
RV_Q = 1 << 6, ///< RevFeatureType: Q-extension
33-
RV_C = 1 << 7, ///< RevFeatureType: C-extension
34-
RV_B = 1 << 8, ///< RevFeatureType: C-extension
35-
RV_P = 1 << 9, ///< RevFeatureType: P-Extension
36-
RV_V = 1 << 10, ///< RevFeatureType: V-extension
37-
RV_H = 1 << 11, ///< RevFeatureType: H-extension
38-
RV_ZICBOM = 1 << 12, ///< RevFeatureType: Zicbom-extension
39-
RV_ZICSR = 1 << 13, ///< RevFEatureType: Zicsr-extension
40-
RV_ZIFENCEI = 1 << 14, ///< RevFeatureType: Zifencei-extension
41-
RV_ZMMUL = 1 << 15, ///< RevFeatureType: Zmmul-extension
42-
RV_ZFA = 1 << 16, ///< RevFeatureType: Zfa-extension
43-
RV_ZFH = 1 << 17, ///< RevFeatureType: H-extension
44-
RV_ZFHMIN = 1 << 18, ///< RevFeatureRtpe: Zfhmin extension
45-
RV_ZTSO = 1 << 19, ///< RevFeatureType: Ztso-extension
29+
RV_F = 1 << 3, ///< RevFeatureType: F-extension
30+
RV_D = 1 << 4, ///< RevFeatureType: D-extension
31+
RV_Q = 1 << 5, ///< RevFeatureType: Q-extension
32+
RV_C = 1 << 6, ///< RevFeatureType: C-extension
33+
RV_B = 1 << 7, ///< RevFeatureType: C-extension
34+
RV_P = 1 << 8, ///< RevFeatureType: P-Extension
35+
RV_V = 1 << 9, ///< RevFeatureType: V-extension
36+
RV_H = 1 << 10, ///< RevFeatureType: H-extension
37+
RV_ZICBOM = 1 << 11, ///< RevFeatureType: Zicbom-extension
38+
RV_ZICSR = 1 << 12, ///< RevFEatureType: Zicsr-extension
39+
RV_ZIFENCEI = 1 << 13, ///< RevFeatureType: Zifencei-extension
40+
RV_ZMMUL = 1 << 14, ///< RevFeatureType: Zmmul-extension
41+
RV_ZAAMO = 1 << 15, ///< RevFeatureType: Zaamo-extension
42+
RV_ZALRSC = 1 << 16, ///< RevFeatureType: Zalrsc-extension
43+
RV_ZFA = 1 << 17, ///< RevFeatureType: Zfa-extension
44+
RV_ZFH = 1 << 18, ///< RevFeatureType: H-extension
45+
RV_ZFHMIN = 1 << 19, ///< RevFeatureRtpe: Zfhmin extension
46+
RV_ZTSO = 1 << 20, ///< RevFeatureType: Ztso-extension
4647
};
4748

4849
class RevFeature {
@@ -77,11 +78,8 @@ class RevFeature {
7778
/// GetMaxCost: get the maximum cost
7879
auto GetMaxCost() const { return MaxCost; }
7980

80-
/// IsRV32: Is the device an RV32
81-
bool IsRV32() const { return xlen == 32; }
82-
8381
/// IsRV64: Is the device an RV64
84-
bool IsRV64() const { return xlen == 64; }
82+
bool IsRV64() const { return xlen >= 64; }
8583

8684
/// HasF: Does the device support F?
8785
bool HasF() const { return IsModeEnabled( RV_F ); }

include/RevInstHelpers.h

+16-16
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ uint32_t fclass( T val ) {
133133
/// Load template
134134
template<typename T>
135135
bool load( RevFeature* F, RevRegFile* R, RevMem* M, const RevInst& Inst ) {
136-
if( sizeof( T ) < sizeof( int64_t ) && R->IsRV32 ) {
136+
if( sizeof( T ) < sizeof( int64_t ) && !R->IsRV64 ) {
137137
static constexpr RevFlag flags =
138138
sizeof( T ) < sizeof( int32_t ) ? std::is_signed_v<T> ? RevFlag::F_SEXT32 : RevFlag::F_ZEXT32 : RevFlag::F_NONE;
139139
auto rs1 = R->GetX<uint64_t>( Inst.rs1 ); // read once for tracer
@@ -284,7 +284,7 @@ enum class OpKind { Imm, Reg };
284284
// The optional fourth parameter indicates W mode (32-bit on XLEN == 64)
285285
template<template<class> class OP, OpKind KIND, template<class> class SIGN = std::make_signed_t, bool W_MODE = false>
286286
bool oper( RevFeature* F, RevRegFile* R, RevMem* M, const RevInst& Inst ) {
287-
if( !W_MODE && R->IsRV32 ) {
287+
if( !W_MODE && !R->IsRV64 ) {
288288
using T = SIGN<int32_t>;
289289
T rs1 = R->GetX<T>( Inst.rs1 );
290290
T rs2 = KIND == OpKind::Imm ? T( Inst.ImmSignExt( 12 ) ) : R->GetX<T>( Inst.rs2 );
@@ -323,16 +323,7 @@ struct ShiftRight {
323323
// Computes the UPPER half of multiplication, based on signedness
324324
template<bool rs1_is_signed, bool rs2_is_signed>
325325
bool uppermul( RevFeature* F, RevRegFile* R, RevMem* M, const RevInst& Inst ) {
326-
if( R->IsRV32 ) {
327-
uint32_t rs1 = R->GetX<uint32_t>( Inst.rs1 );
328-
uint32_t rs2 = R->GetX<uint32_t>( Inst.rs2 );
329-
uint32_t mul = static_cast<uint32_t>( rs1 * int64_t( rs2 ) >> 32 );
330-
if( rs1_is_signed && ( rs1 & ( uint32_t{ 1 } << 31 ) ) != 0 )
331-
mul -= rs2;
332-
if( rs2_is_signed && ( rs2 & ( uint32_t{ 1 } << 31 ) ) != 0 )
333-
mul -= rs1;
334-
R->SetX( Inst.rd, mul );
335-
} else {
326+
if( R->IsRV64 ) {
336327
uint64_t rs1 = R->GetX<uint64_t>( Inst.rs1 );
337328
uint64_t rs2 = R->GetX<uint64_t>( Inst.rs2 );
338329
uint64_t mul = static_cast<uint64_t>( rs1 * __int128( rs2 ) >> 64 );
@@ -341,6 +332,15 @@ bool uppermul( RevFeature* F, RevRegFile* R, RevMem* M, const RevInst& Inst ) {
341332
if( rs2_is_signed && ( rs2 & ( uint64_t{ 1 } << 63 ) ) != 0 )
342333
mul -= rs1;
343334
R->SetX( Inst.rd, mul );
335+
} else {
336+
uint32_t rs1 = R->GetX<uint32_t>( Inst.rs1 );
337+
uint32_t rs2 = R->GetX<uint32_t>( Inst.rs2 );
338+
uint32_t mul = static_cast<uint32_t>( rs1 * int64_t( rs2 ) >> 32 );
339+
if( rs1_is_signed && ( rs1 & ( uint32_t{ 1 } << 31 ) ) != 0 )
340+
mul -= rs2;
341+
if( rs2_is_signed && ( rs2 & ( uint32_t{ 1 } << 31 ) ) != 0 )
342+
mul -= rs1;
343+
R->SetX( Inst.rd, mul );
344344
}
345345
R->AdvancePC( Inst );
346346
return true;
@@ -354,7 +354,7 @@ enum class DivRem { Div, Rem };
354354
// The optional third parameter indicates W mode (32-bit on XLEN == 64)
355355
template<DivRem DIVREM, template<class> class SIGN, bool W_MODE = false>
356356
bool divrem( RevFeature* F, RevRegFile* R, RevMem* M, const RevInst& Inst ) {
357-
if( !W_MODE && R->IsRV32 ) {
357+
if( !W_MODE && !R->IsRV64 ) {
358358
using T = SIGN<int32_t>;
359359
T rs1 = R->GetX<T>( Inst.rs1 );
360360
T rs2 = R->GetX<T>( Inst.rs2 );
@@ -388,10 +388,10 @@ bool divrem( RevFeature* F, RevRegFile* R, RevMem* M, const RevInst& Inst ) {
388388
template<template<class> class OP, template<class> class SIGN = std::make_unsigned_t>
389389
bool bcond( RevFeature* F, RevRegFile* R, RevMem* M, const RevInst& Inst ) {
390390
bool cond;
391-
if( R->IsRV32 ) {
392-
cond = OP()( R->GetX<SIGN<int32_t>>( Inst.rs1 ), R->GetX<SIGN<int32_t>>( Inst.rs2 ) );
393-
} else {
391+
if( R->IsRV64 ) {
394392
cond = OP()( R->GetX<SIGN<int64_t>>( Inst.rs1 ), R->GetX<SIGN<int64_t>>( Inst.rs2 ) );
393+
} else {
394+
cond = OP()( R->GetX<SIGN<int32_t>>( Inst.rs1 ), R->GetX<SIGN<int32_t>>( Inst.rs2 ) );
395395
}
396396
if( cond ) {
397397
R->SetPC( R->GetPC() + Inst.ImmSignExt( 13 ) );

include/RevInstTable.h

+25-25
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@
3838
#define DECODE_FUNCT3( x ) ( ( ( x ) >> ( 12 ) ) & ( 0b111 ) )
3939

4040
#define DECODE_RM( x ) static_cast<FRMode>( DECODE_FUNCT3( x ) )
41-
#define DECODE_RL( x ) ( ( ( x ) >> ( 25 ) ) & ( 0b1 ) )
42-
#define DECODE_AQ( x ) ( ( ( x ) >> ( 26 ) ) & ( 0b1 ) )
41+
#define DECODE_RL( x ) ( ( ( x ) >> 25 & 0b1 ) != 0 )
42+
#define DECODE_AQ( x ) ( ( ( x ) >> 26 & 0b1 ) != 0 )
4343

4444
namespace SST::RevCPU {
4545

@@ -79,29 +79,29 @@ enum RevImmFunc : int { ///< Rev Immediate Values
7979
*
8080
*/
8181
struct RevInst {
82-
uint8_t opcode = 0; ///< RevInst: opcode
83-
uint8_t funct2 = 0; ///< RevInst: compressed funct2 value
84-
uint8_t funct3 = 0; ///< RevInst: funct3 value
85-
uint8_t funct4 = 0; ///< RevInst: compressed funct4 value
86-
uint8_t funct6 = 0; ///< RevInst: compressed funct6 value
87-
uint8_t funct2or7 = 0; ///< RevInst: uncompressed funct2 or funct7 value
88-
uint64_t rd = ~0; ///< RevInst: rd value
89-
uint64_t rs1 = ~0; ///< RevInst: rs1 value
90-
uint64_t rs2 = ~0; ///< RevInst: rs2 value
91-
uint64_t rs3 = ~0; ///< RevInst: rs3 value
92-
uint64_t imm = 0; ///< RevInst: immediate value
93-
bool raisefpe = 0; ///< RevInst: raises FP exceptions
94-
FRMode rm{ FRMode::None }; ///< RevInst: floating point rounding mode
95-
uint8_t aq = 0; ///< RevInst: aq field for atomic instructions
96-
uint8_t rl = 0; ///< RevInst: rl field for atomic instructions
97-
uint16_t offset = 0; ///< RevInst: compressed offset
98-
uint16_t jumpTarget = 0; ///< RevInst: compressed jumpTarget
99-
uint8_t instSize = 0; ///< RevInst: size of the instruction in bytes
100-
bool compressed = 0; ///< RevInst: determines if the instruction is compressed
101-
uint32_t cost = 0; ///< RevInst: the cost to execute this instruction, in clock cycles
102-
unsigned entry = 0; ///< RevInst: Where to find this instruction in the InstTables
103-
uint16_t hart = 0; ///< RevInst: What hart is this inst being executed on
104-
bool isCoProcInst = 0; ///< RevInst: whether instruction is coprocessor instruction
82+
uint8_t opcode = 0; ///< RevInst: opcode
83+
uint8_t funct2 = 0; ///< RevInst: compressed funct2 value
84+
uint8_t funct3 = 0; ///< RevInst: funct3 value
85+
uint8_t funct4 = 0; ///< RevInst: compressed funct4 value
86+
uint8_t funct6 = 0; ///< RevInst: compressed funct6 value
87+
uint8_t funct2or7 = 0; ///< RevInst: uncompressed funct2 or funct7 value
88+
uint64_t rd = ~0; ///< RevInst: rd value
89+
uint64_t rs1 = ~0; ///< RevInst: rs1 value
90+
uint64_t rs2 = ~0; ///< RevInst: rs2 value
91+
uint64_t rs3 = ~0; ///< RevInst: rs3 value
92+
uint64_t imm = 0; ///< RevInst: immediate value
93+
bool raisefpe = 0; ///< RevInst: raises FP exceptions
94+
FRMode rm{ FRMode::None }; ///< RevInst: floating point rounding mode
95+
bool aq = false; ///< RevInst: aqr field for atomic instructions
96+
bool rl = false; ///< RevInst: rel field for atomic instructions
97+
uint16_t offset = 0; ///< RevInst: compressed offset
98+
uint16_t jumpTarget = 0; ///< RevInst: compressed jumpTarget
99+
uint8_t instSize = 0; ///< RevInst: size of the instruction in bytes
100+
bool compressed = 0; ///< RevInst: determines if the instruction is compressed
101+
uint32_t cost = 0; ///< RevInst: the cost to execute this instruction, in clock cycles
102+
unsigned entry = 0; ///< RevInst: Where to find this instruction in the InstTables
103+
uint16_t hart = 0; ///< RevInst: What hart is this inst being executed on
104+
bool isCoProcInst = 0; ///< RevInst: whether instruction is coprocessor instruction
105105

106106
explicit RevInst() = default; // prevent aggregate initialization
107107

include/RevMem.h

+10-26
Original file line numberDiff line numberDiff line change
@@ -203,17 +203,11 @@ class RevMem {
203203
return ReadMem( Hart, Addr, sizeof( T ), Target, req, flags );
204204
}
205205

206-
/// RevMem: template LOAD RESERVE memory interface
207-
template<typename T>
208-
bool LR( unsigned Hart, uint64_t Addr, T* Target, uint8_t aq, uint8_t rl, const MemReq& req, RevFlag flags ) {
209-
return LRBase( Hart, Addr, sizeof( T ), Target, aq, rl, req, flags );
210-
}
206+
/// RevMem: LOAD RESERVE memory interface
207+
void LR( unsigned hart, uint64_t addr, size_t len, void* target, const MemReq& req, RevFlag flags );
211208

212-
/// RevMem: template STORE CONDITIONAL memory interface
213-
template<typename T>
214-
bool SC( unsigned Hart, uint64_t Addr, T* Data, T* Target, uint8_t aq, uint8_t rl, RevFlag flags ) {
215-
return SCBase( Hart, Addr, sizeof( T ), Data, Target, aq, rl, flags );
216-
}
209+
/// RevMem: STORE CONDITIONAL memory interface
210+
bool SC( unsigned Hart, uint64_t addr, size_t len, void* data, RevFlag flags );
217211

218212
/// RevMem: template AMO memory interface
219213
template<typename T>
@@ -246,15 +240,12 @@ class RevMem {
246240
// ----------------------------------------------------
247241
// ---- Atomic/Future/LRSC Interfaces
248242
// ----------------------------------------------------
249-
/// RevMem: Add a memory reservation for the target address
250-
bool LRBase( unsigned Hart, uint64_t Addr, size_t Len, void* Data, uint8_t aq, uint8_t rl, const MemReq& req, RevFlag flags );
251-
252-
/// RevMem: Clear a memory reservation for the target address
253-
bool SCBase( unsigned Hart, uint64_t Addr, size_t Len, void* Data, void* Target, uint8_t aq, uint8_t rl, RevFlag flags );
254-
255243
/// RevMem: Initiated an AMO request
256244
bool AMOMem( unsigned Hart, uint64_t Addr, size_t Len, void* Data, void* Target, const MemReq& req, RevFlag flags );
257245

246+
/// RevMem: Invalidate Matching LR reservations
247+
bool InvalidateLRReservations( unsigned hart, uint64_t addr, size_t len );
248+
258249
/// RevMem: Initiates a future operation [RV64P only]
259250
bool SetFuture( uint64_t Addr );
260251

@@ -424,16 +415,9 @@ class RevMem {
424415
uint64_t heapstart{}; ///< RevMem: top of the stack
425416
uint64_t stacktop{}; ///< RevMem: top of the stack
426417

427-
std::vector<uint64_t> FutureRes{}; ///< RevMem: future operation reservations
428-
429-
// these are LRSC tuple index macros
430-
#define LRSC_HART 0
431-
#define LRSC_ADDR 1
432-
#define LRSC_AQRL 2
433-
#define LRSC_VAL 3
434-
std::vector<std::tuple<unsigned, uint64_t, unsigned, uint64_t*>> LRSC{}; ///< RevMem: load reserve/store conditional vector
435-
436-
}; // class RevMem
418+
std::vector<uint64_t> FutureRes{}; ///< RevMem: future operation reservations
419+
std::unordered_map<unsigned, std::pair<uint64_t, size_t>> LRSC{}; ///< RevMem: load reserve/store conditional set
420+
}; // class RevMem
437421

438422
} // namespace SST::RevCPU
439423

include/RevMemCtrl.h

+4
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,10 @@ constexpr bool RevFlagHas( RevFlag flag, RevFlag has ) {
7070
return ( static_cast<uint32_t>( flag ) & static_cast<uint32_t>( has ) ) != 0;
7171
}
7272

73+
inline void RevFlagSet( RevFlag& flag, RevFlag set ) {
74+
flag = RevFlag{ uint32_t( flag ) | uint32_t( set ) };
75+
}
76+
7377
/// RevFlag: Handle flag response
7478
void RevHandleFlagResp( void* target, size_t size, RevFlag flags );
7579

0 commit comments

Comments
 (0)