mirror of
https://github.com/vortexgpgpu/vortex.git
synced 2025-04-24 05:47:35 -04:00
adding floating extension to SimX
This commit is contained in:
parent
34ce0b8e89
commit
4fe345f269
11 changed files with 939 additions and 286 deletions
|
@ -13,7 +13,7 @@ RTL_DIR = ../hw/rtl
|
|||
|
||||
PROJECT = simX
|
||||
|
||||
SRCS = util.cpp args.cpp mem.cpp core.cpp warp.cpp instr.cpp decode.cpp execute.cpp simX.cpp
|
||||
SRCS = util.cpp args.cpp mem.cpp core.cpp warp.cpp instr.cpp decode.cpp execute.cpp main.cpp
|
||||
|
||||
# Debugigng
|
||||
ifdef DEBUG
|
||||
|
@ -27,6 +27,9 @@ all: $(PROJECT)
|
|||
$(PROJECT): $(SRCS)
|
||||
$(CXX) $(CXXFLAGS) $^ $(LDFLAGS) -o $@
|
||||
|
||||
run: $(PROJECT)
|
||||
./$(PROJECT)
|
||||
|
||||
.depend: $(SRCS)
|
||||
$(CXX) $(CXXFLAGS) -MM $^ > .depend;
|
||||
|
||||
|
|
|
@ -117,11 +117,6 @@ Core::Core(const ArchDef &arch, Decoder &decoder, MemoryUnit &mem, Word id)
|
|||
warps_[0].setSpawned(true);
|
||||
}
|
||||
|
||||
bool Core::interrupt(Word r0) {
|
||||
warps_[0].interrupt(r0);
|
||||
return false;
|
||||
}
|
||||
|
||||
Core::~Core() {
|
||||
//--
|
||||
}
|
||||
|
|
|
@ -21,7 +21,6 @@ public:
|
|||
Core(const ArchDef &arch, Decoder &decoder, MemoryUnit &mem, Word id = 0);
|
||||
~Core();
|
||||
|
||||
bool interrupt(Word r0);
|
||||
bool running() const;
|
||||
|
||||
void getCacheDelays(trace_inst_t *);
|
||||
|
|
|
@ -38,7 +38,14 @@ static const std::unordered_map<int, struct InstTableEntry_t> sc_instTable = {
|
|||
{Opcode::GPGPU, {"gpgpu" , false, InstType::R_TYPE}},
|
||||
{Opcode::VSET_ARITH, {"vsetvl", false, InstType::V_TYPE}},
|
||||
{Opcode::VL, {"vl" , false, InstType::V_TYPE}},
|
||||
{Opcode::VS, {"vs" , false, InstType::V_TYPE}}
|
||||
{Opcode::VS, {"vs" , false, InstType::V_TYPE}},
|
||||
{Opcode::FL, {"fl" , false, InstType::I_TYPE }},
|
||||
{Opcode::FS, {"fs" , false, InstType::S_TYPE }},
|
||||
{Opcode::FCI, {"fci" , false, InstType::R_TYPE }},
|
||||
{Opcode::FMADD, {"fma" , false, InstType::R4_TYPE }},
|
||||
{Opcode::FMSUB, {"fms" , false, InstType::R4_TYPE }},
|
||||
{Opcode::FMNMADD, {"fmnma" , false, InstType::R4_TYPE }},
|
||||
{Opcode::FMNMSUB, {"fmnms" , false, InstType::R4_TYPE }}
|
||||
};
|
||||
|
||||
std::ostream &vortex::operator<<(std::ostream &os, Instr &instr) {
|
||||
|
@ -50,6 +57,7 @@ Decoder::Decoder(const ArchDef &arch) {
|
|||
inst_s_ = arch.getWordSize() * 8;
|
||||
opcode_s_ = 7;
|
||||
reg_s_ = 5;
|
||||
func2_s_ = 2;
|
||||
func3_s_ = 3;
|
||||
mop_s_ = 3;
|
||||
vmask_s_ = 1;
|
||||
|
@ -60,6 +68,8 @@ Decoder::Decoder(const ArchDef &arch) {
|
|||
shift_rs1_ = opcode_s_ + reg_s_ + func3_s_;
|
||||
shift_rs2_ = opcode_s_ + reg_s_ + func3_s_ + reg_s_;
|
||||
shift_func7_ = opcode_s_ + reg_s_ + func3_s_ + reg_s_ + reg_s_;
|
||||
shift_func2_ = opcode_s_ + reg_s_ + func3_s_ + reg_s_ + reg_s_;
|
||||
shift_rs3_ = opcode_s_ + reg_s_ + func3_s_ + reg_s_ + reg_s_ + func2_s_;
|
||||
shift_j_u_immed_ = opcode_s_ + reg_s_;
|
||||
shift_s_b_immed_ = opcode_s_ + reg_s_ + func3_s_ + reg_s_ + reg_s_;
|
||||
shift_i_immed_ = opcode_s_ + reg_s_ + func3_s_ + reg_s_;
|
||||
|
@ -71,6 +81,7 @@ Decoder::Decoder(const ArchDef &arch) {
|
|||
shift_vset_ = opcode_s_ + reg_s_ + func3_s_ + reg_s_ + reg_s_ + 6;
|
||||
|
||||
reg_mask_ = 0x1f;
|
||||
func2_mask_ = 0x2;
|
||||
func3_mask_ = 0x7;
|
||||
func6_mask_ = 0x3f;
|
||||
func7_mask_ = 0x7f;
|
||||
|
@ -96,13 +107,21 @@ std::shared_ptr<Instr> Decoder::decode(const std::vector<Byte> &v, Size &idx, tr
|
|||
Word imeed, dest_bits, imm_bits, bit_11, bits_4_1, bit_10_5,
|
||||
bit_12, bits_19_12, bits_10_1, bit_20, unordered, func3;
|
||||
|
||||
InstType curInstType = sc_instTable.at(op).iType; // get current inst type
|
||||
if (op == Opcode::FL || op == Opcode::FS) { // need to find out whether it is vector or floating point inst
|
||||
Word width_bits = (code >> shift_func3_) & func3_mask_;
|
||||
if ((width_bits == 0x1) || (width_bits == 0x2)
|
||||
|| (width_bits == 0x3) || (width_bits == 0x4)) {
|
||||
curInstType = (op == Opcode::FL)? InstType::I_TYPE : InstType::S_TYPE;
|
||||
}
|
||||
}
|
||||
|
||||
// std::cout << "op: " << std::hex << op << " what " << sc_instTable[op].iType << "\n";
|
||||
switch (sc_instTable.at(op).iType) {
|
||||
switch (curInstType) {
|
||||
case InstType::N_TYPE:
|
||||
break;
|
||||
|
||||
case InstType::R_TYPE:
|
||||
instr->setPred((code >> shift_rs1_) & reg_mask_);
|
||||
instr->setDestReg((code >> shift_rd_) & reg_mask_);
|
||||
instr->setSrcReg((code >> shift_rs1_) & reg_mask_);
|
||||
instr->setSrcReg((code >> shift_rs2_) & reg_mask_);
|
||||
|
@ -122,7 +141,7 @@ std::shared_ptr<Instr> Decoder::decode(const std::vector<Byte> &v, Size &idx, tr
|
|||
func3 = (code >> shift_func3_) & func3_mask_;
|
||||
instr->setFunc3(func3);
|
||||
|
||||
if ((func3 == 5) && (op != L_INST)) {
|
||||
if ((func3 == 5) && (op != L_INST) && (op != FL)) {
|
||||
// std::cout << "func7: " << func7 << "\n";
|
||||
instr->setSrcImm(signExt(((code >> shift_rs2_) & reg_mask_), 5, reg_mask_));
|
||||
} else {
|
||||
|
@ -282,6 +301,20 @@ std::shared_ptr<Instr> Decoder::decode(const std::vector<Byte> &v, Size &idx, tr
|
|||
std::abort();
|
||||
}
|
||||
break;
|
||||
case R4_TYPE:
|
||||
// RT: add R4_TYPE decoder
|
||||
instr->setDestReg((code >> shift_rd_) & reg_mask_);
|
||||
instr->setSrcReg((code >> shift_rs1_) & reg_mask_);
|
||||
instr->setSrcReg((code >> shift_rs2_) & reg_mask_);
|
||||
instr->setSrcReg((code >> shift_rs3_) & reg_mask_);
|
||||
instr->setFunc3((code >> shift_func3_) & func3_mask_);
|
||||
|
||||
trace_inst->valid_inst = true;
|
||||
trace_inst->rs1 = ((code >> shift_rs1_) & reg_mask_);
|
||||
trace_inst->rs2 = ((code >> shift_rs2_) & reg_mask_);
|
||||
trace_inst->rs3 = ((code >> shift_rs3_) & reg_mask_);
|
||||
trace_inst->rd = ((code >> shift_rd_) & reg_mask_);
|
||||
break;
|
||||
default:
|
||||
std::cout << "Unrecognized argument class in word decoder.\n";
|
||||
std::abort();
|
||||
|
|
|
@ -21,11 +21,14 @@ private:
|
|||
Word inst_s_;
|
||||
Word opcode_s_;
|
||||
Word reg_s_;
|
||||
Word func2_s_;
|
||||
Word func3_s_;
|
||||
Word shift_opcode_;
|
||||
Word shift_rd_;
|
||||
Word shift_rs1_;
|
||||
Word shift_rs2_;
|
||||
Word shift_rs3_;
|
||||
Word shift_func2_;
|
||||
Word shift_func3_;
|
||||
Word shift_func7_;
|
||||
Word shift_j_u_immed_;
|
||||
|
@ -33,6 +36,7 @@ private:
|
|||
Word shift_i_immed_;
|
||||
|
||||
Word reg_mask_;
|
||||
Word func2_mask_;
|
||||
Word func3_mask_;
|
||||
Word func6_mask_;
|
||||
Word func7_mask_;
|
||||
|
|
986
simX/execute.cpp
986
simX/execute.cpp
File diff suppressed because it is too large
Load diff
35
simX/instr.h
35
simX/instr.h
|
@ -25,6 +25,14 @@ enum Opcode {
|
|||
VSET_ARITH= 0x57,
|
||||
VL = 0x7,
|
||||
VS = 0x27,
|
||||
// F-Extension
|
||||
FL = 0x7,
|
||||
FS = 0x27,
|
||||
FCI = 0x53,
|
||||
FMADD = 0x43,
|
||||
FMSUB = 0x47,
|
||||
FMNMSUB = 0x4b,
|
||||
FMNMADD = 0x4f,
|
||||
};
|
||||
|
||||
enum InstType {
|
||||
|
@ -35,25 +43,28 @@ enum InstType {
|
|||
B_TYPE,
|
||||
U_TYPE,
|
||||
J_TYPE,
|
||||
V_TYPE
|
||||
V_TYPE,
|
||||
R4_TYPE
|
||||
};
|
||||
|
||||
class Instr {
|
||||
public:
|
||||
Instr()
|
||||
: predicated_(false)
|
||||
: opcode_(Opcode::NOP)
|
||||
, nRsrc_(0)
|
||||
, nPsrc_(0)
|
||||
, hasImmSrc_(false)
|
||||
, hasRDest_(false)
|
||||
, hasPDest_(false)
|
||||
, func2_(0)
|
||||
, func3_(0)
|
||||
, func7_(0)
|
||||
{}
|
||||
|
||||
|
||||
friend std::ostream &operator<<(std::ostream &, Instr &);
|
||||
|
||||
/* Setters used to "craft" the instruction. */
|
||||
void setOpcode(Opcode opcode) { opcode_ = opcode; }
|
||||
void setPred(RegNum pReg) { predicated_ = true; pred_ = pReg; }
|
||||
void setDestReg(RegNum destReg) { hasRDest_ = true; rdest_ = destReg; }
|
||||
void setSrcReg(RegNum srcReg) { rsrc_[nRsrc_++] = srcReg; }
|
||||
void setFunc3(Word func3) { func3_ = func3; }
|
||||
|
@ -69,7 +80,6 @@ public:
|
|||
void setVsew(Word sew);
|
||||
void setVediv(Word ediv);
|
||||
void setFunc6(Word func6) { func6_ = func6; }
|
||||
void setPrivileged(bool privileged) { privileged_ = privileged; }
|
||||
|
||||
/* Getters used by encoders. */
|
||||
Opcode getOpcode() const { return opcode_; }
|
||||
|
@ -80,10 +90,6 @@ public:
|
|||
RegNum getRSrc(RegNum i) const { return rsrc_[i]; }
|
||||
bool hasRDest() const { return hasRDest_; }
|
||||
RegNum getRDest() const { return rdest_; }
|
||||
bool hasPDest() const { return hasPDest_; }
|
||||
RegNum getPDest() const { return pdest_; }
|
||||
bool hasPred() const { return predicated_; }
|
||||
RegNum getPred() const { return pred_; }
|
||||
bool hasImm() const { return hasImmSrc_; }
|
||||
Word getImm() const { return immsrc_; }
|
||||
bool getVsetImm() const { return vsetImm_; }
|
||||
|
@ -95,7 +101,6 @@ public:
|
|||
Word getVlmul() const { return vlmul_; }
|
||||
Word getVsew() const { return vsew_; }
|
||||
Word getVediv() const { return vediv_; }
|
||||
bool getPrivileged() const { return privileged_; }
|
||||
|
||||
private:
|
||||
|
||||
|
@ -104,20 +109,16 @@ private:
|
|||
};
|
||||
|
||||
Opcode opcode_;
|
||||
bool predicated_;
|
||||
RegNum pred_;
|
||||
int nRsrc_;
|
||||
int nPsrc_;
|
||||
RegNum rsrc_[MAX_REG_SOURCES];
|
||||
bool hasImmSrc_;
|
||||
bool hasRDest_;
|
||||
Word immsrc_;
|
||||
Word func2_;
|
||||
Word func3_;
|
||||
Word func7_;
|
||||
bool hasRDest_;
|
||||
bool hasPDest_;
|
||||
RegNum rsrc_[MAX_REG_SOURCES];
|
||||
RegNum rdest_;
|
||||
RegNum pdest_;
|
||||
bool privileged_;
|
||||
|
||||
//Vector
|
||||
bool vsetImm_;
|
||||
|
|
78
simX/main.cpp
Normal file
78
simX/main.cpp
Normal file
|
@ -0,0 +1,78 @@
|
|||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <fstream>
|
||||
#include <stdlib.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include "types.h"
|
||||
#include "core.h"
|
||||
#include "args.h"
|
||||
|
||||
using namespace vortex;
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
|
||||
std::string archString("rv32i");
|
||||
int num_cores(1);
|
||||
int num_warps(NUM_WARPS);
|
||||
int num_threads(NUM_THREADS);
|
||||
std::string imgFileName;
|
||||
bool showHelp(false);
|
||||
bool showStats(false);
|
||||
|
||||
/* Read the command line arguments. */
|
||||
CommandLineArgFlag fh("-h", "--help", "", showHelp);
|
||||
CommandLineArgSetter<std::string> fa("-a", "--arch", "", archString);
|
||||
CommandLineArgSetter<std::string> fi("-i", "--image", "", imgFileName);
|
||||
CommandLineArgSetter<int> fc("-c", "--cores", "", num_cores);
|
||||
CommandLineArgSetter<int> fw("-w", "--warps", "", num_warps);
|
||||
CommandLineArgSetter<int> ft("-t", "--threads", "", num_threads);
|
||||
CommandLineArgFlag fs("-s", "--stats", "", showStats);
|
||||
|
||||
CommandLineArg::readArgs(argc - 1, argv + 1);
|
||||
|
||||
if (showHelp || imgFileName.empty()) {
|
||||
std::cout << "Vortex emulator command line arguments:\n"
|
||||
" -i, --image <filename> Program RAM image\n"
|
||||
" -c, --cores <num> Number of cores\n"
|
||||
" -w, --warps <num> Number of warps\n"
|
||||
" -t, --threads <num> Number of threads\n"
|
||||
" -a, --arch <arch string> Architecture string\n"
|
||||
" -s, --stats Print stats on exit.\n";
|
||||
return 0;
|
||||
}
|
||||
|
||||
ArchDef arch(archString, num_cores, num_warps, num_threads);
|
||||
|
||||
Decoder decoder(arch);
|
||||
MemoryUnit mu(4096, arch.getWordSize(), true);
|
||||
|
||||
RAM old_ram;
|
||||
old_ram.loadHexImpl(imgFileName.c_str());
|
||||
mu.attach(old_ram, 0);
|
||||
|
||||
struct stat hello;
|
||||
fstat(0, &hello);
|
||||
|
||||
std::vector<std::shared_ptr<Core>> cores(num_cores);
|
||||
for (int i = 0; i < num_cores; ++i) {
|
||||
cores[i] = std::make_shared<Core>(arch, decoder, mu);
|
||||
}
|
||||
|
||||
bool running;
|
||||
|
||||
do {
|
||||
running = false;
|
||||
for (int i = 0; i < num_cores; ++i) {
|
||||
if (!cores[i]->running())
|
||||
continue;
|
||||
running = true;
|
||||
cores[i]->step();
|
||||
}
|
||||
} while (running);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -14,6 +14,7 @@ namespace vortex {
|
|||
// Encoder
|
||||
int rs1;
|
||||
int rs2;
|
||||
int rs3;
|
||||
int rd;
|
||||
|
||||
//Encoder
|
||||
|
|
|
@ -16,12 +16,8 @@ Warp::Warp(Core *core, Word id)
|
|||
, shadowPc_(0)
|
||||
, activeThreads_(0)
|
||||
, shadowActiveThreads_(0)
|
||||
, shadowReg_(core_->arch().getNumRegs())
|
||||
, shadowIReg_(core_->arch().getNumRegs())
|
||||
, VLEN_(1024)
|
||||
, interruptEnable_(true)
|
||||
, shadowInterruptEnable_(false)
|
||||
, supervisorMode_(true)
|
||||
, shadowSupervisorMode_(false)
|
||||
, spawned_(false)
|
||||
, steps_(0)
|
||||
, insts_(0)
|
||||
|
@ -31,9 +27,9 @@ Warp::Warp(Core *core, Word id)
|
|||
/* Build the register file. */
|
||||
Word regNum(0);
|
||||
for (Word j = 0; j < core_->arch().getNumThreads(); ++j) {
|
||||
regFile_.push_back(std::vector<Reg<Word>>(0));
|
||||
iRegFile_.push_back(std::vector<Reg<Word>>(0));
|
||||
for (Word i = 0; i < core_->arch().getNumRegs(); ++i) {
|
||||
regFile_[j].push_back(Reg<Word>(id, regNum++));
|
||||
iRegFile_[j].push_back(Reg<Word>(id, regNum++));
|
||||
}
|
||||
|
||||
bool act = false;
|
||||
|
@ -44,11 +40,11 @@ Warp::Warp(Core *core, Word id)
|
|||
}
|
||||
|
||||
for (Word i = 0; i < (1 << 12); i++) {
|
||||
csrs_.push_back(Reg<uint16_t>(id, regNum++));
|
||||
csrs_.push_back(Reg<uint32_t>(id, regNum++));
|
||||
}
|
||||
|
||||
/* Set initial register contents. */
|
||||
regFile_[0][0] = (core_->arch().getNumThreads() << (core_->arch().getWordSize() * 8 / 2)) | id;
|
||||
iRegFile_[0][0] = (core_->arch().getNumThreads() << (core_->arch().getWordSize() * 8 / 2)) | id;
|
||||
}
|
||||
|
||||
void Warp::step(trace_inst_t *trace_inst) {
|
||||
|
@ -73,7 +69,7 @@ void Warp::step(trace_inst_t *trace_inst) {
|
|||
|
||||
unsigned fetchSize = 4;
|
||||
fetchBuffer.resize(fetchSize);
|
||||
Word fetched = core_->mem().fetch(pc_ + fetchPos, supervisorMode_);
|
||||
Word fetched = core_->mem().fetch(pc_ + fetchPos, 0);
|
||||
writeWord(fetchBuffer, fetchPos, fetchSize, fetched);
|
||||
|
||||
decPos = 0;
|
||||
|
@ -87,11 +83,11 @@ void Warp::step(trace_inst_t *trace_inst) {
|
|||
|
||||
// At Debug Level 3, print debug info after each instruction.
|
||||
D(3, "Register state:");
|
||||
for (unsigned i = 0; i < regFile_[0].size(); ++i) {
|
||||
for (unsigned i = 0; i < iRegFile_[0].size(); ++i) {
|
||||
D_RAW(" %r" << std::setfill('0') << std::setw(2) << std::dec << i << ':');
|
||||
for (unsigned j = 0; j < (activeThreads_); ++j)
|
||||
D_RAW(' ' << std::setfill('0') << std::setw(8) << std::hex << regFile_[j][i] << std::setfill(' ') << ' ');
|
||||
D_RAW('(' << shadowReg_[i] << ')' << std::endl);
|
||||
D_RAW(' ' << std::setfill('0') << std::setw(8) << std::hex << iRegFile_[j][i] << std::setfill(' ') << ' ');
|
||||
D_RAW('(' << shadowIReg_[i] << ')' << std::endl);
|
||||
}
|
||||
|
||||
DPH(3, "Thread mask:");
|
||||
|
@ -100,31 +96,6 @@ void Warp::step(trace_inst_t *trace_inst) {
|
|||
DPN(3, "\n");
|
||||
}
|
||||
|
||||
bool Warp::interrupt(Word r0) {
|
||||
if (!interruptEnable_)
|
||||
return false;
|
||||
|
||||
shadowActiveThreads_ = activeThreads_;
|
||||
shadowTmask_ = tmask_;
|
||||
shadowInterruptEnable_ = interruptEnable_; /* For traps. */
|
||||
shadowSupervisorMode_ = supervisorMode_;
|
||||
|
||||
for (Word i = 0; i < regFile_[0].size(); ++i)
|
||||
shadowReg_[i] = regFile_[0][i];
|
||||
|
||||
for (Word i = 0; i < regFile_.size(); ++i)
|
||||
tmask_[i] = 1;
|
||||
|
||||
shadowPc_ = pc_;
|
||||
activeThreads_ = 1;
|
||||
interruptEnable_ = false;
|
||||
supervisorMode_ = true;
|
||||
regFile_[0][0] = r0;
|
||||
pc_ = core_->interruptEntry();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Warp::printStats() const {
|
||||
std::cout << "Steps : " << steps_ << std::endl
|
||||
<< "Insts : " << insts_ << std::endl
|
||||
|
|
22
simX/warp.h
22
simX/warp.h
|
@ -89,8 +89,6 @@ public:
|
|||
|
||||
void step(trace_inst_t *);
|
||||
|
||||
bool interrupt(Word r0);
|
||||
|
||||
bool running() const {
|
||||
return (activeThreads_ != 0);
|
||||
}
|
||||
|
@ -125,14 +123,6 @@ public:
|
|||
spawned_ = spawned;
|
||||
}
|
||||
|
||||
void setSupervisorMode(bool supervisorMode) {
|
||||
supervisorMode_ = supervisorMode;
|
||||
}
|
||||
|
||||
bool getSupervisorMode() const {
|
||||
return supervisorMode_;
|
||||
}
|
||||
|
||||
void setTmask(size_t index, bool value) {
|
||||
tmask_[index] = value;
|
||||
}
|
||||
|
@ -156,14 +146,16 @@ private:
|
|||
Word shadowPc_;
|
||||
Size activeThreads_;
|
||||
Size shadowActiveThreads_;
|
||||
std::vector<std::vector<Reg<Word>>> regFile_;
|
||||
std::vector<Reg<uint16_t>> csrs_;
|
||||
std::vector<std::vector<Reg<Word>>> iRegFile_;
|
||||
std::vector<std::vector<Reg<Word>>> fRegFile_;
|
||||
std::vector<Reg<uint32_t>> csrs_;
|
||||
|
||||
std::vector<bool> tmask_;
|
||||
std::vector<bool> shadowTmask_;
|
||||
std::stack<DomStackEntry> domStack_;
|
||||
|
||||
std::vector<Word> shadowReg_;
|
||||
std::vector<Word> shadowIReg_;
|
||||
std::vector<Word> shadowFReg_;
|
||||
|
||||
struct vtype vtype_; // both of them are XLEN WIDE
|
||||
int vl_; // both of them are XLEN WIDE
|
||||
|
@ -171,10 +163,6 @@ private:
|
|||
|
||||
std::vector<std::vector<Reg<char *>>> vregFile_; // 32 vector registers
|
||||
|
||||
bool interruptEnable_;
|
||||
bool shadowInterruptEnable_;
|
||||
bool supervisorMode_;
|
||||
bool shadowSupervisorMode_;
|
||||
bool spawned_;
|
||||
|
||||
unsigned long steps_;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue