summaryrefslogtreecommitdiff
path: root/arch/sparc/isa
diff options
context:
space:
mode:
authorGabe Black <gblack@eecs.umich.edu>2006-04-18 09:27:22 -0400
committerGabe Black <gblack@eecs.umich.edu>2006-04-18 09:27:22 -0400
commit3d99b4a5447abb1ccca552cee281137e2b11a674 (patch)
treeb2c5fe75b956939247339e44cc546eb71393f9d5 /arch/sparc/isa
parent832311a17094501a6883100ac9dba8c781211782 (diff)
downloadgem5-3d99b4a5447abb1ccca552cee281137e2b11a674.tar.xz
Fixes to SPARC syscall emulation mode.
arch/sparc/isa/base.isa: Added a set of abbreviations for the different condition tests. arch/sparc/isa/decoder.isa: Fixes and additions to get syscall emulation closer to working. arch/sparc/isa/formats/branch.isa: Fixed branches so that the immediate version actually uses the immediate value arch/sparc/isa/formats/integerop.isa: Compute the condition codes -before- writing to the state of the machine. arch/sparc/isa/formats/mem.isa: An attempt to fix up the output of the disassembly of loads and stores. arch/sparc/isa/formats/trap.isa: Added code to disassemble a trap instruction. This probably needs to be fixed up so there are immediate and register versions. arch/sparc/isa/operands.isa: Added an R1 operand, and fixed up the numbering arch/sparc/isa_traits.hh: SyscallNumReg is no longer needed, the max number of sources and destinations are fixed up, and the syscall return uses xcc instead of icc. arch/sparc/linux/process.cc: arch/sparc/linux/process.hh: Added a getresuidFunc syscall implementation. This isn't actually used, but I thought it was and will leave it in. arch/sparc/process.cc: arch/sparc/process.hh: Fixed up how the initial stack frame is set up. arch/sparc/regfile.hh: Changed the number of windows from 6 to 32 so we don't have to worry about spill and fill traps for now, and commented out the register file setting itself up. cpu/cpu_exec_context.hh: cpu/exec_context.hh: cpu/simple/cpu.hh: sim/process.cc: sim/process.hh: Changed the syscall mechanism to pass down the syscall number directly. --HG-- extra : convert_revision : 15723b949a0ddb3d24e68c079343b4dba2439f43
Diffstat (limited to 'arch/sparc/isa')
-rw-r--r--arch/sparc/isa/base.isa25
-rw-r--r--arch/sparc/isa/decoder.isa79
-rw-r--r--arch/sparc/isa/formats/branch.isa5
-rw-r--r--arch/sparc/isa/formats/integerop.isa2
-rw-r--r--arch/sparc/isa/formats/mem.isa12
-rw-r--r--arch/sparc/isa/formats/trap.isa14
-rw-r--r--arch/sparc/isa/operands.isa5
7 files changed, 104 insertions, 38 deletions
diff --git a/arch/sparc/isa/base.isa b/arch/sparc/isa/base.isa
index 434426ffa..cb370a3e7 100644
--- a/arch/sparc/isa/base.isa
+++ b/arch/sparc/isa/base.isa
@@ -37,6 +37,8 @@ output header {{
OverflowSet=0x7
};
+ extern char * CondTestAbbrev[];
+
/**
* Base class for all SPARC static instructions.
*/
@@ -65,6 +67,29 @@ output header {{
}
}};
+output decoder {{
+
+ char * CondTestAbbrev[] =
+ {
+ "nev", //Never
+ "e", //Equal
+ "le", //Less or Equal
+ "l", //Less
+ "leu", //Less or Equal Unsigned
+ "c", //Carry set
+ "n", //Negative
+ "o", //Overflow set
+ "a", //Always
+ "ne", //Not Equal
+ "g", //Greater
+ "ge", //Greater or Equal
+ "gu", //Greater Unsigned
+ "cc", //Carry clear
+ "p", //Positive
+ "oc" //Overflow Clear
+ };
+}};
+
def template ROrImmDecode {{
{
return (I ? (SparcStaticInst *)(new %(class_name)sImm(machInst))
diff --git a/arch/sparc/isa/decoder.isa b/arch/sparc/isa/decoder.isa
index b4084518c..823bf2626 100644
--- a/arch/sparc/isa/decoder.isa
+++ b/arch/sparc/isa/decoder.isa
@@ -423,41 +423,70 @@ decode OP default Unknown::unknown()
}
}});
0x39: Branch::return({{
+ //If both MemAddressNotAligned and
+ //a fill trap happen, it's not clear
+ //which one should be returned.
Addr target = Rs1 + Rs2_or_imm13;
if(target & 0x3)
fault = new MemAddressNotAligned;
else
NNPC = target;
- //This needs to change the register window
- //like restore does
+ if(fault == NoFault)
+ {
+ //CWP should be set directly so that it always happens
+ //Also, this will allow writing to the new window and
+ //reading from the old one
+ Cwp = (Cwp - 1 + NWindows) % NWindows;
+ if(Canrestore == 0)
+ {
+ if(Otherwin)
+ fault = new FillNOther(WstateOther);
+ else
+ fault = new FillNNormal(WstateNormal);
+ }
+ else
+ {
+ Rd = Rs1 + Rs2_or_imm13;
+ Cansave = Cansave + 1;
+ Canrestore = Canrestore - 1;
+ }
+ //This is here to make sure the CWP is written
+ //no matter what. This ensures that the results
+ //are written in the new window as well.
+ xc->setMiscRegWithEffect(MISCREG_CWP, Cwp);
+ }
}});
0x3A: decode CC
{
0x0: Trap::tcci({{
+ if(passesCondition(CcrIcc, COND2))
+ {
+ int lTrapNum = I ? (Rs1 + SW_TRAP) : (Rs1 + Rs2);
+ DPRINTF(Sparc, "The trap number is %d\n", lTrapNum);
#if FULL_SYSTEM
- fault = new TrapInstruction;
+ fault = new TrapInstruction(lTrapNum);
#else
- if(passesCondition(CcrIcc, machInst<25:28>))
+ DPRINTF(Sparc, "The syscall number is %d\n", R1);
+ xc->syscall(R1);
+#endif
+ }
+ else
{
- // At least glibc only uses trap 0,
- // solaris/sunos may use others
- assert((I ? Rs1 + Rs2 : Rs1 + SW_TRAP) == 0);
- xc->syscall();
+ DPRINTF(Sparc, "Didn't fire on %s\n", CondTestAbbrev[machInst<25:28>]);
}
-#endif
}});
0x2: Trap::tccx({{
+ if(passesCondition(CcrXcc, COND2))
+ {
+ int lTrapNum = I ? (Rs1 + SW_TRAP) : (Rs1 + Rs2);
+ DPRINTF(Sparc, "The trap number is %d\n", lTrapNum);
#if FULL_SYSTEM
- fault = new TrapInstruction;
+ fault = new TrapInstruction(lTrapNum);
#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();
- }
+ DPRINTF(Sparc, "The syscall number is %d\n", R1);
+ xc->syscall(R1);
#endif
+ }
}});
}
0x3B: Nop::flush({{/*Instruction memory flush*/}});
@@ -482,8 +511,8 @@ decode OP default Unknown::unknown()
{
Cwp = (Cwp + 1) % NWindows;
Rd = Rs1 + Rs2_or_imm13;
- Cansave--;
- Canrestore++;
+ Cansave = Cansave - 1;
+ Canrestore = Canrestore + 1;
}
//This is here to make sure the CWP is written
//no matter what. This ensures that the results
@@ -505,8 +534,8 @@ decode OP default Unknown::unknown()
else
{
Rd = Rs1 + Rs2_or_imm13;
- Cansave++;
- Canrestore--;
+ Cansave = Cansave + 1;
+ Canrestore = Canrestore - 1;
}
//This is here to make sure the CWP is written
//no matter what. This ensures that the results
@@ -607,15 +636,15 @@ decode OP default Unknown::unknown()
format Trap {
0x20: ldf({{fault = new FpDisabled;}});
0x21: decode X {
- 0x0: ldfsr({{fault = new FpDisabled;}});
- 0x1: ldxfsr({{fault = new FpDisabled;}});
+ 0x0: Load::ldfsr({{Fsr = Mem<31:0> | Fsr<63:32>;}}, {{32}});
+ 0x1: Load::ldxfsr({{Fsr = Mem;}}, {{64}});
}
0x22: ldqf({{fault = new FpDisabled;}});
0x23: lddf({{fault = new FpDisabled;}});
0x24: stf({{fault = new FpDisabled;}});
0x25: decode X {
- 0x0: stfsr({{fault = new FpDisabled;}});
- 0x1: stxfsr({{fault = new FpDisabled;}});
+ 0x0: Store::stfsr({{Mem = Fsr<31:0>;}}, {{32}});
+ 0x1: Store::stxfsr({{Mem = Fsr;}}, {{64}});
}
0x26: stqf({{fault = new FpDisabled;}});
0x27: stdf({{fault = new FpDisabled;}});
diff --git a/arch/sparc/isa/formats/branch.isa b/arch/sparc/isa/formats/branch.isa
index e4ce4592c..b76f7a9f6 100644
--- a/arch/sparc/isa/formats/branch.isa
+++ b/arch/sparc/isa/formats/branch.isa
@@ -230,14 +230,13 @@ def template BranchExecute {{
def format Branch(code, *opt_flags) {{
(usesImm, code, immCode,
rString, iString) = splitOutImm(code)
- codeBlk = CodeBlock(code)
- iop = InstObjParams(name, Name, 'Branch', codeBlk, opt_flags)
+ iop = InstObjParams(name, Name, 'Branch', code, opt_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
exec_output = BranchExecute.subst(iop)
if usesImm:
imm_iop = InstObjParams(name, Name + 'Imm', 'BranchImm' + iString,
- codeBlk, opt_flags)
+ immCode, opt_flags)
header_output += BasicDeclare.subst(imm_iop)
decoder_output += BasicConstructor.subst(imm_iop)
exec_output += BranchExecute.subst(imm_iop)
diff --git a/arch/sparc/isa/formats/integerop.isa b/arch/sparc/isa/formats/integerop.isa
index f14f9e858..401af2e51 100644
--- a/arch/sparc/isa/formats/integerop.isa
+++ b/arch/sparc/isa/formats/integerop.isa
@@ -243,8 +243,8 @@ def template IntOpExecute {{
//Write the resulting state to the execution context
if(fault == NoFault)
{
- %(op_wb)s;
%(cc_code)s;
+ %(op_wb)s;
}
return fault;
}
diff --git a/arch/sparc/isa/formats/mem.isa b/arch/sparc/isa/formats/mem.isa
index db2a4aaaa..e15349c7b 100644
--- a/arch/sparc/isa/formats/mem.isa
+++ b/arch/sparc/isa/formats/mem.isa
@@ -47,17 +47,18 @@ output decoder {{
{
std::stringstream response;
bool load = flags[IsLoad];
+ bool save = flags[IsStore];
printMnemonic(response, mnemonic);
- if(!load)
+ if(save)
{
printReg(response, _srcRegIdx[0]);
ccprintf(response, ", ");
}
ccprintf(response, "[ ");
- printReg(response, _srcRegIdx[load ? 0 : 1]);
+ printReg(response, _srcRegIdx[!save ? 0 : 1]);
ccprintf(response, " + ");
- printReg(response, _srcRegIdx[load ? 1 : 2]);
+ printReg(response, _srcRegIdx[!save ? 1 : 2]);
ccprintf(response, " ]");
if(load)
{
@@ -73,15 +74,16 @@ output decoder {{
{
std::stringstream response;
bool load = flags[IsLoad];
+ bool save = flags[IsStore];
printMnemonic(response, mnemonic);
- if(!load)
+ if(save)
{
printReg(response, _srcRegIdx[0]);
ccprintf(response, ", ");
}
ccprintf(response, "[ ");
- printReg(response, _srcRegIdx[load ? 0 : 1]);
+ printReg(response, _srcRegIdx[!save ? 0 : 1]);
ccprintf(response, " + 0x%x ]", imm);
if(load)
{
diff --git a/arch/sparc/isa/formats/trap.isa b/arch/sparc/isa/formats/trap.isa
index 5608548bd..f6a45ca48 100644
--- a/arch/sparc/isa/formats/trap.isa
+++ b/arch/sparc/isa/formats/trap.isa
@@ -14,12 +14,14 @@ output header {{
// Constructor
Trap(const char *mnem, ExtMachInst _machInst, OpClass __opClass) :
- SparcStaticInst(mnem, _machInst, __opClass)
+ SparcStaticInst(mnem, _machInst, __opClass), trapNum(SW_TRAP)
{
}
std::string generateDisassembly(Addr pc,
const SymbolTable *symtab) const;
+
+ int trapNum;
};
}};
@@ -27,7 +29,15 @@ output decoder {{
std::string Trap::generateDisassembly(Addr pc,
const SymbolTable *symtab) const
{
- return "Trap instruction";
+ std::stringstream response;
+
+ printMnemonic(response, mnemonic);
+ ccprintf(response, " ");
+ printReg(response, _srcRegIdx[0]);
+ ccprintf(response, ", 0x%x", trapNum);
+ ccprintf(response, ", or ");
+ printReg(response, _srcRegIdx[1]);
+ return response.str();
}
}};
diff --git a/arch/sparc/isa/operands.isa b/arch/sparc/isa/operands.isa
index 17e58ad59..64a032eea 100644
--- a/arch/sparc/isa/operands.isa
+++ b/arch/sparc/isa/operands.isa
@@ -30,8 +30,9 @@ def operands {{
#'Runiq': ('ControlReg', 'uq', 'Uniq', None, 1),
#'FPCR': ('ControlReg', 'uq', 'Fpcr', None, 1),
'R0': ('IntReg', 'udw', '0', None, 6),
- 'R15': ('IntReg', 'udw', '15', 'IsInteger', 7),
- 'R16': ('IntReg', 'udw', '16', None, 8),
+ 'R1': ('IntReg', 'udw', '1', None, 7),
+ 'R15': ('IntReg', 'udw', '15', 'IsInteger', 8),
+ 'R16': ('IntReg', 'udw', '16', None, 9),
# Control registers
'Pstate': ('ControlReg', 'udw', 'MISCREG_PSTATE', None, 1),
'PstateAg': ('ControlReg', 'udw', 'MISCREG_PSTATE_AG', None, 2),