Skip to content

Commit 17f4c6e

Browse files
authored
Merge pull request #301 from tactcomplabs/Zfa
Zfa implementation Lots of changes to the test infrastructure to avoid tests when the toolchain does not support `Zfa` or `RV32`.
2 parents 5a32dc8 + 508872f commit 17f4c6e

39 files changed

+1158
-415
lines changed

include/AllRevInstTables.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include "insns/RV64I.h"
3131
#include "insns/RV64M.h"
3232
#include "insns/RV64P.h"
33+
#include "insns/Zfa.h"
3334
#include "insns/Zicbom.h"
3435
#include "insns/Zicsr.h"
3536
#include "insns/Zifencei.h"

include/RevCore.h

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ class RevCore {
175175
uint32_t GetActiveThreadID() { return Harts.at( HartToDecodeID )->GetAssignedThreadID(); }
176176

177177
///< RevCore: Get this Core's feature
178-
RevFeature* GetRevFeature() const { return feature; }
178+
const RevFeature* GetRevFeature() const { return feature; }
179179

180180
///< RevCore: Mark a current request as complete
181181
void MarkLoadComplete( const MemReq& req );
@@ -683,16 +683,16 @@ class RevCore {
683683
//std::vector<std::tuple<uint16_t, RevInst, bool>> Pipeline; ///< RevCore: pipeline of instructions
684684
std::deque<std::pair<uint16_t, RevInst>> Pipeline{}; ///< RevCore: pipeline of instructions
685685
std::unordered_map<std::string, unsigned> NameToEntry{}; ///< RevCore: instruction mnemonic to table entry mapping
686-
std::unordered_multimap<uint32_t, unsigned> EncToEntry{}; ///< RevCore: instruction encoding to table entry mapping
687-
std::unordered_multimap<uint32_t, unsigned> CEncToEntry{}; ///< RevCore: compressed instruction encoding to table entry mapping
686+
std::unordered_multimap<uint64_t, unsigned> EncToEntry{}; ///< RevCore: instruction encoding to table entry mapping
687+
std::unordered_multimap<uint64_t, unsigned> CEncToEntry{}; ///< RevCore: compressed instruction encoding to table entry mapping
688688
std::unordered_map<unsigned, std::pair<unsigned, unsigned>> EntryToExt{}; ///< RevCore: instruction entry to extension mapping
689689
/// first = Master table entry number
690690
/// second = pair<Extension Index, Extension Entry>
691691

692692
/// RevCore: finds an entry which matches an encoding whose predicate is true
693693
auto matchInst(
694-
const std::unordered_multimap<uint32_t, unsigned>& map,
695-
uint32_t encoding,
694+
const std::unordered_multimap<uint64_t, unsigned>& map,
695+
uint64_t encoding,
696696
const std::vector<RevInstEntry>& InstTable,
697697
uint32_t Inst
698698
) const;
@@ -707,7 +707,7 @@ class RevCore {
707707
bool SeedInstTable();
708708

709709
/// RevCore: enable the target extension by merging its instruction table with the master
710-
bool EnableExt( RevExt* Ext, bool Opt );
710+
bool EnableExt( RevExt* Ext );
711711

712712
/// RevCore: initializes the internal mapping tables
713713
bool InitTableMapping();
@@ -716,13 +716,13 @@ class RevCore {
716716
bool ReadOverrideTables();
717717

718718
/// RevCore: compresses the encoding structure to a single value
719-
uint32_t CompressEncoding( RevInstEntry Entry );
719+
uint64_t CompressEncoding( const RevInstEntry& Entry );
720720

721721
/// RevCore: compressed the compressed encoding structure to a single value
722-
uint32_t CompressCEncoding( RevInstEntry Entry );
722+
uint32_t CompressCEncoding( const RevInstEntry& Entry );
723723

724724
/// RevCore: extracts the instruction mnemonic from the table entry
725-
std::string ExtractMnemonic( RevInstEntry Entry );
725+
std::string ExtractMnemonic( const RevInstEntry& Entry );
726726

727727
/// RevCore: reset the core and its associated features
728728
bool Reset();

include/RevExt.h

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -51,33 +51,25 @@ struct RevExt {
5151
/// RevExt: sets the internal compressed instruction table
5252
void SetCTable( std::vector<RevInstEntry>&& InstVect ) { ctable = std::move( InstVect ); }
5353

54-
/// RevExt: sets the optional table (used for variant-specific compressed encodings)
55-
void SetOTable( std::vector<RevInstEntry>&& InstVect ) { otable = std::move( InstVect ); }
56-
5754
/// RevExt: retrieve the extension name
5855
std::string_view GetName() const { return name; }
5956

6057
/// RevExt: baseline execution function
6158
bool Execute( unsigned Inst, const RevInst& Payload, uint16_t HartID, RevRegFile* regFile );
6259

6360
/// RevExt: retrieves the extension's instruction table
64-
const std::vector<RevInstEntry>& GetInstTable() { return table; }
61+
const std::vector<RevInstEntry>& GetTable() { return table; }
6562

6663
/// RevExt: retrieves the extension's compressed instruction table
67-
const std::vector<RevInstEntry>& GetCInstTable() { return ctable; }
68-
69-
/// RevExt: retrieves the extension's optional instruction table
70-
const std::vector<RevInstEntry>& GetOInstTable() { return otable; }
64+
const std::vector<RevInstEntry>& GetCTable() { return ctable; }
7165

7266
private:
73-
std::string_view const name; ///< RevExt: extension name
74-
RevFeature* const feature; ///< RevExt: feature object
75-
RevMem* const mem; ///< RevExt: memory object
76-
SST::Output* const output; ///< RevExt: output handler
77-
67+
std::string_view const name; ///< RevExt: extension name
68+
RevFeature* const feature; ///< RevExt: feature object
69+
RevMem* const mem; ///< RevExt: memory object
70+
SST::Output* const output; ///< RevExt: output handler
7871
std::vector<RevInstEntry> table{}; ///< RevExt: instruction table
7972
std::vector<RevInstEntry> ctable{}; ///< RevExt: compressed instruction table
80-
std::vector<RevInstEntry> otable{}; ///< RevExt: optional compressed instruction table
8173

8274
}; // class RevExt
8375

include/RevInstHelpers.h

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -230,24 +230,32 @@ bool foper( RevFeature* F, RevRegFile* R, RevMem* M, const RevInst& Inst ) {
230230
}
231231

232232
/// Floating-point minimum functor
233+
/// If one argument is NaN, the result is the other argument
233234
template<typename = void>
234235
struct FMin {
235236
template<typename T>
236237
auto operator()( T x, T y ) const {
237-
if( fclass( x ) == SignalingNaN || fclass( y ) == SignalingNaN )
238+
auto xclass = fclass( x );
239+
auto yclass = fclass( y );
240+
if( xclass == SignalingNaN || yclass == SignalingNaN ) {
238241
feraiseexcept( FE_INVALID );
239-
return std::fmin( x, y );
242+
}
243+
return ( xclass == ZeroPos && yclass == ZeroNeg ) || ( xclass == ZeroNeg && yclass == ZeroPos ) ? -T{ 0 } : std::fmin( x, y );
240244
}
241245
};
242246

243247
/// Floating-point maximum functor
248+
/// If one argument is NaN, the result is the other argument
244249
template<typename = void>
245250
struct FMax {
246251
template<typename T>
247252
auto operator()( T x, T y ) const {
248-
if( fclass( x ) == SignalingNaN || fclass( y ) == SignalingNaN )
253+
auto xclass = fclass( x );
254+
auto yclass = fclass( y );
255+
if( xclass == SignalingNaN || yclass == SignalingNaN ) {
249256
feraiseexcept( FE_INVALID );
250-
return std::fmax( x, y );
257+
}
258+
return ( xclass == ZeroPos && yclass == ZeroNeg ) || ( xclass == ZeroNeg && yclass == ZeroPos ) ? T{ 0 } : std::fmax( x, y );
251259
}
252260
};
253261

include/RevInstTable.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ struct RevInstEntry {
145145
// formatting
146146
RevInstF format = RVTypeR; ///< RevInstEntry: instruction format
147147
bool compressed = false; ///< RevInstEntry: compressed instruction
148-
uint8_t fpcvtOp = 0; ///<RevInstEntry: Stores the rs2 field in R-instructions
148+
uint8_t rs2fcvtOp = 0; ///<RevInstEntry: Stores the rs2 field in R-instructions
149149
bool raisefpe = false; ///<RevInstEntry: Whether FP exceptions are raised
150150

151151
/// Instruction implementation function
@@ -174,7 +174,7 @@ struct RevInstEntry {
174174
auto& Setimm(RevImmFunc imm) { this->imm = imm; return *this; }
175175
auto& SetFormat(RevInstF format) { this->format = format;return *this; }
176176
auto& SetCompressed(bool c) { this->compressed = c; return *this; }
177-
auto& SetfpcvtOp(uint8_t op) { this->fpcvtOp = op; return *this; }
177+
auto& Setrs2fcvtOp(uint8_t op) { this->rs2fcvtOp = op; return *this; }
178178
auto& SetRaiseFPE(bool c) { this->raisefpe = c; return *this; }
179179
auto& SetImplFunc( bool func( RevFeature *, RevRegFile *, RevMem *, const RevInst& ) )
180180
{ this->func = func; return *this; }

include/RevRegFile.h

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -310,10 +310,9 @@ class RevRegFile {
310310
fp32 = SPF[size_t( rs )]; // The FP32 register's value
311311
} else {
312312
uint64_t i64;
313-
memcpy( &i64, &DPF[size_t( rs )],
314-
sizeof( i64 ) ); // The FP64 register's value
315-
if( !FMV_FS && ~i64 >> 32 ) { // Check for boxed NaN unless FMV/FS
316-
fp32 = NAN; // Return NaN if it's not boxed
313+
memcpy( &i64, &DPF[size_t( rs )], sizeof( i64 ) ); // The FP64 register's value
314+
if( !FMV_FS && ~i64 >> 32 ) { // Check for boxed NaN unless FMV/FS
315+
fp32 = NAN; // Return NaN if it's not boxed
317316
} else {
318317
auto i32 = static_cast<uint32_t>( i64 ); // For endian independence on host
319318
memcpy( &fp32, &i32, sizeof( fp32 ) ); // The bottom half of FP64
@@ -329,8 +328,7 @@ class RevRegFile {
329328
if constexpr( std::is_same_v<T, double> ) {
330329
DPF[size_t( rd )] = value; // Store in FP64 register
331330
} else if( HasD ) {
332-
BoxNaN( &DPF[size_t( rd )],
333-
&value ); // Store NaN-boxed float in FP64 register
331+
BoxNaN( &DPF[size_t( rd )], &value ); // Store NaN-boxed float in FP64 register
334332
} else {
335333
SPF[size_t( rd )] = value; // Store in FP32 register
336334
}
@@ -340,17 +338,17 @@ class RevRegFile {
340338
// Performance counters
341339

342340
// Template is used to break circular dependencies between RevCore and RevRegFile
343-
template<typename CORE>
341+
template<typename CORE, typename = std::enable_if_t<std::is_same_v<CORE, RevCore>>>
344342
uint64_t rdcycle( CORE* core ) const {
345343
return core->GetCycles();
346344
}
347345

348-
template<typename CORE>
346+
template<typename CORE, typename = std::enable_if_t<std::is_same_v<CORE, RevCore>>>
349347
uint64_t rdtime( CORE* core ) const {
350348
return core->GetCurrentSimCycle();
351349
}
352350

353-
template<typename CORE>
351+
template<typename CORE, typename = std::enable_if_t<std::is_same_v<CORE, RevCore>>>
354352
uint64_t rdinstret( CORE* ) const {
355353
return InstRet;
356354
}

include/insns/RV32A.h

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -134,18 +134,17 @@ class RV32A : public RevExt {
134134

135135
// clang-format off
136136
std::vector<RevInstEntry> RV32ATable = {
137-
{ RV32AInstDefaults().SetMnemonic("lr.w %rd, (%rs1)" ).SetFunct2or7(0b0000010).SetImplFunc(lrw )
138-
.Setrs2Class(RevRegClass::RegUNKNOWN) },
139-
{ RV32AInstDefaults().SetMnemonic("sc.w %rd, %rs1, %rs2" ).SetFunct2or7(0b0000011).SetImplFunc(scw ) },
140-
{ RV32AInstDefaults().SetMnemonic("amoswap.w %rd, %rs1, %rs2").SetFunct2or7(0b0000001).SetImplFunc(amoswapw) },
141-
{ RV32AInstDefaults().SetMnemonic("amoadd.w %rd, %rs1, %rs2" ).SetFunct2or7(0b0000000).SetImplFunc(amoaddw ) },
142-
{ RV32AInstDefaults().SetMnemonic("amoxor.w %rd, %rs1, %rs2" ).SetFunct2or7(0b0000100).SetImplFunc(amoxorw ) },
143-
{ RV32AInstDefaults().SetMnemonic("amoand.w %rd, %rs1, %rs2" ).SetFunct2or7(0b0001100).SetImplFunc(amoandw ) },
144-
{ RV32AInstDefaults().SetMnemonic("amoor.w %rd, %rs1, %rs2" ).SetFunct2or7(0b0001000).SetImplFunc(amoorw ) },
145-
{ RV32AInstDefaults().SetMnemonic("amomin.w %rd, %rs1, %rs2" ).SetFunct2or7(0b0010000).SetImplFunc(amominw ) },
146-
{ RV32AInstDefaults().SetMnemonic("amomax.w %rd, %rs1, %rs2" ).SetFunct2or7(0b0010100).SetImplFunc(amomaxw ) },
147-
{ RV32AInstDefaults().SetMnemonic("amominu.w %rd, %rs1, %rs2").SetFunct2or7(0b0011000).SetImplFunc(amominuw) },
148-
{ RV32AInstDefaults().SetMnemonic("amomaxu.w %rd, %rs1, %rs2").SetFunct2or7(0b0011100).SetImplFunc(amomaxuw) },
137+
RV32AInstDefaults().SetMnemonic("lr.w %rd, (%rs1)" ).SetFunct2or7(0b0000010).SetImplFunc(lrw ).Setrs2Class(RevRegClass::RegUNKNOWN),
138+
RV32AInstDefaults().SetMnemonic("sc.w %rd, %rs1, %rs2" ).SetFunct2or7(0b0000011).SetImplFunc(scw ),
139+
RV32AInstDefaults().SetMnemonic("amoswap.w %rd, %rs1, %rs2").SetFunct2or7(0b0000001).SetImplFunc(amoswapw),
140+
RV32AInstDefaults().SetMnemonic("amoadd.w %rd, %rs1, %rs2" ).SetFunct2or7(0b0000000).SetImplFunc(amoaddw ),
141+
RV32AInstDefaults().SetMnemonic("amoxor.w %rd, %rs1, %rs2" ).SetFunct2or7(0b0000100).SetImplFunc(amoxorw ),
142+
RV32AInstDefaults().SetMnemonic("amoand.w %rd, %rs1, %rs2" ).SetFunct2or7(0b0001100).SetImplFunc(amoandw ),
143+
RV32AInstDefaults().SetMnemonic("amoor.w %rd, %rs1, %rs2" ).SetFunct2or7(0b0001000).SetImplFunc(amoorw ),
144+
RV32AInstDefaults().SetMnemonic("amomin.w %rd, %rs1, %rs2" ).SetFunct2or7(0b0010000).SetImplFunc(amominw ),
145+
RV32AInstDefaults().SetMnemonic("amomax.w %rd, %rs1, %rs2" ).SetFunct2or7(0b0010100).SetImplFunc(amomaxw ),
146+
RV32AInstDefaults().SetMnemonic("amominu.w %rd, %rs1, %rs2").SetFunct2or7(0b0011000).SetImplFunc(amominuw),
147+
RV32AInstDefaults().SetMnemonic("amomaxu.w %rd, %rs1, %rs2").SetFunct2or7(0b0011100).SetImplFunc(amomaxuw),
149148
};
150149
// clang-format on
151150

0 commit comments

Comments
 (0)