diff options
Diffstat (limited to 'arch')
-rwxr-xr-x | arch/isa_parser.py | 4 | ||||
-rw-r--r-- | arch/mips/isa/decoder.isa | 291 | ||||
-rw-r--r-- | arch/mips/isa/formats/fp.isa | 4 | ||||
-rw-r--r-- | arch/mips/isa/formats/mem.isa | 26 | ||||
-rw-r--r-- | arch/mips/isa/formats/util.isa | 21 | ||||
-rw-r--r-- | arch/mips/isa_traits.cc | 31 | ||||
-rw-r--r-- | arch/mips/isa_traits.hh | 170 | ||||
-rw-r--r-- | arch/sparc/SConscript | 1 | ||||
-rw-r--r-- | arch/sparc/isa/decoder.isa | 51 | ||||
-rw-r--r-- | arch/sparc/isa/formats/branch.isa | 23 | ||||
-rw-r--r-- | arch/sparc/isa/formats/integerop.isa | 16 | ||||
-rw-r--r-- | arch/sparc/isa/formats/mem.isa | 1 | ||||
-rw-r--r-- | arch/sparc/linux/linux.cc | 68 | ||||
-rw-r--r-- | arch/sparc/linux/linux.hh | 61 | ||||
-rw-r--r-- | arch/sparc/linux/process.cc | 6 | ||||
-rw-r--r-- | arch/sparc/linux/process.hh | 1 | ||||
-rw-r--r-- | arch/sparc/process.cc | 111 | ||||
-rw-r--r-- | arch/sparc/process.hh | 19 |
18 files changed, 688 insertions, 217 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 §ion); - }; + 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; |