summaryrefslogtreecommitdiff
path: root/arch/mips
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips')
-rw-r--r--arch/mips/isa/decoder.isa16
-rw-r--r--arch/mips/isa/formats/branch.isa4
-rw-r--r--arch/mips/isa/formats/noop.isa4
-rw-r--r--arch/mips/isa_traits.hh100
-rw-r--r--arch/mips/linux_process.cc3
-rw-r--r--arch/mips/process.cc120
-rw-r--r--arch/mips/process.hh27
7 files changed, 199 insertions, 75 deletions
diff --git a/arch/mips/isa/decoder.isa b/arch/mips/isa/decoder.isa
index ac97241ed..93e7238f8 100644
--- a/arch/mips/isa/decoder.isa
+++ b/arch/mips/isa/decoder.isa
@@ -30,11 +30,17 @@ decode OPCODE_HI default Unknown::unknown() {
//Table A-3 Note: "1. Specific encodings of the rt, rd, and sa fields
//are used to distinguish among the SLL, NOP, SSNOP and EHB functions."
- 0x0: decode RS {
- 0x0: sll({{ Rd = Rt.uw << SA; }});
- //0x0:nop({{ ; }}); //really sll r0,r0,0
- // 0x1:ssnop({{ ; }});//really sll r0,r0,1
- // 0x3:ehb({{ ; }}); //really sll r0,r0,3
+ 0x0: decode RS {
+ 0x0: decode RT {
+ 0x0: decode RD default Nop::nop() {
+ 0x0: decode SA {
+ 0x1: ssnop({{ ; }}); //really sll r0,r0,1
+ 0x3: ehb({{ ; }}); //really sll r0,r0,3
+ }
+ }
+ }
+
+ default: sll({{ Rd = Rt.uw << SA; }});
}
0x2: decode SRL {
diff --git a/arch/mips/isa/formats/branch.isa b/arch/mips/isa/formats/branch.isa
index 0d2ad7855..ce84f4b51 100644
--- a/arch/mips/isa/formats/branch.isa
+++ b/arch/mips/isa/formats/branch.isa
@@ -265,8 +265,6 @@ def format Branch(code,*flags) {{
code += ' NNPC = NNPC;\n'
code += '} \n'
- code += 'cout << hex << "NPC: " << NPC << " + " << disp << " = " << NNPC << endl;'
-
iop = InstObjParams(name, Name, 'Branch', CodeBlock(code),
('IsDirectControl', 'IsCondControl'))
@@ -305,8 +303,6 @@ def format Jump(code,*flags) {{
if strlen > 1 and name[1:] == 'al':
code = 'r31 = NNPC;\n' + code
- #code += 'if(NNPC == 0x80000638) { NNPC = r31; cout << "SKIPPING JUMP TO SIM_GET_MEM_CONF" << endl;}'
- #code += 'target = NNPC;'
iop = InstObjParams(name, Name, 'Jump', CodeBlock(code),\
('IsIndirectControl', 'IsUncondControl'))
diff --git a/arch/mips/isa/formats/noop.isa b/arch/mips/isa/formats/noop.isa
index d35179005..2aa4816e3 100644
--- a/arch/mips/isa/formats/noop.isa
+++ b/arch/mips/isa/formats/noop.isa
@@ -88,3 +88,7 @@ def format BasicOperateWithNopCheck(code, *opt_args) {{
exec_output = BasicExecute.subst(iop)
}};
+def format Nop() {{
+ decode_block = 'return new Nop(\"sll r0,r0,0\",machInst);\n'
+}};
+
diff --git a/arch/mips/isa_traits.hh b/arch/mips/isa_traits.hh
index 4850010d4..833d3cc63 100644
--- a/arch/mips/isa_traits.hh
+++ b/arch/mips/isa_traits.hh
@@ -96,46 +96,57 @@ namespace MipsISA
typedef uint64_t ExtMachInst;
typedef uint8_t RegIndex;
// typedef uint64_t Addr;
- enum {
- MemoryEnd = 0xffffffffffffffffULL,
-
- NumIntRegs = 32,
- NumFloatRegs = 32,
- NumMiscRegs = 258, //account for hi,lo regs
-
- MaxRegsOfAnyType = 32,
- // Static instruction parameters
- MaxInstSrcRegs = 3,
- MaxInstDestRegs = 2,
-
- // semantically meaningful register indices
- ZeroReg = 0, // architecturally meaningful
- // the rest of these depend on the ABI
- StackPointerReg = 30,
- GlobalPointerReg = 29,
- ProcedureValueReg = 27,
- ReturnAddressReg = 26,
- ReturnValueReg = 0,
- FramePointerReg = 15,
- ArgumentReg0 = 16,
- ArgumentReg1 = 17,
- ArgumentReg2 = 18,
- ArgumentReg3 = 19,
- ArgumentReg4 = 20,
- ArgumentReg5 = 21,
- SyscallNumReg = ReturnValueReg,
- SyscallPseudoReturnReg = ArgumentReg4,
- SyscallSuccessReg = 19,
- LogVMPageSize = 13, // 8K bytes
- VMPageSize = (1 << LogVMPageSize),
-
- BranchPredAddrShiftAmt = 2, // instructions are 4-byte aligned
-
- WordBytes = 4,
- HalfwordBytes = 2,
- ByteBytes = 1,
- DepNA = 0,
- };
+
+ // Constants Related to the number of registers
+
+ const int NumIntArchRegs = 32;
+ const int NumPALShadowRegs = 8;
+ const int NumFloatArchRegs = 32;
+ // @todo: Figure out what this number really should be.
+ const int NumMiscArchRegs = 32;
+
+ const int NumIntRegs = NumIntArchRegs + NumPALShadowRegs;
+ const int NumFloatRegs = NumFloatArchRegs;
+ const int NumMiscRegs = NumMiscArchRegs;
+
+ const int TotalNumRegs = NumIntRegs + NumFloatRegs +
+ NumMiscRegs + 0/*NumInternalProcRegs*/;
+
+ const int TotalDataRegs = NumIntRegs + NumFloatRegs;
+
+ // Static instruction parameters
+ const int MaxInstSrcRegs = 3;
+ const int MaxInstDestRegs = 2;
+
+ // semantically meaningful register indices
+ const int ZeroReg = 31; // architecturally meaningful
+ // the rest of these depend on the ABI
+ const int StackPointerReg = 30;
+ const int GlobalPointerReg = 29;
+ const int ProcedureValueReg = 27;
+ const int ReturnAddressReg = 26;
+ const int ReturnValueReg = 0;
+ const int FramePointerReg = 15;
+ const int ArgumentReg0 = 16;
+ const int ArgumentReg1 = 17;
+ const int ArgumentReg2 = 18;
+ const int ArgumentReg3 = 19;
+ const int ArgumentReg4 = 20;
+ const int ArgumentReg5 = 21;
+ const int SyscallNumReg = ReturnValueReg;
+ const int SyscallPseudoReturnReg = ArgumentReg4;
+ const int SyscallSuccessReg = 19;
+
+ const int LogVMPageSize = 13; // 8K bytes
+ const int VMPageSize = (1 << LogVMPageSize);
+
+ const int BranchPredAddrShiftAmt = 2; // instructions are 4-byte aligned
+
+ const int MachineBytes = 4;
+ const int WordBytes = 4;
+ const int HalfwordBytes = 2;
+ const int ByteBytes = 1;
+
// These enumerate all the registers for dependence tracking.
enum DependenceTags {
@@ -402,15 +413,6 @@ extern const Addr PageOffset;
};
#endif
- enum {
- TotalNumRegs =
- NumIntRegs + NumFloatRegs + NumMiscRegs + NumInternalProcRegs
- };
-
- enum {
- TotalDataRegs = NumIntRegs + NumFloatRegs
- };
-
typedef union {
IntReg intreg;
FloatReg fpreg;
diff --git a/arch/mips/linux_process.cc b/arch/mips/linux_process.cc
index 318b7934a..93706d8aa 100644
--- a/arch/mips/linux_process.cc
+++ b/arch/mips/linux_process.cc
@@ -571,7 +571,8 @@ MipsLinuxProcess::MipsLinuxProcess(const std::string &name,
int stderr_fd,
std::vector<std::string> &argv,
std::vector<std::string> &envp)
- : LiveProcess(name, objFile, system, stdin_fd, stdout_fd, stderr_fd, argv, envp),
+ : MipsLiveProcess(name, objFile, system, stdin_fd, stdout_fd, stderr_fd,
+ argv, envp),
Num_Syscall_Descs(sizeof(syscallDescs) / sizeof(SyscallDesc))
{
//init_regs->intRegFile[0] = 0;
diff --git a/arch/mips/process.cc b/arch/mips/process.cc
index f63e668b5..a4ce3f5f1 100644
--- a/arch/mips/process.cc
+++ b/arch/mips/process.cc
@@ -26,27 +26,37 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include "arch/mips/isa_traits.hh"
#include "arch/mips/process.hh"
-#include "arch/mips/linux/process.hh"
+#include "arch/mips/linux_process.hh"
#include "base/loader/object_file.hh"
#include "base/misc.hh"
+#include "cpu/exec_context.hh"
+#include "sim/builder.hh"
+#include "sim/system.hh"
using namespace std;
+using namespace MipsISA;
-namespace MipsISA
-{
-LiveProcess *
-createProcess(const string &nm, ObjectFile * objFile, System * system,
- int stdin_fd, int stdout_fd, int stderr_fd,
- vector<string> &argv, vector<string> &envp)
+MipsLiveProcess *
+MipsLiveProcess::create(const std::string &nm, System *system, int stdin_fd,
+ int stdout_fd, int stderr_fd, std::string executable,
+ std::vector<std::string> &argv, std::vector<std::string> &envp)
{
- LiveProcess * process = NULL;
+ MipsLiveProcess *process = NULL;
+
+ ObjectFile *objFile = createObjectFile(executable);
+ if (objFile == NULL) {
+ fatal("Can't load object file %s", executable);
+ }
+
+
if (objFile->getArch() != ObjectFile::MIPS)
fatal("Object file does not match architecture.");
switch (objFile->getOpSys()) {
case ObjectFile::Linux:
- process = new MipsLinuxProcess(nm, objFile,system,
+ process = new MipsLinuxProcess(nm, objFile, system,
stdin_fd, stdout_fd, stderr_fd,
argv, envp);
break;
@@ -54,8 +64,98 @@ createProcess(const string &nm, ObjectFile * objFile, System * system,
default:
fatal("Unknown/unsupported operating system.");
}
+
+ if (process == NULL)
+ fatal("Unknown error creating process object.");
return process;
}
-} // namespace MipsISA
+MipsLiveProcess::MipsLiveProcess(const std::string &nm, ObjectFile *objFile,
+ System *_system, int stdin_fd, int stdout_fd, int stderr_fd,
+ std::vector<std::string> &argv, std::vector<std::string> &envp)
+ : LiveProcess(nm, objFile, _system, stdin_fd, stdout_fd, stderr_fd,
+ argv, envp)
+{
+
+ // XXX all the below need to be updated for SPARC - Ali
+ brk_point = objFile->dataBase() + objFile->dataSize() + objFile->bssSize();
+ brk_point = roundUp(brk_point, VMPageSize);
+
+ // Set up stack. On Alpha, stack goes below text section. This
+ // code should get moved to some architecture-specific spot.
+ stack_base = objFile->textBase() - (409600+4096);
+
+ // Set up region for mmaps. Tru64 seems to start just above 0 and
+ // grow up from there.
+ mmap_start = mmap_end = 0x10000;
+
+ // Set pointer for next thread stack. Reserve 8M for main stack.
+ next_thread_stack_base = stack_base - (8 * 1024 * 1024);
+
+}
+
+void
+MipsLiveProcess::startup()
+{
+ argsInit(MachineBytes, VMPageSize);
+}
+
+
+
+
+BEGIN_DECLARE_SIM_OBJECT_PARAMS(MipsLiveProcess)
+
+ VectorParam<string> cmd;
+ Param<string> executable;
+ Param<string> input;
+ Param<string> output;
+ VectorParam<string> env;
+ SimObjectParam<System *> system;
+
+END_DECLARE_SIM_OBJECT_PARAMS(MipsLiveProcess)
+
+
+BEGIN_INIT_SIM_OBJECT_PARAMS(MipsLiveProcess)
+
+ INIT_PARAM(cmd, "command line (executable plus arguments)"),
+ INIT_PARAM(executable, "executable (overrides cmd[0] if set)"),
+ INIT_PARAM(input, "filename for stdin (dflt: use sim stdin)"),
+ INIT_PARAM(output, "filename for stdout/stderr (dflt: use sim stdout)"),
+ INIT_PARAM(env, "environment settings"),
+ INIT_PARAM(system, "system")
+
+END_INIT_SIM_OBJECT_PARAMS(MipsLiveProcess)
+
+
+CREATE_SIM_OBJECT(MipsLiveProcess)
+{
+ string in = input;
+ string out = output;
+
+ // initialize file descriptors to default: same as simulator
+ int stdin_fd, stdout_fd, stderr_fd;
+
+ if (in == "stdin" || in == "cin")
+ stdin_fd = STDIN_FILENO;
+ else
+ stdin_fd = Process::openInputFile(input);
+
+ if (out == "stdout" || out == "cout")
+ stdout_fd = STDOUT_FILENO;
+ else if (out == "stderr" || out == "cerr")
+ stdout_fd = STDERR_FILENO;
+ else
+ stdout_fd = Process::openOutputFile(out);
+
+ stderr_fd = (stdout_fd != STDOUT_FILENO) ? stdout_fd : STDERR_FILENO;
+
+ return MipsLiveProcess::create(getInstanceName(), system,
+ stdin_fd, stdout_fd, stderr_fd,
+ (string)executable == "" ? cmd[0] : executable,
+ cmd, env);
+}
+
+
+REGISTER_SIM_OBJECT("MipsLiveProcess", MipsLiveProcess)
+
diff --git a/arch/mips/process.hh b/arch/mips/process.hh
index 8f5d74d96..2a13dc955 100644
--- a/arch/mips/process.hh
+++ b/arch/mips/process.hh
@@ -31,19 +31,34 @@
#include <string>
#include <vector>
+#include "sim/process.hh"
class LiveProcess;
class ObjectFile;
class System;
-namespace MipsISA
+class MipsLiveProcess : public LiveProcess
{
+ protected:
+ MipsLiveProcess(const std::string &nm, ObjectFile *objFile,
+ System *_system, int stdin_fd, int stdout_fd, int stderr_fd,
+ std::vector<std::string> &argv,
+ std::vector<std::string> &envp);
-LiveProcess *
-createProcess(const std::string &nm, ObjectFile * objFile,System * system,
- int stdin_fd, int stdout_fd, int stderr_fd,
- std::vector<std::string> &argv, std::vector<std::string> &envp);
+ void startup();
+
+ public:
+ // this function is used to create the LiveProcess object, since
+ // we can't tell which subclass of LiveProcess to use until we
+ // open and look at the object file.
+ static MipsLiveProcess *create(const std::string &nm,
+ System *_system,
+ int stdin_fd, int stdout_fd, int stderr_fd,
+ std::string executable,
+ std::vector<std::string> &argv,
+ std::vector<std::string> &envp);
+
+};
-} // namespace MipsISA
#endif // __MIPS_PROCESS_HH__