From 9900ac95b5c0e197f03e5efd8d9f840a643b32c6 Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Tue, 15 Sep 2009 05:30:08 -0700 Subject: [mq]: x86syscalls.patch --- src/arch/x86/linux/syscalls.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/linux/syscalls.cc b/src/arch/x86/linux/syscalls.cc index 4d7bca95c..5a425ed9a 100644 --- a/src/arch/x86/linux/syscalls.cc +++ b/src/arch/x86/linux/syscalls.cc @@ -508,12 +508,12 @@ const int X86_64LinuxProcess::numSyscalls = SyscallDesc I386LinuxProcess::syscallDescs[] = { /* 0 */ SyscallDesc("restart_syscall", unimplementedFunc), - /* 1 */ SyscallDesc("exit", unimplementedFunc), + /* 1 */ SyscallDesc("exit", exitFunc), /* 2 */ SyscallDesc("fork", unimplementedFunc), - /* 3 */ SyscallDesc("read", unimplementedFunc), + /* 3 */ SyscallDesc("read", readFunc), /* 4 */ SyscallDesc("write", writeFunc), - /* 5 */ SyscallDesc("open", openFunc), - /* 6 */ SyscallDesc("close", unimplementedFunc), + /* 5 */ SyscallDesc("open", openFunc), + /* 6 */ SyscallDesc("close", closeFunc), /* 7 */ SyscallDesc("waitpid", unimplementedFunc), /* 8 */ SyscallDesc("creat", unimplementedFunc), /* 9 */ SyscallDesc("link", unimplementedFunc), -- cgit v1.2.3 From 0f569b4d9dd5b7be253d45c22e9c40f615e90ecd Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Tue, 15 Sep 2009 05:48:20 -0700 Subject: SPARC: Make resTemp in udivcc wide enough to hold all the bits we need. --- src/arch/sparc/isa/decoder.isa | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/arch') diff --git a/src/arch/sparc/isa/decoder.isa b/src/arch/sparc/isa/decoder.isa index e34ca033f..ce5e34ff0 100644 --- a/src/arch/sparc/isa/decoder.isa +++ b/src/arch/sparc/isa/decoder.isa @@ -226,7 +226,8 @@ decode OP default Unknown::unknown() if(Rs2_or_imm13.udw == 0) fault = new DivisionByZero; else Rd = Rs1.udw / Rs2_or_imm13.udw;}}); 0x1E: IntOpCcRes::udivcc({{ - uint32_t resTemp, val2 = Rs2_or_imm13.udw; + uint64_t resTemp; + uint32_t val2 = Rs2_or_imm13.udw; int32_t overflow = 0; if(val2 == 0) fault = new DivisionByZero; else -- cgit v1.2.3 From 9b8e61beb38af081454ffd5e06d14458080b98e0 Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Tue, 15 Sep 2009 22:36:47 -0700 Subject: Syscalls: Implement sysinfo() syscall. --- src/arch/alpha/linux/linux.hh | 15 +++++++++++++++ src/arch/alpha/linux/process.cc | 2 +- src/arch/arm/linux/linux.hh | 15 +++++++++++++++ src/arch/arm/linux/process.cc | 2 +- src/arch/mips/linux/linux.hh | 16 ++++++++++++++++ src/arch/mips/linux/process.cc | 2 +- src/arch/sparc/linux/linux.hh | 32 ++++++++++++++++++++++++++++++++ src/arch/sparc/linux/syscalls.cc | 4 ++-- src/arch/x86/linux/linux.hh | 31 +++++++++++++++++++++++++++++++ src/arch/x86/linux/syscalls.cc | 4 ++-- 10 files changed, 116 insertions(+), 7 deletions(-) (limited to 'src/arch') diff --git a/src/arch/alpha/linux/linux.hh b/src/arch/alpha/linux/linux.hh index c622c5ef1..e9947644c 100644 --- a/src/arch/alpha/linux/linux.hh +++ b/src/arch/alpha/linux/linux.hh @@ -125,6 +125,21 @@ class AlphaLinux : public Linux TGT_RLIMIT_MEMLOCK = 9, TGT_RLIMIT_LOCKS = 10 }; + + typedef struct { + int64_t uptime; /* Seconds since boot */ + uint64_t loads[3]; /* 1, 5, and 15 minute load averages */ + uint64_t totalram; /* Total usable main memory size */ + uint64_t freeram; /* Available memory size */ + uint64_t sharedram; /* Amount of shared memory */ + uint64_t bufferram; /* Memory used by buffers */ + uint64_t totalswap; /* Total swap space size */ + uint64_t freeswap; /* swap space still available */ + uint16_t procs; /* Number of current processes */ + uint64_t totalhigh; /* Total high memory size */ + uint64_t freehigh; /* Available high memory size */ + uint64_t mem_unit; /* Memory unit size in bytes */ + } tgt_sysinfo; }; #endif // __ALPHA_ALPHA_LINUX_LINUX_HH__ diff --git a/src/arch/alpha/linux/process.cc b/src/arch/alpha/linux/process.cc index 9886c7ea7..0f09e472b 100644 --- a/src/arch/alpha/linux/process.cc +++ b/src/arch/alpha/linux/process.cc @@ -440,7 +440,7 @@ SyscallDesc AlphaLinuxProcess::syscallDescs[] = { /* 315 */ SyscallDesc("munlock", unimplementedFunc), /* 316 */ SyscallDesc("mlockall", unimplementedFunc), /* 317 */ SyscallDesc("munlockall", unimplementedFunc), - /* 318 */ SyscallDesc("sysinfo", unimplementedFunc), + /* 318 */ SyscallDesc("sysinfo", sysinfoFunc), /* 319 */ SyscallDesc("_sysctl", unimplementedFunc), /* 320 */ SyscallDesc("was sys_idle", unimplementedFunc), /* 321 */ SyscallDesc("oldumount", unimplementedFunc), diff --git a/src/arch/arm/linux/linux.hh b/src/arch/arm/linux/linux.hh index d99fa8e49..b9b10a593 100644 --- a/src/arch/arm/linux/linux.hh +++ b/src/arch/arm/linux/linux.hh @@ -147,6 +147,21 @@ class ArmLinux : public Linux uint64_t st_ino; } tgt_stat64; + typedef struct { + int32_t uptime; /* Seconds since boot */ + uint32_t loads[3]; /* 1, 5, and 15 minute load averages */ + uint32_t totalram; /* Total usable main memory size */ + uint32_t freeram; /* Available memory size */ + uint32_t sharedram; /* Amount of shared memory */ + uint32_t bufferram; /* Memory used by buffers */ + uint32_t totalswap; /* Total swap space size */ + uint32_t freeswap; /* swap space still available */ + uint16_t procs; /* Number of current processes */ + uint32_t totalhigh; /* Total high memory size */ + uint32_t freehigh; /* Available high memory size */ + uint32_t mem_unit; /* Memory unit size in bytes */ + } tgt_sysinfo; + }; diff --git a/src/arch/arm/linux/process.cc b/src/arch/arm/linux/process.cc index 56e3588a7..a7f36e18d 100644 --- a/src/arch/arm/linux/process.cc +++ b/src/arch/arm/linux/process.cc @@ -179,7 +179,7 @@ SyscallDesc ArmLinuxProcess::syscallDescs[] = { /* 113 */ SyscallDesc("vm86", unimplementedFunc), /* 114 */ SyscallDesc("wait4", unimplementedFunc), /* 115 */ SyscallDesc("swapoff", unimplementedFunc), - /* 116 */ SyscallDesc("sysinfo", unimplementedFunc), + /* 116 */ SyscallDesc("sysinfo", sysinfoFunc), /* 117 */ SyscallDesc("ipc", unimplementedFunc), /* 118 */ SyscallDesc("fsync", unimplementedFunc), /* 119 */ SyscallDesc("sigreturn", unimplementedFunc), diff --git a/src/arch/mips/linux/linux.hh b/src/arch/mips/linux/linux.hh index ee81fa18f..b30cca2fb 100644 --- a/src/arch/mips/linux/linux.hh +++ b/src/arch/mips/linux/linux.hh @@ -126,6 +126,22 @@ class MipsLinux : public Linux /// assign themselves to process IDs reserved for /// the root users. static const int NUM_ROOT_PROCS = 2; + + typedef struct { + int32_t uptime; /* Seconds since boot */ + uint32_t loads[3]; /* 1, 5, and 15 minute load averages */ + uint32_t totalram; /* Total usable main memory size */ + uint32_t freeram; /* Available memory size */ + uint32_t sharedram; /* Amount of shared memory */ + uint32_t bufferram; /* Memory used by buffers */ + uint32_t totalswap; /* Total swap space size */ + uint32_t freeswap; /* swap space still available */ + uint16_t procs; /* Number of current processes */ + uint32_t totalhigh; /* Total high memory size */ + uint32_t freehigh; /* Available high memory size */ + uint32_t mem_unit; /* Memory unit size in bytes */ + } tgt_sysinfo; + }; #endif diff --git a/src/arch/mips/linux/process.cc b/src/arch/mips/linux/process.cc index 53a24487f..0fa3c382a 100644 --- a/src/arch/mips/linux/process.cc +++ b/src/arch/mips/linux/process.cc @@ -238,7 +238,7 @@ SyscallDesc MipsLinuxProcess::syscallDescs[] = { /* 113 */ SyscallDesc("vm86", unimplementedFunc), /* 114 */ SyscallDesc("wait4", unimplementedFunc), /* 115 */ SyscallDesc("swapoff", unimplementedFunc), - /* 116 */ SyscallDesc("sysinfo", unimplementedFunc), + /* 116 */ SyscallDesc("sysinfo", sysinfoFunc), /* 117 */ SyscallDesc("ipc", unimplementedFunc), /* 118 */ SyscallDesc("fsync", unimplementedFunc), /* 119 */ SyscallDesc("sigreturn", unimplementedFunc), diff --git a/src/arch/sparc/linux/linux.hh b/src/arch/sparc/linux/linux.hh index b1dc691ce..1f7567d43 100644 --- a/src/arch/sparc/linux/linux.hh +++ b/src/arch/sparc/linux/linux.hh @@ -77,6 +77,22 @@ class SparcLinux : public Linux static const int NUM_OPEN_FLAGS; static const unsigned TGT_MAP_ANONYMOUS = 0x20; + + typedef struct { + int64_t uptime; /* Seconds since boot */ + uint64_t loads[3]; /* 1, 5, and 15 minute load averages */ + uint64_t totalram; /* Total usable main memory size */ + uint64_t freeram; /* Available memory size */ + uint64_t sharedram; /* Amount of shared memory */ + uint64_t bufferram; /* Memory used by buffers */ + uint64_t totalswap; /* Total swap space size */ + uint64_t freeswap; /* swap space still available */ + uint16_t procs; /* Number of current processes */ + uint64_t totalhigh; /* Total high memory size */ + uint64_t freehigh; /* Available high memory size */ + uint64_t mem_unit; /* Memory unit size in bytes */ + } tgt_sysinfo; + }; class Sparc32Linux : public SparcLinux @@ -105,6 +121,22 @@ class Sparc32Linux : public SparcLinux uint32_t __unused4; uint32_t __unused5; } tgt_stat64; + + typedef struct { + int32_t uptime; /* Seconds since boot */ + uint32_t loads[3]; /* 1, 5, and 15 minute load averages */ + uint32_t totalram; /* Total usable main memory size */ + uint32_t freeram; /* Available memory size */ + uint32_t sharedram; /* Amount of shared memory */ + uint32_t bufferram; /* Memory used by buffers */ + uint32_t totalswap; /* Total swap space size */ + uint32_t freeswap; /* swap space still available */ + uint16_t procs; /* Number of current processes */ + uint32_t totalhigh; /* Total high memory size */ + uint32_t freehigh; /* Available high memory size */ + uint32_t mem_unit; /* Memory unit size in bytes */ + } tgt_sysinfo; + }; #endif diff --git a/src/arch/sparc/linux/syscalls.cc b/src/arch/sparc/linux/syscalls.cc index f4781d886..c50803976 100644 --- a/src/arch/sparc/linux/syscalls.cc +++ b/src/arch/sparc/linux/syscalls.cc @@ -302,7 +302,7 @@ SyscallDesc SparcLinuxProcess::syscall32Descs[] = { /* 211 */ SyscallDesc("tgkill", unimplementedFunc), //32 bit /* 212 */ SyscallDesc("waitpid", unimplementedFunc), //32 bit /* 213 */ SyscallDesc("swapoff", unimplementedFunc), - /* 214 */ SyscallDesc("sysinfo", unimplementedFunc), //32 bit + /* 214 */ SyscallDesc("sysinfo", sysinfoFunc), //32 bit /* 215 */ SyscallDesc("ipc", unimplementedFunc), //32 bit /* 216 */ SyscallDesc("sigreturn", unimplementedFunc), //32 bit /* 217 */ SyscallDesc("clone", cloneFunc), @@ -608,7 +608,7 @@ SyscallDesc SparcLinuxProcess::syscallDescs[] = { /* 211 */ SyscallDesc("tgkill", unimplementedFunc), /* 212 */ SyscallDesc("waitpid", unimplementedFunc), /* 213 */ SyscallDesc("swapoff", unimplementedFunc), - /* 214 */ SyscallDesc("sysinfo", unimplementedFunc), + /* 214 */ SyscallDesc("sysinfo", sysinfoFunc), /* 215 */ SyscallDesc("ipc", unimplementedFunc), /* 216 */ SyscallDesc("sigreturn", unimplementedFunc), /* 217 */ SyscallDesc("clone", cloneFunc), diff --git a/src/arch/x86/linux/linux.hh b/src/arch/x86/linux/linux.hh index c2941c769..d5bead8f3 100644 --- a/src/arch/x86/linux/linux.hh +++ b/src/arch/x86/linux/linux.hh @@ -111,6 +111,22 @@ class X86Linux64 : public Linux uint64_t iov_base; // void * uint64_t iov_len; // size_t } tgt_iovec; + + typedef struct { + int64_t uptime; /* Seconds since boot */ + uint64_t loads[3]; /* 1, 5, and 15 minute load averages */ + uint64_t totalram; /* Total usable main memory size */ + uint64_t freeram; /* Available memory size */ + uint64_t sharedram; /* Amount of shared memory */ + uint64_t bufferram; /* Memory used by buffers */ + uint64_t totalswap; /* Total swap space size */ + uint64_t freeswap; /* swap space still available */ + uint16_t procs; /* Number of current processes */ + uint64_t totalhigh; /* Total high memory size */ + uint64_t freehigh; /* Available high memory size */ + uint64_t mem_unit; /* Memory unit size in bytes */ + } tgt_sysinfo; + }; class X86Linux32 : public Linux @@ -160,6 +176,21 @@ class X86Linux32 : public Linux static const int NUM_OPEN_FLAGS; static const unsigned TGT_MAP_ANONYMOUS = 0x20; + + typedef struct { + int32_t uptime; /* Seconds since boot */ + uint32_t loads[3]; /* 1, 5, and 15 minute load averages */ + uint32_t totalram; /* Total usable main memory size */ + uint32_t freeram; /* Available memory size */ + uint32_t sharedram; /* Amount of shared memory */ + uint32_t bufferram; /* Memory used by buffers */ + uint32_t totalswap; /* Total swap space size */ + uint32_t freeswap; /* swap space still available */ + uint16_t procs; /* Number of current processes */ + uint32_t totalhigh; /* Total high memory size */ + uint32_t freehigh; /* Available high memory size */ + uint32_t mem_unit; /* Memory unit size in bytes */ + } tgt_sysinfo; }; #endif diff --git a/src/arch/x86/linux/syscalls.cc b/src/arch/x86/linux/syscalls.cc index 5a425ed9a..52352ee80 100644 --- a/src/arch/x86/linux/syscalls.cc +++ b/src/arch/x86/linux/syscalls.cc @@ -327,7 +327,7 @@ SyscallDesc X86_64LinuxProcess::syscallDescs[] = { /* 96 */ SyscallDesc("gettimeofday", unimplementedFunc), /* 97 */ SyscallDesc("getrlimit", unimplementedFunc), /* 98 */ SyscallDesc("getrusage", unimplementedFunc), - /* 99 */ SyscallDesc("sysinfo", unimplementedFunc), + /* 99 */ SyscallDesc("sysinfo", sysinfoFunc), /* 100 */ SyscallDesc("times", unimplementedFunc), /* 101 */ SyscallDesc("ptrace", unimplementedFunc), /* 102 */ SyscallDesc("getuid", getuidFunc), @@ -623,7 +623,7 @@ SyscallDesc I386LinuxProcess::syscallDescs[] = { /* 113 */ SyscallDesc("vm86old", unimplementedFunc), /* 114 */ SyscallDesc("wait4", unimplementedFunc), /* 115 */ SyscallDesc("swapoff", unimplementedFunc), - /* 116 */ SyscallDesc("sysinfo", unimplementedFunc), + /* 116 */ SyscallDesc("sysinfo", sysinfoFunc), /* 117 */ SyscallDesc("ipc", unimplementedFunc), /* 118 */ SyscallDesc("fsync", unimplementedFunc), /* 119 */ SyscallDesc("sigreturn", unimplementedFunc), -- cgit v1.2.3 From eec6bfaa9de23b075762a62e57e46cd3f2f977ef Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 16 Sep 2009 19:28:01 -0700 Subject: X86: Fix setting the busy bit in the task descriptor in LTR. --- src/arch/x86/isa/insts/system/segmentation.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/insts/system/segmentation.py b/src/arch/x86/isa/insts/system/segmentation.py index b83fcba95..c97f2f152 100644 --- a/src/arch/x86/isa/insts/system/segmentation.py +++ b/src/arch/x86/isa/insts/system/segmentation.py @@ -179,7 +179,8 @@ def macroop LTR_R wrdh t3, t1, t2 wrdl tr, t1, reg wrbase tr, t3, dataSize=8 - ori t1, t1, (1 << 9) + limm t5, (1 << 9) + or t1, t1, t5 st t1, tsg, [8, t4, t0], dataSize=8 }; @@ -195,7 +196,8 @@ def macroop LTR_M wrdh t3, t1, t2 wrdl tr, t1, t5 wrbase tr, t3, dataSize=8 - ori t1, t1, (1 << 9) + limm t5, (1 << 9) + or t1, t1, t5 st t1, tsg, [8, t4, t0], dataSize=8 }; @@ -212,7 +214,8 @@ def macroop LTR_P wrdh t3, t1, t2 wrdl tr, t1, t5 wrbase tr, t3, dataSize=8 - ori t1, t1, (1 << 9) + limm t5, (1 << 9) + or t1, t1, t5 st t1, tsg, [8, t4, t0], dataSize=8 }; -- cgit v1.2.3 From 239f1dea31144d8ea35065c8e037b88298db616f Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 16 Sep 2009 19:28:30 -0700 Subject: X86: Fix checking the NT bit during an IRET. --- .../insts/general_purpose/control_transfer/interrupts_and_exceptions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/insts/general_purpose/control_transfer/interrupts_and_exceptions.py b/src/arch/x86/isa/insts/general_purpose/control_transfer/interrupts_and_exceptions.py index a9ad611b7..1c0650683 100644 --- a/src/arch/x86/isa/insts/general_purpose/control_transfer/interrupts_and_exceptions.py +++ b/src/arch/x86/isa/insts/general_purpose/control_transfer/interrupts_and_exceptions.py @@ -62,7 +62,7 @@ def macroop IRET_PROT { .adjust_env oszIn64Override # Check for a nested task. This isn't supported at the moment. - rflag t1, NT + rflag t1, 14; #NT bit panic "Task switching with iret is unimplemented!", flags=(nCEZF,) #t1 = temp_RIP -- cgit v1.2.3 From 7a0ef6c36fa4f188fecfd709436dfa52bb0918d6 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 16 Sep 2009 19:28:57 -0700 Subject: X86: Make the imm8 member of immediate microops really 8 bits consistently. --- src/arch/x86/isa/microops/regop.isa | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/microops/regop.isa b/src/arch/x86/isa/microops/regop.isa index a4cb6f4cc..a8d50f17c 100644 --- a/src/arch/x86/isa/microops/regop.isa +++ b/src/arch/x86/isa/microops/regop.isa @@ -149,12 +149,12 @@ def template MicroRegOpImmDeclare {{ %(class_name)s(ExtMachInst _machInst, const char * instMnem, bool isMicro, bool isDelayed, bool isFirst, bool isLast, - InstRegIndex _src1, uint16_t _imm8, InstRegIndex _dest, + InstRegIndex _src1, uint8_t _imm8, InstRegIndex _dest, uint8_t _dataSize, uint16_t _ext); %(class_name)s(ExtMachInst _machInst, const char * instMnem, - InstRegIndex _src1, uint16_t _imm8, InstRegIndex _dest, + InstRegIndex _src1, uint8_t _imm8, InstRegIndex _dest, uint8_t _dataSize, uint16_t _ext); %(BasicExecDeclare)s @@ -203,7 +203,7 @@ def template MicroRegOpImmConstructor {{ inline %(class_name)s::%(class_name)s( ExtMachInst machInst, const char * instMnem, - InstRegIndex _src1, uint16_t _imm8, InstRegIndex _dest, + InstRegIndex _src1, uint8_t _imm8, InstRegIndex _dest, uint8_t _dataSize, uint16_t _ext) : %(base_class)s(machInst, "%(mnemonic)s", instMnem, false, false, false, false, @@ -216,7 +216,7 @@ def template MicroRegOpImmConstructor {{ inline %(class_name)s::%(class_name)s( ExtMachInst machInst, const char * instMnem, bool isMicro, bool isDelayed, bool isFirst, bool isLast, - InstRegIndex _src1, uint16_t _imm8, InstRegIndex _dest, + InstRegIndex _src1, uint8_t _imm8, InstRegIndex _dest, uint8_t _dataSize, uint16_t _ext) : %(base_class)s(machInst, "%(mnemonic)s", instMnem, isMicro, isDelayed, isFirst, isLast, -- cgit v1.2.3 From c876a781a592c75b38853b2ec4b7d9435f1444cf Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 16 Sep 2009 19:29:51 -0700 Subject: X86: Sign extend the immediate of wripi like the register version. --- src/arch/x86/isa/microops/regop.isa | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/microops/regop.isa b/src/arch/x86/isa/microops/regop.isa index a8d50f17c..fd1ad6925 100644 --- a/src/arch/x86/isa/microops/regop.isa +++ b/src/arch/x86/isa/microops/regop.isa @@ -324,11 +324,12 @@ let {{ matcher.sub(src2_name, flag_code), matcher.sub(src2_name, cond_check), matcher.sub(src2_name, else_code)) + imm_name = "%simm8" % match.group("prefix") self.buildCppClasses(name + "i", Name, suffix + "Imm", - matcher.sub("imm8", code), - matcher.sub("imm8", flag_code), - matcher.sub("imm8", cond_check), - matcher.sub("imm8", else_code)) + matcher.sub(imm_name, code), + matcher.sub(imm_name, flag_code), + matcher.sub(imm_name, cond_check), + matcher.sub(imm_name, else_code)) return # If there's something optional to do with flags, generate @@ -353,13 +354,16 @@ let {{ matcher = re.compile("(? Date: Thu, 17 Sep 2009 02:56:06 -0700 Subject: X86: Fix the expected size of the immediate offset in MOV_MI. --- src/arch/x86/predecoder_tables.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/arch') diff --git a/src/arch/x86/predecoder_tables.cc b/src/arch/x86/predecoder_tables.cc index 5f2b5c421..e8c838dfb 100644 --- a/src/arch/x86/predecoder_tables.cc +++ b/src/arch/x86/predecoder_tables.cc @@ -191,7 +191,7 @@ namespace X86ISA /* 7 */ BY, BY, BY, BY, BY, BY, BY, BY, BY, BY, BY, BY, BY, BY, BY, BY, /* 8 */ BY, ZW, BY, BY, 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , /* 9 */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , -/* A */ BY, VW, BY, VW, 0 , 0 , 0 , 0 , BY, ZW, 0 , 0 , 0 , 0 , 0 , 0 , +/* A */ VW, VW, VW, VW, 0 , 0 , 0 , 0 , BY, ZW, 0 , 0 , 0 , 0 , 0 , 0 , /* B */ BY, BY, BY, BY, BY, BY, BY, BY, VW, VW, VW, VW, VW, VW, VW, VW, /* C */ BY, BY, WO, 0 , 0 , 0 , BY, ZW, EN, 0 , WO, 0 , 0 , BY, 0 , 0 , /* D */ 0 , 0 , 0 , 0 , BY, BY, 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , -- cgit v1.2.3 From b7094ec38b8ec2f4de1fdf3d60a0f5953efa3e06 Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Thu, 17 Sep 2009 15:59:43 -0400 Subject: mips: fix command line arguments arguments were not being saved correctly into M5 memory --- src/arch/mips/linux/process.cc | 6 ---- src/arch/mips/linux/process.hh | 2 -- src/arch/mips/process.cc | 81 ++++++++++++++++++++++++++++++++++++++++++ src/arch/mips/process.hh | 4 ++- 4 files changed, 84 insertions(+), 9 deletions(-) (limited to 'src/arch') diff --git a/src/arch/mips/linux/process.cc b/src/arch/mips/linux/process.cc index 0fa3c382a..dde3a4efd 100644 --- a/src/arch/mips/linux/process.cc +++ b/src/arch/mips/linux/process.cc @@ -413,12 +413,6 @@ MipsLinuxProcess::MipsLinuxProcess(LiveProcessParams * params, Num_Syscall_Descs(sizeof(syscallDescs) / sizeof(SyscallDesc)) { } -void -MipsLinuxProcess::startup() -{ - MipsLiveProcess::argsInit(MachineBytes, VMPageSize); -} - SyscallDesc* MipsLinuxProcess::getDesc(int callnum) { diff --git a/src/arch/mips/linux/process.hh b/src/arch/mips/linux/process.hh index 5afde2be1..8c45014e0 100644 --- a/src/arch/mips/linux/process.hh +++ b/src/arch/mips/linux/process.hh @@ -43,8 +43,6 @@ class MipsLinuxProcess : public MipsLiveProcess /// Constructor. MipsLinuxProcess(LiveProcessParams * params, ObjectFile *objFile); - void startup(); - virtual SyscallDesc* getDesc(int callnum); /// The target system's hostname. diff --git a/src/arch/mips/process.cc b/src/arch/mips/process.cc index 3e9fb7c20..b9f608922 100644 --- a/src/arch/mips/process.cc +++ b/src/arch/mips/process.cc @@ -32,9 +32,15 @@ #include "arch/mips/isa_traits.hh" #include "arch/mips/process.hh" + #include "base/loader/object_file.hh" #include "base/misc.hh" #include "cpu/thread_context.hh" + +#include "mem/page_table.hh" + +#include "sim/process.hh" +#include "sim/process_impl.hh" #include "sim/system.hh" using namespace std; @@ -62,9 +68,84 @@ MipsLiveProcess::MipsLiveProcess(LiveProcessParams * params, void MipsLiveProcess::startup() { + Process::startup(); + argsInit(MachineBytes, VMPageSize); } +void +MipsLiveProcess::argsInit(int intSize, int pageSize) +{ + // load object file into target memory + objFile->loadSections(initVirtMem); + + // Calculate how much space we need for arg & env arrays. + int argv_array_size = intSize * (argv.size() + 1); + int envp_array_size = intSize * (envp.size() + 1); + int arg_data_size = 0; + for (vector::size_type i = 0; i < argv.size(); ++i) { + arg_data_size += argv[i].size() + 1; + } + int env_data_size = 0; + for (vector::size_type i = 0; i < envp.size(); ++i) { + env_data_size += envp[i].size() + 1; + } + + int space_needed = + argv_array_size + envp_array_size + arg_data_size + env_data_size; + if (space_needed < 32*1024) + space_needed = 32*1024; + + // set bottom of stack + stack_min = stack_base - space_needed; + // align it + stack_min = roundDown(stack_min, pageSize); + stack_size = stack_base - stack_min; + // map memory + pTable->allocate(stack_min, roundUp(stack_size, pageSize)); + + // map out initial stack contents + // ======== + // NOTE: Using uint32_t hardcodes MIPS32 and not MIPS64 + // even if MIPS64 was intended. This is because the + // copyStringArray function templates on the parameters. + // Elegant way to check intSize and vary between 32/64? + // ======== + uint32_t argv_array_base = stack_min + intSize; // room for argc + uint32_t envp_array_base = argv_array_base + argv_array_size; + uint32_t arg_data_base = envp_array_base + envp_array_size; + uint32_t env_data_base = arg_data_base + arg_data_size; + + // write contents to stack + uint32_t argc = argv.size(); + + if (intSize == 8) + argc = htog((uint64_t)argc); + else if (intSize == 4) + argc = htog((uint32_t)argc); + else + panic("Unknown int size"); + + + initVirtMem->writeBlob(stack_min, (uint8_t*)&argc, intSize); + + copyStringArray(argv, argv_array_base, arg_data_base, initVirtMem); + + copyStringArray(envp, envp_array_base, env_data_base, initVirtMem); + + ThreadContext *tc = system->getThreadContext(contextIds[0]); + + setSyscallArg(tc, 0, argc); + setSyscallArg(tc, 1, argv_array_base); + tc->setIntReg(StackPointerReg, stack_min); + + Addr prog_entry = objFile->entryPoint(); + tc->setPC(prog_entry); + tc->setNextPC(prog_entry + sizeof(MachInst)); + tc->setNextNPC(prog_entry + (2 * sizeof(MachInst))); +} + + MipsISA::IntReg MipsLiveProcess::getSyscallArg(ThreadContext *tc, int i) { diff --git a/src/arch/mips/process.hh b/src/arch/mips/process.hh index 87c62330f..b8f4de20a 100644 --- a/src/arch/mips/process.hh +++ b/src/arch/mips/process.hh @@ -45,7 +45,9 @@ class MipsLiveProcess : public LiveProcess protected: MipsLiveProcess(LiveProcessParams * params, ObjectFile *objFile); - virtual void startup(); + void startup(); + + void argsInit(int intSize, int pageSize); public: MipsISA::IntReg getSyscallArg(ThreadContext *tc, int i); -- cgit v1.2.3 From 9a8cb7db7e86c25a755f2e2817a0385b13e3ac32 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Tue, 22 Sep 2009 15:24:16 -0700 Subject: python: Move more code into m5.util allow SCons to use that code. Get rid of misc.py and just stick misc things in __init__.py Move utility functions out of SCons files and into m5.util Move utility type stuff from m5/__init__.py to m5/util/__init__.py Remove buildEnv from m5 and allow access only from m5.defines Rename AddToPath to addToPath while we're moving it to m5.util Rename read_command to readCommand while we're moving it Rename compare_versions to compareVersions while we're moving it. --HG-- rename : src/python/m5/convert.py => src/python/m5/util/convert.py rename : src/python/m5/smartdict.py => src/python/m5/util/smartdict.py --- src/arch/mips/BISystem.py | 5 +++-- src/arch/mips/MipsCPU.py | 5 +++-- src/arch/mips/MipsSystem.py | 6 +++--- src/arch/x86/X86TLB.py | 9 +++++---- 4 files changed, 14 insertions(+), 11 deletions(-) (limited to 'src/arch') diff --git a/src/arch/mips/BISystem.py b/src/arch/mips/BISystem.py index dd4e4fe25..a6e4091f2 100755 --- a/src/arch/mips/BISystem.py +++ b/src/arch/mips/BISystem.py @@ -28,10 +28,11 @@ # # Authors: Jaidev Patwardhan -from m5 import build_env +from m5.defines import buildEnv + from System import * -if build_env['FULL_SYSTEM']: +if buildEnv['FULL_SYSTEM']: class BareIronMipsSystem(MipsSystem): type = 'BareIronMipsSystem' system_type = 34 diff --git a/src/arch/mips/MipsCPU.py b/src/arch/mips/MipsCPU.py index 81c6bdacf..48ee4171c 100644 --- a/src/arch/mips/MipsCPU.py +++ b/src/arch/mips/MipsCPU.py @@ -29,12 +29,13 @@ # Authors: Jaidev Patwardhan # Korey Sewell -from m5.SimObject import SimObject +from m5.defines import buildEnv from m5.params import * + from BaseCPU import BaseCPU class BaseMipsCPU(BaseCPU) - if build_env['TARGET_ISA'] == 'mips': + if buildEnv['TARGET_ISA'] == 'mips': CP0_IntCtl_IPTI = Param.Unsigned(0,"No Description") CP0_IntCtl_IPPCI = Param.Unsigned(0,"No Description") CP0_SrsCtl_HSS = Param.Unsigned(0,"No Description") diff --git a/src/arch/mips/MipsSystem.py b/src/arch/mips/MipsSystem.py index c3dcf4e0b..d271bd387 100644 --- a/src/arch/mips/MipsSystem.py +++ b/src/arch/mips/MipsSystem.py @@ -28,10 +28,10 @@ # # Authors: Jaidev Patwardhan -from m5.SimObject import SimObject +from m5.defines import buildEnv from m5.params import * from m5.proxy import * -from m5 import build_env + from System import System class MipsSystem(System): @@ -42,7 +42,7 @@ class MipsSystem(System): system_type = Param.UInt64("Type of system we are emulating") system_rev = Param.UInt64("Revision of system we are emulating") -if build_env['FULL_SYSTEM']: +if buildEnv['FULL_SYSTEM']: class LinuxMipsSystem(MipsSystem): type = 'LinuxMipsSystem' system_type = 34 diff --git a/src/arch/x86/X86TLB.py b/src/arch/x86/X86TLB.py index 15b03fd33..9f7dc43b3 100644 --- a/src/arch/x86/X86TLB.py +++ b/src/arch/x86/X86TLB.py @@ -53,13 +53,14 @@ # # Authors: Gabe Black -from MemObject import MemObject +from m5.defines import buildEnv from m5.params import * from m5.proxy import * -from m5 import build_env + from BaseTLB import BaseTLB +from MemObject import MemObject -if build_env['FULL_SYSTEM']: +if buildEnv['FULL_SYSTEM']: class X86PagetableWalker(MemObject): type = 'X86PagetableWalker' cxx_class = 'X86ISA::Walker' @@ -70,6 +71,6 @@ class X86TLB(BaseTLB): type = 'X86TLB' cxx_class = 'X86ISA::TLB' size = Param.Int(64, "TLB size") - if build_env['FULL_SYSTEM']: + if buildEnv['FULL_SYSTEM']: walker = Param.X86PagetableWalker(\ X86PagetableWalker(), "page table walker") -- cgit v1.2.3 From e9288b2cd35863c600d7ff7bf04f4c08e055e3e0 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Tue, 22 Sep 2009 15:24:16 -0700 Subject: scons: add slicc and ply to sys.path and PYTHONPATH so everyone has access --- src/arch/isa_parser.py | 5 ----- src/arch/micro_asm.py | 4 ---- 2 files changed, 9 deletions(-) (limited to 'src/arch') diff --git a/src/arch/isa_parser.py b/src/arch/isa_parser.py index d5b5bbe4f..23260ca48 100755 --- a/src/arch/isa_parser.py +++ b/src/arch/isa_parser.py @@ -34,11 +34,6 @@ import traceback # get type names from types import * -# Prepend the directory where the PLY lex & yacc modules are found -# to the search path. Assumes we're compiling in a subdirectory -# of 'build' in the current tree. -sys.path[0:0] = [os.environ['M5_PLY']] - from ply import lex from ply import yacc diff --git a/src/arch/micro_asm.py b/src/arch/micro_asm.py index 3433a8076..4e5400cef 100644 --- a/src/arch/micro_asm.py +++ b/src/arch/micro_asm.py @@ -34,10 +34,6 @@ import traceback # get type names from types import * -# Prepend the directory where the PLY lex & yacc modules are found -# to the search path. -sys.path[0:0] = [os.environ['M5_PLY']] - from ply import lex from ply import yacc -- cgit v1.2.3 From d9f39c8ce75aac84c88b32392c2967344362906b Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Wed, 23 Sep 2009 08:34:21 -0700 Subject: arch: nuke arch/isa_specific.hh and move stuff to generated config/the_isa.hh --- src/arch/arm/stacktrace.hh | 1 + src/arch/isa_specific.hh | 70 ---------------------------------------------- 2 files changed, 1 insertion(+), 70 deletions(-) delete mode 100644 src/arch/isa_specific.hh (limited to 'src/arch') diff --git a/src/arch/arm/stacktrace.hh b/src/arch/arm/stacktrace.hh index 3f9c91096..c5225455c 100644 --- a/src/arch/arm/stacktrace.hh +++ b/src/arch/arm/stacktrace.hh @@ -34,6 +34,7 @@ #define __ARCH_ARM_STACKTRACE_HH__ #include "base/trace.hh" +#include "config/the_isa.hh" #include "cpu/static_inst.hh" class ThreadContext; diff --git a/src/arch/isa_specific.hh b/src/arch/isa_specific.hh deleted file mode 100644 index de070bbf9..000000000 --- a/src/arch/isa_specific.hh +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2003-2005 The Regents of The University of Michigan - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Authors: Gabe Black - */ - -#ifndef __ARCH_ISA_SPECIFIC_HH__ -#define __ARCH_ISA_SPECIFIC_HH__ - -//This file provides a mechanism for other source code to bring in -//files from the ISA being compiled in. - -//These are constants so you can selectively compile code based on the isa. -//To use them, do something like: -// -//#if THE_ISA == YOUR_FAVORITE_ISA -// conditional_code -//#endif -// -//Note that this is how this file sets up the TheISA macro. - -//These macros have numerical values because otherwise the preprocessor -//would treat them as 0 in comparisons. -#define ALPHA_ISA 21064 -#define SPARC_ISA 42 -#define MIPS_ISA 34000 -#define X86_ISA 8086 -#define ARM_ISA 6 - -//These tell the preprocessor where to find the files of a particular -//ISA, and set the "TheISA" macro for use elsewhere. -#if THE_ISA == ALPHA_ISA - #define TheISA AlphaISA -#elif THE_ISA == SPARC_ISA - #define TheISA SparcISA -#elif THE_ISA == MIPS_ISA - #define TheISA MipsISA -#elif THE_ISA == X86_ISA - #define TheISA X86ISA -#elif THE_ISA == ARM_ISA - #define TheISA ArmISA -#else - #error "THE_ISA not set" -#endif - -#endif -- cgit v1.2.3 From baca1f0566b51a24fda506dc95e3baa6265280d4 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Wed, 23 Sep 2009 18:28:29 -0700 Subject: isa_parser: Turn the ISA Parser into a subclass of Grammar. This is to prepare for future cleanup where we allow SCons to create a separate grammar class for each ISA --- src/arch/isa_parser.py | 1376 ++++++++++++++++++++++++------------------------ 1 file changed, 691 insertions(+), 685 deletions(-) (limited to 'src/arch') diff --git a/src/arch/isa_parser.py b/src/arch/isa_parser.py index 23260ca48..f001eff41 100755 --- a/src/arch/isa_parser.py +++ b/src/arch/isa_parser.py @@ -34,697 +34,699 @@ import traceback # get type names from types import * -from ply import lex -from ply import yacc - -##################################################################### -# -# Lexer -# -# The PLY lexer module takes two things as input: -# - A list of token names (the string list 'tokens') -# - A regular expression describing a match for each token. The -# regexp for token FOO can be provided in two ways: -# - as a string variable named t_FOO -# - as the doc string for a function named t_FOO. In this case, -# the function is also executed, allowing an action to be -# associated with each token match. -# -##################################################################### - -# Reserved words. These are listed separately as they are matched -# using the same regexp as generic IDs, but distinguished in the -# t_ID() function. The PLY documentation suggests this approach. -reserved = ( - 'BITFIELD', 'DECODE', 'DECODER', 'DEFAULT', 'DEF', 'EXEC', 'FORMAT', - 'HEADER', 'LET', 'NAMESPACE', 'OPERAND_TYPES', 'OPERANDS', - 'OUTPUT', 'SIGNED', 'TEMPLATE' +from m5.util.grammar import Grammar + +class ISAParser(Grammar): + def __init__(self, *args, **kwargs): + super(ISAParser, self).__init__(*args, **kwargs) + self.templateMap = {} + + ##################################################################### + # + # Lexer + # + # The PLY lexer module takes two things as input: + # - A list of token names (the string list 'tokens') + # - A regular expression describing a match for each token. The + # regexp for token FOO can be provided in two ways: + # - as a string variable named t_FOO + # - as the doc string for a function named t_FOO. In this case, + # the function is also executed, allowing an action to be + # associated with each token match. + # + ##################################################################### + + # Reserved words. These are listed separately as they are matched + # using the same regexp as generic IDs, but distinguished in the + # t_ID() function. The PLY documentation suggests this approach. + reserved = ( + 'BITFIELD', 'DECODE', 'DECODER', 'DEFAULT', 'DEF', 'EXEC', 'FORMAT', + 'HEADER', 'LET', 'NAMESPACE', 'OPERAND_TYPES', 'OPERANDS', + 'OUTPUT', 'SIGNED', 'TEMPLATE' + ) + + # List of tokens. The lex module requires this. + tokens = reserved + ( + # identifier + 'ID', + + # integer literal + 'INTLIT', + + # string literal + 'STRLIT', + + # code literal + 'CODELIT', + + # ( ) [ ] { } < > , ; . : :: * + 'LPAREN', 'RPAREN', + 'LBRACKET', 'RBRACKET', + 'LBRACE', 'RBRACE', + 'LESS', 'GREATER', 'EQUALS', + 'COMMA', 'SEMI', 'DOT', 'COLON', 'DBLCOLON', + 'ASTERISK', + + # C preprocessor directives + 'CPPDIRECTIVE' + + # The following are matched but never returned. commented out to + # suppress PLY warning + # newfile directive + # 'NEWFILE', + + # endfile directive + # 'ENDFILE' ) -# List of tokens. The lex module requires this. -tokens = reserved + ( - # identifier - 'ID', - - # integer literal - 'INTLIT', - - # string literal - 'STRLIT', - - # code literal - 'CODELIT', - - # ( ) [ ] { } < > , ; . : :: * - 'LPAREN', 'RPAREN', - 'LBRACKET', 'RBRACKET', - 'LBRACE', 'RBRACE', - 'LESS', 'GREATER', 'EQUALS', - 'COMMA', 'SEMI', 'DOT', 'COLON', 'DBLCOLON', - 'ASTERISK', - - # C preprocessor directives - 'CPPDIRECTIVE' - -# The following are matched but never returned. commented out to -# suppress PLY warning - # newfile directive -# 'NEWFILE', - - # endfile directive -# 'ENDFILE' -) - -# Regular expressions for token matching -t_LPAREN = r'\(' -t_RPAREN = r'\)' -t_LBRACKET = r'\[' -t_RBRACKET = r'\]' -t_LBRACE = r'\{' -t_RBRACE = r'\}' -t_LESS = r'\<' -t_GREATER = r'\>' -t_EQUALS = r'=' -t_COMMA = r',' -t_SEMI = r';' -t_DOT = r'\.' -t_COLON = r':' -t_DBLCOLON = r'::' -t_ASTERISK = r'\*' - -# Identifiers and reserved words -reserved_map = { } -for r in reserved: - reserved_map[r.lower()] = r - -def t_ID(t): - r'[A-Za-z_]\w*' - t.type = reserved_map.get(t.value,'ID') - return t - -# Integer literal -def t_INTLIT(t): - r'(0x[\da-fA-F]+)|\d+' - try: - t.value = int(t.value,0) - except ValueError: - error(t.lexer.lineno, 'Integer value "%s" too large' % t.value) - t.value = 0 - return t - -# String literal. Note that these use only single quotes, and -# can span multiple lines. -def t_STRLIT(t): - r"(?m)'([^'])+'" - # strip off quotes - t.value = t.value[1:-1] - t.lexer.lineno += t.value.count('\n') - return t - - -# "Code literal"... like a string literal, but delimiters are -# '{{' and '}}' so they get formatted nicely under emacs c-mode -def t_CODELIT(t): - r"(?m)\{\{([^\}]|}(?!\}))+\}\}" - # strip off {{ & }} - t.value = t.value[2:-2] - t.lexer.lineno += t.value.count('\n') - return t - -def t_CPPDIRECTIVE(t): - r'^\#[^\#].*\n' - t.lexer.lineno += t.value.count('\n') - return t - -def t_NEWFILE(t): - r'^\#\#newfile\s+"[\w/.-]*"' - fileNameStack.push((t.value[11:-1], t.lexer.lineno)) - t.lexer.lineno = 0 - -def t_ENDFILE(t): - r'^\#\#endfile' - (old_filename, t.lexer.lineno) = fileNameStack.pop() - -# -# The functions t_NEWLINE, t_ignore, and t_error are -# special for the lex module. -# - -# Newlines -def t_NEWLINE(t): - r'\n+' - t.lexer.lineno += t.value.count('\n') - -# Comments -def t_comment(t): - r'//.*' - -# Completely ignored characters -t_ignore = ' \t\x0c' - -# Error handler -def t_error(t): - error(t.lexer.lineno, "illegal character '%s'" % t.value[0]) - t.skip(1) - -# Build the lexer -lexer = lex.lex() - -##################################################################### -# -# Parser -# -# Every function whose name starts with 'p_' defines a grammar rule. -# The rule is encoded in the function's doc string, while the -# function body provides the action taken when the rule is matched. -# The argument to each function is a list of the values of the -# rule's symbols: t[0] for the LHS, and t[1..n] for the symbols -# on the RHS. For tokens, the value is copied from the t.value -# attribute provided by the lexer. For non-terminals, the value -# is assigned by the producing rule; i.e., the job of the grammar -# rule function is to set the value for the non-terminal on the LHS -# (by assigning to t[0]). -##################################################################### - -# The LHS of the first grammar rule is used as the start symbol -# (in this case, 'specification'). Note that this rule enforces -# that there will be exactly one namespace declaration, with 0 or more -# global defs/decls before and after it. The defs & decls before -# the namespace decl will be outside the namespace; those after -# will be inside. The decoder function is always inside the namespace. -def p_specification(t): - 'specification : opt_defs_and_outputs name_decl opt_defs_and_outputs decode_block' - global_code = t[1] - isa_name = t[2] - namespace = isa_name + "Inst" - # wrap the decode block as a function definition - t[4].wrap_decode_block(''' + # Regular expressions for token matching + t_LPAREN = r'\(' + t_RPAREN = r'\)' + t_LBRACKET = r'\[' + t_RBRACKET = r'\]' + t_LBRACE = r'\{' + t_RBRACE = r'\}' + t_LESS = r'\<' + t_GREATER = r'\>' + t_EQUALS = r'=' + t_COMMA = r',' + t_SEMI = r';' + t_DOT = r'\.' + t_COLON = r':' + t_DBLCOLON = r'::' + t_ASTERISK = r'\*' + + # Identifiers and reserved words + reserved_map = { } + for r in reserved: + reserved_map[r.lower()] = r + + def t_ID(self, t): + r'[A-Za-z_]\w*' + t.type = self.reserved_map.get(t.value, 'ID') + return t + + # Integer literal + def t_INTLIT(self, t): + r'(0x[\da-fA-F]+)|\d+' + try: + t.value = int(t.value,0) + except ValueError: + error(t.lexer.lineno, 'Integer value "%s" too large' % t.value) + t.value = 0 + return t + + # String literal. Note that these use only single quotes, and + # can span multiple lines. + def t_STRLIT(self, t): + r"(?m)'([^'])+'" + # strip off quotes + t.value = t.value[1:-1] + t.lexer.lineno += t.value.count('\n') + return t + + + # "Code literal"... like a string literal, but delimiters are + # '{{' and '}}' so they get formatted nicely under emacs c-mode + def t_CODELIT(self, t): + r"(?m)\{\{([^\}]|}(?!\}))+\}\}" + # strip off {{ & }} + t.value = t.value[2:-2] + t.lexer.lineno += t.value.count('\n') + return t + + def t_CPPDIRECTIVE(self, t): + r'^\#[^\#].*\n' + t.lexer.lineno += t.value.count('\n') + return t + + def t_NEWFILE(self, t): + r'^\#\#newfile\s+"[\w/.-]*"' + fileNameStack.push((t.value[11:-1], t.lexer.lineno)) + t.lexer.lineno = 0 + + def t_ENDFILE(self, t): + r'^\#\#endfile' + (old_filename, t.lexer.lineno) = fileNameStack.pop() + + # + # The functions t_NEWLINE, t_ignore, and t_error are + # special for the lex module. + # + + # Newlines + def t_NEWLINE(self, t): + r'\n+' + t.lexer.lineno += t.value.count('\n') + + # Comments + def t_comment(self, t): + r'//.*' + + # Completely ignored characters + t_ignore = ' \t\x0c' + + # Error handler + def t_error(self, t): + error(t.lexer.lineno, "illegal character '%s'" % t.value[0]) + t.skip(1) + + ##################################################################### + # + # Parser + # + # Every function whose name starts with 'p_' defines a grammar + # rule. The rule is encoded in the function's doc string, while + # the function body provides the action taken when the rule is + # matched. The argument to each function is a list of the values + # of the rule's symbols: t[0] for the LHS, and t[1..n] for the + # symbols on the RHS. For tokens, the value is copied from the + # t.value attribute provided by the lexer. For non-terminals, the + # value is assigned by the producing rule; i.e., the job of the + # grammar rule function is to set the value for the non-terminal + # on the LHS (by assigning to t[0]). + ##################################################################### + + # The LHS of the first grammar rule is used as the start symbol + # (in this case, 'specification'). Note that this rule enforces + # that there will be exactly one namespace declaration, with 0 or + # more global defs/decls before and after it. The defs & decls + # before the namespace decl will be outside the namespace; those + # after will be inside. The decoder function is always inside the + # namespace. + def p_specification(self, t): + 'specification : opt_defs_and_outputs name_decl opt_defs_and_outputs decode_block' + global_code = t[1] + isa_name = t[2] + namespace = isa_name + "Inst" + # wrap the decode block as a function definition + t[4].wrap_decode_block(''' StaticInstPtr %(isa_name)s::decodeInst(%(isa_name)s::ExtMachInst machInst) { using namespace %(namespace)s; ''' % vars(), '}') - # both the latter output blocks and the decode block are in the namespace - namespace_code = t[3] + t[4] - # pass it all back to the caller of yacc.parse() - t[0] = (isa_name, namespace, global_code, namespace_code) - -# ISA name declaration looks like "namespace ;" -def p_name_decl(t): - 'name_decl : NAMESPACE ID SEMI' - t[0] = t[2] - -# 'opt_defs_and_outputs' is a possibly empty sequence of -# def and/or output statements. -def p_opt_defs_and_outputs_0(t): - 'opt_defs_and_outputs : empty' - t[0] = GenCode() - -def p_opt_defs_and_outputs_1(t): - 'opt_defs_and_outputs : defs_and_outputs' - t[0] = t[1] - -def p_defs_and_outputs_0(t): - 'defs_and_outputs : def_or_output' - t[0] = t[1] - -def p_defs_and_outputs_1(t): - 'defs_and_outputs : defs_and_outputs def_or_output' - t[0] = t[1] + t[2] - -# The list of possible definition/output statements. -def p_def_or_output(t): - '''def_or_output : def_format - | def_bitfield - | def_bitfield_struct - | def_template - | def_operand_types - | def_operands - | output_header - | output_decoder - | output_exec - | global_let''' - t[0] = t[1] - -# Output blocks 'output {{...}}' (C++ code blocks) are copied -# directly to the appropriate output section. - - -# Protect any non-dict-substitution '%'s in a format string -# (i.e. those not followed by '(') -def protect_non_subst_percents(s): - return re.sub(r'%(?!\()', '%%', s) - -# Massage output block by substituting in template definitions and bit -# operators. We handle '%'s embedded in the string that don't -# indicate template substitutions (or CPU-specific symbols, which get -# handled in GenCode) by doubling them first so that the format -# operation will reduce them back to single '%'s. -def process_output(s): - s = protect_non_subst_percents(s) - # protects cpu-specific symbols too - s = protect_cpu_symbols(s) - return substBitOps(s % templateMap) - -def p_output_header(t): - 'output_header : OUTPUT HEADER CODELIT SEMI' - t[0] = GenCode(header_output = process_output(t[3])) - -def p_output_decoder(t): - 'output_decoder : OUTPUT DECODER CODELIT SEMI' - t[0] = GenCode(decoder_output = process_output(t[3])) - -def p_output_exec(t): - 'output_exec : OUTPUT EXEC CODELIT SEMI' - t[0] = GenCode(exec_output = process_output(t[3])) - -# global let blocks 'let {{...}}' (Python code blocks) are executed -# directly when seen. Note that these execute in a special variable -# context 'exportContext' to prevent the code from polluting this -# script's namespace. -def p_global_let(t): - 'global_let : LET CODELIT SEMI' - updateExportContext() - exportContext["header_output"] = '' - exportContext["decoder_output"] = '' - exportContext["exec_output"] = '' - exportContext["decode_block"] = '' - try: - exec fixPythonIndentation(t[2]) in exportContext - except Exception, exc: - error(t.lexer.lineno, - 'error: %s in global let block "%s".' % (exc, t[2])) - t[0] = GenCode(header_output = exportContext["header_output"], - decoder_output = exportContext["decoder_output"], - exec_output = exportContext["exec_output"], - decode_block = exportContext["decode_block"]) - -# Define the mapping from operand type extensions to C++ types and bit -# widths (stored in operandTypeMap). -def p_def_operand_types(t): - 'def_operand_types : DEF OPERAND_TYPES CODELIT SEMI' - try: - userDict = eval('{' + t[3] + '}') - except Exception, exc: - error(t.lexer.lineno, - 'error: %s in def operand_types block "%s".' % (exc, t[3])) - buildOperandTypeMap(userDict, t.lexer.lineno) - t[0] = GenCode() # contributes nothing to the output C++ file - -# Define the mapping from operand names to operand classes and other -# traits. Stored in operandNameMap. -def p_def_operands(t): - 'def_operands : DEF OPERANDS CODELIT SEMI' - if not globals().has_key('operandTypeMap'): - error(t.lexer.lineno, - 'error: operand types must be defined before operands') - try: - userDict = eval('{' + t[3] + '}', exportContext) - except Exception, exc: - error(t.lexer.lineno, - 'error: %s in def operands block "%s".' % (exc, t[3])) - buildOperandNameMap(userDict, t.lexer.lineno) - t[0] = GenCode() # contributes nothing to the output C++ file - -# A bitfield definition looks like: -# 'def [signed] bitfield [:]' -# This generates a preprocessor macro in the output file. -def p_def_bitfield_0(t): - 'def_bitfield : DEF opt_signed BITFIELD ID LESS INTLIT COLON INTLIT GREATER SEMI' - expr = 'bits(machInst, %2d, %2d)' % (t[6], t[8]) - if (t[2] == 'signed'): - expr = 'sext<%d>(%s)' % (t[6] - t[8] + 1, expr) - hash_define = '#undef %s\n#define %s\t%s\n' % (t[4], t[4], expr) - t[0] = GenCode(header_output = hash_define) - -# alternate form for single bit: 'def [signed] bitfield []' -def p_def_bitfield_1(t): - 'def_bitfield : DEF opt_signed BITFIELD ID LESS INTLIT GREATER SEMI' - expr = 'bits(machInst, %2d, %2d)' % (t[6], t[6]) - if (t[2] == 'signed'): - expr = 'sext<%d>(%s)' % (1, expr) - hash_define = '#undef %s\n#define %s\t%s\n' % (t[4], t[4], expr) - t[0] = GenCode(header_output = hash_define) - -# alternate form for structure member: 'def bitfield ' -def p_def_bitfield_struct(t): - 'def_bitfield_struct : DEF opt_signed BITFIELD ID id_with_dot SEMI' - if (t[2] != ''): - error(t.lexer.lineno, 'error: structure bitfields are always unsigned.') - expr = 'machInst.%s' % t[5] - hash_define = '#undef %s\n#define %s\t%s\n' % (t[4], t[4], expr) - t[0] = GenCode(header_output = hash_define) - -def p_id_with_dot_0(t): - 'id_with_dot : ID' - t[0] = t[1] - -def p_id_with_dot_1(t): - 'id_with_dot : ID DOT id_with_dot' - t[0] = t[1] + t[2] + t[3] - -def p_opt_signed_0(t): - 'opt_signed : SIGNED' - t[0] = t[1] - -def p_opt_signed_1(t): - 'opt_signed : empty' - t[0] = '' - -# Global map variable to hold templates -templateMap = {} - -def p_def_template(t): - 'def_template : DEF TEMPLATE ID CODELIT SEMI' - templateMap[t[3]] = Template(t[4]) - t[0] = GenCode() - -# An instruction format definition looks like -# "def format () {{...}};" -def p_def_format(t): - 'def_format : DEF FORMAT ID LPAREN param_list RPAREN CODELIT SEMI' - (id, params, code) = (t[3], t[5], t[7]) - defFormat(id, params, code, t.lexer.lineno) - t[0] = GenCode() - -# The formal parameter list for an instruction format is a possibly -# empty list of comma-separated parameters. Positional (standard, -# non-keyword) parameters must come first, followed by keyword -# parameters, followed by a '*foo' parameter that gets excess -# positional arguments (as in Python). Each of these three parameter -# categories is optional. -# -# Note that we do not support the '**foo' parameter for collecting -# otherwise undefined keyword args. Otherwise the parameter list is -# (I believe) identical to what is supported in Python. -# -# The param list generates a tuple, where the first element is a list of -# the positional params and the second element is a dict containing the -# keyword params. -def p_param_list_0(t): - 'param_list : positional_param_list COMMA nonpositional_param_list' - t[0] = t[1] + t[3] - -def p_param_list_1(t): - '''param_list : positional_param_list - | nonpositional_param_list''' - t[0] = t[1] - -def p_positional_param_list_0(t): - 'positional_param_list : empty' - t[0] = [] - -def p_positional_param_list_1(t): - 'positional_param_list : ID' - t[0] = [t[1]] - -def p_positional_param_list_2(t): - 'positional_param_list : positional_param_list COMMA ID' - t[0] = t[1] + [t[3]] - -def p_nonpositional_param_list_0(t): - 'nonpositional_param_list : keyword_param_list COMMA excess_args_param' - t[0] = t[1] + t[3] - -def p_nonpositional_param_list_1(t): - '''nonpositional_param_list : keyword_param_list - | excess_args_param''' - t[0] = t[1] - -def p_keyword_param_list_0(t): - 'keyword_param_list : keyword_param' - t[0] = [t[1]] - -def p_keyword_param_list_1(t): - 'keyword_param_list : keyword_param_list COMMA keyword_param' - t[0] = t[1] + [t[3]] - -def p_keyword_param(t): - 'keyword_param : ID EQUALS expr' - t[0] = t[1] + ' = ' + t[3].__repr__() - -def p_excess_args_param(t): - 'excess_args_param : ASTERISK ID' - # Just concatenate them: '*ID'. Wrap in list to be consistent - # with positional_param_list and keyword_param_list. - t[0] = [t[1] + t[2]] - -# End of format definition-related rules. -############## - -# -# A decode block looks like: -# decode [, ]* [default ] { ... } -# -def p_decode_block(t): - 'decode_block : DECODE ID opt_default LBRACE decode_stmt_list RBRACE' - default_defaults = defaultStack.pop() - codeObj = t[5] - # use the "default defaults" only if there was no explicit - # default statement in decode_stmt_list - if not codeObj.has_decode_default: - codeObj += default_defaults - codeObj.wrap_decode_block('switch (%s) {\n' % t[2], '}\n') - t[0] = codeObj - -# The opt_default statement serves only to push the "default defaults" -# onto defaultStack. This value will be used by nested decode blocks, -# and used and popped off when the current decode_block is processed -# (in p_decode_block() above). -def p_opt_default_0(t): - 'opt_default : empty' - # no default specified: reuse the one currently at the top of the stack - defaultStack.push(defaultStack.top()) - # no meaningful value returned - t[0] = None - -def p_opt_default_1(t): - 'opt_default : DEFAULT inst' - # push the new default - codeObj = t[2] - codeObj.wrap_decode_block('\ndefault:\n', 'break;\n') - defaultStack.push(codeObj) - # no meaningful value returned - t[0] = None - -def p_decode_stmt_list_0(t): - 'decode_stmt_list : decode_stmt' - t[0] = t[1] - -def p_decode_stmt_list_1(t): - 'decode_stmt_list : decode_stmt decode_stmt_list' - if (t[1].has_decode_default and t[2].has_decode_default): - error(t.lexer.lineno, 'Two default cases in decode block') - t[0] = t[1] + t[2] - -# -# Decode statement rules -# -# There are four types of statements allowed in a decode block: -# 1. Format blocks 'format { ... }' -# 2. Nested decode blocks -# 3. Instruction definitions. -# 4. C preprocessor directives. - - -# Preprocessor directives found in a decode statement list are passed -# through to the output, replicated to all of the output code -# streams. This works well for ifdefs, so we can ifdef out both the -# declarations and the decode cases generated by an instruction -# definition. Handling them as part of the grammar makes it easy to -# keep them in the right place with respect to the code generated by -# the other statements. -def p_decode_stmt_cpp(t): - 'decode_stmt : CPPDIRECTIVE' - t[0] = GenCode(t[1], t[1], t[1], t[1]) - -# A format block 'format { ... }' sets the default instruction -# format used to handle instruction definitions inside the block. -# This format can be overridden by using an explicit format on the -# instruction definition or with a nested format block. -def p_decode_stmt_format(t): - 'decode_stmt : FORMAT push_format_id LBRACE decode_stmt_list RBRACE' - # The format will be pushed on the stack when 'push_format_id' is - # processed (see below). Once the parser has recognized the full - # production (though the right brace), we're done with the format, - # so now we can pop it. - formatStack.pop() - t[0] = t[4] - -# This rule exists so we can set the current format (& push the stack) -# when we recognize the format name part of the format block. -def p_push_format_id(t): - 'push_format_id : ID' - try: - formatStack.push(formatMap[t[1]]) - t[0] = ('', '// format %s' % t[1]) - except KeyError: - error(t.lexer.lineno, 'instruction format "%s" not defined.' % t[1]) - -# Nested decode block: if the value of the current field matches the -# specified constant, do a nested decode on some other field. -def p_decode_stmt_decode(t): - 'decode_stmt : case_label COLON decode_block' - label = t[1] - codeObj = t[3] - # just wrap the decoding code from the block as a case in the - # outer switch statement. - codeObj.wrap_decode_block('\n%s:\n' % label) - codeObj.has_decode_default = (label == 'default') - t[0] = codeObj - -# Instruction definition (finally!). -def p_decode_stmt_inst(t): - 'decode_stmt : case_label COLON inst SEMI' - label = t[1] - codeObj = t[3] - codeObj.wrap_decode_block('\n%s:' % label, 'break;\n') - codeObj.has_decode_default = (label == 'default') - t[0] = codeObj - -# The case label is either a list of one or more constants or 'default' -def p_case_label_0(t): - 'case_label : intlit_list' - t[0] = ': '.join(map(lambda a: 'case %#x' % a, t[1])) - -def p_case_label_1(t): - 'case_label : DEFAULT' - t[0] = 'default' - -# -# The constant list for a decode case label must be non-empty, but may have -# one or more comma-separated integer literals in it. -# -def p_intlit_list_0(t): - 'intlit_list : INTLIT' - t[0] = [t[1]] - -def p_intlit_list_1(t): - 'intlit_list : intlit_list COMMA INTLIT' - t[0] = t[1] - t[0].append(t[3]) - -# Define an instruction using the current instruction format (specified -# by an enclosing format block). -# "()" -def p_inst_0(t): - 'inst : ID LPAREN arg_list RPAREN' - # Pass the ID and arg list to the current format class to deal with. - currentFormat = formatStack.top() - codeObj = currentFormat.defineInst(t[1], t[3], t.lexer.lineno) - args = ','.join(map(str, t[3])) - args = re.sub('(?m)^', '//', args) - args = re.sub('^//', '', args) - comment = '\n// %s::%s(%s)\n' % (currentFormat.id, t[1], args) - codeObj.prepend_all(comment) - t[0] = codeObj - -# Define an instruction using an explicitly specified format: -# "::()" -def p_inst_1(t): - 'inst : ID DBLCOLON ID LPAREN arg_list RPAREN' - try: - format = formatMap[t[1]] - except KeyError: - error(t.lexer.lineno, 'instruction format "%s" not defined.' % t[1]) - codeObj = format.defineInst(t[3], t[5], t.lexer.lineno) - comment = '\n// %s::%s(%s)\n' % (t[1], t[3], t[5]) - codeObj.prepend_all(comment) - t[0] = codeObj - -# The arg list generates a tuple, where the first element is a list of -# the positional args and the second element is a dict containing the -# keyword args. -def p_arg_list_0(t): - 'arg_list : positional_arg_list COMMA keyword_arg_list' - t[0] = ( t[1], t[3] ) - -def p_arg_list_1(t): - 'arg_list : positional_arg_list' - t[0] = ( t[1], {} ) - -def p_arg_list_2(t): - 'arg_list : keyword_arg_list' - t[0] = ( [], t[1] ) - -def p_positional_arg_list_0(t): - 'positional_arg_list : empty' - t[0] = [] - -def p_positional_arg_list_1(t): - 'positional_arg_list : expr' - t[0] = [t[1]] - -def p_positional_arg_list_2(t): - 'positional_arg_list : positional_arg_list COMMA expr' - t[0] = t[1] + [t[3]] - -def p_keyword_arg_list_0(t): - 'keyword_arg_list : keyword_arg' - t[0] = t[1] - -def p_keyword_arg_list_1(t): - 'keyword_arg_list : keyword_arg_list COMMA keyword_arg' - t[0] = t[1] - t[0].update(t[3]) - -def p_keyword_arg(t): - 'keyword_arg : ID EQUALS expr' - t[0] = { t[1] : t[3] } - -# -# Basic expressions. These constitute the argument values of -# "function calls" (i.e. instruction definitions in the decode block) -# and default values for formal parameters of format functions. -# -# Right now, these are either strings, integers, or (recursively) -# lists of exprs (using Python square-bracket list syntax). Note that -# bare identifiers are trated as string constants here (since there -# isn't really a variable namespace to refer to). -# -def p_expr_0(t): - '''expr : ID - | INTLIT - | STRLIT - | CODELIT''' - t[0] = t[1] - -def p_expr_1(t): - '''expr : LBRACKET list_expr RBRACKET''' - t[0] = t[2] - -def p_list_expr_0(t): - 'list_expr : expr' - t[0] = [t[1]] - -def p_list_expr_1(t): - 'list_expr : list_expr COMMA expr' - t[0] = t[1] + [t[3]] - -def p_list_expr_2(t): - 'list_expr : empty' - t[0] = [] + # both the latter output blocks and the decode block are in + # the namespace + namespace_code = t[3] + t[4] + # pass it all back to the caller of yacc.parse() + t[0] = (isa_name, namespace, global_code, namespace_code) + + # ISA name declaration looks like "namespace ;" + def p_name_decl(self, t): + 'name_decl : NAMESPACE ID SEMI' + t[0] = t[2] + + # 'opt_defs_and_outputs' is a possibly empty sequence of + # def and/or output statements. + def p_opt_defs_and_outputs_0(self, t): + 'opt_defs_and_outputs : empty' + t[0] = GenCode() + + def p_opt_defs_and_outputs_1(self, t): + 'opt_defs_and_outputs : defs_and_outputs' + t[0] = t[1] + + def p_defs_and_outputs_0(self, t): + 'defs_and_outputs : def_or_output' + t[0] = t[1] + + def p_defs_and_outputs_1(self, t): + 'defs_and_outputs : defs_and_outputs def_or_output' + t[0] = t[1] + t[2] + + # The list of possible definition/output statements. + def p_def_or_output(self, t): + '''def_or_output : def_format + | def_bitfield + | def_bitfield_struct + | def_template + | def_operand_types + | def_operands + | output_header + | output_decoder + | output_exec + | global_let''' + t[0] = t[1] + + # Output blocks 'output {{...}}' (C++ code blocks) are copied + # directly to the appropriate output section. + + # Massage output block by substituting in template definitions and + # bit operators. We handle '%'s embedded in the string that don't + # indicate template substitutions (or CPU-specific symbols, which + # get handled in GenCode) by doubling them first so that the + # format operation will reduce them back to single '%'s. + def process_output(self, s): + s = protect_non_subst_percents(s) + # protects cpu-specific symbols too + s = protect_cpu_symbols(s) + return substBitOps(s % self.templateMap) + + def p_output_header(self, t): + 'output_header : OUTPUT HEADER CODELIT SEMI' + t[0] = GenCode(header_output = self.process_output(t[3])) + + def p_output_decoder(self, t): + 'output_decoder : OUTPUT DECODER CODELIT SEMI' + t[0] = GenCode(decoder_output = self.process_output(t[3])) + + def p_output_exec(self, t): + 'output_exec : OUTPUT EXEC CODELIT SEMI' + t[0] = GenCode(exec_output = self.process_output(t[3])) + + # global let blocks 'let {{...}}' (Python code blocks) are + # executed directly when seen. Note that these execute in a + # special variable context 'exportContext' to prevent the code + # from polluting this script's namespace. + def p_global_let(self, t): + 'global_let : LET CODELIT SEMI' + updateExportContext() + exportContext["header_output"] = '' + exportContext["decoder_output"] = '' + exportContext["exec_output"] = '' + exportContext["decode_block"] = '' + try: + exec fixPythonIndentation(t[2]) in exportContext + except Exception, exc: + error(t.lexer.lineno, + 'error: %s in global let block "%s".' % (exc, t[2])) + t[0] = GenCode(header_output = exportContext["header_output"], + decoder_output = exportContext["decoder_output"], + exec_output = exportContext["exec_output"], + decode_block = exportContext["decode_block"]) + + # Define the mapping from operand type extensions to C++ types and + # bit widths (stored in operandTypeMap). + def p_def_operand_types(self, t): + 'def_operand_types : DEF OPERAND_TYPES CODELIT SEMI' + try: + userDict = eval('{' + t[3] + '}') + except Exception, exc: + error(t.lexer.lineno, + 'error: %s in def operand_types block "%s".' % (exc, t[3])) + buildOperandTypeMap(userDict, t.lexer.lineno) + t[0] = GenCode() # contributes nothing to the output C++ file + + # Define the mapping from operand names to operand classes and + # other traits. Stored in operandNameMap. + def p_def_operands(self, t): + 'def_operands : DEF OPERANDS CODELIT SEMI' + if not globals().has_key('operandTypeMap'): + error(t.lexer.lineno, + 'error: operand types must be defined before operands') + try: + userDict = eval('{' + t[3] + '}', exportContext) + except Exception, exc: + error(t.lexer.lineno, + 'error: %s in def operands block "%s".' % (exc, t[3])) + buildOperandNameMap(userDict, t.lexer.lineno) + t[0] = GenCode() # contributes nothing to the output C++ file + + # A bitfield definition looks like: + # 'def [signed] bitfield [:]' + # This generates a preprocessor macro in the output file. + def p_def_bitfield_0(self, t): + 'def_bitfield : DEF opt_signed BITFIELD ID LESS INTLIT COLON INTLIT GREATER SEMI' + expr = 'bits(machInst, %2d, %2d)' % (t[6], t[8]) + if (t[2] == 'signed'): + expr = 'sext<%d>(%s)' % (t[6] - t[8] + 1, expr) + hash_define = '#undef %s\n#define %s\t%s\n' % (t[4], t[4], expr) + t[0] = GenCode(header_output = hash_define) + + # alternate form for single bit: 'def [signed] bitfield []' + def p_def_bitfield_1(self, t): + 'def_bitfield : DEF opt_signed BITFIELD ID LESS INTLIT GREATER SEMI' + expr = 'bits(machInst, %2d, %2d)' % (t[6], t[6]) + if (t[2] == 'signed'): + expr = 'sext<%d>(%s)' % (1, expr) + hash_define = '#undef %s\n#define %s\t%s\n' % (t[4], t[4], expr) + t[0] = GenCode(header_output = hash_define) + + # alternate form for structure member: 'def bitfield ' + def p_def_bitfield_struct(self, t): + 'def_bitfield_struct : DEF opt_signed BITFIELD ID id_with_dot SEMI' + if (t[2] != ''): + error(t.lexer.lineno, + 'error: structure bitfields are always unsigned.') + expr = 'machInst.%s' % t[5] + hash_define = '#undef %s\n#define %s\t%s\n' % (t[4], t[4], expr) + t[0] = GenCode(header_output = hash_define) + + def p_id_with_dot_0(self, t): + 'id_with_dot : ID' + t[0] = t[1] + + def p_id_with_dot_1(self, t): + 'id_with_dot : ID DOT id_with_dot' + t[0] = t[1] + t[2] + t[3] + + def p_opt_signed_0(self, t): + 'opt_signed : SIGNED' + t[0] = t[1] + + def p_opt_signed_1(self, t): + 'opt_signed : empty' + t[0] = '' + + def p_def_template(self, t): + 'def_template : DEF TEMPLATE ID CODELIT SEMI' + self.templateMap[t[3]] = Template(t[4]) + t[0] = GenCode() + + # An instruction format definition looks like + # "def format () {{...}};" + def p_def_format(self, t): + 'def_format : DEF FORMAT ID LPAREN param_list RPAREN CODELIT SEMI' + (id, params, code) = (t[3], t[5], t[7]) + defFormat(id, params, code, t.lexer.lineno) + t[0] = GenCode() + + # The formal parameter list for an instruction format is a + # possibly empty list of comma-separated parameters. Positional + # (standard, non-keyword) parameters must come first, followed by + # keyword parameters, followed by a '*foo' parameter that gets + # excess positional arguments (as in Python). Each of these three + # parameter categories is optional. + # + # Note that we do not support the '**foo' parameter for collecting + # otherwise undefined keyword args. Otherwise the parameter list + # is (I believe) identical to what is supported in Python. + # + # The param list generates a tuple, where the first element is a + # list of the positional params and the second element is a dict + # containing the keyword params. + def p_param_list_0(self, t): + 'param_list : positional_param_list COMMA nonpositional_param_list' + t[0] = t[1] + t[3] + + def p_param_list_1(self, t): + '''param_list : positional_param_list + | nonpositional_param_list''' + t[0] = t[1] + + def p_positional_param_list_0(self, t): + 'positional_param_list : empty' + t[0] = [] + + def p_positional_param_list_1(self, t): + 'positional_param_list : ID' + t[0] = [t[1]] + + def p_positional_param_list_2(self, t): + 'positional_param_list : positional_param_list COMMA ID' + t[0] = t[1] + [t[3]] + + def p_nonpositional_param_list_0(self, t): + 'nonpositional_param_list : keyword_param_list COMMA excess_args_param' + t[0] = t[1] + t[3] + + def p_nonpositional_param_list_1(self, t): + '''nonpositional_param_list : keyword_param_list + | excess_args_param''' + t[0] = t[1] + + def p_keyword_param_list_0(self, t): + 'keyword_param_list : keyword_param' + t[0] = [t[1]] + + def p_keyword_param_list_1(self, t): + 'keyword_param_list : keyword_param_list COMMA keyword_param' + t[0] = t[1] + [t[3]] + + def p_keyword_param(self, t): + 'keyword_param : ID EQUALS expr' + t[0] = t[1] + ' = ' + t[3].__repr__() + + def p_excess_args_param(self, t): + 'excess_args_param : ASTERISK ID' + # Just concatenate them: '*ID'. Wrap in list to be consistent + # with positional_param_list and keyword_param_list. + t[0] = [t[1] + t[2]] + + # End of format definition-related rules. + ############## + + # + # A decode block looks like: + # decode [, ]* [default ] { ... } + # + def p_decode_block(self, t): + 'decode_block : DECODE ID opt_default LBRACE decode_stmt_list RBRACE' + default_defaults = defaultStack.pop() + codeObj = t[5] + # use the "default defaults" only if there was no explicit + # default statement in decode_stmt_list + if not codeObj.has_decode_default: + codeObj += default_defaults + codeObj.wrap_decode_block('switch (%s) {\n' % t[2], '}\n') + t[0] = codeObj + + # The opt_default statement serves only to push the "default + # defaults" onto defaultStack. This value will be used by nested + # decode blocks, and used and popped off when the current + # decode_block is processed (in p_decode_block() above). + def p_opt_default_0(self, t): + 'opt_default : empty' + # no default specified: reuse the one currently at the top of + # the stack + defaultStack.push(defaultStack.top()) + # no meaningful value returned + t[0] = None + + def p_opt_default_1(self, t): + 'opt_default : DEFAULT inst' + # push the new default + codeObj = t[2] + codeObj.wrap_decode_block('\ndefault:\n', 'break;\n') + defaultStack.push(codeObj) + # no meaningful value returned + t[0] = None + + def p_decode_stmt_list_0(self, t): + 'decode_stmt_list : decode_stmt' + t[0] = t[1] + + def p_decode_stmt_list_1(self, t): + 'decode_stmt_list : decode_stmt decode_stmt_list' + if (t[1].has_decode_default and t[2].has_decode_default): + error(t.lexer.lineno, 'Two default cases in decode block') + t[0] = t[1] + t[2] + + # + # Decode statement rules + # + # There are four types of statements allowed in a decode block: + # 1. Format blocks 'format { ... }' + # 2. Nested decode blocks + # 3. Instruction definitions. + # 4. C preprocessor directives. + + + # Preprocessor directives found in a decode statement list are + # passed through to the output, replicated to all of the output + # code streams. This works well for ifdefs, so we can ifdef out + # both the declarations and the decode cases generated by an + # instruction definition. Handling them as part of the grammar + # makes it easy to keep them in the right place with respect to + # the code generated by the other statements. + def p_decode_stmt_cpp(self, t): + 'decode_stmt : CPPDIRECTIVE' + t[0] = GenCode(t[1], t[1], t[1], t[1]) + + # A format block 'format { ... }' sets the default + # instruction format used to handle instruction definitions inside + # the block. This format can be overridden by using an explicit + # format on the instruction definition or with a nested format + # block. + def p_decode_stmt_format(self, t): + 'decode_stmt : FORMAT push_format_id LBRACE decode_stmt_list RBRACE' + # The format will be pushed on the stack when 'push_format_id' + # is processed (see below). Once the parser has recognized + # the full production (though the right brace), we're done + # with the format, so now we can pop it. + formatStack.pop() + t[0] = t[4] + + # This rule exists so we can set the current format (& push the + # stack) when we recognize the format name part of the format + # block. + def p_push_format_id(self, t): + 'push_format_id : ID' + try: + formatStack.push(formatMap[t[1]]) + t[0] = ('', '// format %s' % t[1]) + except KeyError: + error(t.lexer.lineno, + 'instruction format "%s" not defined.' % t[1]) + + # Nested decode block: if the value of the current field matches + # the specified constant, do a nested decode on some other field. + def p_decode_stmt_decode(self, t): + 'decode_stmt : case_label COLON decode_block' + label = t[1] + codeObj = t[3] + # just wrap the decoding code from the block as a case in the + # outer switch statement. + codeObj.wrap_decode_block('\n%s:\n' % label) + codeObj.has_decode_default = (label == 'default') + t[0] = codeObj + + # Instruction definition (finally!). + def p_decode_stmt_inst(self, t): + 'decode_stmt : case_label COLON inst SEMI' + label = t[1] + codeObj = t[3] + codeObj.wrap_decode_block('\n%s:' % label, 'break;\n') + codeObj.has_decode_default = (label == 'default') + t[0] = codeObj + + # The case label is either a list of one or more constants or + # 'default' + def p_case_label_0(self, t): + 'case_label : intlit_list' + t[0] = ': '.join(map(lambda a: 'case %#x' % a, t[1])) + + def p_case_label_1(self, t): + 'case_label : DEFAULT' + t[0] = 'default' + + # + # The constant list for a decode case label must be non-empty, but + # may have one or more comma-separated integer literals in it. + # + def p_intlit_list_0(self, t): + 'intlit_list : INTLIT' + t[0] = [t[1]] + + def p_intlit_list_1(self, t): + 'intlit_list : intlit_list COMMA INTLIT' + t[0] = t[1] + t[0].append(t[3]) + + # Define an instruction using the current instruction format + # (specified by an enclosing format block). + # "()" + def p_inst_0(self, t): + 'inst : ID LPAREN arg_list RPAREN' + # Pass the ID and arg list to the current format class to deal with. + currentFormat = formatStack.top() + codeObj = currentFormat.defineInst(t[1], t[3], t.lexer.lineno) + args = ','.join(map(str, t[3])) + args = re.sub('(?m)^', '//', args) + args = re.sub('^//', '', args) + comment = '\n// %s::%s(%s)\n' % (currentFormat.id, t[1], args) + codeObj.prepend_all(comment) + t[0] = codeObj + + # Define an instruction using an explicitly specified format: + # "::()" + def p_inst_1(self, t): + 'inst : ID DBLCOLON ID LPAREN arg_list RPAREN' + try: + format = formatMap[t[1]] + except KeyError: + error(t.lexer.lineno, + 'instruction format "%s" not defined.' % t[1]) + codeObj = format.defineInst(t[3], t[5], t.lexer.lineno) + comment = '\n// %s::%s(%s)\n' % (t[1], t[3], t[5]) + codeObj.prepend_all(comment) + t[0] = codeObj + + # The arg list generates a tuple, where the first element is a + # list of the positional args and the second element is a dict + # containing the keyword args. + def p_arg_list_0(self, t): + 'arg_list : positional_arg_list COMMA keyword_arg_list' + t[0] = ( t[1], t[3] ) + + def p_arg_list_1(self, t): + 'arg_list : positional_arg_list' + t[0] = ( t[1], {} ) + + def p_arg_list_2(self, t): + 'arg_list : keyword_arg_list' + t[0] = ( [], t[1] ) + + def p_positional_arg_list_0(self, t): + 'positional_arg_list : empty' + t[0] = [] + + def p_positional_arg_list_1(self, t): + 'positional_arg_list : expr' + t[0] = [t[1]] + + def p_positional_arg_list_2(self, t): + 'positional_arg_list : positional_arg_list COMMA expr' + t[0] = t[1] + [t[3]] + + def p_keyword_arg_list_0(self, t): + 'keyword_arg_list : keyword_arg' + t[0] = t[1] + + def p_keyword_arg_list_1(self, t): + 'keyword_arg_list : keyword_arg_list COMMA keyword_arg' + t[0] = t[1] + t[0].update(t[3]) + + def p_keyword_arg(self, t): + 'keyword_arg : ID EQUALS expr' + t[0] = { t[1] : t[3] } + + # + # Basic expressions. These constitute the argument values of + # "function calls" (i.e. instruction definitions in the decode + # block) and default values for formal parameters of format + # functions. + # + # Right now, these are either strings, integers, or (recursively) + # lists of exprs (using Python square-bracket list syntax). Note + # that bare identifiers are trated as string constants here (since + # there isn't really a variable namespace to refer to). + # + def p_expr_0(self, t): + '''expr : ID + | INTLIT + | STRLIT + | CODELIT''' + t[0] = t[1] + + def p_expr_1(self, t): + '''expr : LBRACKET list_expr RBRACKET''' + t[0] = t[2] + + def p_list_expr_0(self, t): + 'list_expr : expr' + t[0] = [t[1]] + + def p_list_expr_1(self, t): + 'list_expr : list_expr COMMA expr' + t[0] = t[1] + [t[3]] + + def p_list_expr_2(self, t): + 'list_expr : empty' + t[0] = [] + + # + # Empty production... use in other rules for readability. + # + def p_empty(self, t): + 'empty :' + pass + + # Parse error handler. Note that the argument here is the + # offending *token*, not a grammar symbol (hence the need to use + # t.value) + def p_error(self, t): + if t: + error(t.lexer.lineno, "syntax error at '%s'" % t.value) + else: + error(0, "unknown syntax error", True) -# -# Empty production... use in other rules for readability. -# -def p_empty(t): - 'empty :' - pass - -# Parse error handler. Note that the argument here is the offending -# *token*, not a grammar symbol (hence the need to use t.value) -def p_error(t): - if t: - error(t.lexer.lineno, "syntax error at '%s'" % t.value) - else: - error(0, "unknown syntax error", True) + # END OF GRAMMAR RULES -# END OF GRAMMAR RULES -# # Now build the parser. -parser = yacc.yacc() - +parser = ISAParser() ##################################################################### # @@ -761,6 +763,11 @@ def expand_cpu_symbols_to_string(template): def protect_cpu_symbols(template): return re.sub(r'%(?=\(CPU_)', '%%', template) +# Protect any non-dict-substitution '%'s in a format string +# (i.e. those not followed by '(') +def protect_non_subst_percents(s): + return re.sub(r'%(?!\()', '%%', s) + ############### # GenCode class # @@ -834,7 +841,7 @@ exportContext = {} def updateExportContext(): exportContext.update(exportDict(*exportContextSymbols)) - exportContext.update(templateMap) + exportContext.update(parser.templateMap) def exportDict(*symNames): return dict([(s, eval(s)) for s in symNames]) @@ -1044,7 +1051,7 @@ class Template: # Build a dict ('myDict') to use for the template substitution. # Start with the template namespace. Make a copy since we're # going to modify it. - myDict = templateMap.copy() + myDict = parser.templateMap.copy() if isinstance(d, InstObjParams): # If we're dealing with an InstObjParams object, we need @@ -1970,8 +1977,7 @@ def parse_isa_desc(isa_desc_file, output_dir): fileNameStack.push((isa_desc_file, 0)) # Parse it. - (isa_name, namespace, global_code, namespace_code) = \ - parser.parse(isa_desc, lexer=lexer) + (isa_name, namespace, global_code, namespace_code) = parser.parse(isa_desc) # grab the last three path components of isa_desc_file to put in # the output -- cgit v1.2.3 From 44ceb80c2dd1c4991357292ca27809b5012b9556 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 2 Oct 2009 01:32:58 -0700 Subject: X86: Make successive anonymous mmaps move down in 32 bit SE mode Linux. --- src/arch/x86/linux/linux.hh | 4 +++- src/arch/x86/process.cc | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/linux/linux.hh b/src/arch/x86/linux/linux.hh index d5bead8f3..a810d4a79 100644 --- a/src/arch/x86/linux/linux.hh +++ b/src/arch/x86/linux/linux.hh @@ -190,7 +190,9 @@ class X86Linux32 : public Linux uint32_t totalhigh; /* Total high memory size */ uint32_t freehigh; /* Available high memory size */ uint32_t mem_unit; /* Memory unit size in bytes */ - } tgt_sysinfo; + } tgt_sysinfo; + + static bool mmapGrowsDown() { return true; } }; #endif diff --git a/src/arch/x86/process.cc b/src/arch/x86/process.cc index 4082e568c..f7678443d 100644 --- a/src/arch/x86/process.cc +++ b/src/arch/x86/process.cc @@ -184,7 +184,7 @@ I386LiveProcess::I386LiveProcess(LiveProcessParams *params, // Set up region for mmaps. This was determined empirically and may not // always be correct. - mmap_start = mmap_end = (Addr)0xf7ffd000ULL; + mmap_start = mmap_end = (Addr)0xf7ffe000ULL; } SyscallDesc* -- cgit v1.2.3 From 30a185dcd04cc7797609398219482d03a68509f9 Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Sat, 10 Oct 2009 22:31:56 -0700 Subject: Hook up the munmap() syscall for 32-bit x86. This is straightforward, as munmapFunc() doesn't do anything. I've tested it with code running munmap() just in case. --- src/arch/x86/linux/syscalls.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/arch') diff --git a/src/arch/x86/linux/syscalls.cc b/src/arch/x86/linux/syscalls.cc index 52352ee80..affe2d6ea 100644 --- a/src/arch/x86/linux/syscalls.cc +++ b/src/arch/x86/linux/syscalls.cc @@ -598,7 +598,7 @@ SyscallDesc I386LinuxProcess::syscallDescs[] = { /* 88 */ SyscallDesc("reboot", unimplementedFunc), /* 89 */ SyscallDesc("readdir", unimplementedFunc), /* 90 */ SyscallDesc("mmap", unimplementedFunc), - /* 91 */ SyscallDesc("munmap", unimplementedFunc), + /* 91 */ SyscallDesc("munmap", munmapFunc), /* 92 */ SyscallDesc("truncate", unimplementedFunc), /* 93 */ SyscallDesc("ftruncate", unimplementedFunc), /* 94 */ SyscallDesc("fchmod", unimplementedFunc), -- cgit v1.2.3 From 010b13c937c80b9138d5c70fda6c47ea75d2a9b3 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sat, 17 Oct 2009 01:13:41 -0700 Subject: ISA: Fix compilation. --- src/arch/alpha/isa.cc | 4 ++-- src/arch/alpha/isa.hh | 5 +++-- src/arch/arm/isa.hh | 5 +++-- src/arch/mips/isa.hh | 7 +++++-- 4 files changed, 13 insertions(+), 8 deletions(-) (limited to 'src/arch') diff --git a/src/arch/alpha/isa.cc b/src/arch/alpha/isa.cc index eee391a0d..8b6da3649 100644 --- a/src/arch/alpha/isa.cc +++ b/src/arch/alpha/isa.cc @@ -36,7 +36,7 @@ namespace AlphaISA { void -ISA::serialize(std::ostream &os) +ISA::serialize(EventManager *em, std::ostream &os) { SERIALIZE_SCALAR(fpcr); SERIALIZE_SCALAR(uniq); @@ -46,7 +46,7 @@ ISA::serialize(std::ostream &os) } void -ISA::unserialize(Checkpoint *cp, const std::string §ion) +ISA::unserialize(EventManager *em, Checkpoint *cp, const std::string §ion) { UNSERIALIZE_SCALAR(fpcr); UNSERIALIZE_SCALAR(uniq); diff --git a/src/arch/alpha/isa.hh b/src/arch/alpha/isa.hh index 622d1da4c..574b50841 100644 --- a/src/arch/alpha/isa.hh +++ b/src/arch/alpha/isa.hh @@ -83,8 +83,9 @@ namespace AlphaISA intr_flag = 0; } - void serialize(std::ostream &os); - void unserialize(Checkpoint *cp, const std::string §ion); + void serialize(EventManager *em, std::ostream &os); + void unserialize(EventManager *em, Checkpoint *cp, + const std::string §ion); void reset(std::string core_name, ThreadID num_threads, unsigned num_vpes, BaseCPU *_cpu) diff --git a/src/arch/arm/isa.hh b/src/arch/arm/isa.hh index 2315afa9e..9b21c03cd 100644 --- a/src/arch/arm/isa.hh +++ b/src/arch/arm/isa.hh @@ -95,9 +95,10 @@ namespace ArmISA return reg; } - void serialize(std::ostream &os) + void serialize(EventManager *em, std::ostream &os) {} - void unserialize(Checkpoint *cp, const std::string §ion) + void unserialize(EventManager *em, Checkpoint *cp, + const std::string §ion) {} ISA() diff --git a/src/arch/mips/isa.hh b/src/arch/mips/isa.hh index 15c043dc0..165adff83 100644 --- a/src/arch/mips/isa.hh +++ b/src/arch/mips/isa.hh @@ -172,8 +172,11 @@ namespace MipsISA return reg; } - void serialize(std::ostream &os); - void unserialize(Checkpoint *cp, const std::string §ion); + void serialize(EventManager *em, std::ostream &os) + {} + void unserialize(EventManager *em, Checkpoint *cp, + const std::string §ion) + {} }; } -- cgit v1.2.3 From 22dc2b5595519d5fc7ca93854053b22a359e331b Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Fri, 16 Oct 2009 13:54:20 -0400 Subject: Ignore rt_sigaction() syscalls on x86 and x86_64 This is currently how alpha handles this syscall. This is needed for the gcc spec2k benchmarks to run. --- src/arch/x86/linux/syscalls.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/linux/syscalls.cc b/src/arch/x86/linux/syscalls.cc index affe2d6ea..74a6ad0b7 100644 --- a/src/arch/x86/linux/syscalls.cc +++ b/src/arch/x86/linux/syscalls.cc @@ -241,7 +241,7 @@ SyscallDesc X86_64LinuxProcess::syscallDescs[] = { /* 10 */ SyscallDesc("mprotect", unimplementedFunc), /* 11 */ SyscallDesc("munmap", munmapFunc), /* 12 */ SyscallDesc("brk", brkFunc), - /* 13 */ SyscallDesc("rt_sigaction", unimplementedFunc), + /* 13 */ SyscallDesc("rt_sigaction", ignoreFunc), /* 14 */ SyscallDesc("rt_sigprocmask", unimplementedFunc), /* 15 */ SyscallDesc("rt_sigreturn", unimplementedFunc), /* 16 */ SyscallDesc("ioctl", unimplementedFunc), @@ -681,7 +681,7 @@ SyscallDesc I386LinuxProcess::syscallDescs[] = { /* 171 */ SyscallDesc("getresgid", unimplementedFunc), /* 172 */ SyscallDesc("prctl", unimplementedFunc), /* 173 */ SyscallDesc("rt_sigreturn", unimplementedFunc), - /* 174 */ SyscallDesc("rt_sigaction", unimplementedFunc), + /* 174 */ SyscallDesc("rt_sigaction", ignoreFunc), /* 175 */ SyscallDesc("rt_sigprocmask", unimplementedFunc), /* 176 */ SyscallDesc("rt_sigpending", unimplementedFunc), /* 177 */ SyscallDesc("rt_sigtimedwait", unimplementedFunc), -- cgit v1.2.3 From 56154cff5eab4a28a6d86a820a4364f99889555f Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Mon, 19 Oct 2009 17:29:34 -0400 Subject: Enable getuid and getgid related syscalls on X86_SE I've tested these on x86 and they work as expected. In theory for 32-bit x86 we should have some sort of special handling for the legacy 16-bit uid/gid syscalls, but in practice modern toolchains don't use the 16-bit versions, and m5 sets the uid and gid values to be less than 16-bits anyway. This fix is needed for the perl spec2k benchmarks to run. --- src/arch/x86/linux/syscalls.cc | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/linux/syscalls.cc b/src/arch/x86/linux/syscalls.cc index 74a6ad0b7..2b54843f3 100644 --- a/src/arch/x86/linux/syscalls.cc +++ b/src/arch/x86/linux/syscalls.cc @@ -531,7 +531,7 @@ SyscallDesc I386LinuxProcess::syscallDescs[] = { /* 21 */ SyscallDesc("mount", unimplementedFunc), /* 22 */ SyscallDesc("umount", unimplementedFunc), /* 23 */ SyscallDesc("setuid", unimplementedFunc), - /* 24 */ SyscallDesc("getuid", unimplementedFunc), + /* 24 */ SyscallDesc("getuid", getuidFunc), /* 25 */ SyscallDesc("stime", unimplementedFunc), /* 26 */ SyscallDesc("ptrace", unimplementedFunc), /* 27 */ SyscallDesc("alarm", unimplementedFunc), @@ -554,10 +554,10 @@ SyscallDesc I386LinuxProcess::syscallDescs[] = { /* 44 */ SyscallDesc("prof", unimplementedFunc), /* 45 */ SyscallDesc("brk", brkFunc), /* 46 */ SyscallDesc("setgid", unimplementedFunc), - /* 47 */ SyscallDesc("getgid", unimplementedFunc), + /* 47 */ SyscallDesc("getgid", getgidFunc), /* 48 */ SyscallDesc("signal", unimplementedFunc), - /* 49 */ SyscallDesc("geteuid", unimplementedFunc), - /* 50 */ SyscallDesc("getegid", unimplementedFunc), + /* 49 */ SyscallDesc("geteuid", geteuidFunc), + /* 50 */ SyscallDesc("getegid", getegidFunc), /* 51 */ SyscallDesc("acct", unimplementedFunc), /* 52 */ SyscallDesc("umount2", unimplementedFunc), /* 53 */ SyscallDesc("lock", unimplementedFunc), @@ -706,10 +706,10 @@ SyscallDesc I386LinuxProcess::syscallDescs[] = { /* 196 */ SyscallDesc("lstat64", unimplementedFunc), /* 197 */ SyscallDesc("fstat64", fstat64Func), /* 198 */ SyscallDesc("lchown32", unimplementedFunc), - /* 199 */ SyscallDesc("getuid32", unimplementedFunc), - /* 200 */ SyscallDesc("getgid32", unimplementedFunc), - /* 201 */ SyscallDesc("geteuid32", unimplementedFunc), - /* 202 */ SyscallDesc("getegid32", unimplementedFunc), + /* 199 */ SyscallDesc("getuid32", getuidFunc), + /* 200 */ SyscallDesc("getgid32", getgidFunc), + /* 201 */ SyscallDesc("geteuid32", geteuidFunc), + /* 202 */ SyscallDesc("getegid32", getegidFunc), /* 203 */ SyscallDesc("setreuid32", unimplementedFunc), /* 204 */ SyscallDesc("setregid32", unimplementedFunc), /* 205 */ SyscallDesc("getgroups32", unimplementedFunc), -- cgit v1.2.3 From 1b2d75d6d276f316b8c3f40fa93901ab6233128f Mon Sep 17 00:00:00 2001 From: "Timothy M. Jones" Date: Sat, 24 Oct 2009 10:53:59 -0700 Subject: syscall: Addition of an ioctl command code for Power. --- src/arch/alpha/linux/linux.hh | 1 + src/arch/alpha/tru64/tru64.hh | 1 + src/arch/arm/linux/linux.hh | 1 + src/arch/mips/linux/linux.hh | 1 + 4 files changed, 4 insertions(+) (limited to 'src/arch') diff --git a/src/arch/alpha/linux/linux.hh b/src/arch/alpha/linux/linux.hh index e9947644c..c728ce1fb 100644 --- a/src/arch/alpha/linux/linux.hh +++ b/src/arch/alpha/linux/linux.hh @@ -105,6 +105,7 @@ class AlphaLinux : public Linux static const unsigned TIOCISATTY_ = 0x2000745e; static const unsigned TIOCGETS_ = 0x402c7413; static const unsigned TIOCGETA_ = 0x40127417; + static const unsigned TCSETAW_ = 0x80147419; // 2.6.15 kernel //@} /// For table(). diff --git a/src/arch/alpha/tru64/tru64.hh b/src/arch/alpha/tru64/tru64.hh index 4ba35fc50..0ee12973c 100644 --- a/src/arch/alpha/tru64/tru64.hh +++ b/src/arch/alpha/tru64/tru64.hh @@ -99,6 +99,7 @@ class AlphaTru64 : public Tru64 static const unsigned TIOCISATTY_ = 0x2000745e; static const unsigned TIOCGETS_ = 0x402c7413; static const unsigned TIOCGETA_ = 0x40127417; + static const unsigned TCSETAW_ = 0x80147419; //@} //@{ diff --git a/src/arch/arm/linux/linux.hh b/src/arch/arm/linux/linux.hh index b9b10a593..f829dd7c6 100644 --- a/src/arch/arm/linux/linux.hh +++ b/src/arch/arm/linux/linux.hh @@ -86,6 +86,7 @@ class ArmLinux : public Linux static const unsigned TIOCISATTY_ = 0x2000745e; static const unsigned TIOCGETS_ = 0x402c7413; static const unsigned TIOCGETA_ = 0x40127417; + static const unsigned TCSETAW_ = 0x5407; // 2.6.15 kernel //@} /// For table(). diff --git a/src/arch/mips/linux/linux.hh b/src/arch/mips/linux/linux.hh index b30cca2fb..a2418cfb6 100644 --- a/src/arch/mips/linux/linux.hh +++ b/src/arch/mips/linux/linux.hh @@ -100,6 +100,7 @@ class MipsLinux : public Linux static const unsigned TIOCISATTY_ = 0x5480; static const unsigned TIOCGETS_ = 0x540d; static const unsigned TIOCGETA_ = 0x7417; + static const unsigned TCSETAW_ = 0x5403; // 2.6.15 kernel //@} /// For table(). -- cgit v1.2.3 From 835a55e7f347697815fc43851b2dd5a8642d21c4 Mon Sep 17 00:00:00 2001 From: "Timothy M. Jones" Date: Tue, 27 Oct 2009 09:24:39 -0700 Subject: POWER: Add support for the Power ISA This adds support for the 32-bit, big endian Power ISA. This supports both integer and floating point instructions based on the Power ISA Book I v2.06. --- src/arch/isa_parser.py | 10 + src/arch/power/PowerTLB.py | 37 ++ src/arch/power/SConscript | 61 ++++ src/arch/power/SConsopts | 33 ++ src/arch/power/faults.hh | 87 +++++ src/arch/power/insts/branch.cc | 169 +++++++++ src/arch/power/insts/branch.hh | 241 +++++++++++++ src/arch/power/insts/condition.cc | 59 +++ src/arch/power/insts/condition.hh | 86 +++++ src/arch/power/insts/floating.cc | 60 ++++ src/arch/power/insts/floating.hh | 153 ++++++++ src/arch/power/insts/integer.cc | 170 +++++++++ src/arch/power/insts/integer.hh | 176 +++++++++ src/arch/power/insts/mem.cc | 74 ++++ src/arch/power/insts/mem.hh | 91 +++++ src/arch/power/insts/misc.cc | 60 ++++ src/arch/power/insts/misc.hh | 57 +++ src/arch/power/insts/static_inst.cc | 62 ++++ src/arch/power/insts/static_inst.hh | 70 ++++ src/arch/power/isa.hh | 115 ++++++ src/arch/power/isa/bitfields.isa | 84 +++++ src/arch/power/isa/decoder.isa | 593 +++++++++++++++++++++++++++++++ src/arch/power/isa/formats/basic.isa | 103 ++++++ src/arch/power/isa/formats/branch.isa | 222 ++++++++++++ src/arch/power/isa/formats/condition.isa | 47 +++ src/arch/power/isa/formats/formats.isa | 60 ++++ src/arch/power/isa/formats/fp.isa | 132 +++++++ src/arch/power/isa/formats/integer.isa | 369 +++++++++++++++++++ src/arch/power/isa/formats/mem.isa | 351 ++++++++++++++++++ src/arch/power/isa/formats/misc.isa | 61 ++++ src/arch/power/isa/formats/unimp.isa | 146 ++++++++ src/arch/power/isa/formats/unknown.isa | 87 +++++ src/arch/power/isa/formats/util.isa | 174 +++++++++ src/arch/power/isa/includes.isa | 92 +++++ src/arch/power/isa/main.isa | 57 +++ src/arch/power/isa/operands.isa | 81 +++++ src/arch/power/isa_traits.hh | 75 ++++ src/arch/power/linux/linux.cc | 79 ++++ src/arch/power/linux/linux.hh | 148 ++++++++ src/arch/power/linux/process.cc | 455 ++++++++++++++++++++++++ src/arch/power/linux/process.hh | 58 +++ src/arch/power/locked_mem.hh | 64 ++++ src/arch/power/microcode_rom.hh | 45 +++ src/arch/power/miscregs.hh | 95 +++++ src/arch/power/mmaped_ipr.hh | 66 ++++ src/arch/power/pagetable.cc | 82 +++++ src/arch/power/pagetable.hh | 158 ++++++++ src/arch/power/predecoder.hh | 121 +++++++ src/arch/power/process.cc | 288 +++++++++++++++ src/arch/power/process.hh | 59 +++ src/arch/power/registers.hh | 105 ++++++ src/arch/power/remote_gdb.hh | 84 +++++ src/arch/power/stacktrace.hh | 148 ++++++++ src/arch/power/tlb.cc | 322 +++++++++++++++++ src/arch/power/tlb.hh | 171 +++++++++ src/arch/power/types.hh | 91 +++++ src/arch/power/utility.hh | 118 ++++++ src/arch/power/vtophys.hh | 57 +++ 58 files changed, 7419 insertions(+) create mode 100644 src/arch/power/PowerTLB.py create mode 100644 src/arch/power/SConscript create mode 100644 src/arch/power/SConsopts create mode 100644 src/arch/power/faults.hh create mode 100644 src/arch/power/insts/branch.cc create mode 100644 src/arch/power/insts/branch.hh create mode 100644 src/arch/power/insts/condition.cc create mode 100644 src/arch/power/insts/condition.hh create mode 100644 src/arch/power/insts/floating.cc create mode 100644 src/arch/power/insts/floating.hh create mode 100644 src/arch/power/insts/integer.cc create mode 100644 src/arch/power/insts/integer.hh create mode 100644 src/arch/power/insts/mem.cc create mode 100644 src/arch/power/insts/mem.hh create mode 100644 src/arch/power/insts/misc.cc create mode 100644 src/arch/power/insts/misc.hh create mode 100644 src/arch/power/insts/static_inst.cc create mode 100644 src/arch/power/insts/static_inst.hh create mode 100644 src/arch/power/isa.hh create mode 100644 src/arch/power/isa/bitfields.isa create mode 100644 src/arch/power/isa/decoder.isa create mode 100644 src/arch/power/isa/formats/basic.isa create mode 100644 src/arch/power/isa/formats/branch.isa create mode 100644 src/arch/power/isa/formats/condition.isa create mode 100644 src/arch/power/isa/formats/formats.isa create mode 100644 src/arch/power/isa/formats/fp.isa create mode 100644 src/arch/power/isa/formats/integer.isa create mode 100644 src/arch/power/isa/formats/mem.isa create mode 100644 src/arch/power/isa/formats/misc.isa create mode 100644 src/arch/power/isa/formats/unimp.isa create mode 100644 src/arch/power/isa/formats/unknown.isa create mode 100644 src/arch/power/isa/formats/util.isa create mode 100644 src/arch/power/isa/includes.isa create mode 100644 src/arch/power/isa/main.isa create mode 100644 src/arch/power/isa/operands.isa create mode 100644 src/arch/power/isa_traits.hh create mode 100644 src/arch/power/linux/linux.cc create mode 100644 src/arch/power/linux/linux.hh create mode 100644 src/arch/power/linux/process.cc create mode 100644 src/arch/power/linux/process.hh create mode 100644 src/arch/power/locked_mem.hh create mode 100644 src/arch/power/microcode_rom.hh create mode 100644 src/arch/power/miscregs.hh create mode 100644 src/arch/power/mmaped_ipr.hh create mode 100644 src/arch/power/pagetable.cc create mode 100644 src/arch/power/pagetable.hh create mode 100644 src/arch/power/predecoder.hh create mode 100644 src/arch/power/process.cc create mode 100644 src/arch/power/process.hh create mode 100644 src/arch/power/registers.hh create mode 100644 src/arch/power/remote_gdb.hh create mode 100644 src/arch/power/stacktrace.hh create mode 100644 src/arch/power/tlb.cc create mode 100644 src/arch/power/tlb.hh create mode 100644 src/arch/power/types.hh create mode 100644 src/arch/power/utility.hh create mode 100644 src/arch/power/vtophys.hh (limited to 'src/arch') diff --git a/src/arch/isa_parser.py b/src/arch/isa_parser.py index f001eff41..e3da240d2 100755 --- a/src/arch/isa_parser.py +++ b/src/arch/isa_parser.py @@ -1465,6 +1465,16 @@ class MemOperand(Operand): def makeAccSize(self): return self.size +class PCOperand(Operand): + def makeConstructor(self): + return '' + + def makeRead(self): + return '%s = xc->readPC();\n' % self.base_name + + def makeWrite(self): + return 'xc->setPC(%s);\n' % self.base_name + class UPCOperand(Operand): def makeConstructor(self): return '' diff --git a/src/arch/power/PowerTLB.py b/src/arch/power/PowerTLB.py new file mode 100644 index 000000000..36dff5333 --- /dev/null +++ b/src/arch/power/PowerTLB.py @@ -0,0 +1,37 @@ +# -*- mode:python -*- + +# Copyright (c) 2009 The University of Edinburgh +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# Authors: Timothy M. Jones + +from m5.SimObject import SimObject +from m5.params import * + +class PowerTLB(SimObject): + type = 'PowerTLB' + cxx_class = 'PowerISA::TLB' + size = Param.Int(64, "TLB size") diff --git a/src/arch/power/SConscript b/src/arch/power/SConscript new file mode 100644 index 000000000..1fb36eaab --- /dev/null +++ b/src/arch/power/SConscript @@ -0,0 +1,61 @@ +# -*- mode:python -*- + +# Copyright (c) 2009 The University of Edinburgh +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# Authors: Timothy M. Jones + +Import('*') + +if env['TARGET_ISA'] == 'power': +# Workaround for bug in SCons version > 0.97d20071212 +# Scons bug id: 2006 M5 Bug id: 308 + Dir('isa/formats') + Source('insts/branch.cc') + Source('insts/mem.cc') + Source('insts/integer.cc') + Source('insts/floating.cc') + Source('insts/condition.cc') + Source('insts/static_inst.cc') + Source('pagetable.cc') + Source('tlb.cc') + + SimObject('PowerTLB.py') + TraceFlag('Power') + + if not env['FULL_SYSTEM']: + Source('process.cc') + Source('linux/linux.cc') + Source('linux/process.cc') + + # Add in files generated by the ISA description. + isa_desc_files = env.ISADesc('isa/main.isa') + + # Only non-header files need to be compiled. + for f in isa_desc_files: + if not f.path.endswith('.hh'): + Source(f) + diff --git a/src/arch/power/SConsopts b/src/arch/power/SConsopts new file mode 100644 index 000000000..d762c2d58 --- /dev/null +++ b/src/arch/power/SConsopts @@ -0,0 +1,33 @@ +# -*- mode:python -*- + +# Copyright (c) 2009 The University of Edinburgh +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# Authors: Timothy M. Jones + +Import('*') + +all_isa_list.append('power') diff --git a/src/arch/power/faults.hh b/src/arch/power/faults.hh new file mode 100644 index 000000000..eadcb7900 --- /dev/null +++ b/src/arch/power/faults.hh @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2003-2005 The Regents of The University of Michigan + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Gabe Black + * Timothy M. Jones + */ + +#ifndef __ARCH_POWER_FAULTS_HH__ +#define __ARCH_POWER_FAULTS_HH__ + +#include "sim/faults.hh" + +namespace PowerISA +{ + +class PowerFault : public FaultBase +{ + protected: + FaultName _name; + + PowerFault(FaultName name) + : _name(name) + { + } + + FaultName + name() const + { + return _name; + } +}; + + +class UnimplementedOpcodeFault : public PowerFault +{ + public: + UnimplementedOpcodeFault() + : PowerFault("Unimplemented Opcode") + { + } +}; + + +class MachineCheckFault : public PowerFault +{ + public: + MachineCheckFault() + : PowerFault("Machine Check") + { + } +}; + + +static inline Fault +genMachineCheckFault() +{ + return new MachineCheckFault(); +} + +} // PowerISA namespace + +#endif // __ARCH_POWER_FAULTS_HH__ diff --git a/src/arch/power/insts/branch.cc b/src/arch/power/insts/branch.cc new file mode 100644 index 000000000..3f4346c97 --- /dev/null +++ b/src/arch/power/insts/branch.cc @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Timothy M. Jones + */ + +#include "arch/power/insts/branch.hh" +#include "base/loader/symtab.hh" + +using namespace PowerISA; + +const std::string & +PCDependentDisassembly::disassemble(Addr pc, const SymbolTable *symtab) const +{ + if (!cachedDisassembly || + pc != cachedPC || symtab != cachedSymtab) + { + if (cachedDisassembly) + delete cachedDisassembly; + + cachedDisassembly = + new std::string(generateDisassembly(pc, symtab)); + cachedPC = pc; + cachedSymtab = symtab; + } + + return *cachedDisassembly; +} + +Addr +BranchPCRel::branchTarget(Addr pc) const +{ + return (uint32_t)(pc + disp); +} + +std::string +BranchPCRel::generateDisassembly(Addr pc, const SymbolTable *symtab) const +{ + std::stringstream ss; + + ccprintf(ss, "%-10s ", mnemonic); + + Addr target = pc + disp; + + std::string str; + if (symtab && symtab->findSymbol(target, str)) + ss << str; + else + ccprintf(ss, "0x%x", target); + + return ss.str(); +} + +Addr +BranchNonPCRel::branchTarget(Addr pc) const +{ + return targetAddr; +} + +std::string +BranchNonPCRel::generateDisassembly(Addr pc, const SymbolTable *symtab) const +{ + std::stringstream ss; + + ccprintf(ss, "%-10s ", mnemonic); + + std::string str; + if (symtab && symtab->findSymbol(targetAddr, str)) + ss << str; + else + ccprintf(ss, "0x%x", targetAddr); + + return ss.str(); +} + +Addr +BranchPCRelCond::branchTarget(Addr pc) const +{ + return (uint32_t)(pc + disp); +} + +std::string +BranchPCRelCond::generateDisassembly(Addr pc, const SymbolTable *symtab) const +{ + std::stringstream ss; + + ccprintf(ss, "%-10s ", mnemonic); + + ss << bo << ", " << bi << ", "; + + Addr target = pc + disp; + + std::string str; + if (symtab && symtab->findSymbol(target, str)) + ss << str; + else + ccprintf(ss, "0x%x", target); + + return ss.str(); +} + +Addr +BranchNonPCRelCond::branchTarget(Addr pc) const +{ + return targetAddr; +} + +std::string +BranchNonPCRelCond::generateDisassembly(Addr pc, + const SymbolTable *symtab) const +{ + std::stringstream ss; + + ccprintf(ss, "%-10s ", mnemonic); + + ss << bo << ", " << bi << ", "; + + std::string str; + if (symtab && symtab->findSymbol(targetAddr, str)) + ss << str; + else + ccprintf(ss, "0x%x", targetAddr); + + return ss.str(); +} + +Addr +BranchRegCond::branchTarget(ThreadContext *tc) const +{ + uint32_t regVal = tc->readIntReg(_srcRegIdx[_numSrcRegs - 1]); + return (regVal & 0xfffffffc); +} + +std::string +BranchRegCond::generateDisassembly(Addr pc, + const SymbolTable *symtab) const +{ + std::stringstream ss; + + ccprintf(ss, "%-10s ", mnemonic); + + ss << bo << ", " << bi << ", "; + + return ss.str(); +} diff --git a/src/arch/power/insts/branch.hh b/src/arch/power/insts/branch.hh new file mode 100644 index 000000000..dd00e42c3 --- /dev/null +++ b/src/arch/power/insts/branch.hh @@ -0,0 +1,241 @@ +/* Copyright (c) 2007-2008 The Florida State University + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Timothy M. Jones + */ + +#ifndef __ARCH_POWER_INSTS_BRANCH_HH__ +#define __ARCH_POWER_INSTS_BRANCH_HH__ + +#include "arch/power/insts/static_inst.hh" + +namespace PowerISA +{ + +/** + * Base class for instructions whose disassembly is not purely a + * function of the machine instruction (i.e., it depends on the + * PC). This class overrides the disassemble() method to check + * the PC and symbol table values before re-using a cached + * disassembly string. This is necessary for branches and jumps, + * where the disassembly string includes the target address (which + * may depend on the PC and/or symbol table). + */ +class PCDependentDisassembly : public PowerStaticInst +{ + protected: + /// Cached program counter from last disassembly + mutable Addr cachedPC; + /// Cached symbol table pointer from last disassembly + mutable const SymbolTable *cachedSymtab; + + /// Constructor + PCDependentDisassembly(const char *mnem, ExtMachInst _machInst, + OpClass __opClass) + : PowerStaticInst(mnem, _machInst, __opClass), + cachedPC(0), cachedSymtab(0) + { + } + + const std::string & + disassemble(Addr pc, const SymbolTable *symtab) const; +}; + +/** + * Base class for unconditional, PC-relative branches. + */ +class BranchPCRel : public PCDependentDisassembly +{ + protected: + + /// Displacement + uint32_t disp; + + /// Constructor. + BranchPCRel(const char *mnem, MachInst _machInst, OpClass __opClass) + : PCDependentDisassembly(mnem, _machInst, __opClass), + disp(machInst.li << 2) + { + // If bit 26 is 1 then sign extend + if (disp & 0x2000000) { + disp |= 0xfc000000; + } + } + + Addr branchTarget(Addr pc) const; + + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; +}; + +/** + * Base class for unconditional, non PC-relative branches. + */ +class BranchNonPCRel : public PCDependentDisassembly +{ + protected: + + /// Target address + uint32_t targetAddr; + + /// Constructor. + BranchNonPCRel(const char *mnem, MachInst _machInst, OpClass __opClass) + : PCDependentDisassembly(mnem, _machInst, __opClass), + targetAddr(machInst.li << 2) + { + // If bit 26 is 1 then sign extend + if (targetAddr & 0x2000000) { + targetAddr |= 0xfc000000; + } + } + + Addr branchTarget(Addr pc) const; + + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; +}; + +/** + * Base class for conditional branches. + */ +class BranchCond : public PCDependentDisassembly +{ + protected: + + /// Fields needed for conditions + uint32_t bo; + uint32_t bi; + + /// Constructor. + BranchCond(const char *mnem, MachInst _machInst, OpClass __opClass) + : PCDependentDisassembly(mnem, _machInst, __opClass), + bo(machInst.bo), + bi(machInst.bi) + { + } + + inline bool + ctrOk(uint32_t& ctr) const + { + bool ctr_ok; + if (bo & 4) { + ctr_ok = true; + } else { + ctr--; + if (ctr != 0) { + ctr_ok = ((bo & 2) == 0); + } else { + ctr_ok = ((bo & 2) != 0); + } + } + return ctr_ok; + } + + inline bool + condOk(uint32_t cr) const + { + bool cond_ok; + if (bo & 16) { + cond_ok = true; + } else { + cond_ok = (((cr >> (31 - bi)) & 1) == ((bo >> 3) & 1)); + } + return cond_ok; + } +}; + +/** + * Base class for conditional, PC-relative branches. + */ +class BranchPCRelCond : public BranchCond +{ + protected: + + /// Displacement + uint32_t disp; + + /// Constructor. + BranchPCRelCond(const char *mnem, MachInst _machInst, OpClass __opClass) + : BranchCond(mnem, _machInst, __opClass), + disp(machInst.bd << 2) + { + // If bit 16 is 1 then sign extend + if (disp & 0x8000) { + disp |= 0xffff0000; + } + } + + Addr branchTarget(Addr pc) const; + + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; +}; + +/** + * Base class for conditional, non PC-relative branches. + */ +class BranchNonPCRelCond : public BranchCond +{ + protected: + + /// Target address + uint32_t targetAddr; + + /// Constructor. + BranchNonPCRelCond(const char *mnem, MachInst _machInst, OpClass __opClass) + : BranchCond(mnem, _machInst, __opClass), + targetAddr(machInst.bd << 2) + { + // If bit 16 is 1 then sign extend + if (targetAddr & 0x8000) { + targetAddr |= 0xffff0000; + } + } + + Addr branchTarget(Addr pc) const; + + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; +}; + +/** + * Base class for conditional, register-based branches + */ +class BranchRegCond : public BranchCond +{ + protected: + + /// Constructor. + BranchRegCond(const char *mnem, MachInst _machInst, OpClass __opClass) + : BranchCond(mnem, _machInst, __opClass) + { + } + + Addr branchTarget(ThreadContext *tc) const; + + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; +}; + +} // PowerISA namespace + +#endif //__ARCH_POWER_INSTS_BRANCH_HH__ diff --git a/src/arch/power/insts/condition.cc b/src/arch/power/insts/condition.cc new file mode 100644 index 000000000..0a942a982 --- /dev/null +++ b/src/arch/power/insts/condition.cc @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Timothy M. Jones + */ + +#include "arch/power/insts/condition.hh" + +using namespace PowerISA; + +std::string +CondLogicOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const +{ + std::stringstream ss; + + ccprintf(ss, "%-10s ", mnemonic); + + // Format is bt, ba, bb + ss << bt << ", " << ba << ", " << bb; + + return ss.str(); +} + +std::string +CondMoveOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const +{ + std::stringstream ss; + + ccprintf(ss, "%-10s ", mnemonic); + + // Format is bf, bfa + ss << bf << ", " << bfa; + + return ss.str(); +} diff --git a/src/arch/power/insts/condition.hh b/src/arch/power/insts/condition.hh new file mode 100644 index 000000000..a23667d9e --- /dev/null +++ b/src/arch/power/insts/condition.hh @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Timothy M. Jones + */ + +#ifndef __ARCH_POWER_INSTS_CONDITION_HH__ +#define __ARCH_POWER_INSTS_CONDITION_HH__ + +#include "arch/power/insts/static_inst.hh" +#include "base/cprintf.hh" + +namespace PowerISA +{ + +/** + * Class for condition register logical operations. + */ +class CondLogicOp : public PowerStaticInst +{ + protected: + + uint32_t ba; + uint32_t bb; + uint32_t bt; + + /// Constructor + CondLogicOp(const char *mnem, MachInst _machInst, OpClass __opClass) + : PowerStaticInst(mnem, _machInst, __opClass), + ba(machInst.ba), + bb(machInst.bb), + bt(machInst.bt) + { + } + + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; +}; + +/** + * Class for condition register move operations. + */ +class CondMoveOp : public PowerStaticInst +{ + protected: + + uint32_t bf; + uint32_t bfa; + + /// Constructor + CondMoveOp(const char *mnem, MachInst _machInst, OpClass __opClass) + : PowerStaticInst(mnem, _machInst, __opClass), + bf(machInst.bf), + bfa(machInst.bfa) + { + } + + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; +}; + +} // PowerISA namespace + +#endif //__ARCH_POWER_INSTS_CONDITION_HH__ diff --git a/src/arch/power/insts/floating.cc b/src/arch/power/insts/floating.cc new file mode 100644 index 000000000..f5c34ee2a --- /dev/null +++ b/src/arch/power/insts/floating.cc @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Timothy M. Jones + */ + +#include "arch/power/insts/floating.hh" + +using namespace PowerISA; + +std::string +FloatOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const +{ + std::stringstream ss; + + ccprintf(ss, "%-10s ", mnemonic); + + // Print the first destination only + if (_numDestRegs > 0) { + printReg(ss, _destRegIdx[0]); + } + + // Print the (possibly) two source registers + if (_numSrcRegs > 0) { + if (_numDestRegs > 0) { + ss << ", "; + } + printReg(ss, _srcRegIdx[0]); + if (_numSrcRegs > 1) { + ss << ", "; + printReg(ss, _srcRegIdx[1]); + } + } + + return ss.str(); +} diff --git a/src/arch/power/insts/floating.hh b/src/arch/power/insts/floating.hh new file mode 100644 index 000000000..2b2668409 --- /dev/null +++ b/src/arch/power/insts/floating.hh @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Timothy M. Jones + * Korey Sewell + */ + +#ifndef __ARCH_POWER_INSTS_FLOATING_HH__ +#define __ARCH_POWER_INSTS_FLOATING_HH__ + +#include "arch/power/insts/static_inst.hh" +#include "base/cprintf.hh" +#include "base/bitfield.hh" + +namespace PowerISA +{ + +/** + * Base class for floating point operations. + */ +class FloatOp : public PowerStaticInst +{ + protected: + + bool rcSet; + + /// Constructor + FloatOp(const char *mnem, MachInst _machInst, OpClass __opClass) + : PowerStaticInst(mnem, _machInst, __opClass) + { + } + + // Test for NaN (maximum biased exponent & non-zero fraction) + inline bool + isNan(uint32_t val_bits) const + { + return ((bits(val_bits, 30, 23) == 0xFF) && bits(val_bits, 22, 0)); + } + + inline bool + isNan(uint64_t val_bits) const + { + return ((bits(val_bits, 62, 52) == 0x7FF) && bits(val_bits, 51, 0)); + } + + inline bool + isNan(float val) const + { + void *val_ptr = &val; + uint32_t val_bits = *(uint32_t *) val_ptr; + return isNan(val_bits); + } + + inline bool + isNan(double val) const + { + void *val_ptr = &val; + uint64_t val_bits = *(uint64_t *) val_ptr; + return isNan(val_bits); + } + + // Test for SNaN (NaN with high order bit of fraction set to 0) + inline bool + isSnan(uint32_t val_bits) const + { + return ((bits(val_bits, 30, 22) == 0x1FE) && bits(val_bits, 22, 0)); + } + + // Test for QNaN (NaN with high order bit of fraction set to 1) + inline bool + isQnan(uint32_t val_bits) const + { + return (bits(val_bits, 30, 22) == 0x1FF); + } + + // Test for infinity (maximum biased exponent and zero fraction) + inline bool + isInfinity(uint32_t val_bits) const + { + return ((bits(val_bits, 30, 23) == 0xFF) && !bits(val_bits, 22, 0)); + } + + // Test for normalized numbers (biased exponent in the range 1 to 254) + inline bool + isNormalized(uint32_t val_bits) const + { + return ((bits(val_bits, 30, 23) != 0xFF) && bits(val_bits, 22, 0)); + } + + // Test for denormalized numbers (biased exponent of zero and + // non-zero fraction) + inline bool + isDenormalized(uint32_t val_bits) const + { + return (!bits(val_bits, 30, 23) && bits(val_bits, 22, 0)); + } + + // Test for zero (biased exponent of zero and fraction of zero) + inline bool + isZero(uint32_t val_bits) const + { + return (!bits(val_bits, 30, 23) && !bits(val_bits, 22, 0)); + } + + // Test for negative + inline bool + isNegative(uint32_t val_bits) const + { + return (bits(val_bits, 31)); + } + + // Compute the CR field + inline uint32_t + makeCRField(double a, double b) const + { + uint32_t c = 0; + if (isNan(a) || isNan(b)) { c = 0x1; } + else if (a < b) { c = 0x8; } + else if (a > b) { c = 0x4; } + else { c = 0x2; } + return c; + } + + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; +}; + +} // PowerISA namespace + +#endif //__ARCH_POWER_INSTS_FLOATING_HH__ diff --git a/src/arch/power/insts/integer.cc b/src/arch/power/insts/integer.cc new file mode 100644 index 000000000..1f81a15dc --- /dev/null +++ b/src/arch/power/insts/integer.cc @@ -0,0 +1,170 @@ +/* + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Timothy M. Jones + */ + +#include "arch/power/insts/integer.hh" + +using namespace std; +using namespace PowerISA; + +string +IntOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const +{ + stringstream ss; + bool printDest = true; + bool printSrcs = true; + bool printSecondSrc = true; + + // Generate the correct mnemonic + string myMnemonic(mnemonic); + + // Special cases + if (!myMnemonic.compare("or") && _srcRegIdx[0] == _srcRegIdx[1]) { + myMnemonic = "mr"; + printSecondSrc = false; + } else if (!myMnemonic.compare("mtlr") || !myMnemonic.compare("cmpi")) { + printDest = false; + } else if (!myMnemonic.compare("mflr")) { + printSrcs = false; + } + + // Additional characters depending on isa bits being set + if (oeSet) myMnemonic = myMnemonic + "o"; + if (rcSet) myMnemonic = myMnemonic + "."; + ccprintf(ss, "%-10s ", myMnemonic); + + // Print the first destination only + if (_numDestRegs > 0 && printDest) { + printReg(ss, _destRegIdx[0]); + } + + // Print the (possibly) two source registers + if (_numSrcRegs > 0 && printSrcs) { + if (_numDestRegs > 0 && printDest) { + ss << ", "; + } + printReg(ss, _srcRegIdx[0]); + if (_numSrcRegs > 1 && printSecondSrc) { + ss << ", "; + printReg(ss, _srcRegIdx[1]); + } + } + + return ss.str(); +} + + +string +IntImmOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const +{ + stringstream ss; + + // Generate the correct mnemonic + string myMnemonic(mnemonic); + + // Special cases + if (!myMnemonic.compare("addi") && _numSrcRegs == 0) { + myMnemonic = "li"; + } else if (!myMnemonic.compare("addis") && _numSrcRegs == 0) { + myMnemonic = "lis"; + } + ccprintf(ss, "%-10s ", myMnemonic); + + // Print the first destination only + if (_numDestRegs > 0) { + printReg(ss, _destRegIdx[0]); + } + + // Print the source register + if (_numSrcRegs > 0) { + if (_numDestRegs > 0) { + ss << ", "; + } + printReg(ss, _srcRegIdx[0]); + } + + // Print the immediate value last + ss << ", " << (int32_t)imm; + + return ss.str(); +} + + +string +IntShiftOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const +{ + stringstream ss; + + ccprintf(ss, "%-10s ", mnemonic); + + // Print the first destination only + if (_numDestRegs > 0) { + printReg(ss, _destRegIdx[0]); + } + + // Print the first source register + if (_numSrcRegs > 0) { + if (_numDestRegs > 0) { + ss << ", "; + } + printReg(ss, _srcRegIdx[0]); + } + + // Print the shift + ss << ", " << sh; + + return ss.str(); +} + + +string +IntRotateOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const +{ + stringstream ss; + + ccprintf(ss, "%-10s ", mnemonic); + + // Print the first destination only + if (_numDestRegs > 0) { + printReg(ss, _destRegIdx[0]); + } + + // Print the first source register + if (_numSrcRegs > 0) { + if (_numDestRegs > 0) { + ss << ", "; + } + printReg(ss, _srcRegIdx[0]); + } + + // Print the shift, mask begin and mask end + ss << ", " << sh << ", " << mb << ", " << me; + + return ss.str(); +} diff --git a/src/arch/power/insts/integer.hh b/src/arch/power/insts/integer.hh new file mode 100644 index 000000000..b4b96d5dc --- /dev/null +++ b/src/arch/power/insts/integer.hh @@ -0,0 +1,176 @@ +/* + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Timothy M. Jones + */ + +#ifndef __ARCH_POWER_INSTS_INTEGER_HH__ +#define __ARCH_POWER_INSTS_INTEGER_HH__ + +#include "arch/power/insts/static_inst.hh" +#include "base/cprintf.hh" +#include "base/bitfield.hh" + +namespace PowerISA +{ + +/** + * We provide a base class for integer operations and then inherit for + * several other classes. These specialise for instructions using immediate + * values and also rotate instructions. We also need to have versions that + * consider the Rc and OE bits. + */ + +/** + * Base class for integer operations. + */ +class IntOp : public PowerStaticInst +{ + protected: + + bool rcSet; + bool oeSet; + + // Needed for srawi only + uint32_t sh; + + /// Constructor + IntOp(const char *mnem, MachInst _machInst, OpClass __opClass) + : PowerStaticInst(mnem, _machInst, __opClass), + rcSet(false), oeSet(false) + { + } + + /* Compute the CR (condition register) field using signed comparison */ + inline uint32_t + makeCRField(int32_t a, int32_t b, uint32_t xerSO) const + { + uint32_t c = xerSO; + + /* We've pre-shifted the immediate values here */ + if (a < b) { c += 0x8; } + else if (a > b) { c += 0x4; } + else { c += 0x2; } + return c; + } + + /* Compute the CR (condition register) field using unsigned comparison */ + inline uint32_t + makeCRField(uint32_t a, uint32_t b, uint32_t xerSO) const + { + uint32_t c = xerSO; + + /* We've pre-shifted the immediate values here */ + if (a < b) { c += 0x8; } + else if (a > b) { c += 0x4; } + else { c += 0x2; } + return c; + } + + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; +}; + + +/** + * Class for integer immediate (signed and unsigned) operations. + */ +class IntImmOp : public IntOp +{ + protected: + + int32_t imm; + uint32_t uimm; + + /// Constructor + IntImmOp(const char *mnem, MachInst _machInst, OpClass __opClass) + : IntOp(mnem, _machInst, __opClass), + imm(sext<16>(machInst.si)), + uimm(machInst.si) + { + } + + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; +}; + + +/** + * Class for integer operations with a shift. + */ +class IntShiftOp : public IntOp +{ + protected: + + uint32_t sh; + + /// Constructor + IntShiftOp(const char *mnem, MachInst _machInst, OpClass __opClass) + : IntOp(mnem, _machInst, __opClass), + sh(machInst.sh) + { + } + + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; +}; + + +/** + * Class for integer rotate operations. + */ +class IntRotateOp : public IntShiftOp +{ + protected: + + uint32_t mb; + uint32_t me; + uint32_t fullMask; + + /// Constructor + IntRotateOp(const char *mnem, MachInst _machInst, OpClass __opClass) + : IntShiftOp(mnem, _machInst, __opClass), + mb(machInst.mb), + me(machInst.me) + { + if (me >= mb) { + fullMask = mask(31 - mb, 31 - me); + } else { + fullMask = ~mask(31 - (me + 1), 31 - (mb - 1)); + } + } + + uint32_t + rotateValue(uint32_t rs, uint32_t shift) const + { + uint32_t n = shift & 31; + return (rs << n) | (rs >> (32 - n)); + } + + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; +}; + +} // PowerISA namespace + +#endif //__ARCH_POWER_INSTS_INTEGER_HH__ diff --git a/src/arch/power/insts/mem.cc b/src/arch/power/insts/mem.cc new file mode 100644 index 000000000..447efa2f4 --- /dev/null +++ b/src/arch/power/insts/mem.cc @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Timothy M. Jones + */ + +#include "arch/power/insts/mem.hh" +#include "base/loader/symtab.hh" + +using namespace PowerISA; + +std::string +MemOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const +{ + return csprintf("%-10s", mnemonic); +} + +std::string +MemDispOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const +{ + std::stringstream ss; + + ccprintf(ss, "%-10s ", mnemonic); + + // Print the destination only for a load + if (!flags[IsStore]) { + if (_numDestRegs > 0) { + + // If the instruction updates the source register with the + // EA, then this source register is placed in position 0, + // therefore we print the last destination register. + printReg(ss, _destRegIdx[_numDestRegs-1]); + } + } + + // Print the data register for a store + else { + printReg(ss, _srcRegIdx[1]); + } + + // Print the displacement + ss << ", " << (int32_t)disp; + + // Print the address register + ss << "("; + printReg(ss, _srcRegIdx[0]); + ss << ")"; + + return ss.str(); +} diff --git a/src/arch/power/insts/mem.hh b/src/arch/power/insts/mem.hh new file mode 100644 index 000000000..329dafe57 --- /dev/null +++ b/src/arch/power/insts/mem.hh @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Timothy M. Jones + */ + +#ifndef __ARCH_POWER_MEM_HH__ +#define __ARCH_POWER_MEM_HH__ + +#include "arch/power/insts/static_inst.hh" + +namespace PowerISA +{ + +/** + * Base class for memory operations. + */ +class MemOp : public PowerStaticInst +{ + protected: + + /// Memory request flags. See mem_req_base.hh. + unsigned memAccessFlags; + /// Pointer to EAComp object. + const StaticInstPtr eaCompPtr; + /// Pointer to MemAcc object. + const StaticInstPtr memAccPtr; + + /// Constructor + MemOp(const char *mnem, MachInst _machInst, OpClass __opClass, + StaticInstPtr _eaCompPtr = nullStaticInstPtr, + StaticInstPtr _memAccPtr = nullStaticInstPtr) + : PowerStaticInst(mnem, _machInst, __opClass), + memAccessFlags(0), + eaCompPtr(_eaCompPtr), + memAccPtr(_memAccPtr) + { + } + + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; +}; + + +/** + * Class for memory operations with displacement. + */ +class MemDispOp : public MemOp +{ + protected: + + int16_t disp; + + /// Constructor + MemDispOp(const char *mnem, MachInst _machInst, OpClass __opClass, + StaticInstPtr _eaCompPtr = nullStaticInstPtr, + StaticInstPtr _memAccPtr = nullStaticInstPtr) + : MemOp(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr), + disp(machInst.d) + { + } + + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; +}; + +} // PowerISA namespace + +#endif //__ARCH_POWER_INSTS_MEM_HH__ diff --git a/src/arch/power/insts/misc.cc b/src/arch/power/insts/misc.cc new file mode 100644 index 000000000..913030b61 --- /dev/null +++ b/src/arch/power/insts/misc.cc @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Timothy M. Jones + */ + +#include "arch/power/insts/misc.hh" + +using namespace PowerISA; + +std::string +MiscOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const +{ + std::stringstream ss; + + ccprintf(ss, "%-10s ", mnemonic); + + // Print the first destination only + if (_numDestRegs > 0) { + printReg(ss, _destRegIdx[0]); + } + + // Print the (possibly) two source registers + if (_numSrcRegs > 0) { + if (_numDestRegs > 0) { + ss << ", "; + } + printReg(ss, _srcRegIdx[0]); + if (_numSrcRegs > 1) { + ss << ", "; + printReg(ss, _srcRegIdx[1]); + } + } + + return ss.str(); +} diff --git a/src/arch/power/insts/misc.hh b/src/arch/power/insts/misc.hh new file mode 100644 index 000000000..dd4941b93 --- /dev/null +++ b/src/arch/power/insts/misc.hh @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Timothy M. Jones + */ + +#ifndef __ARCH_POWER_INSTS_MISC_HH__ +#define __ARCH_POWER_INSTS_MISC_HH__ + +#include "arch/power/insts/static_inst.hh" + +namespace PowerISA +{ + +/** + * Class for misc operations. + */ +class MiscOp : public PowerStaticInst +{ + protected: + + /// Constructor + MiscOp(const char *mnem, MachInst _machInst, OpClass __opClass) + : PowerStaticInst(mnem, _machInst, __opClass) + { + } + + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; +}; + +} // PowerISA namespace + +#endif //__ARCH_POWER_INSTS_MISC_HH__ diff --git a/src/arch/power/insts/static_inst.cc b/src/arch/power/insts/static_inst.cc new file mode 100644 index 000000000..1982744bf --- /dev/null +++ b/src/arch/power/insts/static_inst.cc @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Timothy M. Jones + */ + +#include "arch/power/insts/static_inst.hh" + +using namespace PowerISA; + +void +PowerStaticInst::printReg(std::ostream &os, int reg) const +{ + if (reg < FP_Base_DepTag) { + ccprintf(os, "r%d", reg); + } else if (reg < Ctrl_Base_DepTag) { + ccprintf(os, "f%d", reg - FP_Base_DepTag); + } else { + switch (reg - Ctrl_Base_DepTag) { + case 0: ccprintf(os, "cr"); break; + case 1: ccprintf(os, "xer"); break; + case 2: ccprintf(os, "lr"); break; + case 3: ccprintf(os, "ctr"); break; + default: ccprintf(os, "unknown_reg"); + } + } +} + +std::string +PowerStaticInst::generateDisassembly(Addr pc, + const SymbolTable *symtab) const +{ + std::stringstream ss; + + ccprintf(ss, "%-10s ", mnemonic); + + return ss.str(); +} diff --git a/src/arch/power/insts/static_inst.hh b/src/arch/power/insts/static_inst.hh new file mode 100644 index 000000000..399e75371 --- /dev/null +++ b/src/arch/power/insts/static_inst.hh @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Timothy M. Jones + */ + +#ifndef __ARCH_POWER_INSTS_STATICINST_HH__ +#define __ARCH_POWER_INSTS_STATICINST_HH__ + +#include "base/trace.hh" +#include "cpu/static_inst.hh" + +namespace PowerISA +{ + +class PowerStaticInst : public StaticInst +{ + protected: + + // Constructor + PowerStaticInst(const char *mnem, MachInst _machInst, OpClass __opClass) + : StaticInst(mnem, _machInst, __opClass) + { + } + + // Insert a condition value into a CR (condition register) field + inline uint32_t + insertCRField(uint32_t cr, uint32_t bf, uint32_t value) const + { + uint32_t bits = value << ((7 - bf) * 4); + uint32_t mask = ~(0xf << ((7 - bf) * 4)); + return (cr & mask) | bits; + } + + /// Print a register name for disassembly given the unique + /// dependence tag number (FP or int). + void + printReg(std::ostream &os, int reg) const; + + std::string + generateDisassembly(Addr pc, const SymbolTable *symtab) const; +}; + +} // PowerISA namespace + +#endif //__ARCH_POWER_INSTS_STATICINST_HH__ diff --git a/src/arch/power/isa.hh b/src/arch/power/isa.hh new file mode 100644 index 000000000..ba1b5018d --- /dev/null +++ b/src/arch/power/isa.hh @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2009 The Regents of The University of Michigan + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Gabe Black + * Timothy M. Jones + */ + +#ifndef __ARCH_POWER_ISA_HH__ +#define __ARCH_POWER_ISA_HH__ + +#include "arch/power/registers.hh" +#include "arch/power/types.hh" +#include "base/misc.hh" + +class ThreadContext; +class Checkpoint; +class EventManager; + +namespace PowerISA +{ + +class ISA +{ + protected: + MiscReg dummy; + MiscReg miscRegs[NumMiscRegs]; + + public: + void + clear() + { + } + + MiscReg + readMiscRegNoEffect(int misc_reg) + { + fatal("Power does not currently have any misc regs defined\n"); + return dummy; + } + + MiscReg + readMiscReg(int misc_reg, ThreadContext *tc) + { + fatal("Power does not currently have any misc regs defined\n"); + return dummy; + } + + void + setMiscRegNoEffect(int misc_reg, const MiscReg &val) + { + fatal("Power does not currently have any misc regs defined\n"); + } + + void + setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc) + { + fatal("Power does not currently have any misc regs defined\n"); + } + + int + flattenIntIndex(int reg) + { + return reg; + } + + int + flattenFloatIndex(int reg) + { + return reg; + } + + void + serialize(EventManager *em, std::ostream &os) + { + } + + void + unserialize(EventManager *em, Checkpoint *cp, const std::string §ion) + { + } + + ISA() + { + clear(); + } +}; + +} // PowerISA namespace + +#endif // __ARCH_POWER_ISA_HH__ diff --git a/src/arch/power/isa/bitfields.isa b/src/arch/power/isa/bitfields.isa new file mode 100644 index 000000000..8cd323ad5 --- /dev/null +++ b/src/arch/power/isa/bitfields.isa @@ -0,0 +1,84 @@ +// -*- mode:c++ -*- + +// Copyright (c) 2009 The University of Edinburgh +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer; +// redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution; +// neither the name of the copyright holders nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: Timothy M. Jones + +//////////////////////////////////////////////////////////////////// +// +// Bitfield definitions. +// +// The endianness is the opposite to what's used here, so things +// are reversed sometimes. Not sure of a fix to this though... + +// Opcode fields +def bitfield OPCODE <31:26>; +def bitfield X_XO <10:0>; +def bitfield XO_XO <10:1>; +def bitfield A_XO <5:1>; + +// Register fields +def bitfield RA <20:16>; +def bitfield RB <15:11>; +def bitfield RS <25:21>; +def bitfield RT <25:21>; +def bitfield FRA <20:16>; +def bitfield FRB <15:11>; +def bitfield FRC <10:6>; +def bitfield FRS <25:21>; +def bitfield FRT <25:21>; + +// The record bit can be in two positions +// Used to enable setting of the condition register +def bitfield RC31 <0>; +def bitfield RC21 <10>; + +// Used to enable setting of the overflow flags +def bitfield OE <10>; + +// SPR field for mtspr instruction +def bitfield SPR <20:11>; + +// FXM field for mtcrf instruction +def bitfield FXM <19:12>; + +// Branch fields +def bitfield LK <0>; +def bitfield AA <1>; + +// Specifies a CR or FPSCR field +def bitfield BF <25:23>; + +// Fields for FPSCR manipulation instructions +def bitfield FLM <24:17>; +def bitfield L <25>; +def bitfield W <16>; +// Named so to avoid conflicts with range.hh +def bitfield U_FIELD <15:12>; + +// Field for specifying a bit in CR or FPSCR +def bitfield BT <25:21>; diff --git a/src/arch/power/isa/decoder.isa b/src/arch/power/isa/decoder.isa new file mode 100644 index 000000000..3252ff14a --- /dev/null +++ b/src/arch/power/isa/decoder.isa @@ -0,0 +1,593 @@ +// -*- mode:c++ -*- + +// Copyright (c) 2009 The University of Edinburgh +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer; +// redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution; +// neither the name of the copyright holders nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: Timothy M. Jones + +//////////////////////////////////////////////////////////////////// +// +// The actual Power ISA decoder +// ------------------------------ +// +// I've used the Power ISA Book I v2.06 for instruction formats, +// opcode numbers, register names, etc. +// +decode OPCODE default Unknown::unknown() { + + format IntImmOp { + 10: cmpli({{ + Xer xer = XER; + uint32_t cr = makeCRField(Ra, (uint32_t)uimm, xer.so); + CR = insertCRField(CR, BF, cr); + }}); + 11: cmpi({{ + Xer xer = XER; + uint32_t cr = makeCRField(Ra.sw, (int32_t)imm, xer.so); + CR = insertCRField(CR, BF, cr); + }}); + } + + // Some instructions use bits 21 - 30, others 22 - 30. We have to use + // the larger size to account for all opcodes. For those that use the + // smaller value, the OE bit is bit 21. Therefore, we have two versions + // of each instruction: 1 with OE set, the other without. For an + // example see 'add' and 'addo'. + 31: decode XO_XO { + + // These instructions can all be reduced to the form + // Rt = src1 + src2 [+ CA], therefore we just give src1 and src2 + // (and, if necessary, CA) definitions and let the python script + // deal with setting things up correctly. We also give flags to + // say which control registers to set. + format IntSumOp { + 266: add({{ Ra }}, {{ Rb }}); + 40: subf({{ ~Ra }}, {{ Rb }}, {{ 1 }}); + 10: addc({{ Ra }}, {{ Rb }}, + computeCA = true); + 8: subfc({{ ~Ra }}, {{ Rb }}, {{ 1 }}, + true); + 104: neg({{ ~Ra }}, {{ 1 }}); + 138: adde({{ Ra }}, {{ Rb }}, {{ xer.ca }}, + true); + 234: addme({{ Ra }}, {{ (uint32_t)-1 }}, {{ xer.ca }}, + true); + 136: subfe({{ ~Ra }}, {{ Rb }}, {{ xer.ca }}, + true); + 232: subfme({{ ~Ra }}, {{ (uint32_t)-1 }}, {{ xer.ca }}, + true); + 202: addze({{ Ra }}, {{ xer.ca }}, + computeCA = true); + 200: subfze({{ ~Ra }}, {{ xer.ca }}, + computeCA = true); + } + + // Arithmetic instructions all use source registers Ra and Rb, + // with destination register Rt. + format IntArithOp { + 75: mulhw({{ int64_t prod = Ra.sq * Rb.sq; Rt = prod >> 32; }}); + 11: mulhwu({{ uint64_t prod = Ra.uq * Rb.uq; Rt = prod >> 32; }}); + 235: mullw({{ int64_t prod = Ra.sq * Rb.sq; Rt = prod; }}); + 747: mullwo({{ int64_t src1 = Ra.sq; int64_t src2 = Rb; int64_t prod = src1 * src2; Rt = prod; }}, + true); + + 491: divw({{ + int32_t src1 = Ra.sw; + int32_t src2 = Rb.sw; + if ((src1 != 0x80000000 || src2 != 0xffffffff) + && src2 != 0) { + Rt = src1 / src2; + } else { + Rt = 0; + } + }}); + + 1003: divwo({{ + int32_t src1 = Ra.sw; + int32_t src2 = Rb.sw; + if ((src1 != 0x80000000 || src2 != 0xffffffff) + && src2 != 0) { + Rt = src1 / src2; + } else { + Rt = 0; + divSetOV = true; + } + }}, + true); + + 459: divwu({{ + uint32_t src1 = Ra.sw; + uint32_t src2 = Rb.sw; + if (src2 != 0) { + Rt = src1 / src2; + } else { + Rt = 0; + } + }}); + + 971: divwuo({{ + uint32_t src1 = Ra.sw; + uint32_t src2 = Rb.sw; + if (src2 != 0) { + Rt = src1 / src2; + } else { + Rt = 0; + divSetOV = true; + } + }}, + true); + } + + // Integer logic instructions use source registers Rs and Rb, + // with destination register Ra. + format IntLogicOp { + 28: and({{ Ra = Rs & Rb; }}); + 316: xor({{ Ra = Rs ^ Rb; }}); + 476: nand({{ Ra = ~(Rs & Rb); }}); + 444: or({{ Ra = Rs | Rb; }}); + 124: nor({{ Ra = ~(Rs | Rb); }}); + 60: andc({{ Ra = Rs & ~Rb; }}); + 954: extsb({{ Ra = sext<8>(Rs); }}); + 284: eqv({{ Ra = ~(Rs ^ Rb); }}); + 412: orc({{ Ra = Rs | ~Rb; }}); + 922: extsh({{ Ra = sext<16>(Rs); }}); + 26: cntlzw({{ Ra = Rs == 0 ? 32 : 31 - findMsbSet(Rs); }}); + 508: cmpb({{ + uint32_t val = 0; + for (int n = 0; n < 32; n += 8) { + if(bits(Rs, n, n+7) == bits(Rb, n, n+7)) { + val = insertBits(val, n, n+7, 0xff); + } + } + Ra = val; + }}); + + 24: slw({{ + if (Rb & 0x20) { + Ra = 0; + } else { + Ra = Rs << (Rb & 0x1f); + } + }}); + + 536: srw({{ + if (Rb & 0x20) { + Ra = 0; + } else { + Ra = Rs >> (Rb & 0x1f); + } + }}); + + 792: sraw({{ + bool shiftSetCA = false; + int32_t s = Rs; + if (Rb == 0) { + Ra = Rs; + shiftSetCA = true; + } else if (Rb & 0x20) { + if (s < 0) { + Ra = (uint32_t)-1; + if (s & 0x7fffffff) { + shiftSetCA = true; + } else { + shiftSetCA = false; + } + } else { + Ra = 0; + shiftSetCA = false; + } + } else { + Ra = s >> (Rb & 0x1f); + if (s < 0 && (s << (32 - (Rb & 0x1f))) != 0) { + shiftSetCA = true; + } else { + shiftSetCA = false; + } + } + Xer xer1 = XER; + if (shiftSetCA) { + xer1.ca = 1; + } else { + xer1.ca = 0; + } + XER = xer1; + }}); + } + + // Integer logic instructions with a shift value. + format IntShiftOp { + 824: srawi({{ + bool shiftSetCA = false; + if (sh == 0) { + Ra = Rs; + shiftSetCA = false; + } else { + int32_t s = Rs; + Ra = s >> sh; + if (s < 0 && (s << (32 - sh)) != 0) { + shiftSetCA = true; + } else { + shiftSetCA = false; + } + } + Xer xer1 = XER; + if (shiftSetCA) { + xer1.ca = 1; + } else { + xer1.ca = 0; + } + XER = xer1; + }}); + } + + // Generic integer format instructions. + format IntOp { + 0: cmp({{ + Xer xer = XER; + uint32_t cr = makeCRField(Ra.sw, Rb.sw, xer.so); + CR = insertCRField(CR, BF, cr); + }}); + 32: cmpl({{ + Xer xer = XER; + uint32_t cr = makeCRField(Ra, Rb, xer.so); + CR = insertCRField(CR, BF, cr); + }}); + 144: mtcrf({{ + uint32_t mask = 0; + for (int i = 0; i < 8; ++i) { + if (((FXM >> i) & 0x1) == 0x1) { + mask |= 0xf << (4 * i); + } + } + CR = (Rs & mask) | (CR & ~mask); + }}); + 19: mfcr({{ Rt = CR; }}); + 339: decode SPR { + 0x20: mfxer({{ Rt = XER; }}); + 0x100: mflr({{ Rt = LR; }}); + 0x120: mfctr({{ Rt = CTR; }}); + } + 467: decode SPR { + 0x20: mtxer({{ XER = Rs; }}); + 0x100: mtlr({{ LR = Rs; }}); + 0x120: mtctr({{ CTR = Rs; }}); + } + } + + // All loads with an index register. The non-update versions + // all use the value 0 if Ra == R0, not the value contained in + // R0. Others update Ra with the effective address. In all cases, + // Ra and Rb are source registers, Rt is the destintation. + format LoadIndexOp { + 87: lbzx({{ Rt = Mem.ub; }}); + 279: lhzx({{ Rt = Mem.uh; }}); + 343: lhax({{ Rt = Mem.sh; }}); + 23: lwzx({{ Rt = Mem; }}); + 341: lwax({{ Rt = Mem.sw; }}); + 20: lwarx({{ Rt = Mem.sw; Rsv = 1; RsvLen = 4; RsvAddr = EA; }}); + 535: lfsx({{ Ft.sf = Mem.sf; }}); + 599: lfdx({{ Ft = Mem.df; }}); + 855: lfiwax({{ Ft.uw = Mem; }}); + } + + format LoadIndexUpdateOp { + 119: lbzux({{ Rt = Mem.ub; }}); + 311: lhzux({{ Rt = Mem.uh; }}); + 375: lhaux({{ Rt = Mem.sh; }}); + 55: lwzux({{ Rt = Mem; }}); + 373: lwaux({{ Rt = Mem.sw; }}); + 567: lfsux({{ Ft.sf = Mem.sf; }}); + 631: lfdux({{ Ft = Mem.df; }}); + } + + format StoreIndexOp { + 215: stbx({{ Mem.ub = Rs.ub; }}); + 407: sthx({{ Mem.uh = Rs.uh; }}); + 151: stwx({{ Mem = Rs; }}); + 150: stwcx({{ + bool store_performed = false; + if (Rsv) { + if (RsvLen == 4) { + if (RsvAddr == EA) { + Mem = Rs; + store_performed = true; + } + } + } + Xer xer = XER; + Cr cr = CR; + cr.cr0 = ((store_performed ? 0x2 : 0x0) | xer.so); + CR = cr; + Rsv = 0; + }}); + 663: stfsx({{ Mem.sf = Fs.sf; }}); + 727: stfdx({{ Mem.df = Fs; }}); + 983: stfiwx({{ Mem = Fs.uw; }}); + } + + format StoreIndexUpdateOp { + 247: stbux({{ Mem.ub = Rs.ub; }}); + 439: sthux({{ Mem.uh = Rs.uh; }}); + 183: stwux({{ Mem = Rs; }}); + 695: stfsux({{ Mem.sf = Fs.sf; }}); + 759: stfdux({{ Mem.df = Fs; }}); + } + + // These instructions all provide data cache hints + format MiscOp { + 278: dcbt({{ }}); + 246: dcbtst({{ }}); + 598: sync({{ }}, [ IsMemBarrier ]); + 854: eieio({{ }}, [ IsMemBarrier ]); + } + } + + format IntImmArithCheckRaOp { + 14: addi({{ Rt = Ra + imm; }}, + {{ Rt = imm }}); + 15: addis({{ Rt = Ra + (imm << 16); }}, + {{ Rt = imm << 16; }}); + } + + format IntImmArithOp { + 12: addic({{ uint32_t src = Ra; Rt = src + imm; }}, + [computeCA]); + 13: addic_({{ uint32_t src = Ra; Rt = src + imm; }}, + [computeCA, computeCR0]); + 8: subfic({{ int32_t src = ~Ra; Rt = src + imm + 1; }}, + [computeCA]); + 7: mulli({{ + int32_t src = Ra.sw; + int64_t prod = src * imm; + Rt = (uint32_t)prod; + }}); + } + + format IntImmLogicOp { + 24: ori({{ Ra = Rs | uimm; }}); + 25: oris({{ Ra = Rs | (uimm << 16); }}); + 26: xori({{ Ra = Rs ^ uimm; }}); + 27: xoris({{ Ra = Rs ^ (uimm << 16); }}); + 28: andi_({{ Ra = Rs & uimm; }}, + true); + 29: andis_({{ Ra = Rs & (uimm << 16); }}, + true); + } + + 16: decode AA { + + // Conditionally branch relative to PC based on CR and CTR. + format BranchPCRelCondCtr { + 0: bc({{ NPC = PC + disp; }}); + } + + // Conditionally branch to fixed address based on CR and CTR. + format BranchNonPCRelCondCtr { + 1: bca({{ NPC = targetAddr; }}); + } + } + + 18: decode AA { + + // Unconditionally branch relative to PC. + format BranchPCRel { + 0: b({{ NPC = PC + disp; }}); + } + + // Unconditionally branch to fixed address. + format BranchNonPCRel { + 1: ba({{ NPC = targetAddr; }}); + } + } + + 19: decode XO_XO { + + // Conditionally branch to address in LR based on CR and CTR. + format BranchLrCondCtr { + 16: bclr({{ NPC = LR & 0xfffffffc; }}); + } + + // Conditionally branch to address in CTR based on CR. + format BranchCtrCond { + 528: bcctr({{ NPC = CTR & 0xfffffffc; }}); + } + + // Condition register manipulation instructions. + format CondLogicOp { + 257: crand({{ + uint32_t crBa = bits(CR, 31 - ba); + uint32_t crBb = bits(CR, 31 - bb); + CR = insertBits(CR, 31 - bt, crBa & crBb); + }}); + 449: cror({{ + uint32_t crBa = bits(CR, 31 - ba); + uint32_t crBb = bits(CR, 31 - bb); + CR = insertBits(CR, 31 - bt, crBa | crBb); + }}); + 255: crnand({{ + uint32_t crBa = bits(CR, 31 - ba); + uint32_t crBb = bits(CR, 31 - bb); + CR = insertBits(CR, 31 - bt, !(crBa & crBb)); + }}); + 193: crxor({{ + uint32_t crBa = bits(CR, 31 - ba); + uint32_t crBb = bits(CR, 31 - bb); + CR = insertBits(CR, 31 - bt, crBa ^ crBb); + }}); + 33: crnor({{ + uint32_t crBa = bits(CR, 31 - ba); + uint32_t crBb = bits(CR, 31 - bb); + CR = insertBits(CR, 31 - bt, !(crBa | crBb)); + }}); + 289: creqv({{ + uint32_t crBa = bits(CR, 31 - ba); + uint32_t crBb = bits(CR, 31 - bb); + CR = insertBits(CR, 31 - bt, crBa == crBb); + }}); + 129: crandc({{ + uint32_t crBa = bits(CR, 31 - ba); + uint32_t crBb = bits(CR, 31 - bb); + CR = insertBits(CR, 31 - bt, crBa & !crBb); + }}); + 417: crorc({{ + uint32_t crBa = bits(CR, 31 - ba); + uint32_t crBb = bits(CR, 31 - bb); + CR = insertBits(CR, 31 - bt, crBa | !crBb); + }}); + } + format CondMoveOp { + 0: mcrf({{ + uint32_t crBfa = bits(CR, 31 - bfa*4, 28 - bfa*4); + CR = insertBits(CR, 31 - bf*4, 28 - bf*4, crBfa); + }}); + } + format MiscOp { + 150: isync({{ }}, [ IsSerializeAfter ]); + } + } + + format IntRotateOp { + 21: rlwinm({{ Ra = rotateValue(Rs, sh) & fullMask; }}); + 23: rlwnm({{ Ra = rotateValue(Rs, Rb) & fullMask; }}); + 20: rlwimi({{ Ra = (rotateValue(Rs, sh) & fullMask) | (Ra & ~fullMask); }}); + } + + format LoadDispOp { + 34: lbz({{ Rt = Mem.ub; }}); + 40: lhz({{ Rt = Mem.uh; }}); + 42: lha({{ Rt = Mem.sh; }}); + 32: lwz({{ Rt = Mem; }}); + 58: lwa({{ Rt = Mem.sw; }}, + {{ EA = Ra + (disp & 0xfffffffc); }}, + {{ EA = disp & 0xfffffffc; }}); + 48: lfs({{ Ft.sf = Mem.sf; }}); + 50: lfd({{ Ft = Mem.df; }}); + } + + format LoadDispUpdateOp { + 35: lbzu({{ Rt = Mem.ub; }}); + 41: lhzu({{ Rt = Mem.uh; }}); + 43: lhau({{ Rt = Mem.sh; }}); + 33: lwzu({{ Rt = Mem; }}); + 49: lfsu({{ Ft.sf = Mem.sf; }}); + 51: lfdu({{ Ft = Mem.df; }}); + } + + format StoreDispOp { + 38: stb({{ Mem.ub = Rs.ub; }}); + 44: sth({{ Mem.uh = Rs.uh; }}); + 36: stw({{ Mem = Rs; }}); + 52: stfs({{ Mem.sf = Fs.sf; }}); + 54: stfd({{ Mem.df = Fs; }}); + } + + format StoreDispUpdateOp { + 39: stbu({{ Mem.ub = Rs.ub; }}); + 45: sthu({{ Mem.uh = Rs.uh; }}); + 37: stwu({{ Mem = Rs; }}); + 53: stfsu({{ Mem.sf = Fs.sf; }}); + 55: stfdu({{ Mem.df = Fs; }}); + } + + 17: IntOp::sc({{ xc->syscall(R0); }}, + [ IsSyscall, IsNonSpeculative, IsSerializeAfter ]); + + format FloatArithOp { + 59: decode A_XO { + 21: fadds({{ Ft = Fa + Fb; }}); + 20: fsubs({{ Ft = Fa - Fb; }}); + 25: fmuls({{ Ft = Fa * Fc; }}); + 18: fdivs({{ Ft = Fa / Fb; }}); + 29: fmadds({{ Ft = (Fa * Fc) + Fb; }}); + 28: fmsubs({{ Ft = (Fa * Fc) - Fb; }}); + 31: fnmadds({{ Ft = -((Fa * Fc) + Fb); }}); + 30: fnmsubs({{ Ft = -((Fa * Fc) - Fb); }}); + } + } + + 63: decode A_XO { + format FloatArithOp { + 21: fadd({{ Ft = Fa + Fb; }}); + 20: fsub({{ Ft = Fa - Fb; }}); + 25: fmul({{ Ft = Fa * Fc; }}); + 18: fdiv({{ Ft = Fa / Fb; }}); + 29: fmadd({{ Ft = (Fa * Fc) + Fb; }}); + 28: fmsub({{ Ft = (Fa * Fc) - Fb; }}); + 31: fnmadd({{ Ft = -((Fa * Fc) + Fb); }}); + 30: fnmsub({{ Ft = -((Fa * Fc) - Fb); }}); + } + + default: decode XO_XO { + format FloatConvertOp { + 12: frsp({{ Ft.sf = Fb; }}); + 15: fctiwz({{ Ft.sw = (int32_t)trunc(Fb); }}); + } + + format FloatOp { + 0: fcmpu({{ + uint32_t c = makeCRField(Fa, Fb); + Fpscr fpscr = FPSCR; + fpscr.fprf.fpcc = c; + FPSCR = fpscr; + CR = insertCRField(CR, BF, c); + }}); + } + + format FloatRCCheckOp { + 72: fmr({{ Ft = Fb; }}); + 264: fabs({{ + Ft.uq = Fb.uq; + Ft.uq = insertBits(Ft.uq, 63, 0); }}); + 136: fnabs({{ + Ft.uq = Fb.uq; + Ft.uq = insertBits(Ft.uq, 63, 1); }}); + 40: fneg({{ Ft = -Fb; }}); + 8: fcpsgn({{ + Ft.uq = Fb.uq; + Ft.uq = insertBits(Ft.uq, 63, Fa.uq<63:63>); + }}); + 583: mffs({{ Ft.uq = FPSCR; }}); + 134: mtfsfi({{ + FPSCR = insertCRField(FPSCR, BF + (8 * (1 - W)), U_FIELD); + }}); + 711: mtfsf({{ + if (L == 1) { FPSCR = Fb.uq; } + else { + for (int i = 0; i < 8; ++i) { + if (bits(FLM, i) == 1) { + int k = 4 * (i + (8 * (1 - W))); + FPSCR = insertBits(FPSCR, k, k + 3, + bits(Fb.uq, k, k + 3)); + } + } + } + }}); + 70: mtfsb0({{ FPSCR = insertBits(FPSCR, 31 - BT, 0); }}); + 38: mtfsb1({{ FPSCR = insertBits(FPSCR, 31 - BT, 1); }}); + } + } + } +} diff --git a/src/arch/power/isa/formats/basic.isa b/src/arch/power/isa/formats/basic.isa new file mode 100644 index 000000000..adb5e7ef8 --- /dev/null +++ b/src/arch/power/isa/formats/basic.isa @@ -0,0 +1,103 @@ +// -*- mode:c++ -*- + +// Copyright (c) 2009 The University of Edinburgh +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer; +// redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution; +// neither the name of the copyright holders nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: Timothy M. Jones + +// Declarations for execute() methods. +def template BasicExecDeclare {{ + Fault execute(%(CPU_exec_context)s *, Trace::InstRecord *) const; +}}; + +// Basic instruction class declaration template. +def template BasicDeclare {{ + /** + * Static instruction class for "%(mnemonic)s". + */ + class %(class_name)s : public %(base_class)s + { + public: + /// Constructor. + %(class_name)s(ExtMachInst machInst); + %(BasicExecDeclare)s + }; +}}; + +// Basic instruction class constructor template. +def template BasicConstructor {{ + inline %(class_name)s::%(class_name)s(ExtMachInst machInst) : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s) + { + %(constructor)s; + } +}}; + + +// Basic instruction class execute method template. +def template BasicExecute {{ + Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const + { + Fault fault = NoFault; + + %(op_decl)s; + %(op_rd)s; + %(code)s; + + if (fault == NoFault) + { + %(op_wb)s; + } + + return fault; + } +}}; + +// Basic decode template. +def template BasicDecode {{ + return new %(class_name)s(machInst); +}}; + +// Basic decode template, passing mnemonic in as string arg to constructor. +def template BasicDecodeWithMnemonic {{ + return new %(class_name)s("%(mnemonic)s", machInst); +}}; + +// Definitions of execute methods that panic. +def template BasicExecPanic {{ +Fault execute(%(CPU_exec_context)s *, Trace::InstRecord *) const +{ + panic("Execute method called when it shouldn't!"); +} +}}; + +// The most basic instruction format... +def format BasicOp(code, *flags) {{ + iop = InstObjParams(name, Name, 'PowerStaticInst', code, flags) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecode.subst(iop) + exec_output = BasicExecute.subst(iop) +}}; diff --git a/src/arch/power/isa/formats/branch.isa b/src/arch/power/isa/formats/branch.isa new file mode 100644 index 000000000..d51ed5c25 --- /dev/null +++ b/src/arch/power/isa/formats/branch.isa @@ -0,0 +1,222 @@ +// -*- mode:c++ -*- + +// Copyright (c) 2009 The University of Edinburgh +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer; +// redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution; +// neither the name of the copyright holders nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: Timothy M. Jones + +//////////////////////////////////////////////////////////////////// +// +// Control transfer instructions +// +// From the Power ISA Book I v2.06, page 33, the following rules should +// be obeyed by programmers: +// +// - Use branch instructions where LK == 1 only as subroutine calls. +// - Pair each subroutine call with a bclr instruction with BH == 00 +// that returns from the subroutine. +// - Do not use bclrl as a subroutine call. +// +// Therefore, I've flagged all versions that update the link register (LR) +// as calls, except bclrl (BranchLrCtrCond format) which is flagged as +// a return. + + +let {{ + +# Simple code to update link register (LR). +updateLrCode = 'LR = PC + 4;' + +}}; + +// Instructions that unconditionally branch relative to the current PC. +def format BranchPCRel(br_code, inst_flags = []) {{ + inst_flags += ('IsUncondControl', 'IsDirectControl') + basic_code = br_code + + # The version that does not update LR + (header_output, decoder_output, decode_block, exec_output) = \ + GenAluOp(name, Name, 'BranchPCRel', basic_code, inst_flags, + CheckLkDecode, BasicConstructor) + + # The version that does the update + update_code = basic_code + updateLrCode + update_flags = inst_flags + [ 'IsCall' ] + (header_output_up, decoder_output_up, _, exec_output_up) = \ + GenAluOp(name, Name + 'UpdateLr', 'BranchPCRel', update_code, + update_flags, CheckLkDecode, BasicConstructor) + + # Add the outputs together + header_output += header_output_up + decoder_output += decoder_output_up + exec_output += exec_output_up +}}; + +// Instructions that unconditionally branch to a specific address. +def format BranchNonPCRel(br_code, inst_flags = []) {{ + inst_flags += ('IsUncondControl', 'IsDirectControl') + basic_code = br_code + + # The version that does not update LR + (header_output, decoder_output, decode_block, exec_output) = \ + GenAluOp(name, Name, 'BranchNonPCRel', basic_code, inst_flags, + CheckLkDecode, BasicConstructor) + + # The version that does the update + update_code = basic_code + updateLrCode + update_flags = inst_flags + [ 'IsCall' ] + (header_output_up, decoder_output_up, _, exec_output_up) = \ + GenAluOp(name, Name + 'UpdateLr', 'BranchNonPCRel', update_code, + update_flags, CheckLkDecode, BasicConstructor) + + # Add the outputs together + header_output += header_output_up + decoder_output += decoder_output_up + exec_output += exec_output_up +}}; + +let {{ + +# Check the condition register (CR) allows the branch to be taken. +def GetCondCode(br_code): + cond_code = 'if(condOk(CR)) {\n' + cond_code += ' ' + br_code + '\n' + cond_code += '} else {\n' + cond_code += ' NPC = NPC;\n' + cond_code += '}\n' + return cond_code + +# Check the condition register (CR) and count register (CTR) allow the +# branch to be taken. Also, in certain situations, decrement the count +# register too. This takes place in ctrOk within BranchCond classes. +def GetCtrCondCode(br_code): + cond_code = 'uint32_t ctr = CTR;\n' + cond_code += 'bool ctr_ok = ctrOk(ctr);\n' + cond_code += 'bool cond_ok = condOk(CR);\n' + cond_code += 'if(ctr_ok && cond_ok) {\n' + cond_code += ' ' + br_code + '\n' + cond_code += '} else {\n' + cond_code += ' NPC = NPC;\n' + cond_code += '}\n' + cond_code += 'CTR = ctr;\n' + return cond_code + +}}; + +// Instructions that conditionally branch relative to the current PC based on +// the condition register (CR) and count register (CTR). +def format BranchPCRelCondCtr(br_code, inst_flags = []) {{ + inst_flags += ('IsCondControl', 'IsDirectControl') + basic_code = GetCtrCondCode(br_code) + + # The version that does not update LR + (header_output, decoder_output, decode_block, exec_output) = \ + GenAluOp(name, Name, 'BranchPCRelCond', basic_code, inst_flags, + CheckLkDecode, BasicConstructor) + + # The version that does the update + update_code = basic_code + updateLrCode + update_flags = inst_flags + [ 'IsCall' ] + (header_output_up, decoder_output_up, _, exec_output_up) = \ + GenAluOp(name, Name + 'UpdateLr', 'BranchPCRelCond', update_code, + update_flags, CheckLkDecode, BasicConstructor) + + # Add the outputs together + header_output += header_output_up + decoder_output += decoder_output_up + exec_output += exec_output_up +}}; + +// Instructions that conditionally branch to a specific address based on the +// condition register (CR) and count register (CTR). +def format BranchNonPCRelCondCtr(br_code, inst_flags = []) {{ + inst_flags += ('IsCondControl', 'IsDirectControl') + basic_code = GetCtrCondCode(br_code) + + # The version that does not update LR + (header_output, decoder_output, decode_block, exec_output) = \ + GenAluOp(name, Name, 'BranchNonPCRelCond', basic_code, inst_flags, + CheckLkDecode, BasicConstructor) + + # The version that does the update + update_code = basic_code + updateLrCode + update_flags = inst_flags + [ 'IsCall' ] + (header_output_up, decoder_output_up, _, exec_output_up) = \ + GenAluOp(name, Name + 'UpdateLr', 'BranchNonPCRelCond', update_code, + update_flags, CheckLkDecode, BasicConstructor) + + # Add the outputs together + header_output += header_output_up + decoder_output += decoder_output_up + exec_output += exec_output_up +}}; + +// Instructions that conditionally branch to the address in the link register +// (LR) based on the condition register (CR) and count register (CTR). +def format BranchLrCondCtr(br_code, inst_flags = []) {{ + inst_flags += ('IsCondControl', 'IsIndirectControl', 'IsReturn') + basic_code = GetCtrCondCode(br_code) + + # The version that does not update LR + (header_output, decoder_output, decode_block, exec_output) = \ + GenAluOp(name, Name, 'BranchRegCond', basic_code, inst_flags, + CheckLkDecode, BasicConstructor) + + # The version that does the update + update_code = basic_code + updateLrCode + (header_output_up, decoder_output_up, _, exec_output_up) = \ + GenAluOp(name, Name + 'UpdateLr', 'BranchRegCond', update_code, + inst_flags, CheckLkDecode, BasicConstructor) + + # Add the outputs together + header_output += header_output_up + decoder_output += decoder_output_up + exec_output += exec_output_up +}}; + +// Instructions that conditionally branch to the address in the count register +// (CTR) based on the condition register (CR). +def format BranchCtrCond(br_code, inst_flags = []) {{ + inst_flags += ('IsCondControl', 'IsIndirectControl') + basic_code = GetCondCode(br_code) + + # The version that does not update LR + (header_output, decoder_output, decode_block, exec_output) = \ + GenAluOp(name, Name, 'BranchRegCond', basic_code, inst_flags, + CheckLkDecode, BasicConstructor) + + # The version that does the update + update_code = basic_code + updateLrCode + update_flags = inst_flags + [ 'IsCall' ] + (header_output_up, decoder_output_up, _, exec_output_up) = \ + GenAluOp(name, Name + 'UpdateLr', 'BranchRegCond', update_code, + update_flags, CheckLkDecode, BasicConstructor) + + # Add the outputs together + header_output += header_output_up + decoder_output += decoder_output_up + exec_output += exec_output_up +}}; diff --git a/src/arch/power/isa/formats/condition.isa b/src/arch/power/isa/formats/condition.isa new file mode 100644 index 000000000..12ee7ae7d --- /dev/null +++ b/src/arch/power/isa/formats/condition.isa @@ -0,0 +1,47 @@ +// -*- mode:c++ -*- + +// Copyright (c) 2009 The University of Edinburgh +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer; +// redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution; +// neither the name of the copyright holders nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: Timothy M. Jones + +// Logical instructions that manipulate the condition register +def format CondLogicOp(code, *flags) {{ + iop = InstObjParams(name, Name, 'CondLogicOp', code, flags) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecode.subst(iop) + exec_output = BasicExecute.subst(iop) +}}; + +// Instructions that condition register fields +def format CondMoveOp(code, *flags) {{ + iop = InstObjParams(name, Name, 'CondMoveOp', code, flags) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecode.subst(iop) + exec_output = BasicExecute.subst(iop) +}}; diff --git a/src/arch/power/isa/formats/formats.isa b/src/arch/power/isa/formats/formats.isa new file mode 100644 index 000000000..ec2575196 --- /dev/null +++ b/src/arch/power/isa/formats/formats.isa @@ -0,0 +1,60 @@ +// -*- mode:c++ -*- + +// Copyright (c) 2009 The University of Edinburgh +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer; +// redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution; +// neither the name of the copyright holders nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: Timothy M. Jones + +//Templates from this format are used later +//Include the basic format +##include "basic.isa" + +//Include integer instructions +##include "integer.isa" + +//Include condition register instructions +##include "condition.isa" + +//Include utility functions +##include "util.isa" + +//Include the float formats +##include "fp.isa" + +//Include the mem format +##include "mem.isa" + +//Include the branch format +##include "branch.isa" + +//Include the misc format +##include "misc.isa" + +//Include the unimplemented format +##include "unimp.isa" + +//Include the unknown format +##include "unknown.isa" diff --git a/src/arch/power/isa/formats/fp.isa b/src/arch/power/isa/formats/fp.isa new file mode 100644 index 000000000..db917476e --- /dev/null +++ b/src/arch/power/isa/formats/fp.isa @@ -0,0 +1,132 @@ +// -*- mode:c++ -*- + +// Copyright (c) 2009 The University of Edinburgh +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer; +// redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution; +// neither the name of the copyright holders nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: Timothy M. Jones + +//////////////////////////////////////////////////////////////////// +// +// Floating Point operate instructions +// + + +let {{ + + readFPSCRCode = 'Fpscr fpscr = FPSCR;' + + computeCR1Code = ''' + Cr cr = CR; + cr.cr1 = (fpscr.fx << 3) | (fpscr.fex << 2) | + (fpscr.vx << 1) | fpscr.ox; + CR = cr; + ''' + +}}; + +// Primary format for floating point operate instructions: +def format FloatOp(code, inst_flags = []) {{ + iop = InstObjParams(name, Name, 'FloatOp', + {"code": code}, + inst_flags) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecode.subst(iop) + exec_output = BasicExecute.subst(iop) +}}; + +// Floating point operations that compute the CR1 code if RC is set. No other +// special registers are touched using these operations. +def format FloatRCCheckOp(code, inst_flags = []) {{ + + # Code when Rc is set + code_rc1 = code + readFPSCRCode + computeCR1Code + + # Generate the first class + (header_output, decoder_output, decode_block, exec_output) = \ + GenAluOp(name, Name, 'FloatOp', code, inst_flags, + CheckRcDecode, BasicConstructor) + + # Generate the second class + (header_output_rc1, decoder_output_rc1, _, exec_output_rc1) = \ + GenAluOp(name, Name + 'RcSet', 'FloatOp', code_rc1, inst_flags, + CheckRcDecode, IntRcConstructor) + + # Finally, add to the other outputs + header_output += header_output_rc1 + decoder_output += decoder_output_rc1 + exec_output += exec_output_rc1 +}}; + +// Floating point elementary arithmetic operations. Besides having two +// versions of each instruction for when Rc is set or not, we also have +// to alter lots of special registers depending on the result of the +// operation. The result is always in Ft.sf. +def format FloatArithOp(code, inst_flags = []) {{ + + # Code when Rc is set + code_rc1 = code + readFPSCRCode + computeCR1Code + + # Generate the first class + (header_output, decoder_output, decode_block, exec_output) = \ + GenAluOp(name, Name, 'FloatOp', code, inst_flags, + CheckRcDecode, BasicConstructor) + + # Generate the second class + (header_output_rc1, decoder_output_rc1, _, exec_output_rc1) = \ + GenAluOp(name, Name + 'RcSet', 'FloatOp', code_rc1, inst_flags, + CheckRcDecode, IntRcConstructor) + + # Finally, add to the other outputs + header_output += header_output_rc1 + decoder_output += decoder_output_rc1 + exec_output += exec_output_rc1 +}}; + +// Floating point rounding and conversion operations. Besides having two +// versions of each instruction for when Rc is set or not, we also have +// to alter lots of special registers depending on the result of the +// operation. The result is always in Ft.sf. +def format FloatConvertOp(code, inst_flags = []) {{ + + # Code when Rc is set + code_rc1 = code + readFPSCRCode + computeCR1Code + + # Generate the first class + (header_output, decoder_output, decode_block, exec_output) = \ + GenAluOp(name, Name, 'FloatOp', code, inst_flags, + CheckRcDecode, BasicConstructor) + + # Generate the second class + (header_output_rc1, decoder_output_rc1, _, exec_output_rc1) = \ + GenAluOp(name, Name + 'RcSet', 'FloatOp', code_rc1, inst_flags, + CheckRcDecode, IntRcConstructor) + + # Finally, add to the other outputs + header_output += header_output_rc1 + decoder_output += decoder_output_rc1 + exec_output += exec_output_rc1 +}}; diff --git a/src/arch/power/isa/formats/integer.isa b/src/arch/power/isa/formats/integer.isa new file mode 100644 index 000000000..0766826ec --- /dev/null +++ b/src/arch/power/isa/formats/integer.isa @@ -0,0 +1,369 @@ +// -*- mode:c++ -*- + +// Copyright (c) 2009 The University of Edinburgh +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer; +// redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution; +// neither the name of the copyright holders nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: Timothy M. Jones + +//////////////////////////////////////////////////////////////////// +// +// Integer ALU instructions +// + + +// Instruction class constructor template when Rc is set. +def template IntRcConstructor {{ + inline %(class_name)s::%(class_name)s(ExtMachInst machInst) : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s) + { + %(constructor)s; + rcSet = true; + } +}}; + + +// Instruction class constructor template when OE is set. +def template IntOeConstructor {{ + inline %(class_name)s::%(class_name)s(ExtMachInst machInst) : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s) + { + %(constructor)s; + oeSet = true; + } +}}; + + +// Instruction class constructor template when both Rc and OE are set. +def template IntRcOeConstructor {{ + inline %(class_name)s::%(class_name)s(ExtMachInst machInst) : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s) + { + %(constructor)s; + rcSet = true; + oeSet = true; + } +}}; + + +let {{ + +readXERCode = 'Xer xer = XER;' + +setXERCode = 'XER = xer;' + +computeCR0Code = ''' + Cr cr = CR; + cr.cr0 = makeCRField((int32_t)%(result)s, (int32_t)0, xer.so); + CR = cr; +''' + +computeCACode = ''' + if (findCarry(32, %(result)s, %(inputa)s, %(inputb)s)) { + xer.ca = 1; + } else { + xer.ca = 0; + } +''' + +computeOVCode = ''' + if (findOverflow(32, %(result)s, %(inputa)s, %(inputb)s)) { + xer.ov = 1; + xer.so = 1; + } else { + xer.ov = 0; + } +''' + +computeDivOVCode = ''' + if (divSetOV) { + xer.ov = 1; + xer.so = 1; + } else { + if (findOverflow(32, %(result)s, %(inputa)s, %(inputb)s)) { + xer.ov = 1; + xer.so = 1; + } else { + xer.ov = 0; + } + } +''' + +}}; + + +// A basic integer instruction. +def format IntOp(code, inst_flags = []) {{ + (header_output, decoder_output, decode_block, exec_output) = \ + GenAluOp(name, Name, 'IntOp', code, inst_flags, BasicDecode, + BasicConstructor) +}}; + + +// Integer instructions with immediate (signed or unsigned). +def format IntImmOp(code, inst_flags = []) {{ + (header_output, decoder_output, decode_block, exec_output) = \ + GenAluOp(name, Name, 'IntImmOp', code, inst_flags, BasicDecode, + BasicConstructor) +}}; + + +// Integer instructions with immediate that perform arithmetic. +// These instructions all write to Rt and use an altered form of the +// value in source register Ra, hence the use of src to hold the actual +// value. The control flags include the use of code to compute the +// carry bit or the CR0 code. +def format IntImmArithOp(code, ctrl_flags = [], inst_flags = []) {{ + + # Set up the dictionary and deal with control flags + dict = {'result':'Rt', 'inputa':'src', 'inputb':'imm'} + if ctrl_flags: + code += readXERCode + for val in ctrl_flags: + if val == 'computeCA': + code += computeCACode % dict + setXERCode + elif val == 'computeCR0': + code += computeCR0Code % dict + + # Generate the class + (header_output, decoder_output, decode_block, exec_output) = \ + GenAluOp(name, Name, 'IntImmOp', code, inst_flags, BasicDecode, + BasicConstructor) +}}; + + +// Integer instructions with immediate that perform arithmetic but use +// the value 0 when Ra == 0. We generate two versions of each instruction +// corresponding to these two different scenarios. The correct version is +// determined at decode (see the CheckRaDecode template). +def format IntImmArithCheckRaOp(code, code_ra0, inst_flags = []) {{ + + # First the version where Ra is non-zero + (header_output, decoder_output, decode_block, exec_output) = \ + GenAluOp(name, Name, 'IntImmOp', code, inst_flags, + CheckRaDecode, BasicConstructor) + + # Now another version where Ra == 0 + (header_output_ra0, decoder_output_ra0, _, exec_output_ra0) = \ + GenAluOp(name, Name + 'RaZero', 'IntImmOp', code_ra0, inst_flags, + CheckRaDecode, BasicConstructor) + + # Finally, add to the other outputs + header_output += header_output_ra0 + decoder_output += decoder_output_ra0 + exec_output += exec_output_ra0 +}}; + + +// Integer instructions with immediate that perform logic operations. +// All instructions write to Ra and use Rs as a source register. Some +// also compute the CR0 code too. +def format IntImmLogicOp(code, computeCR0 = 0, inst_flags = []) {{ + + # Set up the dictionary and deal with computing CR0 + dict = {'result':'Ra'} + if computeCR0: + code += readXERCode + computeCR0Code % dict + + # Generate the class + (header_output, decoder_output, decode_block, exec_output) = \ + GenAluOp(name, Name, 'IntImmOp', code, inst_flags, BasicDecode, + BasicConstructor) +}}; + + +// Integer instructions that perform logic operations. The result is +// always written into Ra. All instructions have 2 versions depending on +// whether the Rc bit is set to compute the CR0 code. This is determined +// at decode as before. +def format IntLogicOp(code, inst_flags = []) {{ + dict = {'result':'Ra'} + + # Code when Rc is set + code_rc1 = code + readXERCode + computeCR0Code % dict + + # Generate the first class + (header_output, decoder_output, decode_block, exec_output) = \ + GenAluOp(name, Name, 'IntOp', code, inst_flags, + CheckRcDecode, BasicConstructor) + + # Generate the second class + (header_output_rc1, decoder_output_rc1, _, exec_output_rc1) = \ + GenAluOp(name, Name + 'RcSet', 'IntOp', code_rc1, inst_flags, + CheckRcDecode, IntRcConstructor) + + # Finally, add to the other outputs + header_output += header_output_rc1 + decoder_output += decoder_output_rc1 + exec_output += exec_output_rc1 +}}; + + +// Integer instructions with a shift amount. As above, except inheriting +// from the IntShiftOp class. +def format IntShiftOp(code, inst_flags = []) {{ + dict = {'result':'Ra'} + + # Code when Rc is set + code_rc1 = code + readXERCode + computeCR0Code % dict + + # Generate the first class + (header_output, decoder_output, decode_block, exec_output) = \ + GenAluOp(name, Name, 'IntShiftOp', code, inst_flags, + CheckRcDecode, BasicConstructor) + + # Generate the second class + (header_output_rc1, decoder_output_rc1, _, exec_output_rc1) = \ + GenAluOp(name, Name + 'RcSet', 'IntShiftOp', code_rc1, inst_flags, + CheckRcDecode, IntRcConstructor) + + # Finally, add to the other outputs + header_output += header_output_rc1 + decoder_output += decoder_output_rc1 + exec_output += exec_output_rc1 +}}; + + +// Instructions in this format are all reduced to the form Rt = src1 + src2, +// therefore we just give src1 and src2 definitions. In working out the +// template we first put in the definitions of the variables and then +// the code for the addition. We also deal with computing the carry flag +// if required. +// +// We generate 4 versions of each instruction. This correspond to the +// different combinations of having the OE bit set or unset (which controls +// whether the overflow flag is computed) and the Rc bit set or unset too +// (which controls whether the CR0 code is computed). +def format IntSumOp(src1, src2, ca = {{ 0 }}, computeCA = 0, + inst_flags = []) {{ + + # The result is always in Rt, but the source values vary + dict = {'result':'Rt', 'inputa':'src1', 'inputb':'src2'} + + # Add code to set up variables and do the sum + code = 'uint32_t src1 = ' + src1 + ';\n' + code += 'uint32_t src2 = ' + src2 + ';\n' + code += 'uint32_t ca = ' + ca + ';\n' + code += 'Rt = src1 + src2 + ca;\n' + + # Add code for calculating the carry, if needed + if computeCA: + code += computeCACode % dict + setXERCode + + # Setup the 4 code versions and add code to access XER if necessary + code_rc1 = readXERCode + code + code_oe1 = readXERCode + code + computeOVCode % dict + setXERCode + code_rc1_oe1 = readXERCode + code + computeOVCode % dict + setXERCode + if (computeCA or ca == 'xer.ca'): + code = readXERCode + code + code_rc1 += computeCR0Code % dict + code_rc1_oe1 += computeCR0Code % dict + + # Generate the classes + (header_output, decoder_output, decode_block, exec_output) = \ + GenAluOp(name, Name, 'IntOp', code, inst_flags, + CheckRcOeDecode, BasicConstructor) + (header_output_rc1, decoder_output_rc1, _, exec_output_rc1) = \ + GenAluOp(name, Name + 'RcSet', 'IntOp', code_rc1, inst_flags, + CheckRcOeDecode, IntRcConstructor) + (header_output_oe1, decoder_output_oe1, _, exec_output_oe1) = \ + GenAluOp(name, Name + 'OeSet', 'IntOp', code_oe1, inst_flags, + CheckRcOeDecode, IntOeConstructor) + (header_output_rc1_oe1, decoder_output_rc1_oe1, _, exec_output_rc1_oe1) = \ + GenAluOp(name, Name + 'RcSetOeSet', 'IntOp', code_rc1_oe1, + inst_flags, CheckRcOeDecode, IntRcOeConstructor) + + # Finally, add to the other outputs + header_output += \ + header_output_rc1 + header_output_oe1 + header_output_rc1_oe1 + decoder_output += \ + decoder_output_rc1 + decoder_output_oe1 + decoder_output_rc1_oe1 + exec_output += \ + exec_output_rc1 + exec_output_oe1 + exec_output_rc1_oe1 + +}}; + + +// Instructions that use source registers Ra and Rb, with the result +// placed into Rt. Basically multiply and divide instructions. The +// carry bit is never set, but overflow can be calculated. Division +// explicitly sets the overflow bit in certain situations and this is +// dealt with using the 'divSetOV' boolean in decoder.isa. We generate +// two versions of each instruction to deal with the Rc bit. +def format IntArithOp(code, computeOV = 0, inst_flags = []) {{ + + # The result is always in Rt, but the source values vary + dict = {'result':'Rt', 'inputa':'src1', 'inputb':'src2'} + + # Deal with setting the overflow flag + if computeOV: + code = 'bool divSetOV = false;\n' + code + code += computeDivOVCode % dict + setXERCode + + # Setup the 2 code versions and add code to access XER if necessary + code_rc1 = readXERCode + code + computeCR0Code % dict + if computeOV: + code = readXERCode + code + + # Generate the classes + (header_output, decoder_output, decode_block, exec_output) = \ + GenAluOp(name, Name, 'IntOp', code, inst_flags, + CheckRcDecode, BasicConstructor) + + # Generate the second class + (header_output_rc1, decoder_output_rc1, _, exec_output_rc1) = \ + GenAluOp(name, Name + 'RcSet', 'IntOp', code_rc1, inst_flags, + CheckRcDecode, IntRcConstructor) + + # Finally, add to the other outputs + header_output += header_output_rc1 + decoder_output += decoder_output_rc1 + exec_output += exec_output_rc1 +}}; + + +// A special format for rotate instructions which use certain fields +// from the instruction's binary encoding. We need two versions for each +// instruction to deal with the Rc bit. +def format IntRotateOp(code, inst_flags = []) {{ + + # The result is always in Ra + dict = {'result':'Ra'} + + # Setup the code for when Rc is set + code_rc1 = readXERCode + code + computeCR0Code % dict + + # Generate the first class + (header_output, decoder_output, decode_block, exec_output) = \ + GenAluOp(name, Name, 'IntRotateOp', code, inst_flags, + CheckRcDecode, BasicConstructor) + + # Generate the second class + (header_output_rc1, decoder_output_rc1, _, exec_output_rc1) = \ + GenAluOp(name, Name + 'RcSet', 'IntRotateOp', code_rc1, inst_flags, + CheckRcDecode, IntRcConstructor) + + # Finally, add to the other outputs + header_output += header_output_rc1 + decoder_output += decoder_output_rc1 + exec_output += exec_output_rc1 +}}; diff --git a/src/arch/power/isa/formats/mem.isa b/src/arch/power/isa/formats/mem.isa new file mode 100644 index 000000000..1be49c2f7 --- /dev/null +++ b/src/arch/power/isa/formats/mem.isa @@ -0,0 +1,351 @@ +// -*- mode:c++ -*- + +// Copyright (c) 2009 The University of Edinburgh +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer; +// redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution; +// neither the name of the copyright holders nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: Timothy M. Jones + +//////////////////////////////////////////////////////////////////// +// +// Memory-format instructions +// + +def template LoadStoreDeclare {{ + /** + * Static instruction class for "%(mnemonic)s". + */ + class %(class_name)s : public %(base_class)s + { + public: + + /// Constructor. + %(class_name)s(ExtMachInst machInst); + + %(BasicExecDeclare)s + + %(InitiateAccDeclare)s + + %(CompleteAccDeclare)s + }; +}}; + + +def template InitiateAccDeclare {{ + Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const; +}}; + + +def template CompleteAccDeclare {{ + Fault completeAcc(PacketPtr, %(CPU_exec_context)s *, Trace::InstRecord *) const; +}}; + + +def template LoadStoreConstructor {{ + inline %(class_name)s::%(class_name)s(ExtMachInst machInst) + : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s) + { + %(constructor)s; + } +}}; + + +def template LoadExecute {{ + Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + Addr EA; + Fault fault = NoFault; + + %(op_decl)s; + %(op_rd)s; + %(ea_code)s; + + if (fault == NoFault) { + fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags); + %(memacc_code)s; + } + + if (fault == NoFault) { + %(op_wb)s; + } + + return fault; + } +}}; + + +def template LoadInitiateAcc {{ + Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + Addr EA; + Fault fault = NoFault; + + %(op_src_decl)s; + %(op_rd)s; + %(ea_code)s; + + if (fault == NoFault) { + fault = xc->read(EA, (uint%(mem_acc_size)d_t &)Mem, memAccessFlags); + xc->setEA(EA); + } + + return fault; + } +}}; + + +def template LoadCompleteAcc {{ + Fault %(class_name)s::completeAcc(PacketPtr pkt, + %(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + Addr EA; + Fault fault = NoFault; + uint%(mem_acc_size)d_t val; + + %(op_decl)s; + %(op_rd)s; + + EA = xc->getEA(); + + val = pkt->get(); + *((uint%(mem_acc_size)d_t*)&Mem) = val; + + if (fault == NoFault) { + %(memacc_code)s; + } + + if (fault == NoFault) { + %(op_wb)s; + } + + return fault; + } +}}; + + +def template StoreExecute {{ + Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + Addr EA; + Fault fault = NoFault; + + %(op_decl)s; + %(op_rd)s; + %(ea_code)s; + + if (fault == NoFault) { + %(memacc_code)s; + } + + if (fault == NoFault) { + fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, + memAccessFlags, NULL); + if (traceData) { traceData->setData(Mem); } + } + + if (fault == NoFault) { + %(op_wb)s; + } + + return fault; + } +}}; + + +def template StoreInitiateAcc {{ + Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + Addr EA; + Fault fault = NoFault; + + %(op_decl)s; + %(op_rd)s; + %(ea_code)s; + + if (fault == NoFault) { + %(memacc_code)s; + } + + if (fault == NoFault) { + fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, + memAccessFlags, NULL); + if (traceData) { traceData->setData(Mem); } + } + + // Need to write back any potential address register update + if (fault == NoFault) { + %(op_wb)s; + } + + return fault; + } +}}; + + +def template StoreCompleteAcc {{ + Fault %(class_name)s::completeAcc(PacketPtr pkt, + %(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + Fault fault = NoFault; + + %(op_dest_decl)s; + + if (fault == NoFault) { + %(op_wb)s; + } + + return fault; + } +}}; + + +// The generic memory operation generator. This is called when two versions +// of an instruction are needed - when Ra == 0 and otherwise. This is so +// that instructions can use the value 0 when Ra == 0 but avoid having a +// dependence on Ra. +let {{ + +def GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0, base, + load_or_store, mem_flags = [], inst_flags = []): + + # First the version where Ra is non-zero + (header_output, decoder_output, decode_block, exec_output) = \ + LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, + base_class = base, + decode_template = CheckRaDecode, + exec_template_base = load_or_store) + + # Now another version where Ra == 0 + (header_output_ra0, decoder_output_ra0, _, exec_output_ra0) = \ + LoadStoreBase(name, Name + 'RaZero', ea_code_ra0, memacc_code, + mem_flags, inst_flags, + base_class = base, + exec_template_base = load_or_store) + + # Finally, add to the other outputs + header_output += header_output_ra0 + decoder_output += decoder_output_ra0 + exec_output += exec_output_ra0 + return (header_output, decoder_output, decode_block, exec_output) + +}}; + + +def format LoadIndexOp(memacc_code, ea_code = {{ EA = Ra + Rb; }}, + ea_code_ra0 = {{ EA = Rb; }}, + mem_flags = [], inst_flags = []) {{ + (header_output, decoder_output, decode_block, exec_output) = \ + GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0, + 'MemOp', 'Load', mem_flags, inst_flags) +}}; + + +def format StoreIndexOp(memacc_code, ea_code = {{ EA = Ra + Rb; }}, + ea_code_ra0 = {{ EA = Rb; }}, + mem_flags = [], inst_flags = []) {{ + (header_output, decoder_output, decode_block, exec_output) = \ + GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0, + 'MemOp', 'Store', mem_flags, inst_flags) +}}; + + +def format LoadIndexUpdateOp(memacc_code, ea_code = {{ EA = Ra + Rb; }}, + mem_flags = [], inst_flags = []) {{ + + # Add in the update code + memacc_code += 'Ra = EA;' + + # Generate the class + (header_output, decoder_output, decode_block, exec_output) = \ + LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, + base_class = 'MemOp', + exec_template_base = 'Load') +}}; + + +def format StoreIndexUpdateOp(memacc_code, ea_code = {{ EA = Ra + Rb; }}, + mem_flags = [], inst_flags = []) {{ + + # Add in the update code + memacc_code += 'Ra = EA;' + + # Generate the class + (header_output, decoder_output, decode_block, exec_output) = \ + LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, + base_class = 'MemOp', + exec_template_base = 'Store') +}}; + + +def format LoadDispOp(memacc_code, ea_code = {{ EA = Ra + disp; }}, + ea_code_ra0 = {{ EA = disp; }}, + mem_flags = [], inst_flags = []) {{ + (header_output, decoder_output, decode_block, exec_output) = \ + GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0, + 'MemDispOp', 'Load', mem_flags, inst_flags) +}}; + + +def format StoreDispOp(memacc_code, ea_code = {{ EA = Ra + disp; }}, + ea_code_ra0 = {{ EA = disp; }}, + mem_flags = [], inst_flags = []) {{ + (header_output, decoder_output, decode_block, exec_output) = \ + GenMemOp(name, Name, memacc_code, ea_code, ea_code_ra0, + 'MemDispOp', 'Store', mem_flags, inst_flags) +}}; + + +def format LoadDispUpdateOp(memacc_code, ea_code = {{ EA = Ra + disp; }}, + mem_flags = [], inst_flags = []) {{ + + # Add in the update code + memacc_code += 'Ra = EA;' + + # Generate the class + (header_output, decoder_output, decode_block, exec_output) = \ + LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, + base_class = 'MemDispOp', + exec_template_base = 'Load') +}}; + + +def format StoreDispUpdateOp(memacc_code, ea_code = {{ EA = Ra + disp; }}, + mem_flags = [], inst_flags = []) {{ + + # Add in the update code + memacc_code += 'Ra = EA;' + + # Generate the class + (header_output, decoder_output, decode_block, exec_output) = \ + LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, + base_class = 'MemDispOp', + exec_template_base = 'Store') +}}; diff --git a/src/arch/power/isa/formats/misc.isa b/src/arch/power/isa/formats/misc.isa new file mode 100644 index 000000000..93536aa18 --- /dev/null +++ b/src/arch/power/isa/formats/misc.isa @@ -0,0 +1,61 @@ +// -*- mode:c++ -*- + +// Copyright (c) 2009 The University of Edinburgh +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer; +// redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution; +// neither the name of the copyright holders nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: Timothy M. Jones + +//////////////////////////////////////////////////////////////////// +// +// Misc instructions +// + +def template MiscOpExecute {{ + Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const + { + Fault fault = NoFault; + %(op_decl)s; + %(op_rd)s; + + %(code)s; + if (fault == NoFault) + { + %(op_wb)s; + } + + return fault; + } +}}; + +def format MiscOp(code, opt_flags = []) {{ + iop = InstObjParams(name, Name, 'IntOp', + {"code": code}, + opt_flags) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecode.subst(iop) + exec_output = MiscOpExecute.subst(iop) +}}; diff --git a/src/arch/power/isa/formats/unimp.isa b/src/arch/power/isa/formats/unimp.isa new file mode 100644 index 000000000..60a7c469d --- /dev/null +++ b/src/arch/power/isa/formats/unimp.isa @@ -0,0 +1,146 @@ +// -*- mode:c++ -*- + +// Copyright (c) 2007-2008 The Florida State University +// Copyright (c) 2009 The University of Edinburgh +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer; +// redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution; +// neither the name of the copyright holders nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: Stephen Hines +// Timothy M. Jones + +//////////////////////////////////////////////////////////////////// +// +// Unimplemented instructions +// + +output header {{ + /** + * Static instruction class for unimplemented instructions that + * cause simulator termination. Note that these are recognized + * (legal) instructions that the simulator does not support; the + * 'Unknown' class is used for unrecognized/illegal instructions. + * This is a leaf class. + */ + class FailUnimplemented : public PowerStaticInst + { + public: + /// Constructor + FailUnimplemented(const char *_mnemonic, MachInst _machInst) + : PowerStaticInst(_mnemonic, _machInst, No_OpClass) + { + // don't call execute() (which panics) if we're on a + // speculative path + flags[IsNonSpeculative] = true; + } + + %(BasicExecDeclare)s + + std::string + generateDisassembly(Addr pc, const SymbolTable *symtab) const; + }; + + /** + * Base class for unimplemented instructions that cause a warning + * to be printed (but do not terminate simulation). This + * implementation is a little screwy in that it will print a + * warning for each instance of a particular unimplemented machine + * instruction, not just for each unimplemented opcode. Should + * probably make the 'warned' flag a static member of the derived + * class. + */ + class WarnUnimplemented : public PowerStaticInst + { + private: + /// Have we warned on this instruction yet? + mutable bool warned; + + public: + /// Constructor + WarnUnimplemented(const char *_mnemonic, MachInst _machInst) + : PowerStaticInst(_mnemonic, _machInst, No_OpClass), warned(false) + { + // don't call execute() (which panics) if we're on a + // speculative path + flags[IsNonSpeculative] = true; + } + + %(BasicExecDeclare)s + + std::string + generateDisassembly(Addr pc, const SymbolTable *symtab) const; + }; +}}; + +output decoder {{ + std::string + FailUnimplemented::generateDisassembly(Addr pc, + const SymbolTable *symtab) const + { + return csprintf("%-10s (unimplemented)", mnemonic); + } + + std::string + WarnUnimplemented::generateDisassembly(Addr pc, + const SymbolTable *symtab) const + { + return csprintf("%-10s (unimplemented)", mnemonic); + } +}}; + +output exec {{ + Fault + FailUnimplemented::execute(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + panic("attempt to execute unimplemented instruction '%s' " + "(inst 0x%08x, opcode 0x%x, binary:%s)", mnemonic, machInst, OPCODE, + inst2string(machInst)); + return new UnimplementedOpcodeFault; + } + + Fault + WarnUnimplemented::execute(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + if (!warned) { + warn("\tinstruction '%s' unimplemented\n", mnemonic); + warned = true; + } + + return NoFault; + } +}}; + + +def format FailUnimpl() {{ + iop = InstObjParams(name, 'FailUnimplemented') + decode_block = BasicDecodeWithMnemonic.subst(iop) +}}; + +def format WarnUnimpl() {{ + iop = InstObjParams(name, 'WarnUnimplemented') + decode_block = BasicDecodeWithMnemonic.subst(iop) +}}; + diff --git a/src/arch/power/isa/formats/unknown.isa b/src/arch/power/isa/formats/unknown.isa new file mode 100644 index 000000000..06e6ece26 --- /dev/null +++ b/src/arch/power/isa/formats/unknown.isa @@ -0,0 +1,87 @@ +// -*- mode:c++ -*- + +// Copyright (c) 2007-2008 The Florida State University +// Copyright (c) 2009 The University of Edinburgh +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer; +// redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution; +// neither the name of the copyright holders nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: Stephen Hines +// Timothy M. Jones + +//////////////////////////////////////////////////////////////////// +// +// Unknown instructions +// + +output header {{ + /** + * Static instruction class for unknown (illegal) instructions. + * These cause simulator termination if they are executed in a + * non-speculative mode. This is a leaf class. + */ + class Unknown : public PowerStaticInst + { + public: + /// Constructor + Unknown(ExtMachInst _machInst) + : PowerStaticInst("unknown", _machInst, No_OpClass) + { + // don't call execute() (which panics) if we're on a + // speculative path + flags[IsNonSpeculative] = true; + } + + %(BasicExecDeclare)s + + std::string + generateDisassembly(Addr pc, const SymbolTable *symtab) const; + }; +}}; + +output decoder {{ + std::string + Unknown::generateDisassembly(Addr pc, const SymbolTable *symtab) const + { + return csprintf("%-10s (inst 0x%x, opcode 0x%x, binary:%s)", + "unknown", machInst, OPCODE, inst2string(machInst)); + } +}}; + +output exec {{ + Fault + Unknown::execute(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + panic("attempt to execute unknown instruction at %#x" + "(inst 0x%08x, opcode 0x%x, binary: %s)", + xc->readPC(), machInst, OPCODE, inst2string(machInst)); + return new UnimplementedOpcodeFault; + } +}}; + +def format Unknown() {{ + decode_block = 'return new Unknown(machInst);\n' +}}; + diff --git a/src/arch/power/isa/formats/util.isa b/src/arch/power/isa/formats/util.isa new file mode 100644 index 000000000..ab1e530b2 --- /dev/null +++ b/src/arch/power/isa/formats/util.isa @@ -0,0 +1,174 @@ +// -*- mode:c++ -*- + +// Copyright (c) 2003-2005 The Regents of The University of Michigan +// Copyright (c) 2009 The University of Edinburgh +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer; +// redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution; +// neither the name of the copyright holders nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: Steve Reinhardt +// Korey Sewell +// Timothy M. Jones + +// Some instructions ignore the contents of Ra if Ra == 0, +// so check for this. +def template CheckRaDecode {{ + { + if (RA == 0) { + return new %(class_name)sRaZero(machInst); + } else { + return new %(class_name)s(machInst); + } + } +}}; + + +// Some instructions have extra behaviour if Rc is set. +def template CheckRcDecode {{ + { + if (RC31 == 0) { + return new %(class_name)s(machInst); + } else { + return new %(class_name)sRcSet(machInst); + } + } +}}; + + +// Some instructions have extra behaviour if Rc and OE are set. +def template CheckRcOeDecode {{ + { + if (RC31 == 0) { + if (OE == 0) { + return new %(class_name)s(machInst); + } else { + return new %(class_name)sOeSet(machInst); + } + } else { + if (OE == 0) { + return new %(class_name)sRcSet(machInst); + } else { + return new %(class_name)sRcSetOeSet(machInst); + } + } + } +}}; + +// Branch instructions always have two versions, one which sets the link +// register (LR). +def template CheckLkDecode {{ + { + if (LK == 0) { + return new %(class_name)s(machInst); + } else { + return new %(class_name)sUpdateLr(machInst); + } + } +}}; + + +let {{ + +def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, + base_class = 'MemOp', + decode_template = BasicDecode, exec_template_base = ''): + # Make sure flags are in lists (convert to lists if not). + mem_flags = makeList(mem_flags) + inst_flags = makeList(inst_flags) + + # add hook to get effective addresses into execution trace output. + ea_code += '\nif (traceData) { traceData->setAddr(EA); }\n' + + # Generate InstObjParams for the memory access. + iop = InstObjParams(name, Name, base_class, + {'ea_code': ea_code, + 'memacc_code': memacc_code}, + inst_flags) + + if mem_flags: + s = '\n\tmemAccessFlags = ' + string.join(mem_flags, '|') + ';' + iop.constructor += s + + fullExecTemplate = eval(exec_template_base + 'Execute') + initiateAccTemplate = eval(exec_template_base + 'InitiateAcc') + completeAccTemplate = eval(exec_template_base + 'CompleteAcc') + + # (header_output, decoder_output, decode_block, exec_output) + return (LoadStoreDeclare.subst(iop), + LoadStoreConstructor.subst(iop), + decode_template.subst(iop), + fullExecTemplate.subst(iop) + + initiateAccTemplate.subst(iop) + + completeAccTemplate.subst(iop)) + + +# The generic ALU instruction generator. Integer and fp formats calls this +# to generate the different output sections. +def GenAluOp(name, Name, base_class, code, inst_flags, decode_template, + constructor_template): + iop = InstObjParams(name, Name, base_class, + {"code": code}, + inst_flags) + header_output = BasicDeclare.subst(iop) + exec_output = BasicExecute.subst(iop) + + # We use constructors dependent on the Rc and OE bits being set + decoder_output = constructor_template.subst(iop) + + # The decode block defines which version to use + decode_block = decode_template.subst(iop) + return (header_output, decoder_output, decode_block, exec_output) + +}}; + + +output header {{ + std::string + inst2string(MachInst machInst); +}}; + +output decoder {{ + + std::string + inst2string(MachInst machInst) + { + std::string str = ""; + uint32_t mask = 0x80000000; + + for(int i=0; i < 32; i++) { + if ((machInst & mask) == 0) { + str += "0"; + } else { + str += "1"; + } + + mask = mask >> 1; + } + + return str; + } + +}}; + + diff --git a/src/arch/power/isa/includes.isa b/src/arch/power/isa/includes.isa new file mode 100644 index 000000000..47e8c1411 --- /dev/null +++ b/src/arch/power/isa/includes.isa @@ -0,0 +1,92 @@ +// -*- mode:c++ -*- + +// Copyright (c) 2009 The University of Edinburgh +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer; +// redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution; +// neither the name of the copyright holders nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: Timothy M. Jones + +//////////////////////////////////////////////////////////////////// +// +// Output include file directives. +// + +output header {{ +#include +#include +#include + +#include "arch/power/insts/branch.hh" +#include "arch/power/insts/mem.hh" +#include "arch/power/insts/integer.hh" +#include "arch/power/insts/floating.hh" +#include "arch/power/insts/condition.hh" +#include "arch/power/insts/misc.hh" +#include "arch/power/insts/static_inst.hh" +#include "arch/power/isa_traits.hh" +#include "cpu/static_inst.hh" +#include "mem/packet.hh" + +using namespace PowerISA; +}}; + +output decoder {{ +#include +#if defined(linux) +#include +#endif + +#include "arch/power/faults.hh" +#include "arch/power/isa_traits.hh" +#include "arch/power/utility.hh" +#include "base/cprintf.hh" +#include "base/loader/symtab.hh" +#include "cpu/thread_context.hh" + +using namespace PowerISA; +using std::isnan; +}}; + +output exec {{ +#include "arch/power/faults.hh" +#include "arch/power/isa_traits.hh" +#include "arch/power/utility.hh" + +#include +#if defined(linux) +#include +#endif + +#include "base/condcodes.hh" +#include "cpu/base.hh" +#include "cpu/exetrace.hh" +#include "mem/packet.hh" +#include "mem/packet_access.hh" +#include "sim/sim_exit.hh" + +using namespace PowerISA; +using std::isnan; +}}; + diff --git a/src/arch/power/isa/main.isa b/src/arch/power/isa/main.isa new file mode 100644 index 000000000..cce7e39ee --- /dev/null +++ b/src/arch/power/isa/main.isa @@ -0,0 +1,57 @@ +// -*- mode:c++ -*- + +// Copyright (c) 2009 The University of Edinburgh +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer; +// redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution; +// neither the name of the copyright holders nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: Timothy M. Jones + +//////////////////////////////////////////////////////////////////// +// +// Power ISA description file. +// +//////////////////////////////////////////////////////////////////// + +//Include the C++ include directives +##include "includes.isa" + +//////////////////////////////////////////////////////////////////// +// +// Namespace statement. Everything below this line will be in the +// PowerISAInst namespace. +// +namespace PowerISA; + +//Include the bitfield definitions +##include "bitfields.isa" + +//Include the operand_types and operand definitions +##include "operands.isa" + +//Include the definitions for the instruction formats +##include "formats/formats.isa" + +//Include the decoder definition +##include "decoder.isa" diff --git a/src/arch/power/isa/operands.isa b/src/arch/power/isa/operands.isa new file mode 100644 index 000000000..fc6c32685 --- /dev/null +++ b/src/arch/power/isa/operands.isa @@ -0,0 +1,81 @@ +// -*- mode:c++ -*- + +// Copyright (c) 2009 The University of Edinburgh +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer; +// redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution; +// neither the name of the copyright holders nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: Timothy M. Jones + +def operand_types {{ + 'sb' : ('signed int', 8), + 'ub' : ('unsigned int', 8), + 'sh' : ('signed int', 16), + 'uh' : ('unsigned int', 16), + 'sw' : ('signed int', 32), + 'uw' : ('unsigned int', 32), + 'sq' : ('signed int', 64), + 'uq' : ('unsigned int', 64), + 'sf' : ('float', 32), + 'df' : ('float', 64) +}}; + +def operands {{ + # General Purpose Integer Reg Operands + 'Ra': ('IntReg', 'uw', 'RA', 'IsInteger', 1), + 'Rb': ('IntReg', 'uw', 'RB', 'IsInteger', 2), + 'Rs': ('IntReg', 'uw', 'RS', 'IsInteger', 3), + 'Rt': ('IntReg', 'uw', 'RT', 'IsInteger', 4), + + # General Purpose Floating Point Reg Operands + 'Fa': ('FloatReg', 'df', 'FRA', 'IsFloating', 1), + 'Fb': ('FloatReg', 'df', 'FRB', 'IsFloating', 2), + 'Fc': ('FloatReg', 'df', 'FRC', 'IsFloating', 3), + 'Fs': ('FloatReg', 'df', 'FRS', 'IsFloating', 4), + 'Ft': ('FloatReg', 'df', 'FRT', 'IsFloating', 5), + + # Memory Operand + 'Mem': ('Mem', 'uw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 8), + + # Program counter and next + 'PC': ('PC', 'uw', None, (None, None, 'IsControl'), 9), + 'NPC': ('NPC', 'uw', None, (None, None, 'IsControl'), 9), + + # Control registers + 'CR': ('IntReg', 'uw', 'INTREG_CR', 'IsInteger', 9), + 'LR': ('IntReg', 'uw', 'INTREG_LR', 'IsInteger', 9), + 'CTR': ('IntReg', 'uw', 'INTREG_CTR', 'IsInteger', 9), + 'XER': ('IntReg', 'uw', 'INTREG_XER', 'IsInteger', 9), + + # Setting as IntReg so things are stored as an integer, not double + 'FPSCR': ('IntReg', 'uw', 'INTREG_FPSCR', 'IsFloating', 9), + + # Registers for linked loads and stores + 'Rsv': ('IntReg', 'uw', 'INTREG_RSV', 'IsInteger', 9), + 'RsvLen': ('IntReg', 'uw', 'INTREG_RSV_LEN', 'IsInteger', 9), + 'RsvAddr': ('IntReg', 'uw', 'INTREG_RSV_ADDR', 'IsInteger', 9), + + # Hack for non-full-system syscall emulation + 'R0': ('IntReg', 'uw', '0', None, 1), +}}; diff --git a/src/arch/power/isa_traits.hh b/src/arch/power/isa_traits.hh new file mode 100644 index 000000000..886c2cb0b --- /dev/null +++ b/src/arch/power/isa_traits.hh @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2003-2005 The Regents of The University of Michigan + * Copyright (c) 2007-2008 The Florida State University + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Timothy M. Jones + * Gabe Black + * Stephen Hines + */ + +#ifndef __ARCH_POWER_ISA_TRAITS_HH__ +#define __ARCH_POWER_ISA_TRAITS_HH__ + +#include "arch/power/types.hh" +#include "base/types.hh" + +namespace BigEndianGuest {}; + +class StaticInstPtr; + +namespace PowerISA +{ + +using namespace BigEndianGuest; + +StaticInstPtr decodeInst(ExtMachInst); + +// POWER DOES NOT have a delay slot +#define ISA_HAS_DELAY_SLOT 0 + +const Addr PageShift = 12; +const Addr PageBytes = ULL(1) << PageShift; +const Addr Page_Mask = ~(PageBytes - 1); +const Addr PageOffset = PageBytes - 1; + +const Addr PteShift = 3; +const Addr NPtePageShift = PageShift - PteShift; +const Addr NPtePage = ULL(1) << NPtePageShift; +const Addr PteMask = NPtePage - 1; + +const int LogVMPageSize = 12; // 4K bytes +const int VMPageSize = (1 << LogVMPageSize); + +const int MachineBytes = 4; + +// This is ori 0, 0, 0 +const ExtMachInst NoopMachInst = 0x60000000; + +} // PowerISA namespace + +#endif // __ARCH_POWER_ISA_TRAITS_HH__ diff --git a/src/arch/power/linux/linux.cc b/src/arch/power/linux/linux.cc new file mode 100644 index 000000000..113f3e48e --- /dev/null +++ b/src/arch/power/linux/linux.cc @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2003-2005 The Regents of The University of Michigan + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Timothy M. Jones + */ + +#include "arch/power/linux/linux.hh" + +#include + +// open(2) flags translation table +OpenFlagTransTable PowerLinux::openFlagTable[] = { +#ifdef _MSC_VER + { PowerLinux::TGT_O_RDONLY, _O_RDONLY }, + { PowerLinux::TGT_O_WRONLY, _O_WRONLY }, + { PowerLinux::TGT_O_RDWR, _O_RDWR }, + { PowerLinux::TGT_O_APPEND, _O_APPEND }, + { PowerLinux::TGT_O_CREAT, _O_CREAT }, + { PowerLinux::TGT_O_TRUNC, _O_TRUNC }, + { PowerLinux::TGT_O_EXCL, _O_EXCL }, +#ifdef _O_NONBLOCK + { PowerLinux::TGT_O_NONBLOCK, _O_NONBLOCK }, +#endif +#ifdef _O_NOCTTY + { PowerLinux::TGT_O_NOCTTY, _O_NOCTTY }, +#endif +#ifdef _O_SYNC + { PowerLinux::TGT_O_SYNC, _O_SYNC }, +#endif +#ifdef _O_LARGEFILE + { PowerLinux::TGT_O_LARGEFILE, _O_LARGEFILE }, +#endif +#else /* !_MSC_VER */ + { PowerLinux::TGT_O_RDONLY, O_RDONLY }, + { PowerLinux::TGT_O_WRONLY, O_WRONLY }, + { PowerLinux::TGT_O_RDWR, O_RDWR }, + { PowerLinux::TGT_O_APPEND, O_APPEND }, + { PowerLinux::TGT_O_CREAT, O_CREAT }, + { PowerLinux::TGT_O_TRUNC, O_TRUNC }, + { PowerLinux::TGT_O_EXCL, O_EXCL }, + { PowerLinux::TGT_O_NONBLOCK, O_NONBLOCK }, + { PowerLinux::TGT_O_NOCTTY, O_NOCTTY }, +#ifdef O_SYNC + { PowerLinux::TGT_O_SYNC, O_SYNC }, +#endif +#ifdef O_LARGEFILE + { PowerLinux::TGT_O_LARGEFILE, O_LARGEFILE }, +#endif +#endif /* _MSC_VER */ +}; + +const int PowerLinux::NUM_OPEN_FLAGS = + (sizeof(PowerLinux::openFlagTable)/sizeof(PowerLinux::openFlagTable[0])); + diff --git a/src/arch/power/linux/linux.hh b/src/arch/power/linux/linux.hh new file mode 100644 index 000000000..c681c8baf --- /dev/null +++ b/src/arch/power/linux/linux.hh @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2003-2005 The Regents of The University of Michigan + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Timothy M. Jones + */ + +#ifndef __ARCH_POWER_LINUX_LINUX_HH__ +#define __ARCH_POWER_LINUX_LINUX_HH__ + +#include "kern/linux/linux.hh" + +/* + * This works for a 2.6.15 kernel. + */ + +class PowerLinux : public Linux +{ + public: + + typedef int32_t time_t; + + typedef struct { + uint64_t st_dev; + uint32_t __pad1; + uint32_t st_ino; + uint32_t st_mode; + uint32_t st_nlink; + uint32_t st_uid; + uint32_t st_gid; + uint64_t st_rdev; + uint32_t __pad2; + uint32_t st_size; + uint32_t st_blksize; + uint32_t st_blocks; + uint32_t st_atimeX; + uint32_t st_atime_nsec; + uint32_t st_mtimeX; + uint32_t st_mtime_nsec; + uint32_t st_ctimeX; + uint32_t st_ctime_nsec; + uint32_t __unused4; + uint32_t __unused5; + } tgt_stat; + + typedef struct { + uint64_t st_dev; + uint64_t st_ino; + uint32_t st_mode; + uint32_t st_nlink; + uint32_t st_uid; + uint32_t st_gid; + uint64_t st_rdev; + uint64_t __pad2; + uint64_t st_size; + uint32_t st_blksize; + uint32_t __blksize_pad; + uint64_t st_blocks; + uint32_t st_atimeX; + uint32_t st_atime_nsec; + uint32_t st_mtimeX; + uint32_t st_mtime_nsec; + uint32_t st_ctimeX; + uint32_t st_ctime_nsec; + uint32_t __unused4; + uint32_t __unused5; + } tgt_stat64; + + /// For times(). + struct tms { + int32_t tms_utime; //!< user time + int32_t tms_stime; //!< system time + int32_t tms_cutime; //!< user time of children + int32_t tms_cstime; //!< system time of children + }; + + /// This table maps the target open() flags to the corresponding + /// host open() flags. + static OpenFlagTransTable openFlagTable[]; + + /// Number of entries in openFlagTable[]. + static const int NUM_OPEN_FLAGS; + + //@{ + /// open(2) flag values. + static const int TGT_O_RDONLY = 00000000; //!< O_RDONLY + static const int TGT_O_WRONLY = 00000001; //!< O_WRONLY + static const int TGT_O_RDWR = 00000002; //!< O_RDWR + static const int TGT_O_CREAT = 00000100; //!< O_CREAT + static const int TGT_O_EXCL = 00000200; //!< O_EXCL + static const int TGT_O_NOCTTY = 00000400; //!< O_NOCTTY + static const int TGT_O_TRUNC = 00001000; //!< O_TRUNC + static const int TGT_O_APPEND = 00002000; //!< O_APPEND + static const int TGT_O_NONBLOCK = 00004000; //!< O_NONBLOCK + static const int TGT_O_SYNC = 00010000; //!< O_SYNC + static const int TGT_FASYNC = 00020000; //!< FASYNC + static const int TGT_O_DIRECTORY = 00040000; //!< O_DIRECTORY + static const int TGT_O_NOFOLLOW = 00100000; //!< O_NOFOLLOW + static const int TGT_O_LARGEFILE = 00200000; //!< O_LARGEFILE + static const int TGT_O_DIRECT = 00400000; //!< O_DIRECT + static const int TGT_O_NOATIME = 01000000; //!< O_NOATIME + //@} + + /// For mmap(). + static const unsigned TGT_MAP_ANONYMOUS = 0x800; + + //@{ + /// ioctl() command codes. + /// These are for the 2.6.15 kernel. Some have changed for + /// later versions. + static const unsigned TIOCGETP_ = 0x40067408; + static const unsigned TIOCSETP_ = 0x80067409; + static const unsigned TIOCSETN_ = 0x8006740a; + static const unsigned TIOCSETC_ = 0x80067411; + static const unsigned TIOCGETC_ = 0x40067412; + static const unsigned FIONREAD_ = 0x4004667f; + static const unsigned TIOCISATTY_ = 0x2000745e; + static const unsigned TIOCGETS_ = 0x402c7413; + static const unsigned TIOCGETA_ = 0x40147417; + static const unsigned TCSETAW_ = 0x80147419; + //@} +}; + +#endif // __ARCH_POWER_LINUX_LINUX_HH__ diff --git a/src/arch/power/linux/process.cc b/src/arch/power/linux/process.cc new file mode 100644 index 000000000..b03ccfc8c --- /dev/null +++ b/src/arch/power/linux/process.cc @@ -0,0 +1,455 @@ +/* + * Copyright (c) 2003-2005 The Regents of The University of Michigan + * Copyright (c) 2007-2008 The Florida State University + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Korey Sewell + * Stephen Hines + * Timothy M. Jones + */ + +#include "arch/power/linux/linux.hh" +#include "arch/power/linux/process.hh" +#include "arch/power/isa_traits.hh" + +#include "base/trace.hh" +#include "cpu/thread_context.hh" +#include "kern/linux/linux.hh" + +#include "sim/process.hh" +#include "sim/syscall_emul.hh" +#include "sim/system.hh" + +using namespace std; +using namespace PowerISA; + +/// Target uname() handler. +static SyscallReturn +unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process, + ThreadContext *tc) +{ + TypedBufferArg name(process->getSyscallArg(tc, 0)); + + strcpy(name->sysname, "Linux"); + strcpy(name->nodename, "m5.eecs.umich.edu"); + strcpy(name->release, "2.6.16.19"); + strcpy(name->version, "#1 Mon Aug 18 11:32:15 EDT 2003"); + strcpy(name->machine, "power"); + + name.copyOut(tc->getMemPort()); + return 0; +} + +SyscallDesc PowerLinuxProcess::syscallDescs[] = { + /* 0 */ SyscallDesc("syscall", unimplementedFunc), + /* 1 */ SyscallDesc("exit", exitFunc), + /* 2 */ SyscallDesc("fork", unimplementedFunc), + /* 3 */ SyscallDesc("read", readFunc), + /* 4 */ SyscallDesc("write", writeFunc), + /* 5 */ SyscallDesc("open", openFunc), + /* 6 */ SyscallDesc("close", closeFunc), + /* 7 */ SyscallDesc("waitpid", unimplementedFunc), //??? + /* 8 */ SyscallDesc("creat", unimplementedFunc), + /* 9 */ SyscallDesc("link", unimplementedFunc), + /* 10 */ SyscallDesc("unlink", unlinkFunc), + /* 11 */ SyscallDesc("execve", unimplementedFunc), + /* 12 */ SyscallDesc("chdir", unimplementedFunc), + /* 13 */ SyscallDesc("time", timeFunc), + /* 14 */ SyscallDesc("mknod", unimplementedFunc), + /* 15 */ SyscallDesc("chmod", chmodFunc), + /* 16 */ SyscallDesc("lchown", chownFunc), + /* 17 */ SyscallDesc("break", brkFunc), //??? + /* 18 */ SyscallDesc("unused#18", unimplementedFunc), //??? + /* 19 */ SyscallDesc("lseek", lseekFunc), + /* 20 */ SyscallDesc("getpid", getpidFunc), + /* 21 */ SyscallDesc("mount", unimplementedFunc), + /* 22 */ SyscallDesc("umount", unimplementedFunc), + /* 23 */ SyscallDesc("setuid", setuidFunc), + /* 24 */ SyscallDesc("getuid", getuidFunc), + /* 25 */ SyscallDesc("stime", unimplementedFunc), + /* 26 */ SyscallDesc("ptrace", unimplementedFunc), + /* 27 */ SyscallDesc("alarm", unimplementedFunc), + /* 28 */ SyscallDesc("unused#28", unimplementedFunc), + /* 29 */ SyscallDesc("pause", unimplementedFunc), + /* 30 */ SyscallDesc("utime", unimplementedFunc), + /* 31 */ SyscallDesc("stty", unimplementedFunc), + /* 32 */ SyscallDesc("gtty", unimplementedFunc), + /* 33 */ SyscallDesc("access", unimplementedFunc), + /* 34 */ SyscallDesc("nice", unimplementedFunc), + /* 35 */ SyscallDesc("ftime", unimplementedFunc), + /* 36 */ SyscallDesc("sync", unimplementedFunc), + /* 37 */ SyscallDesc("kill", ignoreFunc), + /* 38 */ SyscallDesc("rename", renameFunc), + /* 39 */ SyscallDesc("mkdir", unimplementedFunc), + /* 40 */ SyscallDesc("rmdir", unimplementedFunc), + /* 41 */ SyscallDesc("dup", dupFunc), + /* 42 */ SyscallDesc("pipe", unimplementedFunc), + /* 43 */ SyscallDesc("times", timesFunc), + /* 44 */ SyscallDesc("prof", unimplementedFunc), + /* 45 */ SyscallDesc("brk", brkFunc), + /* 46 */ SyscallDesc("setgid", unimplementedFunc), + /* 47 */ SyscallDesc("getgid", getgidFunc), + /* 48 */ SyscallDesc("signal", ignoreFunc), + /* 49 */ SyscallDesc("geteuid", geteuidFunc), + /* 50 */ SyscallDesc("getegid", getegidFunc), + /* 51 */ SyscallDesc("acct", unimplementedFunc), + /* 52 */ SyscallDesc("umount2", unimplementedFunc), + /* 53 */ SyscallDesc("lock", unimplementedFunc), + /* 54 */ SyscallDesc("ioctl", ioctlFunc), + /* 55 */ SyscallDesc("fcntl", fcntlFunc), + /* 56 */ SyscallDesc("mpx", unimplementedFunc), + /* 57 */ SyscallDesc("setpgid", unimplementedFunc), + /* 58 */ SyscallDesc("ulimit", unimplementedFunc), + /* 59 */ SyscallDesc("unused#59", unimplementedFunc), + /* 60 */ SyscallDesc("umask", umaskFunc), + /* 61 */ SyscallDesc("chroot", unimplementedFunc), + /* 62 */ SyscallDesc("ustat", unimplementedFunc), + /* 63 */ SyscallDesc("dup2", unimplementedFunc), + /* 64 */ SyscallDesc("getppid", getpagesizeFunc), + /* 65 */ SyscallDesc("getpgrp", unimplementedFunc), + /* 66 */ SyscallDesc("setsid", unimplementedFunc), + /* 67 */ SyscallDesc("sigaction",unimplementedFunc), + /* 68 */ SyscallDesc("sgetmask", unimplementedFunc), + /* 69 */ SyscallDesc("ssetmask", unimplementedFunc), + /* 70 */ SyscallDesc("setreuid", unimplementedFunc), + /* 71 */ SyscallDesc("setregid", unimplementedFunc), + /* 72 */ SyscallDesc("sigsuspend", unimplementedFunc), + /* 73 */ SyscallDesc("sigpending", unimplementedFunc), + /* 74 */ SyscallDesc("sethostname", ignoreFunc), + /* 75 */ SyscallDesc("setrlimit", ignoreFunc), + /* 76 */ SyscallDesc("getrlimit", unimplementedFunc), + /* 77 */ SyscallDesc("getrusage", ignoreFunc), + /* 78 */ SyscallDesc("gettimeofday", unimplementedFunc), + /* 79 */ SyscallDesc("settimeofday", unimplementedFunc), + /* 80 */ SyscallDesc("getgroups", unimplementedFunc), + /* 81 */ SyscallDesc("setgroups", unimplementedFunc), + /* 82 */ SyscallDesc("reserved#82", unimplementedFunc), + /* 83 */ SyscallDesc("symlink", unimplementedFunc), + /* 84 */ SyscallDesc("unused#84", unimplementedFunc), + /* 85 */ SyscallDesc("readlink", unimplementedFunc), + /* 86 */ SyscallDesc("uselib", unimplementedFunc), + /* 87 */ SyscallDesc("swapon", gethostnameFunc), + /* 88 */ SyscallDesc("reboot", unimplementedFunc), + /* 89 */ SyscallDesc("readdir", unimplementedFunc), + /* 90 */ SyscallDesc("mmap", mmapFunc), + /* 91 */ SyscallDesc("munmap",munmapFunc), + /* 92 */ SyscallDesc("truncate", truncateFunc), + /* 93 */ SyscallDesc("ftruncate", ftruncateFunc), + /* 94 */ SyscallDesc("fchmod", unimplementedFunc), + /* 95 */ SyscallDesc("fchown", unimplementedFunc), + /* 96 */ SyscallDesc("getpriority", unimplementedFunc), + /* 97 */ SyscallDesc("setpriority", unimplementedFunc), + /* 98 */ SyscallDesc("profil", unimplementedFunc), + /* 99 */ SyscallDesc("statfs", unimplementedFunc), + /* 100 */ SyscallDesc("fstatfs", unimplementedFunc), + /* 101 */ SyscallDesc("ioperm", unimplementedFunc), + /* 102 */ SyscallDesc("socketcall", unimplementedFunc), + /* 103 */ SyscallDesc("syslog", unimplementedFunc), + /* 104 */ SyscallDesc("setitimer", unimplementedFunc), + /* 105 */ SyscallDesc("getitimer", unimplementedFunc), + /* 106 */ SyscallDesc("stat", statFunc), + /* 107 */ SyscallDesc("lstat", unimplementedFunc), + /* 108 */ SyscallDesc("fstat", fstatFunc), + /* 109 */ SyscallDesc("unused#109", unimplementedFunc), + /* 110 */ SyscallDesc("iopl", unimplementedFunc), + /* 111 */ SyscallDesc("vhangup", unimplementedFunc), + /* 112 */ SyscallDesc("idle", ignoreFunc), + /* 113 */ SyscallDesc("vm86", unimplementedFunc), + /* 114 */ SyscallDesc("wait4", unimplementedFunc), + /* 115 */ SyscallDesc("swapoff", unimplementedFunc), + /* 116 */ SyscallDesc("sysinfo", unimplementedFunc), + /* 117 */ SyscallDesc("ipc", unimplementedFunc), + /* 118 */ SyscallDesc("fsync", unimplementedFunc), + /* 119 */ SyscallDesc("sigreturn", unimplementedFunc), + /* 120 */ SyscallDesc("clone", unimplementedFunc), + /* 121 */ SyscallDesc("setdomainname", unimplementedFunc), + /* 122 */ SyscallDesc("uname", unameFunc), + /* 123 */ SyscallDesc("modify_ldt", unimplementedFunc), + /* 124 */ SyscallDesc("adjtimex", unimplementedFunc), + /* 125 */ SyscallDesc("mprotect", ignoreFunc), + /* 126 */ SyscallDesc("sigprocmask", unimplementedFunc), + /* 127 */ SyscallDesc("create_module", unimplementedFunc), + /* 128 */ SyscallDesc("init_module", unimplementedFunc), + /* 129 */ SyscallDesc("delete_module", unimplementedFunc), + /* 130 */ SyscallDesc("get_kernel_syms", unimplementedFunc), + /* 131 */ SyscallDesc("quotactl", unimplementedFunc), + /* 132 */ SyscallDesc("getpgid", unimplementedFunc), + /* 133 */ SyscallDesc("fchdir", unimplementedFunc), + /* 134 */ SyscallDesc("bdflush", unimplementedFunc), + /* 135 */ SyscallDesc("sysfs", unimplementedFunc), + /* 136 */ SyscallDesc("personality", unimplementedFunc), + /* 137 */ SyscallDesc("afs_syscall", unimplementedFunc), + /* 138 */ SyscallDesc("setfsuid", unimplementedFunc), + /* 139 */ SyscallDesc("setfsgid", unimplementedFunc), + /* 140 */ SyscallDesc("llseek", _llseekFunc), + /* 141 */ SyscallDesc("getdents", unimplementedFunc), + /* 142 */ SyscallDesc("newselect", unimplementedFunc), + /* 143 */ SyscallDesc("flock", unimplementedFunc), + /* 144 */ SyscallDesc("msync", unimplementedFunc), + /* 145 */ SyscallDesc("readv", unimplementedFunc), + /* 146 */ SyscallDesc("writev", writevFunc), + /* 147 */ SyscallDesc("getsid", unimplementedFunc), + /* 148 */ SyscallDesc("fdatasync", unimplementedFunc), + /* 149 */ SyscallDesc("sysctl", unimplementedFunc), + /* 150 */ SyscallDesc("mlock", unimplementedFunc), + /* 151 */ SyscallDesc("munlock", unimplementedFunc), + /* 152 */ SyscallDesc("mlockall", unimplementedFunc), + /* 153 */ SyscallDesc("munlockall", unimplementedFunc), + /* 154 */ SyscallDesc("sched_setparam", unimplementedFunc), + /* 155 */ SyscallDesc("sched_getparam", unimplementedFunc), + /* 156 */ SyscallDesc("sched_setscheduler", unimplementedFunc), + /* 157 */ SyscallDesc("sched_getscheduler", unimplementedFunc), + /* 158 */ SyscallDesc("sched_yield", unimplementedFunc), + /* 159 */ SyscallDesc("sched_get_priority_max", unimplementedFunc), + /* 160 */ SyscallDesc("sched_get_priority_min", unimplementedFunc), + /* 161 */ SyscallDesc("sched_rr_get_interval", unimplementedFunc), + /* 162 */ SyscallDesc("nanosleep", unimplementedFunc), + /* 163 */ SyscallDesc("mremap", unimplementedFunc), + /* 164 */ SyscallDesc("setresuid", unimplementedFunc), + /* 165 */ SyscallDesc("getresuid", unimplementedFunc), + /* 166 */ SyscallDesc("vm862", unimplementedFunc), + /* 167 */ SyscallDesc("query_module", unimplementedFunc), + /* 168 */ SyscallDesc("poll", unimplementedFunc), + /* 169 */ SyscallDesc("nfsservctl", unimplementedFunc), + /* 170 */ SyscallDesc("setresgid", unimplementedFunc), + /* 171 */ SyscallDesc("getresgid", unimplementedFunc), + /* 172 */ SyscallDesc("prctl", unimplementedFunc), + /* 173 */ SyscallDesc("rt_sigaction", ignoreFunc), + /* 174 */ SyscallDesc("rt_sigprocmask", unimplementedFunc), + /* 175 */ SyscallDesc("unknown#175", unimplementedFunc), + /* 176 */ SyscallDesc("rt_sigpending", unimplementedFunc), + /* 177 */ SyscallDesc("rt_sigtimedwait", unimplementedFunc), + /* 178 */ SyscallDesc("rt_sigqueueinfo", ignoreFunc), + /* 179 */ SyscallDesc("rt_sigsuspend", unimplementedFunc), + /* 180 */ SyscallDesc("pread64", unimplementedFunc), + /* 181 */ SyscallDesc("pwrite64", unimplementedFunc), + /* 182 */ SyscallDesc("chown", unimplementedFunc), + /* 183 */ SyscallDesc("getcwd", unimplementedFunc), + /* 184 */ SyscallDesc("capget", unimplementedFunc), + /* 185 */ SyscallDesc("capset", unimplementedFunc), + /* 186 */ SyscallDesc("sigaltstack", unimplementedFunc), + /* 187 */ SyscallDesc("sendfile", unimplementedFunc), + /* 188 */ SyscallDesc("getpmsg", unimplementedFunc), + /* 189 */ SyscallDesc("putpmsg", unimplementedFunc), + /* 190 */ SyscallDesc("ugetrlimit", ignoreFunc), + /* 191 */ SyscallDesc("getrlimit", unimplementedFunc), + /* 192 */ SyscallDesc("mmap2", mmapFunc), + /* 193 */ SyscallDesc("truncate64", unimplementedFunc), + /* 194 */ SyscallDesc("ftruncate64", ftruncate64Func), + /* 195 */ SyscallDesc("stat64", stat64Func), + /* 196 */ SyscallDesc("lstat64", lstat64Func), + /* 197 */ SyscallDesc("fstat64", fstat64Func), + /* 198 */ SyscallDesc("lchown", unimplementedFunc), + /* 199 */ SyscallDesc("getuid", getuidFunc), + /* 200 */ SyscallDesc("getgid", getgidFunc), + /* 201 */ SyscallDesc("geteuid", geteuidFunc), + /* 202 */ SyscallDesc("getegid", getegidFunc), + /* 203 */ SyscallDesc("setreuid", unimplementedFunc), + /* 204 */ SyscallDesc("fcntl64", fcntl64Func), + /* 205 */ SyscallDesc("getgroups", unimplementedFunc), + /* 206 */ SyscallDesc("setgroups", unimplementedFunc), + /* 207 */ SyscallDesc("fchown", unimplementedFunc), + /* 208 */ SyscallDesc("setresuid", unimplementedFunc), + /* 209 */ SyscallDesc("getresuid", unimplementedFunc), + /* 210 */ SyscallDesc("setresgid", unimplementedFunc), + /* 211 */ SyscallDesc("getresgid", unimplementedFunc), + /* 212 */ SyscallDesc("chown", unimplementedFunc), + /* 213 */ SyscallDesc("setuid", unimplementedFunc), + /* 214 */ SyscallDesc("setgid", unimplementedFunc), + /* 215 */ SyscallDesc("setfsuid", unimplementedFunc), + /* 216 */ SyscallDesc("setfsgid", unimplementedFunc), + /* 217 */ SyscallDesc("getdents64", unimplementedFunc), + /* 218 */ SyscallDesc("pivot_root", unimplementedFunc), + /* 219 */ SyscallDesc("mincore", unimplementedFunc), + /* 220 */ SyscallDesc("madvise", unimplementedFunc), + /* 221 */ SyscallDesc("unknown#221", unimplementedFunc), + /* 222 */ SyscallDesc("tux", unimplementedFunc), + /* 223 */ SyscallDesc("unknown#223", unimplementedFunc), + /* 224 */ SyscallDesc("gettid", unimplementedFunc), + /* 225 */ SyscallDesc("readahead", unimplementedFunc), + /* 226 */ SyscallDesc("setxattr", unimplementedFunc), + /* 227 */ SyscallDesc("lsetxattr", unimplementedFunc), + /* 228 */ SyscallDesc("fsetxattr", unimplementedFunc), + /* 229 */ SyscallDesc("getxattr", unimplementedFunc), + /* 230 */ SyscallDesc("lgetxattr", unimplementedFunc), + /* 231 */ SyscallDesc("fgetxattr", unimplementedFunc), + /* 232 */ SyscallDesc("listxattr", unimplementedFunc), + /* 233 */ SyscallDesc("llistxattr", unimplementedFunc), + /* 234 */ SyscallDesc("exit_group", exitGroupFunc), + /* 235 */ SyscallDesc("removexattr", unimplementedFunc), + /* 236 */ SyscallDesc("lremovexattr", unimplementedFunc), + /* 237 */ SyscallDesc("fremovexattr", unimplementedFunc), + /* 238 */ SyscallDesc("tkill", unimplementedFunc), + /* 239 */ SyscallDesc("sendfile64", unimplementedFunc), + /* 240 */ SyscallDesc("futex", unimplementedFunc), + /* 241 */ SyscallDesc("sched_setaffinity", unimplementedFunc), + /* 242 */ SyscallDesc("sched_getaffinity", unimplementedFunc), + /* 243 */ SyscallDesc("io_setup", unimplementedFunc), + /* 244 */ SyscallDesc("io_destory", unimplementedFunc), + /* 245 */ SyscallDesc("io_getevents", unimplementedFunc), + /* 246 */ SyscallDesc("io_submit", unimplementedFunc), + /* 247 */ SyscallDesc("io_cancel", unimplementedFunc), + /* 248 */ SyscallDesc("unknown#248", unimplementedFunc), + /* 249 */ SyscallDesc("lookup_dcookie", unimplementedFunc), + /* 250 */ SyscallDesc("epoll_create", unimplementedFunc), + /* 251 */ SyscallDesc("epoll_ctl", unimplementedFunc), + /* 252 */ SyscallDesc("epoll_wait", unimplementedFunc), + /* 253 */ SyscallDesc("remap_file_pages", unimplementedFunc), + /* 254 */ SyscallDesc("set_thread_area", unimplementedFunc), + /* 255 */ SyscallDesc("get_thread_area", unimplementedFunc), + /* 256 */ SyscallDesc("set_tid_address", unimplementedFunc), + /* 257 */ SyscallDesc("timer_create", unimplementedFunc), + /* 258 */ SyscallDesc("timer_settime", unimplementedFunc), + /* 259 */ SyscallDesc("timer_gettime", unimplementedFunc), + /* 260 */ SyscallDesc("timer_getoverrun", unimplementedFunc), + /* 261 */ SyscallDesc("timer_delete", unimplementedFunc), + /* 262 */ SyscallDesc("clock_settime", unimplementedFunc), + /* 263 */ SyscallDesc("clock_gettime", unimplementedFunc), + /* 264 */ SyscallDesc("clock_getres", unimplementedFunc), + /* 265 */ SyscallDesc("clock_nanosleep", unimplementedFunc), + /* 266 */ SyscallDesc("statfs64", unimplementedFunc), + /* 267 */ SyscallDesc("fstatfs64", unimplementedFunc), + /* 268 */ SyscallDesc("tgkill", unimplementedFunc), + /* 269 */ SyscallDesc("utimes", unimplementedFunc), + /* 270 */ SyscallDesc("arm_fadvise64_64", unimplementedFunc), + /* 271 */ SyscallDesc("pciconfig_iobase", unimplementedFunc), + /* 272 */ SyscallDesc("pciconfig_read", unimplementedFunc), + /* 273 */ SyscallDesc("pciconfig_write", unimplementedFunc), + /* 274 */ SyscallDesc("mq_open", unimplementedFunc), + /* 275 */ SyscallDesc("mq_unlink", unimplementedFunc), + /* 276 */ SyscallDesc("mq_timedsend", unimplementedFunc), + /* 277 */ SyscallDesc("mq_timedreceive", unimplementedFunc), + /* 278 */ SyscallDesc("mq_notify", unimplementedFunc), + /* 279 */ SyscallDesc("mq_getsetattr", unimplementedFunc), + /* 280 */ SyscallDesc("waitid", unimplementedFunc), + /* 281 */ SyscallDesc("socket", unimplementedFunc), + /* 282 */ SyscallDesc("bind", unimplementedFunc), + /* 283 */ SyscallDesc("connect", unimplementedFunc), + /* 284 */ SyscallDesc("listen", unimplementedFunc), + /* 285 */ SyscallDesc("accept", unimplementedFunc), + /* 286 */ SyscallDesc("getsockname", unimplementedFunc), + /* 287 */ SyscallDesc("getpeername", unimplementedFunc), + /* 288 */ SyscallDesc("socketpair", unimplementedFunc), + /* 289 */ SyscallDesc("send", unimplementedFunc), + /* 290 */ SyscallDesc("sendto", unimplementedFunc), + /* 291 */ SyscallDesc("recv", unimplementedFunc), + /* 292 */ SyscallDesc("recvfrom", unimplementedFunc), + /* 293 */ SyscallDesc("shutdown", unimplementedFunc), + /* 294 */ SyscallDesc("setsockopt", unimplementedFunc), + /* 295 */ SyscallDesc("getsockopt", unimplementedFunc), + /* 296 */ SyscallDesc("sendmsg", unimplementedFunc), + /* 297 */ SyscallDesc("rcvmsg", unimplementedFunc), + /* 298 */ SyscallDesc("semop", unimplementedFunc), + /* 299 */ SyscallDesc("semget", unimplementedFunc), + /* 300 */ SyscallDesc("semctl", unimplementedFunc), + /* 301 */ SyscallDesc("msgsend", unimplementedFunc), + /* 302 */ SyscallDesc("msgrcv", unimplementedFunc), + /* 303 */ SyscallDesc("msgget", unimplementedFunc), + /* 304 */ SyscallDesc("msgctl", unimplementedFunc), + /* 305 */ SyscallDesc("shmat", unimplementedFunc), + /* 306 */ SyscallDesc("shmdt", unimplementedFunc), + /* 307 */ SyscallDesc("shmget", unimplementedFunc), + /* 308 */ SyscallDesc("shmctl", unimplementedFunc), + /* 309 */ SyscallDesc("add_key", unimplementedFunc), + /* 310 */ SyscallDesc("request_key", unimplementedFunc), + /* 311 */ SyscallDesc("keyctl", unimplementedFunc), + /* 312 */ SyscallDesc("semtimedop", unimplementedFunc), + /* 313 */ SyscallDesc("vserver", unimplementedFunc), + /* 314 */ SyscallDesc("ioprio_set", unimplementedFunc), + /* 315 */ SyscallDesc("ioprio_get", unimplementedFunc), + /* 316 */ SyscallDesc("inotify_init", unimplementedFunc), + /* 317 */ SyscallDesc("inotify_add_watch", unimplementedFunc), + /* 318 */ SyscallDesc("inotify_rm_watch", unimplementedFunc), + /* 319 */ SyscallDesc("mbind", unimplementedFunc), + /* 320 */ SyscallDesc("get_mempolicy", unimplementedFunc), + /* 321 */ SyscallDesc("set_mempolicy", unimplementedFunc), + /* 322 */ SyscallDesc("openat", unimplementedFunc), + /* 323 */ SyscallDesc("mkdirat", unimplementedFunc), + /* 324 */ SyscallDesc("mknodat", unimplementedFunc), + /* 325 */ SyscallDesc("fchownat", unimplementedFunc), + /* 326 */ SyscallDesc("futimesat", unimplementedFunc), + /* 327 */ SyscallDesc("fstatat64", unimplementedFunc), + /* 328 */ SyscallDesc("unlinkat", unimplementedFunc), + /* 329 */ SyscallDesc("renameat", unimplementedFunc), + /* 330 */ SyscallDesc("linkat", unimplementedFunc), + /* 331 */ SyscallDesc("symlinkat", unimplementedFunc), + /* 332 */ SyscallDesc("readlinkat", unimplementedFunc), + /* 333 */ SyscallDesc("fchmodat", unimplementedFunc), + /* 334 */ SyscallDesc("faccessat", unimplementedFunc), + /* 335 */ SyscallDesc("pselect6", unimplementedFunc), + /* 336 */ SyscallDesc("ppoll", unimplementedFunc), + /* 337 */ SyscallDesc("unshare", unimplementedFunc), + /* 338 */ SyscallDesc("set_robust_list", unimplementedFunc), + /* 339 */ SyscallDesc("get_robust_list", unimplementedFunc), + /* 340 */ SyscallDesc("splice", unimplementedFunc), + /* 341 */ SyscallDesc("arm_sync_file_range", unimplementedFunc), + /* 342 */ SyscallDesc("tee", unimplementedFunc), + /* 343 */ SyscallDesc("vmsplice", unimplementedFunc), + /* 344 */ SyscallDesc("move_pages", unimplementedFunc), + /* 345 */ SyscallDesc("getcpu", unimplementedFunc), + /* 346 */ SyscallDesc("epoll_pwait", unimplementedFunc), +}; + +PowerLinuxProcess::PowerLinuxProcess(LiveProcessParams * params, + ObjectFile *objFile) + : PowerLiveProcess(params, objFile), + Num_Syscall_Descs(sizeof(syscallDescs) / sizeof(SyscallDesc)) +{ +} + +SyscallDesc* +PowerLinuxProcess::getDesc(int callnum) +{ + if (callnum < 0 || callnum > Num_Syscall_Descs) + return NULL; + + return &syscallDescs[callnum]; +} + +void +PowerLinuxProcess::startup() +{ + PowerLiveProcess::startup(); +} + +PowerISA::IntReg +PowerLinuxProcess::getSyscallArg(ThreadContext *tc, int i) +{ + // Linux apparently allows more parameter than the ABI says it should. + // This limit may need to be increased even further. + assert(i < 6); + return tc->readIntReg(ArgumentReg0 + i); +} + +void +PowerLinuxProcess::setSyscallArg(ThreadContext *tc, int i, PowerISA::IntReg val) +{ + // Linux apparently allows more parameter than the ABI says it should. + // This limit may need to be increased even further. + assert(i < 6); + tc->setIntReg(ArgumentReg0 + i, val); +} diff --git a/src/arch/power/linux/process.hh b/src/arch/power/linux/process.hh new file mode 100644 index 000000000..78b0eef7f --- /dev/null +++ b/src/arch/power/linux/process.hh @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2007-2008 The Florida State University + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Stephen Hines + * Timothy M. Jones + */ + +#ifndef __POWER_LINUX_PROCESS_HH__ +#define __POWER_LINUX_PROCESS_HH__ + +#include "arch/power/process.hh" + + +/// A process with emulated PPC/Linux syscalls. +class PowerLinuxProcess : public PowerLiveProcess +{ + public: + PowerLinuxProcess(LiveProcessParams * params, ObjectFile *objFile); + + virtual SyscallDesc* getDesc(int callnum); + + void startup(); + + PowerISA::IntReg getSyscallArg(ThreadContext *tc, int i); + void setSyscallArg(ThreadContext *tc, int i, PowerISA::IntReg val); + + /// Array of syscall descriptors, indexed by call number. + static SyscallDesc syscallDescs[]; + + const int Num_Syscall_Descs; +}; + +#endif // __POWER_LINUX_PROCESS_HH__ diff --git a/src/arch/power/locked_mem.hh b/src/arch/power/locked_mem.hh new file mode 100644 index 000000000..56ab1d4a0 --- /dev/null +++ b/src/arch/power/locked_mem.hh @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2006 The Regents of The University of Michigan + * Copyright (c) 2007-2008 The Florida State University + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Steve Reinhardt + * Stephen Hines + * Timothy M. Jones + */ + +#ifndef __ARCH_POWER_LOCKED_MEM_HH__ +#define __ARCH_POWER_LOCKED_MEM_HH__ + +/** + * @file + * + * ISA-specific helper functions for locked memory accesses. + */ + +#include "mem/request.hh" + +namespace PowerISA +{ + +template +inline void +handleLockedRead(XC *xc, Request *req) +{ +} + +template +inline bool +handleLockedWrite(XC *xc, Request *req) +{ + return true; +} + +} // PowerISA namespace + +#endif // __ARCH_POWER_LOCKED_MEM_HH__ diff --git a/src/arch/power/microcode_rom.hh b/src/arch/power/microcode_rom.hh new file mode 100644 index 000000000..e35db5112 --- /dev/null +++ b/src/arch/power/microcode_rom.hh @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2008 The Regents of The University of Michigan + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Gabe Black + * Timothy M. Jones + */ + +#ifndef __ARCH_POWER_MICROCODE_ROM_HH__ +#define __ARCH_POWER_MICROCODE_ROM_HH__ + +#include "sim/microcode_rom.hh" + +namespace PowerISA +{ + +using ::MicrocodeRom; + +} // PowerISA namespace + +#endif // __ARCH_POWER_MICROCODE_ROM_HH__ diff --git a/src/arch/power/miscregs.hh b/src/arch/power/miscregs.hh new file mode 100644 index 000000000..cd9815b2a --- /dev/null +++ b/src/arch/power/miscregs.hh @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Timothy M. Jones + */ + +#ifndef __ARCH_POWER_MISCREGS_HH__ +#define __ARCH_POWER_MISCREGS_HH__ + +#include "base/bitunion.hh" + +namespace PowerISA +{ + +enum MiscRegIndex { + NUM_MISCREGS = 0 +}; + +const char * const miscRegName[NUM_MISCREGS] = { +}; + +BitUnion32(Cr) + Bitfield<31,28> cr0; + Bitfield<27,24> cr1; +EndBitUnion(Cr) + +BitUnion32(Xer) + Bitfield<31> so; + Bitfield<30> ov; + Bitfield<29> ca; +EndBitUnion(Xer) + +BitUnion32(Fpscr) + Bitfield<31> fx; + Bitfield<30> fex; + Bitfield<29> vx; + Bitfield<28> ox; + Bitfield<27> ux; + Bitfield<26> zx; + Bitfield<25> xx; + Bitfield<24> vxsnan; + Bitfield<23> vxisi; + Bitfield<22> vxidi; + Bitfield<21> vxzdz; + Bitfield<20> vximz; + Bitfield<19> vxvc; + Bitfield<18> fr; + Bitfield<17> fi; + SubBitUnion(fprf, 16, 12) + Bitfield<16> c; + SubBitUnion(fpcc, 15, 12) + Bitfield<15> fl; + Bitfield<14> fg; + Bitfield<13> fe; + Bitfield<12> fu; + EndSubBitUnion(fpcc) + EndSubBitUnion(fprf) + Bitfield<10> vxsqrt; + Bitfield<9> vxcvi; + Bitfield<8> ve; + Bitfield<7> oe; + Bitfield<6> ue; + Bitfield<5> ze; + Bitfield<4> xe; + Bitfield<3> ni; + Bitfield<2,1> rn; +EndBitUnion(Fpscr) + +}; // PowerISA namespace + +#endif // __ARCH_POWER_MISCREGS_HH__ diff --git a/src/arch/power/mmaped_ipr.hh b/src/arch/power/mmaped_ipr.hh new file mode 100644 index 000000000..bd1ea10b3 --- /dev/null +++ b/src/arch/power/mmaped_ipr.hh @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2006 The Regents of The University of Michigan + * Copyright (c) 2007-2008 The Florida State University + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Ali Saidi + * Stephen Hines + * Timothy M. Jones + */ + +#ifndef __ARCH_POWER_MMAPED_IPR_HH__ +#define __ARCH_POWER_MMAPED_IPR_HH__ + +/** + * @file + * + * ISA-specific helper functions for memory mapped IPR accesses. + */ + +#include "base/misc.hh" +#include "mem/packet.hh" + +class ThreadContext; + +namespace PowerISA +{ + +inline Tick +handleIprRead(ThreadContext *xc, Packet *pkt) +{ + panic("No implementation for handleIprRead in POWER\n"); +} + +inline Tick +handleIprWrite(ThreadContext *xc, Packet *pkt) +{ + panic("No implementation for handleIprWrite in POWER\n"); +} + +} // PowerISA namespace + +#endif // __ARCH_POWER_MMAPED_IPR_HH__ diff --git a/src/arch/power/pagetable.cc b/src/arch/power/pagetable.cc new file mode 100644 index 000000000..862404578 --- /dev/null +++ b/src/arch/power/pagetable.cc @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2002-2005 The Regents of The University of Michigan + * Copyright (c) 2007 MIPS Technologies, Inc. + * Copyright (c) 2007-2008 The Florida State University + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Nathan Binkert + * Steve Reinhardt + * Jaidev Patwardhan + * Stephen Hines + * Timothy M. Jones + */ + +#include "arch/power/pagetable.hh" +#include "sim/serialize.hh" + +namespace PowerISA +{ + +void +PTE::serialize(std::ostream &os) +{ + SERIALIZE_SCALAR(Mask); + SERIALIZE_SCALAR(VPN); + SERIALIZE_SCALAR(asid); + SERIALIZE_SCALAR(G); + SERIALIZE_SCALAR(PFN0); + SERIALIZE_SCALAR(D0); + SERIALIZE_SCALAR(V0); + SERIALIZE_SCALAR(C0); + SERIALIZE_SCALAR(PFN1); + SERIALIZE_SCALAR(D1); + SERIALIZE_SCALAR(V1); + SERIALIZE_SCALAR(C1); + SERIALIZE_SCALAR(AddrShiftAmount); + SERIALIZE_SCALAR(OffsetMask); +} + +void +PTE::unserialize(Checkpoint *cp, const std::string §ion) +{ + UNSERIALIZE_SCALAR(Mask); + UNSERIALIZE_SCALAR(VPN); + UNSERIALIZE_SCALAR(asid); + UNSERIALIZE_SCALAR(G); + UNSERIALIZE_SCALAR(PFN0); + UNSERIALIZE_SCALAR(D0); + UNSERIALIZE_SCALAR(V0); + UNSERIALIZE_SCALAR(C0); + UNSERIALIZE_SCALAR(PFN1); + UNSERIALIZE_SCALAR(D1); + UNSERIALIZE_SCALAR(V1); + UNSERIALIZE_SCALAR(C1); + UNSERIALIZE_SCALAR(AddrShiftAmount); + UNSERIALIZE_SCALAR(OffsetMask); +} + +} // PowerISA namespace diff --git a/src/arch/power/pagetable.hh b/src/arch/power/pagetable.hh new file mode 100644 index 000000000..bd2b9d397 --- /dev/null +++ b/src/arch/power/pagetable.hh @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2002-2005 The Regents of The University of Michigan + * Copyright (c) 2007 MIPS Technologies, Inc. + * Copyright (c) 2007-2008 The Florida State University + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Nathan Binkert + * Steve Reinhardt + * Jaidev Patwardhan + * Stephen Hines + * Timothy M. Jones + */ + +#ifndef __ARCH_POWER_PAGETABLE_H__ +#define __ARCH_POWER_PAGETABLE_H__ + +#include "arch/power/isa_traits.hh" +#include "arch/power/utility.hh" +#include "arch/power/vtophys.hh" +#include "config/full_system.hh" + +namespace PowerISA { + +struct VAddr +{ + static const int ImplBits = 43; + static const Addr ImplMask = (ULL(1) << ImplBits) - 1; + static const Addr UnImplMask = ~ImplMask; + + Addr addr; + + VAddr(Addr a) + : addr(a) + {} + + operator Addr() const + { + return addr; + } + + const VAddr + &operator=(Addr a) + { + addr = a; + return *this; + } + + Addr + vpn() const + { + return (addr & ImplMask) >> PageShift; + } + + Addr + page() const + { + return addr & Page_Mask; + } + + Addr + offset() const + { + return addr & PageOffset; + } + + Addr + level3() const + { + return PowerISA::PteAddr(addr >> PageShift); + } + + Addr + level2() const + { + return PowerISA::PteAddr(addr >> (NPtePageShift + PageShift)); + } + + Addr + level1() const + { + return PowerISA::PteAddr(addr >> (2 * NPtePageShift + PageShift)); + } +}; + +// ITB/DTB page table entry +struct PTE +{ + // What parts of the VAddr (from bits 28..11) should be used in + // translation (includes Mask and MaskX from PageMask) + Addr Mask; + + // Virtual Page Number (/2) (Includes VPN2 + VPN2X .. bits 31..11 + // from EntryHi) + Addr VPN; + + // Address Space ID (8 bits) // Lower 8 bits of EntryHi + uint8_t asid; + + // Global Bit - Obtained by an *AND* of EntryLo0 and EntryLo1 G bit + bool G; + + /* Contents of Entry Lo0 */ + Addr PFN0; // Physical Frame Number - Even + bool D0; // Even entry Dirty Bit + bool V0; // Even entry Valid Bit + uint8_t C0; // Cache Coherency Bits - Even + + /* Contents of Entry Lo1 */ + Addr PFN1; // Physical Frame Number - Odd + bool D1; // Odd entry Dirty Bit + bool V1; // Odd entry Valid Bit + uint8_t C1; // Cache Coherency Bits (3 bits) + + // The next few variables are put in as optimizations to reduce TLB + // lookup overheads. For a given Mask, what is the address shift amount + // and what is the OffsetMask + int AddrShiftAmount; + int OffsetMask; + + bool + Valid() + { + return (V0 | V1); + }; + + void serialize(std::ostream &os); + + void unserialize(Checkpoint *cp, const std::string §ion); +}; + +} // PowerISA namespace + +#endif // __ARCH_POWER_PAGETABLE_H__ + diff --git a/src/arch/power/predecoder.hh b/src/arch/power/predecoder.hh new file mode 100644 index 000000000..1f3ac41cb --- /dev/null +++ b/src/arch/power/predecoder.hh @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2006 The Regents of The University of Michigan + * Copyright (c) 2007-2008 The Florida State University + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Gabe Black + * Stephen Hines + * Timothy M. Jones + */ + +#ifndef __ARCH_ARM_PREDECODER_HH__ +#define __ARCH_ARM_PREDECODER_HH__ + +#include "arch/power/types.hh" +#include "base/misc.hh" +#include "base/types.hh" + +class ThreadContext; + +namespace PowerISA +{ + +class Predecoder +{ + protected: + ThreadContext * tc; + + // The extended machine instruction being generated + ExtMachInst emi; + + public: + Predecoder(ThreadContext * _tc) + : tc(_tc) + { + } + + ThreadContext * + getTC() + { + return tc; + } + + void + setTC(ThreadContext * _tc) + { + tc = _tc; + } + + void + process() + { + } + + void + reset() + { + } + + // Use this to give data to the predecoder. This should be used + // when there is control flow. + void + moreBytes(Addr pc, Addr fetchPC, MachInst inst) + { + emi = inst; + } + + // Use this to give data to the predecoder. This should be used + // when instructions are executed in order. + void + moreBytes(MachInst machInst) + { + moreBytes(0, 0, machInst); + } + + bool + needMoreBytes() + { + return true; + } + + bool + extMachInstReady() + { + return true; + } + + // This returns a constant reference to the ExtMachInst to avoid a copy + const ExtMachInst & + getExtMachInst() + { + return emi; + } +}; + +} // PowerISA namespace + +#endif // __ARCH_POWER_PREDECODER_HH__ diff --git a/src/arch/power/process.cc b/src/arch/power/process.cc new file mode 100644 index 000000000..8828a1a93 --- /dev/null +++ b/src/arch/power/process.cc @@ -0,0 +1,288 @@ +/* + * Copyright (c) 2007-2008 The Florida State University + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Stephen Hines + * Timothy M. Jones + */ + +#include "arch/power/isa_traits.hh" +#include "arch/power/process.hh" +#include "arch/power/types.hh" +#include "base/loader/elf_object.hh" +#include "base/loader/object_file.hh" +#include "base/misc.hh" +#include "cpu/thread_context.hh" +#include "mem/page_table.hh" +#include "mem/translating_port.hh" +#include "sim/process_impl.hh" +#include "sim/system.hh" + +using namespace std; +using namespace PowerISA; + +PowerLiveProcess::PowerLiveProcess(LiveProcessParams *params, + ObjectFile *objFile) + : LiveProcess(params, objFile) +{ + stack_base = 0xbf000000L; + + // Set pointer for next thread stack. Reserve 8M for main stack. + next_thread_stack_base = stack_base - (8 * 1024 * 1024); + + // Set up break point (Top of Heap) + brk_point = objFile->dataBase() + objFile->dataSize() + objFile->bssSize(); + brk_point = roundUp(brk_point, VMPageSize); + + // Set up region for mmaps. For now, start at bottom of kuseg space. + mmap_start = mmap_end = 0x70000000L; +} + +void +PowerLiveProcess::startup() +{ + argsInit(MachineBytes, VMPageSize); +} + +void +PowerLiveProcess::argsInit(int intSize, int pageSize) +{ + typedef AuxVector auxv_t; + std::vector auxv; + + string filename; + if (argv.size() < 1) + filename = ""; + else + filename = argv[0]; + + //We want 16 byte alignment + uint64_t align = 16; + + // Overloaded argsInit so that we can fine-tune for POWER architecture + Process::startup(); + + // load object file into target memory + objFile->loadSections(initVirtMem); + + //Setup the auxilliary vectors. These will already have endian conversion. + //Auxilliary vectors are loaded only for elf formatted executables. + ElfObject * elfObject = dynamic_cast(objFile); + if (elfObject) { + uint32_t features = 0; + + //Bits which describe the system hardware capabilities + //XXX Figure out what these should be + auxv.push_back(auxv_t(M5_AT_HWCAP, features)); + //The system page size + auxv.push_back(auxv_t(M5_AT_PAGESZ, PowerISA::VMPageSize)); + //Frequency at which times() increments + auxv.push_back(auxv_t(M5_AT_CLKTCK, 0x64)); + // For statically linked executables, this is the virtual address of the + // program header tables if they appear in the executable image + auxv.push_back(auxv_t(M5_AT_PHDR, elfObject->programHeaderTable())); + // This is the size of a program header entry from the elf file. + auxv.push_back(auxv_t(M5_AT_PHENT, elfObject->programHeaderSize())); + // This is the number of program headers from the original elf file. + auxv.push_back(auxv_t(M5_AT_PHNUM, elfObject->programHeaderCount())); + //This is the address of the elf "interpreter", It should be set + //to 0 for regular executables. It should be something else + //(not sure what) for dynamic libraries. + auxv.push_back(auxv_t(M5_AT_BASE, 0)); + + //XXX Figure out what this should be. + auxv.push_back(auxv_t(M5_AT_FLAGS, 0)); + //The entry point to the program + auxv.push_back(auxv_t(M5_AT_ENTRY, objFile->entryPoint())); + //Different user and group IDs + auxv.push_back(auxv_t(M5_AT_UID, uid())); + auxv.push_back(auxv_t(M5_AT_EUID, euid())); + auxv.push_back(auxv_t(M5_AT_GID, gid())); + auxv.push_back(auxv_t(M5_AT_EGID, egid())); + //Whether to enable "secure mode" in the executable + auxv.push_back(auxv_t(M5_AT_SECURE, 0)); + //The filename of the program + auxv.push_back(auxv_t(M5_AT_EXECFN, 0)); + //The string "v51" with unknown meaning + auxv.push_back(auxv_t(M5_AT_PLATFORM, 0)); + } + + //Figure out how big the initial stack nedes to be + + // A sentry NULL void pointer at the top of the stack. + int sentry_size = intSize; + + string platform = "v51"; + int platform_size = platform.size() + 1; + + // The aux vectors are put on the stack in two groups. The first group are + // the vectors that are generated as the elf is loaded. The second group + // are the ones that were computed ahead of time and include the platform + // string. + int aux_data_size = filename.size() + 1; + + int env_data_size = 0; + for (int i = 0; i < envp.size(); ++i) { + env_data_size += envp[i].size() + 1; + } + int arg_data_size = 0; + for (int i = 0; i < argv.size(); ++i) { + arg_data_size += argv[i].size() + 1; + } + + int info_block_size = + sentry_size + env_data_size + arg_data_size + + aux_data_size + platform_size; + + //Each auxilliary vector is two 4 byte words + int aux_array_size = intSize * 2 * (auxv.size() + 1); + + int envp_array_size = intSize * (envp.size() + 1); + int argv_array_size = intSize * (argv.size() + 1); + + int argc_size = intSize; + + //Figure out the size of the contents of the actual initial frame + int frame_size = + info_block_size + + aux_array_size + + envp_array_size + + argv_array_size + + argc_size; + + //There needs to be padding after the auxiliary vector data so that the + //very bottom of the stack is aligned properly. + int partial_size = frame_size; + int aligned_partial_size = roundUp(partial_size, align); + int aux_padding = aligned_partial_size - partial_size; + + int space_needed = frame_size + aux_padding; + + stack_min = stack_base - space_needed; + stack_min = roundDown(stack_min, align); + stack_size = stack_base - stack_min; + + // map memory + pTable->allocate(roundDown(stack_min, pageSize), + roundUp(stack_size, pageSize)); + + // map out initial stack contents + uint32_t sentry_base = stack_base - sentry_size; + uint32_t aux_data_base = sentry_base - aux_data_size; + uint32_t env_data_base = aux_data_base - env_data_size; + uint32_t arg_data_base = env_data_base - arg_data_size; + uint32_t platform_base = arg_data_base - platform_size; + uint32_t auxv_array_base = platform_base - aux_array_size - aux_padding; + uint32_t envp_array_base = auxv_array_base - envp_array_size; + uint32_t argv_array_base = envp_array_base - argv_array_size; + uint32_t argc_base = argv_array_base - argc_size; + + DPRINTF(Stack, "The addresses of items on the initial stack:\n"); + DPRINTF(Stack, "0x%x - aux data\n", aux_data_base); + DPRINTF(Stack, "0x%x - env data\n", env_data_base); + DPRINTF(Stack, "0x%x - arg data\n", arg_data_base); + DPRINTF(Stack, "0x%x - platform base\n", platform_base); + DPRINTF(Stack, "0x%x - auxv array\n", auxv_array_base); + DPRINTF(Stack, "0x%x - envp array\n", envp_array_base); + DPRINTF(Stack, "0x%x - argv array\n", argv_array_base); + DPRINTF(Stack, "0x%x - argc \n", argc_base); + DPRINTF(Stack, "0x%x - stack min\n", stack_min); + + // write contents to stack + + // figure out argc + uint32_t argc = argv.size(); + uint32_t guestArgc = PowerISA::htog(argc); + + //Write out the sentry void * + uint32_t sentry_NULL = 0; + initVirtMem->writeBlob(sentry_base, + (uint8_t*)&sentry_NULL, sentry_size); + + //Fix up the aux vectors which point to other data + for (int i = auxv.size() - 1; i >= 0; i--) { + if (auxv[i].a_type == M5_AT_PLATFORM) { + auxv[i].a_val = platform_base; + initVirtMem->writeString(platform_base, platform.c_str()); + } else if (auxv[i].a_type == M5_AT_EXECFN) { + auxv[i].a_val = aux_data_base; + initVirtMem->writeString(aux_data_base, filename.c_str()); + } + } + + //Copy the aux stuff + for (int x = 0; x < auxv.size(); x++) + { + initVirtMem->writeBlob(auxv_array_base + x * 2 * intSize, + (uint8_t*)&(auxv[x].a_type), intSize); + initVirtMem->writeBlob(auxv_array_base + (x * 2 + 1) * intSize, + (uint8_t*)&(auxv[x].a_val), intSize); + } + //Write out the terminating zeroed auxilliary vector + const uint64_t zero = 0; + initVirtMem->writeBlob(auxv_array_base + 2 * intSize * auxv.size(), + (uint8_t*)&zero, 2 * intSize); + + copyStringArray(envp, envp_array_base, env_data_base, initVirtMem); + copyStringArray(argv, argv_array_base, arg_data_base, initVirtMem); + + initVirtMem->writeBlob(argc_base, (uint8_t*)&guestArgc, intSize); + + ThreadContext *tc = system->getThreadContext(contextIds[0]); + + //Set the stack pointer register + tc->setIntReg(StackPointerReg, stack_min); + + Addr prog_entry = objFile->entryPoint(); + tc->setPC(prog_entry); + tc->setNextPC(prog_entry + sizeof(MachInst)); + + //Align the "stack_min" to a page boundary. + stack_min = roundDown(stack_min, pageSize); +} + +PowerISA::IntReg +PowerLiveProcess::getSyscallArg(ThreadContext *tc, int i) +{ + assert(i < 5); + return tc->readIntReg(ArgumentReg0 + i); +} + +void +PowerLiveProcess::setSyscallArg(ThreadContext *tc, + int i, PowerISA::IntReg val) +{ + assert(i < 5); + tc->setIntReg(ArgumentReg0 + i, val); +} + +void +PowerLiveProcess::setSyscallReturn(ThreadContext *tc, + SyscallReturn return_value) +{ + tc->setIntReg(ReturnValueReg, return_value.value()); +} diff --git a/src/arch/power/process.hh b/src/arch/power/process.hh new file mode 100644 index 000000000..dae776c4c --- /dev/null +++ b/src/arch/power/process.hh @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2007-2008 The Florida State University + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Stephen Hines + * Timothy M. Jones + */ + +#ifndef __POWER_PROCESS_HH__ +#define __POWER_PROCESS_HH__ + +#include +#include +#include "sim/process.hh" + +class LiveProcess; +class ObjectFile; +class System; + +class PowerLiveProcess : public LiveProcess +{ + protected: + PowerLiveProcess(LiveProcessParams * params, ObjectFile *objFile); + + void startup(); + + public: + void argsInit(int intSize, int pageSize); + PowerISA::IntReg getSyscallArg(ThreadContext *tc, int i); + void setSyscallArg(ThreadContext *tc, int i, PowerISA::IntReg val); + void setSyscallReturn(ThreadContext *tc, SyscallReturn return_value); +}; + +#endif // __POWER_PROCESS_HH__ + diff --git a/src/arch/power/registers.hh b/src/arch/power/registers.hh new file mode 100644 index 000000000..5bcca3641 --- /dev/null +++ b/src/arch/power/registers.hh @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Timothy M. Jones + */ + +#ifndef __ARCH_POWER_REGISTERS_HH__ +#define __ARCH_POWER_REGISTERS_HH__ + +#include "arch/power/max_inst_regs.hh" +#include "arch/power/miscregs.hh" + +namespace PowerISA { + +using PowerISAInst::MaxInstSrcRegs; +using PowerISAInst::MaxInstDestRegs; + +typedef uint8_t RegIndex; + +typedef uint64_t IntReg; + +// Floating point register file entry type +typedef uint64_t FloatRegBits; +typedef double FloatReg; +typedef uint64_t MiscReg; + +// Constants Related to the number of registers +const int NumIntArchRegs = 32; + +// CR, XER, LR, CTR, FPSCR, RSV, RSV-LEN, RSV-ADDR +// and zero register, which doesn't actually exist but needs a number +const int NumIntSpecialRegs = 9; +const int NumFloatArchRegs = 32; +const int NumFloatSpecialRegs = 0; +const int NumInternalProcRegs = 0; + +const int NumIntRegs = NumIntArchRegs + NumIntSpecialRegs; +const int NumFloatRegs = NumFloatArchRegs + NumFloatSpecialRegs; +const int NumMiscRegs = NUM_MISCREGS; + +// Semantically meaningful register indices +const int ReturnValueReg = 3; +const int ArgumentReg0 = 3; +const int ArgumentReg1 = 4; +const int ArgumentReg2 = 5; +const int ArgumentReg3 = 6; +const int ArgumentReg4 = 7; +const int FramePointerReg = 31; +const int StackPointerReg = 1; + +// There isn't one in Power, but we need to define one somewhere +const int ZeroReg = NumIntRegs - 1; + +const int SyscallNumReg = 0; +const int SyscallPseudoReturnReg = 3; +const int SyscallSuccessReg = 3; + +// These help enumerate all the registers for dependence tracking. +const int FP_Base_DepTag = NumIntRegs; +const int Ctrl_Base_DepTag = FP_Base_DepTag + NumFloatRegs; + +typedef union { + IntReg intreg; + FloatReg fpreg; + MiscReg ctrlreg; +} AnyReg; + +enum MiscIntRegNums { + INTREG_CR = NumIntArchRegs, + INTREG_XER, + INTREG_LR, + INTREG_CTR, + INTREG_FPSCR, + INTREG_RSV, + INTREG_RSV_LEN, + INTREG_RSV_ADDR +}; + +} // PowerISA namespace + +#endif // __ARCH_POWER_REGISTERS_HH__ diff --git a/src/arch/power/remote_gdb.hh b/src/arch/power/remote_gdb.hh new file mode 100644 index 000000000..34bb4bd1f --- /dev/null +++ b/src/arch/power/remote_gdb.hh @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2002-2005 The Regents of The University of Michigan + * Copyright (c) 2007-2008 The Florida State University + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Nathan Binkert + * Stephen Hines + * Timothy M. Jones + */ + +#ifndef __ARCH_ARM_REMOTE_GDB_HH__ +#define __ARCH_ARM_REMOTE_GDB_HH__ + +#include "base/remote_gdb.hh" + +namespace PowerISA +{ + +class RemoteGDB : public BaseRemoteGDB +{ + public: + RemoteGDB(System *system, ThreadContext *context) + : BaseRemoteGDB(system, context, 1) + { + } + + bool + acc(Addr, size_t) + { + panic("acc not implemented for POWER!"); + } + + void + getregs() + { + panic("getregs not implemented for POWER!"); + } + + void + setregs() + { + panic("setregs not implemented for POWER!"); + } + + void + clearSingleStep() + { + panic("clearSingleStep not implemented for POWER!"); + } + + void + setSingleStep() + { + panic("setSingleStep not implemented for POWER!"); + } +}; + +} // PowerISA namespace + +#endif /* __ARCH_POWER_REMOTE_GDB_H__ */ diff --git a/src/arch/power/stacktrace.hh b/src/arch/power/stacktrace.hh new file mode 100644 index 000000000..49d687a6e --- /dev/null +++ b/src/arch/power/stacktrace.hh @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2005 The Regents of The University of Michigan + * Copyright (c) 2007-2008 The Florida State University + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Ali Saidi + * Stephen Hines + * Timothy M. Jones + */ + +#ifndef __ARCH_POWER_STACKTRACE_HH__ +#define __ARCH_POWER_STACKTRACE_HH__ + +#include "base/trace.hh" +#include "cpu/static_inst.hh" + +class ThreadContext; +class StackTrace; + +namespace PowerISA +{ + +class ProcessInfo +{ + private: + ThreadContext *tc; + + int thread_info_size; + int task_struct_size; + int task_off; + int pid_off; + int name_off; + + public: + ProcessInfo(ThreadContext *_tc); + + Addr task(Addr ksp) const; + int pid(Addr ksp) const; + std::string name(Addr ksp) const; +}; + +class StackTrace +{ + protected: + typedef TheISA::MachInst MachInst; + private: + ThreadContext *tc; + std::vector stack; + + private: + bool isEntry(Addr addr); + bool decodePrologue(Addr sp, Addr callpc, Addr func, int &size, Addr &ra); + bool decodeSave(MachInst inst, int ®, int &disp); + bool decodeStack(MachInst inst, int &disp); + + void trace(ThreadContext *tc, bool is_call); + + public: + StackTrace(); + StackTrace(ThreadContext *tc, StaticInstPtr inst); + ~StackTrace(); + + void + clear() + { + tc = 0; + stack.clear(); + } + + bool + valid() const + { + return tc != NULL; + } + + bool trace(ThreadContext *tc, StaticInstPtr inst); + + public: + const std::vector & + getstack() const + { + return stack; + } + + static const int user = 1; + static const int console = 2; + static const int unknown = 3; + +#if TRACING_ON + private: + void dump(); + + public: + void + dprintf() + { + if (DTRACE(Stack)) + dump(); + } +#else + public: + void + dprintf() + { + } +#endif +}; + +inline bool +StackTrace::trace(ThreadContext *tc, StaticInstPtr inst) +{ + if (!inst->isCall() && !inst->isReturn()) + return false; + + if (valid()) + clear(); + + trace(tc, !inst->isReturn()); + return true; +} + +} // PowerISA namespace + +#endif // __ARCH_POWER_STACKTRACE_HH__ diff --git a/src/arch/power/tlb.cc b/src/arch/power/tlb.cc new file mode 100644 index 000000000..125c92a1a --- /dev/null +++ b/src/arch/power/tlb.cc @@ -0,0 +1,322 @@ +/* + * Copyright (c) 2001-2005 The Regents of The University of Michigan + * Copyright (c) 2007 MIPS Technologies, Inc. + * Copyright (c) 2007-2008 The Florida State University + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Nathan Binkert + * Steve Reinhardt + * Jaidev Patwardhan + * Stephen Hines + * Timothy M. Jones + */ + +#include +#include + +#include "arch/power/faults.hh" +#include "arch/power/pagetable.hh" +#include "arch/power/tlb.hh" +#include "arch/power/utility.hh" +#include "base/inifile.hh" +#include "base/str.hh" +#include "base/trace.hh" +#include "cpu/thread_context.hh" +#include "mem/page_table.hh" +#include "params/PowerTLB.hh" +#include "sim/process.hh" + + +using namespace std; +using namespace PowerISA; + +/////////////////////////////////////////////////////////////////////// +// +// POWER TLB +// + +#define MODE2MASK(X) (1 << (X)) + +TLB::TLB(const Params *p) + : BaseTLB(p), size(p->size), nlu(0) +{ + table = new PowerISA::PTE[size]; + memset(table, 0, sizeof(PowerISA::PTE[size])); + smallPages = 0; +} + +TLB::~TLB() +{ + if (table) + delete [] table; +} + +// look up an entry in the TLB +PowerISA::PTE * +TLB::lookup(Addr vpn, uint8_t asn) const +{ + // assume not found... + PowerISA::PTE *retval = NULL; + PageTable::const_iterator i = lookupTable.find(vpn); + if (i != lookupTable.end()) { + while (i->first == vpn) { + int index = i->second; + PowerISA::PTE *pte = &table[index]; + Addr Mask = pte->Mask; + Addr InvMask = ~Mask; + Addr VPN = pte->VPN; + if (((vpn & InvMask) == (VPN & InvMask)) + && (pte->G || (asn == pte->asid))) { + + // We have a VPN + ASID Match + retval = pte; + break; + } + ++i; + } + } + + DPRINTF(TLB, "lookup %#x, asn %#x -> %s ppn %#x\n", vpn, (int)asn, + retval ? "hit" : "miss", retval ? retval->PFN1 : 0); + return retval; +} + +PowerISA::PTE* +TLB::getEntry(unsigned Index) const +{ + // Make sure that Index is valid + assert(Indexfirst == vpn) { + int index = i->second; + PowerISA::PTE *pte = &table[index]; + Addr Mask = pte->Mask; + Addr InvMask = ~Mask; + Addr VPN = pte->VPN; + if (((vpn & InvMask) == (VPN & InvMask)) + && (pte->G || (asn == pte->asid))) { + + // We have a VPN + ASID Match + retval = pte; + Ind = index; + break; + } + ++i; + } + } + + DPRINTF(Power, "VPN: %x, asid: %d, Result of TLBP: %d\n", vpn, asn, Ind); + return Ind; +} + +inline Fault +TLB::checkCacheability(RequestPtr &req) +{ + Addr VAddrUncacheable = 0xA0000000; + if ((req->getVaddr() & VAddrUncacheable) == VAddrUncacheable) { + + // mark request as uncacheable + req->setFlags(Request::UNCACHEABLE); + } + return NoFault; +} + +void +TLB::insertAt(PowerISA::PTE &pte, unsigned Index, int _smallPages) +{ + smallPages=_smallPages; + if (Index > size){ + warn("Attempted to write at index (%d) beyond TLB size (%d)", + Index, size); + } else { + + // Update TLB + if (table[Index].V0 == true || table[Index].V1 == true) { + + // Previous entry is valid + PageTable::iterator i = lookupTable.find(table[Index].VPN); + lookupTable.erase(i); + } + table[Index]=pte; + + // Update fast lookup table + lookupTable.insert(make_pair(table[Index].VPN, Index)); + } +} + +// insert a new TLB entry +void +TLB::insert(Addr addr, PowerISA::PTE &pte) +{ + fatal("TLB Insert not yet implemented\n"); +} + +void +TLB::flushAll() +{ + DPRINTF(TLB, "flushAll\n"); + memset(table, 0, sizeof(PowerISA::PTE[size])); + lookupTable.clear(); + nlu = 0; +} + +void +TLB::serialize(ostream &os) +{ + SERIALIZE_SCALAR(size); + SERIALIZE_SCALAR(nlu); + + for (int i = 0; i < size; i++) { + nameOut(os, csprintf("%s.PTE%d", name(), i)); + table[i].serialize(os); + } +} + +void +TLB::unserialize(Checkpoint *cp, const string §ion) +{ + UNSERIALIZE_SCALAR(size); + UNSERIALIZE_SCALAR(nlu); + + for (int i = 0; i < size; i++) { + table[i].unserialize(cp, csprintf("%s.PTE%d", section, i)); + if (table[i].V0 || table[i].V1) { + lookupTable.insert(make_pair(table[i].VPN, i)); + } + } +} + +void +TLB::regStats() +{ + read_hits + .name(name() + ".read_hits") + .desc("DTB read hits") + ; + + read_misses + .name(name() + ".read_misses") + .desc("DTB read misses") + ; + + + read_accesses + .name(name() + ".read_accesses") + .desc("DTB read accesses") + ; + + write_hits + .name(name() + ".write_hits") + .desc("DTB write hits") + ; + + write_misses + .name(name() + ".write_misses") + .desc("DTB write misses") + ; + + + write_accesses + .name(name() + ".write_accesses") + .desc("DTB write accesses") + ; + + hits + .name(name() + ".hits") + .desc("DTB hits") + ; + + misses + .name(name() + ".misses") + .desc("DTB misses") + ; + + invalids + .name(name() + ".invalids") + .desc("DTB access violations") + ; + + accesses + .name(name() + ".accesses") + .desc("DTB accesses") + ; + + hits = read_hits + write_hits; + misses = read_misses + write_misses; + accesses = read_accesses + write_accesses; +} + +Fault +TLB::translateAtomic(RequestPtr req, ThreadContext *tc, Mode mode) +{ +#if !FULL_SYSTEM + Process * p = tc->getProcessPtr(); + + Fault fault = p->pTable->translate(req); + if (fault != NoFault) + return fault; + + return NoFault; +#else + fatal("translate atomic not yet implemented\n"); +#endif +} + +void +TLB::translateTiming(RequestPtr req, ThreadContext *tc, + Translation *translation, Mode mode) +{ + assert(translation); + translation->finish(translateAtomic(req, tc, mode), req, tc, mode); +} + +PowerISA::PTE & +TLB::index(bool advance) +{ + PowerISA::PTE *pte = &table[nlu]; + + if (advance) + nextnlu(); + + return *pte; +} + +PowerISA::TLB * +PowerTLBParams::create() +{ + return new PowerISA::TLB(this); +} diff --git a/src/arch/power/tlb.hh b/src/arch/power/tlb.hh new file mode 100644 index 000000000..8b6c7233d --- /dev/null +++ b/src/arch/power/tlb.hh @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2001-2005 The Regents of The University of Michigan + * Copyright (c) 2007 MIPS Technologies, Inc. + * Copyright (c) 2007-2008 The Florida State University + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Nathan Binkert + * Steve Reinhardt + * Stephen Hines + * Timothy M. Jones + */ + +#ifndef __ARCH_POWER_TLB_HH__ +#define __ARCH_POWER_TLB_HH__ + +#include + +#include "arch/power/isa_traits.hh" +#include "arch/power/utility.hh" +#include "arch/power/vtophys.hh" +#include "arch/power/pagetable.hh" +#include "base/statistics.hh" +#include "mem/request.hh" +#include "params/PowerTLB.hh" +#include "sim/faults.hh" +#include "sim/tlb.hh" + +class ThreadContext; + +namespace PowerISA { + +// This is copied from the ARM ISA and has not been checked against the +// Power at all. +struct TlbEntry +{ + Addr _pageStart; + + TlbEntry() + { + } + + TlbEntry(Addr asn, Addr vaddr, Addr paddr) + : _pageStart(paddr) + { + } + + void + updateVaddr(Addr new_vaddr) + { + panic("unimplemented"); + } + + Addr + pageStart() + { + return _pageStart; + } + + void + serialize(std::ostream &os) + { + SERIALIZE_SCALAR(_pageStart); + } + + void + unserialize(Checkpoint *cp, const std::string §ion) + { + UNSERIALIZE_SCALAR(_pageStart); + } +}; + +class TLB : public BaseTLB +{ + protected: + typedef std::multimap PageTable; + PageTable lookupTable; // Quick lookup into page table + + PowerISA::PTE *table; // the Page Table + int size; // TLB Size + int nlu; // not last used entry (for replacement) + + void + nextnlu() + { + if (++nlu >= size) { + nlu = 0; + } + } + + PowerISA::PTE *lookup(Addr vpn, uint8_t asn) const; + + mutable Stats::Scalar read_hits; + mutable Stats::Scalar read_misses; + mutable Stats::Scalar read_acv; + mutable Stats::Scalar read_accesses; + mutable Stats::Scalar write_hits; + mutable Stats::Scalar write_misses; + mutable Stats::Scalar write_acv; + mutable Stats::Scalar write_accesses; + Stats::Formula hits; + Stats::Formula misses; + Stats::Formula invalids; + Stats::Formula accesses; + + public: + typedef PowerTLBParams Params; + TLB(const Params *p); + virtual ~TLB(); + + int probeEntry(Addr vpn,uint8_t) const; + PowerISA::PTE *getEntry(unsigned) const; + + int smallPages; + + int + getsize() const + { + return size; + } + + PowerISA::PTE &index(bool advance = true); + void insert(Addr vaddr, PowerISA::PTE &pte); + void insertAt(PowerISA::PTE &pte, unsigned Index, int _smallPages); + void flushAll(); + + void + demapPage(Addr vaddr, uint64_t asn) + { + panic("demapPage unimplemented.\n"); + } + + // static helper functions... really + static bool validVirtualAddress(Addr vaddr); + static Fault checkCacheability(RequestPtr &req); + Fault translateAtomic(RequestPtr req, ThreadContext *tc, Mode mode); + void translateTiming(RequestPtr req, ThreadContext *tc, + Translation *translation, Mode mode); + + // Checkpointing + void serialize(std::ostream &os); + void unserialize(Checkpoint *cp, const std::string §ion); + void regStats(); +}; + +} // PowerISA namespace + +#endif // __ARCH_POWER_TLB_HH__ diff --git a/src/arch/power/types.hh b/src/arch/power/types.hh new file mode 100644 index 000000000..7b994adc9 --- /dev/null +++ b/src/arch/power/types.hh @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Timothy M. Jones + */ + +#ifndef __ARCH_POWER_TYPES_HH__ +#define __ARCH_POWER_TYPES_HH__ + +#include "base/bitunion.hh" +#include "base/types.hh" + +namespace PowerISA +{ + +typedef uint32_t MachInst; + +BitUnion32(ExtMachInst) + + // Registers + Bitfield<25, 21> rs; + Bitfield<20, 16> ra; + + // Shifts and masks + Bitfield<15, 11> sh; + Bitfield<10, 6> mb; + Bitfield< 5, 1> me; + + // Immediate fields + Bitfield<15, 0> si; + Bitfield<15, 0> d; + + // Special purpose register identifier + Bitfield<20, 11> spr; + Bitfield<25, 2> li; + Bitfield<1> aa; + Bitfield<25, 23> bf; + Bitfield<15, 2> bd; + Bitfield<25, 21> bo; + Bitfield<20, 16> bi; + Bitfield<20, 18> bfa; + + // Record bits + Bitfield<0> rc31; + Bitfield<10> oe; + + // Condition register fields + Bitfield<25, 21> bt; + Bitfield<20, 16> ba; + Bitfield<15, 11> bb; + + // FXM field for mtcrf instruction + Bitfield<19, 12> fxm; +EndBitUnion(ExtMachInst) + +// typedef uint64_t LargestRead; +// // Need to use 64 bits to make sure that read requests get handled properly + +// typedef int RegContextParam; +// typedef int RegContextVal; + +struct CoreSpecific { +}; + +} // PowerISA namspace + +#endif // __ARCH_POWER_TYPES_HH__ diff --git a/src/arch/power/utility.hh b/src/arch/power/utility.hh new file mode 100644 index 000000000..442075aa2 --- /dev/null +++ b/src/arch/power/utility.hh @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2003-2005 The Regents of The University of Michigan + * Copyright (c) 2007-2008 The Florida State University + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Korey Sewell + * Stephen Hines + * Timothy M. Jones + */ + +#ifndef __ARCH_POWER_UTILITY_HH__ +#define __ARCH_POWER_UTILITY_HH__ + +#include "arch/power/miscregs.hh" +#include "arch/power/types.hh" +#include "base/hashmap.hh" +#include "base/types.hh" +#include "cpu/thread_context.hh" + +namespace __hash_namespace { + +template<> +struct hash : public hash { + size_t operator()(const PowerISA::ExtMachInst &emi) const { + return hash::operator()((uint32_t)emi); + }; +}; + +} // __hash_namespace namespace + +namespace PowerISA { + +/** + * Function to ensure ISA semantics about 0 registers. + * @param tc The thread context. + */ +template +void zeroRegisters(TC *tc); + +// Instruction address compression hooks +static inline Addr +realPCToFetchPC(const Addr &addr) +{ + return addr; +} + +static inline Addr +fetchPCToRealPC(const Addr &addr) +{ + return addr; +} + +// the size of "fetched" instructions +static inline size_t +fetchInstSize() +{ + return sizeof(MachInst); +} + +static inline MachInst +makeRegisterCopy(int dest, int src) +{ + panic("makeRegisterCopy not implemented"); + return 0; +} + +inline void +startupCPU(ThreadContext *tc, int cpuId) +{ + tc->activate(0); +} + +template +Fault +checkFpEnableFault(XC *xc) +{ + return NoFault; +} + +static inline void +copyRegs(ThreadContext *src, ThreadContext *dest) +{ + panic("Copy Regs Not Implemented Yet\n"); +} + +static inline void +copyMiscRegs(ThreadContext *src, ThreadContext *dest) +{ + panic("Copy Misc. Regs Not Implemented Yet\n"); +} + +} // PowerISA namespace + +#endif // __ARCH_POWER_UTILITY_HH__ diff --git a/src/arch/power/vtophys.hh b/src/arch/power/vtophys.hh new file mode 100644 index 000000000..3cfebcfc7 --- /dev/null +++ b/src/arch/power/vtophys.hh @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2002-2005 The Regents of The University of Michigan + * Copyright (c) 2007-2008 The Florida State University + * Copyright (c) 2009 The University of Edinburgh + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Ali Saidi + * Nathan Binkert + * Stephen Hines + * Timothy M. Jones + */ + +#ifndef __ARCH_POWER_VTOPHYS_HH__ +#define __ARCH_POWER_VTOPHYS_HH__ + +#include "arch/power/isa_traits.hh" +#include "arch/power/utility.hh" + + +class ThreadContext; +class FunctionalPort; + +namespace PowerISA { + +inline Addr +PteAddr(Addr a) +{ + return (a & PteMask) << PteShift; +} + +} // PowerISA namespace + +#endif // __ARCH_POWER_VTOPHYS_HH__ + -- cgit v1.2.3 From 776f9405fa0e58ea5ca0354cd233ebb2603bddbf Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Tue, 20 Oct 2009 15:15:37 -0400 Subject: Fix stat64 structure on 32-bit X86_SE The st_size entry was in the wrong place (see linux-2.6.29/arch/x86/include/asm/stat.h ) Also, the packed attribute is needed when compiling on a 64-bit machine, otherwise gcc adds extra padding that break the layout of the structure. --- src/arch/x86/linux/linux.hh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/linux/linux.hh b/src/arch/x86/linux/linux.hh index a810d4a79..238b5e683 100644 --- a/src/arch/x86/linux/linux.hh +++ b/src/arch/x86/linux/linux.hh @@ -142,8 +142,8 @@ class X86Linux32 : public Linux uint32_t st_uid; uint32_t st_gid; uint64_t st_rdev; - int64_t st_size; uint8_t __pad3[4]; + int64_t st_size; uint32_t st_blksize; uint64_t st_blocks; uint32_t st_atimeX; @@ -153,7 +153,7 @@ class X86Linux32 : public Linux uint32_t st_ctimeX; uint32_t st_ctime_nsec; uint64_t st_ino; - } tgt_stat64; + } __attribute__((__packed__)) tgt_stat64; static OpenFlagTransTable openFlagTable[]; -- cgit v1.2.3 From 2b473cb099ad64030a103ee4292e2247f7a3e817 Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Tue, 20 Oct 2009 14:44:51 -0400 Subject: hook up stat64 syscall on 32-bit X86_SE --- src/arch/x86/linux/syscalls.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/arch') diff --git a/src/arch/x86/linux/syscalls.cc b/src/arch/x86/linux/syscalls.cc index 2b54843f3..40f70c3fb 100644 --- a/src/arch/x86/linux/syscalls.cc +++ b/src/arch/x86/linux/syscalls.cc @@ -702,7 +702,7 @@ SyscallDesc I386LinuxProcess::syscallDescs[] = { /* 192 */ SyscallDesc("mmap2", mmapFunc), /* 193 */ SyscallDesc("truncate64", unimplementedFunc), /* 194 */ SyscallDesc("ftruncate64", unimplementedFunc), - /* 195 */ SyscallDesc("stat64", unimplementedFunc), + /* 195 */ SyscallDesc("stat64", stat64Func), /* 196 */ SyscallDesc("lstat64", unimplementedFunc), /* 197 */ SyscallDesc("fstat64", fstat64Func), /* 198 */ SyscallDesc("lchown32", unimplementedFunc), -- cgit v1.2.3 From 5b6f707a008b4312fd02a4383bf107adfa677d33 Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Tue, 20 Oct 2009 16:48:00 -0400 Subject: hook up stat syscall on 64-bit x86_SE --- src/arch/x86/linux/syscalls.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/arch') diff --git a/src/arch/x86/linux/syscalls.cc b/src/arch/x86/linux/syscalls.cc index 40f70c3fb..14b3fa69b 100644 --- a/src/arch/x86/linux/syscalls.cc +++ b/src/arch/x86/linux/syscalls.cc @@ -232,7 +232,7 @@ SyscallDesc X86_64LinuxProcess::syscallDescs[] = { /* 1 */ SyscallDesc("write", writeFunc), /* 2 */ SyscallDesc("open", openFunc), /* 3 */ SyscallDesc("close", closeFunc), - /* 4 */ SyscallDesc("stat", unimplementedFunc), + /* 4 */ SyscallDesc("stat", stat64Func), /* 5 */ SyscallDesc("fstat", fstat64Func), /* 6 */ SyscallDesc("lstat", unimplementedFunc), /* 7 */ SyscallDesc("poll", unimplementedFunc), -- cgit v1.2.3 From 14691148cd9300ed7a23dd889b9c0173124b30eb Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Wed, 21 Oct 2009 13:40:43 -0400 Subject: Implement X86 sse2 movdqu and movdqa instructions The movdqa instruction should enforce 16-byte alignment. This implementation does not do that. These instructions are needed for most of x86_64 spec2k to run. --- src/arch/x86/isa/decoder/two_byte_opcodes.isa | 8 ++-- .../insts/simd128/integer/data_transfer/move.py | 56 +++++++++++++++++++++- 2 files changed, 58 insertions(+), 6 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/decoder/two_byte_opcodes.isa b/src/arch/x86/isa/decoder/two_byte_opcodes.isa index c23eeccab..27aabaccc 100644 --- a/src/arch/x86/isa/decoder/two_byte_opcodes.isa +++ b/src/arch/x86/isa/decoder/two_byte_opcodes.isa @@ -604,7 +604,7 @@ } // repe (0xF3) 0x4: decode OPCODE_OP_BOTTOM3 { - 0x7: WarnUnimpl::movdqu_Vo_Wo(); + 0x7: MOVDQU(Vo,Wo); default: UD2(); } // operand size (0x66) @@ -616,7 +616,7 @@ 0x4: PUNPCKLQDQ(Vo,Wq); 0x5: PUNPCKHQDQ(Vo,Wq); 0x6: WarnUnimpl::movd_Vo_Ed(); - 0x7: WarnUnimpl::movdqa_Vo_Wo(); + 0x7: MOVDQA(Vo,Wo); } default: UD2(); } @@ -702,7 +702,7 @@ // repe (0xF3) 0x4: decode OPCODE_OP_BOTTOM3 { 0x6: MOVQ(Vq,Wq); - 0x7: WarnUnimpl::movdqu_Wo_Vo(); + 0x7: MOVDQU(Wo,Vo); default: UD2(); } // operand size (0x66) @@ -710,7 +710,7 @@ 0x4: WarnUnimpl::haddpd_Vo_Wo(); 0x5: WarnUnimpl::hsubpd_Vo_Wo(); 0x6: WarnUnimpl::movd_Ed_Vd(); - 0x7: WarnUnimpl::movdqa_Wo_Vo(); + 0x7: MOVDQA(Wo,Vo); default: UD2(); } // repne (0xF2) diff --git a/src/arch/x86/isa/insts/simd128/integer/data_transfer/move.py b/src/arch/x86/isa/insts/simd128/integer/data_transfer/move.py index c34bd42bb..ec80ffe73 100644 --- a/src/arch/x86/isa/insts/simd128/integer/data_transfer/move.py +++ b/src/arch/x86/isa/insts/simd128/integer/data_transfer/move.py @@ -87,7 +87,59 @@ def macroop MOVQ2DQ_XMM_MMX { movfp xmml, mmxm, dataSize=8 lfpimm xmmh, 0 }; + +def macroop MOVDQA_XMM_XMM { + movfp xmml, xmmlm + movfp xmmh, xmmhm +}; + +def macroop MOVDQA_XMM_M { + ldfp xmml, seg, sib, "DISPLACEMENT", dataSize=8 + ldfp xmmh, seg, sib, "DISPLACEMENT + 8", dataSize=8 +}; + +def macroop MOVDQA_XMM_P { + rdip t7 + ldfp xmml, seg, riprel, "DISPLACEMENT", dataSize=8 + ldfp xmmh, seg, riprel, "DISPLACEMENT + 8", dataSize=8 +}; + +def macroop MOVDQA_M_XMM { + stfp xmml, seg, sib, "DISPLACEMENT", dataSize=8 + stfp xmmh, seg, sib, "DISPLACEMENT + 8", dataSize=8 +}; + +def macroop MOVDQA_P_XMM { + rdip t7 + stfp xmml, seg, riprel, "DISPLACEMENT", dataSize=8 + stfp xmmh, seg, riprel, "DISPLACEMENT + 8", dataSize=8 +}; + +def macroop MOVDQU_XMM_XMM { + movfp xmml, xmmlm + movfp xmmh, xmmhm +}; + +def macroop MOVDQU_XMM_M { + ldfp xmml, seg, sib, "DISPLACEMENT", dataSize=8 + ldfp xmmh, seg, sib, "DISPLACEMENT + 8", dataSize=8 +}; + +def macroop MOVDQU_XMM_P { + rdip t7 + ldfp xmml, seg, riprel, "DISPLACEMENT", dataSize=8 + ldfp xmmh, seg, riprel, "DISPLACEMENT + 8", dataSize=8 +}; + +def macroop MOVDQU_M_XMM { + stfp xmml, seg, sib, "DISPLACEMENT", dataSize=8 + stfp xmmh, seg, sib, "DISPLACEMENT + 8", dataSize=8 +}; + +def macroop MOVDQU_P_XMM { + rdip t7 + stfp xmml, seg, riprel, "DISPLACEMENT", dataSize=8 + stfp xmmh, seg, riprel, "DISPLACEMENT + 8", dataSize=8 +}; ''' -# MOVDQA -# MOVDQU # LDDQU -- cgit v1.2.3 From 87b97f28bd2abc9feb352e7d3f0a85e9bc073912 Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Tue, 27 Oct 2009 14:11:06 -0400 Subject: Fix problem with the x86 sse movhpd instruction. The movhpd instruction was writing to the wrong memory offset. --- .../x86/isa/insts/simd128/floating_point/data_transfer/move.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/insts/simd128/floating_point/data_transfer/move.py b/src/arch/x86/isa/insts/simd128/floating_point/data_transfer/move.py index 1f4044bde..09b380fbd 100644 --- a/src/arch/x86/isa/insts/simd128/floating_point/data_transfer/move.py +++ b/src/arch/x86/isa/insts/simd128/floating_point/data_transfer/move.py @@ -187,22 +187,21 @@ def macroop MOVHPS_P_XMM { }; def macroop MOVHPD_XMM_M { - ldfp xmmh, seg, sib, "DISPLACEMENT + 8", dataSize=8 + ldfp xmmh, seg, sib, "DISPLACEMENT", dataSize=8 }; def macroop MOVHPD_XMM_P { rdip t7 - ldfp xmmh, seg, riprel, "DISPLACEMENT + 8", dataSize=8 + ldfp xmmh, seg, riprel, "DISPLACEMENT", dataSize=8 }; def macroop MOVHPD_M_XMM { - stfp xmmh, seg, sib, "DISPLACEMENT + 8", dataSize=8 + stfp xmmh, seg, sib, "DISPLACEMENT", dataSize=8 }; def macroop MOVHPD_P_XMM { rdip t7 - stfp xmml, seg, riprel, "DISPLACEMENT", dataSize=8 - stfp xmmh, seg, riprel, "DISPLACEMENT + 8", dataSize=8 + stfp xmmh, seg, riprel, "DISPLACEMENT", dataSize=8 }; def macroop MOVLPS_XMM_M { -- cgit v1.2.3 From f9624e49f6d37e42af63a4d7ca401103c67d8027 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 27 Oct 2009 23:50:25 -0700 Subject: X86: Replace "DISPLACEMENT" with disp in movhpd. --- .../x86/isa/insts/simd128/floating_point/data_transfer/move.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/insts/simd128/floating_point/data_transfer/move.py b/src/arch/x86/isa/insts/simd128/floating_point/data_transfer/move.py index 09b380fbd..ffe084786 100644 --- a/src/arch/x86/isa/insts/simd128/floating_point/data_transfer/move.py +++ b/src/arch/x86/isa/insts/simd128/floating_point/data_transfer/move.py @@ -187,21 +187,21 @@ def macroop MOVHPS_P_XMM { }; def macroop MOVHPD_XMM_M { - ldfp xmmh, seg, sib, "DISPLACEMENT", dataSize=8 + ldfp xmmh, seg, sib, disp, dataSize=8 }; def macroop MOVHPD_XMM_P { rdip t7 - ldfp xmmh, seg, riprel, "DISPLACEMENT", dataSize=8 + ldfp xmmh, seg, riprel, disp, dataSize=8 }; def macroop MOVHPD_M_XMM { - stfp xmmh, seg, sib, "DISPLACEMENT", dataSize=8 + stfp xmmh, seg, sib, disp, dataSize=8 }; def macroop MOVHPD_P_XMM { rdip t7 - stfp xmmh, seg, riprel, "DISPLACEMENT", dataSize=8 + stfp xmmh, seg, riprel, disp, dataSize=8 }; def macroop MOVLPS_XMM_M { -- cgit v1.2.3 From 3f722b991fcb33ca21330501960406a8a58e2be2 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 30 Oct 2009 00:44:55 -0700 Subject: Syscalls: Make system calls access arguments like a stack, not an array. When accessing arguments for a syscall, the position of an argument depends on the policies of the ISA, how much space preceding arguments took up, and the "alignment" of the index for this particular argument into the number of possible storate locations. This change adjusts getSyscallArg to take its index parameter by reference instead of value and to adjust it to point to the possible location of the next argument on the stack, basically just after the current one. This way, the rules for the new argument can be applied locally without knowing about other arguments since those have already been taken into account implicitly. All system calls have also been changed to reflect the new interface. In a number of cases this made the implementation clearer since it encourages arguments to be collected in one place in order and then used as necessary later, as opposed to scattering them throughout the function or using them in place in long expressions. It also discourages using getSyscallArg over and over to retrieve the same value when a temporary would do the job. --- src/arch/alpha/linux/process.cc | 15 +++++++++----- src/arch/alpha/process.cc | 4 ++-- src/arch/alpha/process.hh | 2 +- src/arch/alpha/tru64/process.cc | 41 ++++++++++++++++++++++----------------- src/arch/arm/linux/process.cc | 10 ++++++---- src/arch/arm/linux/process.hh | 2 +- src/arch/arm/process.cc | 4 ++-- src/arch/arm/process.hh | 2 +- src/arch/mips/linux/process.cc | 19 +++++++++++------- src/arch/mips/process.cc | 4 ++-- src/arch/mips/process.hh | 2 +- src/arch/power/linux/process.cc | 7 ++++--- src/arch/power/linux/process.hh | 2 +- src/arch/power/process.cc | 4 ++-- src/arch/power/process.hh | 2 +- src/arch/sparc/linux/syscalls.cc | 10 ++++++---- src/arch/sparc/process.cc | 8 ++++---- src/arch/sparc/process.hh | 4 ++-- src/arch/sparc/solaris/process.cc | 3 ++- src/arch/x86/linux/syscalls.cc | 11 +++++++---- src/arch/x86/process.cc | 19 ++++++++++++++---- src/arch/x86/process.hh | 5 +++-- 22 files changed, 108 insertions(+), 72 deletions(-) (limited to 'src/arch') diff --git a/src/arch/alpha/linux/process.cc b/src/arch/alpha/linux/process.cc index 0f09e472b..a653d7845 100644 --- a/src/arch/alpha/linux/process.cc +++ b/src/arch/alpha/linux/process.cc @@ -48,7 +48,8 @@ static SyscallReturn unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - TypedBufferArg name(process->getSyscallArg(tc, 0)); + int index = 0; + TypedBufferArg name(process->getSyscallArg(tc, index)); strcpy(name->sysname, "Linux"); strcpy(name->nodename, "m5.eecs.umich.edu"); @@ -67,13 +68,15 @@ static SyscallReturn osf_getsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - unsigned op = process->getSyscallArg(tc, 0); + int index = 0; + unsigned op = process->getSyscallArg(tc, index); + Addr bufPtr = process->getSyscallArg(tc, index); // unsigned nbytes = process->getSyscallArg(tc, 2); switch (op) { case 45: { // GSI_IEEE_FP_CONTROL - TypedBufferArg fpcr(process->getSyscallArg(tc, 1)); + TypedBufferArg fpcr(bufPtr); // I don't think this exactly matches the HW FPCR *fpcr = 0; fpcr.copyOut(tc->getMemPort()); @@ -94,13 +97,15 @@ static SyscallReturn osf_setsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - unsigned op = process->getSyscallArg(tc, 0); + int index = 0; + unsigned op = process->getSyscallArg(tc, index); + Addr bufPtr = process->getSyscallArg(tc, index); // unsigned nbytes = process->getSyscallArg(tc, 2); switch (op) { case 14: { // SSI_IEEE_FP_CONTROL - TypedBufferArg fpcr(process->getSyscallArg(tc, 1)); + TypedBufferArg fpcr(bufPtr); // I don't think this exactly matches the HW FPCR fpcr.copyIn(tc->getMemPort()); DPRINTFR(SyscallVerbose, "osf_setsysinfo(SSI_IEEE_FP_CONTROL): " diff --git a/src/arch/alpha/process.cc b/src/arch/alpha/process.cc index 6aad45da8..9d75d5fa1 100644 --- a/src/arch/alpha/process.cc +++ b/src/arch/alpha/process.cc @@ -193,10 +193,10 @@ AlphaLiveProcess::startup() } AlphaISA::IntReg -AlphaLiveProcess::getSyscallArg(ThreadContext *tc, int i) +AlphaLiveProcess::getSyscallArg(ThreadContext *tc, int &i) { assert(i < 6); - return tc->readIntReg(FirstArgumentReg + i); + return tc->readIntReg(FirstArgumentReg + i++); } void diff --git a/src/arch/alpha/process.hh b/src/arch/alpha/process.hh index 6d083c5ac..36b25a48e 100644 --- a/src/arch/alpha/process.hh +++ b/src/arch/alpha/process.hh @@ -44,7 +44,7 @@ class AlphaLiveProcess : public LiveProcess void argsInit(int intSize, int pageSize); public: - AlphaISA::IntReg getSyscallArg(ThreadContext *tc, int i); + AlphaISA::IntReg getSyscallArg(ThreadContext *tc, int &i); void setSyscallArg(ThreadContext *tc, int i, AlphaISA::IntReg val); void setSyscallReturn(ThreadContext *tc, SyscallReturn return_value); }; diff --git a/src/arch/alpha/tru64/process.cc b/src/arch/alpha/tru64/process.cc index 8fa3cdeda..b039fbe19 100644 --- a/src/arch/alpha/tru64/process.cc +++ b/src/arch/alpha/tru64/process.cc @@ -45,7 +45,8 @@ static SyscallReturn unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - TypedBufferArg name(process->getSyscallArg(tc, 0)); + int index = 0; + TypedBufferArg name(process->getSyscallArg(tc, index)); strcpy(name->sysname, "OSF1"); strcpy(name->nodename, "m5.eecs.umich.edu"); @@ -62,35 +63,36 @@ static SyscallReturn getsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - unsigned op = process->getSyscallArg(tc, 0); - unsigned nbytes = process->getSyscallArg(tc, 2); + int index = 0; + unsigned op = process->getSyscallArg(tc, index); + Addr bufPtr = process->getSyscallArg(tc, index); + unsigned nbytes = process->getSyscallArg(tc, index); switch (op) { case AlphaTru64::GSI_MAX_CPU: { - TypedBufferArg max_cpu(process->getSyscallArg(tc, 1)); + TypedBufferArg max_cpu(bufPtr); *max_cpu = htog((uint32_t)process->numCpus()); max_cpu.copyOut(tc->getMemPort()); return 1; } case AlphaTru64::GSI_CPUS_IN_BOX: { - TypedBufferArg cpus_in_box(process->getSyscallArg(tc, 1)); + TypedBufferArg cpus_in_box(bufPtr); *cpus_in_box = htog((uint32_t)process->numCpus()); cpus_in_box.copyOut(tc->getMemPort()); return 1; } case AlphaTru64::GSI_PHYSMEM: { - TypedBufferArg physmem(process->getSyscallArg(tc, 1)); + TypedBufferArg physmem(bufPtr); *physmem = htog((uint64_t)1024 * 1024); // physical memory in KB physmem.copyOut(tc->getMemPort()); return 1; } case AlphaTru64::GSI_CPU_INFO: { - TypedBufferArg - infop(process->getSyscallArg(tc, 1)); + TypedBufferArg infop(bufPtr); infop->current_cpu = htog(0); infop->cpus_in_box = htog(process->numCpus()); @@ -107,14 +109,14 @@ getsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process, } case AlphaTru64::GSI_PROC_TYPE: { - TypedBufferArg proc_type(process->getSyscallArg(tc, 1)); + TypedBufferArg proc_type(bufPtr); *proc_type = htog((uint64_t)11); proc_type.copyOut(tc->getMemPort()); return 1; } case AlphaTru64::GSI_PLATFORM_NAME: { - BufferArg bufArg(process->getSyscallArg(tc, 1), nbytes); + BufferArg bufArg(bufPtr, nbytes); strncpy((char *)bufArg.bufferPtr(), "COMPAQ Professional Workstation XP1000", nbytes); @@ -123,7 +125,7 @@ getsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process, } case AlphaTru64::GSI_CLK_TCK: { - TypedBufferArg clk_hz(process->getSyscallArg(tc, 1)); + TypedBufferArg clk_hz(bufPtr); *clk_hz = htog((uint64_t)1024); clk_hz.copyOut(tc->getMemPort()); return 1; @@ -142,12 +144,13 @@ static SyscallReturn setsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - unsigned op = process->getSyscallArg(tc, 0); + int index = 0; + unsigned op = process->getSyscallArg(tc, index); switch (op) { case AlphaTru64::SSI_IEEE_FP_CONTROL: warn("setsysinfo: ignoring ieee_set_fp_control() arg 0x%x\n", - process->getSyscallArg(tc, 1)); + process->getSyscallArg(tc, index)); break; default: @@ -165,17 +168,19 @@ tableFunc(SyscallDesc *desc, int callnum, LiveProcess *process, { using namespace std; - int id = process->getSyscallArg(tc, 0); // table ID - int index = process->getSyscallArg(tc, 1); // index into table + int argIndex = 0; + int id = process->getSyscallArg(tc, argIndex); // table ID + int index = process->getSyscallArg(tc, argIndex); // index into table + Addr bufPtr = process->getSyscallArg(tc, argIndex); // arg 2 is buffer pointer; type depends on table ID - int nel = process->getSyscallArg(tc, 3); // number of elements - int lel = process->getSyscallArg(tc, 4); // expected element size + int nel = process->getSyscallArg(tc, argIndex); // number of elements + int lel = process->getSyscallArg(tc, argIndex); // expected element size switch (id) { case AlphaTru64::TBL_SYSINFO: { if (index != 0 || nel != 1 || lel != sizeof(Tru64::tbl_sysinfo)) return -EINVAL; - TypedBufferArg elp(process->getSyscallArg(tc, 2)); + TypedBufferArg elp(bufPtr); const int clk_hz = one_million; elp->si_user = htog(curTick / (Clock::Frequency / clk_hz)); diff --git a/src/arch/arm/linux/process.cc b/src/arch/arm/linux/process.cc index a7f36e18d..f909d871a 100644 --- a/src/arch/arm/linux/process.cc +++ b/src/arch/arm/linux/process.cc @@ -50,7 +50,8 @@ static SyscallReturn unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - TypedBufferArg name(process->getSyscallArg(tc, 0)); + int index = 0; + TypedBufferArg name(process->getSyscallArg(tc, index)); strcpy(name->sysname, "Linux"); strcpy(name->nodename, "m5.eecs.umich.edu"); @@ -417,7 +418,8 @@ static SyscallReturn setTLSFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - uint32_t tlsPtr = process->getSyscallArg(tc, 0); + int index = 0; + uint32_t tlsPtr = process->getSyscallArg(tc, index); tc->getMemPort()->writeBlob(ArmLinuxProcess::commPage + 0x0ff0, (uint8_t *)&tlsPtr, sizeof(tlsPtr)); @@ -511,12 +513,12 @@ ArmLinuxProcess::startup() } ArmISA::IntReg -ArmLinuxProcess::getSyscallArg(ThreadContext *tc, int i) +ArmLinuxProcess::getSyscallArg(ThreadContext *tc, int &i) { // Linux apparently allows more parameter than the ABI says it should. // This limit may need to be increased even further. assert(i < 6); - return tc->readIntReg(ArgumentReg0 + i); + return tc->readIntReg(ArgumentReg0 + i++); } void diff --git a/src/arch/arm/linux/process.hh b/src/arch/arm/linux/process.hh index 53b3781d2..ab836fab2 100644 --- a/src/arch/arm/linux/process.hh +++ b/src/arch/arm/linux/process.hh @@ -44,7 +44,7 @@ class ArmLinuxProcess : public ArmLiveProcess void startup(); - ArmISA::IntReg getSyscallArg(ThreadContext *tc, int i); + ArmISA::IntReg getSyscallArg(ThreadContext *tc, int &i); void setSyscallArg(ThreadContext *tc, int i, ArmISA::IntReg val); /// The target system's hostname. diff --git a/src/arch/arm/process.cc b/src/arch/arm/process.cc index cd7cc9736..702922a43 100644 --- a/src/arch/arm/process.cc +++ b/src/arch/arm/process.cc @@ -324,10 +324,10 @@ ArmLiveProcess::argsInit(int intSize, int pageSize) } ArmISA::IntReg -ArmLiveProcess::getSyscallArg(ThreadContext *tc, int i) +ArmLiveProcess::getSyscallArg(ThreadContext *tc, int &i) { assert(i < 4); - return tc->readIntReg(ArgumentReg0 + i); + return tc->readIntReg(ArgumentReg0 + i++); } void diff --git a/src/arch/arm/process.hh b/src/arch/arm/process.hh index 8954d3719..f793892d0 100644 --- a/src/arch/arm/process.hh +++ b/src/arch/arm/process.hh @@ -53,7 +53,7 @@ class ArmLiveProcess : public LiveProcess public: void argsInit(int intSize, int pageSize); - ArmISA::IntReg getSyscallArg(ThreadContext *tc, int i); + ArmISA::IntReg getSyscallArg(ThreadContext *tc, int &i); void setSyscallArg(ThreadContext *tc, int i, ArmISA::IntReg val); void setSyscallReturn(ThreadContext *tc, SyscallReturn return_value); }; diff --git a/src/arch/mips/linux/process.cc b/src/arch/mips/linux/process.cc index dde3a4efd..c2a05b73b 100644 --- a/src/arch/mips/linux/process.cc +++ b/src/arch/mips/linux/process.cc @@ -51,7 +51,8 @@ static SyscallReturn unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - TypedBufferArg name(process->getSyscallArg(tc, 0)); + int index = 0; + TypedBufferArg name(process->getSyscallArg(tc, index)); strcpy(name->sysname, "Linux"); strcpy(name->nodename,"m5.eecs.umich.edu"); @@ -70,14 +71,16 @@ static SyscallReturn sys_getsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - unsigned op = process->getSyscallArg(tc, 0); - // unsigned nbytes = process->getSyscallArg(tc, 2); + int index = 0; + unsigned op = process->getSyscallArg(tc, index); + unsigned bufPtr = process->getSyscallArg(tc, index); + // unsigned nbytes = process->getSyscallArg(tc, index); switch (op) { case 45: { // GSI_IEEE_FP_CONTROL - TypedBufferArg fpcr(process->getSyscallArg(tc, 1)); + TypedBufferArg fpcr(bufPtr); // I don't think this exactly matches the HW FPCR *fpcr = 0; fpcr.copyOut(tc->getMemPort()); @@ -97,15 +100,17 @@ static SyscallReturn sys_setsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - unsigned op = process->getSyscallArg(tc, 0); - // unsigned nbytes = process->getSyscallArg(tc, 2); + int index = 0; + unsigned op = process->getSyscallArg(tc, index); + Addr bufPtr = process->getSyscallArg(tc, index); + // unsigned nbytes = process->getSyscallArg(tc, index); switch (op) { case 14: { // SSI_IEEE_FP_CONTROL - TypedBufferArg fpcr(process->getSyscallArg(tc, 1)); + TypedBufferArg fpcr(bufPtr); // I don't think this exactly matches the HW FPCR fpcr.copyIn(tc->getMemPort()); DPRINTFR(SyscallVerbose, "sys_setsysinfo(SSI_IEEE_FP_CONTROL): " diff --git a/src/arch/mips/process.cc b/src/arch/mips/process.cc index b9f608922..d96b0c81c 100644 --- a/src/arch/mips/process.cc +++ b/src/arch/mips/process.cc @@ -147,10 +147,10 @@ MipsLiveProcess::argsInit(int intSize, int pageSize) MipsISA::IntReg -MipsLiveProcess::getSyscallArg(ThreadContext *tc, int i) +MipsLiveProcess::getSyscallArg(ThreadContext *tc, int &i) { assert(i < 6); - return tc->readIntReg(FirstArgumentReg + i); + return tc->readIntReg(FirstArgumentReg + i++); } void diff --git a/src/arch/mips/process.hh b/src/arch/mips/process.hh index b8f4de20a..f35ec8554 100644 --- a/src/arch/mips/process.hh +++ b/src/arch/mips/process.hh @@ -50,7 +50,7 @@ class MipsLiveProcess : public LiveProcess void argsInit(int intSize, int pageSize); public: - MipsISA::IntReg getSyscallArg(ThreadContext *tc, int i); + MipsISA::IntReg getSyscallArg(ThreadContext *tc, int &i); void setSyscallArg(ThreadContext *tc, int i, MipsISA::IntReg val); void setSyscallReturn(ThreadContext *tc, SyscallReturn return_value); }; diff --git a/src/arch/power/linux/process.cc b/src/arch/power/linux/process.cc index b03ccfc8c..504d0e334 100644 --- a/src/arch/power/linux/process.cc +++ b/src/arch/power/linux/process.cc @@ -52,7 +52,8 @@ static SyscallReturn unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - TypedBufferArg name(process->getSyscallArg(tc, 0)); + int index = 0; + TypedBufferArg name(process->getSyscallArg(tc, index)); strcpy(name->sysname, "Linux"); strcpy(name->nodename, "m5.eecs.umich.edu"); @@ -437,12 +438,12 @@ PowerLinuxProcess::startup() } PowerISA::IntReg -PowerLinuxProcess::getSyscallArg(ThreadContext *tc, int i) +PowerLinuxProcess::getSyscallArg(ThreadContext *tc, int &i) { // Linux apparently allows more parameter than the ABI says it should. // This limit may need to be increased even further. assert(i < 6); - return tc->readIntReg(ArgumentReg0 + i); + return tc->readIntReg(ArgumentReg0 + i++); } void diff --git a/src/arch/power/linux/process.hh b/src/arch/power/linux/process.hh index 78b0eef7f..db6759a77 100644 --- a/src/arch/power/linux/process.hh +++ b/src/arch/power/linux/process.hh @@ -46,7 +46,7 @@ class PowerLinuxProcess : public PowerLiveProcess void startup(); - PowerISA::IntReg getSyscallArg(ThreadContext *tc, int i); + PowerISA::IntReg getSyscallArg(ThreadContext *tc, int &i); void setSyscallArg(ThreadContext *tc, int i, PowerISA::IntReg val); /// Array of syscall descriptors, indexed by call number. diff --git a/src/arch/power/process.cc b/src/arch/power/process.cc index 8828a1a93..92f993e4c 100644 --- a/src/arch/power/process.cc +++ b/src/arch/power/process.cc @@ -266,10 +266,10 @@ PowerLiveProcess::argsInit(int intSize, int pageSize) } PowerISA::IntReg -PowerLiveProcess::getSyscallArg(ThreadContext *tc, int i) +PowerLiveProcess::getSyscallArg(ThreadContext *tc, int &i) { assert(i < 5); - return tc->readIntReg(ArgumentReg0 + i); + return tc->readIntReg(ArgumentReg0 + i++); } void diff --git a/src/arch/power/process.hh b/src/arch/power/process.hh index dae776c4c..ede75f05f 100644 --- a/src/arch/power/process.hh +++ b/src/arch/power/process.hh @@ -50,7 +50,7 @@ class PowerLiveProcess : public LiveProcess public: void argsInit(int intSize, int pageSize); - PowerISA::IntReg getSyscallArg(ThreadContext *tc, int i); + PowerISA::IntReg getSyscallArg(ThreadContext *tc, int &i); void setSyscallArg(ThreadContext *tc, int i, PowerISA::IntReg val); void setSyscallReturn(ThreadContext *tc, SyscallReturn return_value); }; diff --git a/src/arch/sparc/linux/syscalls.cc b/src/arch/sparc/linux/syscalls.cc index c50803976..874ddc005 100644 --- a/src/arch/sparc/linux/syscalls.cc +++ b/src/arch/sparc/linux/syscalls.cc @@ -41,7 +41,8 @@ static SyscallReturn unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - TypedBufferArg name(process->getSyscallArg(tc, 0)); + int index = 0; + TypedBufferArg name(process->getSyscallArg(tc, index)); strcpy(name->sysname, "Linux"); strcpy(name->nodename, "m5.eecs.umich.edu"); @@ -59,9 +60,10 @@ SyscallReturn getresuidFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) { const IntReg id = htog(100); - Addr ruid = p->getSyscallArg(tc, 0); - Addr euid = p->getSyscallArg(tc, 1); - Addr suid = p->getSyscallArg(tc, 2); + int index = 0; + Addr ruid = p->getSyscallArg(tc, index); + Addr euid = p->getSyscallArg(tc, index); + Addr suid = p->getSyscallArg(tc, index); //Handle the EFAULT case //Set the ruid if(ruid) diff --git a/src/arch/sparc/process.cc b/src/arch/sparc/process.cc index 89e853573..7e01f6b07 100644 --- a/src/arch/sparc/process.cc +++ b/src/arch/sparc/process.cc @@ -514,10 +514,10 @@ void Sparc64LiveProcess::flushWindows(ThreadContext *tc) } IntReg -Sparc32LiveProcess::getSyscallArg(ThreadContext *tc, int i) +Sparc32LiveProcess::getSyscallArg(ThreadContext *tc, int &i) { assert(i < 6); - return bits(tc->readIntReg(FirstArgumentReg + i), 31, 0); + return bits(tc->readIntReg(FirstArgumentReg + i++), 31, 0); } void @@ -528,10 +528,10 @@ Sparc32LiveProcess::setSyscallArg(ThreadContext *tc, int i, IntReg val) } IntReg -Sparc64LiveProcess::getSyscallArg(ThreadContext *tc, int i) +Sparc64LiveProcess::getSyscallArg(ThreadContext *tc, int &i) { assert(i < 6); - return tc->readIntReg(FirstArgumentReg + i); + return tc->readIntReg(FirstArgumentReg + i++); } void diff --git a/src/arch/sparc/process.hh b/src/arch/sparc/process.hh index fdb9734ba..cca312e0a 100644 --- a/src/arch/sparc/process.hh +++ b/src/arch/sparc/process.hh @@ -95,7 +95,7 @@ class Sparc32LiveProcess : public SparcLiveProcess void flushWindows(ThreadContext *tc); - SparcISA::IntReg getSyscallArg(ThreadContext *tc, int i); + SparcISA::IntReg getSyscallArg(ThreadContext *tc, int &i); void setSyscallArg(ThreadContext *tc, int i, SparcISA::IntReg val); }; @@ -123,7 +123,7 @@ class Sparc64LiveProcess : public SparcLiveProcess void flushWindows(ThreadContext *tc); - SparcISA::IntReg getSyscallArg(ThreadContext *tc, int i); + SparcISA::IntReg getSyscallArg(ThreadContext *tc, int &i); void setSyscallArg(ThreadContext *tc, int i, SparcISA::IntReg val); }; diff --git a/src/arch/sparc/solaris/process.cc b/src/arch/sparc/solaris/process.cc index eafb488df..24abd8687 100644 --- a/src/arch/sparc/solaris/process.cc +++ b/src/arch/sparc/solaris/process.cc @@ -48,7 +48,8 @@ static SyscallReturn unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - TypedBufferArg name(process->getSyscallArg(tc, 0)); + int index = 0; + TypedBufferArg name(process->getSyscallArg(tc, index)); strcpy(name->sysname, "SunOS"); strcpy(name->nodename, "m5.eecs.umich.edu"); diff --git a/src/arch/x86/linux/syscalls.cc b/src/arch/x86/linux/syscalls.cc index 14b3fa69b..4c29559fb 100644 --- a/src/arch/x86/linux/syscalls.cc +++ b/src/arch/x86/linux/syscalls.cc @@ -68,7 +68,8 @@ static SyscallReturn unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - TypedBufferArg name(process->getSyscallArg(tc, 0)); + int index = 0; + TypedBufferArg name(process->getSyscallArg(tc, index)); strcpy(name->sysname, "Linux"); strcpy(name->nodename, "m5.eecs.umich.edu"); @@ -94,8 +95,9 @@ archPrctlFunc(SyscallDesc *desc, int callnum, LiveProcess *process, }; //First argument is the code, second is the address - int code = process->getSyscallArg(tc, 0); - uint64_t addr = process->getSyscallArg(tc, 1); + int index = 0; + int code = process->getSyscallArg(tc, index); + uint64_t addr = process->getSyscallArg(tc, index); uint64_t fsBase, gsBase; TranslatingPort *p = tc->getMemPort(); switch(code) @@ -159,7 +161,8 @@ setThreadArea32Func(SyscallDesc *desc, int callnum, assert((maxTLSEntry + 1) * sizeof(uint64_t) <= x86lp->gdtSize()); - TypedBufferArg userDesc(process->getSyscallArg(tc, 0)); + int argIndex = 0; + TypedBufferArg userDesc(process->getSyscallArg(tc, argIndex)); TypedBufferArg gdt(x86lp->gdtStart() + minTLSEntry * sizeof(uint64_t), numTLSEntries * sizeof(uint64_t)); diff --git a/src/arch/x86/process.cc b/src/arch/x86/process.cc index f7678443d..f7b3ce24a 100644 --- a/src/arch/x86/process.cc +++ b/src/arch/x86/process.cc @@ -698,10 +698,10 @@ X86LiveProcess::setSyscallReturn(ThreadContext *tc, SyscallReturn return_value) } X86ISA::IntReg -X86_64LiveProcess::getSyscallArg(ThreadContext *tc, int i) +X86_64LiveProcess::getSyscallArg(ThreadContext *tc, int &i) { assert(i < NumArgumentRegs); - return tc->readIntReg(ArgumentReg[i]); + return tc->readIntReg(ArgumentReg[i++]); } void @@ -712,10 +712,21 @@ X86_64LiveProcess::setSyscallArg(ThreadContext *tc, int i, X86ISA::IntReg val) } X86ISA::IntReg -I386LiveProcess::getSyscallArg(ThreadContext *tc, int i) +I386LiveProcess::getSyscallArg(ThreadContext *tc, int &i) { assert(i < NumArgumentRegs32); - return tc->readIntReg(ArgumentReg32[i]); + return tc->readIntReg(ArgumentReg32[i++]); +} + +X86ISA::IntReg +I386LiveProcess::getSyscallArg(ThreadContext *tc, int &i, int width) +{ + assert(width == 32 || width == 64); + assert(i < NumArgumentRegs); + uint64_t retVal = tc->readIntReg(ArgumentReg32[i++]) & mask(32); + if (width == 64) + retVal |= ((uint64_t)tc->readIntReg(ArgumentReg[i++]) << 32); + return retVal; } void diff --git a/src/arch/x86/process.hh b/src/arch/x86/process.hh index cd6d99e66..4d031bd5a 100644 --- a/src/arch/x86/process.hh +++ b/src/arch/x86/process.hh @@ -105,7 +105,7 @@ namespace X86ISA void argsInit(int intSize, int pageSize); void startup(); - X86ISA::IntReg getSyscallArg(ThreadContext *tc, int i); + X86ISA::IntReg getSyscallArg(ThreadContext *tc, int &i); void setSyscallArg(ThreadContext *tc, int i, X86ISA::IntReg val); }; @@ -130,7 +130,8 @@ namespace X86ISA void startup(); void syscall(int64_t callnum, ThreadContext *tc); - X86ISA::IntReg getSyscallArg(ThreadContext *tc, int i); + X86ISA::IntReg getSyscallArg(ThreadContext *tc, int &i); + X86ISA::IntReg getSyscallArg(ThreadContext *tc, int &i, int width); void setSyscallArg(ThreadContext *tc, int i, X86ISA::IntReg val); }; } -- cgit v1.2.3 From cf269025f9e51eebb56d04fea6994fd72b1be4f9 Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Fri, 30 Oct 2009 12:51:13 -0400 Subject: X86: Hookup truncate/ftruncate syscalls on X86 This patch hooks up the truncate, ftruncate, truncate64 and ftruncate64 system calls on 32-bit and 64-bit X86. These have been tested on both architectures. ftruncate/ftruncate64 is needed for the f90 spec2k benchmarks. --- src/arch/x86/linux/syscalls.cc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/linux/syscalls.cc b/src/arch/x86/linux/syscalls.cc index 4c29559fb..2a7fd8d4e 100644 --- a/src/arch/x86/linux/syscalls.cc +++ b/src/arch/x86/linux/syscalls.cc @@ -307,8 +307,8 @@ SyscallDesc X86_64LinuxProcess::syscallDescs[] = { /* 73 */ SyscallDesc("flock", unimplementedFunc), /* 74 */ SyscallDesc("fsync", unimplementedFunc), /* 75 */ SyscallDesc("fdatasync", unimplementedFunc), - /* 76 */ SyscallDesc("truncate", unimplementedFunc), - /* 77 */ SyscallDesc("ftruncate", unimplementedFunc), + /* 76 */ SyscallDesc("truncate", truncateFunc), + /* 77 */ SyscallDesc("ftruncate", ftruncateFunc), /* 78 */ SyscallDesc("getdents", unimplementedFunc), /* 79 */ SyscallDesc("getcwd", unimplementedFunc), /* 80 */ SyscallDesc("chdir", unimplementedFunc), @@ -602,8 +602,8 @@ SyscallDesc I386LinuxProcess::syscallDescs[] = { /* 89 */ SyscallDesc("readdir", unimplementedFunc), /* 90 */ SyscallDesc("mmap", unimplementedFunc), /* 91 */ SyscallDesc("munmap", munmapFunc), - /* 92 */ SyscallDesc("truncate", unimplementedFunc), - /* 93 */ SyscallDesc("ftruncate", unimplementedFunc), + /* 92 */ SyscallDesc("truncate", truncateFunc), + /* 93 */ SyscallDesc("ftruncate", ftruncateFunc), /* 94 */ SyscallDesc("fchmod", unimplementedFunc), /* 95 */ SyscallDesc("fchown", unimplementedFunc), /* 96 */ SyscallDesc("getpriority", unimplementedFunc), @@ -703,8 +703,8 @@ SyscallDesc I386LinuxProcess::syscallDescs[] = { /* 190 */ SyscallDesc("vfork", unimplementedFunc), /* 191 */ SyscallDesc("ugetrlimit", unimplementedFunc), /* 192 */ SyscallDesc("mmap2", mmapFunc), - /* 193 */ SyscallDesc("truncate64", unimplementedFunc), - /* 194 */ SyscallDesc("ftruncate64", unimplementedFunc), + /* 193 */ SyscallDesc("truncate64", truncate64Func), + /* 194 */ SyscallDesc("ftruncate64", ftruncate64Func), /* 195 */ SyscallDesc("stat64", stat64Func), /* 196 */ SyscallDesc("lstat64", unimplementedFunc), /* 197 */ SyscallDesc("fstat64", fstat64Func), -- cgit v1.2.3 From b2067840a6ad7e70495ad4dc6c74bf080e68133f Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Fri, 30 Oct 2009 14:19:06 -0400 Subject: X86: Implement the X86 sse2 haddpd instruction This patch implements the haddpd instruction. It fixes the problem in the previous version (pointed out by Gabe Black) where an incorrect result would happen if you issue the instruction with the same argument twice, i.e. "haddpd %xmm0,%xmm0" This instruction is used by many spec2k benchmarks. --- src/arch/x86/isa/decoder/two_byte_opcodes.isa | 2 +- .../arithmetic/horizontal_addition.py | 22 +++++++++++++++++++++- 2 files changed, 22 insertions(+), 2 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/decoder/two_byte_opcodes.isa b/src/arch/x86/isa/decoder/two_byte_opcodes.isa index 27aabaccc..5512f417c 100644 --- a/src/arch/x86/isa/decoder/two_byte_opcodes.isa +++ b/src/arch/x86/isa/decoder/two_byte_opcodes.isa @@ -707,7 +707,7 @@ } // operand size (0x66) 0x1: decode OPCODE_OP_BOTTOM3 { - 0x4: WarnUnimpl::haddpd_Vo_Wo(); + 0x4: HADDPD(Vo,Wo); 0x5: WarnUnimpl::hsubpd_Vo_Wo(); 0x6: WarnUnimpl::movd_Ed_Vd(); 0x7: MOVDQA(Wo,Vo); diff --git a/src/arch/x86/isa/insts/simd128/floating_point/arithmetic/horizontal_addition.py b/src/arch/x86/isa/insts/simd128/floating_point/arithmetic/horizontal_addition.py index 8b307d3da..adf7650b9 100644 --- a/src/arch/x86/isa/insts/simd128/floating_point/arithmetic/horizontal_addition.py +++ b/src/arch/x86/isa/insts/simd128/floating_point/arithmetic/horizontal_addition.py @@ -55,5 +55,25 @@ microcode = ''' # HADDPS -# HADDPD + +def macroop HADDPD_XMM_XMM { + maddf ufp1, xmmh , xmml, size=8, ext=1 + maddf xmmh, xmmlm, xmmhm, size=8, ext=1 + movfp xmml, ufp1 +}; + +def macroop HADDPD_XMM_M { + ldfp ufp1, seg, sib, disp, dataSize=8 + ldfp ufp2, seg, sib, "DISPLACEMENT+8", dataSize=8 + maddf xmml, xmmh, xmml, size=8, ext=1 + maddf xmmh, ufp1, ufp2, size=8, ext=1 +}; + +def macroop HADDPD_XMM_P { + rdip t7 + ldfp ufp1, seg, riprel, disp, dataSize=8 + ldfp ufp2, seg, riprel, "DISPLACEMENT+8", dataSize=8 + maddf xmml, xmmh, xmml, size=8, ext=1 + maddf xmmh, ufp1, ufp2, size=8, ext=1 +}; ''' -- cgit v1.2.3 From 5873ec2238e521f34f7e70e6aa1b35a611225d80 Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Fri, 30 Oct 2009 15:52:33 -0400 Subject: X86: Implement movd_Vo_Edp on X86 This patch implements the movd_Vo_Edp series of instructions. It addresses various concerns by Gabe Black about which file the instruction belonged in, as well as supporting REX prefixed instructions properly. This instruction is needed for some of the spec2k benchmarks, most notably bzip2. --- src/arch/x86/isa/decoder/two_byte_opcodes.isa | 4 +-- .../insts/general_purpose/data_transfer/move.py | 30 ++++++++++++++++++++++ 2 files changed, 32 insertions(+), 2 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/decoder/two_byte_opcodes.isa b/src/arch/x86/isa/decoder/two_byte_opcodes.isa index 5512f417c..d52dfb26e 100644 --- a/src/arch/x86/isa/decoder/two_byte_opcodes.isa +++ b/src/arch/x86/isa/decoder/two_byte_opcodes.isa @@ -615,7 +615,7 @@ 0x3: PACKSSDW(Vo,Wo); 0x4: PUNPCKLQDQ(Vo,Wq); 0x5: PUNPCKHQDQ(Vo,Wq); - 0x6: WarnUnimpl::movd_Vo_Ed(); + 0x6: MOVD(Vo,Edp); 0x7: MOVDQA(Vo,Wo); } default: UD2(); @@ -709,7 +709,7 @@ 0x1: decode OPCODE_OP_BOTTOM3 { 0x4: HADDPD(Vo,Wo); 0x5: WarnUnimpl::hsubpd_Vo_Wo(); - 0x6: WarnUnimpl::movd_Ed_Vd(); + 0x6: MOVD(Edp,Vd); 0x7: MOVDQA(Wo,Vo); default: UD2(); } diff --git a/src/arch/x86/isa/insts/general_purpose/data_transfer/move.py b/src/arch/x86/isa/insts/general_purpose/data_transfer/move.py index 7ccdca6c3..7aee3fec1 100644 --- a/src/arch/x86/isa/insts/general_purpose/data_transfer/move.py +++ b/src/arch/x86/isa/insts/general_purpose/data_transfer/move.py @@ -355,6 +355,36 @@ def macroop MOVNTI_P_R { rdip t7 st reg, seg, riprel, disp }; + +def macroop MOVD_XMM_R { + mov2fp xmml, regm, srcSize=dsz, destSize=dsz + lfpimm xmmh, 0 +}; + +def macroop MOVD_XMM_M { + ldfp xmml, seg, sib, disp, dataSize=dsz + lfpimm xmmh, 0 +}; + +def macroop MOVD_XMM_P { + rdip t7 + ldfp xmml, seg, riprel, disp, dataSize=dsz + lfpimm xmmh, 0 +}; + +def macroop MOVD_R_XMM { + mov2int reg, xmml, size=dsz +}; + +def macroop MOVD_M_XMM { + stfp xmml, seg, sib, disp, dataSize=dsz +}; + +def macroop MOVD_P_XMM { + rdip t7 + stfp xmml, seg, riprel, disp, dataSize=dsz +}; + ''' #let {{ # class MOVD(Inst): -- cgit v1.2.3 From a12557439ba0297fefb558b34ecc761d2bc34017 Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Fri, 30 Oct 2009 12:49:37 -0400 Subject: X86: Add support for x86 psrldq and pslldq instructions These are complicated instructions and the micro-code might be suboptimal. This has been tested with some small sample programs (attached) The psrldq instruction is needed by various spec2k programs. --- src/arch/x86/isa/decoder/two_byte_opcodes.isa | 4 +-- .../simd128/integer/shift/left_logical_shift.py | 40 +++++++++++++++++++++- .../simd128/integer/shift/right_logical_shift.py | 38 +++++++++++++++++++- 3 files changed, 78 insertions(+), 4 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/decoder/two_byte_opcodes.isa b/src/arch/x86/isa/decoder/two_byte_opcodes.isa index d52dfb26e..288c5e5a8 100644 --- a/src/arch/x86/isa/decoder/two_byte_opcodes.isa +++ b/src/arch/x86/isa/decoder/two_byte_opcodes.isa @@ -673,9 +673,9 @@ //0x3: group14_pshimq(); 0x3: decode MODRM_REG { 0x2: PSRLQ(VRo,Ib); - 0x3: WarnUnimpl::psrldq_VRo_Ib(); + 0x3: PSRLDQ(VRo,Ib); 0x6: PSLLQ(VRo,Ib); - 0x7: WarnUnimpl::pslldq_VRo_Ib(); + 0x7: PSLLDQ(VRo,Ib); default: UD2(); } 0x4: PCMPEQB(Vo,Wo); diff --git a/src/arch/x86/isa/insts/simd128/integer/shift/left_logical_shift.py b/src/arch/x86/isa/insts/simd128/integer/shift/left_logical_shift.py index 617033bc0..c13c7064c 100644 --- a/src/arch/x86/isa/insts/simd128/integer/shift/left_logical_shift.py +++ b/src/arch/x86/isa/insts/simd128/integer/shift/left_logical_shift.py @@ -122,5 +122,43 @@ def macroop PSLLQ_XMM_I { mslli xmml, xmml, imm, size=8, ext=0 mslli xmmh, xmmh, imm, size=8, ext=0 }; + +def macroop PSLLDQ_XMM_I { + + limm t2, 8 + subi t1, t2, imm, flags=(ECF,), dataSize=1 + br label("pslldq_less_8"), flags=(nCECF,) + + # Greater than 8 + + limm t2, 16 + subi t1, t2, imm, flags=(ECF,), dataSize=1 + br label("pslldq_less_16"), flags=(nCECF,) + + # Greater than 16 + + lfpimm xmml, 0 + lfpimm xmmh, 0 + br label("pslldq_end") + +pslldq_less_16: + + # Between 8 and 16 + + mslli xmmh, xmml, "(IMMEDIATE-8)<<3", size=8, ext=0 + lfpimm xmml, 0 + br label("pslldq_end") + +pslldq_less_8: + + # Less than 8 + + msrli ufp1, xmml, "(8-IMMEDIATE) << 3", size=8, ext=0 + mslli xmmh, xmmh, "IMMEDIATE << 3", size=8, ext=0 + mslli xmml, xmml, "IMMEDIATE << 3", size=8, ext=0 + mor xmmh, xmmh, ufp1 + +pslldq_end: + fault "NoFault" +}; ''' -# PSLLDQ diff --git a/src/arch/x86/isa/insts/simd128/integer/shift/right_logical_shift.py b/src/arch/x86/isa/insts/simd128/integer/shift/right_logical_shift.py index c904eaf50..61efe1a5d 100644 --- a/src/arch/x86/isa/insts/simd128/integer/shift/right_logical_shift.py +++ b/src/arch/x86/isa/insts/simd128/integer/shift/right_logical_shift.py @@ -122,5 +122,41 @@ def macroop PSRLQ_XMM_I { msrli xmml, xmml, imm, size=8, ext=0 msrli xmmh, xmmh, imm, size=8, ext=0 }; + +def macroop PSRLDQ_XMM_I { + limm t2, 8 + subi t1, t2, imm, flags=(ECF,), dataSize=1 + br label("psrldq_less_8"), flags=(nCECF,) + # Greater than 8 + + limm t2, 16 + subi t1, t2, imm, flags=(ECF,), dataSize=1 + br label("psrldq_less_16"), flags=(nCECF,) + + # Greater than 16 + + lfpimm xmml, 0 + lfpimm xmmh, 0 + br label("psrldq_end") + +psrldq_less_16: + + # Between 8 and 16 + + msrli xmml, xmmh, "(IMMEDIATE-8)<<3", size=8, ext=0 + lfpimm xmmh, 0 + br label("psrldq_end") + +psrldq_less_8: + + # Less than 8 + + mslli ufp1, xmmh, "(8-IMMEDIATE) << 3", size=8, ext=0 + msrli xmml, xmml, "IMMEDIATE << 3", size=8, ext=0 + msrli xmmh, xmmh, "IMMEDIATE << 3", size=8, ext=0 + mor xmml, xmml, ufp1 + +psrldq_end: + fault "NoFault" +}; ''' -# PSRLDQ -- cgit v1.2.3 From 9b0a747dd41d3383769be1cd737733902875a528 Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Wed, 4 Nov 2009 00:19:15 -0500 Subject: X86: Hook up time syscall on X86 This has been tested and verified that it works. --- src/arch/x86/linux/syscalls.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/linux/syscalls.cc b/src/arch/x86/linux/syscalls.cc index 2a7fd8d4e..6a659108f 100644 --- a/src/arch/x86/linux/syscalls.cc +++ b/src/arch/x86/linux/syscalls.cc @@ -432,7 +432,7 @@ SyscallDesc X86_64LinuxProcess::syscallDescs[] = { /* 198 */ SyscallDesc("lremovexattr", unimplementedFunc), /* 199 */ SyscallDesc("fremovexattr", unimplementedFunc), /* 200 */ SyscallDesc("tkill", unimplementedFunc), - /* 201 */ SyscallDesc("time", unimplementedFunc), + /* 201 */ SyscallDesc("time", timeFunc), /* 202 */ SyscallDesc("futex", ignoreFunc), /* 203 */ SyscallDesc("sched_setaffinity", unimplementedFunc), /* 204 */ SyscallDesc("sched_getaffinity", unimplementedFunc), @@ -523,7 +523,7 @@ SyscallDesc I386LinuxProcess::syscallDescs[] = { /* 10 */ SyscallDesc("unlink", unimplementedFunc), /* 11 */ SyscallDesc("execve", unimplementedFunc), /* 12 */ SyscallDesc("chdir", unimplementedFunc), - /* 13 */ SyscallDesc("time", unimplementedFunc), + /* 13 */ SyscallDesc("time", timeFunc), /* 14 */ SyscallDesc("mknod", unimplementedFunc), /* 15 */ SyscallDesc("chmod", unimplementedFunc), /* 16 */ SyscallDesc("lchown", unimplementedFunc), -- cgit v1.2.3 From a1042db29098da395d0de96c652c41904feb425a Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Wed, 4 Nov 2009 00:47:12 -0500 Subject: X86: Enable x86_64 vsyscall support 64-bit vsyscall is different than 32-bit. There are only two syscalls, time and gettimeofday. On a real system, there is complicated code that implements these without entering the kernel. That would be complicated to implement in m5. Instead we just place code that calls the regular syscalls (this is how tools such as valgrind handle this case). This is needed for the perlbmk spec2k benchmark. --- src/arch/x86/process.cc | 24 ++++++++++++++++++++++++ src/arch/x86/process.hh | 10 ++++++++++ 2 files changed, 34 insertions(+) (limited to 'src/arch') diff --git a/src/arch/x86/process.cc b/src/arch/x86/process.cc index f7b3ce24a..7cc889d7c 100644 --- a/src/arch/x86/process.cc +++ b/src/arch/x86/process.cc @@ -139,6 +139,12 @@ X86_64LiveProcess::X86_64LiveProcess(LiveProcessParams *params, int _numSyscallDescs) : X86LiveProcess(params, objFile, _syscallDescs, _numSyscallDescs) { + + vsyscallPage.base = 0xffffffffff600000ULL; + vsyscallPage.size = VMPageSize; + vsyscallPage.vtimeOffset = 0x400; + vsyscallPage.vgettimeofdayOffset = 0x410; + // Set up stack. On X86_64 Linux, stack goes from the top of memory // downward, less the hole for the kernel address space plus one page // for undertermined purposes. @@ -205,6 +211,24 @@ X86_64LiveProcess::startup() argsInit(sizeof(uint64_t), VMPageSize); + // Set up the vsyscall page for this process. + pTable->allocate(vsyscallPage.base, vsyscallPage.size); + uint8_t vtimeBlob[] = { + 0x48,0xc7,0xc0,0xc9,0x00,0x00,0x00, // mov $0xc9,%rax + 0x0f,0x05, // syscall + 0xc3 // retq + }; + initVirtMem->writeBlob(vsyscallPage.base + vsyscallPage.vtimeOffset, + vtimeBlob, sizeof(vtimeBlob)); + + uint8_t vgettimeofdayBlob[] = { + 0x48,0xc7,0xc0,0x60,0x00,0x00,0x00, // mov $0x60,%rax + 0x0f,0x05, // syscall + 0xc3 // retq + }; + initVirtMem->writeBlob(vsyscallPage.base + vsyscallPage.vgettimeofdayOffset, + vgettimeofdayBlob, sizeof(vgettimeofdayBlob)); + for (int i = 0; i < contextIds.size(); i++) { ThreadContext * tc = system->getThreadContext(contextIds[i]); diff --git a/src/arch/x86/process.hh b/src/arch/x86/process.hh index 4d031bd5a..3ad2abe08 100644 --- a/src/arch/x86/process.hh +++ b/src/arch/x86/process.hh @@ -101,6 +101,16 @@ namespace X86ISA X86_64LiveProcess(LiveProcessParams *params, ObjectFile *objFile, SyscallDesc *_syscallDescs, int _numSyscallDescs); + class VSyscallPage + { + public: + Addr base; + Addr size; + Addr vtimeOffset; + Addr vgettimeofdayOffset; + }; + VSyscallPage vsyscallPage; + public: void argsInit(int intSize, int pageSize); void startup(); -- cgit v1.2.3 From 2c5fe6f95e64a5a97d56cccc6b8b5417cdd981ae Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Wed, 4 Nov 2009 16:57:01 -0800 Subject: build: fix compile problems pointed out by gcc 4.4 --- src/arch/arm/insts/static_inst.cc | 9 +++++---- src/arch/mips/dsp.cc | 4 +++- src/arch/x86/interrupts.cc | 2 +- src/arch/x86/isa.cc | 2 +- src/arch/x86/system.cc | 2 +- 5 files changed, 11 insertions(+), 8 deletions(-) (limited to 'src/arch') diff --git a/src/arch/arm/insts/static_inst.cc b/src/arch/arm/insts/static_inst.cc index df2d5de25..5181041d0 100644 --- a/src/arch/arm/insts/static_inst.cc +++ b/src/arch/arm/insts/static_inst.cc @@ -29,6 +29,7 @@ #include "arch/arm/insts/static_inst.hh" #include "base/condcodes.hh" +#include "base/cprintf.hh" #include "base/loader/symtab.hh" namespace ArmISA @@ -62,7 +63,7 @@ ArmStaticInst::shift_rm_imm(uint32_t base, uint32_t shamt, else return (base << (32 - shamt)) | (base >> shamt); default: - fprintf(stderr, "Unhandled shift type\n"); + ccprintf(std::cerr, "Unhandled shift type\n"); exit(1); break; } @@ -101,7 +102,7 @@ ArmStaticInst::shift_rm_rs(uint32_t base, uint32_t shamt, else return (base << (32 - shamt)) | (base >> shamt); default: - fprintf(stderr, "Unhandled shift type\n"); + ccprintf(std::cerr, "Unhandled shift type\n"); exit(1); break; } @@ -141,7 +142,7 @@ ArmStaticInst::shift_carry_imm(uint32_t base, uint32_t shamt, else return (base >> (shamt - 1)) & 1; default: - fprintf(stderr, "Unhandled shift type\n"); + ccprintf(std::cerr, "Unhandled shift type\n"); exit(1); break; } @@ -182,7 +183,7 @@ ArmStaticInst::shift_carry_rs(uint32_t base, uint32_t shamt, shamt = 32; return (base >> (shamt - 1)) & 1; default: - fprintf(stderr, "Unhandled shift type\n"); + ccprintf(std::cerr, "Unhandled shift type\n"); exit(1); break; } diff --git a/src/arch/mips/dsp.cc b/src/arch/mips/dsp.cc index 6e4f7afea..b8b02ae9e 100755 --- a/src/arch/mips/dsp.cc +++ b/src/arch/mips/dsp.cc @@ -463,6 +463,8 @@ MipsISA::dspMuleq(int32_t a, int32_t b, int32_t mode, uint32_t *dspctl) uint64_t b_values[SIMD_MAX_VALS]; uint64_t c_values[SIMD_MAX_VALS]; + memset(c_values, 0, sizeof(c_values)); + simdUnpack(a, a_values, SIMD_FMT_PH, SIGNED); simdUnpack(b, b_values, SIMD_FMT_PH, SIGNED); @@ -743,7 +745,7 @@ MipsISA::dspMulsaq(int64_t dspac, int32_t a, int32_t b, int32_t ac, int nvals = SIMD_NVALS[fmt]; uint64_t a_values[SIMD_MAX_VALS]; uint64_t b_values[SIMD_MAX_VALS]; - int64_t temp[2]; + int64_t temp[2] = {0, 0}; uint32_t ouflag = 0; simdUnpack(a, a_values, fmt, SIGNED); diff --git a/src/arch/x86/interrupts.cc b/src/arch/x86/interrupts.cc index 1b7933036..1b83c6649 100644 --- a/src/arch/x86/interrupts.cc +++ b/src/arch/x86/interrupts.cc @@ -500,7 +500,7 @@ X86ISA::Interrupts::setReg(ApicRegIndex reg, uint32_t val) InterruptCommandRegHigh high = regs[APIC_INTERRUPT_COMMAND_HIGH]; // Record that an IPI is being sent. low.deliveryStatus = 1; - TriggerIntMessage message; + TriggerIntMessage message = 0; message.destination = high.destination; message.vector = low.vector; message.deliveryMode = low.deliveryMode; diff --git a/src/arch/x86/isa.cc b/src/arch/x86/isa.cc index 06a656efc..47d24ed1e 100644 --- a/src/arch/x86/isa.cc +++ b/src/arch/x86/isa.cc @@ -41,7 +41,7 @@ void ISA::updateHandyM5Reg(Efer efer, CR0 cr0, SegAttr csAttr, SegAttr ssAttr, RFLAGS rflags) { - HandyM5Reg m5reg; + HandyM5Reg m5reg = 0; if (efer.lma) { m5reg.mode = LongMode; if (csAttr.longMode) diff --git a/src/arch/x86/system.cc b/src/arch/x86/system.cc index 1594cc375..31183f2f9 100644 --- a/src/arch/x86/system.cc +++ b/src/arch/x86/system.cc @@ -211,7 +211,7 @@ X86System::startup() numGDTEntries++; - SegSelector ds; + SegSelector ds = 0; ds.si = numGDTEntries - 1; tc->setMiscReg(MISCREG_DS, (MiscReg)ds); -- cgit v1.2.3 From 5cf2e7ccf027a485c2e2eb9a60b70c3b45853f0c Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Wed, 4 Nov 2009 13:22:15 -0500 Subject: X86: Fix problem with movhps instruction This problem is like the one fixed with movhpd a few weeks ago. A +8 displacement is used to access memory when there should be none. This fix is needed for the perlbmk spec2k benchmark to run. --- .../x86/isa/insts/simd128/floating_point/data_transfer/move.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/insts/simd128/floating_point/data_transfer/move.py b/src/arch/x86/isa/insts/simd128/floating_point/data_transfer/move.py index ffe084786..86ac89ade 100644 --- a/src/arch/x86/isa/insts/simd128/floating_point/data_transfer/move.py +++ b/src/arch/x86/isa/insts/simd128/floating_point/data_transfer/move.py @@ -168,22 +168,21 @@ def macroop MOVUPD_P_XMM { }; def macroop MOVHPS_XMM_M { - ldfp xmmh, seg, sib, "DISPLACEMENT + 8", dataSize=8 + ldfp xmmh, seg, sib, disp, dataSize=8 }; def macroop MOVHPS_XMM_P { rdip t7 - ldfp xmmh, seg, riprel, "DISPLACEMENT + 8", dataSize=8 + ldfp xmmh, seg, riprel, disp, dataSize=8 }; def macroop MOVHPS_M_XMM { - stfp xmmh, seg, sib, "DISPLACEMENT + 8", dataSize=8 + stfp xmmh, seg, sib, disp, dataSize=8 }; def macroop MOVHPS_P_XMM { rdip t7 - stfp xmml, seg, riprel, "DISPLACEMENT", dataSize=8 - stfp xmmh, seg, riprel, "DISPLACEMENT + 8", dataSize=8 + stfp xmmh, seg, riprel, disp, dataSize=8 }; def macroop MOVHPD_XMM_M { -- cgit v1.2.3 From 18b21c1ecaf7858c592c56cf4c12ec8781f821ba Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sat, 7 Nov 2009 22:34:33 -0800 Subject: ARM: Get rid of some unneeded register indexes. --- src/arch/arm/registers.hh | 30 ------------------------------ 1 file changed, 30 deletions(-) (limited to 'src/arch') diff --git a/src/arch/arm/registers.hh b/src/arch/arm/registers.hh index 7f9b6b828..07af32c1e 100644 --- a/src/arch/arm/registers.hh +++ b/src/arch/arm/registers.hh @@ -77,7 +77,6 @@ const int ReturnAddressReg = 14; const int PCReg = 15; const int ZeroReg = NumIntArchRegs; -const int AddrReg = ZeroReg + 1; // Used to generate address for uops const int SyscallNumReg = ReturnValueReg; const int SyscallPseudoReturnReg = ReturnValueReg; @@ -116,35 +115,6 @@ enum FCSRFields { Cause_Field = 11 }; -enum MiscIntRegNums { - zero_reg = NumIntArchRegs, - addr_reg, - - rhi, - rlo, - - r8_fiq, /* FIQ mode register bank */ - r9_fiq, - r10_fiq, - r11_fiq, - r12_fiq, - - r13_fiq, /* FIQ mode SP and LR */ - r14_fiq, - - r13_irq, /* IRQ mode SP and LR */ - r14_irq, - - r13_svc, /* SVC mode SP and LR */ - r14_svc, - - r13_undef, /* UNDEF mode SP and LR */ - r14_undef, - - r13_abt, /* ABT mode SP and LR */ - r14_abt -}; - } // namespace ArmISA #endif -- cgit v1.2.3 From 4a454c4f47362bd6f842fe1919f959a672ab1bb4 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 8 Nov 2009 00:07:35 -0800 Subject: ARM: Set up an intregs.hh for ARM. Add constants for all the modes and registers, maps for aliasing, functions that use the maps and range check, and use a named constant instead of a magic number for the microcode register. --- src/arch/arm/intregs.hh | 326 ++++++++++++++++++++++++++++++++++ src/arch/arm/isa/formats/macromem.isa | 10 +- src/arch/arm/registers.hh | 14 +- 3 files changed, 339 insertions(+), 11 deletions(-) create mode 100644 src/arch/arm/intregs.hh (limited to 'src/arch') diff --git a/src/arch/arm/intregs.hh b/src/arch/arm/intregs.hh new file mode 100644 index 000000000..191965c55 --- /dev/null +++ b/src/arch/arm/intregs.hh @@ -0,0 +1,326 @@ +/* + * Copyright (c) 2009 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Gabe Black + */ + +#include + +#ifndef __ARCH_ARM_INTREGS_HH__ +#define __ARCH_ARM_INTREGS_HH__ + +namespace ArmISA +{ + +enum IntRegIndex +{ + /* All the unique register indices. */ + INTREG_R0, + INTREG_R1, + INTREG_R2, + INTREG_R3, + INTREG_R4, + INTREG_R5, + INTREG_R6, + INTREG_R7, + INTREG_R8, + INTREG_R9, + INTREG_R10, + INTREG_R11, + INTREG_R12, + INTREG_R13, + INTREG_SP = INTREG_R13, + INTREG_R14, + INTREG_LR = INTREG_R14, + INTREG_R15, + INTREG_PC = INTREG_R15, + + INTREG_R13_SVC, + INTREG_SP_SVC = INTREG_R13_SVC, + INTREG_R14_SVC, + INTREG_LR_SVC = INTREG_R14_SVC, + INTREG_R15_SVC = INTREG_R15, + + INTREG_R13_MON, + INTREG_SP_MON = INTREG_R13_MON, + INTREG_R14_MON, + INTREG_LR_MON = INTREG_R14_MON, + INTREG_R15_MON = INTREG_R15, + + INTREG_R13_ABT, + INTREG_SP_ABT = INTREG_R13_ABT, + INTREG_R14_ABT, + INTREG_LR_ABT = INTREG_R14_ABT, + INTREG_R15_ABT = INTREG_R15, + + INTREG_R13_UND, + INTREG_SP_UND = INTREG_R13_UND, + INTREG_R14_UND, + INTREG_LR_UND = INTREG_R14_UND, + INTREG_R15_UND = INTREG_R15, + + INTREG_R13_IRQ, + INTREG_SP_IRQ = INTREG_R13_IRQ, + INTREG_R14_IRQ, + INTREG_LR_IRQ = INTREG_R14_IRQ, + INTREG_R15_IRQ = INTREG_R15, + + INTREG_R8_FIQ, + INTREG_R9_FIQ, + INTREG_R10_FIQ, + INTREG_R11_FIQ, + INTREG_R12_FIQ, + INTREG_R13_FIQ, + INTREG_SP_FIQ = INTREG_R13_FIQ, + INTREG_R14_FIQ, + INTREG_LR_FIQ = INTREG_R14_FIQ, + INTREG_R15_FIQ = INTREG_R15, + + INTREG_ZERO, // Dummy zero reg since there has to be one. + INTREG_UREG0, + + NUM_INTREGS, + NUM_ARCH_INTREGS = INTREG_PC + 1, + + /* All the aliased indexes. */ + + /* USR mode */ + INTREG_R0_USR = INTREG_R0, + INTREG_R1_USR = INTREG_R1, + INTREG_R2_USR = INTREG_R2, + INTREG_R3_USR = INTREG_R3, + INTREG_R4_USR = INTREG_R4, + INTREG_R5_USR = INTREG_R5, + INTREG_R6_USR = INTREG_R6, + INTREG_R7_USR = INTREG_R7, + INTREG_R8_USR = INTREG_R8, + INTREG_R9_USR = INTREG_R9, + INTREG_R10_USR = INTREG_R10, + INTREG_R11_USR = INTREG_R11, + INTREG_R12_USR = INTREG_R12, + INTREG_R13_USR = INTREG_R13, + INTREG_SP_USR = INTREG_SP, + INTREG_R14_USR = INTREG_R14, + INTREG_LR_USR = INTREG_LR, + INTREG_R15_USR = INTREG_R15, + INTREG_PC_USR = INTREG_PC, + + /* SVC mode */ + INTREG_R0_SVC = INTREG_R0, + INTREG_R1_SVC = INTREG_R1, + INTREG_R2_SVC = INTREG_R2, + INTREG_R3_SVC = INTREG_R3, + INTREG_R4_SVC = INTREG_R4, + INTREG_R5_SVC = INTREG_R5, + INTREG_R6_SVC = INTREG_R6, + INTREG_R7_SVC = INTREG_R7, + INTREG_R8_SVC = INTREG_R8, + INTREG_R9_SVC = INTREG_R9, + INTREG_R10_SVC = INTREG_R10, + INTREG_R11_SVC = INTREG_R11, + INTREG_R12_SVC = INTREG_R12, + INTREG_PC_SVC = INTREG_PC, + + /* MON mode */ + INTREG_R0_MON = INTREG_R0, + INTREG_R1_MON = INTREG_R1, + INTREG_R2_MON = INTREG_R2, + INTREG_R3_MON = INTREG_R3, + INTREG_R4_MON = INTREG_R4, + INTREG_R5_MON = INTREG_R5, + INTREG_R6_MON = INTREG_R6, + INTREG_R7_MON = INTREG_R7, + INTREG_R8_MON = INTREG_R8, + INTREG_R9_MON = INTREG_R9, + INTREG_R10_MON = INTREG_R10, + INTREG_R11_MON = INTREG_R11, + INTREG_R12_MON = INTREG_R12, + INTREG_PC_MON = INTREG_PC, + + /* ABT mode */ + INTREG_R0_ABT = INTREG_R0, + INTREG_R1_ABT = INTREG_R1, + INTREG_R2_ABT = INTREG_R2, + INTREG_R3_ABT = INTREG_R3, + INTREG_R4_ABT = INTREG_R4, + INTREG_R5_ABT = INTREG_R5, + INTREG_R6_ABT = INTREG_R6, + INTREG_R7_ABT = INTREG_R7, + INTREG_R8_ABT = INTREG_R8, + INTREG_R9_ABT = INTREG_R9, + INTREG_R10_ABT = INTREG_R10, + INTREG_R11_ABT = INTREG_R11, + INTREG_R12_ABT = INTREG_R12, + INTREG_PC_ABT = INTREG_PC, + + /* UND mode */ + INTREG_R0_UND = INTREG_R0, + INTREG_R1_UND = INTREG_R1, + INTREG_R2_UND = INTREG_R2, + INTREG_R3_UND = INTREG_R3, + INTREG_R4_UND = INTREG_R4, + INTREG_R5_UND = INTREG_R5, + INTREG_R6_UND = INTREG_R6, + INTREG_R7_UND = INTREG_R7, + INTREG_R8_UND = INTREG_R8, + INTREG_R9_UND = INTREG_R9, + INTREG_R10_UND = INTREG_R10, + INTREG_R11_UND = INTREG_R11, + INTREG_R12_UND = INTREG_R12, + INTREG_PC_UND = INTREG_PC, + + /* IRQ mode */ + INTREG_R0_IRQ = INTREG_R0, + INTREG_R1_IRQ = INTREG_R1, + INTREG_R2_IRQ = INTREG_R2, + INTREG_R3_IRQ = INTREG_R3, + INTREG_R4_IRQ = INTREG_R4, + INTREG_R5_IRQ = INTREG_R5, + INTREG_R6_IRQ = INTREG_R6, + INTREG_R7_IRQ = INTREG_R7, + INTREG_R8_IRQ = INTREG_R8, + INTREG_R9_IRQ = INTREG_R9, + INTREG_R10_IRQ = INTREG_R10, + INTREG_R11_IRQ = INTREG_R11, + INTREG_R12_IRQ = INTREG_R12, + INTREG_PC_IRQ = INTREG_PC, + + /* FIQ mode */ + INTREG_R0_FIQ = INTREG_R0, + INTREG_R1_FIQ = INTREG_R1, + INTREG_R2_FIQ = INTREG_R2, + INTREG_R3_FIQ = INTREG_R3, + INTREG_R4_FIQ = INTREG_R4, + INTREG_R5_FIQ = INTREG_R5, + INTREG_R6_FIQ = INTREG_R6, + INTREG_R7_FIQ = INTREG_R7, + INTREG_PC_FIQ = INTREG_PC, +}; + +typedef IntRegIndex IntRegMap[NUM_ARCH_INTREGS]; + +const IntRegMap IntRegUsrMap = { + INTREG_R0_USR, INTREG_R1_USR, INTREG_R2_USR, INTREG_R3_USR, + INTREG_R4_USR, INTREG_R5_USR, INTREG_R6_USR, INTREG_R7_USR, + INTREG_R8_USR, INTREG_R9_USR, INTREG_R10_USR, INTREG_R11_USR, + INTREG_R12_USR, INTREG_R13_USR, INTREG_R14_USR, INTREG_R15_USR +}; + +static inline IntRegIndex +INTREG_USR(unsigned index) +{ + assert(index < NUM_ARCH_INTREGS); + return IntRegUsrMap[index]; +} + +const IntRegMap IntRegSvcMap = { + INTREG_R0_SVC, INTREG_R1_SVC, INTREG_R2_SVC, INTREG_R3_SVC, + INTREG_R4_SVC, INTREG_R5_SVC, INTREG_R6_SVC, INTREG_R7_SVC, + INTREG_R8_SVC, INTREG_R9_SVC, INTREG_R10_SVC, INTREG_R11_SVC, + INTREG_R12_SVC, INTREG_R13_SVC, INTREG_R14_SVC, INTREG_R15_SVC +}; + +static inline IntRegIndex +INTREG_SVC(unsigned index) +{ + assert(index < NUM_ARCH_INTREGS); + return IntRegSvcMap[index]; +} + +const IntRegMap IntRegMonMap = { + INTREG_R0_MON, INTREG_R1_MON, INTREG_R2_MON, INTREG_R3_MON, + INTREG_R4_MON, INTREG_R5_MON, INTREG_R6_MON, INTREG_R7_MON, + INTREG_R8_MON, INTREG_R9_MON, INTREG_R10_MON, INTREG_R11_MON, + INTREG_R12_MON, INTREG_R13_MON, INTREG_R14_MON, INTREG_R15_MON +}; + +static inline IntRegIndex +INTREG_MON(unsigned index) +{ + assert(index < NUM_ARCH_INTREGS); + return IntRegMonMap[index]; +} + +const IntRegMap IntRegAbtMap = { + INTREG_R0_ABT, INTREG_R1_ABT, INTREG_R2_ABT, INTREG_R3_ABT, + INTREG_R4_ABT, INTREG_R5_ABT, INTREG_R6_ABT, INTREG_R7_ABT, + INTREG_R8_ABT, INTREG_R9_ABT, INTREG_R10_ABT, INTREG_R11_ABT, + INTREG_R12_ABT, INTREG_R13_ABT, INTREG_R14_ABT, INTREG_R15_ABT +}; + +static inline IntRegIndex +INTREG_ABT(unsigned index) +{ + assert(index < NUM_ARCH_INTREGS); + return IntRegAbtMap[index]; +} + +const IntRegMap IntRegUndMap = { + INTREG_R0_UND, INTREG_R1_UND, INTREG_R2_UND, INTREG_R3_UND, + INTREG_R4_UND, INTREG_R5_UND, INTREG_R6_UND, INTREG_R7_UND, + INTREG_R8_UND, INTREG_R9_UND, INTREG_R10_UND, INTREG_R11_UND, + INTREG_R12_UND, INTREG_R13_UND, INTREG_R14_UND, INTREG_R15_UND +}; + +static inline IntRegIndex +INTREG_UND(unsigned index) +{ + assert(index < NUM_ARCH_INTREGS); + return IntRegUndMap[index]; +} + +const IntRegMap IntRegIrqMap = { + INTREG_R0_IRQ, INTREG_R1_IRQ, INTREG_R2_IRQ, INTREG_R3_IRQ, + INTREG_R4_IRQ, INTREG_R5_IRQ, INTREG_R6_IRQ, INTREG_R7_IRQ, + INTREG_R8_IRQ, INTREG_R9_IRQ, INTREG_R10_IRQ, INTREG_R11_IRQ, + INTREG_R12_IRQ, INTREG_R13_IRQ, INTREG_R14_IRQ, INTREG_R15_IRQ +}; + +static inline IntRegIndex +INTREG_IRQ(unsigned index) +{ + assert(index < NUM_ARCH_INTREGS); + return IntRegIrqMap[index]; +} + +const IntRegMap IntRegFiqMap = { + INTREG_R0_FIQ, INTREG_R1_FIQ, INTREG_R2_FIQ, INTREG_R3_FIQ, + INTREG_R4_FIQ, INTREG_R5_FIQ, INTREG_R6_FIQ, INTREG_R7_FIQ, + INTREG_R8_FIQ, INTREG_R9_FIQ, INTREG_R10_FIQ, INTREG_R11_FIQ, + INTREG_R12_FIQ, INTREG_R13_FIQ, INTREG_R14_FIQ, INTREG_R15_FIQ +}; + +static inline IntRegIndex +INTREG_FIQ(unsigned index) +{ + assert(index < NUM_ARCH_INTREGS); + return IntRegFiqMap[index]; +} + +} + +#endif diff --git a/src/arch/arm/isa/formats/macromem.isa b/src/arch/arm/isa/formats/macromem.isa index 355a67ea9..d978967ac 100644 --- a/src/arch/arm/isa/formats/macromem.isa +++ b/src/arch/arm/isa/formats/macromem.isa @@ -213,9 +213,9 @@ inline %(class_name)s::%(class_name)s(ExtMachInst machInst) break; } - // Add 0 to Rn and stick it in Raddr (register 17). + // Add 0 to Rn and stick it in ureg0. // This is equivalent to a move. - microOps[0] = new MicroAddiUop(machInst, 17, RN, 0); + microOps[0] = new MicroAddiUop(machInst, INTREG_UREG0, RN, 0); unsigned j = 0; for (int i = 1; i < ones+1; i++) { @@ -225,9 +225,11 @@ inline %(class_name)s::%(class_name)s(ExtMachInst machInst) regs_to_handle &= ~(1< Date: Sun, 8 Nov 2009 00:07:49 -0800 Subject: ARM: Implement the shadow registers using register flattening. --- src/arch/arm/isa.hh | 43 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 2 deletions(-) (limited to 'src/arch') diff --git a/src/arch/arm/isa.hh b/src/arch/arm/isa.hh index 9b21c03cd..1ad5428e5 100644 --- a/src/arch/arm/isa.hh +++ b/src/arch/arm/isa.hh @@ -44,14 +44,44 @@ namespace ArmISA { protected: MiscReg miscRegs[NumMiscRegs]; + const IntRegIndex *intRegMap; + + void + updateRegMap(CPSR cpsr) + { + switch (cpsr.mode) { + case MODE_USER: + case MODE_SYSTEM: + intRegMap = IntRegUsrMap; + break; + case MODE_FIQ: + intRegMap = IntRegFiqMap; + break; + case MODE_IRQ: + intRegMap = IntRegIrqMap; + break; + case MODE_SVC: + intRegMap = IntRegSvcMap; + break; + case MODE_ABORT: + intRegMap = IntRegAbtMap; + break; + case MODE_UNDEFINED: + intRegMap = IntRegUndMap; + break; + default: + panic("Unrecognized mode setting in CPSR.\n"); + } + } public: void clear() { memset(miscRegs, 0, sizeof(miscRegs)); CPSR cpsr = 0; - cpsr.mode = MODE_USER; + cpsr.mode = MODE_SYSTEM; miscRegs[MISCREG_CPSR] = cpsr; + updateRegMap(cpsr); //XXX We need to initialize the rest of the state. } @@ -79,6 +109,9 @@ namespace ArmISA void setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc) { + if (misc_reg == MISCREG_CPSR) { + updateRegMap(val); + } assert(misc_reg < NumMiscRegs); miscRegs[misc_reg] = val; } @@ -86,7 +119,13 @@ namespace ArmISA int flattenIntIndex(int reg) { - return reg; + assert(reg >= 0); + if (reg < NUM_ARCH_INTREGS) { + return intRegMap[reg]; + } else { + assert(reg < NUM_INTREGS); + return reg; + } } int -- cgit v1.2.3 From 43e9209c218daf506b6c2580e689e297c48e8f48 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 8 Nov 2009 00:54:32 -0800 Subject: ARM: Initialize processes in user mode. I accidentally left in a change to test using int registers in system mode. This change reverts that. --- src/arch/arm/isa.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/arch') diff --git a/src/arch/arm/isa.hh b/src/arch/arm/isa.hh index 1ad5428e5..6341e6cd0 100644 --- a/src/arch/arm/isa.hh +++ b/src/arch/arm/isa.hh @@ -79,7 +79,7 @@ namespace ArmISA { memset(miscRegs, 0, sizeof(miscRegs)); CPSR cpsr = 0; - cpsr.mode = MODE_SYSTEM; + cpsr.mode = MODE_USER; miscRegs[MISCREG_CPSR] = cpsr; updateRegMap(cpsr); //XXX We need to initialize the rest of the state. -- cgit v1.2.3 From f63c260d89591d8d57274bb37aea51dc7c093b8f Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 8 Nov 2009 01:57:34 -0800 Subject: ARM: Get rid of the Raddr operand. --- src/arch/arm/isa/operands.isa | 1 - 1 file changed, 1 deletion(-) (limited to 'src/arch') diff --git a/src/arch/arm/isa/operands.isa b/src/arch/arm/isa/operands.isa index ac7427dad..a4c404bd5 100644 --- a/src/arch/arm/isa/operands.isa +++ b/src/arch/arm/isa/operands.isa @@ -63,7 +63,6 @@ def operands {{ 'Rdo': ('IntReg', 'uw', '(RD & ~1)', 'IsInteger', 4, maybePCRead, maybePCWrite), 'Rde': ('IntReg', 'uw', '(RD | 1)', 'IsInteger', 5, maybePCRead, maybePCWrite), - 'Raddr': ('IntReg', 'uw', '17', 'IsInteger', 6), 'Rhi': ('IntReg', 'uw', '18', 'IsInteger', 7), 'Rlo': ('IntReg', 'uw', '19', 'IsInteger', 8), 'LR': ('IntReg', 'uw', '14', 'IsInteger', 9), -- cgit v1.2.3 From 78bd8fe44fe3398f361335d2feb59a8221cc52e8 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 8 Nov 2009 01:59:20 -0800 Subject: ARM: Add back in spots for Rhi and Rlo, and use a named constant for LR. --- src/arch/arm/intregs.hh | 2 ++ src/arch/arm/isa/operands.isa | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'src/arch') diff --git a/src/arch/arm/intregs.hh b/src/arch/arm/intregs.hh index 191965c55..78ad39ee2 100644 --- a/src/arch/arm/intregs.hh +++ b/src/arch/arm/intregs.hh @@ -102,6 +102,8 @@ enum IntRegIndex INTREG_ZERO, // Dummy zero reg since there has to be one. INTREG_UREG0, + INTREG_RHI, + INTREG_RLO, NUM_INTREGS, NUM_ARCH_INTREGS = INTREG_PC + 1, diff --git a/src/arch/arm/isa/operands.isa b/src/arch/arm/isa/operands.isa index a4c404bd5..4ac6790e5 100644 --- a/src/arch/arm/isa/operands.isa +++ b/src/arch/arm/isa/operands.isa @@ -63,9 +63,9 @@ def operands {{ 'Rdo': ('IntReg', 'uw', '(RD & ~1)', 'IsInteger', 4, maybePCRead, maybePCWrite), 'Rde': ('IntReg', 'uw', '(RD | 1)', 'IsInteger', 5, maybePCRead, maybePCWrite), - 'Rhi': ('IntReg', 'uw', '18', 'IsInteger', 7), - 'Rlo': ('IntReg', 'uw', '19', 'IsInteger', 8), - 'LR': ('IntReg', 'uw', '14', 'IsInteger', 9), + 'Rhi': ('IntReg', 'uw', 'INTREG_RHI', 'IsInteger', 7), + 'Rlo': ('IntReg', 'uw', 'INTREG_RLO', 'IsInteger', 8), + 'LR': ('IntReg', 'uw', 'INTREG_LR', 'IsInteger', 9), #Register fields for microops 'Ra' : ('IntReg', 'uw', 'ura', 'IsInteger', 11, maybePCRead, maybePCWrite), -- cgit v1.2.3 From 3a3e8461511663a3154d0507ba1b0f52ea5366c5 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 8 Nov 2009 02:00:55 -0800 Subject: ARM: Get rid of NumInternalProcRegs. That constant is a carry over from Alpha and doesn't do anything in ARM. --- src/arch/arm/registers.hh | 1 - 1 file changed, 1 deletion(-) (limited to 'src/arch') diff --git a/src/arch/arm/registers.hh b/src/arch/arm/registers.hh index 04fd00f3a..41bbf4e7f 100644 --- a/src/arch/arm/registers.hh +++ b/src/arch/arm/registers.hh @@ -55,7 +55,6 @@ typedef uint64_t MiscReg; const int NumIntArchRegs = NUM_ARCH_INTREGS; const int NumFloatArchRegs = 16; const int NumFloatSpecialRegs = 5; -const int NumInternalProcRegs = 0; const int NumIntRegs = NUM_INTREGS; const int NumFloatRegs = NumFloatArchRegs + NumFloatSpecialRegs; -- cgit v1.2.3 From d188821d3700ee42e01fc43c9ef17568991fb3ff Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 8 Nov 2009 02:01:02 -0800 Subject: ARM: Add in more bits for the mon mode. --- src/arch/arm/isa.hh | 3 +++ src/arch/arm/miscregs.hh | 1 + src/arch/arm/types.hh | 1 + 3 files changed, 5 insertions(+) (limited to 'src/arch') diff --git a/src/arch/arm/isa.hh b/src/arch/arm/isa.hh index 6341e6cd0..f8359679b 100644 --- a/src/arch/arm/isa.hh +++ b/src/arch/arm/isa.hh @@ -63,6 +63,9 @@ namespace ArmISA case MODE_SVC: intRegMap = IntRegSvcMap; break; + case MODE_MON: + intRegMap = IntRegMonMap; + break; case MODE_ABORT: intRegMap = IntRegAbtMap; break; diff --git a/src/arch/arm/miscregs.hh b/src/arch/arm/miscregs.hh index 3180669de..ba394d49c 100644 --- a/src/arch/arm/miscregs.hh +++ b/src/arch/arm/miscregs.hh @@ -59,6 +59,7 @@ namespace ArmISA MISCREG_SPSR_FIQ, MISCREG_SPSR_IRQ, MISCREG_SPSR_SVC, + MISCREG_SPSR_MON, MISCREG_SPSR_UND, MISCREG_SPSR_ABT, MISCREG_FPSR, diff --git a/src/arch/arm/types.hh b/src/arch/arm/types.hh index 2c4e1291c..d5cc07eaf 100644 --- a/src/arch/arm/types.hh +++ b/src/arch/arm/types.hh @@ -156,6 +156,7 @@ namespace ArmISA MODE_FIQ = 17, MODE_IRQ = 18, MODE_SVC = 19, + MODE_MON = 22, MODE_ABORT = 23, MODE_UNDEFINED = 27, MODE_SYSTEM = 31 -- cgit v1.2.3 From 48525f581c6233b8f7a8a872c5774d4e245f431c Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 8 Nov 2009 02:08:40 -0800 Subject: ARM: Split the condition codes out of the CPSR. This allows those bits to be renamed while allowing the other fields to control the behavior of the processor. --- src/arch/arm/intregs.hh | 1 + src/arch/arm/isa/decoder.isa | 20 +++++++++++++------- src/arch/arm/isa/formats/branch.isa | 4 ++-- src/arch/arm/isa/formats/fp.isa | 4 ++-- src/arch/arm/isa/formats/pred.isa | 28 ++++++++++++++-------------- src/arch/arm/isa/formats/util.isa | 6 ++++-- src/arch/arm/isa/operands.isa | 1 + src/arch/arm/nativetrace.cc | 3 ++- 8 files changed, 39 insertions(+), 28 deletions(-) (limited to 'src/arch') diff --git a/src/arch/arm/intregs.hh b/src/arch/arm/intregs.hh index 78ad39ee2..b5f955c4b 100644 --- a/src/arch/arm/intregs.hh +++ b/src/arch/arm/intregs.hh @@ -104,6 +104,7 @@ enum IntRegIndex INTREG_UREG0, INTREG_RHI, INTREG_RLO, + INTREG_CONDCODES, NUM_INTREGS, NUM_ARCH_INTREGS = INTREG_PC + 1, diff --git a/src/arch/arm/isa/decoder.isa b/src/arch/arm/isa/decoder.isa index a999b52e9..ebadeb985 100644 --- a/src/arch/arm/isa/decoder.isa +++ b/src/arch/arm/isa/decoder.isa @@ -91,9 +91,9 @@ format DataOp { 0x2: sub({{ Rd = resTemp = Rn - op2; }}, sub); 0x3: rsb({{ Rd = resTemp = op2 - Rn; }}, rsb); 0x4: add({{ Rd = resTemp = Rn + op2; }}, add); - 0x5: adc({{ Rd = resTemp = Rn + op2 + Cpsr<29:>; }}, add); - 0x6: sbc({{ Rd = resTemp = Rn - op2 - !Cpsr<29:>; }}, sub); - 0x7: rsc({{ Rd = resTemp = op2 - Rn - !Cpsr<29:>; }}, rsb); + 0x5: adc({{ Rd = resTemp = Rn + op2 + CondCodes<29:>; }}, add); + 0x6: sbc({{ Rd = resTemp = Rn - op2 - !CondCodes<29:>; }}, sub); + 0x7: rsc({{ Rd = resTemp = op2 - Rn - !CondCodes<29:>; }}, rsb); 0x8: tst({{ resTemp = Rn & op2; }}); 0x9: teq({{ resTemp = Rn ^ op2; }}); 0xa: cmp({{ resTemp = Rn - op2; }}, sub); @@ -163,9 +163,15 @@ format DataOp { 0x2: subi({{ Rd = resTemp = Rn - rotated_imm; }}, sub); 0x3: rsbi({{ Rd = resTemp = rotated_imm - Rn; }}, rsb); 0x4: addi({{ Rd = resTemp = Rn + rotated_imm; }}, add); - 0x5: adci({{ Rd = resTemp = Rn + rotated_imm + Cpsr<29:>; }}, add); - 0x6: sbci({{ Rd = resTemp = Rn -rotated_imm - !Cpsr<29:>; }}, sub); - 0x7: rsci({{ Rd = resTemp = rotated_imm - Rn - !Cpsr<29:>;}}, rsb); + 0x5: adci({{ + Rd = resTemp = Rn + rotated_imm + CondCodes<29:>; + }}, add); + 0x6: sbci({{ + Rd = resTemp = Rn -rotated_imm - !CondCodes<29:>; + }}, sub); + 0x7: rsci({{ + Rd = resTemp = rotated_imm - Rn - !CondCodes<29:>; + }}, rsb); 0x8: tsti({{ resTemp = Rn & rotated_imm; }}); 0x9: teqi({{ resTemp = Rn ^ rotated_imm; }}); 0xa: cmpi({{ resTemp = Rn - rotated_imm; }}, sub); @@ -437,7 +443,7 @@ format DataOp { } format PredOp { // ARM System Call (SoftWare Interrupt) - 1: swi({{ if (testPredicate(Cpsr, condCode)) + 1: swi({{ if (testPredicate(CondCodes, condCode)) { if (IMMED_23_0) xc->syscall(IMMED_23_0); diff --git a/src/arch/arm/isa/formats/branch.isa b/src/arch/arm/isa/formats/branch.isa index 95f4f14e1..5f1b541ff 100644 --- a/src/arch/arm/isa/formats/branch.isa +++ b/src/arch/arm/isa/formats/branch.isa @@ -52,7 +52,7 @@ def format Branch(code,*opt_flags) {{ else: inst_flags += ('IsCondControl', ) - icode = 'if (testPredicate(Cpsr, condCode)) {\n' + icode = 'if (testPredicate(CondCodes, condCode)) {\n' icode += code icode += ' NPC = NPC + 4 + disp;\n' icode += '} else {\n' @@ -90,7 +90,7 @@ def format BranchExchange(code,*opt_flags) {{ #Condition code - icode = 'if (testPredicate(Cpsr, condCode)) {\n' + icode = 'if (testPredicate(CondCodes, condCode)) {\n' icode += code icode += ' NPC = Rm & 0xfffffffe; // Masks off bottom bit\n' icode += '} else {\n' diff --git a/src/arch/arm/isa/formats/fp.isa b/src/arch/arm/isa/formats/fp.isa index e88531580..e79529615 100644 --- a/src/arch/arm/isa/formats/fp.isa +++ b/src/arch/arm/isa/formats/fp.isa @@ -119,8 +119,8 @@ let {{ _ic = %(fReg1)s >= %(fReg2)s; _iv = (isnan(%(fReg1)s) || isnan(%(fReg2)s)) & 1; - Cpsr = _in << 31 | _iz << 30 | _ic << 29 | _iv << 28 | - (Cpsr & 0x0FFFFFFF); + CondCodes = _in << 31 | _iz << 30 | _ic << 29 | _iv << 28 | + (CondCodes & 0x0FFFFFFF); ''' }}; diff --git a/src/arch/arm/isa/formats/pred.isa b/src/arch/arm/isa/formats/pred.isa index e90788c91..3c97560fd 100644 --- a/src/arch/arm/isa/formats/pred.isa +++ b/src/arch/arm/isa/formats/pred.isa @@ -34,7 +34,7 @@ // let {{ - predicateTest = 'testPredicate(Cpsr, condCode)' + predicateTest = 'testPredicate(CondCodes, condCode)' }}; def template PredOpExecute {{ @@ -90,8 +90,8 @@ let {{ _iv = %(ivValue)s & 1; _ic = %(icValue)s & 1; - Cpsr = _in << 31 | _iz << 30 | _ic << 29 | _iv << 28 | - (Cpsr & 0x0FFFFFFF); + CondCodes = _in << 31 | _iz << 30 | _ic << 29 | _iv << 28 | + (CondCodes & 0x0FFFFFFF); DPRINTF(Arm, "in = %%d\\n", _in); DPRINTF(Arm, "iz = %%d\\n", _iz); @@ -105,8 +105,8 @@ let {{ def getCcCode(flagtype): icReg = icImm = iv = '' if flagtype == "none": - icReg = icImm = 'Cpsr<29:>' - iv = 'Cpsr<28:>' + icReg = icImm = 'CondCodes<29:>' + iv = 'CondCodes<28:>' elif flagtype == "add": icReg = icImm = 'findCarry(32, resTemp, Rn, op2)' iv = 'findOverflow(32, resTemp, Rn, op2)' @@ -117,17 +117,17 @@ let {{ icReg = icImm = 'findCarry(32, resTemp, op2, ~Rn)' iv = 'findOverflow(32, resTemp, op2, ~Rn)' else: - icReg = 'shift_carry_rs(Rm, Rs, shift, Cpsr<29:>)' - icImm = 'shift_carry_imm(Rm, shift_size, shift, Cpsr<29:>)' - iv = 'Cpsr<28:>' + icReg = 'shift_carry_rs(Rm, Rs, shift, CondCodes<29:>)' + icImm = 'shift_carry_imm(Rm, shift_size, shift, CondCodes<29:>)' + iv = 'CondCodes<28:>' return (calcCcCode % {"icValue" : icReg, "ivValue" : iv}, calcCcCode % {"icValue" : icImm, "ivValue" : iv}) def getImmCcCode(flagtype): ivValue = icValue = '' if flagtype == "none": - icValue = 'Cpsr<29:>' - ivValue = 'Cpsr<28:>' + icValue = 'CondCodes<29:>' + ivValue = 'CondCodes<28:>' elif flagtype == "add": icValue = 'findCarry(32, resTemp, Rn, rotated_imm)' ivValue = 'findOverflow(32, resTemp, Rn, rotated_imm)' @@ -138,18 +138,18 @@ let {{ icValue = 'findCarry(32, resTemp, rotated_imm, ~Rn)' ivValue = 'findOverflow(32, resTemp, rotated_imm, ~Rn)' else: - icValue = '(rotate ? rotated_carry:Cpsr<29:>)' - ivValue = 'Cpsr<28:>' + icValue = '(rotate ? rotated_carry:CondCodes<29:>)' + ivValue = 'CondCodes<28:>' return calcCcCode % vars() }}; def format DataOp(code, flagtype = logic) {{ (regCcCode, immCcCode) = getCcCode(flagtype) regCode = '''uint32_t op2 = shift_rm_rs(Rm, Rs, - shift, Cpsr<29:0>); + shift, CondCodes<29:0>); op2 = op2;''' + code immCode = '''uint32_t op2 = shift_rm_imm(Rm, shift_size, - shift, Cpsr<29:0>); + shift, CondCodes<29:0>); op2 = op2;''' + code regIop = InstObjParams(name, Name, 'PredIntOp', {"code": regCode, diff --git a/src/arch/arm/isa/formats/util.isa b/src/arch/arm/isa/formats/util.isa index b5efec568..d42ffb147 100644 --- a/src/arch/arm/isa/formats/util.isa +++ b/src/arch/arm/isa/formats/util.isa @@ -33,8 +33,10 @@ let {{ # Generic substitutions for Arm instructions def ArmGenericCodeSubs(code): # Substitute in the shifted portion of operations - new_code = re.sub(r'Rm_Imm', 'shift_rm_imm(Rm, shift_size, shift, Cpsr<29:>)', code) - new_code = re.sub(r'Rm_Rs', 'shift_rm_rs(Rm, Rs, shift, Cpsr<29:>)', new_code) + new_code = re.sub(r'Rm_Imm', + 'shift_rm_imm(Rm, shift_size, shift, CondCodes<29:>)', code) + new_code = re.sub(r'Rm_Rs', + 'shift_rm_rs(Rm, Rs, shift, CondCodes<29:>)', new_code) return new_code def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, diff --git a/src/arch/arm/isa/operands.isa b/src/arch/arm/isa/operands.isa index 4ac6790e5..02acc8ed7 100644 --- a/src/arch/arm/isa/operands.isa +++ b/src/arch/arm/isa/operands.isa @@ -66,6 +66,7 @@ def operands {{ 'Rhi': ('IntReg', 'uw', 'INTREG_RHI', 'IsInteger', 7), 'Rlo': ('IntReg', 'uw', 'INTREG_RLO', 'IsInteger', 8), 'LR': ('IntReg', 'uw', 'INTREG_LR', 'IsInteger', 9), + 'CondCodes': ('IntReg', 'uw', 'INTREG_CONDCODES', 'IsInteger', 10), #Register fields for microops 'Ra' : ('IntReg', 'uw', 'ura', 'IsInteger', 11, maybePCRead, maybePCWrite), diff --git a/src/arch/arm/nativetrace.cc b/src/arch/arm/nativetrace.cc index 1ad9e1a19..01f3205eb 100644 --- a/src/arch/arm/nativetrace.cc +++ b/src/arch/arm/nativetrace.cc @@ -97,7 +97,8 @@ Trace::ArmNativeTrace::ThreadState::update(ThreadContext *tc) changed[STATE_PC] = (newState[STATE_PC] != oldState[STATE_PC]); //CPSR - newState[STATE_CPSR] = tc->readMiscReg(MISCREG_CPSR); + newState[STATE_CPSR] = tc->readMiscReg(MISCREG_CPSR) | + tc->readIntReg(INTREG_CONDCODES); changed[STATE_CPSR] = (newState[STATE_CPSR] != oldState[STATE_CPSR]); } -- cgit v1.2.3 From 708faa767763e65a2fded8aa33ac3c63cca9c84c Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Sun, 8 Nov 2009 13:31:59 -0800 Subject: compile: wrap 64bit numbers with ULL() so 32bit compiles work In the isa_parser, we need to check case statements. --- src/arch/isa_parser.py | 7 ++++++- src/arch/x86/process.cc | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) (limited to 'src/arch') diff --git a/src/arch/isa_parser.py b/src/arch/isa_parser.py index e3da240d2..2db7c6aa6 100755 --- a/src/arch/isa_parser.py +++ b/src/arch/isa_parser.py @@ -585,7 +585,12 @@ StaticInstPtr # 'default' def p_case_label_0(self, t): 'case_label : intlit_list' - t[0] = ': '.join(map(lambda a: 'case %#x' % a, t[1])) + def make_case(intlit): + if intlit >= 2**32: + return 'case ULL(%#x)' % intlit + else: + return 'case %#x' % intlit + t[0] = ': '.join(map(make_case, t[1])) def p_case_label_1(self, t): 'case_label : DEFAULT' diff --git a/src/arch/x86/process.cc b/src/arch/x86/process.cc index 7cc889d7c..42ca7b27d 100644 --- a/src/arch/x86/process.cc +++ b/src/arch/x86/process.cc @@ -175,7 +175,7 @@ I386LiveProcess::I386LiveProcess(LiveProcessParams *params, int _numSyscallDescs) : X86LiveProcess(params, objFile, _syscallDescs, _numSyscallDescs) { - _gdtStart = 0x100000000; + _gdtStart = ULL(0x100000000); _gdtSize = VMPageSize; vsyscallPage.base = 0xffffe000ULL; -- cgit v1.2.3 From bb903b6514b743e93e429929776639879d6c59a7 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 8 Nov 2009 15:16:59 -0800 Subject: ARM: Simplify the load/store multiple generation code. Specifically, get rid of the big switch statement so more cases can be handled. Enumerating all the possible settings doesn't scale well. Also do some minor style clean up. --- src/arch/arm/isa/formats/macromem.isa | 83 ++++++++++++----------------------- 1 file changed, 27 insertions(+), 56 deletions(-) (limited to 'src/arch') diff --git a/src/arch/arm/isa/formats/macromem.isa b/src/arch/arm/isa/formats/macromem.isa index d978967ac..8c8ba8a1a 100644 --- a/src/arch/arm/isa/formats/macromem.isa +++ b/src/arch/arm/isa/formats/macromem.isa @@ -178,75 +178,46 @@ inline %(class_name)s::%(class_name)s(ExtMachInst machInst) : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s) { %(constructor)s; - uint32_t regs_to_handle = reglist; - uint32_t start_addr = 0; + uint32_t regs = reglist; + uint32_t addr = 0; - switch (puswl) - { - case 0x00: // stmda - case 0x01: // L ldmda_l - case 0x02: // W stmda_w - case 0x03: // WL ldmda_wl - start_addr = (ones << 2) - 4; - break; - case 0x08: // U stmia_u - case 0x09: // U L ldmia_ul - case 0x0a: // U W stmia - case 0x0b: // U WL ldmia - start_addr = 0; - break; - case 0x10: // P stmdb - case 0x11: // P L ldmdb - case 0x12: // P W stmdb - case 0x13: // P WL ldmdb - start_addr = (ones << 2); // U-bit is already 0 for subtract - break; - case 0x18: // PU stmib - case 0x19: // PU L ldmib - case 0x1a: // PU W stmib - case 0x1b: // PU WL ldmib - start_addr = 4; - break; - default: - panic("Unhandled Load/Store Multiple Instruction, " - "puswl = 0x%x", (unsigned) puswl); - break; - } + if (!up) + addr = (ones << 2) - 4; + + if (prepost) + addr += 4; // Add 0 to Rn and stick it in ureg0. // This is equivalent to a move. microOps[0] = new MicroAddiUop(machInst, INTREG_UREG0, RN, 0); - unsigned j = 0; - for (int i = 1; i < ones+1; i++) { - // Get next available bit for transfer - while (! ( regs_to_handle & (1<setLastMicroop(); + lastUop->setLastMicroop(); } }}; @@ -287,14 +258,14 @@ inline %(class_name)s::%(class_name)s(ExtMachInst machInst) if (writeback) { if (up) { - microOps[numMicroops-1] = + microOps[numMicroops - 1] = new MicroAddiUop(machInst, RN, RN, disp8); } else { - microOps[numMicroops-1] = + microOps[numMicroops - 1] = new MicroSubiUop(machInst, RN, RN, disp8); } } - microOps[numMicroops-1]->setLastMicroop(); + microOps[numMicroops - 1]->setLastMicroop(); } }}; @@ -318,14 +289,14 @@ inline %(class_name)s::%(class_name)s(ExtMachInst machInst) if (writeback) { if (up) { - microOps[numMicroops-1] = + microOps[numMicroops - 1] = new MicroAddiUop(machInst, RN, RN, disp8); } else { - microOps[numMicroops-1] = + microOps[numMicroops - 1] = new MicroSubiUop(machInst, RN, RN, disp8); } } - microOps[numMicroops-1]->setLastMicroop(); + microOps[numMicroops - 1]->setLastMicroop(); } }}; -- cgit v1.2.3 From 8a4af3668dd8c45de4b98f3eb1fb2ef28bd369a2 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 8 Nov 2009 15:49:03 -0800 Subject: ARM: Support forcing load/store multiple to use user registers. --- src/arch/arm/insts/macromem.hh | 25 ++++++------------------- src/arch/arm/intregs.hh | 7 +++++++ src/arch/arm/isa.hh | 5 ++++- src/arch/arm/isa/formats/macromem.isa | 21 +++++++++++++++------ 4 files changed, 32 insertions(+), 26 deletions(-) (limited to 'src/arch') diff --git a/src/arch/arm/insts/macromem.hh b/src/arch/arm/insts/macromem.hh index 541c9e3f5..714b8bb7e 100644 --- a/src/arch/arm/insts/macromem.hh +++ b/src/arch/arm/insts/macromem.hh @@ -84,33 +84,20 @@ class MicroMemOp : public MicroIntOp */ class ArmMacroMemoryOp : public PredMacroOp { - protected: + protected: /// Memory request flags. See mem_req_base.hh. unsigned memAccessFlags; uint32_t reglist; uint32_t ones; - uint32_t puswl, - prepost, - up, - psruser, - writeback, - loadop; ArmMacroMemoryOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass) - : PredMacroOp(mnem, _machInst, __opClass), - memAccessFlags(0), - reglist(machInst.regList), ones(0), - puswl(machInst.puswl), - prepost(machInst.puswl.prepost), - up(machInst.puswl.up), - psruser(machInst.puswl.psruser), - writeback(machInst.puswl.writeback), - loadop(machInst.puswl.loadOp) + : PredMacroOp(mnem, _machInst, __opClass), memAccessFlags(0), + reglist(machInst.regList), ones(0) { ones = number_of_ones(reglist); - numMicroops = ones + writeback + 1; + numMicroops = ones + machInst.puswl.writeback + 1; // Remember that writeback adds a uop microOps = new StaticInstPtr[numMicroops]; } @@ -121,7 +108,7 @@ class ArmMacroMemoryOp : public PredMacroOp */ class ArmMacroFPAOp : public PredMacroOp { - protected: + protected: uint32_t puswl, prepost, up, @@ -150,7 +137,7 @@ class ArmMacroFPAOp : public PredMacroOp */ class ArmMacroFMOp : public PredMacroOp { - protected: + protected: uint32_t punwl, prepost, up, diff --git a/src/arch/arm/intregs.hh b/src/arch/arm/intregs.hh index b5f955c4b..0c2fc5fbb 100644 --- a/src/arch/arm/intregs.hh +++ b/src/arch/arm/intregs.hh @@ -324,6 +324,13 @@ INTREG_FIQ(unsigned index) return IntRegFiqMap[index]; } +static inline IntRegIndex +intRegForceUser(unsigned index) +{ + assert(index < NUM_ARCH_INTREGS); + return (IntRegIndex)(index + NUM_INTREGS); +} + } #endif diff --git a/src/arch/arm/isa.hh b/src/arch/arm/isa.hh index f8359679b..a4a328614 100644 --- a/src/arch/arm/isa.hh +++ b/src/arch/arm/isa.hh @@ -125,8 +125,11 @@ namespace ArmISA assert(reg >= 0); if (reg < NUM_ARCH_INTREGS) { return intRegMap[reg]; + } else if (reg < NUM_INTREGS) { + return reg; } else { - assert(reg < NUM_INTREGS); + reg -= NUM_INTREGS; + assert(reg < NUM_ARCH_INTREGS); return reg; } } diff --git a/src/arch/arm/isa/formats/macromem.isa b/src/arch/arm/isa/formats/macromem.isa index 8c8ba8a1a..9a3185af3 100644 --- a/src/arch/arm/isa/formats/macromem.isa +++ b/src/arch/arm/isa/formats/macromem.isa @@ -180,11 +180,12 @@ inline %(class_name)s::%(class_name)s(ExtMachInst machInst) %(constructor)s; uint32_t regs = reglist; uint32_t addr = 0; + bool up = machInst.puswl.up; if (!up) addr = (ones << 2) - 4; - if (prepost) + if (machInst.puswl.prepost) addr += 4; // Add 0 to Rn and stick it in ureg0. @@ -198,10 +199,18 @@ inline %(class_name)s::%(class_name)s(ExtMachInst machInst) reg++; replaceBits(regs, reg, 0); - if (loadop) - microOps[i] = new MicroLdrUop(machInst, reg, INTREG_UREG0, addr); - else - microOps[i] = new MicroStrUop(machInst, reg, INTREG_UREG0, addr); + unsigned regIdx = reg; + if (machInst.puswl.psruser) { + regIdx = intRegForceUser(regIdx); + } + + if (machInst.puswl.loadOp) { + microOps[i] = + new MicroLdrUop(machInst, regIdx, INTREG_UREG0, addr); + } else { + microOps[i] = + new MicroStrUop(machInst, regIdx, INTREG_UREG0, addr); + } if (up) addr += 4; @@ -210,7 +219,7 @@ inline %(class_name)s::%(class_name)s(ExtMachInst machInst) } StaticInstPtr &lastUop = microOps[numMicroops - 1]; - if (writeback) { + if (machInst.puswl.writeback) { if (up) { lastUop = new MicroAddiUop(machInst, RN, RN, ones * 4); } else { -- cgit v1.2.3 From 53086dfefe2796497724daaa7d5d1d3d85a8a636 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 8 Nov 2009 22:49:57 -0800 Subject: X86: Make x86 use PREFETCH instead of PF_EXCLUSIVE. --- src/arch/x86/isa/microops/ldstop.isa | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/microops/ldstop.isa b/src/arch/x86/isa/microops/ldstop.isa index 912aa3511..afe1ead59 100644 --- a/src/arch/x86/isa/microops/ldstop.isa +++ b/src/arch/x86/isa/microops/ldstop.isa @@ -157,7 +157,7 @@ def template MicroLoadExecute {{ if (fault == NoFault) { %(code)s; - } else if (memFlags & Request::PF_EXCLUSIVE) { + } else if (memFlags & Request::PREFETCH) { // For prefetches, ignore any faults/exceptions. return NoFault; } @@ -374,7 +374,7 @@ let {{ if atCPL0: self.memFlags += " | (CPL0FlagBit << FlagShift)" if prefetch: - self.memFlags += " | Request::PF_EXCLUSIVE" + self.memFlags += " | Request::PREFETCH" self.memFlags += " | (machInst.legacy.addr ? " + \ "(AddrSizeFlagBit << FlagShift) : 0)" -- cgit v1.2.3 From 44e912c6bd8828a6a3774c1fa54a1f4689383243 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 8 Nov 2009 22:49:57 -0800 Subject: X86: Explain what really didn't work with unmapped addresses in SE mode. --- src/arch/x86/tlb.cc | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/tlb.cc b/src/arch/x86/tlb.cc index 5280b9ba8..0d69d05c9 100644 --- a/src/arch/x86/tlb.cc +++ b/src/arch/x86/tlb.cc @@ -632,12 +632,22 @@ TLB::translate(RequestPtr req, ThreadContext *tc, Translation *translation, Process *p = tc->getProcessPtr(); TlbEntry newEntry; bool success = p->pTable->lookup(vaddr, newEntry); - if(!success && mode != Execute) { + if (!success && mode != Execute) { p->checkAndAllocNextPage(vaddr); success = p->pTable->lookup(vaddr, newEntry); } - if(!success) { - panic("Tried to execute unmapped address %#x.\n", vaddr); + if (!success) { + const char *modeStr = ""; + if (mode == Execute) + modeStr = "execute"; + else if (mode == Read) + modeStr = "read"; + else if (mode == Write) + modeStr = "write"; + else + modeStr = "?"; + panic("Tried to %s unmapped address %#x.\n", + modeStr, vaddr); } else { Addr alignedVaddr = p->pTable->pageAlign(vaddr); DPRINTF(TLB, "Mapping %#x to %#x\n", alignedVaddr, -- cgit v1.2.3 From bbbfdee2ed4feb5e8e448920e5d51701a2192ee1 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 8 Nov 2009 22:49:58 -0800 Subject: X86: Don't panic on faults on prefetches in SE mode. --- src/arch/x86/tlb.cc | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/tlb.cc b/src/arch/x86/tlb.cc index 0d69d05c9..d7959da2c 100644 --- a/src/arch/x86/tlb.cc +++ b/src/arch/x86/tlb.cc @@ -637,17 +637,21 @@ TLB::translate(RequestPtr req, ThreadContext *tc, Translation *translation, success = p->pTable->lookup(vaddr, newEntry); } if (!success) { - const char *modeStr = ""; - if (mode == Execute) - modeStr = "execute"; - else if (mode == Read) - modeStr = "read"; - else if (mode == Write) - modeStr = "write"; - else - modeStr = "?"; - panic("Tried to %s unmapped address %#x.\n", - modeStr, vaddr); + if (req->isPrefetch()) { + return new PageFault(vaddr, true, mode, true, false); + } else { + const char *modeStr = ""; + if (mode == Execute) + modeStr = "execute"; + else if (mode == Read) + modeStr = "read"; + else if (mode == Write) + modeStr = "write"; + else + modeStr = "?"; + panic("Tried to %s unmapped address %#x.\n", + modeStr, vaddr); + } } else { Addr alignedVaddr = p->pTable->pageAlign(vaddr); DPRINTF(TLB, "Mapping %#x to %#x\n", alignedVaddr, -- cgit v1.2.3 From e81cc233a6fa82d2aec45bd9160db15df112f584 Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Tue, 10 Nov 2009 11:18:23 -0500 Subject: X86: Remove double-cast in Cvtf2i micro-op This double cast led to rounding errors which caused some benchmarks to get the wrong values, most notably lucas which failed spectacularly due to CVTTSD2SI returning an off-by-one value. equake was also broken. --- src/arch/x86/isa/microops/mediaop.isa | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/microops/mediaop.isa b/src/arch/x86/isa/microops/mediaop.isa index 9c53fa0fb..fa32583b0 100644 --- a/src/arch/x86/isa/microops/mediaop.isa +++ b/src/arch/x86/isa/microops/mediaop.isa @@ -1237,7 +1237,7 @@ let {{ } if (destSize == 4) { - argBits = (uint32_t)(float)arg; + argBits = (uint32_t)arg; } else { argBits = (uint64_t)arg; } -- cgit v1.2.3 From 53e27c0277a41ab1cae45d82fb4409f65cf660c3 Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Tue, 10 Nov 2009 11:29:30 -0500 Subject: X86: Fix bugs in movd implementation. Unfortunately my implementation of the movd instruction had two bugs. In one case, when moving a 32-bit value into an xmm register, the lower half of the xmm register was not zero extended. The other case is that xmm was used instead of xmmlm as the source for a register move. My test case didn't notice this at first as it moved xmm0 to eax, which both have the same register number. --- src/arch/x86/isa/insts/general_purpose/data_transfer/move.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/insts/general_purpose/data_transfer/move.py b/src/arch/x86/isa/insts/general_purpose/data_transfer/move.py index 7aee3fec1..51f5ad23b 100644 --- a/src/arch/x86/isa/insts/general_purpose/data_transfer/move.py +++ b/src/arch/x86/isa/insts/general_purpose/data_transfer/move.py @@ -357,7 +357,7 @@ def macroop MOVNTI_P_R { }; def macroop MOVD_XMM_R { - mov2fp xmml, regm, srcSize=dsz, destSize=dsz + mov2fp xmml, regm, srcSize=dsz, destSize=8 lfpimm xmmh, 0 }; @@ -373,7 +373,7 @@ def macroop MOVD_XMM_P { }; def macroop MOVD_R_XMM { - mov2int reg, xmml, size=dsz + mov2int reg, xmmlm, size=dsz }; def macroop MOVD_M_XMM { -- cgit v1.2.3 From 4779020e139c70355335729b504195a0e5009e7a Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 10 Nov 2009 20:19:55 -0800 Subject: ARM: Fix the integer register indexes. The PC indexes in the various register sets was defined in the section for unaliased registers which was throwing off the indexing. This moves those where they belong. Also, to make detecting accesses to the PC easier and because it's in the same place in all modes, the intRegForceUser function now passes it through as index 15. --- src/arch/arm/intregs.hh | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'src/arch') diff --git a/src/arch/arm/intregs.hh b/src/arch/arm/intregs.hh index 0c2fc5fbb..15499601a 100644 --- a/src/arch/arm/intregs.hh +++ b/src/arch/arm/intregs.hh @@ -63,31 +63,26 @@ enum IntRegIndex INTREG_SP_SVC = INTREG_R13_SVC, INTREG_R14_SVC, INTREG_LR_SVC = INTREG_R14_SVC, - INTREG_R15_SVC = INTREG_R15, INTREG_R13_MON, INTREG_SP_MON = INTREG_R13_MON, INTREG_R14_MON, INTREG_LR_MON = INTREG_R14_MON, - INTREG_R15_MON = INTREG_R15, INTREG_R13_ABT, INTREG_SP_ABT = INTREG_R13_ABT, INTREG_R14_ABT, INTREG_LR_ABT = INTREG_R14_ABT, - INTREG_R15_ABT = INTREG_R15, INTREG_R13_UND, INTREG_SP_UND = INTREG_R13_UND, INTREG_R14_UND, INTREG_LR_UND = INTREG_R14_UND, - INTREG_R15_UND = INTREG_R15, INTREG_R13_IRQ, INTREG_SP_IRQ = INTREG_R13_IRQ, INTREG_R14_IRQ, INTREG_LR_IRQ = INTREG_R14_IRQ, - INTREG_R15_IRQ = INTREG_R15, INTREG_R8_FIQ, INTREG_R9_FIQ, @@ -98,7 +93,6 @@ enum IntRegIndex INTREG_SP_FIQ = INTREG_R13_FIQ, INTREG_R14_FIQ, INTREG_LR_FIQ = INTREG_R14_FIQ, - INTREG_R15_FIQ = INTREG_R15, INTREG_ZERO, // Dummy zero reg since there has to be one. INTREG_UREG0, @@ -147,6 +141,7 @@ enum IntRegIndex INTREG_R11_SVC = INTREG_R11, INTREG_R12_SVC = INTREG_R12, INTREG_PC_SVC = INTREG_PC, + INTREG_R15_SVC = INTREG_R15, /* MON mode */ INTREG_R0_MON = INTREG_R0, @@ -163,6 +158,7 @@ enum IntRegIndex INTREG_R11_MON = INTREG_R11, INTREG_R12_MON = INTREG_R12, INTREG_PC_MON = INTREG_PC, + INTREG_R15_MON = INTREG_R15, /* ABT mode */ INTREG_R0_ABT = INTREG_R0, @@ -179,6 +175,7 @@ enum IntRegIndex INTREG_R11_ABT = INTREG_R11, INTREG_R12_ABT = INTREG_R12, INTREG_PC_ABT = INTREG_PC, + INTREG_R15_ABT = INTREG_R15, /* UND mode */ INTREG_R0_UND = INTREG_R0, @@ -195,6 +192,7 @@ enum IntRegIndex INTREG_R11_UND = INTREG_R11, INTREG_R12_UND = INTREG_R12, INTREG_PC_UND = INTREG_PC, + INTREG_R15_UND = INTREG_R15, /* IRQ mode */ INTREG_R0_IRQ = INTREG_R0, @@ -211,6 +209,7 @@ enum IntRegIndex INTREG_R11_IRQ = INTREG_R11, INTREG_R12_IRQ = INTREG_R12, INTREG_PC_IRQ = INTREG_PC, + INTREG_R15_IRQ = INTREG_R15, /* FIQ mode */ INTREG_R0_FIQ = INTREG_R0, @@ -222,6 +221,7 @@ enum IntRegIndex INTREG_R6_FIQ = INTREG_R6, INTREG_R7_FIQ = INTREG_R7, INTREG_PC_FIQ = INTREG_PC, + INTREG_R15_FIQ = INTREG_R15, }; typedef IntRegIndex IntRegMap[NUM_ARCH_INTREGS]; @@ -328,7 +328,8 @@ static inline IntRegIndex intRegForceUser(unsigned index) { assert(index < NUM_ARCH_INTREGS); - return (IntRegIndex)(index + NUM_INTREGS); + + return index == 15 ? (IntRegIndex)15 : (IntRegIndex)(index + NUM_INTREGS); } } -- cgit v1.2.3 From 2e28da5583814efe1e0a09718f6a674f983d12d1 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 10 Nov 2009 20:34:38 -0800 Subject: ARM: Implement fault classes. Implement some fault classes using the curriously recurring template pattern, similar to SPARCs. --- src/arch/arm/SConscript | 2 +- src/arch/arm/faults.cc | 534 +++++---------------------------- src/arch/arm/faults.hh | 557 +++-------------------------------- src/arch/arm/isa.hh | 8 + src/arch/arm/isa/formats/unimp.isa | 2 +- src/arch/arm/isa/formats/unknown.isa | 2 +- src/arch/arm/isa_traits.hh | 2 + src/arch/arm/miscregs.hh | 37 ++- src/arch/arm/utility.cc | 19 ++ 9 files changed, 188 insertions(+), 975 deletions(-) create mode 100644 src/arch/arm/utility.cc (limited to 'src/arch') diff --git a/src/arch/arm/SConscript b/src/arch/arm/SConscript index 55ecabdc3..f5fe1727c 100644 --- a/src/arch/arm/SConscript +++ b/src/arch/arm/SConscript @@ -48,7 +48,7 @@ if env['TARGET_ISA'] == 'arm': SimObject('ArmTLB.py') TraceFlag('Arm') - + TraceFlag('Faults', "Trace Exceptions, interrupts, svc/swi") if env['FULL_SYSTEM']: #Insert Full-System Files Here pass diff --git a/src/arch/arm/faults.cc b/src/arch/arm/faults.cc index 3d882c97f..b7dd2d503 100644 --- a/src/arch/arm/faults.cc +++ b/src/arch/arm/faults.cc @@ -26,488 +26,114 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * Authors: Gabe Black - * Stephen Hines + * Authors: Ali Saidi + * Gabe Black */ #include "arch/arm/faults.hh" #include "cpu/thread_context.hh" #include "cpu/base.hh" #include "base/trace.hh" -#if !FULL_SYSTEM -#include "sim/process.hh" -#include "mem/page_table.hh" -#endif namespace ArmISA { -FaultName MachineCheckFault::_name = "Machine Check"; -FaultVect MachineCheckFault::_vect = 0x0401; -FaultStat MachineCheckFault::_count; +template<> ArmFaultBase::FaultVals ArmFault::vals = + {"reset", 0x00, MODE_SVC, 0, 0, true, true}; -FaultName AlignmentFault::_name = "Alignment"; -FaultVect AlignmentFault::_vect = 0x0301; -FaultStat AlignmentFault::_count; +template<> ArmFaultBase::FaultVals ArmFault::vals = + {"Undefined Instruction", 0x04, MODE_UNDEFINED, 4 ,2, false, false} ; -FaultName ResetFault::_name = "Reset Fault"; -#if FULL_SYSTEM -FaultVect ResetFault::_vect = 0xBFC00000; -#else -FaultVect ResetFault::_vect = 0x001; -#endif -FaultStat ResetFault::_count; +template<> ArmFaultBase::FaultVals ArmFault::vals = + {"Supervisor Call", 0x08, MODE_SVC, 4, 2, false, false}; -FaultName AddressErrorFault::_name = "Address Error"; -FaultVect AddressErrorFault::_vect = 0x0180; -FaultStat AddressErrorFault::_count; +template<> ArmFaultBase::FaultVals ArmFault::vals = + {"Prefetch Abort", 0x0C, MODE_ABORT, 4, 4, true, false}; -FaultName StoreAddressErrorFault::_name = "Store Address Error"; -FaultVect StoreAddressErrorFault::_vect = 0x0180; -FaultStat StoreAddressErrorFault::_count; +template<> ArmFaultBase::FaultVals ArmFault::vals = + {"Data Abort", 0x10, MODE_ABORT, 8, 8, true, false}; +template<> ArmFaultBase::FaultVals ArmFault::vals = + {"IRQ", 0x18, MODE_IRQ, 4, 4, true, false}; -FaultName SystemCallFault::_name = "Syscall"; -FaultVect SystemCallFault::_vect = 0x0180; -FaultStat SystemCallFault::_count; +template<> ArmFaultBase::FaultVals ArmFault::vals = + {"FIQ", 0x1C, MODE_FIQ, 4, 4, true, true}; -FaultName CoprocessorUnusableFault::_name = "Coprocessor Unusable Fault"; -FaultVect CoprocessorUnusableFault::_vect = 0x180; -FaultStat CoprocessorUnusableFault::_count; - -FaultName ReservedInstructionFault::_name = "Reserved Instruction Fault"; -FaultVect ReservedInstructionFault::_vect = 0x0180; -FaultStat ReservedInstructionFault::_count; - -FaultName ThreadFault::_name = "Thread Fault"; -FaultVect ThreadFault::_vect = 0x00F1; -FaultStat ThreadFault::_count; - - -FaultName ArithmeticFault::_name = "Arithmetic Overflow Exception"; -FaultVect ArithmeticFault::_vect = 0x180; -FaultStat ArithmeticFault::_count; - -FaultName UnimplementedOpcodeFault::_name = "opdec"; -FaultVect UnimplementedOpcodeFault::_vect = 0x0481; -FaultStat UnimplementedOpcodeFault::_count; - -FaultName InterruptFault::_name = "interrupt"; -FaultVect InterruptFault::_vect = 0x0180; -FaultStat InterruptFault::_count; - -FaultName TrapFault::_name = "Trap"; -FaultVect TrapFault::_vect = 0x0180; -FaultStat TrapFault::_count; - -FaultName BreakpointFault::_name = "Breakpoint"; -FaultVect BreakpointFault::_vect = 0x0180; -FaultStat BreakpointFault::_count; - - -FaultName ItbInvalidFault::_name = "Invalid TLB Entry Exception (I-Fetch/LW)"; -FaultVect ItbInvalidFault::_vect = 0x0180; -FaultStat ItbInvalidFault::_count; - -FaultName ItbPageFault::_name = "itbmiss"; -FaultVect ItbPageFault::_vect = 0x0181; -FaultStat ItbPageFault::_count; - -FaultName ItbMissFault::_name = "itbmiss"; -FaultVect ItbMissFault::_vect = 0x0181; -FaultStat ItbMissFault::_count; - -FaultName ItbAcvFault::_name = "iaccvio"; -FaultVect ItbAcvFault::_vect = 0x0081; -FaultStat ItbAcvFault::_count; - -FaultName ItbRefillFault::_name = "TLB Refill Exception (I-Fetch/LW)"; -FaultVect ItbRefillFault::_vect = 0x0180; -FaultStat ItbRefillFault::_count; - -FaultName NDtbMissFault::_name = "dtb_miss_single"; -FaultVect NDtbMissFault::_vect = 0x0201; -FaultStat NDtbMissFault::_count; - -FaultName PDtbMissFault::_name = "dtb_miss_double"; -FaultVect PDtbMissFault::_vect = 0x0281; -FaultStat PDtbMissFault::_count; - -FaultName DtbPageFault::_name = "dfault"; -FaultVect DtbPageFault::_vect = 0x0381; -FaultStat DtbPageFault::_count; - -FaultName DtbAcvFault::_name = "dfault"; -FaultVect DtbAcvFault::_vect = 0x0381; -FaultStat DtbAcvFault::_count; - -FaultName DtbInvalidFault::_name = "Invalid TLB Entry Exception (Store)"; -FaultVect DtbInvalidFault::_vect = 0x0180; -FaultStat DtbInvalidFault::_count; - -FaultName DtbRefillFault::_name = "TLB Refill Exception (Store)"; -FaultVect DtbRefillFault::_vect = 0x0180; -FaultStat DtbRefillFault::_count; - -FaultName TLBModifiedFault::_name = "TLB Modified Exception"; -FaultVect TLBModifiedFault::_vect = 0x0180; -FaultStat TLBModifiedFault::_count; - -FaultName FloatEnableFault::_name = "float_enable_fault"; -FaultVect FloatEnableFault::_vect = 0x0581; -FaultStat FloatEnableFault::_count; - -FaultName IntegerOverflowFault::_name = "Integer Overflow Fault"; -FaultVect IntegerOverflowFault::_vect = 0x0501; -FaultStat IntegerOverflowFault::_count; - -FaultName DspStateDisabledFault::_name = "DSP Disabled Fault"; -FaultVect DspStateDisabledFault::_vect = 0x001a; -FaultStat DspStateDisabledFault::_count; - -#if FULL_SYSTEM -void ArmFault::setHandlerPC(Addr HandlerBase, ThreadContext *tc) -{ - tc->setPC(HandlerBase); - tc->setNextPC(HandlerBase+sizeof(MachInst)); - tc->setNextNPC(HandlerBase+2*sizeof(MachInst)); -} - -void ArmFault::setExceptionState(ThreadContext *tc,uint8_t ExcCode) -{ - // modify SRS Ctl - Save CSS, put ESS into CSS - MiscReg stat = tc->readMiscReg(ArmISA::Status); - if(bits(stat,Status_EXL) != 1 && bits(stat,Status_BEV) != 1) - { - // SRS Ctl is modified only if Status_EXL and Status_BEV are not set - MiscReg srs = tc->readMiscReg(ArmISA::SRSCtl); - uint8_t CSS,ESS; - CSS = bits(srs,SRSCtl_CSS_HI,SRSCtl_CSS_LO); - ESS = bits(srs,SRSCtl_ESS_HI,SRSCtl_ESS_LO); - // Move CSS to PSS - replaceBits(srs,SRSCtl_PSS_HI,SRSCtl_PSS_LO,CSS); - // Move ESS to CSS - replaceBits(srs,SRSCtl_CSS_HI,SRSCtl_CSS_LO,ESS); - tc->setMiscRegNoEffect(ArmISA::SRSCtl,srs); - //tc->setShadowSet(ESS); - } - - // set EXL bit (don't care if it is already set!) - replaceBits(stat,Status_EXL_HI,Status_EXL_LO,1); - tc->setMiscRegNoEffect(ArmISA::Status,stat); - - // write EPC - // warn("Set EPC to %x\n",tc->readPC()); - // CHECK ME or FIXME or FIX ME or POSSIBLE HACK - // Check to see if the exception occurred in the branch delay slot - DPRINTF(Arm,"PC: %x, NextPC: %x, NNPC: %x\n",tc->readPC(),tc->readNextPC(),tc->readNextNPC()); - int C_BD=0; - if(tc->readPC() + sizeof(MachInst) != tc->readNextPC()){ - tc->setMiscRegNoEffect(ArmISA::EPC,tc->readPC()-sizeof(MachInst)); - // In the branch delay slot? set CAUSE_31 - C_BD = 1; - } else { - tc->setMiscRegNoEffect(ArmISA::EPC,tc->readPC()); - // In the branch delay slot? reset CAUSE_31 - C_BD = 0; - } - - // Set Cause_EXCCODE field - MiscReg cause = tc->readMiscReg(ArmISA::Cause); - replaceBits(cause,Cause_EXCCODE_HI,Cause_EXCCODE_LO,ExcCode); - replaceBits(cause,Cause_BD_HI,Cause_BD_LO,C_BD); - replaceBits(cause,Cause_CE_HI,Cause_CE_LO,0); - tc->setMiscRegNoEffect(ArmISA::Cause,cause); - -} - -void ArithmeticFault::invoke(ThreadContext *tc) -{ - DPRINTF(Arm,"%s encountered.\n", name()); - setExceptionState(tc,0xC); - - // Set new PC - Addr HandlerBase; - MiscReg stat = tc->readMiscReg(ArmISA::Status); - // Here, the handler is dependent on BEV, which is not modified by setExceptionState() - if(bits(stat,Status_BEV)==0){ // See MIPS ARM Vol 3, Revision 2, Page 38 - HandlerBase= vect() + tc->readMiscReg(ArmISA::EBase); - }else{ - HandlerBase = 0xBFC00200; - } - setHandlerPC(HandlerBase,tc); - // warn("Exception Handler At: %x \n",HandlerBase); -} - -void StoreAddressErrorFault::invoke(ThreadContext *tc) -{ - DPRINTF(Arm,"%s encountered.\n", name()); - setExceptionState(tc,0x5); - tc->setMiscRegNoEffect(ArmISA::BadVAddr,BadVAddr); - - // Set new PC - Addr HandlerBase; - HandlerBase= vect() + tc->readMiscReg(ArmISA::EBase); // Offset 0x180 - General Exception Vector - setHandlerPC(HandlerBase,tc); - // warn("Exception Handler At: %x \n",HandlerBase); - // warn("Exception Handler At: %x , EPC set to %x\n",HandlerBase,tc->readMiscReg(ArmISA::EPC)); - -} - -void TrapFault::invoke(ThreadContext *tc) -{ - DPRINTF(Arm,"%s encountered.\n", name()); - // warn("%s encountered.\n", name()); - setExceptionState(tc,0xD); - - // Set new PC - Addr HandlerBase; - HandlerBase= vect() + tc->readMiscReg(ArmISA::EBase); // Offset 0x180 - General Exception Vector - setHandlerPC(HandlerBase,tc); - // warn("Exception Handler At: %x \n",HandlerBase); - // warn("Exception Handler At: %x , EPC set to %x\n",HandlerBase,tc->readMiscReg(ArmISA::EPC)); -} - -void BreakpointFault::invoke(ThreadContext *tc) -{ - setExceptionState(tc,0x9); - - // Set new PC - Addr HandlerBase; - HandlerBase= vect() + tc->readMiscReg(ArmISA::EBase); // Offset 0x180 - General Exception Vector - setHandlerPC(HandlerBase,tc); - // warn("Exception Handler At: %x \n",HandlerBase); - // warn("Exception Handler At: %x , EPC set to %x\n",HandlerBase,tc->readMiscReg(ArmISA::EPC)); - -} - -void DtbInvalidFault::invoke(ThreadContext *tc) +Addr +ArmFaultBase::getVector(ThreadContext *tc) { - DPRINTF(Arm,"%s encountered.\n", name()); - // warn("%s encountered.\n", name()); - tc->setMiscRegNoEffect(ArmISA::BadVAddr,BadVAddr); - MiscReg eh = tc->readMiscReg(ArmISA::EntryHi); - replaceBits(eh,EntryHi_ASID_HI,EntryHi_ASID_LO,EntryHi_Asid); - replaceBits(eh,EntryHi_VPN2_HI,EntryHi_VPN2_LO,EntryHi_VPN2); - replaceBits(eh,EntryHi_VPN2X_HI,EntryHi_VPN2X_LO,EntryHi_VPN2X); - tc->setMiscRegNoEffect(ArmISA::EntryHi,eh); - MiscReg ctxt = tc->readMiscReg(ArmISA::Context); - replaceBits(ctxt,Context_BadVPN2_HI,Context_BadVPN2_LO,Context_BadVPN2); - tc->setMiscRegNoEffect(ArmISA::Context,ctxt); - setExceptionState(tc,0x3); + // ARM ARM B1-3 + SCTLR sctlr = tc->readMiscReg(MISCREG_SCTLR); + + // panic if SCTLR.VE because I have no idea what to do with vectored + // interrupts + assert(!sctlr.ve); + + if (!sctlr.v) + return offset(); + return offset() + HighVecs; - // Set new PC - Addr HandlerBase; - HandlerBase= vect() + tc->readMiscReg(ArmISA::EBase); // Offset 0x180 - General Exception Vector - setHandlerPC(HandlerBase,tc); - // warn("Exception Handler At: %x , EPC set to %x\n",HandlerBase,tc->readMiscReg(ArmISA::EPC)); } -void AddressErrorFault::invoke(ThreadContext *tc) -{ - DPRINTF(Arm,"%s encountered.\n", name()); - setExceptionState(tc,0x4); - tc->setMiscRegNoEffect(ArmISA::BadVAddr,BadVAddr); - - // Set new PC - Addr HandlerBase; - HandlerBase= vect() + tc->readMiscReg(ArmISA::EBase); // Offset 0x180 - General Exception Vector - setHandlerPC(HandlerBase,tc); -} - -void ItbInvalidFault::invoke(ThreadContext *tc) -{ - DPRINTF(Arm,"%s encountered.\n", name()); - setExceptionState(tc,0x2); - tc->setMiscRegNoEffect(ArmISA::BadVAddr,BadVAddr); - MiscReg eh = tc->readMiscReg(ArmISA::EntryHi); - replaceBits(eh,EntryHi_ASID_HI,EntryHi_ASID_LO,EntryHi_Asid); - replaceBits(eh,EntryHi_VPN2_HI,EntryHi_VPN2_LO,EntryHi_VPN2); - replaceBits(eh,EntryHi_VPN2X_HI,EntryHi_VPN2X_LO,EntryHi_VPN2X); - tc->setMiscRegNoEffect(ArmISA::EntryHi,eh); - MiscReg ctxt = tc->readMiscReg(ArmISA::Context); - replaceBits(ctxt,Context_BadVPN2_HI,Context_BadVPN2_LO,Context_BadVPN2); - tc->setMiscRegNoEffect(ArmISA::Context,ctxt); - - - // Set new PC - Addr HandlerBase; - HandlerBase= vect() + tc->readMiscReg(ArmISA::EBase); // Offset 0x180 - General Exception Vector - setHandlerPC(HandlerBase,tc); - DPRINTF(Arm,"Exception Handler At: %x , EPC set to %x\n",HandlerBase,tc->readMiscReg(ArmISA::EPC)); -} - -void ItbRefillFault::invoke(ThreadContext *tc) -{ - DPRINTF(Arm,"%s encountered (%x).\n", name(),BadVAddr); - Addr HandlerBase; - tc->setMiscRegNoEffect(ArmISA::BadVAddr,BadVAddr); - MiscReg eh = tc->readMiscReg(ArmISA::EntryHi); - replaceBits(eh,EntryHi_ASID_HI,EntryHi_ASID_LO,EntryHi_Asid); - replaceBits(eh,EntryHi_VPN2_HI,EntryHi_VPN2_LO,EntryHi_VPN2); - replaceBits(eh,EntryHi_VPN2X_HI,EntryHi_VPN2X_LO,EntryHi_VPN2X); - tc->setMiscRegNoEffect(ArmISA::EntryHi,eh); - MiscReg ctxt = tc->readMiscReg(ArmISA::Context); - replaceBits(ctxt,Context_BadVPN2_HI,Context_BadVPN2_LO,Context_BadVPN2); - tc->setMiscRegNoEffect(ArmISA::Context,ctxt); - - MiscReg stat = tc->readMiscReg(ArmISA::Status); - // Since handler depends on EXL bit, must check EXL bit before setting it!! - if(bits(stat,Status_EXL)==1){ // See MIPS ARM Vol 3, Revision 2, Page 38 - HandlerBase= vect() + tc->readMiscReg(ArmISA::EBase); // Offset 0x180 - General Exception Vector - }else{ - HandlerBase = tc->readMiscReg(ArmISA::EBase); // Offset 0x000 - } - - setExceptionState(tc,0x2); - setHandlerPC(HandlerBase,tc); -} - -void DtbRefillFault::invoke(ThreadContext *tc) -{ - // Set new PC - DPRINTF(Arm,"%s encountered.\n", name()); - Addr HandlerBase; - tc->setMiscRegNoEffect(ArmISA::BadVAddr,BadVAddr); - MiscReg eh = tc->readMiscReg(ArmISA::EntryHi); - replaceBits(eh,EntryHi_ASID_HI,EntryHi_ASID_LO,EntryHi_Asid); - replaceBits(eh,EntryHi_VPN2_HI,EntryHi_VPN2_LO,EntryHi_VPN2); - replaceBits(eh,EntryHi_VPN2X_HI,EntryHi_VPN2X_LO,EntryHi_VPN2X); - tc->setMiscRegNoEffect(ArmISA::EntryHi,eh); - MiscReg ctxt = tc->readMiscReg(ArmISA::Context); - replaceBits(ctxt,Context_BadVPN2_HI,Context_BadVPN2_LO,Context_BadVPN2); - tc->setMiscRegNoEffect(ArmISA::Context,ctxt); - - MiscReg stat = tc->readMiscReg(ArmISA::Status); - // Since handler depends on EXL bit, must check EXL bit before setting it!! - if(bits(stat,Status_EXL)==1){ // See MIPS ARM Vol 3, Revision 2, Page 38 - HandlerBase= vect() + tc->readMiscReg(ArmISA::EBase); // Offset 0x180 - General Exception Vector - }else{ - HandlerBase = tc->readMiscReg(ArmISA::EBase); // Offset 0x000 - } - - - setExceptionState(tc,0x3); - - setHandlerPC(HandlerBase,tc); -} - -void TLBModifiedFault::invoke(ThreadContext *tc) -{ - DPRINTF(Arm,"%s encountered.\n", name()); - tc->setMiscRegNoEffect(ArmISA::BadVAddr,BadVAddr); - MiscReg eh = tc->readMiscReg(ArmISA::EntryHi); - replaceBits(eh,EntryHi_ASID_HI,EntryHi_ASID_LO,EntryHi_Asid); - replaceBits(eh,EntryHi_VPN2_HI,EntryHi_VPN2_LO,EntryHi_VPN2); - replaceBits(eh,EntryHi_VPN2X_HI,EntryHi_VPN2X_LO,EntryHi_VPN2X); - tc->setMiscRegNoEffect(ArmISA::EntryHi,eh); - MiscReg ctxt = tc->readMiscReg(ArmISA::Context); - replaceBits(ctxt,Context_BadVPN2_HI,Context_BadVPN2_LO,Context_BadVPN2); - tc->setMiscRegNoEffect(ArmISA::Context,ctxt); - - // Set new PC - Addr HandlerBase; - HandlerBase= vect() + tc->readMiscReg(ArmISA::EBase); // Offset 0x180 - General Exception Vector - setExceptionState(tc,0x1); - setHandlerPC(HandlerBase,tc); - // warn("Exception Handler At: %x , EPC set to %x\n",HandlerBase,tc->readMiscReg(ArmISA::EPC)); - -} - -void SystemCallFault::invoke(ThreadContext *tc) -{ - DPRINTF(Arm,"%s encountered.\n", name()); - setExceptionState(tc,0x8); - - // Set new PC - Addr HandlerBase; - HandlerBase= vect() + tc->readMiscReg(ArmISA::EBase); // Offset 0x180 - General Exception Vector - setHandlerPC(HandlerBase,tc); - // warn("Exception Handler At: %x \n",HandlerBase); - // warn("Exception Handler At: %x , EPC set to %x\n",HandlerBase,tc->readMiscReg(ArmISA::EPC)); - -} - -void InterruptFault::invoke(ThreadContext *tc) -{ -#if FULL_SYSTEM - DPRINTF(Arm,"%s encountered.\n", name()); - setExceptionState(tc,0x0A); - Addr HandlerBase; - - - uint8_t IV = bits(tc->readMiscRegNoEffect(ArmISA::Cause),Cause_IV); - if (IV)// Offset 200 for release 2 - HandlerBase= 0x20 + vect() + tc->readMiscRegNoEffect(ArmISA::EBase); - else//Ofset at 180 for release 1 - HandlerBase= vect() + tc->readMiscRegNoEffect(ArmISA::EBase); - - setHandlerPC(HandlerBase,tc); -#endif -} - -#endif // FULL_SYSTEM - -void ResetFault::invoke(ThreadContext *tc) -{ #if FULL_SYSTEM - DPRINTF(Arm,"%s encountered.\n", name()); - /* All reset activity must be invoked from here */ - tc->setPC(vect()); - tc->setNextPC(vect()+sizeof(MachInst)); - tc->setNextNPC(vect()+sizeof(MachInst)+sizeof(MachInst)); - DPRINTF(Arm,"(%x) - ResetFault::invoke : PC set to %x",(unsigned)tc,(unsigned)tc->readPC()); -#endif - // Set Coprocessor 1 (Floating Point) To Usable - //tc->setMiscReg(ArmISA::Status, ArmISA::Status | 0x20000000); -} - -void ReservedInstructionFault::invoke(ThreadContext *tc) -{ -#if FULL_SYSTEM - DPRINTF(Arm,"%s encountered.\n", name()); - setExceptionState(tc,0x0A); - Addr HandlerBase; - HandlerBase= vect() + tc->readMiscRegNoEffect(ArmISA::EBase); // Offset 0x180 - General Exception Vector - setHandlerPC(HandlerBase,tc); -#else - panic("%s encountered.\n", name()); -#endif -} - -void ThreadFault::invoke(ThreadContext *tc) -{ - DPRINTF(Arm,"%s encountered.\n", name()); - panic("%s encountered.\n", name()); -} - -void DspStateDisabledFault::invoke(ThreadContext *tc) -{ - DPRINTF(Arm,"%s encountered.\n", name()); - panic("%s encountered.\n", name()); +void +ArmFaultBase::invoke(ThreadContext *tc) +{ + // ARM ARM B1.6.3 + FaultBase::invoke(tc); + countStat()++; + + SCTLR sctlr = tc->readMiscReg(MISCREG_SCTLR); + CPSR cpsr = tc->readMiscReg(MISCREG_CPSR); + CPSR saved_cpsr = tc->readMiscReg(MISCREG_CPSR) | + tc->readIntReg(INTREG_CONDCODES); + + + cpsr.mode = nextMode(); + cpsr.it1 = cpsr.it2 = 0; + cpsr.j = 0; + + if (sctlr.te) + cpsr.t = 1; + cpsr.a = cpsr.a | abortDisable(); + cpsr.f = cpsr.f | fiqDisable(); + cpsr.i = 1; + tc->setMiscReg(MISCREG_CPSR, cpsr); + tc->setIntReg(INTREG_LR, tc->readPC() + + (saved_cpsr.t ? thumbPcOffset() : armPcOffset())); + + switch (nextMode()) { + case MODE_FIQ: + tc->setMiscReg(MISCREG_SPSR_FIQ, saved_cpsr); + break; + case MODE_IRQ: + tc->setMiscReg(MISCREG_SPSR_IRQ, saved_cpsr); + break; + case MODE_SVC: + tc->setMiscReg(MISCREG_SPSR_SVC, saved_cpsr); + break; + case MODE_UNDEFINED: + tc->setMiscReg(MISCREG_SPSR_UND, saved_cpsr); + break; + case MODE_ABORT: + tc->setMiscReg(MISCREG_SPSR_ABT, saved_cpsr); + break; + default: + panic("unknown Mode\n"); + } + + DPRINTF(Faults, "Invoking Fault: %s cpsr: %#x PC: %#x lr: %#x\n", name(), cpsr, + tc->readPC(), tc->readIntReg(INTREG_LR)); + tc->setPC(getVector(tc)); + tc->setNextPC(getVector(tc) + cpsr.t ? 2 : 4 ); } +#endif // FULL_SYSTEM -void CoprocessorUnusableFault::invoke(ThreadContext *tc) -{ -#if FULL_SYSTEM - DPRINTF(Arm,"%s encountered.\n", name()); - setExceptionState(tc,0xb); - /* The ID of the coprocessor causing the exception is stored in CoprocessorUnusableFault::coProcID */ - MiscReg cause = tc->readMiscReg(ArmISA::Cause); - replaceBits(cause,Cause_CE_HI,Cause_CE_LO,coProcID); - tc->setMiscRegNoEffect(ArmISA::Cause,cause); +// return via SUBS pc, lr, xxx; rfe, movs, ldm - Addr HandlerBase; - HandlerBase= vect() + tc->readMiscReg(ArmISA::EBase); // Offset 0x180 - General Exception Vector - setHandlerPC(HandlerBase,tc); - // warn("Status: %x, Cause: %x\n",tc->readMiscReg(ArmISA::Status),tc->readMiscReg(ArmISA::Cause)); -#else - warn("%s (CP%d) encountered.\n", name(), coProcID); -#endif -} } // namespace ArmISA diff --git a/src/arch/arm/faults.hh b/src/arch/arm/faults.hh index 28ecd7591..7f8aa66b6 100644 --- a/src/arch/arm/faults.hh +++ b/src/arch/arm/faults.hh @@ -26,548 +26,79 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * Authors: Gabe Black - * Stephen Hines + * Authors: Ali Saidi + * Gabe Black */ #ifndef __ARM_FAULTS_HH__ #define __ARM_FAULTS_HH__ +#include "arch/arm/types.hh" +#include "config/full_system.hh" #include "sim/faults.hh" // The design of the "name" and "vect" functions is in sim/faults.hh namespace ArmISA { -typedef const Addr FaultVect; +typedef const Addr FaultOffset; -class ArmFault : public FaultBase +class ArmFaultBase : public FaultBase { protected: - virtual bool skipFaultingInstruction() {return false;} - virtual bool setRestartAddress() {return true;} - public: - Addr BadVAddr; - Addr EntryHi_Asid; - Addr EntryHi_VPN2; - Addr EntryHi_VPN2X; - Addr Context_BadVPN2; -#if FULL_SYSTEM - void invoke(ThreadContext * tc) {}; - void setExceptionState(ThreadContext *,uint8_t); - void setHandlerPC(Addr,ThreadContext *); -#endif - virtual FaultVect vect() = 0; - virtual FaultStat & countStat() = 0; -}; - -class MachineCheckFault : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} - bool isMachineCheckFault() {return true;} -}; - -class NonMaskableInterrupt : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} - bool isNonMaskableInterrupt() {return true;} -}; - -class AlignmentFault : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} - bool isAlignmentFault() {return true;} -}; - -class AddressErrorFault : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} -#if FULL_SYSTEM - void invoke(ThreadContext * tc); -#endif - -}; -class StoreAddressErrorFault : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} -#if FULL_SYSTEM - void invoke(ThreadContext * tc); -#endif - -}; -class UnimplementedOpcodeFault : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} -}; - - -class TLBRefillIFetchFault : public ArmFault -{ - private: - Addr vaddr; - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} - void invoke(ThreadContext * tc); -}; -class TLBInvalidIFetchFault : public ArmFault -{ - private: - Addr vaddr; - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} - void invoke(ThreadContext * tc); -}; - -class NDtbMissFault : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} -}; - -class PDtbMissFault : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} -}; - -class DtbPageFault : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} -}; - -class DtbAcvFault : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} -}; - -class CacheErrorFault : public ArmFault -{ - private: - Addr vaddr; - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} - void invoke(ThreadContext * tc); -}; - - - - -static inline Fault genMachineCheckFault() -{ - return new MachineCheckFault; -} - -static inline Fault genAlignmentFault() -{ - return new AlignmentFault; -} - -class ResetFault : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} - void invoke(ThreadContext * tc); - -}; -class SystemCallFault : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} - void invoke(ThreadContext * tc); -}; - -class SoftResetFault : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} - void invoke(ThreadContext * tc); -}; -class DebugSingleStep : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} - void invoke(ThreadContext * tc); -}; -class DebugInterrupt : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} - void invoke(ThreadContext * tc); -}; - -class CoprocessorUnusableFault : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - int coProcID; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} - void invoke(ThreadContext * tc); - CoprocessorUnusableFault(int _procid){ coProcID = _procid;} -}; + Addr getVector(ThreadContext *tc); -class ReservedInstructionFault : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} - void invoke(ThreadContext * tc); -}; - -class ThreadFault : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} - void invoke(ThreadContext * tc); -}; + struct FaultVals + { + const FaultName name; + const FaultOffset offset; + const OperatingMode nextMode; + const uint8_t armPcOffset; + const uint8_t thumbPcOffset; + const bool abortDisable; + const bool fiqDisable; + FaultStat count; + }; - -class ArithmeticFault : public ArmFault -{ - protected: - bool skipFaultingInstruction() {return true;} - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} #if FULL_SYSTEM - void invoke(ThreadContext * tc); + void invoke(ThreadContext *tc); #endif + virtual FaultStat& countStat() = 0; + virtual FaultOffset offset() = 0; + virtual OperatingMode nextMode() = 0; + virtual uint8_t armPcOffset() = 0; + virtual uint8_t thumbPcOffset() = 0; + virtual bool abortDisable() = 0; + virtual bool fiqDisable() = 0; }; -class InterruptFault : public ArmFault +template +class ArmFault : public ArmFaultBase { protected: - bool setRestartAddress() {return false;} - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} - -#if FULL_SYSTEM - void invoke(ThreadContext * tc); -#endif - - //void invoke(ThreadContext * tc); -}; - -class TrapFault : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} -#if FULL_SYSTEM - void invoke(ThreadContext * tc); -#endif -}; - -class BreakpointFault : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} -#if FULL_SYSTEM - void invoke(ThreadContext * tc); -#endif -}; - -class ItbRefillFault : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} -#if FULL_SYSTEM - void invoke(ThreadContext * tc); -#endif -}; -class DtbRefillFault : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} -#if FULL_SYSTEM - void invoke(ThreadContext * tc); -#endif -}; - -class ItbPageFault : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} -#if FULL_SYSTEM - void invoke(ThreadContext * tc); -#endif -}; - -class ItbInvalidFault : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} -#if FULL_SYSTEM - void invoke(ThreadContext * tc); -#endif - -}; -class TLBModifiedFault : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} -#if FULL_SYSTEM - void invoke(ThreadContext * tc); -#endif - -}; + static FaultVals vals; -class DtbInvalidFault : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} -#if FULL_SYSTEM - void invoke(ThreadContext * tc); -#endif - + FaultName name() const { return vals.name; } + FaultStat & countStat() {return vals.count;} + FaultOffset offset() { return vals.offset; } + OperatingMode nextMode() { return vals.nextMode; } + uint8_t armPcOffset() { return vals.armPcOffset; } + uint8_t thumbPcOffset() { return vals.thumbPcOffset; } + bool abortDisable() { return vals.abortDisable; } + bool fiqDisable() { return vals.fiqDisable; } }; -class FloatEnableFault : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} -}; -class ItbMissFault : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} -}; +class Reset : public ArmFault {}; +class UndefinedInstruction : public ArmFault {}; +class SupervisorCall : public ArmFault {}; +class PrefetchAbort : public ArmFault {}; +class DataAbort : public ArmFault {}; +class Interrupt : public ArmFault {}; +class FastInterrupt : public ArmFault {}; -class ItbAcvFault : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} -}; - -class IntegerOverflowFault : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} -}; - -class DspStateDisabledFault : public ArmFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _count; - public: - FaultName name() const {return _name;} - FaultVect vect() {return _vect;} - FaultStat & countStat() {return _count;} - void invoke(ThreadContext * tc); -}; } // ArmISA namespace diff --git a/src/arch/arm/isa.hh b/src/arch/arm/isa.hh index a4a328614..a270f046b 100644 --- a/src/arch/arm/isa.hh +++ b/src/arch/arm/isa.hh @@ -85,6 +85,14 @@ namespace ArmISA cpsr.mode = MODE_USER; miscRegs[MISCREG_CPSR] = cpsr; updateRegMap(cpsr); + + SCTLR sctlr = 0; + sctlr.nmfi = 1; + sctlr.rao1 = 1; + sctlr.rao2 = 1; + sctlr.rao3 = 1; + sctlr.rao4 = 1; + //XXX We need to initialize the rest of the state. } diff --git a/src/arch/arm/isa/formats/unimp.isa b/src/arch/arm/isa/formats/unimp.isa index c82bb41c6..6909c3f85 100644 --- a/src/arch/arm/isa/formats/unimp.isa +++ b/src/arch/arm/isa/formats/unimp.isa @@ -115,7 +115,7 @@ output exec {{ panic("attempt to execute unimplemented instruction '%s' " "(inst 0x%08x, opcode 0x%x, binary:%s)", mnemonic, machInst, OPCODE, inst2string(machInst)); - return new UnimplementedOpcodeFault; + return new UnimpFault("Unimplemented Instruction"); } Fault diff --git a/src/arch/arm/isa/formats/unknown.isa b/src/arch/arm/isa/formats/unknown.isa index 2ad7a2506..97a0caa6b 100644 --- a/src/arch/arm/isa/formats/unknown.isa +++ b/src/arch/arm/isa/formats/unknown.isa @@ -74,7 +74,7 @@ output exec {{ { panic("attempt to execute unknown instruction " "(inst 0x%08x, opcode 0x%x, binary: %s)", machInst, OPCODE, inst2string(machInst)); - return new UnimplementedOpcodeFault; + return new UnimpFault("Unimplemented Instruction"); } }}; diff --git a/src/arch/arm/isa_traits.hh b/src/arch/arm/isa_traits.hh index 542174b6b..91c51c46b 100644 --- a/src/arch/arm/isa_traits.hh +++ b/src/arch/arm/isa_traits.hh @@ -104,6 +104,8 @@ namespace ArmISA const int WordBytes = 4; const int HalfwordBytes = 2; const int ByteBytes = 1; + + const uint32_t HighVecs = 0xFFFF0000; }; using namespace ArmISA; diff --git a/src/arch/arm/miscregs.hh b/src/arch/arm/miscregs.hh index ba394d49c..45233a764 100644 --- a/src/arch/arm/miscregs.hh +++ b/src/arch/arm/miscregs.hh @@ -55,7 +55,7 @@ namespace ArmISA enum MiscRegIndex { MISCREG_CPSR = 0, - MISCREG_SPSR, + MISCREG_SPSR, MISCREG_SPSR_FIQ, MISCREG_SPSR_IRQ, MISCREG_SPSR_SVC, @@ -66,13 +66,13 @@ namespace ArmISA MISCREG_FPSID, MISCREG_FPSCR, MISCREG_FPEXC, - NUM_MISCREGS + MISCREG_SCTLR, + NUM_MISCREGS }; const char * const miscRegName[NUM_MISCREGS] = { - "cpsr", - "spsr", "spsr_fiq", "spsr_irq", "spsr_svc", "spsr_und", "spsr_abt", - "fpsr" + "cpsr", "spsr", "spsr_fiq", "spsr_irq", "spsr_svc", "spsr_und", + "spsr_abt", "fpsr", "fpsid", "fpscr", "fpexc", "sctlr" }; BitUnion32(CPSR) @@ -81,8 +81,10 @@ namespace ArmISA Bitfield<29> c; Bitfield<28> v; Bitfield<27> q; + Bitfield<26,25> it1; Bitfield<24> j; Bitfield<19, 16> ge; + Bitfield<15,10> it2; Bitfield<9> e; Bitfield<8> a; Bitfield<7> i; @@ -90,6 +92,31 @@ namespace ArmISA Bitfield<5> t; Bitfield<4, 0> mode; EndBitUnion(CPSR) + + BitUnion32(SCTLR) + Bitfield<30> te; // Thumb Exception Enable + Bitfield<29> afe; // Access flag enable + Bitfield<28> tre; // TEX Remap bit + Bitfield<27> nmfi;// Non-maskable fast interrupts enable + Bitfield<25> ee; // Exception Endianness bit + Bitfield<24> ve; // Interrupt vectors enable + Bitfield<23> rao1;// Read as one + Bitfield<22> u; // Alignment (now unused) + Bitfield<21> fi; // Fast interrupts configuration enable + Bitfield<18> rao2;// Read as one + Bitfield<17> ha; // Hardware access flag enable + Bitfield<16> rao3;// Read as one + Bitfield<14> rr; // Round robin cache replacement + Bitfield<13> v; // Base address for exception vectors + Bitfield<12> i; // instruction cache enable + Bitfield<11> z; // branch prediction enable bit + Bitfield<10> sw; // Enable swp/swpb + Bitfield<6,3> rao4;// Read as one + Bitfield<7> b; // Endianness support (unused) + Bitfield<2> c; // Cache enable bit + Bitfield<1> a; // Alignment fault checking + Bitfield<0> m; // MMU enable bit + EndBitUnion(SCTLR) }; #endif // __ARCH_ARM_MISCREGS_HH__ diff --git a/src/arch/arm/utility.cc b/src/arch/arm/utility.cc new file mode 100644 index 000000000..8cfa48e18 --- /dev/null +++ b/src/arch/arm/utility.cc @@ -0,0 +1,19 @@ + +#include +#include + + +namespace ArmISA { + +void +initCPU(ThreadContext *tc, int cpuId) +{ + // Reset CP15?? What does that mean -- ali + + // FPEXC.EN = 0 + + static Fault reset = new Reset(); + if (cpuId == 0) + reset->invoke(tc); +} + -- cgit v1.2.3 From b8120f6c38f212acbfd246a3081842a9e3d06eb3 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 10 Nov 2009 21:10:18 -0800 Subject: Mem: Eliminate the NO_FAULT request flag. --- src/arch/alpha/faults.cc | 2 +- src/arch/alpha/isa/decoder.isa | 2 +- src/arch/alpha/isa/mem.isa | 2 +- src/arch/mips/isa/formats/mem.isa | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src/arch') diff --git a/src/arch/alpha/faults.cc b/src/arch/alpha/faults.cc index e93e16711..ff6de8d03 100644 --- a/src/arch/alpha/faults.cc +++ b/src/arch/alpha/faults.cc @@ -144,7 +144,7 @@ DtbFault::invoke(ThreadContext *tc) // read, like the EV5). The EV6 approach is cleaner and seems to // work with EV5 PAL code, but not the other way around. if (!tc->misspeculating() && - reqFlags.noneSet(Request::VPTE|Request::NO_FAULT)) { + reqFlags.noneSet(Request::VPTE | Request::PREFETCH)) { // set VA register with faulting address tc->setMiscRegNoEffect(IPR_VA, vaddr); diff --git a/src/arch/alpha/isa/decoder.isa b/src/arch/alpha/isa/decoder.isa index cb43fcb74..52e124ad5 100644 --- a/src/arch/alpha/isa/decoder.isa +++ b/src/arch/alpha/isa/decoder.isa @@ -627,7 +627,7 @@ decode OPCODE default Unknown::unknown() { format MiscPrefetch { 0xf800: wh64({{ EA = Rb & ~ULL(63); }}, {{ xc->writeHint(EA, 64, memAccessFlags); }}, - mem_flags = NO_FAULT, + mem_flags = PREFETCH, inst_flags = [IsMemRef, IsDataPrefetch, IsStore, MemWriteOp]); } diff --git a/src/arch/alpha/isa/mem.isa b/src/arch/alpha/isa/mem.isa index fedfbf55d..b1703221f 100644 --- a/src/arch/alpha/isa/mem.isa +++ b/src/arch/alpha/isa/mem.isa @@ -548,7 +548,7 @@ def format LoadOrPrefetch(memacc_code, ea_code = {{ EA = Rb + disp; }}, pf_flags = makeList(pf_flags) inst_flags = makeList(inst_flags) - pf_mem_flags = mem_flags + pf_flags + ['NO_FAULT'] + pf_mem_flags = mem_flags + pf_flags + ['PREFETCH'] pf_inst_flags = inst_flags + ['IsMemRef', 'IsLoad', 'IsDataPrefetch', 'MemReadOp'] diff --git a/src/arch/mips/isa/formats/mem.isa b/src/arch/mips/isa/formats/mem.isa index adcb16137..161a52b06 100644 --- a/src/arch/mips/isa/formats/mem.isa +++ b/src/arch/mips/isa/formats/mem.isa @@ -619,7 +619,7 @@ def format StoreUnalignedMemory(memacc_code, ea_code = {{ EA = (Rs + disp) & ~3; def format Prefetch(ea_code = {{ EA = Rs + disp; }}, mem_flags = [], pf_flags = [], inst_flags = []) {{ - pf_mem_flags = mem_flags + pf_flags + ['NO_FAULT'] + pf_mem_flags = mem_flags + pf_flags + ['PREFETCH'] pf_inst_flags = inst_flags + ['IsMemRef', 'IsLoad', 'IsDataPrefetch', 'MemReadOp'] -- cgit v1.2.3 From 5524af83efab8ee502f84987d56306ecd140ab80 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 10 Nov 2009 23:44:05 -0800 Subject: ARM: Fix some bugs in the ISA desc and fill out some instructions. --- src/arch/arm/isa/bitfields.isa | 1 + src/arch/arm/isa/decoder.isa | 64 +++++++++++++++++++++++----------- src/arch/arm/isa/formats/pred.isa | 72 +++++++++++++++++++++++++++------------ src/arch/arm/isa/operands.isa | 1 + src/arch/arm/types.hh | 1 + 5 files changed, 98 insertions(+), 41 deletions(-) (limited to 'src/arch') diff --git a/src/arch/arm/isa/bitfields.isa b/src/arch/arm/isa/bitfields.isa index 5785939cc..fc75ecf79 100644 --- a/src/arch/arm/isa/bitfields.isa +++ b/src/arch/arm/isa/bitfields.isa @@ -43,6 +43,7 @@ def bitfield OPCODE_23_20 opcode23_20; def bitfield OPCODE_23_21 opcode23_21; def bitfield OPCODE_22 opcode22; def bitfield OPCODE_19 opcode19; +def bitfield OPCODE_18 opcode18; def bitfield OPCODE_15_12 opcode15_12; def bitfield OPCODE_15 opcode15; def bitfield MISC_OPCODE miscOpcode; diff --git a/src/arch/arm/isa/decoder.isa b/src/arch/arm/isa/decoder.isa index ebadeb985..b4b820b06 100644 --- a/src/arch/arm/isa/decoder.isa +++ b/src/arch/arm/isa/decoder.isa @@ -51,20 +51,25 @@ format DataOp { resTemp = ((uint64_t)Rm)*((uint64_t)Rs); Rd = (uint32_t)(resTemp & 0xffffffff); Rn = (uint32_t)(resTemp >> 32); - }}); - 0x5: WarnUnimpl::smlal(); + }}, llbit); + 0x5: smlal({{ + resTemp = ((int64_t)Rm) * ((int64_t)Rs); + resTemp += (((uint64_t)Rn) << 32) | ((uint64_t)Rd); + Rd = (uint32_t)(resTemp & 0xffffffff); + Rn = (uint32_t)(resTemp >> 32); + }}, llbit); 0x6: smull({{ resTemp = ((int64_t)(int32_t)Rm)* ((int64_t)(int32_t)Rs); Rd = (int32_t)(resTemp & 0xffffffff); Rn = (int32_t)(resTemp >> 32); - }}); + }}, llbit); 0x7: umlal({{ resTemp = ((uint64_t)Rm)*((uint64_t)Rs); resTemp += ((uint64_t)Rn << 32)+((uint64_t)Rd); Rd = (uint32_t)(resTemp & 0xffffffff); Rn = (uint32_t)(resTemp >> 32); - }}); + }}, llbit); } 1: decode PUBWL { 0x10: WarnUnimpl::swp(); @@ -105,9 +110,17 @@ format DataOp { } 1: decode MISC_OPCODE { 0x0: decode OPCODE { - 0x8: WarnUnimpl::mrs_cpsr(); - 0x9: WarnUnimpl::msr_cpsr(); - 0xa: WarnUnimpl::mrs_spsr(); + 0x8: PredOp::mrs_cpsr({{ Rd = Cpsr | CondCodes; }}); + 0x9: PredOp::msr_cpsr({{ + //assert(!RN<1:0>); + if (OPCODE_18) { + Cpsr = Cpsr<31:20> | mbits(Rm, 19, 16) | Cpsr<15:0>; + } + if (OPCODE_19) { + CondCodes = mbits(Rm, 31,27); + } + }}); + 0xa: PredOp::mrs_spsr({{ Rd = 0; // should be SPSR}}); 0xb: WarnUnimpl::msr_spsr(); } 0x1: decode OPCODE { @@ -129,28 +142,32 @@ format DataOp { 0xb: WarnUnimpl::qdsub(); } 0x8: decode OPCODE { - 0x8: WarnUnimpl::smlabb(); + 0x8: smlabb({{ Rn = resTemp = sext<16>(Rm<15:0>) * sext<16>(Rs<15:0>) + Rd; }}, overflow); 0x9: WarnUnimpl::smlalbb(); 0xa: WarnUnimpl::smlawb(); - 0xb: WarnUnimpl::smulbb(); + 0xb: smulbb({{ Rn = resTemp = sext<16>(Rm<15:0>) * sext<16>(Rs<15:0>); }}, none); } 0xa: decode OPCODE { - 0x8: WarnUnimpl::smlatb(); - 0x9: WarnUnimpl::smulwb(); + 0x8: smlatb({{ Rn = resTemp = sext<16>(Rm<31:16>) * sext<16>(Rs<15:0>) + Rd; }}, overflow); + 0x9: smulwb({{ + Rn = resTemp = bits(sext<32>(Rm) * sext<16>(Rs<15:0>), 47, 16); + }}, none); 0xa: WarnUnimpl::smlaltb(); - 0xb: WarnUnimpl::smultb(); + 0xb: smultb({{ Rn = resTemp = sext<16>(Rm<31:16>) * sext<16>(Rs<15:0>); }}, none); } 0xc: decode OPCODE { - 0x8: WarnUnimpl::smlabt(); + 0x8: smlabt({{ Rn = resTemp = sext<16>(Rm<15:0>) * sext<16>(Rs<31:16>) + Rd; }}, overflow); 0x9: WarnUnimpl::smlawt(); 0xa: WarnUnimpl::smlalbt(); - 0xb: WarnUnimpl::smulbt(); + 0xb: smulbt({{ Rn = resTemp = sext<16>(Rm<15:0>) * sext<16>(Rs<31:16>); }}, none); } 0xe: decode OPCODE { - 0x8: WarnUnimpl::smlatt(); - 0x9: WarnUnimpl::smulwt(); + 0x8: smlatt({{ Rn = resTemp = sext<16>(Rm<31:16>) * sext<16>(Rs<31:16>) + Rd; }}, overflow); + 0x9: smulwt({{ + Rn = resTemp = bits(sext<32>(Rm) * sext<16>(Rs<31:16>), 47, 16); + }}, none); 0xa: WarnUnimpl::smlaltt(); - 0xb: WarnUnimpl::smultt(); + 0xb: smultt({{ Rn = resTemp = sext<16>(Rm<31:16>) * sext<16>(Rs<31:16>); }}, none); } } } @@ -184,8 +201,16 @@ format DataOp { } 1: decode OPCODE { // The following two instructions aren't supposed to be defined - 0x8: WarnUnimpl::undefined_instruction(); - 0x9: WarnUnimpl::undefined_instruction(); + 0x8: DataOp::movw({{ Rd = IMMED_11_0 | (RN << 12) ; }}); + 0x9: DataImmOp::msr_ia_cpsr ({{ + //assert(!RN<1:0>); + if (OPCODE_18) { + Cpsr = Cpsr<31:20> | rotated_imm | Cpsr<15:0>; + } + if (OPCODE_19) { + CondCodes = rotated_imm; + } + }}); 0xa: WarnUnimpl::mrs_i_cpsr(); 0xb: WarnUnimpl::mrs_i_spsr(); @@ -440,6 +465,7 @@ format DataOp { } } } + 0xf: WarnUnimpl::mcr_cp15(); } format PredOp { // ARM System Call (SoftWare Interrupt) diff --git a/src/arch/arm/isa/formats/pred.isa b/src/arch/arm/isa/formats/pred.isa index 3c97560fd..0d6ee32f7 100644 --- a/src/arch/arm/isa/formats/pred.isa +++ b/src/arch/arm/isa/formats/pred.isa @@ -81,32 +81,45 @@ def template DataImmDecode {{ }}; let {{ + + calcCcCode = ''' + if (%(canOverflow)s){ + cprintf("canOverflow: %%d\\n", Rd < resTemp); + replaceBits(CondCodes, 27, Rd < resTemp); + } else { + uint16_t _ic, _iv, _iz, _in; + _in = (resTemp >> %(negBit)d) & 1; + _iz = (resTemp == 0); + _iv = %(ivValue)s & 1; + _ic = %(icValue)s & 1; + + CondCodes = _in << 31 | _iz << 30 | _ic << 29 | _iv << 28 | + (CondCodes & 0x0FFFFFFF); - calcCcCode = ''' - uint16_t _ic, _iv, _iz, _in; - - _in = (resTemp >> 31) & 1; - _iz = (resTemp == 0); - _iv = %(ivValue)s & 1; - _ic = %(icValue)s & 1; - - CondCodes = _in << 31 | _iz << 30 | _ic << 29 | _iv << 28 | - (CondCodes & 0x0FFFFFFF); - - DPRINTF(Arm, "in = %%d\\n", _in); - DPRINTF(Arm, "iz = %%d\\n", _iz); - DPRINTF(Arm, "ic = %%d\\n", _ic); - DPRINTF(Arm, "iv = %%d\\n", _iv); + DPRINTF(Arm, "in = %%d\\n", _in); + DPRINTF(Arm, "iz = %%d\\n", _iz); + DPRINTF(Arm, "ic = %%d\\n", _ic); + DPRINTF(Arm, "iv = %%d\\n", _iv); + } ''' - }}; let {{ def getCcCode(flagtype): icReg = icImm = iv = '' + negBit = 31 + canOverflow = 'false' + if flagtype == "none": icReg = icImm = 'CondCodes<29:>' iv = 'CondCodes<28:>' + elif flagtype == "llbit": + icReg = icImm = 'CondCodes<29:>' + iv = 'CondCodes<28:>' + negBit = 63 + elif flagtype == "overflow": + canOverflow = "true" + icReg = icImm = iv = '0' elif flagtype == "add": icReg = icImm = 'findCarry(32, resTemp, Rn, op2)' iv = 'findOverflow(32, resTemp, Rn, op2)' @@ -117,17 +130,32 @@ let {{ icReg = icImm = 'findCarry(32, resTemp, op2, ~Rn)' iv = 'findOverflow(32, resTemp, op2, ~Rn)' else: - icReg = 'shift_carry_rs(Rm, Rs, shift, CondCodes<29:>)' + icReg = 'shift_carry_rs(Rm, Rs<7:0>, shift, CondCodes<29:>)' icImm = 'shift_carry_imm(Rm, shift_size, shift, CondCodes<29:>)' iv = 'CondCodes<28:>' - return (calcCcCode % {"icValue" : icReg, "ivValue" : iv}, - calcCcCode % {"icValue" : icImm, "ivValue" : iv}) + return (calcCcCode % {"icValue" : icReg, + "ivValue" : iv, + "negBit" : negBit, + "canOverflow" : canOverflow }, + calcCcCode % {"icValue" : icImm, + "ivValue" : iv, + "negBit" : negBit, + "canOverflow" : canOverflow }) def getImmCcCode(flagtype): ivValue = icValue = '' + negBit = 31 + canOverflow = 'false' if flagtype == "none": icValue = 'CondCodes<29:>' ivValue = 'CondCodes<28:>' + elif flagtype == "llbit": + icValue = 'CondCodes<29:>' + ivValue = 'CondCodes<28:>' + negBit = 63 + elif flagtype == "overflow": + icVaule = ivValue = '0' + canOverflow = "true" elif flagtype == "add": icValue = 'findCarry(32, resTemp, Rn, rotated_imm)' ivValue = 'findOverflow(32, resTemp, Rn, rotated_imm)' @@ -145,11 +173,11 @@ let {{ def format DataOp(code, flagtype = logic) {{ (regCcCode, immCcCode) = getCcCode(flagtype) - regCode = '''uint32_t op2 = shift_rm_rs(Rm, Rs, - shift, CondCodes<29:0>); + regCode = '''uint32_t op2 = shift_rm_rs(Rm, Rs<7:0>, + shift, CondCodes<29:>); op2 = op2;''' + code immCode = '''uint32_t op2 = shift_rm_imm(Rm, shift_size, - shift, CondCodes<29:0>); + shift, CondCodes<29:>); op2 = op2;''' + code regIop = InstObjParams(name, Name, 'PredIntOp', {"code": regCode, diff --git a/src/arch/arm/isa/operands.isa b/src/arch/arm/isa/operands.isa index 02acc8ed7..5ae0b8912 100644 --- a/src/arch/arm/isa/operands.isa +++ b/src/arch/arm/isa/operands.isa @@ -58,6 +58,7 @@ def operands {{ 'Rs': ('IntReg', 'uw', 'RS', 'IsInteger', 3, maybePCRead, maybePCWrite), 'Rn': ('IntReg', 'uw', 'RN', 'IsInteger', 4, maybePCRead, maybePCWrite), 'R7': ('IntReg', 'uw', '7', 'IsInteger', 5), + 'R0': ('IntReg', 'uw', '0', 'IsInteger', 0), #Destination register for load/store double instructions 'Rdo': ('IntReg', 'uw', '(RD & ~1)', 'IsInteger', 4, maybePCRead, maybePCWrite), diff --git a/src/arch/arm/types.hh b/src/arch/arm/types.hh index d5cc07eaf..237bf8412 100644 --- a/src/arch/arm/types.hh +++ b/src/arch/arm/types.hh @@ -52,6 +52,7 @@ namespace ArmISA Bitfield<23, 21> opcode23_21; Bitfield<22> opcode22; Bitfield<19> opcode19; + Bitfield<18> opcode18; Bitfield<15, 12> opcode15_12; Bitfield<15> opcode15; Bitfield<7, 4> miscOpcode; -- cgit v1.2.3 From 8f6744c19c7d6cf87a207e901503c3435c1ff7a9 Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Wed, 11 Nov 2009 17:49:09 -0500 Subject: X86: add ULL to 1's being shifted in 64-bit values Some of the micro-ops weren't casting 1 to ULL before shifting, which can cause problems. On the perl makerand input this caused some values to be negative that shouldn't have been. The casts are done as ULL(1) instead of 1ULL to match others in the m5 code base. --- src/arch/x86/isa/microops/mediaop.isa | 31 ++++++++++++++++--------------- src/arch/x86/isa/microops/regop.isa | 4 ++-- 2 files changed, 18 insertions(+), 17 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/microops/mediaop.isa b/src/arch/x86/isa/microops/mediaop.isa index fa32583b0..4052f254d 100644 --- a/src/arch/x86/isa/microops/mediaop.isa +++ b/src/arch/x86/isa/microops/mediaop.isa @@ -452,7 +452,7 @@ let {{ if (signBit) { if (overflow != mask(destBits - srcBits + 1)) { if (ext & 0x1) - picked = (1 << (destBits - 1)); + picked = (ULL(1) << (destBits - 1)); else picked = 0; } @@ -480,7 +480,7 @@ let {{ if (signBit) { if (overflow != mask(destBits - srcBits + 1)) { if (ext & 0x1) - picked = (1 << (destBits - 1)); + picked = (ULL(1) << (destBits - 1)); else picked = 0; } @@ -642,10 +642,10 @@ let {{ int loIndex = (i + 0) * sizeBits; uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex); int64_t arg1 = arg1Bits | - (0 - (arg1Bits & (1 << (sizeBits - 1)))); + (0 - (arg1Bits & (ULL(1) << (sizeBits - 1)))); uint64_t arg2Bits = bits(FpSrcReg2.uqw, hiIndex, loIndex); int64_t arg2 = arg2Bits | - (0 - (arg2Bits & (1 << (sizeBits - 1)))); + (0 - (arg2Bits & (ULL(1) << (sizeBits - 1)))); uint64_t resBits; if (ext & 0x2) { @@ -680,10 +680,10 @@ let {{ int loIndex = (i + 0) * sizeBits; uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex); int64_t arg1 = arg1Bits | - (0 - (arg1Bits & (1 << (sizeBits - 1)))); + (0 - (arg1Bits & (ULL(1) << (sizeBits - 1)))); uint64_t arg2Bits = bits(FpSrcReg2.uqw, hiIndex, loIndex); int64_t arg2 = arg2Bits | - (0 - (arg2Bits & (1 << (sizeBits - 1)))); + (0 - (arg2Bits & (ULL(1) << (sizeBits - 1)))); uint64_t resBits; if (ext & 0x2) { @@ -957,7 +957,7 @@ let {{ int resSign = bits(resBits, sizeBits - 1); if ((arg1Sign == arg2Sign) && (arg1Sign != resSign)) { if (resSign == 0) - resBits = (1 << (sizeBits - 1)); + resBits = (ULL(1) << (sizeBits - 1)); else resBits = mask(sizeBits - 1); } @@ -996,7 +996,7 @@ let {{ int resSign = bits(resBits, sizeBits - 1); if ((arg1Sign == arg2Sign) && (arg1Sign != resSign)) { if (resSign == 0) - resBits = (1 << (sizeBits - 1)); + resBits = (ULL(1) << (sizeBits - 1)); else resBits = mask(sizeBits - 1); } @@ -1032,16 +1032,16 @@ let {{ if (ext & 0x2) { int64_t arg1 = arg1Bits | - (0 - (arg1Bits & (1 << (srcBits - 1)))); + (0 - (arg1Bits & (ULL(1) << (srcBits - 1)))); int64_t arg2 = arg2Bits | - (0 - (arg2Bits & (1 << (srcBits - 1)))); + (0 - (arg2Bits & (ULL(1) << (srcBits - 1)))); resBits = (uint64_t)(arg1 * arg2); } else { resBits = arg1Bits * arg2Bits; } if (ext & 0x4) - resBits += (1 << (destBits - 1)); + resBits += (ULL(1) << (destBits - 1)); if (ext & 0x8) resBits >>= destBits; @@ -1142,7 +1142,7 @@ let {{ } else { resBits = (arg1Bits >> shiftAmt); resBits = resBits | - (0 - (resBits & (1 << (sizeBits - 1 - shiftAmt)))); + (0 - (resBits & (ULL(1) << (sizeBits - 1 - shiftAmt)))); } result = insertBits(result, hiIndex, loIndex, resBits); @@ -1289,7 +1289,8 @@ let {{ int srcHiIndex = srcStart + (i + 1) * srcSizeBits - 1; int srcLoIndex = srcStart + (i + 0) * srcSizeBits; uint64_t argBits = bits(FpSrcReg1.uqw, srcHiIndex, srcLoIndex); - int64_t sArg = argBits | (0 - (argBits & (1 << srcHiIndex))); + + int64_t sArg = argBits | (0 - (argBits & (ULL(1) << srcHiIndex))); double arg = sArg; if (destSize == 4) { @@ -1400,10 +1401,10 @@ let {{ int loIndex = (i + 0) * sizeBits; uint64_t arg1Bits = bits(FpSrcReg1.uqw, hiIndex, loIndex); int64_t arg1 = arg1Bits | - (0 - (arg1Bits & (1 << (sizeBits - 1)))); + (0 - (arg1Bits & (ULL(1) << (sizeBits - 1)))); uint64_t arg2Bits = bits(FpSrcReg2.uqw, hiIndex, loIndex); int64_t arg2 = arg2Bits | - (0 - (arg2Bits & (1 << (sizeBits - 1)))); + (0 - (arg2Bits & (ULL(1) << (sizeBits - 1)))); uint64_t resBits = 0; if (((ext & 0x2) == 0 && arg1 == arg2) || diff --git a/src/arch/x86/isa/microops/regop.isa b/src/arch/x86/isa/microops/regop.isa index fd1ad6925..0b1f9a96a 100644 --- a/src/arch/x86/isa/microops/regop.isa +++ b/src/arch/x86/isa/microops/regop.isa @@ -525,7 +525,7 @@ let {{ code = ''' ProdLow = psrc1 * op2; int halfSize = (dataSize * 8) / 2; - uint64_t shifter = (1ULL << halfSize); + uint64_t shifter = (ULL(1) << halfSize); uint64_t hiResult; uint64_t psrc1_h = psrc1 / shifter; uint64_t psrc1_l = psrc1 & mask(halfSize); @@ -553,7 +553,7 @@ let {{ code = ''' ProdLow = psrc1 * op2; int halfSize = (dataSize * 8) / 2; - uint64_t shifter = (1ULL << halfSize); + uint64_t shifter = (ULL(1) << halfSize); uint64_t psrc1_h = psrc1 / shifter; uint64_t psrc1_l = psrc1 & mask(halfSize); uint64_t psrc2_h = (op2 / shifter) & mask(halfSize); -- cgit v1.2.3 From 48bc573f5f9709480da458e3c4627f7b7afd38f4 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Sat, 14 Nov 2009 11:25:00 -0600 Subject: ARM: Move around decoder to properly decode CP15 --- src/arch/arm/isa/bitfields.isa | 1 + src/arch/arm/isa/decoder.isa | 206 +++++++++++++++++++++-------------------- src/arch/arm/types.hh | 1 + 3 files changed, 109 insertions(+), 99 deletions(-) (limited to 'src/arch') diff --git a/src/arch/arm/isa/bitfields.isa b/src/arch/arm/isa/bitfields.isa index fc75ecf79..816cd4b6d 100644 --- a/src/arch/arm/isa/bitfields.isa +++ b/src/arch/arm/isa/bitfields.isa @@ -42,6 +42,7 @@ def bitfield OPCODE_24 opcode24; def bitfield OPCODE_23_20 opcode23_20; def bitfield OPCODE_23_21 opcode23_21; def bitfield OPCODE_22 opcode22; +def bitfield OPCODE_20 opcode20; def bitfield OPCODE_19 opcode19; def bitfield OPCODE_18 opcode18; def bitfield OPCODE_15_12 opcode15_12; diff --git a/src/arch/arm/isa/decoder.isa b/src/arch/arm/isa/decoder.isa index b4b820b06..20b544a7c 100644 --- a/src/arch/arm/isa/decoder.isa +++ b/src/arch/arm/isa/decoder.isa @@ -355,77 +355,79 @@ format DataOp { } } 0x7: decode OPCODE_24 { - 0: decode CPNUM { - // Coprocessor Instructions - 0x1: decode OPCODE_4 { + 0: decode OPCODE_4 { + 0: decode CPNUM { format FloatOp { - // Basic FPA Instructions - 0: decode OPCODE_23_20 { - 0x0: decode OPCODE_15 { - 0: adf({{ Fd.sf = Fn.sf + Fm.sf; }}); - 1: mvf({{ Fd.sf = Fm.sf; }}); - } - 0x1: decode OPCODE_15 { - 0: muf({{ Fd.sf = Fn.sf * Fm.sf; }}); - 1: mnf({{ Fd.sf = -Fm.sf; }}); - } - 0x2: decode OPCODE_15 { - 0: suf({{ Fd.sf = Fn.sf - Fm.sf; }}); - 1: abs({{ Fd.sf = fabs(Fm.sf); }}); - } - 0x3: decode OPCODE_15 { - 0: rsf({{ Fd.sf = Fm.sf - Fn.sf; }}); - 1: rnd({{ Fd.sf = rint(Fm.sf); }}); - } - 0x4: decode OPCODE_15 { - 0: dvf({{ Fd.sf = Fn.sf / Fm.sf; }}); - 1: sqt({{ Fd.sf = sqrt(Fm.sf); }}); - } - 0x5: decode OPCODE_15 { - 0: rdf({{ Fd.sf = Fm.sf / Fn.sf; }}); - 1: log({{ Fd.sf = log10(Fm.sf); }}); - } - 0x6: decode OPCODE_15 { - 0: pow({{ Fd.sf = pow(Fm.sf, Fn.sf); }}); - 1: lgn({{ Fd.sf = log(Fm.sf); }}); - } - 0x7: decode OPCODE_15 { - 0: rpw({{ Fd.sf = pow(Fn.sf, Fm.sf); }}); - 1: exp({{ Fd.sf = exp(Fm.sf); }}); - } - 0x8: decode OPCODE_15 { - 0: rmf({{ Fd.sf = drem(Fn.sf, Fm.sf); }}); - 1: sin({{ Fd.sf = sin(Fm.sf); }}); - } - 0x9: decode OPCODE_15 { - 0: fml({{ Fd.sf = Fn.sf * Fm.sf; }}); - 1: cos({{ Fd.sf = cos(Fm.sf); }}); - } - 0xa: decode OPCODE_15 { - 0: fdv({{ Fd.sf = Fn.sf / Fm.sf; }}); - 1: tan({{ Fd.sf = tan(Fm.sf); }}); - } - 0xb: decode OPCODE_15 { - 0: frd({{ Fd.sf = Fm.sf / Fn.sf; }}); - 1: asn({{ Fd.sf = asin(Fm.sf); }}); - } - 0xc: decode OPCODE_15 { - 0: pol({{ Fd.sf = atan2(Fn.sf, Fm.sf); }}); - 1: acs({{ Fd.sf = acos(Fm.sf); }}); - } - 0xd: decode OPCODE_15 { - 1: atn({{ Fd.sf = atan(Fm.sf); }}); - } - 0xe: decode OPCODE_15 { - // Unnormalised Round - 1: FailUnimpl::urd(); - } - 0xf: decode OPCODE_15 { - // Normalise - 1: FailUnimpl::nrm(); - } - } - 1: decode OPCODE_15_12 { + 0x1: decode OPCODE_23_20 { + 0x0: decode OPCODE_15 { + 0: adf({{ Fd.sf = Fn.sf + Fm.sf; }}); + 1: mvf({{ Fd.sf = Fm.sf; }}); + } + 0x1: decode OPCODE_15 { + 0: muf({{ Fd.sf = Fn.sf * Fm.sf; }}); + 1: mnf({{ Fd.sf = -Fm.sf; }}); + } + 0x2: decode OPCODE_15 { + 0: suf({{ Fd.sf = Fn.sf - Fm.sf; }}); + 1: abs({{ Fd.sf = fabs(Fm.sf); }}); + } + 0x3: decode OPCODE_15 { + 0: rsf({{ Fd.sf = Fm.sf - Fn.sf; }}); + 1: rnd({{ Fd.sf = rint(Fm.sf); }}); + } + 0x4: decode OPCODE_15 { + 0: dvf({{ Fd.sf = Fn.sf / Fm.sf; }}); + 1: sqt({{ Fd.sf = sqrt(Fm.sf); }}); + } + 0x5: decode OPCODE_15 { + 0: rdf({{ Fd.sf = Fm.sf / Fn.sf; }}); + 1: log({{ Fd.sf = log10(Fm.sf); }}); + } + 0x6: decode OPCODE_15 { + 0: pow({{ Fd.sf = pow(Fm.sf, Fn.sf); }}); + 1: lgn({{ Fd.sf = log(Fm.sf); }}); + } + 0x7: decode OPCODE_15 { + 0: rpw({{ Fd.sf = pow(Fn.sf, Fm.sf); }}); + 1: exp({{ Fd.sf = exp(Fm.sf); }}); + } + 0x8: decode OPCODE_15 { + 0: rmf({{ Fd.sf = drem(Fn.sf, Fm.sf); }}); + 1: sin({{ Fd.sf = sin(Fm.sf); }}); + } + 0x9: decode OPCODE_15 { + 0: fml({{ Fd.sf = Fn.sf * Fm.sf; }}); + 1: cos({{ Fd.sf = cos(Fm.sf); }}); + } + 0xa: decode OPCODE_15 { + 0: fdv({{ Fd.sf = Fn.sf / Fm.sf; }}); + 1: tan({{ Fd.sf = tan(Fm.sf); }}); + } + 0xb: decode OPCODE_15 { + 0: frd({{ Fd.sf = Fm.sf / Fn.sf; }}); + 1: asn({{ Fd.sf = asin(Fm.sf); }}); + } + 0xc: decode OPCODE_15 { + 0: pol({{ Fd.sf = atan2(Fn.sf, Fm.sf); }}); + 1: acs({{ Fd.sf = acos(Fm.sf); }}); + } + 0xd: decode OPCODE_15 { + 1: atn({{ Fd.sf = atan(Fm.sf); }}); + } + 0xe: decode OPCODE_15 { + // Unnormalised Round + 1: FailUnimpl::urd(); + } + 0xf: decode OPCODE_15 { + // Normalise + 1: FailUnimpl::nrm(); + } + } // OPCODE_23_20 + } // format FloatOp + } // CPNUM + 1: decode CPNUM { // 27-24=1110,4 ==1 + 1: decode OPCODE_15_12 { + format FloatOp { 0xf: decode OPCODE_23_21 { format FloatCmp { 0x4: cmf({{ Fn.df }}, {{ Fm.df }}); @@ -448,37 +450,43 @@ format DataOp { 0x4: FailUnimpl::wfc(); 0x5: FailUnimpl::rfc(); } - } - } - } - 0xa: decode MISC_OPCODE { - 0x1: decode MEDIA_OPCODE { - 0xf: decode RN { - 0x0: FloatOp::fmrx_fpsid({{ Rd = Fpsid; }}); - 0x1: FloatOp::fmrx_fpscr({{ Rd = Fpscr; }}); - 0x8: FloatOp::fmrx_fpexc({{ Rd = Fpexc; }}); - } - 0xe: decode RN { - 0x0: FloatOp::fmxr_fpsid({{ Fpsid = Rd; }}); - 0x1: FloatOp::fmxr_fpscr({{ Fpscr = Rd; }}); - 0x8: FloatOp::fmxr_fpexc({{ Fpexc = Rd; }}); - } + } // format FloatOp } + 0xa: decode MISC_OPCODE { + 0x1: decode MEDIA_OPCODE { + 0xf: decode RN { + 0x0: FloatOp::fmrx_fpsid({{ Rd = Fpsid; }}); + 0x1: FloatOp::fmrx_fpscr({{ Rd = Fpscr; }}); + 0x8: FloatOp::fmrx_fpexc({{ Rd = Fpexc; }}); + } + 0xe: decode RN { + 0x0: FloatOp::fmxr_fpsid({{ Fpsid = Rd; }}); + 0x1: FloatOp::fmxr_fpscr({{ Fpscr = Rd; }}); + 0x8: FloatOp::fmxr_fpexc({{ Fpexc = Rd; }}); + } + } // MEDIA_OPCODE (MISC_OPCODE 0x1) + } // MISC_OPCODE (CPNUM 0xA) + 0xf: decode OPCODE_20 { + 0: WarnUnimpl::mcr_cp15(); + 1: WarnUnimpl::mrc_cp15(); + } + } // CPNUM (OP4 == 1) + } //OPCODE_4 + +#if FULL_SYSTEM + 1: PredOp::swi({{ fault = new SupervisorCall; }}, IsSerializeAfter, IsNonSpeculative, IsSyscall); +#else + 1: PredOp::swi({{ if (testPredicate(CondCodes, condCode)) + { + if (IMMED_23_0) + xc->syscall(IMMED_23_0); + else + xc->syscall(R7); } - 0xf: WarnUnimpl::mcr_cp15(); - } - format PredOp { - // ARM System Call (SoftWare Interrupt) - 1: swi({{ if (testPredicate(CondCodes, condCode)) - { - if (IMMED_23_0) - xc->syscall(IMMED_23_0); - else - xc->syscall(R7); - } - }}); - } - } + }}); +#endif // FULL_SYSTEM + } // OPCODE_24 + } } diff --git a/src/arch/arm/types.hh b/src/arch/arm/types.hh index 237bf8412..e37fd3a1f 100644 --- a/src/arch/arm/types.hh +++ b/src/arch/arm/types.hh @@ -50,6 +50,7 @@ namespace ArmISA Bitfield<24> opcode24; Bitfield<23, 20> opcode23_20; Bitfield<23, 21> opcode23_21; + Bitfield<20> opcode20; Bitfield<22> opcode22; Bitfield<19> opcode19; Bitfield<18> opcode18; -- cgit v1.2.3 From 50b9149c7572b4cff351f2c28726226030cefdbd Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sat, 14 Nov 2009 19:22:29 -0800 Subject: ARM: Hook up the moded versions of the SPSR. These registers can be accessed directly, or through MISCREG_SPSR which will act as whichever SPSR is appropriate for the current mode. --- src/arch/arm/isa.hh | 56 +++++++++++++++++++++++++++++++++++++++---- src/arch/arm/isa/operands.isa | 13 +++++----- 2 files changed, 59 insertions(+), 10 deletions(-) (limited to 'src/arch') diff --git a/src/arch/arm/isa.hh b/src/arch/arm/isa.hh index a270f046b..905eb0183 100644 --- a/src/arch/arm/isa.hh +++ b/src/arch/arm/isa.hh @@ -100,20 +100,69 @@ namespace ArmISA readMiscRegNoEffect(int misc_reg) { assert(misc_reg < NumMiscRegs); + if (misc_reg == MISCREG_SPSR) { + CPSR cpsr = miscRegs[MISCREG_CPSR]; + switch (cpsr.mode) { + case MODE_USER: + return miscRegs[MISCREG_SPSR]; + case MODE_FIQ: + return miscRegs[MISCREG_SPSR_FIQ]; + case MODE_IRQ: + return miscRegs[MISCREG_SPSR_IRQ]; + case MODE_SVC: + return miscRegs[MISCREG_SPSR_SVC]; + case MODE_MON: + return miscRegs[MISCREG_SPSR_MON]; + case MODE_ABORT: + return miscRegs[MISCREG_SPSR_ABT]; + case MODE_UNDEFINED: + return miscRegs[MISCREG_SPSR_UND]; + default: + return miscRegs[MISCREG_SPSR]; + } + } return miscRegs[misc_reg]; } MiscReg readMiscReg(int misc_reg, ThreadContext *tc) { - assert(misc_reg < NumMiscRegs); - return miscRegs[misc_reg]; + return readMiscRegNoEffect(misc_reg); } void setMiscRegNoEffect(int misc_reg, const MiscReg &val) { assert(misc_reg < NumMiscRegs); + if (misc_reg == MISCREG_SPSR) { + CPSR cpsr = miscRegs[MISCREG_CPSR]; + switch (cpsr.mode) { + case MODE_USER: + miscRegs[MISCREG_SPSR] = val; + return; + case MODE_FIQ: + miscRegs[MISCREG_SPSR_FIQ] = val; + return; + case MODE_IRQ: + miscRegs[MISCREG_SPSR_IRQ] = val; + return; + case MODE_SVC: + miscRegs[MISCREG_SPSR_SVC] = val; + return; + case MODE_MON: + miscRegs[MISCREG_SPSR_MON] = val; + return; + case MODE_ABORT: + miscRegs[MISCREG_SPSR_ABT] = val; + return; + case MODE_UNDEFINED: + miscRegs[MISCREG_SPSR_UND] = val; + return; + default: + miscRegs[MISCREG_SPSR] = val; + return; + } + } miscRegs[misc_reg] = val; } @@ -123,8 +172,7 @@ namespace ArmISA if (misc_reg == MISCREG_CPSR) { updateRegMap(val); } - assert(misc_reg < NumMiscRegs); - miscRegs[misc_reg] = val; + return setMiscRegNoEffect(misc_reg, val); } int diff --git a/src/arch/arm/isa/operands.isa b/src/arch/arm/isa/operands.isa index 5ae0b8912..fe085cdac 100644 --- a/src/arch/arm/isa/operands.isa +++ b/src/arch/arm/isa/operands.isa @@ -82,11 +82,12 @@ def operands {{ 'Mem': ('Mem', 'uw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 30), 'Cpsr': ('ControlReg', 'uw', 'MISCREG_CPSR', 'IsInteger', 40), - 'Fpsr': ('ControlReg', 'uw', 'MISCREG_FPSR', 'IsInteger', 41), - 'Fpsid': ('ControlReg', 'uw', 'MISCREG_FPSID', 'IsInteger', 42), - 'Fpscr': ('ControlReg', 'uw', 'MISCREG_FPSCR', 'IsInteger', 43), - 'Fpexc': ('ControlReg', 'uw', 'MISCREG_FPEXC', 'IsInteger', 44), - 'NPC': ('NPC', 'uw', None, (None, None, 'IsControl'), 45), - 'NNPC': ('NNPC', 'uw', None, (None, None, 'IsControl'), 46) + 'Spsr': ('ControlReg', 'uw', 'MISCREG_SPSR', 'IsInteger', 41), + 'Fpsr': ('ControlReg', 'uw', 'MISCREG_FPSR', 'IsInteger', 42), + 'Fpsid': ('ControlReg', 'uw', 'MISCREG_FPSID', 'IsInteger', 43), + 'Fpscr': ('ControlReg', 'uw', 'MISCREG_FPSCR', 'IsInteger', 44), + 'Fpexc': ('ControlReg', 'uw', 'MISCREG_FPEXC', 'IsInteger', 45), + 'NPC': ('NPC', 'uw', None, (None, None, 'IsControl'), 50), + 'NNPC': ('NNPC', 'uw', None, (None, None, 'IsControl'), 51) }}; -- cgit v1.2.3 From 1df0025e28d8f9699f86fc118db3b93a0f1ec50c Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sat, 14 Nov 2009 19:22:29 -0800 Subject: ARM: More accurately describe the effects of using the control operands. --- src/arch/arm/isa/operands.isa | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src/arch') diff --git a/src/arch/arm/isa/operands.isa b/src/arch/arm/isa/operands.isa index fe085cdac..aadefc79c 100644 --- a/src/arch/arm/isa/operands.isa +++ b/src/arch/arm/isa/operands.isa @@ -81,12 +81,12 @@ def operands {{ #Memory Operand 'Mem': ('Mem', 'uw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 30), - 'Cpsr': ('ControlReg', 'uw', 'MISCREG_CPSR', 'IsInteger', 40), - 'Spsr': ('ControlReg', 'uw', 'MISCREG_SPSR', 'IsInteger', 41), - 'Fpsr': ('ControlReg', 'uw', 'MISCREG_FPSR', 'IsInteger', 42), - 'Fpsid': ('ControlReg', 'uw', 'MISCREG_FPSID', 'IsInteger', 43), - 'Fpscr': ('ControlReg', 'uw', 'MISCREG_FPSCR', 'IsInteger', 44), - 'Fpexc': ('ControlReg', 'uw', 'MISCREG_FPEXC', 'IsInteger', 45), + 'Cpsr': ('ControlReg', 'uw', 'MISCREG_CPSR', (None, None, 'IsControl'), 40), + 'Spsr': ('ControlReg', 'uw', 'MISCREG_SPSR', (None, None, 'IsControl'), 41), + 'Fpsr': ('ControlReg', 'uw', 'MISCREG_FPSR', (None, None, 'IsControl'), 42), + 'Fpsid': ('ControlReg', 'uw', 'MISCREG_FPSID', (None, None, 'IsControl'), 43), + 'Fpscr': ('ControlReg', 'uw', 'MISCREG_FPSCR', (None, None, 'IsControl'), 44), + 'Fpexc': ('ControlReg', 'uw', 'MISCREG_FPEXC', (None, None, 'IsControl'), 45), 'NPC': ('NPC', 'uw', None, (None, None, 'IsControl'), 50), 'NNPC': ('NNPC', 'uw', None, (None, None, 'IsControl'), 51) -- cgit v1.2.3 From 812e390693253818c49585daf35692759a1c82d4 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sat, 14 Nov 2009 19:22:29 -0800 Subject: ARM: Fix up the implmentation of the mrs instruction. --- src/arch/arm/isa/decoder.isa | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src/arch') diff --git a/src/arch/arm/isa/decoder.isa b/src/arch/arm/isa/decoder.isa index 20b544a7c..cd13fa420 100644 --- a/src/arch/arm/isa/decoder.isa +++ b/src/arch/arm/isa/decoder.isa @@ -110,7 +110,9 @@ format DataOp { } 1: decode MISC_OPCODE { 0x0: decode OPCODE { - 0x8: PredOp::mrs_cpsr({{ Rd = Cpsr | CondCodes; }}); + 0x8: PredOp::mrs_cpsr({{ + Rd = (Cpsr | CondCodes) & 0xF8FF03DF; + }}); 0x9: PredOp::msr_cpsr({{ //assert(!RN<1:0>); if (OPCODE_18) { @@ -120,7 +122,7 @@ format DataOp { CondCodes = mbits(Rm, 31,27); } }}); - 0xa: PredOp::mrs_spsr({{ Rd = 0; // should be SPSR}}); + 0xa: PredOp::mrs_spsr({{ Rd = Spsr; }}); 0xb: WarnUnimpl::msr_spsr(); } 0x1: decode OPCODE { -- cgit v1.2.3 From e543f162475b93a1cae7f301a7edd76067d81ba7 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sat, 14 Nov 2009 19:22:30 -0800 Subject: ARM: Write some functions to write to the CPSR and SPSR for instructions. --- src/arch/arm/insts/static_inst.hh | 50 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) (limited to 'src/arch') diff --git a/src/arch/arm/insts/static_inst.hh b/src/arch/arm/insts/static_inst.hh index c963c1827..f2881c3b6 100644 --- a/src/arch/arm/insts/static_inst.hh +++ b/src/arch/arm/insts/static_inst.hh @@ -74,6 +74,56 @@ class ArmStaticInst : public StaticInst void printDataInst(std::ostream &os, bool withImm) const; std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; + + static uint32_t + cpsrWriteByInstr(CPSR cpsr, uint32_t val, + uint8_t byteMask, bool affectState) + { + bool privileged = (cpsr.mode != MODE_USER); + + uint32_t bitMask = 0; + + if (bits(byteMask, 3)) { + unsigned lowIdx = affectState ? 24 : 27; + bitMask = bitMask | mask(31, lowIdx); + } + if (bits(byteMask, 2)) { + bitMask = bitMask | mask(19, 16); + } + if (bits(byteMask, 1)) { + unsigned highIdx = affectState ? 15 : 9; + unsigned lowIdx = privileged ? 8 : 9; + bitMask = bitMask | mask(highIdx, lowIdx); + } + if (bits(byteMask, 0)) { + if (privileged) { + bitMask = bitMask | mask(7, 6); + bitMask = bitMask | mask(5); + } + if (affectState) + bitMask = bitMask | (1 << 5); + } + + return ((uint32_t)cpsr & ~bitMask) | (val & bitMask); + } + + static uint32_t + spsrWriteByInstr(uint32_t spsr, uint32_t val, + uint8_t byteMask, bool affectState) + { + uint32_t bitMask = 0; + + if (bits(byteMask, 3)) + bitMask = bitMask | mask(31, 24); + if (bits(byteMask, 2)) + bitMask = bitMask | mask(19, 16); + if (bits(byteMask, 1)) + bitMask = bitMask | mask(15, 8); + if (bits(byteMask, 0)) + bitMask = bitMask | mask(7, 0); + + return ((spsr & ~bitMask) | (val & bitMask)); + } }; } -- cgit v1.2.3 From 425ebf6bd736d6a7172476a81e935c7b83467dc9 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sat, 14 Nov 2009 19:22:30 -0800 Subject: ARM: Add a bitfield to indicate if an immediate should be used. --- src/arch/arm/isa/bitfields.isa | 1 + src/arch/arm/types.hh | 1 + 2 files changed, 2 insertions(+) (limited to 'src/arch') diff --git a/src/arch/arm/isa/bitfields.isa b/src/arch/arm/isa/bitfields.isa index 816cd4b6d..bd4cfc320 100644 --- a/src/arch/arm/isa/bitfields.isa +++ b/src/arch/arm/isa/bitfields.isa @@ -38,6 +38,7 @@ def bitfield ENCODING encoding; def bitfield OPCODE opcode; def bitfield MEDIA_OPCODE mediaOpcode; def bitfield MEDIA_OPCODE2 mediaOpcode2; +def bitfield USEIMM useImm; def bitfield OPCODE_24 opcode24; def bitfield OPCODE_23_20 opcode23_20; def bitfield OPCODE_23_21 opcode23_21; diff --git a/src/arch/arm/types.hh b/src/arch/arm/types.hh index e37fd3a1f..07fa33ea1 100644 --- a/src/arch/arm/types.hh +++ b/src/arch/arm/types.hh @@ -45,6 +45,7 @@ namespace ArmISA // All the different types of opcode fields. Bitfield<27, 25> encoding; + Bitfield<25> useImm; Bitfield<24, 21> opcode; Bitfield<24, 20> mediaOpcode; Bitfield<24> opcode24; -- cgit v1.2.3 From e2ab64543b2a206c95fbf38565a50f0d5bba0f2a Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sat, 14 Nov 2009 19:22:30 -0800 Subject: ARM: Define a mask to differentiate purely CPSR bits from CondCodes bits. --- src/arch/arm/miscregs.hh | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/arch') diff --git a/src/arch/arm/miscregs.hh b/src/arch/arm/miscregs.hh index 45233a764..d100efb8e 100644 --- a/src/arch/arm/miscregs.hh +++ b/src/arch/arm/miscregs.hh @@ -93,6 +93,10 @@ namespace ArmISA Bitfield<4, 0> mode; EndBitUnion(CPSR) + // This mask selects bits of the CPSR that actually go in the CondCodes + // integer register to allow renaming. + static const uint32_t CondCodesMask = 0xF80F0000; + BitUnion32(SCTLR) Bitfield<30> te; // Thumb Exception Enable Bitfield<29> afe; // Access flag enable -- cgit v1.2.3 From c4042985d7b13ddd6afdd3748e9c619863f1233a Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sat, 14 Nov 2009 19:22:30 -0800 Subject: ARM: Fix up the implmentation of the msr instruction. --- src/arch/arm/isa/decoder.isa | 37 +++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) (limited to 'src/arch') diff --git a/src/arch/arm/isa/decoder.isa b/src/arch/arm/isa/decoder.isa index cd13fa420..5e82feb1b 100644 --- a/src/arch/arm/isa/decoder.isa +++ b/src/arch/arm/isa/decoder.isa @@ -113,17 +113,34 @@ format DataOp { 0x8: PredOp::mrs_cpsr({{ Rd = (Cpsr | CondCodes) & 0xF8FF03DF; }}); - 0x9: PredOp::msr_cpsr({{ - //assert(!RN<1:0>); - if (OPCODE_18) { - Cpsr = Cpsr<31:20> | mbits(Rm, 19, 16) | Cpsr<15:0>; - } - if (OPCODE_19) { - CondCodes = mbits(Rm, 31,27); - } - }}); + 0x9: decode USEIMM { + // The mask field is the same as the RN index. + 0: PredImmOp::msr_cpsr_imm({{ + uint32_t newCpsr = + cpsrWriteByInstr(Cpsr | CondCodes, + rotated_imm, RN, false); + Cpsr = ~CondCodesMask & newCpsr; + CondCodes = CondCodesMask & newCpsr; + }}); + 1: PredOp::msr_cpsr_reg({{ + uint32_t newCpsr = + cpsrWriteByInstr(Cpsr | CondCodes, + Rm, RN, false); + Cpsr = ~CondCodesMask & newCpsr; + CondCodes = CondCodesMask & newCpsr; + }}); + } 0xa: PredOp::mrs_spsr({{ Rd = Spsr; }}); - 0xb: WarnUnimpl::msr_spsr(); + 0xb: decode USEIMM { + // The mask field is the same as the RN index. + 0: PredImmOp::msr_spsr_imm({{ + Spsr = spsrWriteByInstr(Spsr, rotated_imm, + RN, false); + }}); + 1: PredOp::msr_spsr_reg({{ + Spsr = spsrWriteByInstr(Spsr, Rm, RN, false); + }}); + } } 0x1: decode OPCODE { 0x9: BranchExchange::bx({{ }}); -- cgit v1.2.3 From b41725f7234e17d6d66d697ef415a4cb1bae80d9 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sat, 14 Nov 2009 21:03:10 -0800 Subject: ARM: Check in the actual change from the last commit. The last commit was somehow empty. This was what was supposed to go in it. --- src/arch/arm/isa/decoder.isa | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'src/arch') diff --git a/src/arch/arm/isa/decoder.isa b/src/arch/arm/isa/decoder.isa index 5e82feb1b..27af81382 100644 --- a/src/arch/arm/isa/decoder.isa +++ b/src/arch/arm/isa/decoder.isa @@ -115,17 +115,17 @@ format DataOp { }}); 0x9: decode USEIMM { // The mask field is the same as the RN index. - 0: PredImmOp::msr_cpsr_imm({{ + 0: PredOp::msr_cpsr_reg({{ uint32_t newCpsr = cpsrWriteByInstr(Cpsr | CondCodes, - rotated_imm, RN, false); + Rm, RN, false); Cpsr = ~CondCodesMask & newCpsr; CondCodes = CondCodesMask & newCpsr; }}); - 1: PredOp::msr_cpsr_reg({{ + 1: PredImmOp::msr_cpsr_imm({{ uint32_t newCpsr = cpsrWriteByInstr(Cpsr | CondCodes, - Rm, RN, false); + rotated_imm, RN, false); Cpsr = ~CondCodesMask & newCpsr; CondCodes = CondCodesMask & newCpsr; }}); @@ -133,13 +133,13 @@ format DataOp { 0xa: PredOp::mrs_spsr({{ Rd = Spsr; }}); 0xb: decode USEIMM { // The mask field is the same as the RN index. - 0: PredImmOp::msr_spsr_imm({{ + 0: PredOp::msr_spsr_reg({{ + Spsr = spsrWriteByInstr(Spsr, Rm, RN, false); + }}); + 1: PredImmOp::msr_spsr_imm({{ Spsr = spsrWriteByInstr(Spsr, rotated_imm, RN, false); }}); - 1: PredOp::msr_spsr_reg({{ - Spsr = spsrWriteByInstr(Spsr, Rm, RN, false); - }}); } } 0x1: decode OPCODE { -- cgit v1.2.3 From 903fb8c73df6feec125204fb4e636468f17b5eec Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 15 Nov 2009 00:15:42 -0800 Subject: ARM: Create a new type of load uop that restores spsr into cpsr. --- src/arch/arm/isa/formats/macromem.isa | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'src/arch') diff --git a/src/arch/arm/isa/formats/macromem.isa b/src/arch/arm/isa/formats/macromem.isa index 9a3185af3..ad27b5a56 100644 --- a/src/arch/arm/isa/formats/macromem.isa +++ b/src/arch/arm/isa/formats/macromem.isa @@ -72,6 +72,18 @@ let {{ 'predicate_test': predicateTest}, ['IsMicroop']) + microLdrRetUopCode = ''' + Ra = Mem; + Cpsr = cpsrWriteByInstr(Cpsr, Spsr, 0xF, true); + ''' + microLdrRetUopIop = InstObjParams('ldr_ret_uop', 'MicroLdrRetUop', + 'MicroMemOp', + {'memacc_code': microLdrRetUopCode, + 'ea_code': + 'EA = Rb + (UP ? imm : -imm);', + 'predicate_test': predicateTest}, + ['IsMicroop']) + microStrUopIop = InstObjParams('str_uop', 'MicroStrUop', 'MicroMemOp', {'memacc_code': 'Mem = Ra;', @@ -80,14 +92,19 @@ let {{ ['IsMicroop']) header_output = MicroMemDeclare.subst(microLdrUopIop) + \ + MicroMemDeclare.subst(microLdrRetUopIop) + \ MicroMemDeclare.subst(microStrUopIop) decoder_output = MicroConstructor.subst(microLdrUopIop) + \ + MicroConstructor.subst(microLdrRetUopIop) + \ MicroConstructor.subst(microStrUopIop) exec_output = LoadExecute.subst(microLdrUopIop) + \ + LoadExecute.subst(microLdrRetUopIop) + \ StoreExecute.subst(microStrUopIop) + \ LoadInitiateAcc.subst(microLdrUopIop) + \ + LoadInitiateAcc.subst(microLdrRetUopIop) + \ StoreInitiateAcc.subst(microStrUopIop) + \ LoadCompleteAcc.subst(microLdrUopIop) + \ + LoadCompleteAcc.subst(microLdrRetUopIop) + \ StoreCompleteAcc.subst(microStrUopIop) }}; -- cgit v1.2.3 From 9127ee5ac8913eacfc62967bd4b275a1845d8a9b Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 15 Nov 2009 00:23:14 -0800 Subject: ARM: Make the exception return form of ldm restore CPSR. --- src/arch/arm/isa/formats/macromem.isa | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'src/arch') diff --git a/src/arch/arm/isa/formats/macromem.isa b/src/arch/arm/isa/formats/macromem.isa index ad27b5a56..068b48199 100644 --- a/src/arch/arm/isa/formats/macromem.isa +++ b/src/arch/arm/isa/formats/macromem.isa @@ -210,6 +210,7 @@ inline %(class_name)s::%(class_name)s(ExtMachInst machInst) microOps[0] = new MicroAddiUop(machInst, INTREG_UREG0, RN, 0); unsigned reg = 0; + bool forceUser = machInst.puswl.psruser; for (int i = 1; i < ones + 1; i++) { // Find the next register. while (!bits(regs, reg)) @@ -217,13 +218,19 @@ inline %(class_name)s::%(class_name)s(ExtMachInst machInst) replaceBits(regs, reg, 0); unsigned regIdx = reg; - if (machInst.puswl.psruser) { + if (forceUser) { regIdx = intRegForceUser(regIdx); } if (machInst.puswl.loadOp) { - microOps[i] = - new MicroLdrUop(machInst, regIdx, INTREG_UREG0, addr); + if (reg == INTREG_PC && forceUser) { + // This must be the exception return form of ldm. + microOps[i] = + new MicroLdrRetUop(machInst, regIdx, INTREG_UREG0, addr); + } else { + microOps[i] = + new MicroLdrUop(machInst, regIdx, INTREG_UREG0, addr); + } } else { microOps[i] = new MicroStrUop(machInst, regIdx, INTREG_UREG0, addr); -- cgit v1.2.3 From 171e7f7b24eead1fa82202549e3fad9a0df7b017 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Mon, 16 Nov 2009 11:37:03 -0600 Subject: imported patch isa_fixes2.diff --- src/arch/arm/isa/decoder.isa | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) (limited to 'src/arch') diff --git a/src/arch/arm/isa/decoder.isa b/src/arch/arm/isa/decoder.isa index 27af81382..5a6e8773a 100644 --- a/src/arch/arm/isa/decoder.isa +++ b/src/arch/arm/isa/decoder.isa @@ -221,18 +221,26 @@ format DataOp { 1: decode OPCODE { // The following two instructions aren't supposed to be defined 0x8: DataOp::movw({{ Rd = IMMED_11_0 | (RN << 12) ; }}); - 0x9: DataImmOp::msr_ia_cpsr ({{ - //assert(!RN<1:0>); - if (OPCODE_18) { - Cpsr = Cpsr<31:20> | rotated_imm | Cpsr<15:0>; - } - if (OPCODE_19) { - CondCodes = rotated_imm; - } + 0x9: decode RN { + 0: decode IMM { + 0: PredImmOp::nop({{ ; }}); + 1: WarnUnimpl::yield(); + 2: WarnUnimpl::wfe(); + 3: WarnUnimpl::wfi(); + 4: WarnUnimpl::sev(); + } + default: PredImmOp::msr_i_cpsr({{ + uint32_t newCpsr = + cpsrWriteByInstr(Cpsr | CondCodes, + rotated_imm, RN, false); + Cpsr = ~CondCodesMask & newCpsr; + CondCodes = CondCodesMask & newCpsr; + }}); + } + 0xa: PredOp::movt({{ Rd = IMMED_11_0 << 16 | RN << 28 | Rd<15:0>; }}); + 0xb: PredImmOp::msr_i_spsr({{ + Spsr = spsrWriteByInstr(Spsr, rotated_imm, RN, false); }}); - - 0xa: WarnUnimpl::mrs_i_cpsr(); - 0xb: WarnUnimpl::mrs_i_spsr(); } } 0x2: AddrMode2::addrMode2(Disp, disp); -- cgit v1.2.3 From 1470dae8e949eaef8232dc621d9074329357265c Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Tue, 17 Nov 2009 18:02:08 -0600 Subject: ARM: Boilerplate full-system code. --HG-- rename : src/arch/sparc/interrupts.hh => src/arch/arm/interrupts.hh rename : src/arch/sparc/kernel_stats.hh => src/arch/arm/kernel_stats.hh rename : src/arch/sparc/stacktrace.cc => src/arch/arm/stacktrace.cc rename : src/arch/sparc/system.cc => src/arch/arm/system.cc rename : src/arch/sparc/system.hh => src/arch/arm/system.hh rename : src/dev/sparc/T1000.py => src/dev/arm/Versatile.py rename : src/dev/sparc/t1000.cc => src/dev/arm/versatile.cc rename : src/dev/sparc/t1000.hh => src/dev/arm/versatile.hh --- src/arch/arm/ArmInterrupts.py | 33 +++++++++ src/arch/arm/ArmSystem.py | 35 ++++++++++ src/arch/arm/SConscript | 11 ++- src/arch/arm/interrupts.cc | 37 +++++++++++ src/arch/arm/interrupts.hh | 121 +++++++++++++++++++++++++++++++++ src/arch/arm/kernel_stats.hh | 57 ++++++++++++++++ src/arch/arm/stacktrace.cc | 151 ++++++++++++++++++++++++++++++++++++++++++ src/arch/arm/stacktrace.hh | 17 ++--- src/arch/arm/system.cc | 51 ++++++++++++++ src/arch/arm/system.hh | 56 ++++++++++++++++ src/arch/arm/tlb.cc | 10 ++- src/arch/arm/utility.cc | 47 ++++++++++++- src/arch/arm/utility.hh | 11 +++ 13 files changed, 619 insertions(+), 18 deletions(-) create mode 100644 src/arch/arm/ArmInterrupts.py create mode 100644 src/arch/arm/ArmSystem.py create mode 100644 src/arch/arm/interrupts.cc create mode 100644 src/arch/arm/interrupts.hh create mode 100644 src/arch/arm/kernel_stats.hh create mode 100644 src/arch/arm/stacktrace.cc create mode 100644 src/arch/arm/system.cc create mode 100644 src/arch/arm/system.hh (limited to 'src/arch') diff --git a/src/arch/arm/ArmInterrupts.py b/src/arch/arm/ArmInterrupts.py new file mode 100644 index 000000000..f21d49e95 --- /dev/null +++ b/src/arch/arm/ArmInterrupts.py @@ -0,0 +1,33 @@ +# Copyright (c) 2009 ARM Limited +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# Authors: Ali Saidi + +from m5.SimObject import SimObject + +class ArmInterrupts(SimObject): + type = 'ArmInterrupts' + cxx_class = 'ArmISA::Interrupts' diff --git a/src/arch/arm/ArmSystem.py b/src/arch/arm/ArmSystem.py new file mode 100644 index 000000000..872776c69 --- /dev/null +++ b/src/arch/arm/ArmSystem.py @@ -0,0 +1,35 @@ +# Copyright (c) 2009 ARM Limited +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# Authors: Ali Saidi + +from m5.params import * + +from System import System + +class ArmSystem(System): + type = 'ArmSystem' + diff --git a/src/arch/arm/SConscript b/src/arch/arm/SConscript index f5fe1727c..92a4193f1 100644 --- a/src/arch/arm/SConscript +++ b/src/arch/arm/SConscript @@ -1,6 +1,7 @@ # -*- mode:python -*- # Copyright (c) 2007-2008 The Florida State University +# Copyright (c) 2009 ARM Limited # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -27,6 +28,7 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # Authors: Stephen Hines +# Ali Saidi Import('*') @@ -43,6 +45,7 @@ if env['TARGET_ISA'] == 'arm': Source('pagetable.cc') Source('tlb.cc') Source('vtophys.cc') + Source('utility.cc') SimObject('ArmNativeTrace.py') SimObject('ArmTLB.py') @@ -50,8 +53,12 @@ if env['TARGET_ISA'] == 'arm': TraceFlag('Arm') TraceFlag('Faults', "Trace Exceptions, interrupts, svc/swi") if env['FULL_SYSTEM']: - #Insert Full-System Files Here - pass + Source('interrupts.cc') + Source('stacktrace.cc') + Source('system.cc') + + SimObject('ArmInterrupts.py') + SimObject('ArmSystem.py') else: Source('process.cc') Source('linux/linux.cc') diff --git a/src/arch/arm/interrupts.cc b/src/arch/arm/interrupts.cc new file mode 100644 index 000000000..a47ebc75d --- /dev/null +++ b/src/arch/arm/interrupts.cc @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2009 ARM Limited + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Ali Saidi + */ + +#include "arch/arm/interrupts.hh" + +ArmISA::Interrupts * +ArmInterruptsParams::create() +{ + return new ArmISA::Interrupts(this); +} diff --git a/src/arch/arm/interrupts.hh b/src/arch/arm/interrupts.hh new file mode 100644 index 000000000..189341d6b --- /dev/null +++ b/src/arch/arm/interrupts.hh @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2006 The Regents of The University of Michigan + * Copyright (c) 2009 ARM Limited + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Ali Saidi + */ + +#ifndef __ARCH_ARM_INTERRUPT_HH__ +#define __ARCH_ARM_INTERRUPT_HH__ + +#include "arch/arm/faults.hh" +#include "arch/arm/isa_traits.hh" +#include "arch/arm/registers.hh" +#include "cpu/thread_context.hh" +#include "params/ArmInterrupts.hh" +#include "sim/sim_object.hh" + +namespace ArmISA +{ + +class Interrupts : public SimObject +{ + private: + BaseCPU * cpu; + + uint64_t intStatus; + + public: + + void + setCPU(BaseCPU * _cpu) + { + cpu = _cpu; + } + + typedef ArmInterruptsParams Params; + + const Params * + params() const + { + return dynamic_cast(_params); + } + + Interrupts(Params * p) : SimObject(p), cpu(NULL) + { + clearAll(); + } + + + void + post(int int_num, int index) + { + } + + void + clear(int int_num, int index) + { + } + + void + clearAll() + { + intStatus = 0; + } + + bool + checkInterrupts(ThreadContext *tc) const + { + return intStatus; + } + + Fault + getInterrupt(ThreadContext *tc) + { + warn_once("ARM Interrupts not handled\n"); + return NoFault; + } + + void + updateIntrInfo(ThreadContext *tc) + { + + } + + void + serialize(std::ostream &os) + { + } + + void + unserialize(Checkpoint *cp, const std::string §ion) + { + } +}; +} // namespace ARM_ISA + +#endif // __ARCH_ARM_INTERRUPT_HH__ diff --git a/src/arch/arm/kernel_stats.hh b/src/arch/arm/kernel_stats.hh new file mode 100644 index 000000000..18bdc500d --- /dev/null +++ b/src/arch/arm/kernel_stats.hh @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2004-2005 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Gabe Black + */ + +#ifndef __ARCH_ARM_KERNEL_STATS_HH__ +#define __ARCH_ARM_KERNEL_STATS_HH__ + +#include +#include +#include +#include + +#include "kern/kernel_stats.hh" + +namespace ArmISA { +namespace Kernel { + +enum cpu_mode { hypervisor, kernel, user, idle, cpu_mode_num }; +extern const char *modestr[]; + +class Statistics : public ::Kernel::Statistics +{ + public: + Statistics(System *system) : ::Kernel::Statistics(system) + {} +}; + +} /* end namespace ArmISA::Kernel */ +} /* end namespace ArmISA */ + +#endif // __ARCH_ARM_KERNEL_STATS_HH__ diff --git a/src/arch/arm/stacktrace.cc b/src/arch/arm/stacktrace.cc new file mode 100644 index 000000000..6b346b0ab --- /dev/null +++ b/src/arch/arm/stacktrace.cc @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2005 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Nathan Binkert + */ + +#include + +#include "arch/arm/isa_traits.hh" +#include "arch/arm/stacktrace.hh" +#include "arch/arm/vtophys.hh" +#include "base/bitfield.hh" +#include "base/trace.hh" +#include "cpu/base.hh" +#include "cpu/thread_context.hh" +#include "sim/system.hh" + +using namespace std; +namespace ArmISA +{ + ProcessInfo::ProcessInfo(ThreadContext *_tc) + : tc(_tc) + { + Addr addr = 0; + + VirtualPort *vp; + + vp = tc->getVirtPort(); + + if (!tc->getSystemPtr()->kernelSymtab->findAddress("thread_info_size", addr)) + panic("thread info not compiled into kernel\n"); + thread_info_size = vp->readGtoH(addr); + + if (!tc->getSystemPtr()->kernelSymtab->findAddress("task_struct_size", addr)) + panic("thread info not compiled into kernel\n"); + task_struct_size = vp->readGtoH(addr); + + if (!tc->getSystemPtr()->kernelSymtab->findAddress("thread_info_task", addr)) + panic("thread info not compiled into kernel\n"); + task_off = vp->readGtoH(addr); + + if (!tc->getSystemPtr()->kernelSymtab->findAddress("task_struct_pid", addr)) + panic("thread info not compiled into kernel\n"); + pid_off = vp->readGtoH(addr); + + if (!tc->getSystemPtr()->kernelSymtab->findAddress("task_struct_comm", addr)) + panic("thread info not compiled into kernel\n"); + name_off = vp->readGtoH(addr); + } + + Addr + ProcessInfo::task(Addr ksp) const + { + return 0; + } + + int + ProcessInfo::pid(Addr ksp) const + { + return -1; + } + + string + ProcessInfo::name(Addr ksp) const + { + return "Implement me"; + } + + StackTrace::StackTrace() + : tc(0), stack(64) + { + } + + StackTrace::StackTrace(ThreadContext *_tc, StaticInstPtr inst) + : tc(0), stack(64) + { + trace(_tc, inst); + } + + StackTrace::~StackTrace() + { + } + + void + StackTrace::trace(ThreadContext *_tc, bool is_call) + { + } + + bool + StackTrace::isEntry(Addr addr) + { + return false; + } + + bool + StackTrace::decodeStack(MachInst inst, int &disp) + { + return false; + } + + bool + StackTrace::decodeSave(MachInst inst, int ®, int &disp) + { + return false; + } + + /* + * Decode the function prologue for the function we're in, and note + * which registers are stored where, and how large the stack frame is. + */ + bool + StackTrace::decodePrologue(Addr sp, Addr callpc, Addr func, + int &size, Addr &ra) + { + return false; + } + +#if TRACING_ON + void + StackTrace::dump() + { + DPRINTFN("------ Stack ------\n"); + + DPRINTFN(" Not implemented\n"); + } +#endif +} diff --git a/src/arch/arm/stacktrace.hh b/src/arch/arm/stacktrace.hh index c5225455c..05fdb9e78 100644 --- a/src/arch/arm/stacktrace.hh +++ b/src/arch/arm/stacktrace.hh @@ -1,6 +1,5 @@ /* * Copyright (c) 2005 The Regents of The University of Michigan - * Copyright (c) 2007-2008 The Florida State University * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,23 +25,21 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * Authors: Ali Saidi - * Stephen Hines + * Authors: Nathan Binkert */ #ifndef __ARCH_ARM_STACKTRACE_HH__ #define __ARCH_ARM_STACKTRACE_HH__ #include "base/trace.hh" -#include "config/the_isa.hh" #include "cpu/static_inst.hh" class ThreadContext; -class StackTrace; - namespace ArmISA { +class StackTrace; + class ProcessInfo { private: @@ -65,7 +62,7 @@ class ProcessInfo class StackTrace { protected: - typedef TheISA::MachInst MachInst; + typedef ArmISA::MachInst MachInst; private: ThreadContext *tc; std::vector stack; @@ -95,10 +92,6 @@ class StackTrace public: const std::vector &getstack() const { return stack; } - static const int user = 1; - static const int console = 2; - static const int unknown = 3; - #if TRACING_ON private: void dump(); @@ -124,6 +117,6 @@ StackTrace::trace(ThreadContext *tc, StaticInstPtr inst) return true; } -} +} // Namespace ArmISA #endif // __ARCH_ARM_STACKTRACE_HH__ diff --git a/src/arch/arm/system.cc b/src/arch/arm/system.cc new file mode 100644 index 000000000..e7470f89a --- /dev/null +++ b/src/arch/arm/system.cc @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2002-2006 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Ali Saidi + */ + +#include "arch/arm/system.hh" + + +using namespace LittleEndianGuest; + +ArmSystem::ArmSystem(Params *p) + : System(p) +{ + +} + +ArmSystem::~ArmSystem() +{ +} + + +ArmSystem * +ArmSystemParams::create() +{ + return new ArmSystem(this); +} diff --git a/src/arch/arm/system.hh b/src/arch/arm/system.hh new file mode 100644 index 000000000..9dfb66fb7 --- /dev/null +++ b/src/arch/arm/system.hh @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2002-2005 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Ali Saidi + */ + +#ifndef __ARCH_ARM_SYSTEM_HH__ +#define __ARCH_ARM_SYSTEM_HH__ + +#include +#include + +#include "params/ArmSystem.hh" +#include "sim/sim_object.hh" +#include "sim/system.hh" + +class ArmSystem : public System +{ + public: + typedef ArmSystemParams Params; + ArmSystem(Params *p); + ~ArmSystem(); + + virtual Addr fixFuncEventAddr(Addr addr) + { + //XXX This may eventually have to do something useful. + return addr; + } +}; + +#endif + diff --git a/src/arch/arm/tlb.cc b/src/arch/arm/tlb.cc index febc6d081..864c061a2 100644 --- a/src/arch/arm/tlb.cc +++ b/src/arch/arm/tlb.cc @@ -287,7 +287,15 @@ TLB::translateAtomic(RequestPtr req, ThreadContext *tc, Mode mode) return NoFault; #else - fatal("translate atomic not yet implemented\n"); + SCTLR sctlr = tc->readMiscReg(MISCREG_SCTLR); + if (!sctlr.m) { + req->setPaddr(req->getVaddr()); + return NoFault; + } + panic("MMU translation not implemented\n"); + return NoFault; + + #endif } diff --git a/src/arch/arm/utility.cc b/src/arch/arm/utility.cc index 8cfa48e18..afff97d31 100644 --- a/src/arch/arm/utility.cc +++ b/src/arch/arm/utility.cc @@ -1,6 +1,37 @@ +/* + * Copyright (c) 2009 ARM Limited + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Ali Saidi + */ -#include -#include + +#include "arch/arm/faults.hh" +#include "arch/arm/utility.hh" +#include "cpu/thread_context.hh" namespace ArmISA { @@ -12,8 +43,18 @@ initCPU(ThreadContext *tc, int cpuId) // FPEXC.EN = 0 - static Fault reset = new Reset(); + static Fault reset = new Reset; if (cpuId == 0) reset->invoke(tc); } +uint64_t getArgument(ThreadContext *tc, int number, bool fp) { +#if FULL_SYSTEM + panic("getArgument() not implemented for ARM!\n"); +#else + panic("getArgument() only implemented for FULL_SYSTEM\n"); + M5_DUMMY_RETURN +#endif +} + +} diff --git a/src/arch/arm/utility.hh b/src/arch/arm/utility.hh index a2f0ef170..43e7b14ab 100644 --- a/src/arch/arm/utility.hh +++ b/src/arch/arm/utility.hh @@ -125,6 +125,17 @@ namespace ArmISA { { panic("Copy Misc. Regs Not Implemented Yet\n"); } + + void initCPU(ThreadContext *tc, int cpuId); + + static inline bool + inUserMode(ThreadContext *tc) + { + return (tc->readMiscRegNoEffect(MISCREG_CPSR) & 0x1f) == MODE_USER; + } + +uint64_t getArgument(ThreadContext *tc, int number, bool fp); + }; -- cgit v1.2.3 From 0916c376a97dacf5d11589cfea084f0e7feda4cf Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Tue, 17 Nov 2009 18:02:08 -0600 Subject: ARM: Differentiate between LDM exception return and LDM user regs. --- src/arch/arm/isa/formats/macromem.isa | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src/arch') diff --git a/src/arch/arm/isa/formats/macromem.isa b/src/arch/arm/isa/formats/macromem.isa index 068b48199..c834c22cb 100644 --- a/src/arch/arm/isa/formats/macromem.isa +++ b/src/arch/arm/isa/formats/macromem.isa @@ -210,7 +210,9 @@ inline %(class_name)s::%(class_name)s(ExtMachInst machInst) microOps[0] = new MicroAddiUop(machInst, INTREG_UREG0, RN, 0); unsigned reg = 0; - bool forceUser = machInst.puswl.psruser; + bool force_user = machInst.puswl.psruser & !OPCODE_15; + bool exception_ret = machInst.puswl.psruser & OPCODE_15; + for (int i = 1; i < ones + 1; i++) { // Find the next register. while (!bits(regs, reg)) @@ -218,12 +220,12 @@ inline %(class_name)s::%(class_name)s(ExtMachInst machInst) replaceBits(regs, reg, 0); unsigned regIdx = reg; - if (forceUser) { + if (force_user) { regIdx = intRegForceUser(regIdx); } if (machInst.puswl.loadOp) { - if (reg == INTREG_PC && forceUser) { + if (reg == INTREG_PC && exception_ret) { // This must be the exception return form of ldm. microOps[i] = new MicroLdrRetUop(machInst, regIdx, INTREG_UREG0, addr); -- cgit v1.2.3 From 422f0d9f10c6c3899be5992f9e5555598d4de0d2 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Tue, 17 Nov 2009 18:02:09 -0600 Subject: ARM: Begin implementing CP15 --- src/arch/arm/insts/static_inst.cc | 1 + src/arch/arm/isa/bitfields.isa | 1 + src/arch/arm/isa/decoder.isa | 51 ++++++++++++++++++++++++++++++++++++--- src/arch/arm/types.hh | 1 + src/arch/arm/utility.cc | 16 ++++++++++++ src/arch/arm/utility.hh | 3 +++ 6 files changed, 69 insertions(+), 4 deletions(-) (limited to 'src/arch') diff --git a/src/arch/arm/insts/static_inst.cc b/src/arch/arm/insts/static_inst.cc index 5181041d0..bf7a38c58 100644 --- a/src/arch/arm/insts/static_inst.cc +++ b/src/arch/arm/insts/static_inst.cc @@ -27,6 +27,7 @@ * Authors: Stephen Hines */ +#include "arch/arm/faults.hh" #include "arch/arm/insts/static_inst.hh" #include "base/condcodes.hh" #include "base/cprintf.hh" diff --git a/src/arch/arm/isa/bitfields.isa b/src/arch/arm/isa/bitfields.isa index bd4cfc320..8ff819983 100644 --- a/src/arch/arm/isa/bitfields.isa +++ b/src/arch/arm/isa/bitfields.isa @@ -49,6 +49,7 @@ def bitfield OPCODE_18 opcode18; def bitfield OPCODE_15_12 opcode15_12; def bitfield OPCODE_15 opcode15; def bitfield MISC_OPCODE miscOpcode; +def bitfield OPC2 opc2; def bitfield OPCODE_7 opcode7; def bitfield OPCODE_4 opcode4; diff --git a/src/arch/arm/isa/decoder.isa b/src/arch/arm/isa/decoder.isa index 5a6e8773a..ff20c6107 100644 --- a/src/arch/arm/isa/decoder.isa +++ b/src/arch/arm/isa/decoder.isa @@ -493,10 +493,53 @@ format DataOp { } } // MEDIA_OPCODE (MISC_OPCODE 0x1) } // MISC_OPCODE (CPNUM 0xA) - 0xf: decode OPCODE_20 { - 0: WarnUnimpl::mcr_cp15(); - 1: WarnUnimpl::mrc_cp15(); - } + 0xf: decode RN { + // Barrriers, Cache Maintence, NOPS + 7: decode OPCODE_23_21 { + 0: decode RM { + 0: decode OPC2 { + 4: decode OPCODE_20 { + 0: PredOp::mcr_cp15_nop1({{ }}); // was wfi + } + } + 1: WarnUnimpl::cp15_cache_maint(); + 4: WarnUnimpl::cp15_par(); + 5: decode OPC2 { + 0,1: WarnUnimpl::cp15_cache_maint2(); + 4: PredOp::cp15_isb({{ ; }}, IsMemBarrier, IsSerializeBefore); + 6,7: WarnUnimpl::cp15_bp_maint(); + } + 6: WarnUnimpl::cp15_cache_maint3(); + 8: WarnUnimpl::cp15_va_to_pa(); + 10: decode OPC2 { + 1,2: WarnUnimpl::cp15_cache_maint3(); + 4: PredOp::cp15_dsb({{ ; }}, IsMemBarrier, IsSerializeBefore); + 5: PredOp::cp15_dmb({{ ; }}, IsMemBarrier, IsSerializeBefore); + } + 11: WarnUnimpl::cp15_cache_maint4(); + 13: decode OPC2 { + 1: decode OPCODE_20 { + 0: PredOp::mcr_cp15_nop2({{ }}); // was prefetch + } + } + 14: WarnUnimpl::cp15_cache_maint5(); + } // RM + } // OPCODE_23_21 CR + + // Thread ID and context ID registers + // Thread ID register needs cheaper access than miscreg + 13: WarnUnimpl::mcr_mrc_cp15_c7(); + + // All the rest + default: decode OPCODE_20 { + 0: PredOp::mcr_cp15({{ + fault = setCp15Register(Rd, RN, OPCODE_23_21, RM, OPC2); + }}); + 1: PredOp::mrc_cp15({{ + fault = readCp15Register(Rd, RN, OPCODE_23_21, RM, OPC2); + }}); + } + } // RN } // CPNUM (OP4 == 1) } //OPCODE_4 diff --git a/src/arch/arm/types.hh b/src/arch/arm/types.hh index 07fa33ea1..e0b3951b9 100644 --- a/src/arch/arm/types.hh +++ b/src/arch/arm/types.hh @@ -58,6 +58,7 @@ namespace ArmISA Bitfield<15, 12> opcode15_12; Bitfield<15> opcode15; Bitfield<7, 4> miscOpcode; + Bitfield<7,5> opc2; Bitfield<7> opcode7; Bitfield<4> opcode4; diff --git a/src/arch/arm/utility.cc b/src/arch/arm/utility.cc index afff97d31..5ce32542b 100644 --- a/src/arch/arm/utility.cc +++ b/src/arch/arm/utility.cc @@ -57,4 +57,20 @@ uint64_t getArgument(ThreadContext *tc, int number, bool fp) { #endif } +Fault +setCp15Register(uint32_t &Rd, int CRn, int opc1, int CRm, int opc2) +{ + return new UnimpFault(csprintf("MCR CP15: CRn: %d opc1: %d CRm: %d opc1: %d\n", + CRn, opc1, CRm, opc2)); +} + +Fault +readCp15Register(uint32_t &Rd, int CRn, int opc1, int CRm, int opc2) +{ + return new UnimpFault(csprintf("MRC CP15: CRn: %d opc1: %d CRm: %d opc1: %d\n", + CRn, opc1, CRm, opc2)); + +} + + } diff --git a/src/arch/arm/utility.hh b/src/arch/arm/utility.hh index 43e7b14ab..3ddfd12dd 100644 --- a/src/arch/arm/utility.hh +++ b/src/arch/arm/utility.hh @@ -135,6 +135,9 @@ namespace ArmISA { } uint64_t getArgument(ThreadContext *tc, int number, bool fp); + +Fault setCp15Register(uint32_t &Rd, int CRn, int opc1, int CRm, int opc2); +Fault readCp15Register(uint32_t &Rd, int CRn, int opc1, int CRm, int opc2); }; -- cgit v1.2.3