summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xarch/isa_parser.py4
-rw-r--r--arch/mips/isa/decoder.isa291
-rw-r--r--arch/mips/isa/formats/fp.isa4
-rw-r--r--arch/mips/isa/formats/mem.isa26
-rw-r--r--arch/mips/isa/formats/util.isa21
-rw-r--r--arch/mips/isa_traits.cc31
-rw-r--r--arch/mips/isa_traits.hh170
-rw-r--r--arch/sparc/SConscript1
-rw-r--r--arch/sparc/isa/decoder.isa51
-rw-r--r--arch/sparc/isa/formats/branch.isa23
-rw-r--r--arch/sparc/isa/formats/integerop.isa16
-rw-r--r--arch/sparc/isa/formats/mem.isa1
-rw-r--r--arch/sparc/linux/linux.cc68
-rw-r--r--arch/sparc/linux/linux.hh61
-rw-r--r--arch/sparc/linux/process.cc6
-rw-r--r--arch/sparc/linux/process.hh1
-rw-r--r--arch/sparc/process.cc111
-rw-r--r--arch/sparc/process.hh19
-rwxr-xr-xconfigs/test/hello_sparcbin587552 -> 644149 bytes
-rw-r--r--cpu/simple/cpu.cc8
20 files changed, 693 insertions, 220 deletions
diff --git a/arch/isa_parser.py b/arch/isa_parser.py
index 8279a6a5d..921a6fa82 100755
--- a/arch/isa_parser.py
+++ b/arch/isa_parser.py
@@ -1334,7 +1334,7 @@ class NPCOperand(Operand):
return ''
def makeRead(self):
- return '%s = xc->readPC() + 4;\n' % self.base_name
+ return '%s = xc->readNextPC();\n' % self.base_name
def makeWrite(self):
return 'xc->setNextPC(%s);\n' % self.base_name
@@ -1344,7 +1344,7 @@ class NNPCOperand(Operand):
return ''
def makeRead(self):
- return '%s = xc->readPC() + 8;\n' % self.base_name
+ return '%s = xc->readNextNPC();\n' % self.base_name
def makeWrite(self):
return 'xc->setNextNPC(%s);\n' % self.base_name
diff --git a/arch/mips/isa/decoder.isa b/arch/mips/isa/decoder.isa
index 077f0afd0..6feaec7cb 100644
--- a/arch/mips/isa/decoder.isa
+++ b/arch/mips/isa/decoder.isa
@@ -394,36 +394,82 @@ decode OPCODE_HI default Unknown::unknown() {
0x0: decode RS_HI {
0x0: decode RS_LO {
- format WarnUnimpl {
- 0x0: mfc1();//{{ /*Rt.uw = Fs.ud<31:0>;*/ }}
- 0x3: mfhc1();// /*Rt.uw = Fs.ud<63:32>*/;
- 0x4: mtc1();// /*Fs = Rt.uw*/
- 0x7: mthc1();//{{/*Fs<63:32> = Rt.uw*/}}
+ format FloatOp {
+ 0x0: mfc1 ({{ Rt.uw = Fs.uw<31:0>; }});
+ 0x3: mfhc1({{ Rt.uw = Fs.ud<63:32>;}});
+ 0x4: mtc1 ({{ Fs.uw = Rt.uw; }});
+ 0x7: mthc1({{
+ uint64_t fs_hi = Rt.ud << 32;
+ uint64_t fs_lo = Fs.ud & 0x0000FFFF;
+ Fs.ud = fs_hi & fs_lo;
+ }});
}
format System {
0x2: cfc1({{
uint32_t fcsr_reg = xc->readMiscReg(FCSR);
- if (Fs == 0){
+ switch (FS)
+ {
+ case 0:
Rt = xc->readMiscReg(FIR);
- } else if (Fs == 25) {
+ break;
+ case 25:
Rt = 0 | (fcsr_reg & 0xFE000000) >> 24 | (fcsr_reg & 0x00800000) >> 23;
- } else if (Fs == 26) {
+ break;
+ case 26:
Rt = 0 | (fcsr_reg & 0x0003F07C);
- } else if (Fs == 28) {
+ break;
+ case 28:
Rt = 0 | (fcsr_reg);
- } else if (Fs == 31) {
+ break;
+ case 31:
Rt = fcsr_reg;
- } else {
+ break;
+ default:
panic("FP Control Value (%d) Not Available. Ignoring Access to"
"Floating Control Status Register",fcsr_reg);
}
-
}});
0x6: ctc1({{
- /*xc->setMiscReg(FPCR[Fs],Rt);*/
+ uint32_t fcsr_reg = xc->readMiscReg(FCSR);
+ uint32_t temp;
+ switch (FS)
+ {
+ case 25:
+ temp = 0 | (Rt.uw<7:1> << 25) // move 31...25
+ | (fcsr_reg & 0x01000000) // bit 24
+ | (fcsr_reg & 0x004FFFFF);// bit 22...0
+ break;
+
+ case 26:
+ temp = 0 | (fcsr_reg & 0xFFFC0000) // move 31...18
+ | Rt.uw<17:12> << 12 // bit 17...12
+ | (fcsr_reg & 0x00000F80) << 7// bit 11...7
+ | Rt.uw<6:2> << 2 // bit 6...2
+ | (fcsr_reg & 0x00000002); // bit 1...0
+ break;
+
+ case 28:
+ temp = 0 | (fcsr_reg & 0xFE000000) // move 31...25
+ | Rt.uw<2:2> << 24 // bit 24
+ | (fcsr_reg & 0x00FFF000) << 23// bit 23...12
+ | Rt.uw<11:7> << 7 // bit 24
+ | (fcsr_reg & 0x000007E)
+ | Rt.uw<1:0>;// bit 22...0
+ break;
+
+ case 31:
+ temp = Rt.uw;
+ break;
+
+ default:
+ panic("FP Control Value (%d) Not Available. Ignoring Access to"
+ "Floating Control Status Register",fcsr_reg);
+ }
+
+ xc->setMiscReg(FCSR,temp);
}});
}
}
@@ -450,8 +496,8 @@ decode OPCODE_HI default Unknown::unknown() {
//Table A-14 MIPS32 COP1 Encoding of Function Field When rs=S
//(( single-word ))
- 0x0: decode RS_HI {
- 0x0: decode RS_LO {
+ 0x0: decode FUNCTION_HI {
+ 0x0: decode FUNCTION_LO {
format FloatOp {
0x0: adds({{ Fd.sf = Fs.sf + Ft.sf;}});
0x1: subs({{ Fd.sf = Fs.sf - Ft.sf;}});
@@ -464,24 +510,45 @@ decode OPCODE_HI default Unknown::unknown() {
}
}
- 0x1: decode RS_LO {
- //only legal for 64 bit-FP
+ 0x1: decode FUNCTION_LO {
format Float64Op {
- 0x0: round_l_s({{ Fd = convert_and_round(Fs.sf,RND_NEAREST,FP_LONG,FP_SINGLE);}});
- 0x1: trunc_l_s({{ Fd = convert_and_round(Fs.sf,RND_ZERO,FP_LONG,FP_SINGLE);}});
- 0x2: ceil_l_s({{ Fd = convert_and_round(Fs.sf,RND_UP,FP_LONG,FP_SINGLE);}});
- 0x3: floor_l_s({{ Fd = convert_and_round(Fs.sf,RND_DOWN,FP_LONG,FP_SINGLE);}});
+ 0x0: round_l_s({{
+ Fd = convert_and_round(Fs.uw, SINGLE_TO_LONG, RND_NEAREST);
+ }});
+
+ 0x1: trunc_l_s({{
+ Fd = convert_and_round(Fs.uw, SINGLE_TO_LONG, RND_ZERO);
+ }});
+
+ 0x2: ceil_l_s({{
+ Fd = convert_and_round(Fs.uw, SINGLE_TO_LONG, RND_UP);
+ }});
+
+ 0x3: floor_l_s({{
+ Fd = convert_and_round(Fs.uw, SINGLE_TO_LONG, RND_DOWN);
+ }});
}
format FloatOp {
- 0x4: round_w_s({{ Fd = convert_and_round(Fs.sf,RND_NEAREST,FP_WORD,FP_SINGLE);}});
- 0x5: trunc_w_s({{ Fd = convert_and_round(Fs.sf,RND_ZERO,FP_WORD,FP_SINGLE);}});
- 0x6: ceil_w_s({{ Fd = convert_and_round(Fs.sf,RND_UP,FP_WORD,FP_SINGLE);}});
- 0x7: floor_w_s({{ Fd = convert_and_round(Fs.sf,RND_DOWN,FP_WORD,FP_SINGLE);}});
+ 0x4: round_w_s({{
+ Fd = convert_and_round(Fs.uw, SINGLE_TO_WORD, RND_NEAREST);
+ }});
+
+ 0x5: trunc_w_s({{
+ Fd = convert_and_round(Fs.uw, SINGLE_TO_WORD, RND_ZERO);
+ }});
+
+ 0x6: ceil_w_s({{
+ Fd = convert_and_round(Fs.uw, SINGLE_TO_WORD, RND_UP);
+ }});
+
+ 0x7: floor_w_s({{
+ Fd = convert_and_round(Fs.uw, SINGLE_TO_WORD, RND_DOWN);
+ }});
}
}
- 0x2: decode RS_LO {
+ 0x2: decode FUNCTION_LO {
0x1: decode MOVCF {
format FloatOp {
0x0: movfs({{if (xc->readMiscReg(FPCR) != CC) Fd = Fs; }});
@@ -500,32 +567,37 @@ decode OPCODE_HI default Unknown::unknown() {
}
}
- 0x4: decode RS_LO {
+ 0x4: decode FUNCTION_LO {
format FloatOp {
- 0x1: cvt_d_s({{ int rnd_mode = xc->readMiscReg(FCSR);
- Fd = convert_and_round(Fs.sf,rnd_mode,FP_DOUBLE,FP_SINGLE);
+ 0x1: cvt_d_s({{
+ int rnd_mode = xc->readMiscReg(FCSR) & 0x03;
+ Fd.uw = convert_and_round(Fs.ud, SINGLE_TO_DOUBLE, rnd_mode);
}});
- 0x4: cvt_w_s({{ int rnd_mode = xc->readMiscReg(FCSR);
- Fd = convert_and_round(Fs.sf,rnd_mode,FP_WORD,FP_SINGLE);
+ 0x4: cvt_w_s({{
+ int rnd_mode = xc->readMiscReg(FCSR) & 0x03;
+ Fd.uw = convert_and_round(Fs.uw, SINGLE_TO_WORD, rnd_mode);
}});
}
//only legal for 64 bit
format Float64Op {
- 0x5: cvt_l_s({{ int rnd_mode = xc->readMiscReg(FCSR);
- Fd = convert_and_round(Fs.sf,rnd_mode,FP_LONG,FP_SINGLE);
+ 0x5: cvt_l_s({{
+ int rnd_mode = xc->readMiscReg(FCSR) & 0x03;
+ Fd.uw = convert_and_round(Fs.ud, SINGLE_TO_LONG, rnd_mode);
}});
- 0x6: cvt_ps_s({{ /*Fd.df = Fs.df<31:0> | Ft.df<31:0>;*/ }});
+ 0x6: cvt_ps_st({{
+ Fd.ud = (uint64_t)Fs.uw << 32 | (uint64_t)Ft.uw;
+ }});
}
}
}
//Table A-15 MIPS32 COP1 Encoding of Function Field When rs=D
- 0x1: decode RS_HI {
- 0x0: decode RS_LO {
+ 0x1: decode FUNCTION_HI {
+ 0x0: decode FUNCTION_LO {
format FloatOp {
0x0: addd({{ Fd.df = Fs.df + Ft.df;}});
0x1: subd({{ Fd.df = Fs.df - Ft.df;}});
@@ -538,24 +610,45 @@ decode OPCODE_HI default Unknown::unknown() {
}
}
- 0x1: decode RS_LO {
- //only legal for 64 bit
+ 0x1: decode FUNCTION_LO {
format Float64Op {
- 0x0: round_l_d({{ Fd = convert_and_round(Fs.df,RND_NEAREST,FP_LONG,FP_DOUBLE); }});
- 0x1: trunc_l_d({{ Fd = convert_and_round(Fs.df,RND_ZERO,FP_LONG,FP_DOUBLE);}});
- 0x2: ceil_l_d({{ Fd = convert_and_round(Fs.df,RND_UP,FP_LONG,FP_DOUBLE);}});
- 0x3: floor_l_d({{ Fd = convert_and_round(Fs.df,RND_DOWN,FP_LONG,FP_DOUBLE);}});
+ 0x0: round_l_d({{
+ Fd = convert_and_round(Fs.ud, DOUBLE_TO_LONG, RND_NEAREST);
+ }});
+
+ 0x1: trunc_l_d({{
+ Fd = convert_and_round(Fs.ud, DOUBLE_TO_LONG, RND_ZERO);
+ }});
+
+ 0x2: ceil_l_d({{
+ Fd = convert_and_round(Fs.ud, DOUBLE_TO_LONG, RND_UP);
+ }});
+
+ 0x3: floor_l_d({{
+ Fd = convert_and_round(Fs.ud, DOUBLE_TO_LONG, RND_DOWN);
+ }});
}
format FloatOp {
- 0x4: round_w_d({{ Fd = convert_and_round(Fs.df,RND_NEAREST,FP_LONG,FP_DOUBLE); }});
- 0x5: trunc_w_d({{ Fd = convert_and_round(Fs.df,RND_ZERO,FP_LONG,FP_DOUBLE); }});
- 0x6: ceil_w_d({{ Fd = convert_and_round(Fs.df,RND_UP,FP_LONG,FP_DOUBLE); }});
- 0x7: floor_w_d({{ Fd = convert_and_round(Fs.df,RND_DOWN,FP_LONG,FP_DOUBLE); }});
+ 0x4: round_w_d({{
+ Fd = convert_and_round(Fs.ud, DOUBLE_TO_WORD, RND_NEAREST);
+ }});
+
+ 0x5: trunc_w_d({{
+ Fd = convert_and_round(Fs.ud, DOUBLE_TO_WORD, RND_ZERO);
+ }});
+
+ 0x6: ceil_w_d({{
+ Fd = convert_and_round(Fs.ud, DOUBLE_TO_WORD, RND_UP);
+ }});
+
+ 0x7: floor_w_d({{
+ Fd = convert_and_round(Fs.ud, DOUBLE_TO_WORD, RND_DOWN);
+ }});
}
}
- 0x2: decode RS_LO {
+ 0x2: decode FUNCTION_LO {
0x1: decode MOVCF {
format FloatOp {
0x0: movfd({{if (xc->readMiscReg(FPCR) != CC) Fd.df = Fs.df; }});
@@ -574,24 +667,24 @@ decode OPCODE_HI default Unknown::unknown() {
}
}
- 0x4: decode RS_LO {
+ 0x4: decode FUNCTION_LO {
format FloatOp {
0x0: cvt_s_d({{
- int rnd_mode = xc->readMiscReg(FCSR);
- Fd = convert_and_round(Fs.df,rnd_mode,FP_SINGLE,FP_DOUBLE);
+ int rnd_mode = xc->readMiscReg(FCSR) & 0x03;
+ Fd = convert_and_round(Fs.ud, DOUBLE_TO_SINGLE, rnd_mode);
}});
0x4: cvt_w_d({{
- int rnd_mode = xc->readMiscReg(FCSR);
- Fd = convert_and_round(Fs.df,rnd_mode,FP_WORD,FP_DOUBLE);
+ int rnd_mode = xc->readMiscReg(FCSR) & 0x03;
+ Fd = convert_and_round(Fs.ud, DOUBLE_TO_WORD, rnd_mode);
}});
}
//only legal for 64 bit
format Float64Op {
0x5: cvt_l_d({{
- int rnd_mode = xc->readMiscReg(FCSR);
- Fd = convert_and_round(Fs.df,rnd_mode,FP_LONG,FP_DOUBLE);
+ int rnd_mode = xc->readMiscReg(FCSR) & 0x03;
+ Fd = convert_and_round(Fs.ud, DOUBLE_TO_LONG, rnd_mode);
}});
}
}
@@ -600,14 +693,14 @@ decode OPCODE_HI default Unknown::unknown() {
//Table A-16 MIPS32 COP1 Encoding of Function Field When rs=W
0x4: decode FUNCTION {
format FloatOp {
- 0x20: cvt_s({{
- int rnd_mode = xc->readMiscReg(FCSR);
- Fd = convert_and_round(Fs.df,rnd_mode,FP_SINGLE,FP_WORD);
+ 0x20: cvt_s_w({{
+ int rnd_mode = xc->readMiscReg(FCSR) & 0x03;
+ Fd = convert_and_round(Fs.uw, WORD_TO_SINGLE, rnd_mode);
}});
- 0x21: cvt_d({{
- int rnd_mode = xc->readMiscReg(FCSR);
- Fd = convert_and_round(Fs.df,rnd_mode,FP_DOUBLE,FP_WORD);
+ 0x21: cvt_d_w({{
+ int rnd_mode = xc->readMiscReg(FCSR) & 0x03;
+ Fd = convert_and_round(Fs.uw, WORD_TO_DOUBLE, rnd_mode);
}});
}
}
@@ -616,15 +709,15 @@ decode OPCODE_HI default Unknown::unknown() {
//Note: "1. Format type L is legal only if 64-bit floating point operations
//are enabled."
0x5: decode FUNCTION_HI {
- format FloatOp {
+ format Float64Op {
0x10: cvt_s_l({{
- int rnd_mode = xc->readMiscReg(FCSR);
- Fd = convert_and_round(Fs.df,rnd_mode,FP_SINGLE,FP_LONG);
+ int rnd_mode = xc->readMiscReg(FCSR) & 0x03;
+ Fd = convert_and_round(Fs.ud, LONG_TO_SINGLE, rnd_mode);
}});
0x11: cvt_d_l({{
- int rnd_mode = xc->readMiscReg(FCSR);
- Fd = convert_and_round(Fs.df,rnd_mode,FP_DOUBLE,FP_LONG);
+ int rnd_mode = xc->readMiscReg(FCSR) & 0x03;
+ Fd = convert_and_round(Fs.ud, LONG_TO_DOUBLE, rnd_mode);
}});
}
}
@@ -632,8 +725,8 @@ decode OPCODE_HI default Unknown::unknown() {
//Table A-17 MIPS64 COP1 Encoding of Function Field When rs=PS1
//Note: "1. Format type PS is legal only if 64-bit floating point operations
//are enabled. "
- 0x6: decode RS_HI {
- 0x0: decode RS_LO {
+ 0x6: decode FUNCTION_HI {
+ 0x0: decode FUNCTION_LO {
format Float64Op {
0x0: addps({{ //Must Check for Exception Here... Supposed to Operate on Upper and
//Lower Halves Independently but we take simulator shortcut
@@ -667,7 +760,7 @@ decode OPCODE_HI default Unknown::unknown() {
}
}
- 0x2: decode RS_LO {
+ 0x2: decode FUNCTION_LO {
0x1: decode MOVCF {
format Float64Op {
0x0: movfps({{if (xc->readMiscReg(FPCR) != CC) Fd = Fs;}});
@@ -682,23 +775,25 @@ decode OPCODE_HI default Unknown::unknown() {
}
- 0x4: decode RS_LO {
+ 0x4: decode FUNCTION_LO {
0x0: Float64Op::cvt_s_pu({{
- int rnd_mode = xc->readMiscReg(FCSR);
- Fd = convert_and_round(Fs.df,rnd_mode,FP_DOUBLE,FP_PS_HI);
+ int rnd_mode = xc->readMiscReg(FCSR) & 0x03;
+ Fd = convert_and_round(Fs.ud, PUPPER_TO_SINGLE, rnd_mode);
}});
}
- 0x5: decode RS_LO {
+ 0x5: decode FUNCTION_LO {
format Float64Op {
0x0: cvt_s_pl({{
- int rnd_mode = xc->readMiscReg(FCSR);
- Fd = convert_and_round(Fs.df,rnd_mode,FP_SINGLE,FP_PS_LO);
+ int rnd_mode = xc->readMiscReg(FCSR) & 0x03;
+ Fd = convert_and_round(Fs.ud, PLOWER_TO_SINGLE,
+ rnd_mode);
}});
- 0x4: pll({{ /*Fd.df = Fs<31:0> | Ft<31:0>*/}});
- 0x5: plu({{ /*Fd.df = Fs<31:0> | Ft<63:32>*/}});
- 0x6: pul({{ /*Fd.df = Fs<63:32> | Ft<31:0>*/}});
- 0x7: puu({{ /*Fd.df = Fs<63:32 | Ft<63:32>*/}});
+
+ 0x4: pll({{ Fd.ud = Fs.ud<31:0> << 32 | Ft.ud<31:0>; }});
+ 0x5: plu({{ Fd.ud = Fs.ud<31:0> << 32 | Ft.ud<63:32>;}});
+ 0x6: pul({{ Fd.ud = Fs.ud<63:32> << 32 | Ft.ud<31:0>; }});
+ 0x7: puu({{ Fd.ud = Fs.ud<63:32> << 32 | Ft.ud<63:32>;}});
}
}
}
@@ -743,24 +838,24 @@ decode OPCODE_HI default Unknown::unknown() {
//operations are enabled."
0x3: decode FUNCTION_HI {
0x0: decode FUNCTION_LO {
- format LoadMemory2 {
- 0x0: lwxc1({{ EA = Rs + Rt; }},{{ /*F_t<31:0> = Mem.sf; */}});
- 0x1: ldxc1({{ EA = Rs + Rt; }},{{ /*F_t<63:0> = Mem.df;*/ }});
- 0x5: luxc1({{ //Need to make EA<2:0> = 0
- EA = Rs + Rt;
- }},
- {{ /*F_t<31:0> = Mem.df; */}});
+ format LoadFloatMemory {
+ 0x0: lwxc1({{ /*F_t<31:0> = Mem.sf; */}}, {{ EA = Rs + Rt; }});
+ 0x1: ldxc1({{ /*F_t<63:0> = Mem.df;*/ }}, {{ EA = Rs + Rt; }});
+ 0x5: luxc1({{ /*F_t<31:0> = Mem.df; */}},
+ {{ //Need to make EA<2:0> = 0
+ EA = Rs + Rt;
+ }});
}
}
0x1: decode FUNCTION_LO {
- format StoreMemory2 {
- 0x0: swxc1({{ EA = Rs + Rt; }},{{ /*Mem.sf = Ft<31:0>; */}});
- 0x1: sdxc1({{ EA = Rs + Rt; }},{{ /*Mem.df = Ft<63:0> */}});
- 0x5: suxc1({{ //Need to make EA<2:0> = 0
- EA = Rs + Rt;
- }},
- {{ /*Mem.df = F_t<63:0>;*/}});
+ format StoreFloatMemory {
+ 0x0: swxc1({{ /*Mem.sf = Ft<31:0>; */}},{{ EA = Rs + Rt; }});
+ 0x1: sdxc1({{ /*Mem.df = Ft<63:0> */}}, {{ EA = Rs + Rt; }});
+ 0x5: suxc1({{ /*Mem.df = F_t<63:0>;*/}},
+ {{ //Need to make sure EA<2:0> = 0
+ EA = Rs + Rt;
+ }});
}
0x7: WarnUnimpl::prefx();
@@ -1180,9 +1275,9 @@ decode OPCODE_HI default Unknown::unknown() {
0x6: decode OPCODE_LO default FailUnimpl::reserved() {
0x0: FailUnimpl::ll();
- format LoadMemory {
- 0x1: lwc1({{ /*F_t<31:0> = Mem.sf; */}});
- 0x5: ldc1({{ /*F_t<63:0> = Mem.df; */}});
+ format LoadFloatMemory {
+ 0x1: lwc1({{ Ft.uw = Mem.uw; }});
+ 0x5: ldc1({{ Ft.ud = Mem.ud; }});
}
}
@@ -1190,9 +1285,9 @@ decode OPCODE_HI default Unknown::unknown() {
0x7: decode OPCODE_LO default FailUnimpl::reserved() {
0x0: FailUnimpl::sc();
- format StoreMemory {
- 0x1: swc1({{ //Mem.sf = Ft<31:0>; }});
- 0x5: sdc1({{ //Mem.df = Ft<63:0>; }});
+ format StoreFloatMemory {
+ 0x1: swc1({{ Mem.uw = Ft.uw; }});
+ 0x5: sdc1({{ Mem.ud = Ft.ud; }});
}
}
}
diff --git a/arch/mips/isa/formats/fp.isa b/arch/mips/isa/formats/fp.isa
index 34b71acf7..65b259e20 100644
--- a/arch/mips/isa/formats/fp.isa
+++ b/arch/mips/isa/formats/fp.isa
@@ -30,7 +30,7 @@ output decoder {{
}};
-// Primary format for integer operate instructions:
+// Primary format for float operate instructions:
def format FloatOp(code, *flags) {{
iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags)
header_output = BasicDeclare.subst(iop)
@@ -39,7 +39,7 @@ def format FloatOp(code, *flags) {{
exec_output = BasicExecute.subst(iop)
}};
-// Primary format for integer operate instructions:
+// Primary format for float64 operate instructions:
def format Float64Op(code, *flags) {{
iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags)
header_output = BasicDeclare.subst(iop)
diff --git a/arch/mips/isa/formats/mem.isa b/arch/mips/isa/formats/mem.isa
index df1dca4e1..e2afc7252 100644
--- a/arch/mips/isa/formats/mem.isa
+++ b/arch/mips/isa/formats/mem.isa
@@ -446,30 +446,28 @@ def format StoreMemory(memacc_code, ea_code = {{ EA = Rs + disp; }},
exec_template_base = 'Store')
}};
-def format UnalignedStore(memacc_code, postacc_code,
- ea_code = {{ EA = Rb + disp; }},
+//FP loads are offloaded to these formats for now ...
+def format LoadFloatMemory(memacc_code, ea_code = {{ EA = Rs + disp; }},
mem_flags = [], inst_flags = []) {{
(header_output, decoder_output, decode_block, exec_output) = \
LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
- postacc_code, exec_template_base = 'Store')
+ decode_template = BasicDecode,
+ exec_template_base = 'Load')
}};
-//FP loads are offloaded to these formats for now ...
-def format LoadMemory2(ea_code = {{ EA = Rs + disp; }}, memacc_code = {{ }},
- mem_flags = [], inst_flags = []) {{
+
+def format StoreFloatMemory(memacc_code, ea_code = {{ EA = Rs + disp; }},
+ mem_flags = [], inst_flags = []) {{
(header_output, decoder_output, decode_block, exec_output) = \
LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
- decode_template = LoadNopCheckDecode,
- exec_template_base = 'Load')
+ exec_template_base = 'Store')
}};
-//FP stores are offloaded to these formats for now ...
-def format StoreMemory2(ea_code = {{ EA = Rs + disp; }},memacc_code = {{ }},
- mem_flags = [], inst_flags = []) {{
+def format UnalignedStore(memacc_code, postacc_code,
+ ea_code = {{ EA = Rb + disp; }},
+ mem_flags = [], inst_flags = []) {{
(header_output, decoder_output, decode_block, exec_output) = \
LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
- decode_template = LoadNopCheckDecode,
- exec_template_base = 'Store')
+ postacc_code, exec_template_base = 'Store')
}};
-
diff --git a/arch/mips/isa/formats/util.isa b/arch/mips/isa/formats/util.isa
index dcdf46757..615160931 100644
--- a/arch/mips/isa/formats/util.isa
+++ b/arch/mips/isa/formats/util.isa
@@ -95,9 +95,6 @@ output exec {{
using namespace MipsISA;
-
-
-
/// CLEAR ALL CPU INST/EXE HAZARDS
inline void
clear_exe_inst_hazards()
@@ -126,25 +123,7 @@ output exec {{
}
#endif
- double convert_and_round(float w, int x, int y, int z)
- {
- double temp = .34000;
-
- return temp;
- }
- enum FPTypes{
- FP_SINGLE,
- FP_DOUBLE,
- FP_LONG,
- FP_PS_LO,
- FP_PS_HI,
- FP_WORD,
- RND_NEAREST,
- RND_ZERO,
- RND_UP,
- RND_DOWN
- };
}};
diff --git a/arch/mips/isa_traits.cc b/arch/mips/isa_traits.cc
index c6cfb2a0f..d23cdf367 100644
--- a/arch/mips/isa_traits.cc
+++ b/arch/mips/isa_traits.cc
@@ -33,7 +33,38 @@
using namespace MipsISA;
+uint64_t
+MipsISA::convert_and_round(uint64_t fp_val, ConvertType cvt_type, int rnd_mode)
+{
+ uint64_t ret_val = 0;
+
+ switch (cvt_type)
+ {
+ case SINGLE_TO_DOUBLE:
+ break;
+
+ case SINGLE_TO_WORD:
+ break;
+
+ case SINGLE_TO_LONG:
+ break;
+
+ case DOUBLE_TO_SINGLE:
+ break;
+
+ case LONG_TO_SINGLE:
+ break;
+
+ case WORD_TO_SINGLE:
+ break;
+
+ default:
+ panic("Invalid Floating Point Conversion type being used.\n");
+ }
+
+ return ret_val;
+}
void
MipsISA::copyRegs(ExecContext *src, ExecContext *dest)
diff --git a/arch/mips/isa_traits.hh b/arch/mips/isa_traits.hh
index 1f4ccbd90..3ea72bde2 100644
--- a/arch/mips/isa_traits.hh
+++ b/arch/mips/isa_traits.hh
@@ -30,8 +30,10 @@
#define __ARCH_MIPS_ISA_TRAITS_HH__
//#include "arch/mips/misc_regfile.hh"
+#include "arch/mips/faults.hh"
#include "base/misc.hh"
#include "config/full_system.hh"
+#include "sim/byteswap.hh"
#include "sim/host.hh"
#include "sim/faults.hh"
@@ -105,7 +107,7 @@ namespace MipsISA
const int NumPALShadowRegs = 8;
const int NumFloatArchRegs = 32;
// @todo: Figure out what this number really should be.
- const int NumMiscArchRegs = 32;
+ const int NumMiscArchRegs = 265;
const int NumIntRegs = NumIntArchRegs + NumPALShadowRegs;
const int NumFloatRegs = NumFloatArchRegs;
@@ -189,63 +191,166 @@ namespace MipsISA
typedef double FloatReg;
typedef uint64_t FloatRegBits;
+
+ const int SingleWidth = 32;
+ const int SingleBytes = SingleWidth / 4;
+
+ const int DoubleWidth = 64;
+ const int DoubleBytes = DoubleWidth / 4;
+
+ const int QuadWidth = 128;
+ const int QuadBytes = QuadWidth / 4;
+
+ const int FloatRegSize = SingleWidth / SingleBytes;
+ const int DoubleRegSize = FloatRegSize * 2;
+
class FloatRegFile
{
protected:
- FloatRegBits q[NumFloatRegs]; // integer qword view
- double d[NumFloatRegs]; // double-precision floating point view
+ //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[FloatRegSize * NumFloatRegs];
public:
- FloatReg readReg(int floatReg)
+ void clear()
{
- return d[floatReg];
+ bzero(regSpace, sizeof(regSpace));
}
FloatReg readReg(int floatReg, int width)
{
- return readReg(floatReg);
- }
+ //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:
+ float result32;
+ memcpy(&result32, regSpace + 4 * floatReg, FloatRegSize);
+ return htog(result32);
- FloatRegBits readRegBits(int floatReg)
- {
- return q[floatReg];
+ case DoubleWidth:
+ double result64;
+ memcpy(&result64, regSpace + 4 * floatReg, DoubleRegSize);
+ return htog(result64);
+
+ default:
+ panic("Attempted to read a %d bit floating point register!", width);
+ }
}
FloatRegBits readRegBits(int floatReg, int width)
{
- return readRegBits(floatReg);
- }
+ //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, FloatRegSize);
+ return htog(result32);
- Fault setReg(int floatReg, const FloatReg &val)
- {
- d[floatReg] = val;
- return NoFault;
- }
+ case DoubleWidth:
+ uint64_t result64;
+ memcpy(&result64, regSpace + 4 * floatReg, DoubleRegSize);
+ return htog(result64);
- Fault setReg(int floatReg, const FloatReg &val, int width)
- {
- return setReg(floatReg, val);
+ default:
+ panic("Attempted to read a %d bit floating point register!", width);
+ }
}
- Fault setRegBits(int floatReg, const FloatRegBits &val)
+ Fault setReg(int floatReg, const FloatReg &val, int width)
{
- q[floatReg] = val;
+ //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;
+ result32 = gtoh((uint32_t)val);
+ memcpy(regSpace + 4 * floatReg, &result32, FloatRegSize);
+ break;
+
+ case DoubleWidth:
+ uint64_t result64;
+ result64 = gtoh((uint64_t)val);
+ memcpy(regSpace + 4 * floatReg, &result64, DoubleRegSize);
+ break;
+
+
+ default:
+ panic("Attempted to read a %d bit floating point register!", width);
+ }
return NoFault;
}
Fault setRegBits(int floatReg, const FloatRegBits &val, int width)
{
- return setRegBits(floatReg, val);
+ //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;
+ result32 = gtoh((uint32_t)val);
+ memcpy(regSpace + 4 * floatReg, &result32, FloatRegSize);
+ break;
+
+ case DoubleWidth:
+ uint64_t result64;
+ result64 = gtoh((uint64_t)val);
+ memcpy(regSpace + 4 * floatReg, &result64, DoubleRegSize);
+ break;
+
+ default:
+ panic("Attempted to read a %d bit floating point register!", width);
+ }
+ return NoFault;
}
void serialize(std::ostream &os);
void unserialize(Checkpoint *cp, const std::string &section);
-
};
+ enum ConvertType{
+ SINGLE_TO_DOUBLE,
+ SINGLE_TO_WORD,
+ SINGLE_TO_LONG,
+
+ DOUBLE_TO_SINGLE,
+ DOUBLE_TO_WORD,
+ DOUBLE_TO_LONG,
+
+ LONG_TO_SINGLE,
+ LONG_TO_DOUBLE,
+ LONG_TO_WORD,
+
+ WORD_TO_SINGLE,
+ WORD_TO_DOUBLE,
+ WORD_TO_LONG,
+
+ PLOWER_TO_SINGLE,
+ PUPPER_TO_SINGLE
+ };
+
+ enum RoundMode{
+ RND_ZERO,
+ RND_DOWN,
+ RND_UP,
+ RND_NEAREST
+ };
+
+ uint64_t convert_and_round(uint64_t fp_val,ConvertType cvt_type, int rnd_mode = 0);
+
+
void copyRegs(ExecContext *src, ExecContext *dest);
// cop-0/cop-1 system control register file
@@ -532,44 +637,45 @@ extern const Addr PageOffset;
return miscRegFile.setRegWithEffect(miscReg, val, xc);
}
+
FloatReg readFloatReg(int floatReg)
{
- return floatRegFile.readReg(floatReg);
+ return floatRegFile.readReg(floatReg,SingleWidth);
}
FloatReg readFloatReg(int floatReg, int width)
{
- return readFloatReg(floatReg);
+ return floatRegFile.readReg(floatReg,width);
}
FloatRegBits readFloatRegBits(int floatReg)
{
- return floatRegFile.readRegBits(floatReg);
+ return floatRegFile.readRegBits(floatReg,SingleWidth);
}
FloatRegBits readFloatRegBits(int floatReg, int width)
{
- return readFloatRegBits(floatReg);
+ return floatRegFile.readRegBits(floatReg,width);
}
Fault setFloatReg(int floatReg, const FloatReg &val)
{
- return floatRegFile.setReg(floatReg, val);
+ return floatRegFile.setReg(floatReg, val, SingleWidth);
}
Fault setFloatReg(int floatReg, const FloatReg &val, int width)
{
- return setFloatReg(floatReg, val);
+ return floatRegFile.setReg(floatReg, val, width);
}
Fault setFloatRegBits(int floatReg, const FloatRegBits &val)
{
- return floatRegFile.setRegBits(floatReg, val);
+ return floatRegFile.setRegBits(floatReg, val, SingleWidth);
}
Fault setFloatRegBits(int floatReg, const FloatRegBits &val, int width)
{
- return setFloatRegBits(floatReg, val);
+ return floatRegFile.setRegBits(floatReg, val, width);
}
IntReg readIntReg(int intReg)
diff --git a/arch/sparc/SConscript b/arch/sparc/SConscript
index 172e4390f..fd0df9349 100644
--- a/arch/sparc/SConscript
+++ b/arch/sparc/SConscript
@@ -57,6 +57,7 @@ full_system_sources = Split('''
# Syscall emulation (non-full-system) sources
syscall_emulation_sources = Split('''
+ linux/linux.cc
linux/process.cc
process.cc
''')
diff --git a/arch/sparc/isa/decoder.isa b/arch/sparc/isa/decoder.isa
index 823bf2626..ca409fa66 100644
--- a/arch/sparc/isa/decoder.isa
+++ b/arch/sparc/isa/decoder.isa
@@ -16,16 +16,22 @@ decode OP default Unknown::unknown()
0x0: bpcci({{
if(passesCondition(CcrIcc, COND2))
NNPC = xc->readPC() + disp;
+ else
+ handle_annul
}});
0x2: bpccx({{
if(passesCondition(CcrXcc, COND2))
NNPC = xc->readPC() + disp;
+ else
+ handle_annul
}});
}
}
0x2: Branch22::bicc({{
if(passesCondition(CcrIcc, COND2))
NNPC = xc->readPC() + disp;
+ else
+ handle_annul
}});
0x3: decode RCOND2
{
@@ -34,26 +40,38 @@ decode OP default Unknown::unknown()
0x1: bpreq({{
if(Rs1 == 0)
NNPC = xc->readPC() + disp;
+ else
+ handle_annul
}});
0x2: bprle({{
if(Rs1 <= 0)
NNPC = xc->readPC() + disp;
+ else
+ handle_annul
}});
0x3: bprl({{
if(Rs1 < 0)
NNPC = xc->readPC() + disp;
+ else
+ handle_annul
}});
0x5: bprne({{
if(Rs1 != 0)
NNPC = xc->readPC() + disp;
+ else
+ handle_annul
}});
0x6: bprg({{
if(Rs1 > 0)
NNPC = xc->readPC() + disp;
+ else
+ handle_annul
}});
0x7: bprge({{
if(Rs1 >= 0)
NNPC = xc->readPC() + disp;
+ else
+ handle_annul
}});
}
}
@@ -109,7 +127,7 @@ decode OP default Unknown::unknown()
if(Rd.udw<63:31> != 0)
Rd.udw = 0x7FFFFFFF;
else if(Rd.udw<63:> && Rd.udw<62:31> != 0xFFFFFFFF)
- Rd.udw = 0xFFFFFFFF80000000;
+ Rd.udw = 0xFFFFFFFF80000000ULL;
}
}});
}
@@ -117,22 +135,22 @@ decode OP default Unknown::unknown()
0x10: addcc({{
int64_t resTemp, val2 = Rs2_or_imm13;
Rd = resTemp = Rs1 + val2;}},
- {{((Rs1 & 0xFFFFFFFF + val2 & 0xFFFFFFFF) >> 31)}},
+ {{(Rs1<31:0> + val2<31:0>)<32:>}},
{{Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>}},
- {{((Rs1 >> 1) + (val2 >> 1) + (Rs1 & val2 & 0x1))<63:>}},
+ {{(Rs1<63:1> + val2<63:1> + (Rs1 & val2)<0:>)<63:>}},
{{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}}
);
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 = Rs2_or_imm13;
- Rd = resTemp = Rs1 - val2;}},
- {{((Rs1 & 0xFFFFFFFF - val2 & 0xFFFFFFFF) >> 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:>}}
+ int64_t val2 = Rs2_or_imm13;
+ Rd = Rs1 - val2;}},
+ {{(~(Rs1<31:0> + (~val2)<31:0> + 1))<32:>}},
+ {{(Rs1<31:> != val2<31:>) && (Rs1<31:> != Rd<31:>)}},
+ {{(~(Rs1<63:1> + (~val2)<63:1> +
+ (Rs1 | ~val2)<0:>))<63:>}},
+ {{Rs1<63:> != val2<63:> && Rs1<63:> != Rd<63:>}}
);
0x15: IntOpCcRes::andncc({{Rd = Rs1 & ~Rs2_or_imm13;}});
0x16: IntOpCcRes::orncc({{Rd = Rs1 | ~Rs2_or_imm13;}});
@@ -141,11 +159,10 @@ decode OP default Unknown::unknown()
int64_t resTemp, val2 = Rs2_or_imm13;
int64_t carryin = CcrIccC;
Rd = resTemp = Rs1 + val2 + carryin;}},
- {{((Rs1 & 0xFFFFFFFF + val2 & 0xFFFFFFFF) >> 31
- + carryin)}},
+ {{(Rs1<31:0> + val2<31:0> + carryin)<32:>}},
{{Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>}},
- {{((Rs1 >> 1) + (val2 >> 1) +
- ((Rs1 & val2) | (carryin & (Rs1 | val2)) & 0x1))<63:>}},
+ {{(Rs1<63:1> + val2<63:1> +
+ ((Rs1 & val2) | (carryin & (Rs1 | val2)))<0:>)<63:>}},
{{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}}
);
0x1A: umulcc({{
@@ -162,9 +179,9 @@ decode OP default Unknown::unknown()
int64_t resTemp, val2 = Rs2_or_imm13;
int64_t carryin = CcrIccC;
Rd = resTemp = Rs1 + ~(val2 + carryin) + 1;}},
- {{((Rs1 & 0xFFFFFFFF + (~(val2 + carryin)) & 0xFFFFFFFF + 1) >> 31)}},
+ {{(~((Rs1<31:0> + (~(val2 + carryin))<31:0> + 1))<32:>)}},
{{Rs1<31:> != val2<31:> && Rs1<31:> != resTemp<31:>}},
- {{(((Rs1 >> 1) + (~(val2 + carryin)) >> 1) + ((Rs1 | ~(val2+carryin)) & 0x1))<63:>}},
+ {{(~((Rs1<63:1> + (~(val2 + carryin))<63:1>) + (Rs1<0:> + (~(val2+carryin))<0:> + 1)<63:1>))<63:>}},
{{Rs1<63:> != val2<63:> && Rs1<63:> != resTemp<63:>}}
);
0x1D: udivxcc({{
@@ -197,7 +214,7 @@ decode OP default Unknown::unknown()
overflow = (resTemp<63:31> != 0);
underflow = (resTemp<63:> && resTemp<62:31> != 0xFFFFFFFF);
if(overflow) Rd = resTemp = 0x7FFFFFFF;
- else if(underflow) Rd = resTemp = 0xFFFFFFFF80000000;
+ else if(underflow) Rd = resTemp = 0xFFFFFFFF80000000ULL;
else Rd = resTemp;
} }},
{{0}},
diff --git a/arch/sparc/isa/formats/branch.isa b/arch/sparc/isa/formats/branch.isa
index b76f7a9f6..37bdb9402 100644
--- a/arch/sparc/isa/formats/branch.isa
+++ b/arch/sparc/isa/formats/branch.isa
@@ -194,7 +194,7 @@ output decoder {{
{
ccprintf(response, " <%s", symbol);
if(symbolAddr != target)
- ccprintf(response, "+0x%x>", target - symbolAddr);
+ ccprintf(response, "+%d>", target - symbolAddr);
else
ccprintf(response, ">");
}
@@ -226,8 +226,25 @@ def template BranchExecute {{
}
}};
+let {{
+ handle_annul = '''
+ {
+ if(A)
+ {
+ NPC = xc->readNextNPC();
+ NNPC = NPC + 4;
+ }
+ else
+ {
+ NPC = xc->readNextPC();
+ NNPC = xc->readNextNPC();
+ }
+ }'''
+}};
+
// Primary format for branch instructions:
def format Branch(code, *opt_flags) {{
+ code = re.sub(r'handle_annul', handle_annul, code)
(usesImm, code, immCode,
rString, iString) = splitOutImm(code)
iop = InstObjParams(name, Name, 'Branch', code, opt_flags)
@@ -247,6 +264,7 @@ def format Branch(code, *opt_flags) {{
// Primary format for branch instructions:
def format Branch19(code, *opt_flags) {{
+ code = re.sub(r'handle_annul', handle_annul, code)
codeBlk = CodeBlock(code)
iop = InstObjParams(name, Name, 'Branch19', codeBlk, opt_flags)
header_output = BasicDeclare.subst(iop)
@@ -257,6 +275,7 @@ def format Branch19(code, *opt_flags) {{
// Primary format for branch instructions:
def format Branch22(code, *opt_flags) {{
+ code = re.sub(r'handle_annul', handle_annul, code)
codeBlk = CodeBlock(code)
iop = InstObjParams(name, Name, 'Branch22', codeBlk, opt_flags)
header_output = BasicDeclare.subst(iop)
@@ -267,6 +286,7 @@ def format Branch22(code, *opt_flags) {{
// Primary format for branch instructions:
def format Branch30(code, *opt_flags) {{
+ code = re.sub(r'handle_annul', handle_annul, code)
codeBlk = CodeBlock(code)
iop = InstObjParams(name, Name, 'Branch30', codeBlk, opt_flags)
header_output = BasicDeclare.subst(iop)
@@ -277,6 +297,7 @@ def format Branch30(code, *opt_flags) {{
// Primary format for branch instructions:
def format BranchSplit(code, *opt_flags) {{
+ code = re.sub(r'handle_annul', handle_annul, code)
codeBlk = CodeBlock(code)
iop = InstObjParams(name, Name, 'BranchSplit', codeBlk, opt_flags)
header_output = BasicDeclare.subst(iop)
diff --git a/arch/sparc/isa/formats/integerop.isa b/arch/sparc/isa/formats/integerop.isa
index 401af2e51..407a3e3cd 100644
--- a/arch/sparc/isa/formats/integerop.isa
+++ b/arch/sparc/isa/formats/integerop.isa
@@ -271,14 +271,22 @@ let {{
return (header_output, decoder_output, exec_output, decode_block)
calcCcCode = '''
- CcrIccN = (Rd >> 63) & 1;
- CcrIccZ = (Rd == 0);
- CcrXccN = (Rd >> 31) & 1;
- CcrXccZ = ((Rd & 0xFFFFFFFF) == 0);
+ CcrIccN = (Rd >> 31) & 1;
+ CcrIccZ = ((Rd & 0xFFFFFFFF) == 0);
+ CcrXccN = (Rd >> 63) & 1;
+ CcrXccZ = (Rd == 0);
CcrIccV = %(ivValue)s;
CcrIccC = %(icValue)s;
CcrXccV = %(xvValue)s;
CcrXccC = %(xcValue)s;
+ DPRINTF(Sparc, "in = %%d\\n", CcrIccN);
+ DPRINTF(Sparc, "iz = %%d\\n", CcrIccZ);
+ DPRINTF(Sparc, "xn = %%d\\n", CcrXccN);
+ DPRINTF(Sparc, "xz = %%d\\n", CcrXccZ);
+ DPRINTF(Sparc, "iv = %%d\\n", CcrIccV);
+ DPRINTF(Sparc, "ic = %%d\\n", CcrIccC);
+ DPRINTF(Sparc, "xv = %%d\\n", CcrXccV);
+ DPRINTF(Sparc, "xc = %%d\\n", CcrXccC);
'''
}};
diff --git a/arch/sparc/isa/formats/mem.isa b/arch/sparc/isa/formats/mem.isa
index e15349c7b..ab8b85a94 100644
--- a/arch/sparc/isa/formats/mem.isa
+++ b/arch/sparc/isa/formats/mem.isa
@@ -104,6 +104,7 @@ def template MemExecute {{
%(op_decl)s;
%(op_rd)s;
%(ea_code)s;
+ DPRINTF(Sparc, "The address is 0x%x\n", EA);
%(load)s;
%(code)s;
%(store)s;
diff --git a/arch/sparc/linux/linux.cc b/arch/sparc/linux/linux.cc
new file mode 100644
index 000000000..c7ed29358
--- /dev/null
+++ b/arch/sparc/linux/linux.cc
@@ -0,0 +1,68 @@
+/*
+ * 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.
+ */
+
+#include "arch/sparc/linux/linux.hh"
+
+// open(2) flags translation table
+OpenFlagTransTable SparcLinux::openFlagTable[] = {
+#ifdef _MSC_VER
+ { SparcLinux::TGT_O_RDONLY, _O_RDONLY },
+ { SparcLinux::TGT_O_WRONLY, _O_WRONLY },
+ { SparcLinux::TGT_O_RDWR, _O_RDWR },
+ { SparcLinux::TGT_O_APPEND, _O_APPEND },
+ { SparcLinux::TGT_O_CREAT, _O_CREAT },
+ { SparcLinux::TGT_O_TRUNC, _O_TRUNC },
+ { SparcLinux::TGT_O_EXCL, _O_EXCL },
+#ifdef _O_NONBLOCK
+ { SparcLinux::TGT_O_NONBLOCK, _O_NONBLOCK },
+#endif
+#ifdef _O_NOCTTY
+ { SparcLinux::TGT_O_NOCTTY, _O_NOCTTY },
+#endif
+#ifdef _O_SYNC
+ { SparcLinux::TGT_O_SYNC, _O_SYNC },
+#endif
+#else /* !_MSC_VER */
+ { SparcLinux::TGT_O_RDONLY, O_RDONLY },
+ { SparcLinux::TGT_O_WRONLY, O_WRONLY },
+ { SparcLinux::TGT_O_RDWR, O_RDWR },
+ { SparcLinux::TGT_O_APPEND, O_APPEND },
+ { SparcLinux::TGT_O_CREAT, O_CREAT },
+ { SparcLinux::TGT_O_TRUNC, O_TRUNC },
+ { SparcLinux::TGT_O_EXCL, O_EXCL },
+ { SparcLinux::TGT_O_NONBLOCK, O_NONBLOCK },
+ { SparcLinux::TGT_O_NOCTTY, O_NOCTTY },
+#ifdef O_SYNC
+ { SparcLinux::TGT_O_SYNC, O_SYNC },
+#endif
+#endif /* _MSC_VER */
+};
+
+const int SparcLinux::NUM_OPEN_FLAGS =
+ (sizeof(SparcLinux::openFlagTable)/sizeof(SparcLinux::openFlagTable[0]));
+
diff --git a/arch/sparc/linux/linux.hh b/arch/sparc/linux/linux.hh
new file mode 100644
index 000000000..1b31f67b0
--- /dev/null
+++ b/arch/sparc/linux/linux.hh
@@ -0,0 +1,61 @@
+/*
+ * 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 __MIPS_MIPS_LINUX_HH
+#define __MIPS_MIPS_LINUX_HH
+
+#include "kern/linux/linux.hh"
+
+class SparcLinux : public Linux
+{
+ public:
+
+ static OpenFlagTransTable openFlagTable[];
+
+ static const int TGT_O_RDONLY = 0x00000000; //!< O_RDONLY
+ static const int TGT_O_WRONLY = 0x00000001; //!< O_WRONLY
+ static const int TGT_O_RDWR = 0x00000002; //!< O_RDWR
+ static const int TGT_O_NONBLOCK = 0x00004000; //!< O_NONBLOCK
+ static const int TGT_O_APPEND = 0x00000008; //!< O_APPEND
+ static const int TGT_O_CREAT = 0x00000200; //!< O_CREAT
+ static const int TGT_O_TRUNC = 0x00000400; //!< O_TRUNC
+ static const int TGT_O_EXCL = 0x00000800; //!< O_EXCL
+ static const int TGT_O_NOCTTY = 0x00008000; //!< O_NOCTTY
+ static const int TGT_O_SYNC = 0x00002000; //!< O_SYNC
+// static const int TGT_O_DRD = 0x00010000; //!< O_DRD
+// static const int TGT_O_DIRECTIO = 0x00020000; //!< O_DIRECTIO
+// static const int TGT_O_CACHE = 0x00002000; //!< O_CACHE
+// static const int TGT_O_DSYNC = 0x00008000; //!< O_DSYNC
+// static const int TGT_O_RSYNC = 0x00040000; //!< O_RSYNC
+
+ static const int NUM_OPEN_FLAGS;
+
+ static const unsigned TGT_MAP_ANONYMOUS = 0x20;
+};
+
+#endif
diff --git a/arch/sparc/linux/process.cc b/arch/sparc/linux/process.cc
index ca85a6d2d..4818f1fcc 100644
--- a/arch/sparc/linux/process.cc
+++ b/arch/sparc/linux/process.cc
@@ -98,7 +98,7 @@ SyscallDesc SparcLinuxProcess::syscallDescs[] = {
/* 2 */ SyscallDesc("fork", unimplementedFunc),
/* 3 */ SyscallDesc("read", readFunc),
/* 4 */ SyscallDesc("write", writeFunc),
- /* 5 */ SyscallDesc("open", openFunc<Linux>),
+ /* 5 */ SyscallDesc("open", openFunc<SparcLinux>),
/* 6 */ SyscallDesc("close", closeFunc),
/* 7 */ SyscallDesc("wait4", unimplementedFunc),
/* 8 */ SyscallDesc("creat", unimplementedFunc),
@@ -164,9 +164,9 @@ SyscallDesc SparcLinuxProcess::syscallDescs[] = {
/* 68 */ SyscallDesc("pwrite64", unimplementedFunc),
/* 69 */ SyscallDesc("geteuid32", unimplementedFunc),
/* 70 */ SyscallDesc("getdgid32", unimplementedFunc),
- /* 71 */ SyscallDesc("mmap", unimplementedFunc),
+ /* 71 */ SyscallDesc("mmap", mmapFunc<SparcLinux>),
/* 72 */ SyscallDesc("setreuid32", unimplementedFunc),
- /* 73 */ SyscallDesc("munmap", unimplementedFunc),
+ /* 73 */ SyscallDesc("munmap", munmapFunc),
/* 74 */ SyscallDesc("mprotect", unimplementedFunc),
/* 75 */ SyscallDesc("madvise", unimplementedFunc),
/* 76 */ SyscallDesc("vhangup", unimplementedFunc),
diff --git a/arch/sparc/linux/process.hh b/arch/sparc/linux/process.hh
index 38ddd68b9..23ce66d02 100644
--- a/arch/sparc/linux/process.hh
+++ b/arch/sparc/linux/process.hh
@@ -29,6 +29,7 @@
#ifndef __SPARC_LINUX_PROCESS_HH__
#define __SPARC_LINUX_PROCESS_HH__
+#include "arch/sparc/linux/linux.hh"
#include "arch/sparc/process.hh"
#include "sim/process.hh"
diff --git a/arch/sparc/process.cc b/arch/sparc/process.cc
index 44f2c5984..7f2b0d40a 100644
--- a/arch/sparc/process.cc
+++ b/arch/sparc/process.cc
@@ -54,7 +54,7 @@ SparcLiveProcess::create(const std::string &nm, System *system, int stdin_fd,
if (objFile->getArch() != ObjectFile::SPARC)
- fatal("Object file does not match architecture.");
+ fatal("Object file with arch %x does not match architecture %x.", objFile->getArch(), ObjectFile::SPARC);
switch (objFile->getOpSys()) {
case ObjectFile::Linux:
process = new SparcLinuxProcess(nm, objFile, system,
@@ -85,11 +85,11 @@ SparcLiveProcess::SparcLiveProcess(const std::string &nm, ObjectFile *objFile,
// Set up stack. On SPARC Linux, stack goes from the top of memory
// downward, less the hole for the kernel address space.
- stack_base = ((Addr)0x80000000000);
+ stack_base = ((Addr)0x80000000000ULL);
// Set up region for mmaps. Tru64 seems to start just above 0 and
// grow up from there.
- mmap_start = mmap_end = 0x10000;
+ mmap_start = mmap_end = 0x800000;
// Set pointer for next thread stack. Reserve 8M for main stack.
next_thread_stack_base = stack_base - (8 * 1024 * 1024);
@@ -135,6 +135,14 @@ SparcLiveProcess::startup()
execContexts[0]->setMiscRegWithEffect(MISCREG_CWP, 0);
}
+m5_auxv_t buildAuxVect(int64_t type, int64_t val)
+{
+ m5_auxv_t result;
+ result.a_type = TheISA::htog(type);
+ result.a_val = TheISA::htog(val);
+ return result;
+}
+
void
SparcLiveProcess::argsInit(int intSize, int pageSize)
{
@@ -145,10 +153,75 @@ SparcLiveProcess::argsInit(int intSize, int pageSize)
// load object file into target memory
objFile->loadSections(initVirtMem);
+ //These are the auxilliary vector types
+ enum auxTypes
+ {
+ SPARC_AT_HWCAP = 16,
+ SPARC_AT_PAGESZ = 6,
+ SPARC_AT_CLKTCK = 17,
+ SPARC_AT_PHDR = 3,
+ SPARC_AT_PHENT = 4,
+ SPARC_AT_PHNUM = 5,
+ SPARC_AT_BASE = 7,
+ SPARC_AT_FLAGS = 8,
+ SPARC_AT_ENTRY = 9,
+ SPARC_AT_UID = 11,
+ SPARC_AT_EUID = 12,
+ SPARC_AT_GID = 13,
+ SPARC_AT_EGID = 14
+ };
+
+ enum hardwareCaps
+ {
+ M5_HWCAP_SPARC_FLUSH = 1,
+ M5_HWCAP_SPARC_STBAR = 2,
+ M5_HWCAP_SPARC_SWAP = 4,
+ M5_HWCAP_SPARC_MULDIV = 8,
+ M5_HWCAP_SPARC_V9 = 16,
+ //This one should technically only be set
+ //if there is a cheetah or cheetah_plus tlb,
+ //but we'll use it all the time
+ M5_HWCAP_SPARC_ULTRA3 = 32
+ };
+
+ const int64_t hwcap =
+ M5_HWCAP_SPARC_FLUSH |
+ M5_HWCAP_SPARC_STBAR |
+ M5_HWCAP_SPARC_SWAP |
+ M5_HWCAP_SPARC_MULDIV |
+ M5_HWCAP_SPARC_V9 |
+ M5_HWCAP_SPARC_ULTRA3;
+
+ //Setup the auxilliary vectors. These will already have
+ //endian conversion.
+ auxv.push_back(buildAuxVect(SPARC_AT_EGID, 100));
+ auxv.push_back(buildAuxVect(SPARC_AT_GID, 100));
+ auxv.push_back(buildAuxVect(SPARC_AT_EUID, 100));
+ auxv.push_back(buildAuxVect(SPARC_AT_UID, 100));
+ //This would work, but the entry point is a protected member
+ //auxv.push_back(buildAuxVect(SPARC_AT_ENTRY, objFile->entry));
+ auxv.push_back(buildAuxVect(SPARC_AT_FLAGS, 0));
+ //This is the address of the elf "interpreter", which I don't
+ //think we currently set up. It should be set to 0 (I think)
+ //auxv.push_back(buildAuxVect(SPARC_AT_BASE, 0));
+ //This is the number of headers which were in the original elf
+ //file. This information isn't avaibale by this point.
+ //auxv.push_back(buildAuxVect(SPARC_AT_PHNUM, 3));
+ //This is the size of a program header entry. This isn't easy
+ //to compute here.
+ //auxv.push_back(buildAuxVect(SPARC_AT_PHENT, blah));
+ //This is should be set to load_addr (whatever that is) +
+ //e_phoff. I think it's a pointer to the program headers.
+ //auxv.push_back(buildAuxVect(SPARC_AT_PHDR, blah));
+ //This should be easy to get right, but I won't set it for now
+ //auxv.push_back(buildAuxVect(SPARC_AT_CLKTCK, blah));
+ auxv.push_back(buildAuxVect(SPARC_AT_PAGESZ, SparcISA::VMPageSize));
+ auxv.push_back(buildAuxVect(SPARC_AT_HWCAP, hwcap));
+
//Figure out how big the initial stack needs to be
- int aux_data_size = 0;
- //Figure out the aux_data_size?
+ //Each auxilliary vector is two 8 byte words
+ int aux_data_size = 2 * intSize * auxv.size();
int env_data_size = 0;
for (int i = 0; i < envp.size(); ++i) {
env_data_size += envp[i].size() + 1;
@@ -198,8 +271,8 @@ SparcLiveProcess::argsInit(int intSize, int pageSize)
Addr aux_data_base = stack_base - aux_data_size - info_block_padding;
Addr env_data_base = aux_data_base - env_data_size;
Addr arg_data_base = env_data_base - arg_data_size;
- Addr aux_array_base = arg_data_base - aux_array_size;
- Addr envp_array_base = aux_array_base - envp_array_size;
+ Addr auxv_array_base = arg_data_base - aux_array_size;
+ Addr envp_array_base = auxv_array_base - envp_array_size;
Addr argv_array_base = envp_array_base - argv_array_size;
Addr argc_base = argv_array_base - argc_size;
Addr window_save_base = argc_base - window_save_size;
@@ -208,24 +281,34 @@ SparcLiveProcess::argsInit(int intSize, int pageSize)
DPRINTF(Sparc, "0x%x - aux data\n", aux_data_base);
DPRINTF(Sparc, "0x%x - env data\n", env_data_base);
DPRINTF(Sparc, "0x%x - arg data\n", arg_data_base);
- DPRINTF(Sparc, "0x%x - aux array\n", aux_array_base);
- DPRINTF(Sparc, "0x%x - env array\n", envp_array_base);
- DPRINTF(Sparc, "0x%x - arg array\n", argv_array_base);
+ DPRINTF(Sparc, "0x%x - auxv array\n", auxv_array_base);
+ DPRINTF(Sparc, "0x%x - envp array\n", envp_array_base);
+ DPRINTF(Sparc, "0x%x - argv array\n", argv_array_base);
DPRINTF(Sparc, "0x%x - argc \n", argc_base);
DPRINTF(Sparc, "0x%x - window save\n", window_save_base);
DPRINTF(Sparc, "0x%x - stack min\n", stack_min);
// write contents to stack
uint64_t argc = argv.size();
-
- //Copy the aux stuff? For now just put in the null vect
+ uint64_t guestArgc = TheISA::htog(argc);
+
+ //Copy the aux stuff
+ for(int x = 0; x < auxv.size(); x++)
+ {
+ initVirtMem->writeBlob(auxv_array_base + x * 2 * intSize,
+ (uint8_t*)&(auxv[x].a_type), intSize);
+ initVirtMem->writeBlob(auxv_array_base + (x * 2 + 1) * intSize,
+ (uint8_t*)&(auxv[x].a_val), intSize);
+ }
+ //Write out the terminating zeroed auxilliary vector
const uint64_t zero = 0;
- initVirtMem->writeBlob(aux_array_base, (uint8_t*)&zero, 2 * intSize);
+ initVirtMem->writeBlob(auxv_array_base + 2 * intSize * auxv.size(),
+ (uint8_t*)&zero, 2 * intSize);
copyStringArray(envp, envp_array_base, env_data_base, initVirtMem);
copyStringArray(argv, argv_array_base, arg_data_base, initVirtMem);
- initVirtMem->writeBlob(argc_base, (uint8_t*)&argc, intSize);
+ initVirtMem->writeBlob(argc_base, (uint8_t*)&guestArgc, intSize);
execContexts[0]->setIntReg(ArgumentReg0, argc);
execContexts[0]->setIntReg(ArgumentReg1, argv_array_base);
diff --git a/arch/sparc/process.hh b/arch/sparc/process.hh
index 7b2aec7b9..c177f20a5 100644
--- a/arch/sparc/process.hh
+++ b/arch/sparc/process.hh
@@ -36,18 +36,19 @@
class ObjectFile;
class System;
+typedef struct
+{
+ int64_t a_type;
+ union {
+ int64_t a_val;
+ Addr a_ptr;
+ Addr a_fcn;
+ };
+} m5_auxv_t;
+
class SparcLiveProcess : public LiveProcess
{
protected:
- typedef struct
- {
- int64_t a_type;
- union {
- int64_t a_val;
- Addr a_ptr;
- Addr a_fcn;
- };
- } m5_auxv_t;
static const Addr StackBias = 2047;
diff --git a/configs/test/hello_sparc b/configs/test/hello_sparc
index 7b7302771..e254ae33f 100755
--- a/configs/test/hello_sparc
+++ b/configs/test/hello_sparc
Binary files differ
diff --git a/cpu/simple/cpu.cc b/cpu/simple/cpu.cc
index 40b506a78..be34d1791 100644
--- a/cpu/simple/cpu.cc
+++ b/cpu/simple/cpu.cc
@@ -480,7 +480,7 @@ SimpleCPU::read(Addr addr, T &data, unsigned flags)
// Fault fault = xc->read(memReq,data);
// Not sure what to check for no fault...
if (data_read_pkt->result == Success) {
- data = data_read_pkt->get<T>();
+ data = gtoh(data_read_pkt->get<T>());
}
if (traceData) {
@@ -523,7 +523,7 @@ SimpleCPU::read(Addr addr, T &data, unsigned flags)
// Need to find a way to not duplicate code above.
if (data_read_pkt->result == Success) {
- data = data_read_pkt->get<T>();
+ data = gtoh(data_read_pkt->get<T>());
}
if (traceData) {
@@ -627,10 +627,12 @@ SimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
data_write_pkt = new Packet;
data_write_pkt->cmd = Write;
data_write_pkt->req = data_write_req;
+ T hostData = htog(data);
data_write_pkt->allocate();
- data_write_pkt->set(data);
+ data_write_pkt->set(hostData);
#else
data_write_pkt->reset();
+ data = htog(data);
data_write_pkt->dataStatic(&data);
#endif
data_write_pkt->addr = data_write_req->getPaddr();