RISCV_CPUComponent.cc Source File
Back to the index.
Go to the documentation of this file.
67 if (!
cpu->SetVariableValue(
"model",
"\"" +
settings[
"model"] +
"\""))
91 " can not have bit 0 set!\n");
111 ss.flags(std::ios::hex);
112 ss <<
" pc = 0x" << std::setfill(
'0') << std::setw(16) << (uint32_t)
m_pc;
116 ss <<
" <" <<
symbol <<
">";
120 ss << std::setfill(
' ') << std::setw(4) << RISCV_regnames[i]
121 <<
" = 0x" << std::setfill(
'0') << std::setw(16) << m_x[i];
161 return instr_ToBeTranslated;
200 int aa = iwords[0] & 3, bbb = (iwords[0] >> 2) & 7;
208 if (iwords[0] & 0x20) {
210 if (iwords[0] & 0x40) {
211 int nnn = (iwords[0] >> 12) & 7;
215 result.push_back(
"too many parcels in instruction");
223 int instructionParcelsSuccessfullyRead = 1;
224 for (
int i = 1; i < nparcels; ++i) {
227 instructionParcelsSuccessfullyRead ++;
230 if (instructionParcelsSuccessfullyRead != nparcels)
235 result.push_back(
"instruction could not be read");
240 ssHex.flags(std::ios::hex);
241 for (
int i = nparcels-1; i >= 0; --i)
242 ssHex << std::setfill(
'0') << std::setw(4) << (uint32_t) iwords[i];
244 result.push_back(ssHex.str());
247 stringstream ssOpcode;
249 stringstream ssComments;
258 int opcode = iwords[0] & 0x7f;
259 int rd = (iwords[0] >> 7) & 31;
260 uint64_t requiredExtension = 0;
267 if (opcode == 0x6f) {
269 int32_t simm = ((iwords[1] & 0x8000) << 5);
270 simm |= ((iwords[1] & 0x7fe0) >> 4);
271 simm |= ((iwords[1] & 0x0010) << 7);
272 simm |= ((iwords[1] & 0x000f) << 16);
273 simm |= ((iwords[0] & 0xf000) << 0);
276 ssOpcode << (rd ?
"jal" :
"j");
278 ssArgs << RISCV_regnames[rd] <<
",";
279 uint64_t
addr = vaddr + simm;
280 ssArgs.flags(std::ios::hex | std::ios::showbase);
281 ssArgs << std::setfill(
'0') <<
addr;
284 ssArgs <<
" <" +
symbol +
">";
293 ssOpcode <<
"unknown main opcode 0x";
294 ssOpcode.flags(std::ios::hex);
295 ssOpcode << std::setfill(
'0') << std::setw(2) << (int)opcode;
299 result.push_back(ssOpcode.str());
300 result.push_back(ssArgs.str());
302 string comments = ssComments.str();
303 if (comments.length() > 0)
304 result.push_back(comments);
306 if ((m_extensions & requiredExtension) != requiredExtension) {
307 if (comments.length() == 0)
308 result.push_back(
"");
310 result.push_back(
"; extension not implemented by this CPU");
313 return sizeof(uint16_t) * nparcels;
319 if (attributeName ==
"description")
320 return "RISC-V processor.";
356 void RISCV_CPUComponent::Translate(uint16_t iwords[],
int nparcels,
struct DyntransIC*
ic)
361 unsigned int opcode = iwords[0];
363 if (
ic->f == NULL && ui != NULL) {
365 ss.flags(std::ios::hex);
366 ss <<
"unimplemented opcode 0x" << opcode;
376 cpu->DyntransToBeTranslatedBegin(
ic);
379 if (
cpu->DyntransReadInstruction(iwords[0])) {
381 int aa = iwords[0] & 3, bbb = (iwords[0] >> 2) & 7;
387 if (iwords[0] & 0x20) {
389 if (iwords[0] & 0x40) {
390 int nnn = (iwords[0] >> 12) & 7;
394 UI* ui =
cpu->GetUI();
403 int instructionParcelsSuccessfullyRead = 1;
404 for (
int i = 1; i < nparcels; ++i) {
405 if (
cpu->DyntransReadInstruction(iwords[i],
sizeof(iwords[0]) * i))
406 instructionParcelsSuccessfullyRead ++;
409 if (instructionParcelsSuccessfullyRead == nparcels) {
410 cpu->Translate(iwords, nparcels,
ic);
412 UI* ui =
cpu->GetUI();
417 cpu->DyntransToBeTranslatedDone(
ic);
428 static void Test_RISCV_CPUComponent_Create()
438 static void Test_RISCV_CPUComponent_Disassembly_Basic()
443 vector<string> result;
445 unsigned char instruction[
sizeof(uint32_t) * 2];
448 instruction[0] = 0x00;
449 instruction[1] = 0x30;
450 instruction[2] = 0x68;
451 instruction[3] = 0x8c;
453 instruction[4] = 0x01;
454 instruction[5] = 0x23;
455 instruction[6] = 0x34;
456 instruction[7] = 0x45;
458 len =
cpu->DisassembleInstruction(0x12345678,
sizeof(instruction), instruction, result);
467 static GXemul SimpleMachine()
478 static void Test_RISCV_CPUComponent_Execute_mov()
480 GXemul gxemul = SimpleMachine();
489 cpu->SetVariableValue(
"pc",
"0x3fe00048");
490 cpu->SetVariableValue(
"r4",
"0x1234");
495 UnitTest::Assert(
"pc should have increased",
cpu->GetVariable(
"pc")->ToInteger(), 0x3fe0004c);
498 cpu->SetVariableValue(
"r4",
"0x12345");
503 UnitTest::Assert(
"pc should have increased again",
cpu->GetVariable(
"pc")->ToInteger(), 0x3fe00050);
504 UnitTest::Assert(
"r4 should have been modified again",
cpu->GetVariable(
"r4")->ToInteger(), 6);
507 static void Test_RISCV_CPUComponent_Execute_b()
509 GXemul gxemul = SimpleMachine();
516 cpu->SetVariableValue(
"pc",
"0x3fe00004");
521 UnitTest::Assert(
"pc should have changed",
cpu->GetVariable(
"pc")->ToInteger(), 0x3fe006c4);
523 cpu->SetVariableValue(
"pc",
"0x3fe00004");
528 UnitTest::Assert(
"pc should have changed again",
cpu->GetVariable(
"pc")->ToInteger(), 0x3fe006c4);
531 static void Test_RISCV_CPUComponent_Execute_lda_with_offset()
533 GXemul gxemul = SimpleMachine();
540 cpu->SetVariableValue(
"pc",
"0x3fe00010");
547 static void Test_RISCV_CPUComponent_Execute_lda_with_displacement()
549 GXemul gxemul = SimpleMachine();
558 cpu->SetVariableValue(
"pc",
"0x3fe00010");
568 UNITTEST(Test_RISCV_CPUComponent_Create);
571 UNITTEST(Test_RISCV_CPUComponent_Disassembly_Basic);
573 UNITTEST(Test_RISCV_CPUComponent_Execute_mov);
574 UNITTEST(Test_RISCV_CPUComponent_Execute_b);
575 UNITTEST(Test_RISCV_CPUComponent_Execute_lda_with_offset);
576 UNITTEST(Test_RISCV_CPUComponent_Execute_lda_with_displacement);
RISCV_CPUComponent()
Constructs a RISCV_CPUComponent.
static bool GetCreationArgOverrides(ComponentCreationSettings &settings, const ComponentCreateArgs &createArgs)
Get override arguments for component creation.
bool AddVariable(const string &name, T *variablePointer)
Adds a state variable of type T to the Component.
virtual void(*)(CPUDyntransComponent *, DyntransIC *) GetDyntransToBeTranslated()
SymbolRegistry & GetSymbolRegistry()
Gets a reference to the CPU's symbol registry.
virtual bool FunctionTraceReturnImpl(int64_t &retval)
CommandInterpreter & GetCommandInterpreter()
Gets a reference to the CommandInterpreter.
#define RISCV_MAX_PARCELS
StateVariables make up the persistent state of Component objects.
virtual bool PreRunCheckForComponent(GXemul *gxemul)
Checks the state of this component, before starting execution.
virtual bool PreRunCheckForComponent(GXemul *gxemul)
Checks the state of this component, before starting execution.
virtual int FunctionTraceArgumentCount()
#define UNITTESTS(class)
Helper for unit test case execution.
UI * GetUI()
Gets an UI reference for outputting debug messages during runtime.
A base-class for processors Component implementations that use dynamic translation.
refcount_ptr< Component > GetRootComponent()
Gets a pointer to the root configuration component.
#define UNITTEST(functionname)
Helper for unit test case execution.
Base class for a User Interface.
virtual int GetDyntransICshift() const
static void Assert(const string &strFailMessage, bool condition)
Asserts that a boolean condition is correct.
virtual bool WriteData(const uint8_t &data, Endianness endianness=BigEndian)=0
Writes 8-bit data to the currently selected address.
void SetRunState(RunState newState)
Sets the RunState.
virtual int64_t FunctionTraceArgument(int n)
virtual void ShowDebugMessage(const string &msg)=0
Shows a debug message.
struct arm_instr_call * ic
void Execute(const int longestTotalRun=100000)
Run the emulation for "a while".
string LookupAddress(uint64_t vaddr, bool allowOffset) const
Looks up an address.
const refcount_ptr< Component > LookupPath(string path) const
Looks up a path from this Component, and returns a pointer to the found Component,...
static refcount_ptr< Component > CreateComponent(const string &componentNameAndOptionalArgs, GXemul *gxemul=NULL)
Creates a component given a short component name.
virtual void AddressSelect(uint64_t address)=0
Place an address on the bus.
#define DYNTRANS_INSTR_HEAD(class)
DYNTRANS_INSTR(RISCV_CPUComponent, ToBeTranslated)
A Component representing a RISC-V processor.
bool RunCommand(const string &command, bool *pSuccess=NULL)
Runs a command, given as a string.
map< string, string > ComponentCreationSettings
virtual void ShowRegisters(GXemul *gxemul, const vector< string > &arguments) const
static string GetAttribute(const string &attributeName)
virtual bool CheckVariableWrite(StateVariable &var, const string &oldValue)
Checks whether a write to a variable is OK.
UI * GetUI()
Gets a pointer to the GXemul instance' active UI.
virtual uint64_t PCtoInstructionAddress(uint64_t pc)
Convert PC value to instuction address.
virtual void ResetState()
Resets the state variables of this component.
virtual bool ReadData(uint8_t &data, Endianness endianness)
Reads 8-bit data from the currently selected address.
virtual bool CheckVariableWrite(StateVariable &var, const string &oldValue)
Checks whether a write to a variable is OK.
#define RISCV_EXTENSION_I
virtual CPUComponent * AsCPUComponent()
Returns the component's CPUComponent interface.
An interface for implementing components that read/write data via an address bus.
virtual size_t DisassembleInstruction(uint64_t vaddr, vector< string > &result)
Disassembles an instruction into readable strings.
static string GetAttribute(const string &attributeName)
Creates a Component.
virtual void ResetState()
Resets the state variables of this component.
virtual bool VirtualToPhysical(uint64_t vaddr, uint64_t &paddr, bool &writable)
Virtual to physical address translation (MMU).
virtual void AddressSelect(uint64_t address)
Place an address on the bus.
static refcount_ptr< Component > Create(const ComponentCreateArgs &args)
Creates a RISCV_CPUComponent.
A base-class for processors Component implementations.
Generated on Tue Aug 25 2020 19:25:06 for GXemul by
1.8.18