summaryrefslogtreecommitdiff
path: root/arch/sparc
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sparc')
-rw-r--r--arch/sparc/SConscript3
-rw-r--r--arch/sparc/faults.cc16
-rw-r--r--arch/sparc/faults.hh4
-rw-r--r--arch/sparc/isa/base.isa90
-rw-r--r--arch/sparc/isa/bitfields.isa14
-rw-r--r--arch/sparc/isa/decoder.isa1126
-rw-r--r--arch/sparc/isa/formats.isa11
-rw-r--r--arch/sparc/isa/formats/branch.isa3
-rw-r--r--arch/sparc/isa/formats/integerop.isa203
-rw-r--r--arch/sparc/isa/formats/mem.isa15
-rw-r--r--arch/sparc/isa/formats/noop.isa4
-rw-r--r--arch/sparc/isa/formats/priv.isa165
-rw-r--r--arch/sparc/isa/formats/trap.isa13
-rw-r--r--arch/sparc/isa/formats/unknown.isa46
-rw-r--r--arch/sparc/isa/includes.isa6
-rw-r--r--arch/sparc/isa/operands.isa81
-rw-r--r--arch/sparc/isa_traits.hh500
-rw-r--r--arch/sparc/linux/process.cc580
-rw-r--r--arch/sparc/linux/process.hh7
-rw-r--r--arch/sparc/process.cc123
-rw-r--r--arch/sparc/process.hh33
-rw-r--r--arch/sparc/regfile.hh520
22 files changed, 2077 insertions, 1486 deletions
diff --git a/arch/sparc/SConscript b/arch/sparc/SConscript
index edff5821e..172e4390f 100644
--- a/arch/sparc/SConscript
+++ b/arch/sparc/SConscript
@@ -57,8 +57,7 @@ full_system_sources = Split('''
# Syscall emulation (non-full-system) sources
syscall_emulation_sources = Split('''
- common_syscall_emul.cc
- linux_process.cc
+ linux/process.cc
process.cc
''')
diff --git a/arch/sparc/faults.cc b/arch/sparc/faults.cc
index b48fc600b..9831a7679 100644
--- a/arch/sparc/faults.cc
+++ b/arch/sparc/faults.cc
@@ -89,10 +89,10 @@ TrapType IllegalInstruction::_trapType = 0x010;
FaultPriority IllegalInstruction::_priority = 7;
FaultStat IllegalInstruction::_count;
-FaultName PrivelegedOpcode::_name = "priv_opcode";
-TrapType PrivelegedOpcode::_trapType = 0x011;
-FaultPriority PrivelegedOpcode::_priority = 6;
-FaultStat PrivelegedOpcode::_count;
+FaultName PrivilegedOpcode::_name = "priv_opcode";
+TrapType PrivilegedOpcode::_trapType = 0x011;
+FaultPriority PrivilegedOpcode::_priority = 6;
+FaultStat PrivilegedOpcode::_count;
FaultName UnimplementedLDD::_name = "unimp_ldd";
TrapType UnimplementedLDD::_trapType = 0x012;
@@ -159,10 +159,10 @@ TrapType STDFMemAddressNotAligned::_trapType = 0x036;
FaultPriority STDFMemAddressNotAligned::_priority = 10;
FaultStat STDFMemAddressNotAligned::_count;
-FaultName PrivelegedAction::_name = "priv_action";
-TrapType PrivelegedAction::_trapType = 0x037;
-FaultPriority PrivelegedAction::_priority = 11;
-FaultStat PrivelegedAction::_count;
+FaultName PrivilegedAction::_name = "priv_action";
+TrapType PrivilegedAction::_trapType = 0x037;
+FaultPriority PrivilegedAction::_priority = 11;
+FaultStat PrivilegedAction::_count;
FaultName LDQFMemAddressNotAligned::_name = "unalign_ldqf";
TrapType LDQFMemAddressNotAligned::_trapType = 0x038;
diff --git a/arch/sparc/faults.hh b/arch/sparc/faults.hh
index 318b1ad5a..985407c26 100644
--- a/arch/sparc/faults.hh
+++ b/arch/sparc/faults.hh
@@ -216,7 +216,7 @@ class IllegalInstruction : public SparcFault
FaultStat & countStat() {return _count;}
};
-class PrivelegedOpcode : public SparcFault
+class PrivilegedOpcode : public SparcFault
{
private:
static FaultName _name;
@@ -412,7 +412,7 @@ class STDFMemAddressNotAligned : public SparcFault
FaultStat & countStat() {return _count;}
};
-class PrivelegedAction : public SparcFault
+class PrivilegedAction : public SparcFault
{
private:
static FaultName _name;
diff --git a/arch/sparc/isa/base.isa b/arch/sparc/isa/base.isa
index 992504369..4721f728b 100644
--- a/arch/sparc/isa/base.isa
+++ b/arch/sparc/isa/base.isa
@@ -5,15 +5,19 @@
output header {{
- struct condCodes
+ union CondCodes
{
- uint8_t c:1;
- uint8_t v:1;
- uint8_t z:1;
- uint8_t n:1;
- }
+ struct
+ {
+ uint8_t c:1;
+ uint8_t v:1;
+ uint8_t z:1;
+ uint8_t n:1;
+ };
+ uint32_t bits;
+ };
- enum condTest
+ enum CondTest
{
Always=0x8,
Never=0x0,
@@ -31,7 +35,7 @@ output header {{
Negative=0x6,
OverflowClear=0xF,
OverflowSet=0x7
- }
+ };
/**
* Base class for all SPARC static instructions.
@@ -48,13 +52,47 @@ output header {{
std::string generateDisassembly(Addr pc,
const SymbolTable *symtab) const;
+
+ void printReg(std::ostream &os, int reg) const;
};
- bool passesCondition(condCodes codes, condTest condition);
+ bool passesCondition(uint32_t codes, uint32_t condition);
+}};
+
+def template ROrImmDecode {{
+ {
+ return (I ? (SparcStaticInst *)(new %(class_name)sImm(machInst))
+ : (SparcStaticInst *)(new %(class_name)s(machInst)));
+ }
+}};
+
+let {{
+ def splitOutImm(code):
+ matcher = re.compile(r'Rs(?P<rNum>\d)_or_imm(?P<iNum>d{0,2})')
+ rOrImmMatch = matcher.search(code)
+ if (rOrImmMatch == None):
+ return (False, CodeBlock(code), None, '', '')
+ rString = matcher.sub(r'(?P=rNum)', rOrImmMatch.string)
+ iString = matcher.sub(r'(?P=iNum)', rOrImmMatch.string)
+ orig_code = code
+ code = matcher.sub(r'Rs(?P<rNum>)', orig_code)
+ imm_code = matcher.sub('imm', orig_code)
+ return (True, CodeBlock(code), CodeBlock(imm_code), rString, iString)
}};
output decoder {{
+ void
+ SparcStaticInst::printReg(std::ostream &os, int reg) const
+ {
+ if (reg < FP_Base_DepTag) {
+ ccprintf(os, "r%d", reg);
+ }
+ else {
+ ccprintf(os, "f%d", reg - FP_Base_DepTag);
+ }
+ }
+
std::string SparcStaticInst::generateDisassembly(Addr pc,
const SymbolTable *symtab) const
{
@@ -87,8 +125,10 @@ output decoder {{
return ss.str();
}
- bool passesCondition(condCodes codes, condTest condition)
+ bool passesCondition(uint32_t codes, uint32_t condition)
{
+ CondCodes condCodes;
+ condCodes.bits = codes;
switch(condition)
{
case Always:
@@ -96,34 +136,36 @@ output decoder {{
case Never:
return false;
case NotEqual:
- return !codes.z;
+ return !condCodes.z;
case Equal:
- return codes.z;
+ return condCodes.z;
case Greater:
- return !(codes.z | (codes.n ^ codes.v));
+ return !(condCodes.z | (condCodes.n ^ condCodes.v));
case LessOrEqual:
- return codes.z | (codes.n ^ codes.v);
+ return condCodes.z | (condCodes.n ^ condCodes.v);
case GreaterOrEqual:
- return !(codes.n ^ codes.v);
+ return !(condCodes.n ^ condCodes.v);
case Less:
- return (codes.n ^ codes.v);
+ return (condCodes.n ^ condCodes.v);
case GreaterUnsigned:
- return !(codes.c | codes.z);
+ return !(condCodes.c | condCodes.z);
case LessOrEqualUnsigned:
- return (codes.c | codes.z);
+ return (condCodes.c | condCodes.z);
case CarryClear:
- return !codes.c;
+ return !condCodes.c;
case CarrySet:
- return codes.c;
+ return condCodes.c;
case Positive:
- return !codes.n;
+ return !condCodes.n;
case Negative:
- return codes.n;
+ return condCodes.n;
case OverflowClear:
- return !codes.v;
+ return !condCodes.v;
case OverflowSet:
- return codes.v;
+ return condCodes.v;
}
+ panic("Tried testing condition nonexistant "
+ "condition code %d", condition);
}
}};
diff --git a/arch/sparc/isa/bitfields.isa b/arch/sparc/isa/bitfields.isa
index b0ac57575..2e4478099 100644
--- a/arch/sparc/isa/bitfields.isa
+++ b/arch/sparc/isa/bitfields.isa
@@ -7,13 +7,11 @@
// simply defined alphabetically
def bitfield A <29>;
-def bitfield CC02 <20>;
-def bitfield CC03 <25>;
-def bitfield CC04 <11>;
-def bitfield CC12 <21>;
-def bitfield CC13 <26>;
-def bitfield CC14 <12>;
-def bitfield CC2 <18>;
+def bitfield BPCC <21:20>; // for BPcc & FBPcc
+def bitfield FCMPCC <26:56>; // for FCMP & FCMPEa
+def bitfield FMOVCC <13:11>; // for FMOVcc
+def bitfield CC <12:11>; // for MOVcc & Tcc
+def bitfield MOVCC3 <18>; // also for MOVcc
def bitfield CMASK <6:4>;
def bitfield COND2 <28:25>;
def bitfield COND4 <17:14>;
@@ -46,5 +44,5 @@ def bitfield SHCNT64 <5:0>;
def bitfield SIMM10 <9:0>;
def bitfield SIMM11 <10:0>;
def bitfield SIMM13 <12:0>;
-def bitfield SW_TRAP <6:0>;
+def bitfield SW_TRAP <7:0>;
def bitfield X <12>;
diff --git a/arch/sparc/isa/decoder.isa b/arch/sparc/isa/decoder.isa
index eb458211b..a1bbf8984 100644
--- a/arch/sparc/isa/decoder.isa
+++ b/arch/sparc/isa/decoder.isa
@@ -3,660 +3,538 @@
// The actual decoder specification
//
-decode OP default Trap::unknown({{IllegalInstruction}}) {
-
- 0x0: decode OP2 {
- 0x0: Trap::illtrap({{illegal_instruction}}); //ILLTRAP
- 0x1: Branch::bpcc({{
- switch((CC12 << 1) | CC02)
- {
- case 1:
- case 3:
- fault = new IllegalInstruction;
- case 0:
- if(passesCondition(xc->regs.MiscRegs.ccrFields.icc, COND2))
+decode OP default Unknown::unknown()
+{
+ 0x0: decode OP2
+ {
+ format Branch
+ {
+ //Throw an illegal instruction acception
+ 0x0: Trap::illtrap({{fault = new IllegalInstruction;}});
+ 0x1: decode BPCC
+ {
+ 0x0: bpcci({{
+ if(passesCondition(CcrIcc, COND2))
;//branchHere
- break;
- case 2:
- if(passesCondition(xc->regs.MiscRegs.ccrFields.xcc, COND2))
+ }});
+ 0x2: bpccx({{
+ if(passesCondition(CcrXcc, COND2))
;//branchHere
- break;
- }
- }});//BPcc
- 0x2: Branch::bicc({{
- if(passesCondition(xc->regs.MiscRegs.ccrFields.icc, COND2))
+ }});
+ }
+ 0x2: bicc({{
+ if(passesCondition(CcrIcc, COND2))
;//branchHere
- }});//Bicc
- 0x3: Branch::bpr({{
- switch(RCOND)
- {
- case 0:
- case 4:
- fault = new IllegalInstruction;
- case 1:
+ }});
+ 0x3: decode RCOND2
+ {
+ 0x1: bpreq({{
if(Rs1 == 0)
;//branchHere
- break;
- case 2:
+ }});
+ 0x2: bprle({{
if(Rs1 <= 0)
;//branchHere
- break;
- case 3:
+ }});
+ 0x3: bprl({{
if(Rs1 < 0)
;//branchHere
- break;
- case 5:
+ }});
+ 0x5: bprne({{
if(Rs1 != 0)
;//branchHere
- break;
- case 6:
+ }});
+ 0x6: bprg({{
if(Rs1 > 0)
;//branchHere
- break;
- case 7:
+ }});
+ 0x7: bprge({{
if(Rs1 >= 0)
;//branchHere
- break;
+ }});
+ }
+ //SETHI (or NOP if rd == 0 and imm == 0)
+ 0x4: IntOp::sethi({{Rd = (IMM22 << 10) & 0xFFFFFC00;}});
+ 0x5: Trap::fbpfcc({{fault = new FpDisabled;}});
+ 0x6: Trap::fbfcc({{fault = new FpDisabled;}});
+ }
+ }
+ 0x1: Branch::call({{
+ //branch here
+ Rd = xc->readPC();
+ }});
+ 0x2: decode OP3 {
+ format IntOp {
+ 0x00: add({{Rd = Rs1.sdw + Rs2_or_imm13;}});
+ 0x01: and({{Rd = Rs1.udw & Rs2_or_imm13;}});
+ 0x02: or({{Rd = Rs1.udw | Rs2_or_imm13;}});
+ 0x03: xor({{Rd = Rs1.udw ^ Rs2_or_imm13;}});
+ 0x04: sub({{Rd = Rs1.sdw + (~Rs2_or_imm)+1;}});
+ 0x05: andn({{Rd = Rs1.udw & ~Rs2_or_imm;}});
+ 0x06: orn({{Rd = Rs1.udw | ~Rs2_or_imm;}});
+ 0x07: xnor({{Rd = ~(Rs1.udw ^ Rs2_or_imm);}});
+ 0x08: addc({{Rd = Rs1.sdw + Rs2_or_imm + CcrIccC;}});
+ 0x09: mulx({{Rd = Rs1 * Rs2_or_imm;}});
+ 0x0A: umul({{
+ Rd = Rs1.udw<31:0> * Rs2_or_imm<31:0>;
+ YValue = Rd<63:32>;
+ }});
+ 0x0B: smul({{
+ Rd.sdw = Rs1.sdw<31:0> * Rs2_or_imm<31:0>;
+ YValue = Rd.sdw;
+ }});
+ 0x0C: subc({{Rd.sdw = Rs1.sdw + (~Rs2_or_imm) + 1 + CcrIccC;}});
+ 0x0D: udivx({{
+ if(val2 == 0) fault = new DivisionByZero;
+ else Rd.udw = Rs1.udw / Rs2_or_imm;
+ }});
+ 0x0E: udiv({{
+ uint32_t resTemp, val2 = (I ? SIMM13 : Rs2.udw<31:0>);
+ if(Rs2_or_imm.udw == 0) fault = new DivisionByZero;
+ else
+ {
+ Rd.udw = ((YValue << 32) | Rs1.udw<31:0>) / Rs2_or_imm.udw;
+ if(Rd.udw >> 32 != 0)
+ Rd.udw = 0xFFFFFFFF;
+ }
+ }});
+ 0x0F: sdiv({{
+ if(val2 == 0)
+ fault = new DivisionByZero;
+ else
+ {
+ Rd.udw = ((YValue << 32) | Rs1.sdw<31:0>) / Rs2_or_imm;
+ if(Rd.udw<63:31> != 0)
+ Rd.udw = 0x7FFFFFFF;
+ else if(Rd.udw<63:> && Rd.udw<62:31> != 0xFFFFFFFF)
+ Rd.udw = 0xFFFFFFFF80000000;
}
- }}); //BPr
- //SETHI (or NOP if rd == 0 and imm == 0)
- 0x4: IntegerOp::sethi({{Rd = (IMM22 << 10) & 0xFFFFFC00;}});
- 0x5: Trap::fbpfcc({{throw fp_disabled;}}); //FBPfcc
- 0x6: Trap::fbfcc({{throw fp_disabled;}}); //FBfcc
+ }});//SDIV
}
- 0x1: Branch::call({{
- //branch here
- Rd = xc->pc;
- }});
- 0x2: decode OP3 {
- format IntegerOp {
- 0x00: add({{
- int64_t val2 = (I ? SIMM13.sdw : Rs2.sdw);
- Rd = Rs1.sdw + val2;
- }});//ADD
- 0x01: and({{
- uint64_t val2 = (I ? SIMM13.sdw : Rs2.udw);
- Rd = Rs1.udw & val2;
- }});//AND
- 0x02: or({{
- uint64_t val2 = (I ? SIMM13.sdw : Rs2.udw);
- Rd = Rs1.udw | val2;
- }});//OR
- 0x03: xor({{
- uint64_t val2 = (I ? SIMM13.sdw : Rs2.udw);
- Rd = Rs1.udw ^ val2;
- }});//XOR
- 0x04: sub({{
- int64_t val2 = ~((uint64_t)(I ? SIMM13.sdw : Rs2.udw))+1;
- Rd = Rs1.sdw + val2;
- }});//SUB
- 0x05: andn({{
- uint64_t val2 = (I ? SIMM13.sdw : Rs2.udw);
- Rd = Rs1.udw & ~val2;
- }});//ANDN
- 0x06: orn({{
- uint64_t val2 = (I ? SIMM13.sdw : Rs2.udw);
- Rd = Rs1.udw | ~val2;
- }});//ORN
- 0x07: xnor({{
- uint64_t val2 = (I ? SIMM13.sdw : Rs2.udw);
- Rd = ~(Rs1.udw ^ val2);
- }});//XNOR
- 0x08: addc({{
- int64_t val2 = (I ? SIMM13.sdw : Rs2.sdw);
- int64_t carryin = xc->regs.MiscRegs.ccrfields.iccfields.c;
- Rd = Rs1.sdw + val2 + carryin;
- }});//ADDC
- 0x09: mulx({{
- int64_t val2 = (I ? SIMM13.sdw : Rs2);
- Rd = Rs1 * val2;
- }});//MULX
- 0x0A: umul({{
- uint64_t resTemp, val2 = (I ? SIMM13.sdw : Rs2.udw);
- Rd = resTemp = Rs1.udw<31:0> * val2<31:0>;
- xc->regs.MiscRegs.yFields.value = resTemp<63:32>;
- }});//UMUL
- 0x0B: smul({{
- int64_t resTemp, val2 = (I ? SIMM13.sdw : Rs2.sdw);
- rd.sdw = resTemp = Rs1.sdw<31:0> * val2<31:0>;
- xc->regs.MiscRegs.yFields.value = resTemp<63:32>;
- }});//SMUL
- 0x0C: subc({{
- int64_t val2 = ~((int64_t)(I ? SIMM13.sdw : Rs2.sdw))+1;
- int64_t carryin = xc->regs.MiscRegs.ccrfields.iccfields.c;
- Rd.sdw = Rs1.sdw + val2 + carryin;
- }});//SUBC
- 0x0D: udivx({{
- uint64_t val2 = (I ? SIMM13.sdw : Rs2.udw);
- if(val2 == 0) throw division_by_zero;
- Rd.udw = Rs1.udw / val2;
- }});//UDIVX
- 0x0E: udiv({{
- uint32_t resTemp, val2 = (I ? SIMM13.sw : Rs2.udw<31:0>);
- if(val2 == 0)
- fault = new DivisionByZero;
- resTemp = (uint64_t)((xc->regs.MiscRegs.yFields.value << 32)
- | Rs1.udw<31:0>) / val2;
+ format IntOpCc {
+ 0x10: addcc({{
+ int64_t resTemp, val2 = (I ? SIMM13 : Rs2);
+ Rd = resTemp = Rs1 + val2;}},
+ {{((Rs1 & 0xFFFFFFFF + val2 & 0xFFFFFFFF) >> 31)}},
+ {{Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>}},
+ {{((Rs1 >> 1) + (val2 >> 1) + (Rs1 & val2 & 0x1))<63:>}},
+ {{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}}
+ );//ADDcc
+ 0x11: IntOpCcRes::andcc({{Rd = Rs1 & Rs2_or_imm13;}});
+ 0x12: IntOpCcRes::orcc({{Rd = Rs1 | Rs2_or_imm13;}});
+ 0x13: IntOpCcRes::xorcc({{Rd = Rs1 ^ Rs2_or_imm13;}});
+ 0x14: subcc({{
+ int64_t resTemp, val2 = (int64_t)(I ? SIMM13 : Rs2);
+ Rd = resTemp = Rs1 - val2;}},
+ {{((Rs1 & 0xFFFFFFFF + (~val2) & 0xFFFFFFFF + 1) >> 31)}},
+ {{Rs1<31:> != val2<31:> && Rs1<31:> != resTemp<31:>}},
+ {{((Rs1 >> 1) + (~val2) >> 1) +
+ ((Rs1 | ~val2) & 0x1))<63:>}},
+ {{Rs1<63:> != val2<63:> && Rs1<63:> != resTemp<63:>}}
+ );//SUBcc
+ 0x15: IntOpCcRes::andncc({{Rd = Rs1 & ~Rs2_or_imm13;}});
+ 0x16: IntOpCcRes::orncc({{Rd = Rs1 | ~Rs2_or_imm13;}});
+ 0x17: IntOpCcRes::xnorcc({{Rd = ~(Rs1 ^ Rs2_or_imm13);}});
+ 0x18: addccc({{
+ int64_t resTemp, val2 = (I ? SIMM13 : Rs2);
+ int64_t carryin = CcrIccC;
+ Rd = resTemp = Rs1 + val2 + carryin;}},
+ {{((Rs1 & 0xFFFFFFFF + val2 & 0xFFFFFFFF) >> 31
+ + carryin)}},
+ {{Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>}},
+ {{((Rs1 >> 1) + (val2 >> 1) +
+ ((Rs1 & val2) | (carryin & (Rs1 | val2)) & 0x1))<63:>}},
+ {{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}}
+ );//ADDCcc
+ 0x1A: umulcc({{
+ uint64_t resTemp, val2 = (I ? SIMM13 : Rs2);
+ Rd = resTemp = Rs1.udw<31:0> * val2<31:0>;
+ YValue = resTemp<63:32>;}},
+ {{0}},{{0}},{{0}},{{0}});//UMULcc
+ 0x1B: smulcc({{
+ int64_t resTemp, val2 = (I ? SIMM13 : Rs2);
+ Rd = resTemp = Rs1.sdw<31:0> * val2<31:0>;
+ YValue = resTemp<63:32>;}}
+ ,{{0}},{{0}},{{0}},{{0}});//SMULcc
+ 0x1C: subccc({{
+ int64_t resTemp, val2 = (int64_t)(I ? SIMM13 : Rs2);
+ int64_t carryin = CcrIccC;
+ Rd = resTemp = Rs1 + ~(val2 + carryin) + 1;}},
+ {{((Rs1 & 0xFFFFFFFF + (~(val2 + carryin)) & 0xFFFFFFFF + 1) >> 31)}},
+ {{Rs1<31:> != val2<31:> && Rs1<31:> != resTemp<31:>}},
+ {{((Rs1 >> 1) + (~(val2 + carryin)) >> 1) + ((Rs1 | ~(val2+carryin)) & 0x1))<63:>}},
+ {{Rs1<63:> != val2<63:> && Rs1<63:> != resTemp<63:>}}
+ );//SUBCcc
+ 0x1D: udivxcc({{
+ uint64_t val2 = (I ? SIMM13 : Rs2.udw);
+ if(val2 == 0) fault = new DivisionByZero;
+ else Rd.udw = Rs1.udw / val2;}}
+ ,{{0}},{{0}},{{0}},{{0}});//UDIVXcc
+ 0x1E: udivcc({{
+ uint32_t resTemp, val2 = (I ? SIMM13 : Rs2.udw<31:0>);
+ if(val2 == 0) fault = new DivisionByZero;
+ else
+ {
+ resTemp = (uint64_t)((YValue << 32) | Rs1.udw<31:0>) / val2;
int32_t overflow = (resTemp<63:32> != 0);
- if(overflow)
- rd.udw = resTemp = 0xFFFFFFFF;
- else
- rd.udw = resTemp;
- }}); //UDIV
- 0x0F: sdiv({{
- int32_t resTemp, val2 = (I ? SIMM13.sw : Rs2.sdw<31:0>);
- if(val2 == 0)
- fault = new DivisionByZero;
-
- Rd.sdw = (int64_t)((xc->regs.MiscRegs.yFields.value << 32) |
- Rs1.sdw<31:0>) / val2;
- resTemp = Rd.sdw;
+ if(overflow) rd.udw = resTemp = 0xFFFFFFFF;
+ else rd.udw = resTemp;
+ } }},
+ {{0}},
+ {{overflow}},
+ {{0}},
+ {{0}}
+ );//UDIVcc
+ 0x1F: sdivcc({{
+ int32_t resTemp, val2 = (I ? SIMM13 : Rs2.sdw<31:0>);
+ if(val2 == 0) fault = new DivisionByZero;
+ else
+ {
+ Rd.sdw = resTemp = (int64_t)((YValue << 32) | Rs1.sdw<31:0>) / val2;
int32_t overflow = (resTemp<63:31> != 0);
- int32_t underflow =
- (resTemp<63:> && resTemp<62:31> != 0xFFFFFFFF);
- if(overflow)
- rd.udw = resTemp = 0x7FFFFFFF;
- else if(underflow)
- rd.udw = resTemp = 0xFFFFFFFF80000000;
- else
- rd.udw = resTemp;
- }});//SDIV
+ int32_t underflow = (resTemp<63:> && resTemp<62:31> != 0xFFFFFFFF);
+ if(overflow) rd.udw = resTemp = 0x7FFFFFFF;
+ else if(underflow) rd.udw = resTemp = 0xFFFFFFFF80000000;
+ else rd.udw = resTemp;
+ } }},
+ {{0}},
+ {{overflow || underflow}},
+ {{0}},
+ {{0}}
+ );//SDIVcc
+ 0x20: taddcc({{
+ int64_t resTemp, val2 = (I ? SIMM13 : Rs2);
+ Rd = resTemp = Rs1 + val2;
+ int32_t overflow = Rs1<1:0> || val2<1:0> || (Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>);}},
+ {{((Rs1 & 0xFFFFFFFF + val2 & 0xFFFFFFFF) >> 31)}},
+ {{overflow}},
+ {{((Rs1 >> 1) + (val2 >> 1) + (Rs1 & val2 & 0x1))<63:>}},
+ {{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}}
+ );//TADDcc
+ 0x21: tsubcc({{
+ int64_t resTemp, val2 = (I ? SIMM13 : Rs2);
+ Rd = resTemp = Rs1 + val2;
+ int32_t overflow = Rs1<1:0> || val2<1:0> || (Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>);}},
+ {{(Rs1 & 0xFFFFFFFF + val2 & 0xFFFFFFFF) >> 31)}},
+ {{overflow}},
+ {{((Rs1 >> 1) + (val2 >> 1) + (Rs1 & val2 & 0x1))<63:>}},
+ {{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}}
+ );//TSUBcc
+ 0x22: taddcctv({{
+ int64_t resTemp, val2 = (I ? SIMM13 : Rs2);
+ Rd = resTemp = Rs1 + val2;
+ int32_t overflow = Rs1<1:0> || val2<1:0> || (Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>);
+ if(overflow) fault = new TagOverflow;}},
+ {{((Rs1 & 0xFFFFFFFF + val2 & 0xFFFFFFFF) >> 31)}},
+ {{overflow}},
+ {{((Rs1 >> 1) + (val2 >> 1) + (Rs1 & val2 & 0x1))<63:>}},
+ {{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}}
+ );//TADDccTV
+ 0x23: tsubcctv({{
+ int64_t resTemp, val2 = (I ? SIMM13 : Rs2);
+ Rd = resTemp = Rs1 + val2;
+ int32_t overflow = Rs1<1:0> || val2<1:0> || (Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>);
+ if(overflow) fault = new TagOverflow;}},
+ {{((Rs1 & 0xFFFFFFFF + val2 & 0xFFFFFFFF) >> 31)}},
+ {{overflow}},
+ {{((Rs1 >> 1) + (val2 >> 1) + (Rs1 & val2 & 0x1))<63:>}},
+ {{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}}
+ );//TSUBccTV
+ 0x24: mulscc({{
+ int64_t resTemp, multiplicand = (I ? SIMM13 : Rs2);
+ int32_t multiplier = Rs1<31:0>;
+ int32_t savedLSB = Rs1<0:>;
+ multiplier = multipler<31:1> |
+ ((CcrIccN
+ ^ CcrIccV) << 32);
+ if(!YValue<0:>)
+ multiplicand = 0;
+ Rd = resTemp = multiplicand + multiplier;
+ YValue = YValue<31:1> | (savedLSB << 31);}},
+ {{((multiplicand & 0xFFFFFFFF + multiplier & 0xFFFFFFFF) >> 31)}},
+ {{multiplicand<31:> == multiplier<31:> && multiplier<31:> != resTemp<31:>}},
+ {{((multiplicand >> 1) + (multiplier >> 1) + (multiplicand & multiplier & 0x1))<63:>}},
+ {{multiplicand<63:> == multiplier<63:> && multiplier<63:> != resTemp<63:>}}
+ );//MULScc
}
- format IntegerOpCc {
- 0x10: addcc({{
- int64_t resTemp, val2 = (I ? SIMM13.sdw : Rs2);
- Rd = resTemp = Rs1 + val2;}},
- {{((Rs1 & 0xFFFFFFFF + val2 & 0xFFFFFFFF) >> 31)}},
- {{Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>}},
- {{((Rs1 >> 1) + (val2 >> 1) + (Rs1 & val2 & 0x1))<63:>}},
- {{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}}
- );//ADDcc
- 0x11: andcc({{
- int64_t val2 = (I ? SIMM13.sdw : Rs2);
- Rd = Rs1 & val2;}},
- {{0}},{{0}},{{0}},{{0}});//ANDcc
- 0x12: orcc({{
- int64_t val2 = (I ? SIMM13.sdw : Rs2);
- Rd = Rs1 | val2;}},
- {{0}},{{0}},{{0}},{{0}});//ORcc
- 0x13: xorcc({{
- int64_t val2 = (I ? SIMM13.sdw : Rs2);
- Rd = Rs1 ^ val2;}},
- {{0}},{{0}},{{0}},{{0}});//XORcc
- 0x14: subcc({{
- int64_t resTemp, val2 = (int64_t)(I ? SIMM13.sdw : Rs2);
- Rd = resTemp = Rs1 - val2;}},
- {{((Rs1 & 0xFFFFFFFF + (~val2) & 0xFFFFFFFF + 1) >> 31)}},
- {{Rs1<31:> != val2<31:> && Rs1<31:> != resTemp<31:>}},
- {{((Rs1 >> 1) + (~val2) >> 1) +
- ((Rs1 | ~val2) & 0x1))<63:>}},
- {{Rs1<63:> != val2<63:> && Rs1<63:> != resTemp<63:>}}
- );//SUBcc
- 0x15: andncc({{
- int64_t val2 = (I ? SIMM13.sdw : Rs2);
- Rd = Rs1 & ~val2;}},
- {{0}},{{0}},{{0}},{{0}});//ANDNcc
- 0x16: orncc({{
- int64_t val2 = (I ? SIMM13.sdw : Rs2);
- Rd = Rs1 | ~val2;}},
- {{0}},{{0}},{{0}},{{0}});//ORNcc
- 0x17: xnorcc({{
- int64_t val2 = (I ? SIMM13.sdw : Rs2);
- Rd = ~(Rs1 ^ val2);}},
- {{0}},{{0}},{{0}},{{0}});//XNORcc
- 0x18: addccc({{
- int64_t resTemp, val2 = (I ? SIMM13.sdw : Rs2);
- int64_t carryin = xc->regs.MiscRegs.ccrfields.iccfields.c;
- Rd = resTemp = Rs1 + val2 + carryin;}},
- {{((Rs1 & 0xFFFFFFFF + val2 & 0xFFFFFFFF) >> 31
- + carryin)}},
- {{Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>}},
- {{((Rs1 >> 1) + (val2 >> 1) +
- ((Rs1 & val2) | (carryin & (Rs1 | val2)) & 0x1))<63:>}},
- {{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}}
- );//ADDCcc
- 0x1A: umulcc({{
- uint64_t resTemp, val2 = (I ? SIMM13.sdw : Rs2);
- Rd = resTemp = Rs1.udw<31:0> * val2<31:0>;
- xc->regs.MiscRegs.yFields.value = resTemp<63:32>;}},
- {{0}},{{0}},{{0}},{{0}});//UMULcc
- 0x1B: smulcc({{
- int64_t resTemp, val2 = (I ? SIMM13.sdw : Rs2);
- Rd = resTemp = Rs1.sdw<31:0> * val2<31:0>;
- xc->regs.MiscRegs.yFields.value = resTemp<63:32>;}}
- ,{{0}},{{0}},{{0}},{{0}});//SMULcc
- 0x1C: subccc({{
- int64_t resTemp, val2 = (int64_t)(I ? SIMM13.sdw : Rs2);
- int64_t carryin = xc->regs.MiscRegs.ccrfields.iccfields.c;
- Rd = resTemp = Rs1 + ~(val2 + carryin) + 1;}},
- {{((Rs1 & 0xFFFFFFFF + (~(val2 + carryin)) & 0xFFFFFFFF + 1) >> 31)}},
- {{Rs1<31:> != val2<31:> && Rs1<31:> != resTemp<31:>}},
- {{((Rs1 >> 1) + (~(val2 + carryin)) >> 1) + ((Rs1 | ~(val2+carryin)) & 0x1))<63:>}},
- {{Rs1<63:> != val2<63:> && Rs1<63:> != resTemp<63:>}}
- );//SUBCcc
- 0x1D: udivxcc({{
- uint64_t val2 = (I ? SIMM13.sdw : Rs2.udw);
- if(val2 == 0) throw division_by_zero;
- Rd.udw = Rs1.udw / val2;}}
- ,{{0}},{{0}},{{0}},{{0}});//UDIVXcc
- 0x1E: udivcc({{
- uint32_t resTemp, val2 = (I ? SIMM13.sw : Rs2.udw<31:0>);
- if(val2 == 0) throw division_by_zero;
- resTemp = (uint64_t)((xc->regs.MiscRegs.yFields.value << 32) | Rs1.udw<31:0>) / val2;
- int32_t overflow = (resTemp<63:32> != 0);
- if(overflow) rd.udw = resTemp = 0xFFFFFFFF;
- else rd.udw = resTemp;}},
- {{0}},
- {{overflow}},
- {{0}},
- {{0}}
- );//UDIVcc
- 0x1F: sdivcc({{
- int32_t resTemp, val2 = (I ? SIMM13.sw : Rs2.sdw<31:0>);
- if(val2 == 0) throw division_by_zero;
- Rd.sdw = resTemp = (int64_t)((xc->regs.MiscRegs.yFields.value << 32) | Rs1.sdw<31:0>) / val2;
- int32_t overflow = (resTemp<63:31> != 0);
- int32_t underflow = (resTemp<63:> && resTemp<62:31> != 0xFFFFFFFF);
- if(overflow) rd.udw = resTemp = 0x7FFFFFFF;
- else if(underflow) rd.udw = resTemp = 0xFFFFFFFF80000000;
- else rd.udw = resTemp;}},
- {{0}},
- {{overflow || underflow}},
- {{0}},
- {{0}}
- );//SDIVcc
- 0x20: taddcc({{
- int64_t resTemp, val2 = (I ? SIMM13.sdw : Rs2);
- Rd = resTemp = Rs1 + val2;
- int32_t overflow = Rs1<1:0> || val2<1:0> || (Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>);}},
- {{((Rs1 & 0xFFFFFFFF + val2 & 0xFFFFFFFF) >> 31)}},
- {{overflow}},
- {{((Rs1 >> 1) + (val2 >> 1) + (Rs1 & val2 & 0x1))<63:>}},
- {{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}}
- );//TADDcc
- 0x21: tsubcc({{
- int64_t resTemp, val2 = (I ? SIMM13.sdw : Rs2);
- Rd = resTemp = Rs1 + val2;
- int32_t overflow = Rs1<1:0> || val2<1:0> || (Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>);}},
- {{(Rs1 & 0xFFFFFFFF + val2 & 0xFFFFFFFF) >> 31)}},
- {{overflow}},
- {{((Rs1 >> 1) + (val2 >> 1) + (Rs1 & val2 & 0x1))<63:>}},
- {{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}}
- );//TSUBcc
- 0x22: taddcctv({{
- int64_t resTemp, val2 = (I ? SIMM13.sdw : Rs2);
- Rd = resTemp = Rs1 + val2;
- int32_t overflow = Rs1<1:0> || val2<1:0> || (Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>);
- if(overflow) throw tag_overflow;}},
- {{((Rs1 & 0xFFFFFFFF + val2 & 0xFFFFFFFF) >> 31)}},
- {{overflow}},
- {{((Rs1 >> 1) + (val2 >> 1) + (Rs1 & val2 & 0x1))<63:>}},
- {{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}}
- );//TADDccTV
- 0x23: tsubcctv({{
- int64_t resTemp, val2 = (I ? SIMM13.sdw : Rs2);
- Rd = resTemp = Rs1 + val2;
- int32_t overflow = Rs1<1:0> || val2<1:0> || (Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>);
- if(overflow) throw tag_overflow;}},
- {{((Rs1 & 0xFFFFFFFF + val2 & 0xFFFFFFFF) >> 31)}},
- {{overflow}},
- {{((Rs1 >> 1) + (val2 >> 1) + (Rs1 & val2 & 0x1))<63:>}},
- {{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}}
- );//TSUBccTV
- 0x24: mulscc({{
- int64_t resTemp, multiplicand = (I ? SIMM13.sdw : Rs2);
- int32_t multiplier = Rs1<31:0>;
- int32_t savedLSB = Rs1<0:>;
- multiplier = multipler<31:1> |
- ((xc->regs.MiscRegs.ccrFields.iccFields.n
- ^ xc->regs.MiscRegs.ccrFields.iccFields.v) << 32);
- if(!xc->regs.MiscRegs.yFields.value<0:>)
- multiplicand = 0;
- Rd = resTemp = multiplicand + multiplier;
- xc->regs.MiscRegs.yFields.value = xc->regs.MiscRegs.yFields.value<31:1> | (savedLSB << 31);}},
- {{((multiplicand & 0xFFFFFFFF + multiplier & 0xFFFFFFFF) >> 31)}},
- {{multiplicand<31:> == multiplier<31:> && multiplier<31:> != resTemp<31:>}},
- {{((multiplicand >> 1) + (multiplier >> 1) + (multiplicand & multiplier & 0x1))<63:>}},
- {{multiplicand<63:> == multiplier<63:> && multiplier<63:> != resTemp<63:>}}
- );//MULScc
+ format IntOp
+ {
+ 0x25: decode X {
+ 0x0: sll({{Rd = Rs1 << (I ? SHCNT32 : Rs2<4:0>);}});
+ 0x1: sllx({{Rd = Rs1 << (I ? SHCNT64 : Rs2<5:0>);}});
+ }
+ 0x26: decode X {
+ 0x0: srl({{Rd = Rs1.uw >> (I ? SHCNT32 : Rs2<4:0>);}});
+ 0x1: srlx({{Rd = Rs1.udw >> (I ? SHCNT64 : Rs2<5:0>);}});
}
- format IntegerOp
+ 0x27: decode X {
+ 0x0: sra({{Rd = Rs1.sw >> (I ? SHCNT32 : Rs2<4:0>);}}); //SRA
+ 0x1: srax({{Rd = Rs1.sdw >> (I ? SHCNT64 : Rs2<5:0>);}});//SRAX
+ }
+ 0x28: decode RS1 {
+ 0x0: rdy({{Rd = YValue;}}); //RDY
+ 0x2: rdccr({{Rd = Ccr;}}); //RDCCR
+ 0x3: rdasi({{Rd = Asi;}}); //RDASI
+ 0x4: PrivTick::rdtick({{Rd = Tick;}});
+ 0x5: rdpc({{Rd = xc->regs.pc;}}); //RDPC
+ 0x6: rdfprs({{Rd = Fprs;}}); //RDFPRS
+ 0xF: decode I {
+ 0x0: Noop::membar({{//Membar isn't needed yet}});
+ 0x1: Noop::stbar({{//Stbar isn't needed yet}});
+ }
+ }
+ 0x2A: decode RS1 {
+ format Priv
+ {
+ 0x0: rdprtpc({{
+ Rd = xc->readMiscReg(MISCREG_TPC_BASE + Tl);
+ }});
+ 0x1: rdprtnpc({{
+ Rd = xc->readMiscReg(MISCREG_TNPC_BASE + Tl);
+ }});
+ 0x2: rdprtstate({{
+ Rd = xc->readMiscReg(MISCREG_TSTATE_BASE + Tl);
+ }});
+ 0x3: rdprtt({{
+ Rd = xc->readMiscReg(MISCREG_TT_BASE + Tl);
+ }});
+ 0x4: rdprtick({{Rd = Tick;}});
+ 0x5: rdprtba({{Rd = Tba;}});
+ 0x6: rdprpstate({{Rd = Pstate;}});
+ 0x7: rdprtl({{Rd = Tl;}});
+ 0x8: rdprpil({{Rd = Pil;}});
+ 0x9: rdprcwp({{Rd = Cwp;}});
+ 0xA: rdprcansave({{Rd = Cansave;}});
+ 0xB: rdprcanrestore({{Rd = CanRestore;}});
+ 0xC: rdprcleanwin({{Rd = Cleanwin;}});
+ 0xD: rdprotherwin({{Rd = Otherwin;}});
+ 0xE: rdprwstate({{Rd = Wstate;}});
+ }
+ //The floating point queue isn't implemented right now.
+ 0xF: Trap::rdprfq({{fault = IllegalInstruction;}});
+ 0x1F: Priv::rdprver({{Rd = Ver;}});
+ }
+ 0x2B: BasicOperate::flushw({{//window toilet}}); //FLUSHW
+ 0x2C: decode MOVCC3
{
- 0x25: decode X {
- 0x0: sll({{Rd = Rs1 << (I ? SHCNT32 : Rs2<4:0>);}}); //SLL
- 0x1: sllx({{Rd = Rs1 << (I ? SHCNT64 : Rs2<5:0>);}}); //SLLX
- }
- 0x26: decode X {
- 0x0: srl({{Rd = Rs1.udw<31:0> >> (I ? SHCNT32 : Rs2<4:0>);}}); //SRL
- 0x1: srlx({{Rd = Rs1.udw >> (I ? SHCNT64 : Rs2<5:0>);}});//SRLX
- }
- 0x27: decode X {
- 0x0: sra({{Rd = Rs1.sdw<31:0> >> (I ? SHCNT32 : Rs2<4:0>);}}); //SRA
- 0x1: srax({{Rd = Rs1.sdw >> (I ? SHCNT64 : Rs2<5:0>);}});//SRAX
- }
- 0x28: decode RS1 {
- 0x0: rdy({{Rd = xc->regs.MiscRegs.yFields.value;}}); //RDY
- 0x2: rdccr({{Rd = xc->regs.MiscRegs.ccr;}}); //RDCCR
- 0x3: rdasi({{Rd = xc->regs.MiscRegs.asi;}}); //RDASI
- 0x4: rdtick({{
- if(xc->regs.MiscRegs.pstateFields.priv == 0 &&
- xc->regs.MiscRegs.tickFields.npt == 1)
- throw privileged_action;
- Rd = xc->regs.MiscRegs.tick;
- }});//RDTICK
- 0x5: rdpc({{Rd = xc->regs.pc;}}); //RDPC
- 0x6: rdfprs({{Rd = xc->regs.MiscRegs.fprs;}}); //RDFPRS
- 0xF: decode I {
- 0x0: Noop::membar({{//Membar isn't needed yet}}); //MEMBAR
- 0x1: Noop::stbar({{//Stbar isn/'t needed yet}}); //STBAR
- }
- }
-
- 0x2A: decode RS1 {
- 0x0: rdprtpc({{checkPriv Rd = xc->regs.MiscRegs.tpc[xc->regs.MiscRegs.tl];}});
- 0x1: rdprtnpc({{checkPriv Rd = xc->regs.MiscRegs.tnpc[xc->regs.MiscRegs.tl];}});
- 0x2: rdprtstate({{checkPriv Rd = xc->regs.MiscRegs.tstate[xc->regs.MiscRegs.tl];}});
- 0x3: rdprtt({{checkPriv Rd = xc->regs.MiscRegs.tt[xc->regs.MiscRegs.tl];}});
- 0x4: rdprtick({{checkPriv Rd = xc->regs.MiscRegs.tick;}});
- 0x5: rdprtba({{checkPriv Rd = xc->regs.MiscRegs.tba;}});
- 0x6: rdprpstate({{checkPriv Rd = xc->regs.MiscRegs.pstate;}});
- 0x7: rdprtl({{checkPriv Rd = xc->regs.MiscRegs.tl;}});
- 0x8: rdprpil({{checkPriv Rd = xc->regs.MiscRegs.pil;}});
- 0x9: rdprcwp({{checkPriv Rd = xc->regs.MiscRegs.cwp;}});
- 0xA: rdprcansave({{checkPriv Rd = xc->regs.MiscRegs.cansave;}});
- 0xB: rdprcanrestore({{checkPriv Rd = xc->regs.MiscRegs.canrestore;}});
- 0xC: rdprcleanwin({{checkPriv Rd = xc->regs.MiscRegs.cleanwin;}});
- 0xD: rdprotherwin({{checkPriv Rd = xc->regs.MiscRegs.otherwin;}});
- 0xE: rdprwstate({{checkPriv Rd = xc->regs.MiscRegs.wstate;}});
- 0xF: rdprfq({{throw illegal_instruction;}}); //The floating point queue isn't implemented right now.
- }
- 0x2B: BasicOperate::flushw({{\\window toilet}}); //FLUSHW
- 0x2C: movcc({{
- ccBank = (CC24 << 2) | (CC14 << 1) | (CC04 << 0);
- switch(ccBank)
- {
- case 0: case 1: case 2: case 3:
- throw fp_disabled;
- break;
- case 5: case 7:
- throw illegal_instruction;
- break;
- case 4:
- if(passesCondition(xc->regs.MiscRegs.ccrFields.icc, COND4))
- Rd = (I ? SIMM11.sdw : RS2);
- break;
- case 6:
- if(passesCondition(xc->regs.MiscRegs.ccrFields.xcc, COND4))
- Rd = (I ? SIMM11.sdw : RS2);
- break;
- }
- }});//MOVcc
- 0x2D: sdivx({{
- int64_t val2 = (I ? SIMM13.sdw : Rs2.sdw);
- if(val2 == 0) throw division_by_zero;
- Rd.sdw = Rs1.sdw / val2;
- }});//SDIVX
- 0x2E: decode RS1 {
- 0x0: IntegerOp::popc({{
- int64_t count = 0, val2 = (I ? SIMM13.sdw : Rs2.sdw);
- uint8_t oneBits[] = {0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4}
- for(unsigned int x = 0; x < 16; x++)
- {
- count += oneBits[val2 & 0xF];
- val2 >> 4;
- }
- }});//POPC
- }
- 0x2F: movr({{
- uint64_t val2 = (I ? SIMM10.sdw : Rs2.sdw);
- switch(RCOND)
- {
- case 0: case 4:
- throw illegal_instruction;
- break;
- case 1:
- if(Rs1 == 0) Rd = val2;
- break;
- case 2:
- if(Rs1 <= 0) Rd = val2;
- break;
- case 3:
- if(Rs1 = 0) Rd = val2;
- break;
- case 5:
- if(Rs1 != 0) Rd = val2;
- break;
- case 6:
- if(Rs1 > 0) Rd = val2;
- break;
- case 7:
- if(Rs1 >= 0) Rd = val2;
- break;
- }
- }});//MOVR
- 0x30: decode RD {
- 0x0: wry({{
- uint64_t val2 = (I ? SIMM13.sdw : Rs2.sdw);
- xc->regs.MiscRegs.y = Rs1 ^ val2;
- }});//WRY
- 0x2: wrccr({{
- uint64_t val2 = (I ? SIMM13.sdw : Rs2.sdw);
- xc->regs.MiscRegs.ccr = Rs1 ^ val2;
- }});//WRCCR
- 0x3: wrasi({{
- uint64_t val2 = (I ? SIMM13.sdw : Rs2.sdw);
- xc->regs.MiscRegs.asi = Rs1 ^ val2;
- }});//WRASI
- 0x6: wrfprs({{
- uint64_t val2 = (I ? SIMM13.sdw : Rs2.sdw);
- xc->regs.MiscRegs.asi = Rs1 ^ val2;
- }});//WRFPRS
- 0xF: Trap::sir({{software_initiated_reset}}); //SIR
- }
- 0x31: decode FCN {
- 0x0: BasicOperate::saved({{\\Boogy Boogy}}); //SAVED
- 0x1: BasicOperate::restored({{\\Boogy Boogy}}); //RESTORED
- }
- 0x32: decode RD {
- 0x0: wrprtpc({{checkPriv
- uint64_t val2 = (I ? SIMM13.sdw : Rs2.sdw);
- xc->regs.MiscRegs.tpc[xc->regs.MiscRegs.tl] = Rs1 ^ val2;
- }});
- 0x1: wrprtnpc({{checkPriv
- uint64_t val2 = (I ? SIMM13.sdw : Rs2.sdw);
- xc->regs.MiscRegs.tnpc[xc->regs.MiscRegs.tl] = Rs1 ^ val2;
- }});
- 0x2: wrprtstate({{checkPriv
- uint64_t val2 = (I ? SIMM13.sdw : Rs2.sdw);
- xc->regs.MiscRegs.tstate[xc->regs.MiscRegs.tl] = Rs1 ^ val2;
- }});
- 0x3: wrprtt({{checkPriv
- uint64_t val2 = (I ? SIMM13.sdw : Rs2.sdw);
- xc->regs.MiscRegs.tt[xc->regs.MiscRegs.tl] = Rs1 ^ val2;
- }});
- 0x4: wrprtick({{checkPriv
- uint64_t val2 = (I ? SIMM13.sdw : Rs2.sdw);
- xc->regs.MiscRegs.tick = Rs1 ^ val2;
- }});
- 0x5: wrprtba({{checkPriv
- uint64_t val2 = (I ? SIMM13.sdw : Rs2.sdw);
- xc->regs.MiscRegs.tba = Rs1 ^ val2;
- }});
- 0x6: wrprpstate({{checkPriv
- uint64_t val2 = (I ? SIMM13.sdw : Rs2.sdw);
- xc->regs.MiscRegs.pstate = Rs1 ^ val2;
- }});
- 0x7: wrprtl({{checkPriv
- uint64_t val2 = (I ? SIMM13.sdw : Rs2.sdw);
- xc->regs.MiscRegs.tl = Rs1 ^ val2;
- }});
- 0x8: wrprpil({{checkPriv
- uint64_t val2 = (I ? SIMM13.sdw : Rs2.sdw);
- xc->regs.MiscRegs.pil = Rs1 ^ val2;
- }});
- 0x9: wrprcwp({{checkPriv
- uint64_t val2 = (I ? SIMM13.sdw : Rs2.sdw);
- xc->regs.MiscRegs.cwp = Rs1 ^ val2;
- }});
- 0xA: wrprcansave({{checkPriv
- uint64_t val2 = (I ? SIMM13.sdw : Rs2.sdw);
- xc->regs.MiscRegs.cansave = Rs1 ^ val2;
- }});
- 0xB: wrprcanrestore({{checkPriv
- uint64_t val2 = (I ? SIMM13.sdw : Rs2.sdw);
- xc->regs.MiscRegs.canrestore = Rs1 ^ val2;
- }});
- 0xC: wrprcleanwin({{checkPriv
- uint64_t val2 = (I ? SIMM13.sdw : Rs2.sdw);
- xc->regs.MiscRegs.cleanwin = Rs1 ^ val2;
- }});
- 0xD: wrprotherwin({{checkPriv
- uint64_t val2 = (I ? SIMM13.sdw : Rs2.sdw);
- xc->regs.MiscRegs.otherwin = Rs1 ^ val2;
- }});
- 0xE: wrprwstate({{checkPriv
- uint64_t val2 = (I ? SIMM13.sdw : Rs2.sdw);
- xc->regs.MiscRegs.wstate = Rs1 ^ val2;
- }});
- }
-
- 0x34: Trap::fpop1({{Throw fp_disabled;}}); //FPOP1
- 0x35: Trap::fpop2({{Throw fp_disabled;}}); //FPOP2
-
-
- 0x38: Branch::jmpl({{//Stuff}}); //JMPL
- 0x39: Branch::return({{//Other Stuff}}); //RETURN
- 0x3A: Trap::tcc({{
- switch((CC14 << 1) | (CC04 << 0))
- {
- case 1: case 3:
- throw illegal_instruction;
- case 0:
- if(passesCondition(xc->regs.MiscRegs.ccrFields.icc, machInst<25:28>))
- throw trap_instruction;
- break;
- case 2:
- if(passesCondition(xc->regs.MiscRegs.ccrFields.xcc, machInst<25:28>))
- throw trap_instruction;
- break;
- }
- }}); //Tcc
- 0x3B: BasicOperate::flush({{//Lala}}); //FLUSH
- 0x3C: BasicOperate::save({{//leprechauns); //SAVE
- 0x3D: BasicOperate::restore({{//Eat my short int}}); //RESTORE
- 0x3E: decode FCN {
- 0x1: BasicOperate::done({{//Done thing}}); //DONE
- 0x2: BasicOperate::retry({{//Retry thing}}); //RETRY
- }
+ 0x0: Trap::movccfcc({{fault = new FpDisabled}});
+ 0x1: decode CC
+ {
+ 0x0: movcci({{
+ if(passesCondition(CcrIcc, COND4))
+ Rd = (I ? SIMM11 : RS2);
+ }});
+ 0x2: movccx({{
+ if(passesCondition(CcrXcc, COND4))
+ Rd = (I ? SIMM11 : RS2);
+ }});
+ }
}
- }
- 0x3: decode OP3 {
- format Mem {
- 0x00: lduw({{Rd.uw = Mem.uw;}}); //LDUW
- 0x01: ldub({{Rd.ub = Mem.ub;}}); //LDUB
- 0x02: lduh({{Rd.uhw = Mem.uhw;}}); //LDUH
- 0x03: ldd({{
- uint64_t val = Mem.udw;
- setIntReg(RD & (~1), val<31:0>);
- setIntReg(RD | 1, val<63:32>);
- }});//LDD
- 0x04: stw({{Mem.sw = Rd.sw;}}); //STW
- 0x05: stb({{Mem.sb = Rd.sb;}}); //STB
- 0x06: sth({{Mem.shw = Rd.shw;}}); //STH
- 0x07: std({{
- Mem.udw = readIntReg(RD & (~1))<31:0> | (readIntReg(RD | 1)<31:0> << 32);
- }});//STD
- 0x08: ldsw({{Rd.sw = Mem.sw;}}); //LDSW
- 0x09: ldsb({{Rd.sb = Mem.sb;}}); //LDSB
- 0x0A: ldsh({{Rd.shw = Mem.shw;}}); //LDSH
- 0x0B: ldx({{Rd.udw = Mem.udw;}}); //LDX
-
- 0x0D: ldstub({{
- Rd.ub = Mem.ub;
- Mem.ub = 0xFF;
- }}); //LDSTUB
- 0x0E: stx({{Rd.udw = Mem.udw;}}); //STX
- 0x0F: swap({{
- uint32_t temp = Rd.uw;
- Rd.uw = Mem.uw;
- Mem.uw = temp;
- }}); //SWAP
- 0x10: lduwa({{Rd.uw = Mem.uw;}}); //LDUWA
- 0x11: lduba({{Rd.ub = Mem.ub;}}); //LDUBA
- 0x12: lduha({{Rd.uhw = Mem.uhw;}}); //LDUHA
- 0x13: ldda({{
- uint64_t val = Mem.udw;
- setIntReg(RD & (~1), val<31:0>);
- setIntReg(RD | 1, val<63:32>);
- }}); //LDDA
- 0x14: stwa({{Mem.uw = Rd.uw;}}); //STWA
- 0x15: stba({{Mem.ub = Rd.ub;}}); //STBA
- 0x16: stha({{Mem.uhw = Rd.uhw;}}); //STHA
- 0x17: stda({{
- Mem.udw = readIntReg(RD & (~1))<31:0> | (readIntReg(RD | 1)<31:0> << 32);
- }}); //STDA
- 0x18: ldswa({{Rd.sw = Mem.sw;}}); //LDSWA
- 0x19: ldsba({{Rd.sb = Mem.sb;}}); //LDSBA
- 0x1A: ldsha({{Rd.shw = Mem.shw;}}); //LDSHA
- 0x1B: ldxa({{Rd.sdw = Mem.sdw;}}); //LDXA
-
- 0x1D: ldstuba({{
- Rd.ub = Mem.ub;
- Mem.ub = 0xFF;
- }}); //LDSTUBA
- 0x1E: stxa({{Mem.sdw = Rd.sdw}}); //STXA
- 0x1F: swapa({{
- uint32_t temp = Rd.uw;
- Rd.uw = Mem.uw;
- Mem.uw = temp;
- }}); //SWAPA
- 0x20: Trap::ldf({{throw fp_disabled;}}); //LDF
- 0x21: decode X {
- 0x0: Trap::ldfsr({{throw fp_disabled;}}); //LDFSR
- 0x1: Trap::ldxfsr({{throw fp_disabled;}}); //LDXFSR
+ 0x2D: sdivx({{
+ if(Rs2_or_imm13 == 0) fault = new DivisionByZero;
+ else Rd.sdw = Rs1.sdw / Rs2_or_imm13;
+ }});//SDIVX
+ 0x2E: decode RS1 {
+ 0x0: IntOp::popc({{
+ int64_t count = 0, val2 = Rs2_or_imm;
+ uint8_t oneBits[] = {0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4};
+ for(unsigned int x = 0; x < 16; x++)
+ {
+ count += oneBits[Rs2_or_imm13 & 0xF];
+ val2 >> 4;
}
- 0x22: Trap::ldqf({{throw fp_disabled;}}); //LDQF
- 0x23: Trap::lddf({{throw fp_disabled;}}); //LDDF
- 0x24: Trap::stf({{throw fp_disabled;}}); //STF
- 0x25: decode X {
- 0x0: Trap::stfsr({{throw fp_disabled;}}); //STFSR
- 0x1: Trap::stxfsr({{throw fp_disabled;}}); //STXFSR
- }
- 0x26: Trap::stqf({{throw fp_disabled;}}); //STQF
- 0x27: Trap::stdf({{throw fp_disabled;}}); //STDF
-
-
-
-
-
- 0x2D: Noop::prefetch({{ }}); //PREFETCH
+ }});//POPC
+ }
+ 0x2F: decode RCOND3
+ {
+ 0x1: movreq({{if(Rs1 == 0) Rd = Rs2_or_imm10;}});
+ 0x2: movrle({{if(Rs1 <= 0) Rd = Rs2_or_imm10;}});
+ 0x3: movrl({{if(Rs1 < 0) Rd = Rs2_or_imm10;}});
+ 0x5: movrne({{if(Rs1 != 0) Rd = Rs2_or_imm10;}});
+ 0x6: movrg({{if(Rs1 > 0) Rd = Rs2_or_imm10;}});
+ 0x7: movrge({{if(Rs1 >= 0) Rd = Rs2_or_imm10;}});
+ }
+ 0x30: decode RD {
+ 0x0: wry({{Y = Rs1 ^ Rs2_or_imm13;}});
+ 0x2: wrccr({{Ccr = Rs1 ^ Rs2_or_imm13;}});
+ 0x3: wrasi({{Asi = Rs1 ^ Rs2_or_imm13;}});
+ 0x6: wrfprs({{Asi = Rs1 ^ Rs2_or_imm13;}});
+ 0xF: Trap::sir({{fault = new SoftwareInitiatedReset;}});
+ }
+ 0x31: decode FCN {
+ 0x0: BasicOperate::saved({{//Boogy Boogy}}); //SAVED
+ 0x1: BasicOperate::restored({{//Boogy Boogy}}); //RESTORED
+ }
+ 0x32: decode RD {
+ format Priv
+ {
+ 0x0: wrprtpc({{
+ xc->setMiscReg(MISCREG_TPC_BASE + Tl,
+ Rs1 ^ Rs2_or_imm13);
+ }});
+ 0x1: wrprtnpc({{
+ xc->setMiscReg(MISCREG_TNPC_BASE + Tl,
+ Rs1 ^ Rs2_or_imm13);
+ }});
+ 0x2: wrprtstate({{
+ xc->setMiscReg(MISCREG_TSTATE_BASE + Tl,
+ Rs1 ^ Rs2_or_imm13);
+ }});
+ 0x3: wrprtt({{
+ xc->setMiscReg(MISCREG_TT_BASE + Tl,
+ Rs1 ^ Rs2_or_imm13);
+ }});
+ 0x4: wrprtick({{Tick = Rs1 ^ Rs2_or_imm13;}});
+ 0x5: wrprtba({{Tba = Rs1 ^ Rs2_or_imm13;}});
+ 0x6: wrprpstate({{Pstate = Rs1 ^ Rs2_or_imm13;}});
+ 0x7: wrprtl({{Tl = Rs1 ^ Rs2_or_imm13;}});
+ 0x8: wrprpil({{Pil = Rs1 ^ Rs2_or_imm13;}});
+ 0x9: wrprcwp({{Cwp = Rs1 ^ Rs2_or_imm13;}});
+ 0xA: wrprcansave({{Cansave = Rs1 ^ Rs2_or_imm13;}});
+ 0xB: wrprcanrestore({{Canrestore = Rs1 ^ Rs2_or_imm13;}});
+ 0xC: wrprcleanwin({{Cleanwin = Rs1 ^ Rs2_or_imm13;}});
+ 0xD: wrprotherwin({{Otherwin = Rs1 ^ Rs2_or_imm13;}});
+ 0xE: wrprwstate({{Wstate = Rs1 ^ Rs2_or_imm13;}});
+ }
+ }
+ 0x34: Trap::fpop1({{fault = new FpDisabled;}});
+ 0x35: Trap::fpop2({{fault = new FpDisabled;}});
- 0x30: Trap::ldfa({{throw fp_disabled;}}); //LDFA
+ 0x38: Branch::jmpl({{//Stuff}}); //JMPL
+ 0x39: Branch::return({{//Other Stuff}}); //RETURN
+ 0x3A: decode CC
+ {
+ 0x0: Trap::tcci({{
+#if FULL_SYSTEM
+ fault = new TrapInstruction;
+#else
+ if(passesCondition(CcrIcc, machInst<25:28>))
+ // At least glibc only uses trap 0,
+ // solaris/sunos may use others
+ assert((I ? Rs1 + Rs2 : Rs1 + SW_TRAP) == 0);
+ xc->syscall();
+#endif
+ }});
+ 0x2: Trap::tccx({{
+#if FULL_SYSTEM
+ fault = new TrapInstruction;
+#else
+ if(passesCondition(CcrXcc, machInst<25:28>))
+ // At least glibc only uses trap 0,
+ // solaris/sunos may use others
+ assert((I ? Rs1 + Rs2 : Rs1 + SW_TRAP) == 0);
+ xc->syscall();
+#endif
+ }});
+ }
+ 0x3B: BasicOperate::flush({{//Lala}}); //FLUSH
+ 0x3C: BasicOperate::save({{//leprechauns); //SAVE
+ 0x3D: BasicOperate::restore({{//Eat my short int}}); //RESTORE
+ 0x3E: decode FCN {
+ 0x1: BasicOperate::done({{//Done thing}}); //DONE
+ 0x2: BasicOperate::retry({{//Retry thing}}); //RETRY
+ }
+ }
+ }
+ 0x3: decode OP3 {
+ format Mem {
+ 0x00: lduw({{Rd.uw = Mem.uw;}}); //LDUW
+ 0x01: ldub({{Rd.ub = Mem.ub;}}); //LDUB
+ 0x02: lduh({{Rd.uhw = Mem.uhw;}}); //LDUH
+ 0x03: ldd({{
+ uint64_t val = Mem.udw;
+ setIntReg(RD & (~1), val<31:0>);
+ setIntReg(RD | 1, val<63:32>);
+ }});//LDD
+ 0x04: stw({{Mem.sw = Rd.sw;}}); //STW
+ 0x05: stb({{Mem.sb = Rd.sb;}}); //STB
+ 0x06: sth({{Mem.shw = Rd.shw;}}); //STH
+ 0x07: std({{
+ Mem.udw = readIntReg(RD & (~1))<31:0> | (readIntReg(RD | 1)<31:0> << 32);
+ }});//STD
+ 0x08: ldsw({{Rd.sw = Mem.sw;}}); //LDSW
+ 0x09: ldsb({{Rd.sb = Mem.sb;}}); //LDSB
+ 0x0A: ldsh({{Rd.shw = Mem.shw;}}); //LDSH
+ 0x0B: ldx({{Rd.udw = Mem.udw;}}); //LDX
- 0x32: Trap::ldqfa({{throw fp_disabled;}}); //LDQFA
- 0x33: Trap::lddfa({{throw fp_disabled;}}); //LDDFA
- 0x34: Trap::stfa({{throw fp_disabled;}}); //STFA
- 0x35: Trap::stqfa({{throw fp_disabled;}}); //STQFA
- 0x36: Trap::stdfa({{throw fp_disabled;}}); //STDFA
+ 0x0D: ldstub({{
+ Rd.ub = Mem.ub;
+ Mem.ub = 0xFF;
+ }}); //LDSTUB
+ 0x0E: stx({{Rd.udw = Mem.udw;}}); //STX
+ 0x0F: swap({{
+ uint32_t temp = Rd.uw;
+ Rd.uw = Mem.uw;
+ Mem.uw = temp;
+ }}); //SWAP
+ 0x10: lduwa({{Rd.uw = Mem.uw;}}); //LDUWA
+ 0x11: lduba({{Rd.ub = Mem.ub;}}); //LDUBA
+ 0x12: lduha({{Rd.uhw = Mem.uhw;}}); //LDUHA
+ 0x13: ldda({{
+ uint64_t val = Mem.udw;
+ setIntReg(RD & (~1), val<31:0>);
+ setIntReg(RD | 1, val<63:32>);
+ }}); //LDDA
+ 0x14: stwa({{Mem.uw = Rd.uw;}}); //STWA
+ 0x15: stba({{Mem.ub = Rd.ub;}}); //STBA
+ 0x16: stha({{Mem.uhw = Rd.uhw;}}); //STHA
+ 0x17: stda({{
+ Mem.udw = readIntReg(RD & (~1))<31:0> | (readIntReg(RD | 1)<31:0> << 32);
+ }}); //STDA
+ 0x18: ldswa({{Rd.sw = Mem.sw;}}); //LDSWA
+ 0x19: ldsba({{Rd.sb = Mem.sb;}}); //LDSBA
+ 0x1A: ldsha({{Rd.shw = Mem.shw;}}); //LDSHA
+ 0x1B: ldxa({{Rd.sdw = Mem.sdw;}}); //LDXA
+ 0x1D: ldstuba({{
+ Rd.ub = Mem.ub;
+ Mem.ub = 0xFF;
+ }}); //LDSTUBA
+ 0x1E: stxa({{Mem.sdw = Rd.sdw}}); //STXA
+ 0x1F: swapa({{
+ uint32_t temp = Rd.uw;
+ Rd.uw = Mem.uw;
+ Mem.uw = temp;
+ }}); //SWAPA
+ 0x20: Trap::ldf({{fault = new FpDisabled;}});
+ 0x21: decode X {
+ 0x0: Trap::ldfsr({{fault = new FpDisabled;}});
+ 0x1: Trap::ldxfsr({{fault = new FpDisabled;}});
+ }
+ 0x22: Trap::ldqf({{fault = new FpDisabled;}});
+ 0x23: Trap::lddf({{fault = new FpDisabled;}});
+ 0x24: Trap::stf({{fault = new FpDisabled;}});
+ 0x25: decode X {
+ 0x0: Trap::stfsr({{fault = new FpDisabled;}});
+ 0x1: Trap::stxfsr({{fault = new FpDisabled;}});
+ }
+ 0x26: Trap::stqf({{fault = new FpDisabled;}});
+ 0x27: Trap::stdf({{fault = new FpDisabled;}});
+ 0x2D: Noop::prefetch({{ }}); //PREFETCH
+ 0x30: Trap::ldfa({{return new FpDisabled;}});
+ 0x32: Trap::ldqfa({{fault = new FpDisabled;}});
+ 0x33: Trap::lddfa({{fault = new FpDisabled;}});
+ 0x34: Trap::stfa({{fault = new FpDisabled;}});
+ 0x35: Trap::stqfa({{fault = new FpDisabled;}});
+ 0x36: Trap::stdfa({{fault = new FpDisabled;}});
- 0x3C: Cas::casa(
- {{uint64_t val = Mem.uw;
- if(Rs2.uw == val)
- Mem.uw = Rd.uw;
- Rd.uw = val;
- }}); //CASA
- 0x3D: Noop::prefetcha({{ }}); //PREFETCHA
- 0x3E: Cas::casxa(
- {{uint64_t val = Mem.udw;
- if(Rs2 == val)
- Mem.udw = Rd;
- Rd = val;
- }}); //CASXA
- }
- }
+ 0x3C: Cas::casa(
+ {{uint64_t val = Mem.uw;
+ if(Rs2.uw == val)
+ Mem.uw = Rd.uw;
+ Rd.uw = val;
+ }}); //CASA
+ 0x3D: Noop::prefetcha({{ }}); //PREFETCHA
+ 0x3E: Cas::casxa({{
+ uint64_t val = Mem.udw;
+ if(Rs2 == val)
+ Mem.udw = Rd;
+ Rd = val;
+ }}); //CASXA
+ }
+ }
}
diff --git a/arch/sparc/isa/formats.isa b/arch/sparc/isa/formats.isa
index 547f8be48..9310ba3d3 100644
--- a/arch/sparc/isa/formats.isa
+++ b/arch/sparc/isa/formats.isa
@@ -5,12 +5,21 @@
//Include the integerOp and integerOpCc format
##include "m5/arch/sparc/isa/formats/integerop.isa"
-//Include the mem format
+//Include the memory format
##include "m5/arch/sparc/isa/formats/mem.isa"
+//Include the compare and swap format
+##include "m5/arch/sparc/isa/formats/cas.isa"
+
//Include the trap format
##include "m5/arch/sparc/isa/formats/trap.isa"
+//Include the "unknown" format
+##include "m5/arch/sparc/isa/formats/unknown.isa"
+
+//Include the priveleged mode format
+##include "m5/arch/sparc/isa/formats/priv.isa"
+
//Include the branch format
##include "m5/arch/sparc/isa/formats/branch.isa"
diff --git a/arch/sparc/isa/formats/branch.isa b/arch/sparc/isa/formats/branch.isa
index 80101de1b..b9dc960de 100644
--- a/arch/sparc/isa/formats/branch.isa
+++ b/arch/sparc/isa/formats/branch.isa
@@ -34,7 +34,6 @@ def template BranchExecute {{
{
//Attempt to execute the instruction
Fault fault = NoFault;
- checkPriv;
%(op_decl)s;
%(op_rd)s;
@@ -57,6 +56,6 @@ def format Branch(code, *opt_flags) {{
iop = InstObjParams(name, Name, 'SparcStaticInst', cblk, opt_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
- decode_block = BasicDecodeWithMnemonic.subst(iop)
+ decode_block = BasicDecode.subst(iop)
exec_output = BranchExecute.subst(iop)
}};
diff --git a/arch/sparc/isa/formats/integerop.isa b/arch/sparc/isa/formats/integerop.isa
index 5a9e09896..e7bd4c2a4 100644
--- a/arch/sparc/isa/formats/integerop.isa
+++ b/arch/sparc/isa/formats/integerop.isa
@@ -7,106 +7,159 @@ output header {{
/**
* Base class for integer operations.
*/
- class IntegerOp : public SparcStaticInst
+ class IntOp : public SparcStaticInst
{
protected:
// Constructor
- IntegerOp(const char *mnem, MachInst _machInst, OpClass __opClass) :
+ IntOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass) :
SparcStaticInst(mnem, _machInst, __opClass)
{
}
std::string generateDisassembly(Addr pc,
- const SymbolTable *symtab) const;
+ const SymbolTable *symtab) const;
+ };
+
+ /**
+ * Base class for 10 bit immediate integer operations.
+ */
+ class IntOpImm10 : public IntOp
+ {
+ protected:
+ // Constructor
+ IntOpImm10(const char *mnem, ExtMachInst _machInst, OpClass __opClass) :
+ IntOp(mnem, _machInst, __opClass), imm(SIMM10)
+ {
+ }
+
+ uint32_t imm;
+ };
+
+ /**
+ * Base class for 13 bit immediate integer operations.
+ */
+ class IntOpImm13 : public IntOp
+ {
+ protected:
+ // Constructor
+ IntOpImm13(const char *mnem, ExtMachInst _machInst, OpClass __opClass) :
+ IntOp(mnem, _machInst, __opClass), imm(SIMM13)
+ {
+ }
+
+ uint32_t imm;
};
}};
output decoder {{
- std::string IntegerOp::generateDisassembly(Addr pc,
+ std::string IntOp::generateDisassembly(Addr pc,
const SymbolTable *symtab) const
{
- return "Integer instruction\n";
+ return "Integer instruction\n";
}
}};
-def template IntegerExecute {{
- Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
+def template IntOpExecute {{
+ Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
{
- //These are set to constants when the execute method
- //is generated
- bool useCc = ;
- bool checkPriv = ;
-
- //Attempt to execute the instruction
- try
- {
- checkPriv;
-
- %(op_decl)s;
- %(op_rd)s;
- %(code)s;
- }
- //If we have an exception for some reason,
- //deal with it
- catch(SparcException except)
- {
- //Deal with exception
- return No_Fault;
- }
-
- //Write the resulting state to the execution context
+ Fault fault = NoFault;
+
+ %(op_decl)s;
+ %(op_rd)s;
+ %(code)s;
+
+ //Write the resulting state to the execution context
+ if(fault == NoFault)
%(op_wb)s;
- if(useCc)
- {
- xc->regs.miscRegFile.ccrFields.iccFields.n = Rd & (1 << 63);
- xc->regs.miscRegFile.ccrFields.iccFields.z = (Rd == 0);
- xc->regs.miscRegFile.ccrFields.iccFields.v = ivValue;
- xc->regs.miscRegFile.ccrFields.iccFields.c = icValue;
- xc->regs.miscRegFile.ccrFields.xccFields.n = Rd & (1 << 31);
- xc->regs.miscRegFile.ccrFields.xccFields.z = ((Rd & 0xFFFFFFFF) == 0);
- xc->regs.miscRegFile.ccrFields.xccFields.v = xvValue;
- xc->regs.miscRegFile.ccrFields.xccFields.c = xcValue;
- }
- return No_Fault;
+ return fault;
}
}};
-// Primary format for integer operate instructions:
-def format IntegerOp(code, *opt_flags) {{
- orig_code = code
- cblk = CodeBlock(code)
- checkPriv = (code.find('checkPriv') != -1)
- code.replace('checkPriv', '')
- if checkPriv:
- code.replace('checkPriv;', 'if(!xc->regs.miscRegFile.pstateFields.priv) throw privileged_opcode;')
- else:
- code.replace('checkPriv;', '')
- for (marker, value) in (('ivValue', '0'), ('icValue', '0'),
- ('xvValue', '0'), ('xcValue', '0')):
- code.replace(marker, value)
- iop = InstObjParams(name, Name, 'SparcStaticInst', cblk, opt_flags)
+def template IntOpCcExecute {{
+ Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ Fault fault;
+
+ %(op_decl)s;
+ %(op_rd)s;
+ %(code)s;
+
+ //Write the resulting state to the execution context
+ if(fault == NoFault)
+ {
+ %(op_wb)s;
+ CcrIccN = Rd & (1 << 63);
+ CcrIccZ = (Rd == 0);
+ CcrIccV = ivValue;
+ CcrIccC = icValue;
+ CcrXccN = Rd & (1 << 31);
+ CcrXccZ = ((Rd & 0xFFFFFFFF) == 0);
+ CcrXccV = xvValue;
+ CcrXccC = xcValue;
+ }
+ return fault;
+ }
+}};
+
+def template IntOpCcResExecute {{
+ Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ Fault fault;
+
+ %(op_decl)s;
+ %(op_rd)s;
+ %(code)s;
+
+ //Write the resulting state to the execution context
+ if(fault == NoFault)
+ {
+ %(op_wb)s;
+ CcrIccN = Rd & (1 << 63);
+ CcrIccZ = (Rd == 0);
+ CcrXccN = Rd & (1 << 31);
+ CcrXccZ = ((Rd & 0xFFFFFFFF) == 0);
+ CcrIccV = CcrIccC = CcrXccV = CcrXccC = 0;
+ }
+ return fault;
+ }
+}};
+
+let {{
+ def doIntFormat(code, execTemplate, name, Name, opt_flags):
+ (usesImm, cblk, immCblk, rString, iString) = splitOutImm(code)
+ iop = InstObjParams(name, Name, 'IntOp', cblk, opt_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
- decode_block = BasicDecodeWithMnemonic.subst(iop)
- exec_output = IntegerExecute.subst(iop)
+ exec_output = execTemplate.subst(iop)
+ if usesImm:
+ imm_iop = InstObjParams(name, Name + 'Imm', 'IntOpImm' + iString,
+ immCblk, opt_flags)
+ header_output += BasicDeclare.subst(imm_iop)
+ decoder_output += BasicConstructor.subst(imm_iop)
+ exec_output += execTemplate.subst(imm_iop)
+ decode_block = ROrImmDecode.subst(iop)
+ else:
+ decode_block = BasicDecode.subst(iop)
}};
// Primary format for integer operate instructions:
-def format IntegerOpCc(code, icValue, ivValue, xcValue, xvValue, *opt_flags) {{
- orig_code = code
- cblk = CodeBlock(code)
- checkPriv = (code.find('checkPriv') != -1)
- code.replace('checkPriv', '')
- if checkPriv:
- code.replace('checkPriv;', 'if(!xc->regs.miscRegFile.pstateFields.priv) throw privileged_opcode;')
- else:
- code.replace('checkPriv;', '')
- for (marker, value) in (('ivValue', ivValue), ('icValue', icValue),
- ('xvValue', xvValue), ('xcValue', xcValue)):
- code.replace(marker, value)
- iop = InstObjParams(name, Name, 'SparcStaticInst', cblk, opt_flags)
- header_output = BasicDeclare.subst(iop)
- decoder_output = BasicConstructor.subst(iop)
- decode_block = BasicDecodeWithMnemonic.subst(iop)
- exec_output = IntegerExecute.subst(iop)
+def format IntOp(code, *opt_flags) {{
+ doIntFormat(code, IntOpExecute, name, Name, opt_flags)
}};
+
+// Primary format for integer operate instructions:
+def format IntOpCc(code, icValue, ivValue, xcValue, xvValue, *opt_flags) {{
+ for (marker, value) in (('ivValue', ivValue), ('icValue', icValue),
+ ('xvValue', xvValue), ('xcValue', xcValue)):
+ code.replace(marker, value)
+ doIntFormat(code, IntOpCcExecute, name, Name, opt_flags)
+}};
+
+// Primary format for integer operate instructions:
+def format IntOpCcRes(code, *opt_flags) {{
+ doIntFormat(code, IntOpCcResExecute, name, Name, opt_flags)
+}};
+
diff --git a/arch/sparc/isa/formats/mem.isa b/arch/sparc/isa/formats/mem.isa
index d72de47d0..06725eae8 100644
--- a/arch/sparc/isa/formats/mem.isa
+++ b/arch/sparc/isa/formats/mem.isa
@@ -12,7 +12,7 @@ output header {{
protected:
// Constructor
- Mem(const char *mnem, MachInst _machInst, OpClass __opClass) :
+ Mem(const char *mnem, ExtMachInst _machInst, OpClass __opClass) :
SparcStaticInst(mnem, _machInst, __opClass)
{
}
@@ -56,18 +56,7 @@ def format Mem(code, *opt_flags) {{
iop = InstObjParams(name, Name, 'SparcStaticInst', cblk, opt_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
- decode_block = BasicDecodeWithMnemonic.subst(iop)
+ decode_block = BasicDecode.subst(iop)
exec_output = MemExecute.subst(iop)
exec_output.replace('ea_code', 'EA = I ? (R1 + SIMM13) : R1 + R2;');
}};
-
-def format Cas(code, *opt_flags) {{
- orig_code = code
- cblk = CodeBlock(code)
- iop = InstObjParams(name, Name, 'SparcStaticInst', cblk, opt_flags)
- header_output = BasicDeclare.subst(iop)
- decoder_output = BasicConstructor.subst(iop)
- decode_block = BasicDecodeWithMnemonic.subst(iop)
- exec_output = MemExecute.subst(iop)
- exec_output.replace('ea_code', 'EA = R1;');
-}};
diff --git a/arch/sparc/isa/formats/noop.isa b/arch/sparc/isa/formats/noop.isa
index fa4047f06..5007f5bcb 100644
--- a/arch/sparc/isa/formats/noop.isa
+++ b/arch/sparc/isa/formats/noop.isa
@@ -11,7 +11,7 @@ output header {{
{
protected:
// Constructor
- Noop(const char *mnem, MachInst _machInst, OpClass __opClass) :
+ Noop(const char *mnem, ExtMachInst _machInst, OpClass __opClass) :
SparcStaticInst(mnem, _machInst, __opClass)
{
}
@@ -45,6 +45,6 @@ def format Noop(code, *opt_flags) {{
iop = InstObjParams(name, Name, 'SparcStaticInst', cblk, opt_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
- decode_block = BasicDecodeWithMnemonic.subst(iop)
+ decode_block = BasicDecode.subst(iop)
exec_output = NoopExecute.subst(iop)
}};
diff --git a/arch/sparc/isa/formats/priv.isa b/arch/sparc/isa/formats/priv.isa
new file mode 100644
index 000000000..c89e769b4
--- /dev/null
+++ b/arch/sparc/isa/formats/priv.isa
@@ -0,0 +1,165 @@
+////////////////////////////////////////////////////////////////////
+//
+// Privilege mode instructions
+//
+
+output header {{
+ /**
+ * Base class for privelege mode operations.
+ */
+ class Priv : public SparcStaticInst
+ {
+ protected:
+ // Constructor
+ Priv(const char *mnem, ExtMachInst _machInst, OpClass __opClass) :
+ SparcStaticInst(mnem, _machInst, __opClass)
+ {
+ }
+
+ std::string generateDisassembly(Addr pc,
+ const SymbolTable *symtab) const;
+ };
+
+ /**
+ * Base class for user mode "tick" access.
+ */
+ class PrivTick : public SparcStaticInst
+ {
+ protected:
+ // Constructor
+ PrivTick(const char *mnem, ExtMachInst _machInst,
+ OpClass __opClass) :
+ SparcStaticInst(mnem, _machInst, __opClass)
+ {
+ }
+
+ std::string generateDisassembly(Addr pc,
+ const SymbolTable *symtab) const;
+ };
+
+ /**
+ * Base class for privelege mode operations with immediates.
+ */
+ class PrivImm : public Priv
+ {
+ protected:
+ // Constructor
+ PrivImm(const char *mnem, ExtMachInst _machInst,
+ OpClass __opClass) :
+ Priv(mnem, _machInst, __opClass), imm(SIMM13)
+ {
+ }
+
+ uint32_t imm;
+ };
+
+ /**
+ * Base class for user mode "tick" access with immediates.
+ */
+ class PrivTickImm : public PrivTick
+ {
+ protected:
+ // Constructor
+ PrivTickImm(const char *mnem, ExtMachInst _machInst,
+ OpClass __opClass) :
+ PrivTick(mnem, _machInst, __opClass), imm(SIMM13)
+ {
+ }
+
+ uint32_t imm;
+ };
+}};
+
+output decoder {{
+ std::string Priv::generateDisassembly(Addr pc,
+ const SymbolTable *symtab) const
+ {
+ return "Privileged Instruction";
+ }
+
+ std::string PrivTick::generateDisassembly(Addr pc,
+ const SymbolTable *symtab) const
+ {
+ return "Regular access to Tick";
+ }
+}};
+
+def template PrivExecute {{
+ Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ %(op_decl)s;
+ %(op_rd)s;
+
+ //If the processor isn't in privileged mode, fault out right away
+ if(!PstatePriv)
+ return new PrivilegedOpcode
+
+ %(code)s;
+ %(op_wb)s;
+ }
+}};
+
+def template PrivTickExecute {{
+ Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ %(op_decl)s;
+ %(op_rd)s;
+
+ //If the processor isn't in privileged mode, fault out right away
+ if(!PstatePriv && TickNpt)
+ return new PrivilegedAction
+
+ %(code)s;
+ %(op_wb)s;
+ }
+}};
+
+// Primary format for integer operate instructions:
+def format Priv(code, *opt_flags) {{
+ uses_imm = (code.find('Rs2_or_imm13') != -1)
+ if uses_imm:
+ orig_code = code
+ code = re.sub(r'Rs2_or_imm13', 'Rs2', orig_code)
+ imm_code = re.sub(r'Rs2_or_imm13(\.\w+)?', 'imm', orig_code)
+ cblk = CodeBlock(code)
+ iop = InstObjParams(name, Name, 'Priv', cblk, opt_flags)
+ header_output = BasicDeclare.subst(iop)
+ decoder_output = BasicConstructor.subst(iop)
+ exec_output = PrivExecute.subst(iop)
+ if uses_imm:
+ imm_cblk = CodeBlock(imm_code)
+ imm_iop = InstObjParams(name, Name + 'Imm', 'PrivImm', imm_cblk,
+ opt_flags)
+ header_output += BasicDeclare.subst(imm_iop)
+ decoder_output += BasicConstructor.subst(imm_iop)
+ exec_output += PrivExecute.subst(imm_iop)
+ decode_block = ROrImmDecode.subst(iop)
+ else:
+ decode_block = BasicDecode.subst(iop)
+}};
+
+// Primary format for integer operate instructions:
+def format PrivTick(code, *opt_flags) {{
+ uses_imm = (code.find('Rs2_or_imm13') != -1)
+ if uses_imm:
+ orig_code = code
+ code = re.sub(r'Rs2_or_imm13', 'Rs2', orig_code)
+ imm_code = re.sub(r'Rs2_or_imm13(\.\w+)?', 'imm', orig_code)
+ cblk = CodeBlock(code)
+ iop = InstObjParams(name, Name, 'PrivTick', cblk, opt_flags)
+ header_output = BasicDeclare.subst(iop)
+ decoder_output = BasicConstructor.subst(iop)
+ exec_output = PrivTickExecute.subst(iop)
+ if uses_imm:
+ imm_cblk = CodeBlock(imm_code)
+ imm_iop = InstObjParams(name, Name + 'Imm', 'PrivTickImm', imm_cblk,
+ opt_flags)
+ header_output += BasicDeclare.subst(imm_iop)
+ decoder_output += BasicConstructor.subst(imm_iop)
+ exec_output += PrivTickExecute.subst(imm_iop)
+ decode_block = Rb2OrImmDecode.subst(iop)
+ else:
+ decode_block = BasicDecode.subst(iop)
+}};
diff --git a/arch/sparc/isa/formats/trap.isa b/arch/sparc/isa/formats/trap.isa
index ff3aadf72..935fbfe6b 100644
--- a/arch/sparc/isa/formats/trap.isa
+++ b/arch/sparc/isa/formats/trap.isa
@@ -5,14 +5,15 @@
output header {{
/**
- * Base class for integer operations.
+ * Base class for trap instructions,
+ * or instructions that always fault.
*/
class Trap : public SparcStaticInst
{
protected:
// Constructor
- Trap(const char *mnem, MachInst _machInst, OpClass __opClass) :
+ Trap(const char *mnem, ExtMachInst _machInst, OpClass __opClass) :
SparcStaticInst(mnem, _machInst, __opClass)
{
}
@@ -34,18 +35,18 @@ def template TrapExecute {{
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
- //TODO: set up a software fault and return it.
- return NoFault;
+ Fault fault = NoFault;
+ %(code)s
+ return fault;
}
}};
-// Primary format for integer operate instructions:
def format Trap(code, *opt_flags) {{
orig_code = code
cblk = CodeBlock(code)
iop = InstObjParams(name, Name, 'SparcStaticInst', cblk, opt_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
- decode_block = BasicDecodeWithMnemonic.subst(iop)
+ decode_block = BasicDecode.subst(iop)
exec_output = TrapExecute.subst(iop)
}};
diff --git a/arch/sparc/isa/formats/unknown.isa b/arch/sparc/isa/formats/unknown.isa
new file mode 100644
index 000000000..eeb2b9496
--- /dev/null
+++ b/arch/sparc/isa/formats/unknown.isa
@@ -0,0 +1,46 @@
+////////////////////////////////////////////////////////////////////
+//
+// Unknown instructions
+//
+
+output header {{
+ /**
+ * Class for Unknown/Illegal instructions
+ */
+ class Unknown : public SparcStaticInst
+ {
+ public:
+
+ // Constructor
+ Unknown(ExtMachInst _machInst) :
+ SparcStaticInst("unknown", _machInst, No_OpClass)
+ {
+ }
+
+ %(BasicExecDeclare)s
+
+ std::string generateDisassembly(Addr pc,
+ const SymbolTable *symtab) const;
+
+ };
+}};
+
+output decoder {{
+ std::string Unknown::generateDisassembly(Addr pc,
+ const SymbolTable *symtab) const
+ {
+ return "Unknown instruction\n";
+ }
+}};
+
+output exec {{
+ Fault Unknown::execute(%(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ return new IllegalInstruction;
+ }
+}};
+
+def format Unknown() {{
+ decode_block = 'return new Unknown(machInst);\n'
+}};
diff --git a/arch/sparc/isa/includes.isa b/arch/sparc/isa/includes.isa
index a99018b49..c39fc2ef9 100644
--- a/arch/sparc/isa/includes.isa
+++ b/arch/sparc/isa/includes.isa
@@ -10,7 +10,7 @@ output header {{
#include "cpu/static_inst.hh"
#include "arch/sparc/faults.hh"
-#include "mem/mem_req.hh" // some constructors use MemReq flags
+#include "mem/request.hh" // some constructors use MemReq flags
#include "arch/sparc/isa_traits.hh"
}};
@@ -34,10 +34,12 @@ output exec {{
#endif
#ifdef FULL_SYSTEM
-//#include "arch/alpha/pseudo_inst.hh"
+//#include "sim/pseudo_inst.hh"
#endif
#include "cpu/base.hh"
#include "cpu/exetrace.hh"
#include "sim/sim_exit.hh"
+
+using namespace SparcISA;
}};
diff --git a/arch/sparc/isa/operands.isa b/arch/sparc/isa/operands.isa
index 64f5abd08..abfdf7bcd 100644
--- a/arch/sparc/isa/operands.isa
+++ b/arch/sparc/isa/operands.isa
@@ -27,5 +27,84 @@ def operands {{
#'Runiq': ('ControlReg', 'uq', 'Uniq', None, 1),
#'FPCR': ('ControlReg', 'uq', 'Fpcr', None, 1),
'R0': ('IntReg', 'udw', '0', None, 1),
- 'R16': ('IntReg', 'udw', '16', None, 1)
+ 'R16': ('IntReg', 'udw', '16', None, 1),
+ # Control registers
+ 'Pstate': ('ControlReg', 'udw', 'MISCREG_PSTATE', None, 1),
+ 'PstateAg': ('ControlReg', 'udw', 'MISCREG_PSTATE_AG', None, 2),
+ 'PstateIe': ('ControlReg', 'udw', 'MISCREG_PSTATE_IE', None, 3),
+ 'PstatePriv': ('ControlReg', 'udw', 'MISCREG_PSTATE_PRIV', None, 4),
+ 'PstateAm': ('ControlReg', 'udw', 'MISCREG_PSTATE_AM', None, 5),
+ 'PstatePef': ('ControlReg', 'udw', 'MISCREG_PSTATE_PEF', None, 6),
+ 'PstateRed': ('ControlReg', 'udw', 'MISCREG_PSTATE_RED', None, 7),
+ 'PstateMm': ('ControlReg', 'udw', 'MISCREG_PSTATE_MM', None, 8),
+ 'PstateTle': ('ControlReg', 'udw', 'MISCREG_PSTATE_TLE', None, 9),
+ 'PstateCle': ('ControlReg', 'udw', 'MISCREG_PSTATE_CLE', None, 10),
+ 'Tba': ('ControlReg', 'udw', 'MISCREG_TBA', None, 11),
+ 'Y': ('ControlReg', 'udw', 'MISCREG_Y', None, 12),
+ 'YValue': ('ControlReg', 'udw', 'MISCREG_Y_VALUE', None, 13),
+ 'Pil': ('ControlReg', 'udw', 'MISCREG_PIL', None, 14),
+ 'Cwp': ('ControlReg', 'udw', 'MISCREG_CWP', None, 15),
+ #'Tt': ('ControlReg', 'udw', 'MISCREG_TT_BASE + tl', None, 16),
+ 'Ccr': ('ControlReg', 'udw', 'MISCREG_CCR', None, 17),
+ 'CcrIcc': ('ControlReg', 'udw', 'MISCREG_CCR_ICC', None, 18),
+ 'CcrIccC': ('ControlReg', 'udw', 'MISCREG_CCR_ICC_C', None, 19),
+ 'CcrIccV': ('ControlReg', 'udw', 'MISCREG_CCR_ICC_V', None, 20),
+ 'CcrIccZ': ('ControlReg', 'udw', 'MISCREG_CCR_ICC_Z', None, 21),
+ 'CcrIccN': ('ControlReg', 'udw', 'MISCREG_CCR_ICC_N', None, 22),
+ 'CcrXcc': ('ControlReg', 'udw', 'MISCREG_CCR_XCC', None, 23),
+ 'CcrXccC': ('ControlReg', 'udw', 'MISCREG_CCR_XCC_C', None, 22),
+ 'CcrXccV': ('ControlReg', 'udw', 'MISCREG_CCR_XCC_V', None, 23),
+ 'CcrXccZ': ('ControlReg', 'udw', 'MISCREG_CCR_XCC_Z', None, 24),
+ 'CcrXccN': ('ControlReg', 'udw', 'MISCREG_XCC_N', None, 25),
+ 'Asi': ('ControlReg', 'udw', 'MISCREG_ASI', None, 26),
+ 'Tl': ('ControlReg', 'udw', 'MISCREG_TL', None, 27),
+ #'Tpc': ('ControlReg', 'udw', 'MISCREG_TPC', None, 28),
+ 'Tick': ('ControlReg', 'udw', 'MISCREG_TICK', None, 29),
+ 'TickCounter': ('ControlReg', 'udw', 'MISCREG_TICK_COUNTER', None, 32),
+ 'TickNpt': ('ControlReg', 'udw', 'MISCREG_TICK_NPT', None, 33),
+ 'Cansave': ('ControlReg', 'udw', 'MISCREG_CANSAVE', None, 34),
+ 'Canrestore': ('ControlReg', 'udw', 'MISCREG_CANRESTORE', None, 35),
+ 'Otherwin': ('ControlReg', 'udw', 'MISCREG_OTHERWIN', None, 36),
+ 'Cleanwin': ('ControlReg', 'udw', 'MISCREG_CLEANWIN', None, 37),
+ 'Wstate': ('ControlReg', 'udw', 'MISCREG_WSTATE', None, 38),
+ 'WstateNormal': ('ControlReg', 'udw', 'MISCREG_WSTATE_NORMAL', None,39),
+ 'WstateOther': ('ControlReg', 'udw', 'MISCREG_WSTATE_OTHER', None, 40),
+ 'Ver': ('ControlReg', 'udw', 'MISCREG_VER', None, 41),
+ 'VerMaxwin': ('ControlReg', 'udw', 'MISCREG_VER_MAXWIN', None, 42),
+ 'VerMaxtl': ('ControlReg', 'udw', 'MISCREG_VER_MAXTL', None, 43),
+ 'VerMask': ('ControlReg', 'udw', 'MISCREG_VER_MASK', None, 44),
+ 'VerImpl': ('ControlReg', 'udw', 'MISCREG_VER_MASK', None, 45),
+ 'VerManuf': ('ControlReg', 'udw', 'MISCREG_VER_MANUF', None, 46),
+ 'Fsr': ('ControlReg', 'udw', 'MISCREG_FSR', None, 47),
+ 'FsrCexc': ('ControlReg', 'udw', 'MISCREG_FSR_CEXC', None, 48),
+ 'FsrCexcNxc': ('ControlReg', 'udw', 'MISCREG_FSR_CEXC_NXC', None, 49),
+ 'FsrCexcDzc': ('ControlReg', 'udw', 'MISCREG_FSR_CEXC_DZC', None, 50),
+ 'FsrCexcUfc': ('ControlReg', 'udw', 'MISCREG_FSR_CEXC_UFC', None, 51),
+ 'FsrCexcOfc': ('ControlReg', 'udw', 'MISCREG_FSR_CEXC_OFC', None, 52),
+ 'FsrCexcNvc': ('ControlReg', 'udw', 'MISCREG_FSR_CEXC_NVC', None, 53),
+ 'FsrAexc': ('ControlReg', 'udw', 'MISCREG_FSR_AEXC', None, 54),
+ 'FsrAexcNxc': ('ControlReg', 'udw', 'MISCREG_FSR_AEXC_NXC', None, 55),
+ 'FsrAexcDzc': ('ControlReg', 'udw', 'MISCREG_FSR_AEXC_DZC', None, 56),
+ 'FsrAexcUfc': ('ControlReg', 'udw', 'MISCREG_FSR_AEXC_UFC', None, 57),
+ 'FsrAexcOfc': ('ControlReg', 'udw', 'MISCREG_FSR_AEXC_OFC', None, 58),
+ 'FsrAexcNvc': ('ControlReg', 'udw', 'MISCREC_FSR_AEXC_NVC', None, 59),
+ 'FsrFcc0': ('ControlReg', 'udw', 'MISCREG_FSR_FCC0', None, 60),
+ 'FsrQne': ('ControlReg', 'udw', 'MISCREG_FSR_QNE', None, 61),
+ 'FsrFtt': ('ControlReg', 'udw', 'MISCREG_FSR_FTT', None, 62),
+ 'FsrVer': ('ControlReg', 'udw', 'MISCREG_FSR_VER', None, 63),
+ 'FsrNs': ('ControlReg', 'udw', 'MISCREG_FSR_NS', None, 64),
+ 'FsrTem': ('ControlReg', 'udw', 'MISCREG_FSR_TEM', None, 65),
+ 'FsrTemNxm': ('ControlReg', 'udw', 'MISCREG_FSR_TEM_NXM', None, 66),
+ 'FsrTemDzm': ('ControlReg', 'udw', 'MISCREG_FSR_TEM_DZM', None, 67),
+ 'FsrTemUfm': ('ControlReg', 'udw', 'MISCREG_FSR_TEM_UFM', None, 68),
+ 'FsrTemOfm': ('ControlReg', 'udw', 'MISCREG_FSR_TEM_OFM', None, 69),
+ 'FsrTemNvm': ('ControlReg', 'udw', 'MISCREG_FSR_TEM_NVM', None, 70),
+ 'FsrRd': ('ControlReg', 'udw', 'MISCREG_FSR_RD', None, 71),
+ 'FsrFcc1': ('ControlReg', 'udw', 'MISCREG_FSR_FCC1', None, 72),
+ 'FsrFcc2': ('ControlReg', 'udw', 'MISCREG_FSR_FCC2', None, 73),
+ 'FsrFcc3': ('ControlReg', 'udw', 'MISCREG_FSR_FCC3', None, 74),
+ 'Fprs': ('ControlReg', 'udw', 'MISCREG_FPRS', None, 75),
+ 'FprsDl': ('ControlReg', 'udw', 'MISCREG_FPRS_DL', None, 76),
+ 'FprsDu': ('ControlReg', 'udw', 'MISCREG_FPRS_DU', None, 77),
+ 'FprsFef': ('ControlReg', 'udw', 'MISCREG_FPRS_FEF', None, 78)
}};
diff --git a/arch/sparc/isa_traits.hh b/arch/sparc/isa_traits.hh
index bd3c35beb..4886da7cf 100644
--- a/arch/sparc/isa_traits.hh
+++ b/arch/sparc/isa_traits.hh
@@ -29,46 +29,87 @@
#ifndef __ARCH_SPARC_ISA_TRAITS_HH__
#define __ARCH_SPARC_ISA_TRAITS_HH__
-#include "arch/sparc/faults.hh"
#include "base/misc.hh"
#include "config/full_system.hh"
#include "sim/host.hh"
-//This makes sure the big endian versions of certain functions are used.
-namespace BigEndianGuest {}
-using namespace BigEndianGuest;
-
class ExecContext;
class FastCPU;
//class FullCPU;
class Checkpoint;
-#define TARGET_SPARC
-
class StaticInst;
class StaticInstPtr;
-//namespace EV5
-//{
-// int DTB_ASN_ASN(uint64_t reg);
-// int ITB_ASN_ASN(uint64_t reg);
-//}
+namespace BigEndianGuest {}
+
+#if !FULL_SYSTEM
+class SyscallReturn
+{
+ public:
+ template <class T>
+ SyscallReturn(T v, bool s)
+ {
+ retval = (uint64_t)v;
+ success = s;
+ }
+
+ template <class T>
+ SyscallReturn(T v)
+ {
+ success = (v >= 0);
+ retval = (uint64_t)v;
+ }
+
+ ~SyscallReturn() {}
+
+ SyscallReturn& operator=(const SyscallReturn& s)
+ {
+ retval = s.retval;
+ success = s.success;
+ return *this;
+ }
+
+ bool successful() { return success; }
+ uint64_t value() { return retval; }
+
+ private:
+ uint64_t retval;
+ bool success;
+};
+
+#endif
+
namespace SparcISA
{
+
+ // These enumerate all the registers for dependence tracking.
+ enum DependenceTags {
+ // 0..31 are the integer regs 0..31
+ // 32..63 are the FP regs 0..31, i.e. use (reg + FP_Base_DepTag)
+ FP_Base_DepTag = 32,
+ Ctrl_Base_DepTag = 96,
+ };
+
+ //This makes sure the big endian versions of certain functions are used.
+ using namespace BigEndianGuest;
+
typedef uint32_t MachInst;
typedef uint64_t ExtMachInst;
- typedef uint8_t RegIndex;
- const int NumFloatRegs = 32;
+ inline ExtMachInst
+ makeExtMI(MachInst inst, const Addr &pc) {
+ return ExtMachInst(inst);
+ }
+
+ const int NumIntRegs = 32;
+ const int NumFloatRegs = 64;
const int NumMiscRegs = 32;
- const int // Maximum trap level
- const int MaxTL = 4;
- const int
- const int // semantically meaningful register indices
+ // semantically meaningful register indices
const int ZeroReg = 0; // architecturally meaningful
- const int // the rest of these depend on the ABI
+ // the rest of these depend on the ABI
const int StackPointerReg = 14;
const int ReturnAddressReg = 31; // post call, precall is 15
const int ReturnValueReg = 8; // Post return, 24 is pre-return.
@@ -79,363 +120,43 @@ namespace SparcISA
const int ArgumentReg3 = 11;
const int ArgumentReg4 = 12;
const int ArgumentReg5 = 13;
+ const int SyscallNumReg = 1;
// Some OS syscall sue a second register (o1) to return a second value
const int SyscallPseudoReturnReg = ArgumentReg1;
+ //XXX These numbers are bogus
+ const int MaxInstSrcRegs = 3;
+ const int MaxInstDestRegs = 2;
+
+ typedef uint64_t IntReg;
+
+ // control register file contents
+ typedef uint64_t MiscReg;
+
+ typedef double FloatReg;
+ typedef uint64_t FloatRegBits;
//8K. This value is implmentation specific; and should probably
//be somewhere else.
const int LogVMPageSize = 13;
const int VMPageSize = (1 << LogVMPageSize);
+ //Why does both the previous set of constants and this one exist?
+ const int PageShift = 13;
+ const int PageBytes = ULL(1) << PageShift;
+ const int BranchPredAddrShiftAmt = 2;
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- typedef uint64_t IntReg;
-
- class IntRegFile
- {
- private:
- //For right now, let's pretend the register file is static
- IntReg regs[32];
- public:
- IntReg & operator [] (RegIndex index)
- {
- //Don't allow indexes outside of the 32 registers
- index &= 0x1F;
- return regs[index];
- }
- };
+ const int MachineBytes = 8;
+ const int WordBytes = 4;
+ const int HalfwordBytes = 2;
+ const int ByteBytes = 1;
void serialize(std::ostream & os);
void unserialize(Checkpoint *cp, const std::string &section);
- typedef float float32_t;
- typedef double float64_t;
- //FIXME This actually usually refers to a 10 byte float, rather than a
- //16 byte float as required. This data type may have to be emulated.
- typedef long double float128_t;
-
- class FloatRegFile
- {
- private:
- //By using the largest data type, we ensure everything
- //is aligned correctly in memory
- union
- {
- float128_t rawRegs[16];
- uint64_t regDump[32];
- };
- class QuadRegs
- {
- private:
- FloatRegFile * parent;
- public:
- QuadRegs(FloatRegFile * p) : parent(p) {;}
- float128_t & operator [] (RegIndex index)
- {
- //Quad floats are index by the single
- //precision register the start on,
- //and only 16 should be accessed
- index = (index >> 2) & 0xF;
- return parent->rawRegs[index];
- }
- };
- class DoubleRegs
- {
- private:
- FloatRegFile * parent;
- public:
- DoubleRegs(FloatRegFile * p) : parent(p) {;}
- float64_t & operator [] (RegIndex index)
- {
- //Double floats are index by the single
- //precision register the start on,
- //and only 32 should be accessed
- index = (index >> 1) & 0x1F;
- return ((float64_t *)parent->rawRegs)[index];
- }
- };
- class SingleRegs
- {
- private:
- FloatRegFile * parent;
- public:
- SingleRegs(FloatRegFile * p) : parent(p) {;}
- float32_t & operator [] (RegIndex index)
- {
- //Only 32 single floats should be accessed
- index &= 0x1F;
- return ((float32_t *)parent->rawRegs)[index];
- }
- };
- public:
- void serialize(std::ostream & os);
-
- void unserialize(Checkpoint * cp, std::string & section);
-
- QuadRegs quadRegs;
- DoubleRegs doubleRegs;
- SingleRegs singleRegs;
- FloatRegFile() : quadRegs(this), doubleRegs(this), singleRegs(this)
- {;}
- };
-
- // control register file contents
- typedef uint64_t MiscReg;
- // The control registers, broken out into fields
- class MiscRegFile
- {
- private:
- union
- {
- uint16_t pstate; // Process State Register
- struct
- {
- uint16_t ag:1; // Alternate Globals
- uint16_t ie:1; // Interrupt enable
- uint16_t priv:1; // Privelege mode
- uint16_t am:1; // Address mask
- uint16_t pef:1; // PSTATE enable floating-point
- uint16_t red:1; // RED (reset, error, debug) state
- uint16_t mm:2; // Memory Model
- uint16_t tle:1; // Trap little-endian
- uint16_t cle:1; // Current little-endian
- } pstateFields;
- };
- uint64_t tba; // Trap Base Address
- union
- {
- uint64_t y; // Y (used in obsolete multiplication)
- struct
- {
- uint64_t value:32; // The actual value stored in y
- uint64_t :32; // reserved bits
- } yFields;
- };
- uint8_t pil; // Process Interrupt Register
- uint8_t cwp; // Current Window Pointer
- uint16_t tt[MaxTL]; // Trap Type (Type of trap which occured
- // on the previous level)
- union
- {
- uint8_t ccr; // Condition Code Register
- struct
- {
- union
- {
- uint8_t icc:4; // 32-bit condition codes
- struct
- {
- uint8_t c:1; // Carry
- uint8_t v:1; // Overflow
- uint8_t z:1; // Zero
- uint8_t n:1; // Negative
- } iccFields;
- };
- union
- {
- uint8_t xcc:4; // 64-bit condition codes
- struct
- {
- uint8_t c:1; // Carry
- uint8_t v:1; // Overflow
- uint8_t z:1; // Zero
- uint8_t n:1; // Negative
- } xccFields;
- };
- } ccrFields;
- };
- uint8_t asi; // Address Space Identifier
- uint8_t tl; // Trap Level
- uint64_t tpc[MaxTL]; // Trap Program Counter (value from
- // previous trap level)
- uint64_t tnpc[MaxTL]; // Trap Next Program Counter (value from
- // previous trap level)
- union
- {
- uint64_t tstate[MaxTL]; // Trap State
- struct
- {
- //Values are from previous trap level
- uint64_t cwp:5; // Current Window Pointer
- uint64_t :2; // Reserved bits
- uint64_t pstate:10; // Process State
- uint64_t :6; // Reserved bits
- uint64_t asi:8; // Address Space Identifier
- uint64_t ccr:8; // Condition Code Register
- } tstateFields[MaxTL];
- };
- union
- {
- uint64_t tick; // Hardware clock-tick counter
- struct
- {
- uint64_t counter:63; // Clock-tick count
- uint64_t npt:1; // Non-priveleged trap
- } tickFields;
- };
- uint8_t cansave; // Savable windows
- uint8_t canrestore; // Restorable windows
- uint8_t otherwin; // Other windows
- uint8_t cleanwin; // Clean windows
- union
- {
- uint8_t wstate; // Window State
- struct
- {
- uint8_t normal:3; // Bits TT<4:2> are set to on a normal
- // register window trap
- uint8_t other:3; // Bits TT<4:2> are set to on an "otherwin"
- // register window trap
- } wstateFields;
- };
- union
- {
- uint64_t ver; // Version
- struct
- {
- uint64_t maxwin:5; // Max CWP value
- uint64_t :2; // Reserved bits
- uint64_t maxtl:8; // Maximum trap level
- uint64_t :8; // Reserved bits
- uint64_t mask:8; // Processor mask set revision number
- uint64_t impl:16; // Implementation identification number
- uint64_t manuf:16; // Manufacturer code
- } verFields;
- };
- union
- {
- uint64_t fsr; // Floating-Point State Register
- struct
- {
- union
- {
- uint64_t cexc:5; // Current excpetion
- struct
- {
- uint64_t nxc:1; // Inexact
- uint64_t dzc:1; // Divide by zero
- uint64_t ufc:1; // Underflow
- uint64_t ofc:1; // Overflow
- uint64_t nvc:1; // Invalid operand
- } cexecFields;
- };
- union
- {
- uint64_t aexc:5; // Accrued exception
- struct
- {
- uint64_t nxc:1; // Inexact
- uint64_t dzc:1; // Divide by zero
- uint64_t ufc:1; // Underflow
- uint64_t ofc:1; // Overflow
- uint64_t nvc:1; // Invalid operand
- } aexecFields;
- };
- uint64_t fcc0:2; // Floating-Point condtion codes
- uint64_t :1; // Reserved bits
- uint64_t qne:1; // Deferred trap queue not empty
- // with no queue, it should read 0
- uint64_t ftt:3; // Floating-Point trap type
- uint64_t ver:3; // Version (of the FPU)
- uint64_t :2; // Reserved bits
- uint64_t ns:1; // Nonstandard floating point
- union
- {
- uint64_t tem:5; // Trap Enable Mask
- struct
- {
- uint64_t nxm:1; // Inexact
- uint64_t dzm:1; // Divide by zero
- uint64_t ufm:1; // Underflow
- uint64_t ofm:1; // Overflow
- uint64_t nvm:1; // Invalid operand
- } temFields;
- };
- uint64_t :2; // Reserved bits
- uint64_t rd:2; // Rounding direction
- uint64_t fcc1:2; // Floating-Point condition codes
- uint64_t fcc2:2; // Floating-Point condition codes
- uint64_t fcc3:2; // Floating-Point condition codes
- uint64_t :26; // Reserved bits
- } fsrFields;
- };
- union
- {
- uint8_t fprs; // Floating-Point Register State
- struct
- {
- uint8_t dl:1; // Dirty lower
- uint8_t du:1; // Dirty upper
- uint8_t fef:1; // FPRS enable floating-Point
- } fprsFields;
- };
-
- public:
- MiscReg readReg(int misc_reg);
-
- MiscReg readRegWithEffect(int misc_reg, Fault &fault, ExecContext *xc);
-
- Fault setReg(int misc_reg, const MiscReg &val);
-
- Fault setRegWithEffect(int misc_reg, const MiscReg &val,
- ExecContext *xc);
-
- void serialize(std::ostream & os);
-
- void unserialize(Checkpoint * cp, std::string & section);
- };
-
- typedef union
- {
- float32_t singReg;
- float64_t doubReg;
- float128_t quadReg;
- } FloatReg;
-
- typedef union
- {
- IntReg intreg;
- FloatReg fpreg;
- MiscReg ctrlreg;
- } AnyReg;
-
- struct RegFile
- {
- IntRegFile intRegFile; // (signed) integer register file
- FloatRegFile floatRegFile; // floating point register file
- MiscRegFile miscRegFile; // control register file
-
- Addr pc; // Program Counter
- Addr npc; // Next Program Counter
- Addr nnpc;
-
- void serialize(std::ostream &os);
- void unserialize(Checkpoint *cp, const std::string &section);
- };
-
- StaticInstPtr decodeInst(MachInst);
+ StaticInstPtr decodeInst(ExtMachInst);
// return a no-op instruction... used for instruction fetch faults
extern const MachInst NoopMachInst;
@@ -463,65 +184,32 @@ namespace SparcISA
* @param xc The execution context.
*/
template <class XC>
+ void zeroRegisters(XC *xc);
+}
+
+#include "arch/sparc/regfile.hh"
+
+namespace SparcISA
+{
- static inline setSyscallReturn(SyscallReturn return_value, RegFile *regs)
+#if !FULL_SYSTEM
+ static inline void setSyscallReturn(SyscallReturn return_value,
+ RegFile *regs)
{
// check for error condition. SPARC syscall convention is to
// indicate success/failure in reg the carry bit of the ccr
// and put the return value itself in the standard return value reg ().
if (return_value.successful()) {
// no error
- regs->miscRegFile.ccrFields.iccFields.c = 0;
+ regs->miscRegs.setReg(MISCREG_CCR_ICC_C, 0);
regs->intRegFile[ReturnValueReg] = return_value.value();
} else {
// got an error, return details
- regs->miscRegFile.ccrFields.iccFields.c = 1;
+ regs->miscRegs.setReg(MISCREG_CCR_ICC_C, 1);
regs->intRegFile[ReturnValueReg] = -return_value.value();
}
}
-};
-
-#if !FULL_SYSTEM
-class SyscallReturn
-{
- public:
- template <class T>
- SyscallReturn(T v, bool s)
- {
- retval = (uint64_t)v;
- success = s;
- }
-
- template <class T>
- SyscallReturn(T v)
- {
- success = (v >= 0);
- retval = (uint64_t)v;
- }
-
- ~SyscallReturn() {}
-
- SyscallReturn& operator=(const SyscallReturn& s)
- {
- retval = s.retval;
- success = s.success;
- return *this;
- }
-
- bool successful() { return success; }
- uint64_t value() { return retval; }
-
- private:
- uint64_t retval;
- bool success;
-};
-
-#endif
-
-
-#if FULL_SYSTEM
-
-#include "arch/alpha/ev5.hh"
#endif
+};
#endif // __ARCH_SPARC_ISA_TRAITS_HH__
diff --git a/arch/sparc/linux/process.cc b/arch/sparc/linux/process.cc
index fa2a7b9f5..cb056eadc 100644
--- a/arch/sparc/linux/process.cc
+++ b/arch/sparc/linux/process.cc
@@ -26,14 +26,12 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include "arch/sparc/common_syscall_emul.hh"
#include "arch/sparc/linux/process.hh"
#include "arch/sparc/isa_traits.hh"
#include "base/trace.hh"
#include "cpu/exec_context.hh"
#include "kern/linux/linux.hh"
-#include "mem/functional/functional.hh"
#include "sim/process.hh"
#include "sim/syscall_emul.hh"
@@ -55,318 +53,318 @@ unameFunc(SyscallDesc *desc, int callnum, Process *process,
strcpy(name->version, "#1 Mon Aug 18 11:32:15 EDT 2003");
strcpy(name->machine, "sparc");
- name.copyOut(xc->mem);
+ name.copyOut(xc->getMemPort());
return 0;
}
SyscallDesc SparcLinuxProcess::syscallDescs[] = {
- /* 0 */ SyscallDesc("restart_syscall", unimplementedFunc);
- /* 1 */ SyscallDesc("exit", exitFunc);
- /* 2 */ SyscallDesc("fork", unimplementedFunc);
- /* 3 */ SyscallDesc("read", readFunc);
- /* 4 */ SyscallDesc("write", writeFunc);
- /* 5 */ SyscallDesc("open", openFunc<Linux>);
- /* 6 */ SyscallDesc("close", closeFinc);
- /* 7 */ SyscallDesc("wait4", unimplementedFunc);
- /* 8 */ SyscallDesc("creat", unimplementedFunc);
- /* 9 */ SyscallDesc("link", unimplementedFunc);
- /* 10 */ SyscallDesc("unlink", unlinkFunc);
- /* 11 */ SyscallDesc("execv", unimplementedFunc);
- /* 12 */ SyscallDesc("chdir", unimplementedFunc);
- /* 13 */ SyscallDesc("chown", chownFunc);
- /* 14 */ SyscallDesc("mknod", unimplementedFunc);
- /* 15 */ SyscallDesc("chmod", chmodFunc<Linux>);
- /* 16 */ SyscallDesc("lchown", unimplementedFunc);
- /* 17 */ SyscallDesc("brk", obreakFunc);
- /* 18 */ SyscallDesc("perfctr", unimplementedFunc);
- /* 19 */ SyscallDesc("lseek", lseekFunc);
- /* 20 */ SyscallDesc("getpid", getpidFunc);
- /* 21 */ SyscallDesc("capget", unimplementedFunc);
- /* 22 */ SyscallDesc("capset", unimplementedFunc);
- /* 23 */ SyscallDesc("setuid", setuidFunc);
- /* 24 */ SyscallDesc("getuid", getuidFunc);
- /* 25 */ SyscallDesc("time", unimplementedFunc);
- /* 26 */ SyscallDesc("ptrace", unimplementedFunc);
- /* 27 */ SyscallDesc("alarm", unimplementedFunc);
- /* 28 */ SyscallDesc("sigaltstack", unimplementedFunc);
- /* 29 */ SyscallDesc("pause", unimplementedFunc);
- /* 30 */ SyscallDesc("utime", unimplementedFunc);
- /* 31 */ SyscallDesc("lchown32", unimplementedFunc);
- /* 32 */ SyscallDesc("fchown32", unimplementedFunc);
- /* 33 */ SyscallDesc("access", unimplementedFunc);
- /* 34 */ SyscallDesc("nice", unimplementedFunc);
- /* 35 */ SyscallDesc("chown32", unimplementedFunc);
- /* 36 */ SyscallDesc("sync", unimplementedFunc);
- /* 37 */ SyscallDesc("kill", unimplementedFunc);
- /* 38 */ SyscallDesc("stat", unimplementedFunc);
- /* 39 */ SyscallDesc("sendfile", unimplementedFunc);
- /* 40 */ SyscallDesc("lstat", unimplementedFunc);
- /* 41 */ SyscallDesc("dup", unimplementedFunc);
- /* 42 */ SyscallDesc("pipe", pipePseudoFunc);
- /* 43 */ SyscallDesc("times", unimplementedFunc);
- /* 44 */ SyscallDesc("getuid32", unimplementedFunc);
- /* 45 */ SyscallDesc("umount2", unimplementedFunc);
- /* 46 */ SyscallDesc("setgid", unimplementedFunc);
- /* 47 */ SyscallDesc("getgid", getgidFunc);
- /* 48 */ SyscallDesc("signal", unimplementedFunc);
- /* 49 */ SyscallDesc("geteuid", geteuidFunc);
- /* 50 */ SyscallDesc("getegid", getegidFunc);
- /* 51 */ SyscallDesc("acct", unimplementedFunc);
- /* 52 */ SyscallDesc("memory_ordering", unimplementedFunc);
- /* 53 */ SyscallDesc("getgid32", unimplementedFunc);
- /* 54 */ SyscallDesc("ioctl", unimplementedFunc);
- /* 55 */ SyscallDesc("reboot", unimplementedFunc);
- /* 56 */ SyscallDesc("mmap2", unimplementedFunc);
- /* 57 */ SyscallDesc("symlink", unimplementedFunc);
- /* 58 */ SyscallDesc("readlink", unimplementedFunc);
- /* 59 */ SyscallDesc("execve", unimplementedFunc);
- /* 60 */ SyscallDesc("umask", unimplementedFunc);
- /* 61 */ SyscallDesc("chroot", unimplementedFunc);
- /* 62 */ SyscallDesc("fstat", unimplementedFunc);
- /* 63 */ SyscallDesc("fstat64", unimplementedFunc);
- /* 64 */ SyscallDesc("getpagesize", unimplementedFunc);
- /* 65 */ SyscallDesc("msync", unimplementedFunc);
- /* 66 */ SyscallDesc("vfork", unimplementedFunc);
- /* 67 */ SyscallDesc("pread64", unimplementedFunc);
- /* 68 */ SyscallDesc("pwrite64", unimplementedFunc);
- /* 69 */ SyscallDesc("geteuid32", unimplementedFunc);
- /* 70 */ SyscallDesc("getdgid32", unimplementedFunc);
- /* 71 */ SyscallDesc("mmap", unimplementedFunc);
- /* 72 */ SyscallDesc("setreuid32", unimplementedFunc);
- /* 73 */ SyscallDesc("munmap", unimplementedFunc);
- /* 74 */ SyscallDesc("mprotect", unimplementedFunc);
- /* 75 */ SyscallDesc("madvise", unimplementedFunc);
- /* 76 */ SyscallDesc("vhangup", unimplementedFunc);
- /* 77 */ SyscallDesc("truncate64", unimplementedFunc);
- /* 78 */ SyscallDesc("mincore", unimplementedFunc);
- /* 79 */ SyscallDesc("getgroups", unimplementedFunc);
- /* 80 */ SyscallDesc("setgroups", unimplementedFunc);
- /* 81 */ SyscallDesc("getpgrp", unimplementedFunc);
- /* 82 */ SyscallDesc("setgroups32", unimplementedFunc);
- /* 83 */ SyscallDesc("setitimer", unimplementedFunc);
- /* 84 */ SyscallDesc("ftruncate64", unimplementedFunc);
- /* 85 */ SyscallDesc("swapon", unimplementedFunc);
- /* 86 */ SyscallDesc("getitimer", unimplementedFunc);
- /* 87 */ SyscallDesc("setuid32", unimplementedFunc);
- /* 88 */ SyscallDesc("sethostname", unimplementedFunc);
- /* 89 */ SyscallDesc("setgid32", unimplementedFunc);
- /* 90 */ SyscallDesc("dup2", unimplementedFunc);
- /* 91 */ SyscallDesc("setfsuid32", unimplementedFunc);
- /* 92 */ SyscallDesc("fcntl", unimplementedFunc);
- /* 93 */ SyscallDesc("select", unimplementedFunc);
- /* 94 */ SyscallDesc("setfsgid32", unimplementedFunc);
- /* 95 */ SyscallDesc("fsync", unimplementedFunc);
- /* 96 */ SyscallDesc("setpriority", unimplementedFunc);
- /* 97 */ SyscallDesc("socket", unimplementedFunc);
- /* 98 */ SyscallDesc("connect", unimplementedFunc);
- /* 99 */ SyscallDesc("accept", unimplementedFunc);
- /* 100 */ SyscallDesc("getpriority", unimplementedFunc);
- /* 101 */ SyscallDesc("rt_sigreturn", unimplementedFunc);
- /* 102 */ SyscallDesc("rt_sigaction", unimplementedFunc);
- /* 103 */ SyscallDesc("rt_sigprocmask", unimplementedFunc);
- /* 104 */ SyscallDesc("rt_sigpending", unimplementedFunc);
- /* 105 */ SyscallDesc("rt_sigtimedwait", unimplementedFunc);
- /* 106 */ SyscallDesc("rt_sigqueueinfo", unimplementedFunc);
- /* 107 */ SyscallDesc("rt_sigsuspend", unimplementedFunc);
- /* 108 */ SyscallDesc("setresuid", unimplementedFunc);
- /* 109 */ SyscallDesc("getresuid", unimplementedFunc);
- /* 110 */ SyscallDesc("setresgid", unimplementedFunc);
- /* 111 */ SyscallDesc("getresgid", unimplementedFunc);
- /* 112 */ SyscallDesc("setregid32", unimplementedFunc);
- /* 113 */ SyscallDesc("recvmsg", unimplementedFunc);
- /* 114 */ SyscallDesc("sendmsg", unimplementedFunc);
- /* 115 */ SyscallDesc("getgroups32", unimplementedFunc);
- /* 116 */ SyscallDesc("gettimeofday", unimplementedFunc);
- /* 117 */ SyscallDesc("getrusage", unimplementedFunc);
- /* 118 */ SyscallDesc("getsockopt", unimplementedFunc);
- /* 119 */ SyscallDesc("getcwd", unimplementedFunc);
- /* 120 */ SyscallDesc("readv", unimplementedFunc);
- /* 121 */ SyscallDesc("writev", unimplementedFunc);
- /* 122 */ SyscallDesc("settimeofday", unimplementedFunc);
- /* 123 */ SyscallDesc("fchown", unimplementedFunc);
- /* 124 */ SyscallDesc("fchmod", unimplementedFunc);
- /* 125 */ SyscallDesc("recvfrom", unimplementedFunc);
- /* 126 */ SyscallDesc("setreuid", unimplementedFunc);
- /* 127 */ SyscallDesc("setregid", unimplementedFunc);
- /* 128 */ SyscallDesc("rename", unimplementedFunc);
- /* 129 */ SyscallDesc("truncate", unimplementedFunc);
- /* 130 */ SyscallDesc("ftruncate", unimplementedFunc);
- /* 131 */ SyscallDesc("flock", unimplementedFunc);
- /* 132 */ SyscallDesc("lstat64", unimplementedFunc);
- /* 133 */ SyscallDesc("sendto", unimplementedFunc);
- /* 134 */ SyscallDesc("shutdown", unimplementedFunc);
- /* 135 */ SyscallDesc("socketpair", unimplementedFunc);
- /* 136 */ SyscallDesc("mkdir", unimplementedFunc);
- /* 137 */ SyscallDesc("rmdir", unimplementedFunc);
- /* 138 */ SyscallDesc("utimes", unimplementedFunc);
- /* 139 */ SyscallDesc("stat64", unimplementedFunc);
- /* 140 */ SyscallDesc("sendfile64", unimplementedFunc);
- /* 141 */ SyscallDesc("getpeername", unimplementedFunc);
- /* 142 */ SyscallDesc("futex", unimplementedFunc);
- /* 143 */ SyscallDesc("gettid", unimplementedFunc);
- /* 144 */ SyscallDesc("getrlimit", unimplementedFunc);
- /* 145 */ SyscallDesc("setrlimit", unimplementedFunc);
- /* 146 */ SyscallDesc("pivot_root", unimplementedFunc);
- /* 147 */ SyscallDesc("prctl", unimplementedFunc);
- /* 148 */ SyscallDesc("pciconfig_read", unimplementedFunc);
- /* 149 */ SyscallDesc("pciconfig_write", unimplementedFunc);
- /* 150 */ SyscallDesc("getsockname", unimplementedFunc);
- /* 151 */ SyscallDesc("inotify_init", unimplementedFunc);
- /* 152 */ SyscallDesc("inotify_add_watch", unimplementedFunc);
- /* 153 */ SyscallDesc("poll", unimplementedFunc);
- /* 154 */ SyscallDesc("getdents64", unimplementedFunc);
- /* 155 */ SyscallDesc("fcntl64", unimplementedFunc);
- /* 156 */ SyscallDesc("inotify_rm_watch", unimplementedFunc);
- /* 157 */ SyscallDesc("statfs", unimplementedFunc);
- /* 158 */ SyscallDesc("fstatfs", unimplementedFunc);
- /* 159 */ SyscallDesc("umount", unimplementedFunc);
- /* 160 */ SyscallDesc("sched_set_affinity", unimplementedFunc);
- /* 161 */ SyscallDesc("sched_get_affinity", unimplementedFunc);
- /* 162 */ SyscallDesc("getdomainname", unimplementedFunc);
- /* 163 */ SyscallDesc("setdomainname", unimplementedFunc);
- /* 164 */ SyscallDesc("utrap_install", unimplementedFunc);
- /* 165 */ SyscallDesc("quotactl", unimplementedFunc);
- /* 166 */ SyscallDesc("set_tid_address", unimplementedFunc);
- /* 167 */ SyscallDesc("mount", unimplementedFunc);
- /* 168 */ SyscallDesc("ustat", unimplementedFunc);
- /* 169 */ SyscallDesc("setxattr", unimplementedFunc);
- /* 170 */ SyscallDesc("lsetxattr", unimplementedFunc);
- /* 171 */ SyscallDesc("fsetxattr", unimplementedFunc);
- /* 172 */ SyscallDesc("getxattr", unimplementedFunc);
- /* 173 */ SyscallDesc("lgetxattr", unimplementedFunc);
- /* 174 */ SyscallDesc("getdents", unimplementedFunc);
- /* 175 */ SyscallDesc("setsid", unimplementedFunc);
- /* 176 */ SyscallDesc("fchdir", unimplementedFunc);
- /* 177 */ SyscallDesc("fgetxattr", unimplementedFunc);
- /* 178 */ SyscallDesc("listxattr", unimplementedFunc);
- /* 179 */ SyscallDesc("llistxattr", unimplementedFunc);
- /* 180 */ SyscallDesc("flistxattr", unimplementedFunc);
- /* 181 */ SyscallDesc("removexattr", unimplementedFunc);
- /* 182 */ SyscallDesc("lremovexattr", unimplementedFunc);
- /* 183 */ SyscallDesc("sigpending", unimplementedFunc);
- /* 184 */ SyscallDesc("query_module", unimplementedFunc);
- /* 185 */ SyscallDesc("setpgid", unimplementedFunc);
- /* 186 */ SyscallDesc("fremovexattr", unimplementedFunc);
- /* 187 */ SyscallDesc("tkill", unimplementedFunc);
- /* 188 */ SyscallDesc("exit_group", unimplementedFunc);
- /* 189 */ SyscallDesc("uname", unameFunc);
- /* 190 */ SyscallDesc("init_module", unimplementedFunc);
- /* 191 */ SyscallDesc("personality", unimplementedFunc);
- /* 192 */ SyscallDesc("remap_file_pages", unimplementedFunc);
- /* 193 */ SyscallDesc("epoll_create", unimplementedFunc);
- /* 194 */ SyscallDesc("epoll_ctl", unimplementedFunc);
- /* 195 */ SyscallDesc("epoll_wait", unimplementedFunc);
- /* 196 */ SyscallDesc("ioprio_set", unimplementedFunc);
- /* 197 */ SyscallDesc("getppid", getppidFunc);
- /* 198 */ SyscallDesc("sigaction", unimplementedFunc);
- /* 199 */ SyscallDesc("sgetmask", unimplementedFunc);
- /* 200 */ SyscallDesc("ssetmask", unimplementedFunc);
- /* 201 */ SyscallDesc("sigsuspend", unimplementedFunc);
- /* 202 */ SyscallDesc("oldlstat", unimplementedFunc);
- /* 203 */ SyscallDesc("uselib", unimplementedFunc);
- /* 204 */ SyscallDesc("readdir", unimplementedFunc);
- /* 205 */ SyscallDesc("readahead", unimplementedFunc);
- /* 206 */ SyscallDesc("socketcall", unimplementedFunc);
- /* 207 */ SyscallDesc("syslog", unimplementedFunc);
- /* 208 */ SyscallDesc("lookup_dcookie", unimplementedFunc);
- /* 209 */ SyscallDesc("fadvise64", unimplementedFunc);
- /* 210 */ SyscallDesc("fadvise64_64", unimplementedFunc);
- /* 211 */ SyscallDesc("tgkill", unimplementedFunc);
- /* 212 */ SyscallDesc("waitpid", unimplementedFunc);
- /* 213 */ SyscallDesc("swapoff", unimplementedFunc);
- /* 214 */ SyscallDesc("sysinfo", unimplementedFunc);
- /* 215 */ SyscallDesc("ipc", unimplementedFunc);
- /* 216 */ SyscallDesc("sigreturn", unimplementedFunc);
- /* 217 */ SyscallDesc("clone", unimplementedFunc);
- /* 218 */ SyscallDesc("ioprio_get", unimplementedFunc);
- /* 219 */ SyscallDesc("adjtimex", unimplementedFunc);
- /* 220 */ SyscallDesc("sigprocmask", unimplementedFunc);
- /* 221 */ SyscallDesc("create_module", unimplementedFunc);
- /* 222 */ SyscallDesc("delete_module", unimplementedFunc);
- /* 223 */ SyscallDesc("get_kernel_syms", unimplementedFunc);
- /* 224 */ SyscallDesc("getpgid", unimplementedFunc);
- /* 225 */ SyscallDesc("bdflush", unimplementedFunc);
- /* 226 */ SyscallDesc("sysfs", unimplementedFunc);
- /* 227 */ SyscallDesc("afs_syscall", unimplementedFunc);
- /* 228 */ SyscallDesc("setfsuid", unimplementedFunc);
- /* 229 */ SyscallDesc("setfsgid", unimplementedFunc);
- /* 230 */ SyscallDesc("_newselect", unimplementedFunc);
- /* 231 */ SyscallDesc("time", unimplementedFunc);
- /* 232 */ SyscallDesc("oldstat", unimplementedFunc);
- /* 233 */ SyscallDesc("stime", unimplementedFunc);
- /* 234 */ SyscallDesc("statfs64", unimplementedFunc);
- /* 235 */ SyscallDesc("fstatfs64", unimplementedFunc);
- /* 236 */ SyscallDesc("_llseek", unimplementedFunc);
- /* 237 */ SyscallDesc("mlock", unimplementedFunc);
- /* 238 */ SyscallDesc("munlock", unimplementedFunc);
- /* 239 */ SyscallDesc("mlockall", unimplementedFunc);
- /* 240 */ SyscallDesc("munlockall", unimplementedFunc);
- /* 241 */ SyscallDesc("sched_setparam", unimplementedFunc);
- /* 242 */ SyscallDesc("sched_getparam", unimplementedFunc);
- /* 243 */ SyscallDesc("sched_setscheduler", unimplementedFunc);
- /* 244 */ SyscallDesc("sched_getscheduler", unimplementedFunc);
- /* 245 */ SyscallDesc("sched_yield", unimplementedFunc);
- /* 246 */ SyscallDesc("sched_get_priority_max", unimplimented);
- /* 247 */ SyscallDesc("sched_get_priority_min", unimplimented);
- /* 248 */ SyscallDesc("sched_rr_get_interval", unimplimented);
- /* 249 */ SyscallDesc("nanosleep", unimplementedFunc);
- /* 250 */ SyscallDesc("mremap", unimplementedFunc);
- /* 251 */ SyscallDesc("_sysctl", unimplementedFunc);
- /* 252 */ SyscallDesc("getsid", unimplementedFunc);
- /* 253 */ SyscallDesc("fdatasync", unimplementedFunc);
- /* 254 */ SyscallDesc("nfsservctl", unimplementedFunc);
- /* 255 */ SyscallDesc("aplib", unimplementedFunc);
- /* 256 */ SyscallDesc("clock_settime", unimplementedFunc);
- /* 257 */ SyscallDesc("clock_gettime", unimplementedFunc);
- /* 258 */ SyscallDesc("clock_getres", unimplementedFunc);
- /* 259 */ SyscallDesc("clock_nanosleep", unimplementedFunc);
- /* 260 */ SyscallDesc("sched_getaffinity", unimplementedFunc);
- /* 261 */ SyscallDesc("sched_setaffinity", unimplementedFunc);
- /* 262 */ SyscallDesc("timer_settime", unimplementedFunc);
- /* 263 */ SyscallDesc("timer_gettime", unimplementedFunc);
- /* 264 */ SyscallDesc("timer_getoverrun", unimplementedFunc);
- /* 265 */ SyscallDesc("timer_delete", unimplementedFunc);
- /* 266 */ SyscallDesc("timer_create", unimplementedFunc);
- /* 267 */ SyscallDesc("vserver", unimplementedFunc);
- /* 268 */ SyscallDesc("io_setup", unimplementedFunc);
- /* 269 */ SyscallDesc("io_destroy", unimplementedFunc);
- /* 270 */ SyscallDesc("io_submit", unimplementedFunc);
- /* 271 */ SyscallDesc("io_cancel", unimplementedFunc);
- /* 272 */ SyscallDesc("io_getevents", unimplementedFunc);
- /* 273 */ SyscallDesc("mq_open", unimplementedFunc);
- /* 274 */ SyscallDesc("mq_unlink", unimplementedFunc);
- /* 275 */ SyscallDesc("mq_timedsend", unimplementedFunc);
- /* 276 */ SyscallDesc("mq_timedreceive", unimplementedFunc);
- /* 277 */ SyscallDesc("mq_notify", unimplementedFunc);
- /* 278 */ SyscallDesc("mq_getsetattr", unimplementedFunc);
- /* 279 */ SyscallDesc("waitid", unimplementedFunc);
- /* 280 */ SyscallDesc("sys_setaltroot", unimplementedFunc);
- /* 281 */ SyscallDesc("add_key", unimplementedFunc);
- /* 282 */ SyscallDesc("request_key", unimplementedFunc);
- /* 283 */ SyscallDesc("keyctl", unimplementedFunc);
+ /* 0 */ SyscallDesc("restart_syscall", unimplementedFunc),
+ /* 1 */ SyscallDesc("exit", exitFunc),
+ /* 2 */ SyscallDesc("fork", unimplementedFunc),
+ /* 3 */ SyscallDesc("read", readFunc),
+ /* 4 */ SyscallDesc("write", writeFunc),
+ /* 5 */ SyscallDesc("open", openFunc<Linux>),
+ /* 6 */ SyscallDesc("close", closeFunc),
+ /* 7 */ SyscallDesc("wait4", unimplementedFunc),
+ /* 8 */ SyscallDesc("creat", unimplementedFunc),
+ /* 9 */ SyscallDesc("link", unimplementedFunc),
+ /* 10 */ SyscallDesc("unlink", unlinkFunc),
+ /* 11 */ SyscallDesc("execv", unimplementedFunc),
+ /* 12 */ SyscallDesc("chdir", unimplementedFunc),
+ /* 13 */ SyscallDesc("chown", chownFunc),
+ /* 14 */ SyscallDesc("mknod", unimplementedFunc),
+ /* 15 */ SyscallDesc("chmod", chmodFunc<Linux>),
+ /* 16 */ SyscallDesc("lchown", unimplementedFunc),
+ /* 17 */ SyscallDesc("brk", obreakFunc),
+ /* 18 */ SyscallDesc("perfctr", unimplementedFunc),
+ /* 19 */ SyscallDesc("lseek", lseekFunc),
+ /* 20 */ SyscallDesc("getpid", getpidFunc),
+ /* 21 */ SyscallDesc("capget", unimplementedFunc),
+ /* 22 */ SyscallDesc("capset", unimplementedFunc),
+ /* 23 */ SyscallDesc("setuid", setuidFunc),
+ /* 24 */ SyscallDesc("getuid", getuidFunc),
+ /* 25 */ SyscallDesc("time", unimplementedFunc),
+ /* 26 */ SyscallDesc("ptrace", unimplementedFunc),
+ /* 27 */ SyscallDesc("alarm", unimplementedFunc),
+ /* 28 */ SyscallDesc("sigaltstack", unimplementedFunc),
+ /* 29 */ SyscallDesc("pause", unimplementedFunc),
+ /* 30 */ SyscallDesc("utime", unimplementedFunc),
+ /* 31 */ SyscallDesc("lchown32", unimplementedFunc),
+ /* 32 */ SyscallDesc("fchown32", unimplementedFunc),
+ /* 33 */ SyscallDesc("access", unimplementedFunc),
+ /* 34 */ SyscallDesc("nice", unimplementedFunc),
+ /* 35 */ SyscallDesc("chown32", unimplementedFunc),
+ /* 36 */ SyscallDesc("sync", unimplementedFunc),
+ /* 37 */ SyscallDesc("kill", unimplementedFunc),
+ /* 38 */ SyscallDesc("stat", unimplementedFunc),
+ /* 39 */ SyscallDesc("sendfile", unimplementedFunc),
+ /* 40 */ SyscallDesc("lstat", unimplementedFunc),
+ /* 41 */ SyscallDesc("dup", unimplementedFunc),
+ /* 42 */ SyscallDesc("pipe", pipePseudoFunc),
+ /* 43 */ SyscallDesc("times", unimplementedFunc),
+ /* 44 */ SyscallDesc("getuid32", unimplementedFunc),
+ /* 45 */ SyscallDesc("umount2", unimplementedFunc),
+ /* 46 */ SyscallDesc("setgid", unimplementedFunc),
+ /* 47 */ SyscallDesc("getgid", getgidFunc),
+ /* 48 */ SyscallDesc("signal", unimplementedFunc),
+ /* 49 */ SyscallDesc("geteuid", geteuidFunc),
+ /* 50 */ SyscallDesc("getegid", getegidFunc),
+ /* 51 */ SyscallDesc("acct", unimplementedFunc),
+ /* 52 */ SyscallDesc("memory_ordering", unimplementedFunc),
+ /* 53 */ SyscallDesc("getgid32", unimplementedFunc),
+ /* 54 */ SyscallDesc("ioctl", unimplementedFunc),
+ /* 55 */ SyscallDesc("reboot", unimplementedFunc),
+ /* 56 */ SyscallDesc("mmap2", unimplementedFunc),
+ /* 57 */ SyscallDesc("symlink", unimplementedFunc),
+ /* 58 */ SyscallDesc("readlink", unimplementedFunc),
+ /* 59 */ SyscallDesc("execve", unimplementedFunc),
+ /* 60 */ SyscallDesc("umask", unimplementedFunc),
+ /* 61 */ SyscallDesc("chroot", unimplementedFunc),
+ /* 62 */ SyscallDesc("fstat", unimplementedFunc),
+ /* 63 */ SyscallDesc("fstat64", unimplementedFunc),
+ /* 64 */ SyscallDesc("getpagesize", unimplementedFunc),
+ /* 65 */ SyscallDesc("msync", unimplementedFunc),
+ /* 66 */ SyscallDesc("vfork", unimplementedFunc),
+ /* 67 */ SyscallDesc("pread64", unimplementedFunc),
+ /* 68 */ SyscallDesc("pwrite64", unimplementedFunc),
+ /* 69 */ SyscallDesc("geteuid32", unimplementedFunc),
+ /* 70 */ SyscallDesc("getdgid32", unimplementedFunc),
+ /* 71 */ SyscallDesc("mmap", unimplementedFunc),
+ /* 72 */ SyscallDesc("setreuid32", unimplementedFunc),
+ /* 73 */ SyscallDesc("munmap", unimplementedFunc),
+ /* 74 */ SyscallDesc("mprotect", unimplementedFunc),
+ /* 75 */ SyscallDesc("madvise", unimplementedFunc),
+ /* 76 */ SyscallDesc("vhangup", unimplementedFunc),
+ /* 77 */ SyscallDesc("truncate64", unimplementedFunc),
+ /* 78 */ SyscallDesc("mincore", unimplementedFunc),
+ /* 79 */ SyscallDesc("getgroups", unimplementedFunc),
+ /* 80 */ SyscallDesc("setgroups", unimplementedFunc),
+ /* 81 */ SyscallDesc("getpgrp", unimplementedFunc),
+ /* 82 */ SyscallDesc("setgroups32", unimplementedFunc),
+ /* 83 */ SyscallDesc("setitimer", unimplementedFunc),
+ /* 84 */ SyscallDesc("ftruncate64", unimplementedFunc),
+ /* 85 */ SyscallDesc("swapon", unimplementedFunc),
+ /* 86 */ SyscallDesc("getitimer", unimplementedFunc),
+ /* 87 */ SyscallDesc("setuid32", unimplementedFunc),
+ /* 88 */ SyscallDesc("sethostname", unimplementedFunc),
+ /* 89 */ SyscallDesc("setgid32", unimplementedFunc),
+ /* 90 */ SyscallDesc("dup2", unimplementedFunc),
+ /* 91 */ SyscallDesc("setfsuid32", unimplementedFunc),
+ /* 92 */ SyscallDesc("fcntl", unimplementedFunc),
+ /* 93 */ SyscallDesc("select", unimplementedFunc),
+ /* 94 */ SyscallDesc("setfsgid32", unimplementedFunc),
+ /* 95 */ SyscallDesc("fsync", unimplementedFunc),
+ /* 96 */ SyscallDesc("setpriority", unimplementedFunc),
+ /* 97 */ SyscallDesc("socket", unimplementedFunc),
+ /* 98 */ SyscallDesc("connect", unimplementedFunc),
+ /* 99 */ SyscallDesc("accept", unimplementedFunc),
+ /* 100 */ SyscallDesc("getpriority", unimplementedFunc),
+ /* 101 */ SyscallDesc("rt_sigreturn", unimplementedFunc),
+ /* 102 */ SyscallDesc("rt_sigaction", unimplementedFunc),
+ /* 103 */ SyscallDesc("rt_sigprocmask", unimplementedFunc),
+ /* 104 */ SyscallDesc("rt_sigpending", unimplementedFunc),
+ /* 105 */ SyscallDesc("rt_sigtimedwait", unimplementedFunc),
+ /* 106 */ SyscallDesc("rt_sigqueueinfo", unimplementedFunc),
+ /* 107 */ SyscallDesc("rt_sigsuspend", unimplementedFunc),
+ /* 108 */ SyscallDesc("setresuid", unimplementedFunc),
+ /* 109 */ SyscallDesc("getresuid", unimplementedFunc),
+ /* 110 */ SyscallDesc("setresgid", unimplementedFunc),
+ /* 111 */ SyscallDesc("getresgid", unimplementedFunc),
+ /* 112 */ SyscallDesc("setregid32", unimplementedFunc),
+ /* 113 */ SyscallDesc("recvmsg", unimplementedFunc),
+ /* 114 */ SyscallDesc("sendmsg", unimplementedFunc),
+ /* 115 */ SyscallDesc("getgroups32", unimplementedFunc),
+ /* 116 */ SyscallDesc("gettimeofday", unimplementedFunc),
+ /* 117 */ SyscallDesc("getrusage", unimplementedFunc),
+ /* 118 */ SyscallDesc("getsockopt", unimplementedFunc),
+ /* 119 */ SyscallDesc("getcwd", unimplementedFunc),
+ /* 120 */ SyscallDesc("readv", unimplementedFunc),
+ /* 121 */ SyscallDesc("writev", unimplementedFunc),
+ /* 122 */ SyscallDesc("settimeofday", unimplementedFunc),
+ /* 123 */ SyscallDesc("fchown", unimplementedFunc),
+ /* 124 */ SyscallDesc("fchmod", unimplementedFunc),
+ /* 125 */ SyscallDesc("recvfrom", unimplementedFunc),
+ /* 126 */ SyscallDesc("setreuid", unimplementedFunc),
+ /* 127 */ SyscallDesc("setregid", unimplementedFunc),
+ /* 128 */ SyscallDesc("rename", unimplementedFunc),
+ /* 129 */ SyscallDesc("truncate", unimplementedFunc),
+ /* 130 */ SyscallDesc("ftruncate", unimplementedFunc),
+ /* 131 */ SyscallDesc("flock", unimplementedFunc),
+ /* 132 */ SyscallDesc("lstat64", unimplementedFunc),
+ /* 133 */ SyscallDesc("sendto", unimplementedFunc),
+ /* 134 */ SyscallDesc("shutdown", unimplementedFunc),
+ /* 135 */ SyscallDesc("socketpair", unimplementedFunc),
+ /* 136 */ SyscallDesc("mkdir", unimplementedFunc),
+ /* 137 */ SyscallDesc("rmdir", unimplementedFunc),
+ /* 138 */ SyscallDesc("utimes", unimplementedFunc),
+ /* 139 */ SyscallDesc("stat64", unimplementedFunc),
+ /* 140 */ SyscallDesc("sendfile64", unimplementedFunc),
+ /* 141 */ SyscallDesc("getpeername", unimplementedFunc),
+ /* 142 */ SyscallDesc("futex", unimplementedFunc),
+ /* 143 */ SyscallDesc("gettid", unimplementedFunc),
+ /* 144 */ SyscallDesc("getrlimit", unimplementedFunc),
+ /* 145 */ SyscallDesc("setrlimit", unimplementedFunc),
+ /* 146 */ SyscallDesc("pivot_root", unimplementedFunc),
+ /* 147 */ SyscallDesc("prctl", unimplementedFunc),
+ /* 148 */ SyscallDesc("pciconfig_read", unimplementedFunc),
+ /* 149 */ SyscallDesc("pciconfig_write", unimplementedFunc),
+ /* 150 */ SyscallDesc("getsockname", unimplementedFunc),
+ /* 151 */ SyscallDesc("inotify_init", unimplementedFunc),
+ /* 152 */ SyscallDesc("inotify_add_watch", unimplementedFunc),
+ /* 153 */ SyscallDesc("poll", unimplementedFunc),
+ /* 154 */ SyscallDesc("getdents64", unimplementedFunc),
+ /* 155 */ SyscallDesc("fcntl64", unimplementedFunc),
+ /* 156 */ SyscallDesc("inotify_rm_watch", unimplementedFunc),
+ /* 157 */ SyscallDesc("statfs", unimplementedFunc),
+ /* 158 */ SyscallDesc("fstatfs", unimplementedFunc),
+ /* 159 */ SyscallDesc("umount", unimplementedFunc),
+ /* 160 */ SyscallDesc("sched_set_affinity", unimplementedFunc),
+ /* 161 */ SyscallDesc("sched_get_affinity", unimplementedFunc),
+ /* 162 */ SyscallDesc("getdomainname", unimplementedFunc),
+ /* 163 */ SyscallDesc("setdomainname", unimplementedFunc),
+ /* 164 */ SyscallDesc("utrap_install", unimplementedFunc),
+ /* 165 */ SyscallDesc("quotactl", unimplementedFunc),
+ /* 166 */ SyscallDesc("set_tid_address", unimplementedFunc),
+ /* 167 */ SyscallDesc("mount", unimplementedFunc),
+ /* 168 */ SyscallDesc("ustat", unimplementedFunc),
+ /* 169 */ SyscallDesc("setxattr", unimplementedFunc),
+ /* 170 */ SyscallDesc("lsetxattr", unimplementedFunc),
+ /* 171 */ SyscallDesc("fsetxattr", unimplementedFunc),
+ /* 172 */ SyscallDesc("getxattr", unimplementedFunc),
+ /* 173 */ SyscallDesc("lgetxattr", unimplementedFunc),
+ /* 174 */ SyscallDesc("getdents", unimplementedFunc),
+ /* 175 */ SyscallDesc("setsid", unimplementedFunc),
+ /* 176 */ SyscallDesc("fchdir", unimplementedFunc),
+ /* 177 */ SyscallDesc("fgetxattr", unimplementedFunc),
+ /* 178 */ SyscallDesc("listxattr", unimplementedFunc),
+ /* 179 */ SyscallDesc("llistxattr", unimplementedFunc),
+ /* 180 */ SyscallDesc("flistxattr", unimplementedFunc),
+ /* 181 */ SyscallDesc("removexattr", unimplementedFunc),
+ /* 182 */ SyscallDesc("lremovexattr", unimplementedFunc),
+ /* 183 */ SyscallDesc("sigpending", unimplementedFunc),
+ /* 184 */ SyscallDesc("query_module", unimplementedFunc),
+ /* 185 */ SyscallDesc("setpgid", unimplementedFunc),
+ /* 186 */ SyscallDesc("fremovexattr", unimplementedFunc),
+ /* 187 */ SyscallDesc("tkill", unimplementedFunc),
+ /* 188 */ SyscallDesc("exit_group", unimplementedFunc),
+ /* 189 */ SyscallDesc("uname", unameFunc),
+ /* 190 */ SyscallDesc("init_module", unimplementedFunc),
+ /* 191 */ SyscallDesc("personality", unimplementedFunc),
+ /* 192 */ SyscallDesc("remap_file_pages", unimplementedFunc),
+ /* 193 */ SyscallDesc("epoll_create", unimplementedFunc),
+ /* 194 */ SyscallDesc("epoll_ctl", unimplementedFunc),
+ /* 195 */ SyscallDesc("epoll_wait", unimplementedFunc),
+ /* 196 */ SyscallDesc("ioprio_set", unimplementedFunc),
+ /* 197 */ SyscallDesc("getppid", getppidFunc),
+ /* 198 */ SyscallDesc("sigaction", unimplementedFunc),
+ /* 199 */ SyscallDesc("sgetmask", unimplementedFunc),
+ /* 200 */ SyscallDesc("ssetmask", unimplementedFunc),
+ /* 201 */ SyscallDesc("sigsuspend", unimplementedFunc),
+ /* 202 */ SyscallDesc("oldlstat", unimplementedFunc),
+ /* 203 */ SyscallDesc("uselib", unimplementedFunc),
+ /* 204 */ SyscallDesc("readdir", unimplementedFunc),
+ /* 205 */ SyscallDesc("readahead", unimplementedFunc),
+ /* 206 */ SyscallDesc("socketcall", unimplementedFunc),
+ /* 207 */ SyscallDesc("syslog", unimplementedFunc),
+ /* 208 */ SyscallDesc("lookup_dcookie", unimplementedFunc),
+ /* 209 */ SyscallDesc("fadvise64", unimplementedFunc),
+ /* 210 */ SyscallDesc("fadvise64_64", unimplementedFunc),
+ /* 211 */ SyscallDesc("tgkill", unimplementedFunc),
+ /* 212 */ SyscallDesc("waitpid", unimplementedFunc),
+ /* 213 */ SyscallDesc("swapoff", unimplementedFunc),
+ /* 214 */ SyscallDesc("sysinfo", unimplementedFunc),
+ /* 215 */ SyscallDesc("ipc", unimplementedFunc),
+ /* 216 */ SyscallDesc("sigreturn", unimplementedFunc),
+ /* 217 */ SyscallDesc("clone", unimplementedFunc),
+ /* 218 */ SyscallDesc("ioprio_get", unimplementedFunc),
+ /* 219 */ SyscallDesc("adjtimex", unimplementedFunc),
+ /* 220 */ SyscallDesc("sigprocmask", unimplementedFunc),
+ /* 221 */ SyscallDesc("create_module", unimplementedFunc),
+ /* 222 */ SyscallDesc("delete_module", unimplementedFunc),
+ /* 223 */ SyscallDesc("get_kernel_syms", unimplementedFunc),
+ /* 224 */ SyscallDesc("getpgid", unimplementedFunc),
+ /* 225 */ SyscallDesc("bdflush", unimplementedFunc),
+ /* 226 */ SyscallDesc("sysfs", unimplementedFunc),
+ /* 227 */ SyscallDesc("afs_syscall", unimplementedFunc),
+ /* 228 */ SyscallDesc("setfsuid", unimplementedFunc),
+ /* 229 */ SyscallDesc("setfsgid", unimplementedFunc),
+ /* 230 */ SyscallDesc("_newselect", unimplementedFunc),
+ /* 231 */ SyscallDesc("time", unimplementedFunc),
+ /* 232 */ SyscallDesc("oldstat", unimplementedFunc),
+ /* 233 */ SyscallDesc("stime", unimplementedFunc),
+ /* 234 */ SyscallDesc("statfs64", unimplementedFunc),
+ /* 235 */ SyscallDesc("fstatfs64", unimplementedFunc),
+ /* 236 */ SyscallDesc("_llseek", unimplementedFunc),
+ /* 237 */ SyscallDesc("mlock", unimplementedFunc),
+ /* 238 */ SyscallDesc("munlock", unimplementedFunc),
+ /* 239 */ SyscallDesc("mlockall", unimplementedFunc),
+ /* 240 */ SyscallDesc("munlockall", unimplementedFunc),
+ /* 241 */ SyscallDesc("sched_setparam", unimplementedFunc),
+ /* 242 */ SyscallDesc("sched_getparam", unimplementedFunc),
+ /* 243 */ SyscallDesc("sched_setscheduler", unimplementedFunc),
+ /* 244 */ SyscallDesc("sched_getscheduler", unimplementedFunc),
+ /* 245 */ SyscallDesc("sched_yield", unimplementedFunc),
+ /* 246 */ SyscallDesc("sched_get_priority_max", unimplementedFunc),
+ /* 247 */ SyscallDesc("sched_get_priority_min", unimplementedFunc),
+ /* 248 */ SyscallDesc("sched_rr_get_interval", unimplementedFunc),
+ /* 249 */ SyscallDesc("nanosleep", unimplementedFunc),
+ /* 250 */ SyscallDesc("mremap", unimplementedFunc),
+ /* 251 */ SyscallDesc("_sysctl", unimplementedFunc),
+ /* 252 */ SyscallDesc("getsid", unimplementedFunc),
+ /* 253 */ SyscallDesc("fdatasync", unimplementedFunc),
+ /* 254 */ SyscallDesc("nfsservctl", unimplementedFunc),
+ /* 255 */ SyscallDesc("aplib", unimplementedFunc),
+ /* 256 */ SyscallDesc("clock_settime", unimplementedFunc),
+ /* 257 */ SyscallDesc("clock_gettime", unimplementedFunc),
+ /* 258 */ SyscallDesc("clock_getres", unimplementedFunc),
+ /* 259 */ SyscallDesc("clock_nanosleep", unimplementedFunc),
+ /* 260 */ SyscallDesc("sched_getaffinity", unimplementedFunc),
+ /* 261 */ SyscallDesc("sched_setaffinity", unimplementedFunc),
+ /* 262 */ SyscallDesc("timer_settime", unimplementedFunc),
+ /* 263 */ SyscallDesc("timer_gettime", unimplementedFunc),
+ /* 264 */ SyscallDesc("timer_getoverrun", unimplementedFunc),
+ /* 265 */ SyscallDesc("timer_delete", unimplementedFunc),
+ /* 266 */ SyscallDesc("timer_create", unimplementedFunc),
+ /* 267 */ SyscallDesc("vserver", unimplementedFunc),
+ /* 268 */ SyscallDesc("io_setup", unimplementedFunc),
+ /* 269 */ SyscallDesc("io_destroy", unimplementedFunc),
+ /* 270 */ SyscallDesc("io_submit", unimplementedFunc),
+ /* 271 */ SyscallDesc("io_cancel", unimplementedFunc),
+ /* 272 */ SyscallDesc("io_getevents", unimplementedFunc),
+ /* 273 */ SyscallDesc("mq_open", unimplementedFunc),
+ /* 274 */ SyscallDesc("mq_unlink", unimplementedFunc),
+ /* 275 */ SyscallDesc("mq_timedsend", unimplementedFunc),
+ /* 276 */ SyscallDesc("mq_timedreceive", unimplementedFunc),
+ /* 277 */ SyscallDesc("mq_notify", unimplementedFunc),
+ /* 278 */ SyscallDesc("mq_getsetattr", unimplementedFunc),
+ /* 279 */ SyscallDesc("waitid", unimplementedFunc),
+ /* 280 */ SyscallDesc("sys_setaltroot", unimplementedFunc),
+ /* 281 */ SyscallDesc("add_key", unimplementedFunc),
+ /* 282 */ SyscallDesc("request_key", unimplementedFunc),
+ /* 283 */ SyscallDesc("keyctl", unimplementedFunc)
};
SparcLinuxProcess::SparcLinuxProcess(const std::string &name,
ObjectFile *objFile,
+ System * system,
int stdin_fd,
int stdout_fd,
int stderr_fd,
std::vector<std::string> &argv,
std::vector<std::string> &envp)
- : LiveProcess(name, objFile, stdin_fd, stdout_fd, stderr_fd, argv, envp),
+ : SparcLiveProcess(name, objFile, system,
+ stdin_fd, stdout_fd, stderr_fd, argv, envp),
Num_Syscall_Descs(sizeof(syscallDescs) / sizeof(SyscallDesc))
{
// The sparc syscall table must be <= 283 entries because that is all there
// is space for.
assert(Num_Syscall_Descs <= 283);
-
- init_regs->intRegFile[0] = 0;
}
SyscallDesc*
-AlphaLinuxProcess::getDesc(int callnum)
+SparcLinuxProcess::getDesc(int callnum)
{
if (callnum < 0 || callnum > Num_Syscall_Descs)
return NULL;
diff --git a/arch/sparc/linux/process.hh b/arch/sparc/linux/process.hh
index c41406b4b..1565ab549 100644
--- a/arch/sparc/linux/process.hh
+++ b/arch/sparc/linux/process.hh
@@ -29,16 +29,19 @@
#ifndef __SPARC_LINUX_PROCESS_HH__
#define __SPARC_LINUX_PROCESS_HH__
+#include "arch/sparc/process.hh"
#include "sim/process.hh"
+namespace SparcISA {
/// A process with emulated SPARC/Linux syscalls.
-class SparcLinuxProcess : public LiveProcess
+class SparcLinuxProcess : public SparcLiveProcess
{
public:
/// Constructor.
SparcLinuxProcess(const std::string &name,
ObjectFile *objFile,
+ System * system,
int stdin_fd, int stdout_fd, int stderr_fd,
std::vector<std::string> &argv,
std::vector<std::string> &envp);
@@ -54,5 +57,5 @@ class SparcLinuxProcess : public LiveProcess
const int Num_Syscall_Descs;
};
-
+} // namespace SparcISA
#endif // __ALPHA_LINUX_PROCESS_HH__
diff --git a/arch/sparc/process.cc b/arch/sparc/process.cc
index 53a215379..c7e08358d 100644
--- a/arch/sparc/process.cc
+++ b/arch/sparc/process.cc
@@ -26,22 +26,36 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include "arch/sparc/isa_traits.hh"
#include "arch/sparc/process.hh"
+#include "arch/sparc/linux/process.hh"
+#include "base/loader/object_file.hh"
+#include "base/misc.hh"
+#include "cpu/exec_context.hh"
+#include "sim/builder.hh"
+#include "sim/system.hh"
-namespace SparcISA
-{
+using namespace std;
+using namespace SparcISA;
-LiveProcess *
-createProcess(const string &nm, ObjectFile * objFile,
- int stdin_fd, int stdout_fd, int stderr_fd,
- vector<string> &argv, vector<string> &envp)
+SparcLiveProcess *
+SparcLiveProcess::create(const std::string &nm, System *system, int stdin_fd,
+ int stdout_fd, int stderr_fd, std::string executable,
+ std::vector<std::string> &argv, std::vector<std::string> &envp)
{
- LiveProcess * process = NULL;
+ SparcLiveProcess *process = NULL;
+
+ ObjectFile *objFile = createObjectFile(executable);
+ if (objFile == NULL) {
+ fatal("Can't load object file %s", executable);
+ }
+
+
if (objFile->getArch() != ObjectFile::SPARC)
fatal("Object file does not match architecture.");
switch (objFile->getOpSys()) {
case ObjectFile::Linux:
- process = new SparcLinuxProcess(nm, objFile,
+ process = new SparcLinuxProcess(nm, objFile, system,
stdin_fd, stdout_fd, stderr_fd,
argv, envp);
break;
@@ -50,7 +64,98 @@ createProcess(const string &nm, ObjectFile * objFile,
default:
fatal("Unknown/unsupported operating system.");
}
+
+ if (process == NULL)
+ fatal("Unknown error creating process object.");
return process;
}
-} // namespace SparcISA
+SparcLiveProcess::SparcLiveProcess(const std::string &nm, ObjectFile *objFile,
+ System *_system, int stdin_fd, int stdout_fd, int stderr_fd,
+ std::vector<std::string> &argv, std::vector<std::string> &envp)
+ : LiveProcess(nm, objFile, _system, stdin_fd, stdout_fd, stderr_fd,
+ argv, envp)
+{
+
+ // XXX all the below need to be updated for SPARC - Ali
+ brk_point = objFile->dataBase() + objFile->dataSize() + objFile->bssSize();
+ brk_point = roundUp(brk_point, VMPageSize);
+
+ // Set up stack. On Alpha, stack goes below text section. This
+ // code should get moved to some architecture-specific spot.
+ stack_base = objFile->textBase() - (409600+4096);
+
+ // Set up region for mmaps. Tru64 seems to start just above 0 and
+ // grow up from there.
+ mmap_start = mmap_end = 0x10000;
+
+ // Set pointer for next thread stack. Reserve 8M for main stack.
+ next_thread_stack_base = stack_base - (8 * 1024 * 1024);
+
+}
+
+void
+SparcLiveProcess::startup()
+{
+ argsInit(MachineBytes, VMPageSize);
+}
+
+
+
+
+BEGIN_DECLARE_SIM_OBJECT_PARAMS(SparcLiveProcess)
+
+ VectorParam<string> cmd;
+ Param<string> executable;
+ Param<string> input;
+ Param<string> output;
+ VectorParam<string> env;
+ SimObjectParam<System *> system;
+
+END_DECLARE_SIM_OBJECT_PARAMS(SparcLiveProcess)
+
+
+BEGIN_INIT_SIM_OBJECT_PARAMS(SparcLiveProcess)
+
+ INIT_PARAM(cmd, "command line (executable plus arguments)"),
+ INIT_PARAM(executable, "executable (overrides cmd[0] if set)"),
+ INIT_PARAM(input, "filename for stdin (dflt: use sim stdin)"),
+ INIT_PARAM(output, "filename for stdout/stderr (dflt: use sim stdout)"),
+ INIT_PARAM(env, "environment settings"),
+ INIT_PARAM(system, "system")
+
+END_INIT_SIM_OBJECT_PARAMS(SparcLiveProcess)
+
+
+CREATE_SIM_OBJECT(SparcLiveProcess)
+{
+ string in = input;
+ string out = output;
+
+ // initialize file descriptors to default: same as simulator
+ int stdin_fd, stdout_fd, stderr_fd;
+
+ if (in == "stdin" || in == "cin")
+ stdin_fd = STDIN_FILENO;
+ else
+ stdin_fd = Process::openInputFile(input);
+
+ if (out == "stdout" || out == "cout")
+ stdout_fd = STDOUT_FILENO;
+ else if (out == "stderr" || out == "cerr")
+ stdout_fd = STDERR_FILENO;
+ else
+ stdout_fd = Process::openOutputFile(out);
+
+ stderr_fd = (stdout_fd != STDOUT_FILENO) ? stdout_fd : STDERR_FILENO;
+
+ return SparcLiveProcess::create(getInstanceName(), system,
+ stdin_fd, stdout_fd, stderr_fd,
+ (string)executable == "" ? cmd[0] : executable,
+ cmd, env);
+}
+
+
+REGISTER_SIM_OBJECT("SparcLiveProcess", SparcLiveProcess)
+
+
diff --git a/arch/sparc/process.hh b/arch/sparc/process.hh
index 48041a316..cc4d0ae0a 100644
--- a/arch/sparc/process.hh
+++ b/arch/sparc/process.hh
@@ -29,17 +29,34 @@
#ifndef __SPARC_PROCESS_HH__
#define __SPARC_PROCESS_HH__
-#include "arch/sparc/linux/process.hh"
-#include "base/loader/object_file.hh"
+#include <string>
+#include <vector>
+#include "sim/process.hh"
-namespace SparcISA
+class ObjectFile;
+class System;
+
+class SparcLiveProcess : public LiveProcess
{
+ protected:
+ SparcLiveProcess(const std::string &nm, ObjectFile *objFile,
+ System *_system, int stdin_fd, int stdout_fd, int stderr_fd,
+ std::vector<std::string> &argv,
+ std::vector<std::string> &envp);
+
+ void startup();
-LiveProcess *
-createProcess(const string &nm, ObjectFile * objFile,
- int stdin_fd, int stdout_fd, int stderr_fd,
- vector<string> &argv, vector<string> &envp);
+ public:
+ // this function is used to create the LiveProcess object, since
+ // we can't tell which subclass of LiveProcess to use until we
+ // open and look at the object file.
+ static SparcLiveProcess *create(const std::string &nm,
+ System *_system,
+ int stdin_fd, int stdout_fd, int stderr_fd,
+ std::string executable,
+ std::vector<std::string> &argv,
+ std::vector<std::string> &envp);
-} // namespace SparcISA
+};
#endif // __SPARC_PROCESS_HH__
diff --git a/arch/sparc/regfile.hh b/arch/sparc/regfile.hh
new file mode 100644
index 000000000..944fdfe80
--- /dev/null
+++ b/arch/sparc/regfile.hh
@@ -0,0 +1,520 @@
+/*
+ * 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.
+ */
+
+#ifndef __ARCH_SPARC_REGFILE_HH__
+#define __ARCH_SPARC_REGFILE_HH__
+
+#include "arch/sparc/faults.hh"
+#include "sim/byteswap.hh"
+#include "sim/host.hh"
+
+class Checkpoint;
+
+namespace SparcISA
+{
+
+ typedef uint8_t RegIndex;
+
+ // Maximum trap level
+ const int MaxTL = 4;
+
+ //For right now, let's pretend the register file is flat
+ typedef IntReg IntRegFile[NumIntRegs];
+
+ typedef float float32_t;
+ typedef double float64_t;
+ //FIXME long double refers to a 10 byte float, rather than a
+ //16 byte float as required. This data type may have to be emulated.
+ typedef double float128_t;
+
+ class FloatRegFile
+ {
+ protected:
+ //Since the floating point registers overlap each other,
+ //A generic storage space is used. The float to be returned is
+ //pulled from the appropriate section of this region.
+ char regSpace[32 * 64];
+
+ static const int SingleWidth = 32;
+ static const int DoubleWidth = 64;
+ static const int QuadWidth = 128;
+
+ public:
+
+ FloatReg readReg(int floatReg, int width)
+ {
+ //In each of these cases, we have to copy the value into a temporary
+ //variable. This is because we may otherwise try to access an
+ //unaligned portion of memory.
+ switch(width)
+ {
+ case SingleWidth:
+ float32_t result32;
+ memcpy(&result32, regSpace + 4 * floatReg, width);
+ return htog(result32);
+ case DoubleWidth:
+ float64_t result64;
+ memcpy(&result64, regSpace + 4 * floatReg, width);
+ return htog(result64);
+ case QuadWidth:
+ float128_t result128;
+ memcpy(&result128, regSpace + 4 * floatReg, width);
+ return htog(result128);
+ default:
+ panic("Attempted to read a %d bit floating point register!", width);
+ }
+ }
+
+ FloatReg readReg(int floatReg)
+ {
+ //Use the "natural" width of a single float
+ return readReg(floatReg, SingleWidth);
+ }
+
+ FloatRegBits readRegBits(int floatReg, int width)
+ {
+ //In each of these cases, we have to copy the value into a temporary
+ //variable. This is because we may otherwise try to access an
+ //unaligned portion of memory.
+ switch(width)
+ {
+ case SingleWidth:
+ uint32_t result32;
+ memcpy(&result32, regSpace + 4 * floatReg, width);
+ return htog(result32);
+ case DoubleWidth:
+ uint64_t result64;
+ memcpy(&result64, regSpace + 4 * floatReg, width);
+ return htog(result64);
+ case QuadWidth:
+ uint64_t result128;
+ memcpy(&result128, regSpace + 4 * floatReg, width);
+ return htog(result128);
+ default:
+ panic("Attempted to read a %d bit floating point register!", width);
+ }
+ }
+
+ FloatRegBits readRegBits(int floatReg)
+ {
+ //Use the "natural" width of a single float
+ return readRegBits(floatReg, SingleWidth);
+ }
+
+ Fault setReg(int floatReg, const FloatReg &val, int width)
+ {
+ //In each of these cases, we have to copy the value into a temporary
+ //variable. This is because we may otherwise try to access an
+ //unaligned portion of memory.
+ switch(width)
+ {
+ case SingleWidth:
+ uint32_t result32 = gtoh((uint32_t)val);
+ memcpy(regSpace + 4 * floatReg, &result32, width);
+ case DoubleWidth:
+ uint64_t result64 = gtoh((uint64_t)val);
+ memcpy(regSpace + 4 * floatReg, &result64, width);
+ case QuadWidth:
+ uint64_t result128 = gtoh((uint64_t)val);
+ memcpy(regSpace + 4 * floatReg, &result128, width);
+ default:
+ panic("Attempted to read a %d bit floating point register!", width);
+ }
+ return NoFault;
+ }
+
+ Fault setReg(int floatReg, const FloatReg &val)
+ {
+ //Use the "natural" width of a single float
+ return setReg(floatReg, val, SingleWidth);
+ }
+
+ Fault setRegBits(int floatReg, const FloatRegBits &val, int width)
+ {
+ //In each of these cases, we have to copy the value into a temporary
+ //variable. This is because we may otherwise try to access an
+ //unaligned portion of memory.
+ switch(width)
+ {
+ case SingleWidth:
+ uint32_t result32 = gtoh((uint32_t)val);
+ memcpy(regSpace + 4 * floatReg, &result32, width);
+ case DoubleWidth:
+ uint64_t result64 = gtoh((uint64_t)val);
+ memcpy(regSpace + 4 * floatReg, &result64, width);
+ case QuadWidth:
+ uint64_t result128 = gtoh((uint64_t)val);
+ memcpy(regSpace + 4 * floatReg, &result128, width);
+ default:
+ panic("Attempted to read a %d bit floating point register!", width);
+ }
+ return NoFault;
+ }
+
+ Fault setRegBits(int floatReg, const FloatRegBits &val)
+ {
+ //Use the "natural" width of a single float
+ return setReg(floatReg, val, SingleWidth);
+ }
+
+ void serialize(std::ostream &os);
+
+ void unserialize(Checkpoint *cp, const std::string &section);
+ };
+
+ enum MiscRegIndex
+ {
+ MISCREG_PSTATE,
+ MISCREG_PSTATE_AG,
+ MISCREG_PSTATE_IE,
+ MISCREG_PSTATE_PRIV,
+ MISCREG_PSTATE_AM,
+ MISCREG_PSTATE_PEF,
+ MISCREG_PSTATE_RED,
+ MISCREG_PSTATE_MM,
+ MISCREG_PSTATE_TLE,
+ MISCREG_PSTATE_CLE,
+ MISCREG_TBA,
+ MISCREG_Y,
+ MISCREG_Y_VALUE,
+ MISCREG_PIL,
+ MISCREG_CWP,
+ MISCREG_TT_BASE,
+ MISCREG_TT_END = MISCREG_TT_BASE + MaxTL,
+ MISCREG_CCR,
+ MISCREG_CCR_ICC,
+ MISCREG_CCR_ICC_C,
+ MISCREG_CCR_ICC_V,
+ MISCREG_CCR_ICC_Z,
+ MISCREG_CCR_ICC_N,
+ MISCREG_CCR_XCC,
+ MISCREG_CCR_XCC_C,
+ MISCREG_CCR_XCC_V,
+ MISCREG_CCR_XCC_Z,
+ MISCREG_CCR_XCC_N,
+ MISCREG_ASI,
+ MISCREG_TL,
+ MISCREG_TPC_BASE,
+ MISCREG_TPC_END = MISCREG_TPC_BASE + MaxTL,
+ MISCREG_TNPC_BASE,
+ MISCREG_TNPC_END = MISCREG_TNPC_BASE + MaxTL,
+ MISCREG_TSTATE_BASE,
+ MISCREG_TSTATE_END = MISCREG_TSTATE_BASE + MaxTL,
+ MISCREG_TSTATE_CWP_BASE,
+ MISCREG_TSTATE_CWP_END = MISCREG_TSTATE_CWP_BASE + MaxTL,
+ MISCREG_TSTATE_PSTATE_BASE,
+ MISCREG_TSTATE_PSTATE_END = MISCREG_TSTATE_PSTATE_BASE + MaxTL,
+ MISCREG_TSTATE_ASI_BASE,
+ MISCREG_TSTATE_ASI_END = MISCREG_TSTATE_ASI_BASE + MaxTL,
+ MISCREG_TSTATE_CCR_BASE,
+ MISCREG_TSTATE_CCR_END = MISCREG_TSTATE_CCR_BASE + MaxTL,
+ MISCREG_TICK,
+ MISCREG_TICK_COUNTER,
+ MISCREG_TICK_NPT,
+ MISCREG_CANSAVE,
+ MISCREG_CANRESTORE,
+ MISCREG_OTHERWIN,
+ MISCREG_CLEANWIN,
+ MISCREG_WSTATE,
+ MISCREG_WSTATE_NORMAL,
+ MISCREG_WSTATE_OTHER,
+ MISCREG_VER,
+ MISCREG_VER_MAXWIN,
+ MISCREG_VER_MAXTL,
+ MISCREG_VER_MASK,
+ MISCREG_VER_IMPL,
+ MISCREG_VER_MANUF,
+ MISCREG_FSR,
+ MISCREG_FSR_CEXC,
+ MISCREG_FSR_CEXC_NXC,
+ MISCREG_FSR_CEXC_DZC,
+ MISCREG_FSR_CEXC_UFC,
+ MISCREG_FSR_CEXC_OFC,
+ MISCREG_FSR_CEXC_NVC,
+ MISCREG_FSR_AEXC,
+ MISCREG_FSR_AEXC_NXC,
+ MISCREG_FSR_AEXC_DZC,
+ MISCREG_FSR_AEXC_UFC,
+ MISCREG_FSR_AEXC_OFC,
+ MISCREG_FSR_AEXC_NVC,
+ MISCREG_FSR_FCC0,
+ MISCREG_FSR_QNE,
+ MISCREG_FSR_FTT,
+ MISCREG_FSR_VER,
+ MISCREG_FSR_NS,
+ MISCREG_FSR_TEM,
+ MISCREG_FSR_TEM_NXM,
+ MISCREG_FSR_TEM_DZM,
+ MISCREG_FSR_TEM_UFM,
+ MISCREG_FSR_TEM_OFM,
+ MISCREG_FSR_TEM_NVM,
+ MISCREG_FSR_RD,
+ MISCREG_FSR_FCC1,
+ MISCREG_FSR_FCC2,
+ MISCREG_FSR_FCC3,
+ MISCREG_FPRS,
+ MISCREG_FPRS_DL,
+ MISCREG_FPRS_DU,
+ MISCREG_FPRS_FEF,
+ numMiscRegs
+ };
+
+ // The control registers, broken out into fields
+ class MiscRegFile
+ {
+ private:
+ union
+ {
+ uint16_t pstate; // Process State Register
+ struct
+ {
+ uint16_t ag:1; // Alternate Globals
+ uint16_t ie:1; // Interrupt enable
+ uint16_t priv:1; // Privelege mode
+ uint16_t am:1; // Address mask
+ uint16_t pef:1; // PSTATE enable floating-point
+ uint16_t red:1; // RED (reset, error, debug) state
+ uint16_t mm:2; // Memory Model
+ uint16_t tle:1; // Trap little-endian
+ uint16_t cle:1; // Current little-endian
+ } pstateFields;
+ };
+ uint64_t tba; // Trap Base Address
+ union
+ {
+ uint64_t y; // Y (used in obsolete multiplication)
+ struct
+ {
+ uint64_t value:32; // The actual value stored in y
+ uint64_t :32; // reserved bits
+ } yFields;
+ };
+ uint8_t pil; // Process Interrupt Register
+ uint8_t cwp; // Current Window Pointer
+ uint16_t tt[MaxTL]; // Trap Type (Type of trap which occured
+ // on the previous level)
+ union
+ {
+ uint8_t ccr; // Condition Code Register
+ struct
+ {
+ union
+ {
+ uint8_t icc:4; // 32-bit condition codes
+ struct
+ {
+ uint8_t c:1; // Carry
+ uint8_t v:1; // Overflow
+ uint8_t z:1; // Zero
+ uint8_t n:1; // Negative
+ } iccFields;
+ };
+ union
+ {
+ uint8_t xcc:4; // 64-bit condition codes
+ struct
+ {
+ uint8_t c:1; // Carry
+ uint8_t v:1; // Overflow
+ uint8_t z:1; // Zero
+ uint8_t n:1; // Negative
+ } xccFields;
+ };
+ } ccrFields;
+ };
+ uint8_t asi; // Address Space Identifier
+ uint8_t tl; // Trap Level
+ uint64_t tpc[MaxTL]; // Trap Program Counter (value from
+ // previous trap level)
+ uint64_t tnpc[MaxTL]; // Trap Next Program Counter (value from
+ // previous trap level)
+ union
+ {
+ uint64_t tstate[MaxTL]; // Trap State
+ struct
+ {
+ //Values are from previous trap level
+ uint64_t cwp:5; // Current Window Pointer
+ uint64_t :2; // Reserved bits
+ uint64_t pstate:10; // Process State
+ uint64_t :6; // Reserved bits
+ uint64_t asi:8; // Address Space Identifier
+ uint64_t ccr:8; // Condition Code Register
+ } tstateFields[MaxTL];
+ };
+ union
+ {
+ uint64_t tick; // Hardware clock-tick counter
+ struct
+ {
+ uint64_t counter:63; // Clock-tick count
+ uint64_t npt:1; // Non-priveleged trap
+ } tickFields;
+ };
+ uint8_t cansave; // Savable windows
+ uint8_t canrestore; // Restorable windows
+ uint8_t otherwin; // Other windows
+ uint8_t cleanwin; // Clean windows
+ union
+ {
+ uint8_t wstate; // Window State
+ struct
+ {
+ uint8_t normal:3; // Bits TT<4:2> are set to on a normal
+ // register window trap
+ uint8_t other:3; // Bits TT<4:2> are set to on an "otherwin"
+ // register window trap
+ } wstateFields;
+ };
+ union
+ {
+ uint64_t ver; // Version
+ struct
+ {
+ uint64_t maxwin:5; // Max CWP value
+ uint64_t :2; // Reserved bits
+ uint64_t maxtl:8; // Maximum trap level
+ uint64_t :8; // Reserved bits
+ uint64_t mask:8; // Processor mask set revision number
+ uint64_t impl:16; // Implementation identification number
+ uint64_t manuf:16; // Manufacturer code
+ } verFields;
+ };
+ union
+ {
+ uint64_t fsr; // Floating-Point State Register
+ struct
+ {
+ union
+ {
+ uint64_t cexc:5; // Current excpetion
+ struct
+ {
+ uint64_t nxc:1; // Inexact
+ uint64_t dzc:1; // Divide by zero
+ uint64_t ufc:1; // Underflow
+ uint64_t ofc:1; // Overflow
+ uint64_t nvc:1; // Invalid operand
+ } cexcFields;
+ };
+ union
+ {
+ uint64_t aexc:5; // Accrued exception
+ struct
+ {
+ uint64_t nxc:1; // Inexact
+ uint64_t dzc:1; // Divide by zero
+ uint64_t ufc:1; // Underflow
+ uint64_t ofc:1; // Overflow
+ uint64_t nvc:1; // Invalid operand
+ } aexcFields;
+ };
+ uint64_t fcc0:2; // Floating-Point condtion codes
+ uint64_t :1; // Reserved bits
+ uint64_t qne:1; // Deferred trap queue not empty
+ // with no queue, it should read 0
+ uint64_t ftt:3; // Floating-Point trap type
+ uint64_t ver:3; // Version (of the FPU)
+ uint64_t :2; // Reserved bits
+ uint64_t ns:1; // Nonstandard floating point
+ union
+ {
+ uint64_t tem:5; // Trap Enable Mask
+ struct
+ {
+ uint64_t nxm:1; // Inexact
+ uint64_t dzm:1; // Divide by zero
+ uint64_t ufm:1; // Underflow
+ uint64_t ofm:1; // Overflow
+ uint64_t nvm:1; // Invalid operand
+ } temFields;
+ };
+ uint64_t :2; // Reserved bits
+ uint64_t rd:2; // Rounding direction
+ uint64_t fcc1:2; // Floating-Point condition codes
+ uint64_t fcc2:2; // Floating-Point condition codes
+ uint64_t fcc3:2; // Floating-Point condition codes
+ uint64_t :26; // Reserved bits
+ } fsrFields;
+ };
+ union
+ {
+ uint8_t fprs; // Floating-Point Register State
+ struct
+ {
+ uint8_t dl:1; // Dirty lower
+ uint8_t du:1; // Dirty upper
+ uint8_t fef:1; // FPRS enable floating-Point
+ } fprsFields;
+ };
+
+ public:
+ MiscReg readReg(int miscReg);
+
+ MiscReg readRegWithEffect(int miscReg, Fault &fault, ExecContext *xc);
+
+ Fault setReg(int miscReg, const MiscReg &val);
+
+ Fault setRegWithEffect(int miscReg, const MiscReg &val,
+ ExecContext *xc);
+
+ void serialize(std::ostream & os);
+
+ void unserialize(Checkpoint * cp, const std::string & section);
+
+ void copyMiscRegs(ExecContext * xc);
+ };
+
+ typedef union
+ {
+ IntReg intreg;
+ FloatReg fpreg;
+ MiscReg ctrlreg;
+ } AnyReg;
+
+ struct RegFile
+ {
+ IntRegFile intRegFile; // (signed) integer register file
+ FloatRegFile floatRegFile; // floating point register file
+ MiscRegFile miscRegs; // control register file
+
+ Addr pc; // Program Counter
+ Addr npc; // Next Program Counter
+ Addr nnpc;
+
+ void serialize(std::ostream &os);
+ void unserialize(Checkpoint *cp, const std::string &section);
+ };
+
+ void copyRegs(ExecContext *src, ExecContext *dest);
+
+ void copyMiscRegs(ExecContext *src, ExecContext *dest);
+
+} // namespace SparcISA
+
+#endif