From 79a46838767f82554fafe6dc3c811492bdb32f8a Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 10 Jan 2006 14:57:37 -0500 Subject: [PATCH 001/180] Adding the sparc ISA files which were worked on locally arch/sparc/isa_desc/bitfields.h: This file defines the bit fields used by the isa description system arch/sparc/isa_desc/decoder.h: This file describes the decoder for the isa description system arch/sparc/isa_desc/formats.h: This file declares the instruction formats arch/sparc/isa_desc/formats/basic.format: This file implements the "basic" instruction format arch/sparc/isa_desc/formats/branch.format: This file implements the "branch" instruction format arch/sparc/isa_desc/formats/integerop.format: This file implements the "integerop" instruction format arch/sparc/isa_desc/formats/mem.format: This file implements the "mem" instruction format arch/sparc/isa_desc/formats/noop.format: This file implements the "noop" instruction format arch/sparc/isa_desc/formats/trap.format: This file implements the "trap" instruction format arch/sparc/isa_desc/includes.h: This file is all of the inclues that are used by the isa description system --HG-- extra : convert_revision : 12a2ffe949317b8b57d83263a4261131b9432c2a --- arch/sparc/isa_desc/bitfields.h | 50 ++ arch/sparc/isa_desc/decoder.h | 638 +++++++++++++++++++ arch/sparc/isa_desc/formats.h | 19 + arch/sparc/isa_desc/formats/basic.format | 65 ++ arch/sparc/isa_desc/formats/branch.format | 66 ++ arch/sparc/isa_desc/formats/integerop.format | 110 ++++ arch/sparc/isa_desc/formats/mem.format | 78 +++ arch/sparc/isa_desc/formats/noop.format | 47 ++ arch/sparc/isa_desc/formats/trap.format | 53 ++ arch/sparc/isa_desc/includes.h | 40 ++ 10 files changed, 1166 insertions(+) create mode 100644 arch/sparc/isa_desc/bitfields.h create mode 100644 arch/sparc/isa_desc/decoder.h create mode 100644 arch/sparc/isa_desc/formats.h create mode 100644 arch/sparc/isa_desc/formats/basic.format create mode 100644 arch/sparc/isa_desc/formats/branch.format create mode 100644 arch/sparc/isa_desc/formats/integerop.format create mode 100644 arch/sparc/isa_desc/formats/mem.format create mode 100644 arch/sparc/isa_desc/formats/noop.format create mode 100644 arch/sparc/isa_desc/formats/trap.format create mode 100644 arch/sparc/isa_desc/includes.h diff --git a/arch/sparc/isa_desc/bitfields.h b/arch/sparc/isa_desc/bitfields.h new file mode 100644 index 000000000..b0ac57575 --- /dev/null +++ b/arch/sparc/isa_desc/bitfields.h @@ -0,0 +1,50 @@ +//////////////////////////////////////////////////////////////////// +// +// Bitfield definitions. +// + +// Bitfields are shared liberally between instruction formats, so they are +// simply defined alphabetically + +def bitfield A <29>; +def bitfield CC02 <20>; +def bitfield CC03 <25>; +def bitfield CC04 <11>; +def bitfield CC12 <21>; +def bitfield CC13 <26>; +def bitfield CC14 <12>; +def bitfield CC2 <18>; +def bitfield CMASK <6:4>; +def bitfield COND2 <28:25>; +def bitfield COND4 <17:14>; +def bitfield D16HI <21:20>; +def bitfield D16LO <13:0>; +def bitfield DISP19 <18:0>; +def bitfield DISP22 <21:0>; +def bitfield DISP30 <29:0>; +def bitfield FCN <29:26>; +def bitfield I <13>; +def bitfield IMM_ASI <12:5>; +def bitfield IMM22 <21:0>; +def bitfield MMASK <3:0>; +def bitfield OP <31:30>; +def bitfield OP2 <24:22>; +def bitfield OP3 <24:19>; +def bitfield OPF <13:5>; +def bitfield OPF_CC <13:11>; +def bitfield OPF_LOW5 <9:5>; +def bitfield OPF_LOW6 <10:5>; +def bitfield P <19>; +def bitfield RCOND2 <27:25>; +def bitfield RCOND3 <12:10>; +def bitfield RCOND4 <12:10>; +def bitfield RD <29:25>; +def bitfield RS1 <18:14>; +def bitfield RS2 <4:0>; +def bitfield SHCNT32 <4:0>; +def bitfield SHCNT64 <5:0>; +def bitfield SIMM10 <9:0>; +def bitfield SIMM11 <10:0>; +def bitfield SIMM13 <12:0>; +def bitfield SW_TRAP <6:0>; +def bitfield X <12>; diff --git a/arch/sparc/isa_desc/decoder.h b/arch/sparc/isa_desc/decoder.h new file mode 100644 index 000000000..06834ecc3 --- /dev/null +++ b/arch/sparc/isa_desc/decoder.h @@ -0,0 +1,638 @@ +//////////////////////////////////////////////////////////////////// +// +// The actual decoder specification +// + +decode OP default Trap::unknown({{illegal_instruction}}) { + + 0x0: decode OP2 { + 0x0: Trap::illtrap({{illegal_instruction}}); //ILLTRAP + 0x1: Branch::bpcc({{ + switch((CC12 << 1) | CC02) + { + case 1: case 3: + throw illegal_instruction; + case 0: + if(passesCondition(xc->regs.MiscRegs.ccrFields.icc, COND2)) + ;//branchHere + break; + case 2: + if(passesCondition(xc->regs.MiscRegs.ccrFields.xcc, COND2)) + ;//branchHere + break; + } + }});//BPcc + 0x2: Branch::bicc({{ + if(passesCondition(xc->regs.MiscRegs.ccrFields.icc, COND2)) + ;//branchHere + }});//Bicc + 0x3: Branch::bpr({{ + switch(RCOND) + { + case 0: case 4: + throw illegal_instruction; + case 1: + if(Rs1 == 0) ;//branchHere + break; + case 2: + if(Rs1 <= 0) ;//branchHere + break; + case 3: + if(Rs1 < 0) ;//branchHere + break; + case 5: + if(Rs1 != 0) ;//branchHere + break; + case 6: + if(Rs1 > 0) ;//branchHere + break; + case 7: + if(Rs1 >= 0) ;//branchHere + break; + } + }}); //BPr + 0x4: IntegerOp::sethi({{Rd = (IMM22 << 10) & 0xFFFFFC00;}}); //SETHI (or NOP if rd == 0 and imm == 0) + 0x5: Trap::fbpfcc({{throw fp_disabled;}}); //FBPfcc + 0x6: Trap::fbfcc({{throw fp_disabled;}}); //FBfcc + } + 0x1: Branch::call({{ + //branch here + Rd = xc->pc; + }}); + 0x2: decode OP3 { + format IntegerOp { + 0x00: add({{ + INT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); + Rd = Rs1.sdw + val2; + }});//ADD + 0x01: and({{ + UINT64 val2 = (I ? SIMM13.sdw : Rs2.udw); + Rd = Rs1.udw & val2; + }});//AND + 0x02: or({{ + UINT64 val2 = (I ? SIMM13.sdw : Rs2.udw); + Rd = Rs1.udw | val2; + }});//OR + 0x03: xor({{ + UINT64 val2 = (I ? SIMM13.sdw : Rs2.udw); + Rd = Rs1.udw ^ val2; + }});//XOR + 0x04: sub({{ + INT64 val2 = ~((UINT64)(I ? SIMM13.sdw : Rs2.udw))+1; + Rd = Rs1.sdw + val2; + }});//SUB + 0x05: andn({{ + UINT64 val2 = (I ? SIMM13.sdw : Rs2.udw); + Rd = Rs1.udw & ~val2; + }});//ANDN + 0x06: orn({{ + UINT64 val2 = (I ? SIMM13.sdw : Rs2.udw); + Rd = Rs1.udw | ~val2; + }});//ORN + 0x07: xnor({{ + UINT64 val2 = (I ? SIMM13.sdw : Rs2.udw); + Rd = ~(Rs1.udw ^ val2); + }});//XNOR + 0x08: addc({{ + INT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); + INT64 carryin = xc->regs.MiscRegs.ccrfields.iccfields.c; + Rd = Rs1.sdw + val2 + carryin; + }});//ADDC + 0x09: mulx({{ + INT64 val2 = (I ? SIMM13.sdw : Rs2); + Rd = Rs1 * val2; + }});//MULX + 0x0A: umul({{ + UINT64 resTemp, val2 = (I ? SIMM13.sdw : Rs2.udw); + Rd = resTemp = Rs1.udw<31:0> * val2<31:0>; + xc->regs.MiscRegs.yFields.value = resTemp<63:32>; + }});//UMUL + 0x0B: smul({{ + INT64 resTemp, val2 = (I ? SIMM13.sdw : Rs2.sdw); + rd.sdw = resTemp = Rs1.sdw<31:0> * val2<31:0>; + xc->regs.MiscRegs.yFields.value = resTemp<63:32>; + }});//SMUL + 0x0C: subc({{ + INT64 val2 = ~((INT64)(I ? SIMM13.sdw : Rs2.sdw))+1; + INT64 carryin = xc->regs.MiscRegs.ccrfields.iccfields.c; + Rd.sdw = Rs1.sdw + val2 + carryin; + }});//SUBC + 0x0D: udivx({{ + UINT64 val2 = (I ? SIMM13.sdw : Rs2.udw); + if(val2 == 0) throw division_by_zero; + Rd.udw = Rs1.udw / val2; + }});//UDIVX + 0x0E: udiv({{ + UINT32 resTemp, val2 = (I ? SIMM13.sw : Rs2.udw<31:0>); + if(val2 == 0) throw division_by_zero; + resTemp = (UINT64)((xc->regs.MiscRegs.yFields.value << 32) | Rs1.udw<31:0>) / val2; + INT32 overflow = (resTemp<63:32> != 0); + if(overflow) rd.udw = resTemp = 0xFFFFFFFF; + else rd.udw = resTemp; + }}); //UDIV + 0x0F: sdiv({{ + INT32 resTemp, val2 = (I ? SIMM13.sw : Rs2.sdw<31:0>); + if(val2 == 0) throw division_by_zero; + Rd.sdw = resTemp = (INT64)((xc->regs.MiscRegs.yFields.value << 32) | Rs1.sdw<31:0>) / val2; + INT32 overflow = (resTemp<63:31> != 0); + INT32 underflow = (resTemp<63:> && resTemp<62:31> != 0xFFFFFFFF); + if(overflow) rd.udw = resTemp = 0x7FFFFFFF; + else if(underflow) rd.udw = resTemp = 0xFFFFFFFF80000000; + else rd.udw = resTemp; + }});//SDIV + } + format IntegerOpCc { + 0x10: addcc({{ + INT64 resTemp, val2 = (I ? SIMM13.sdw : Rs2); + Rd = resTemp = Rs1 + val2;}}, + {{((Rs1 & 0xFFFFFFFF + val2 & 0xFFFFFFFF) >> 31)}}, + {{Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>}}, + {{((Rs1 >> 1) + (val2 >> 1) + (Rs1 & val2 & 0x1))<63:>}}, + {{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}} + );//ADDcc + 0x11: andcc({{ + INT64 val2 = (I ? SIMM13.sdw : Rs2); + Rd = Rs1 & val2;}} + ,{{0}},{{0}},{{0}},{{0}});//ANDcc + 0x12: orcc({{ + INT64 val2 = (I ? SIMM13.sdw : Rs2); + Rd = Rs1 | val2;}} + ,{{0}},{{0}},{{0}},{{0}});//ORcc + 0x13: xorcc({{ + INT64 val2 = (I ? SIMM13.sdw : Rs2); + Rd = Rs1 ^ val2;}} + ,{{0}},{{0}},{{0}},{{0}});//XORcc + 0x14: subcc({{ + INT64 resTemp, val2 = (INT64)(I ? SIMM13.sdw : Rs2); + Rd = resTemp = Rs1 - val2;}}, + {{((Rs1 & 0xFFFFFFFF + (~val2) & 0xFFFFFFFF + 1) >> 31)}}, + {{Rs1<31:> != val2<31:> && Rs1<31:> != resTemp<31:>}}, + {{((Rs1 >> 1) + (~val2) >> 1) + ((Rs1 | ~val2) & 0x1))<63:>}}, + {{Rs1<63:> != val2<63:> && Rs1<63:> != resTemp<63:>}} + );//SUBcc + 0x15: andncc({{ + INT64 val2 = (I ? SIMM13.sdw : Rs2); + Rd = Rs1 & ~val2;}} + ,{{0}},{{0}},{{0}},{{0}});//ANDNcc + 0x16: orncc({{ + INT64 val2 = (I ? SIMM13.sdw : Rs2); + Rd = Rs1 | ~val2;}} + ,{{0}},{{0}},{{0}},{{0}});//ORNcc + 0x17: xnorcc({{ + INT64 val2 = (I ? SIMM13.sdw : Rs2); + Rd = ~(Rs1 ^ val2);}} + ,{{0}},{{0}},{{0}},{{0}});//XNORcc + 0x18: addccc({{ + INT64 resTemp, val2 = (I ? SIMM13.sdw : Rs2); + INT64 carryin = xc->regs.MiscRegs.ccrfields.iccfields.c; + Rd = resTemp = Rs1 + val2 + carryin;}}, + {{((Rs1 & 0xFFFFFFFF + val2 & 0xFFFFFFFF) >> 31 + carryin)}}, + {{Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>}}, + {{((Rs1 >> 1) + (val2 >> 1) + ((Rs1 & val2) | (carryin & (Rs1 | val2)) & 0x1))<63:>}}, + {{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}} + );//ADDCcc + 0x1A: umulcc({{ + UINT64 resTemp, val2 = (I ? SIMM13.sdw : Rs2); + Rd = resTemp = Rs1.udw<31:0> * val2<31:0>; + xc->regs.MiscRegs.yFields.value = resTemp<63:32>;}} + ,{{0}},{{0}},{{0}},{{0}});//UMULcc + 0x1B: smulcc({{ + INT64 resTemp, val2 = (I ? SIMM13.sdw : Rs2); + Rd = resTemp = Rs1.sdw<31:0> * val2<31:0>; + xc->regs.MiscRegs.yFields.value = resTemp<63:32>;}} + ,{{0}},{{0}},{{0}},{{0}});//SMULcc + 0x1C: subccc({{ + INT64 resTemp, val2 = (INT64)(I ? SIMM13.sdw : Rs2); + INT64 carryin = xc->regs.MiscRegs.ccrfields.iccfields.c; + Rd = resTemp = Rs1 + ~(val2 + carryin) + 1;}}, + {{((Rs1 & 0xFFFFFFFF + (~(val2 + carryin)) & 0xFFFFFFFF + 1) >> 31)}}, + {{Rs1<31:> != val2<31:> && Rs1<31:> != resTemp<31:>}}, + {{((Rs1 >> 1) + (~(val2 + carryin)) >> 1) + ((Rs1 | ~(val2+carryin)) & 0x1))<63:>}}, + {{Rs1<63:> != val2<63:> && Rs1<63:> != resTemp<63:>}} + );//SUBCcc + 0x1D: udivxcc({{ + UINT64 val2 = (I ? SIMM13.sdw : Rs2.udw); + if(val2 == 0) throw division_by_zero; + Rd.udw = Rs1.udw / val2;}} + ,{{0}},{{0}},{{0}},{{0}});//UDIVXcc + 0x1E: udivcc({{ + UINT32 resTemp, val2 = (I ? SIMM13.sw : Rs2.udw<31:0>); + if(val2 == 0) throw division_by_zero; + resTemp = (UINT64)((xc->regs.MiscRegs.yFields.value << 32) | Rs1.udw<31:0>) / val2; + INT32 overflow = (resTemp<63:32> != 0); + if(overflow) rd.udw = resTemp = 0xFFFFFFFF; + else rd.udw = resTemp;}}, + {{0}}, + {{overflow}}, + {{0}}, + {{0}} + );//UDIVcc + 0x1F: sdivcc({{ + INT32 resTemp, val2 = (I ? SIMM13.sw : Rs2.sdw<31:0>); + if(val2 == 0) throw division_by_zero; + Rd.sdw = resTemp = (INT64)((xc->regs.MiscRegs.yFields.value << 32) | Rs1.sdw<31:0>) / val2; + INT32 overflow = (resTemp<63:31> != 0); + INT32 underflow = (resTemp<63:> && resTemp<62:31> != 0xFFFFFFFF); + if(overflow) rd.udw = resTemp = 0x7FFFFFFF; + else if(underflow) rd.udw = resTemp = 0xFFFFFFFF80000000; + else rd.udw = resTemp;}}, + {{0}}, + {{overflow || underflow}}, + {{0}}, + {{0}} + );//SDIVcc + 0x20: taddcc({{ + INT64 resTemp, val2 = (I ? SIMM13.sdw : Rs2); + Rd = resTemp = Rs1 + val2; + INT32 overflow = Rs1<1:0> || val2<1:0> || (Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>);}}, + {{((Rs1 & 0xFFFFFFFF + val2 & 0xFFFFFFFF) >> 31)}}, + {{overflow}}, + {{((Rs1 >> 1) + (val2 >> 1) + (Rs1 & val2 & 0x1))<63:>}}, + {{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}} + );//TADDcc + 0x21: tsubcc({{ + INT64 resTemp, val2 = (I ? SIMM13.sdw : Rs2); + Rd = resTemp = Rs1 + val2; + INT32 overflow = Rs1<1:0> || val2<1:0> || (Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>);}}, + {{(Rs1 & 0xFFFFFFFF + val2 & 0xFFFFFFFF) >> 31)}}, + {{overflow}}, + {{((Rs1 >> 1) + (val2 >> 1) + (Rs1 & val2 & 0x1))<63:>}}, + {{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}} + );//TSUBcc + 0x22: taddcctv({{ + INT64 resTemp, val2 = (I ? SIMM13.sdw : Rs2); + Rd = resTemp = Rs1 + val2; + INT32 overflow = Rs1<1:0> || val2<1:0> || (Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>); + if(overflow) throw tag_overflow;}}, + {{((Rs1 & 0xFFFFFFFF + val2 & 0xFFFFFFFF) >> 31)}}, + {{overflow}}, + {{((Rs1 >> 1) + (val2 >> 1) + (Rs1 & val2 & 0x1))<63:>}}, + {{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}} + );//TADDccTV + 0x23: tsubcctv({{ + INT64 resTemp, val2 = (I ? SIMM13.sdw : Rs2); + Rd = resTemp = Rs1 + val2; + INT32 overflow = Rs1<1:0> || val2<1:0> || (Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>); + if(overflow) throw tag_overflow;}}, + {{((Rs1 & 0xFFFFFFFF + val2 & 0xFFFFFFFF) >> 31)}}, + {{overflow}}, + {{((Rs1 >> 1) + (val2 >> 1) + (Rs1 & val2 & 0x1))<63:>}}, + {{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}} + );//TSUBccTV + 0x24: mulscc({{ + INT64 resTemp, multiplicand = (I ? SIMM13.sdw : Rs2); + INT32 multiplier = Rs1<31:0>; + INT32 savedLSB = Rs1<0:>; + multiplier = multipler<31:1> | + ((xc->regs.MiscRegs.ccrFields.iccFields.n + ^ xc->regs.MiscRegs.ccrFields.iccFields.v) << 32); + if(!xc->regs.MiscRegs.yFields.value<0:>) + multiplicand = 0; + Rd = resTemp = multiplicand + multiplier; + xc->regs.MiscRegs.yFields.value = xc->regs.MiscRegs.yFields.value<31:1> | (savedLSB << 31);}}, + {{((multiplicand & 0xFFFFFFFF + multiplier & 0xFFFFFFFF) >> 31)}}, + {{multiplicand<31:> == multiplier<31:> && multiplier<31:> != resTemp<31:>}}, + {{((multiplicand >> 1) + (multiplier >> 1) + (multiplicand & multiplier & 0x1))<63:>}}, + {{multiplicand<63:> == multiplier<63:> && multiplier<63:> != resTemp<63:>}} + );//MULScc + } + format IntegerOp + { + 0x25: decode X { + 0x0: sll({{Rd = Rs1 << (I ? SHCNT32 : Rs2<4:0>);}}); //SLL + 0x1: sllx({{Rd = Rs1 << (I ? SHCNT64 : Rs2<5:0>);}}); //SLLX + } + 0x26: decode X { + 0x0: srl({{Rd = Rs1.udw<31:0> >> (I ? SHCNT32 : Rs2<4:0>);}}); //SRL + 0x1: srlx({{Rd = Rs1.udw >> (I ? SHCNT64 : Rs2<5:0>);}});//SRLX + } + 0x27: decode X { + 0x0: sra({{Rd = Rs1.sdw<31:0> >> (I ? SHCNT32 : Rs2<4:0>);}}); //SRA + 0x1: srax({{Rd = Rs1.sdw >> (I ? SHCNT64 : Rs2<5:0>);}});//SRAX + } + 0x28: decode RS1 { + 0x0: rdy({{Rd = xc->regs.MiscRegs.yFields.value;}}); //RDY + 0x2: rdccr({{Rd = xc->regs.MiscRegs.ccr;}}); //RDCCR + 0x3: rdasi({{Rd = xc->regs.MiscRegs.asi;}}); //RDASI + 0x4: rdtick({{ + if(xc->regs.MiscRegs.pstateFields.priv == 0 && + xc->regs.MiscRegs.tickFields.npt == 1) + throw privileged_action; + Rd = xc->regs.MiscRegs.tick; + }});//RDTICK + 0x5: rdpc({{Rd = xc->regs.pc;}}); //RDPC + 0x6: rdfprs({{Rd = xc->regs.MiscRegs.fprs;}}); //RDFPRS + 0xF: decode I { + 0x0: Noop::membar({{//Membar isn't needed yet}}); //MEMBAR + 0x1: Noop::stbar({{//Stbar isn/'t needed yet}}); //STBAR + } + } + + 0x2A: decode RS1 { + 0x0: rdprtpc({{checkPriv Rd = xc->regs.MiscRegs.tpc[xc->regs.MiscRegs.tl];}}); + 0x1: rdprtnpc({{checkPriv Rd = xc->regs.MiscRegs.tnpc[xc->regs.MiscRegs.tl];}}); + 0x2: rdprtstate({{checkPriv Rd = xc->regs.MiscRegs.tstate[xc->regs.MiscRegs.tl];}}); + 0x3: rdprtt({{checkPriv Rd = xc->regs.MiscRegs.tt[xc->regs.MiscRegs.tl];}}); + 0x4: rdprtick({{checkPriv Rd = xc->regs.MiscRegs.tick;}}); + 0x5: rdprtba({{checkPriv Rd = xc->regs.MiscRegs.tba;}}); + 0x6: rdprpstate({{checkPriv Rd = xc->regs.MiscRegs.pstate;}}); + 0x7: rdprtl({{checkPriv Rd = xc->regs.MiscRegs.tl;}}); + 0x8: rdprpil({{checkPriv Rd = xc->regs.MiscRegs.pil;}}); + 0x9: rdprcwp({{checkPriv Rd = xc->regs.MiscRegs.cwp;}}); + 0xA: rdprcansave({{checkPriv Rd = xc->regs.MiscRegs.cansave;}}); + 0xB: rdprcanrestore({{checkPriv Rd = xc->regs.MiscRegs.canrestore;}}); + 0xC: rdprcleanwin({{checkPriv Rd = xc->regs.MiscRegs.cleanwin;}}); + 0xD: rdprotherwin({{checkPriv Rd = xc->regs.MiscRegs.otherwin;}}); + 0xE: rdprwstate({{checkPriv Rd = xc->regs.MiscRegs.wstate;}}); + 0xF: rdprfq({{throw illegal_instruction;}}); //The floating point queue isn't implemented right now. + } + 0x2B: BasicOperate::flushw({{\\window toilet}}); //FLUSHW + 0x2C: movcc({{ + ccBank = (CC24 << 2) | (CC14 << 1) | (CC04 << 0); + switch(ccBank) + { + case 0: case 1: case 2: case 3: + throw fp_disabled; + break; + case 5: case 7: + throw illegal_instruction; + break; + case 4: + if(passesCondition(xc->regs.MiscRegs.ccrFields.icc, COND4)) + Rd = (I ? SIMM11.sdw : RS2); + break; + case 6: + if(passesCondition(xc->regs.MiscRegs.ccrFields.xcc, COND4)) + Rd = (I ? SIMM11.sdw : RS2); + break; + } + }});//MOVcc + 0x2D: sdivx({{ + INT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); + if(val2 == 0) throw division_by_zero; + Rd.sdw = Rs1.sdw / val2; + }});//SDIVX + 0x2E: decode RS1 { + 0x0: IntegerOp::popc({{ + INT64 count = 0, val2 = (I ? SIMM13.sdw : Rs2.sdw); + UINT8 oneBits[] = {0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4} + for(unsigned int x = 0; x < 16; x++) + { + count += oneBits[val2 & 0xF]; + val2 >> 4; + } + }});//POPC + } + 0x2F: movr({{ + UINT64 val2 = (I ? SIMM10.sdw : Rs2.sdw); + switch(RCOND) + { + case 0: case 4: + throw illegal_instruction; + break; + case 1: + if(Rs1 == 0) Rd = val2; + break; + case 2: + if(Rs1 <= 0) Rd = val2; + break; + case 3: + if(Rs1 = 0) Rd = val2; + break; + case 5: + if(Rs1 != 0) Rd = val2; + break; + case 6: + if(Rs1 > 0) Rd = val2; + break; + case 7: + if(Rs1 >= 0) Rd = val2; + break; + } + }});//MOVR + 0x30: decode RD { + 0x0: wry({{ + UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); + xc->regs.MiscRegs.y = Rs1 ^ val2; + }});//WRY + 0x2: wrccr({{ + UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); + xc->regs.MiscRegs.ccr = Rs1 ^ val2; + }});//WRCCR + 0x3: wrasi({{ + UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); + xc->regs.MiscRegs.asi = Rs1 ^ val2; + }});//WRASI + 0x6: wrfprs({{ + UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); + xc->regs.MiscRegs.asi = Rs1 ^ val2; + }});//WRFPRS + 0xF: Trap::sir({{software_initiated_reset}}); //SIR + } + 0x31: decode FCN { + 0x0: BasicOperate::saved({{\\Boogy Boogy}}); //SAVED + 0x1: BasicOperate::restored({{\\Boogy Boogy}}); //RESTORED + } + 0x32: decode RD { + 0x0: wrprtpc({{checkPriv + UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); + xc->regs.MiscRegs.tpc[xc->regs.MiscRegs.tl] = Rs1 ^ val2; + }}); + 0x1: wrprtnpc({{checkPriv + UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); + xc->regs.MiscRegs.tnpc[xc->regs.MiscRegs.tl] = Rs1 ^ val2; + }}); + 0x2: wrprtstate({{checkPriv + UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); + xc->regs.MiscRegs.tstate[xc->regs.MiscRegs.tl] = Rs1 ^ val2; + }}); + 0x3: wrprtt({{checkPriv + UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); + xc->regs.MiscRegs.tt[xc->regs.MiscRegs.tl] = Rs1 ^ val2; + }}); + 0x4: wrprtick({{checkPriv + UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); + xc->regs.MiscRegs.tick = Rs1 ^ val2; + }}); + 0x5: wrprtba({{checkPriv + UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); + xc->regs.MiscRegs.tba = Rs1 ^ val2; + }}); + 0x6: wrprpstate({{checkPriv + UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); + xc->regs.MiscRegs.pstate = Rs1 ^ val2; + }}); + 0x7: wrprtl({{checkPriv + UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); + xc->regs.MiscRegs.tl = Rs1 ^ val2; + }}); + 0x8: wrprpil({{checkPriv + UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); + xc->regs.MiscRegs.pil = Rs1 ^ val2; + }}); + 0x9: wrprcwp({{checkPriv + UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); + xc->regs.MiscRegs.cwp = Rs1 ^ val2; + }}); + 0xA: wrprcansave({{checkPriv + UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); + xc->regs.MiscRegs.cansave = Rs1 ^ val2; + }}); + 0xB: wrprcanrestore({{checkPriv + UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); + xc->regs.MiscRegs.canrestore = Rs1 ^ val2; + }}); + 0xC: wrprcleanwin({{checkPriv + UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); + xc->regs.MiscRegs.cleanwin = Rs1 ^ val2; + }}); + 0xD: wrprotherwin({{checkPriv + UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); + xc->regs.MiscRegs.otherwin = Rs1 ^ val2; + }}); + 0xE: wrprwstate({{checkPriv + UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); + xc->regs.MiscRegs.wstate = Rs1 ^ val2; + }}); + } + + 0x34: Trap::fpop1({{Throw fp_disabled;}}); //FPOP1 + 0x35: Trap::fpop2({{Throw fp_disabled;}}); //FPOP2 + + + 0x38: Branch::jmpl({{//Stuff}}); //JMPL + 0x39: Branch::return({{//Other Stuff}}); //RETURN + 0x3A: Trap::tcc({{ + switch((CC14 << 1) | (CC04 << 0)) + { + case 1: case 3: + throw illegal_instruction; + case 0: + if(passesCondition(xc->regs.MiscRegs.ccrFields.icc, machInst<25:28>)) + throw trap_instruction; + break; + case 2: + if(passesCondition(xc->regs.MiscRegs.ccrFields.xcc, machInst<25:28>)) + throw trap_instruction; + break; + } + }}); //Tcc + 0x3B: BasicOperate::flush({{//Lala}}); //FLUSH + 0x3C: BasicOperate::save({{//leprechauns); //SAVE + 0x3D: BasicOperate::restore({{//Eat my short int}}); //RESTORE + 0x3E: decode FCN { + 0x1: BasicOperate::done({{//Done thing}}); //DONE + 0x2: BasicOperate::retry({{//Retry thing}}); //RETRY + } + } + } + 0x3: decode OP3 { + format Mem { + 0x00: lduw({{Rd.uw = Mem.uw;}}); //LDUW + 0x01: ldub({{Rd.ub = Mem.ub;}}); //LDUB + 0x02: lduh({{Rd.uhw = Mem.uhw;}}); //LDUH + 0x03: ldd({{ + UINT64 val = Mem.udw; + setIntReg(RD & (~1), val<31:0>); + setIntReg(RD | 1, val<63:32>); + }});//LDD + 0x04: stw({{Mem.sw = Rd.sw;}}); //STW + 0x05: stb({{Mem.sb = Rd.sb;}}); //STB + 0x06: sth({{Mem.shw = Rd.shw;}}); //STH + 0x07: std({{ + Mem.udw = readIntReg(RD & (~1))<31:0> | (readIntReg(RD | 1)<31:0> << 32); + }});//STD + 0x08: ldsw({{Rd.sw = Mem.sw;}}); //LDSW + 0x09: ldsb({{Rd.sb = Mem.sb;}}); //LDSB + 0x0A: ldsh({{Rd.shw = Mem.shw;}}); //LDSH + 0x0B: ldx({{Rd.udw = Mem.udw;}}); //LDX + + 0x0D: ldstub({{ + Rd.ub = Mem.ub; + Mem.ub = 0xFF; + }}); //LDSTUB + 0x0E: stx({{Rd.udw = Mem.udw;}}); //STX + 0x0F: swap({{ + UINT32 temp = Rd.uw; + Rd.uw = Mem.uw; + Mem.uw = temp; + }}); //SWAP + 0x10: lduwa({{Rd.uw = Mem.uw;}}); //LDUWA + 0x11: lduba({{Rd.ub = Mem.ub;}}); //LDUBA + 0x12: lduha({{Rd.uhw = Mem.uhw;}}); //LDUHA + 0x13: ldda({{ + UINT64 val = Mem.udw; + setIntReg(RD & (~1), val<31:0>); + setIntReg(RD | 1, val<63:32>); + }}); //LDDA + 0x14: stwa({{Mem.uw = Rd.uw;}}); //STWA + 0x15: stba({{Mem.ub = Rd.ub;}}); //STBA + 0x16: stha({{Mem.uhw = Rd.uhw;}}); //STHA + 0x17: stda({{ + Mem.udw = readIntReg(RD & (~1))<31:0> | (readIntReg(RD | 1)<31:0> << 32); + }}); //STDA + 0x18: ldswa({{Rd.sw = Mem.sw;}}); //LDSWA + 0x19: ldsba({{Rd.sb = Mem.sb;}}); //LDSBA + 0x1A: ldsha({{Rd.shw = Mem.shw;}}); //LDSHA + 0x1B: ldxa({{Rd.sdw = Mem.sdw;}}); //LDXA + + 0x1D: ldstuba({{ + Rd.ub = Mem.ub; + Mem.ub = 0xFF; + }}); //LDSTUBA + 0x1E: stxa({{Mem.sdw = Rd.sdw}}); //STXA + 0x1F: swapa({{ + UINT32 temp = Rd.uw; + Rd.uw = Mem.uw; + Mem.uw = temp; + }}); //SWAPA + 0x20: Trap::ldf({{throw fp_disabled;}}); //LDF + 0x21: decode X { + 0x0: Trap::ldfsr({{throw fp_disabled;}}); //LDFSR + 0x1: Trap::ldxfsr({{throw fp_disabled;}}); //LDXFSR + } + 0x22: Trap::ldqf({{throw fp_disabled;}}); //LDQF + 0x23: Trap::lddf({{throw fp_disabled;}}); //LDDF + 0x24: Trap::stf({{throw fp_disabled;}}); //STF + 0x25: decode X { + 0x0: Trap::stfsr({{throw fp_disabled;}}); //STFSR + 0x1: Trap::stxfsr({{throw fp_disabled;}}); //STXFSR + } + 0x26: Trap::stqf({{throw fp_disabled;}}); //STQF + 0x27: Trap::stdf({{throw fp_disabled;}}); //STDF + + + + + + 0x2D: Noop::prefetch({{ }}); //PREFETCH + + + 0x30: Trap::ldfa({{throw fp_disabled;}}); //LDFA + + 0x32: Trap::ldqfa({{throw fp_disabled;}}); //LDQFA + 0x33: Trap::lddfa({{throw fp_disabled;}}); //LDDFA + 0x34: Trap::stfa({{throw fp_disabled;}}); //STFA + 0x35: Trap::stqfa({{throw fp_disabled;}}); //STQFA + 0x36: Trap::stdfa({{throw fp_disabled;}}); //STDFA + + + + + + 0x3C: Cas::casa( + {{UINT64 val = Mem.uw; + if(Rs2.uw == val) + Mem.uw = Rd.uw; + Rd.uw = val; + }}); //CASA + 0x3D: Noop::prefetcha({{ }}); //PREFETCHA + 0x3E: Cas::casxa( + {{UINT64 val = Mem.udw; + if(Rs2 == val) + Mem.udw = Rd; + Rd = val; + }}); //CASXA + } + } +} diff --git a/arch/sparc/isa_desc/formats.h b/arch/sparc/isa_desc/formats.h new file mode 100644 index 000000000..733a093f5 --- /dev/null +++ b/arch/sparc/isa_desc/formats.h @@ -0,0 +1,19 @@ +//Include the basic format +//Templates from this format are used later +##include "m5/arch/sparc/isa_desc/formats/basic.format" + +//Include the integerOp and integerOpCc format +##include "m5/arch/sparc/isa_desc/formats/integerop.format" + +//Include the mem format +##include "m5/arch/sparc/isa_desc/formats/mem.format" + +//Include the trap format +##include "m5/arch/sparc/isa_desc/formats/trap.format" + +//Include the branch format +##include "m5/arch/sparc/isa_desc/formats/branch.format" + +//Include the noop format +##include "m5/arch/sparc/isa_desc/formats/noop.format" + diff --git a/arch/sparc/isa_desc/formats/basic.format b/arch/sparc/isa_desc/formats/basic.format new file mode 100644 index 000000000..1994df41c --- /dev/null +++ b/arch/sparc/isa_desc/formats/basic.format @@ -0,0 +1,65 @@ + +// Declarations for execute() methods. +def template BasicExecDeclare {{ + Fault execute(%(CPU_exec_context)s *, Trace::InstRecord *) const; +}}; + +// Basic instruction class declaration template. +def template BasicDeclare {{ + /** + * Static instruction class for "%(mnemonic)s". + */ + class %(class_name)s : public %(base_class)s + { + public: + /// Constructor. + %(class_name)s(MachInst machInst); + %(BasicExecDeclare)s + }; +}}; + +// Basic instruction class constructor template. +def template BasicConstructor {{ + inline %(class_name)s::%(class_name)s(MachInst machInst) : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s) + { + %(constructor)s; + } +}}; + +// Basic instruction class execute method template. +def template BasicExecute {{ + Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const + { + Fault fault = No_Fault; + + %(fp_enable_check)s; + %(op_decl)s; + %(op_rd)s; + %(code)s; + + if(fault == No_Fault) + { + %(op_wb)s; + } + return fault; + } +}}; + +// Basic decode template. +def template BasicDecode {{ + return new %(class_name)s(machInst); +}}; + +// Basic decode template, passing mnemonic in as string arg to constructor. +def template BasicDecodeWithMnemonic {{ + return new %(class_name)s("%(mnemonic)s", machInst); +}}; + +// The most basic instruction format... used only for a few misc. insts +def format BasicOperate(code, *flags) {{ + iop = InstObjParams(name, Name, 'SparcStaticInst', CodeBlock(code), flags) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecode.subst(iop) + exec_output = BasicExecute.subst(iop) +}}; diff --git a/arch/sparc/isa_desc/formats/branch.format b/arch/sparc/isa_desc/formats/branch.format new file mode 100644 index 000000000..c4c0a90af --- /dev/null +++ b/arch/sparc/isa_desc/formats/branch.format @@ -0,0 +1,66 @@ +//////////////////////////////////////////////////////////////////// +// +// Branch instructions +// + +output header {{ + /** + * Base class for integer operations. + */ + class Branch : public SparcStaticInst + { + protected: + + /// Constructor + Branch(const char *mnem, MachInst _machInst, OpClass __opClass) : SparcStaticInst(mnem, _machInst, __opClass) + { + } + + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; + }; +}}; + +output decoder {{ + std::string Branch::generateDisassembly(Addr pc, const SymbolTable *symtab) const + { + return "Disassembly of integer instruction\n"; + } +}}; + +def template BranchExecute {{ + Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const + { + //Attempt to execute the instruction + try + { + checkPriv; + + %(op_decl)s; + %(op_rd)s; + %(code)s; + } + //If we have an exception for some reason, + //deal with it + catch(SparcException except) + { + //Deal with exception + return No_Fault; + } + + //Write the resulting state to the execution context + %(op_wb)s; + + return No_Fault; + } +}}; + +// Primary format for integer operate instructions: +def format Branch(code, *opt_flags) {{ + orig_code = code + cblk = CodeBlock(code) + iop = InstObjParams(name, Name, 'SparcStaticInst', cblk, opt_flags) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecodeWithMnemonic.subst(iop) + exec_output = BranchExecute.subst(iop) +}}; diff --git a/arch/sparc/isa_desc/formats/integerop.format b/arch/sparc/isa_desc/formats/integerop.format new file mode 100644 index 000000000..275a346d3 --- /dev/null +++ b/arch/sparc/isa_desc/formats/integerop.format @@ -0,0 +1,110 @@ +//////////////////////////////////////////////////////////////////// +// +// Integer operate instructions +// + +output header {{ + /** + * Base class for integer operations. + */ + class IntegerOp : public SparcStaticInst + { + protected: + + /// Constructor + IntegerOp(const char *mnem, MachInst _machInst, OpClass __opClass) : SparcStaticInst(mnem, _machInst, __opClass) + { + } + + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; + }; +}}; + +output decoder {{ + std::string IntegerOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const + { + return "Disassembly of integer instruction\n"; + } +}}; + +def template IntegerExecute {{ + Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const + { + //These are set to constants when the execute method + //is generated + bool useCc = ; + bool checkPriv = ; + + //Attempt to execute the instruction + try + { + checkPriv; + + %(op_decl)s; + %(op_rd)s; + %(code)s; + } + //If we have an exception for some reason, + //deal with it + catch(SparcException except) + { + //Deal with exception + return No_Fault; + } + + //Write the resulting state to the execution context + %(op_wb)s; + if(useCc) + { + xc->regs.miscRegFile.ccrFields.iccFields.n = Rd & (1 << 63); + xc->regs.miscRegFile.ccrFields.iccFields.z = (Rd == 0); + xc->regs.miscRegFile.ccrFields.iccFields.v = ivValue; + xc->regs.miscRegFile.ccrFields.iccFields.c = icValue; + xc->regs.miscRegFile.ccrFields.xccFields.n = Rd & (1 << 31); + xc->regs.miscRegFile.ccrFields.xccFields.z = ((Rd & 0xFFFFFFFF) == 0); + xc->regs.miscRegFile.ccrFields.xccFields.v = xvValue; + xc->regs.miscRegFile.ccrFields.xccFields.c = xcValue; + } + return No_Fault; + } +}}; + +// Primary format for integer operate instructions: +def format IntegerOp(code, *opt_flags) {{ + orig_code = code + cblk = CodeBlock(code) + checkPriv = (code.find('checkPriv') != -1) + code.replace('checkPriv', '') + if checkPriv: + code.replace('checkPriv;', 'if(!xc->regs.miscRegFile.pstateFields.priv) throw privileged_opcode;') + else: + code.replace('checkPriv;', '') + for (marker, value) in (('ivValue', '0'), ('icValue', '0'), + ('xvValue', '0'), ('xcValue', '0')): + code.replace(marker, value) + iop = InstObjParams(name, Name, 'SparcStaticInst', cblk, opt_flags) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecodeWithMnemonic.subst(iop) + exec_output = IntegerExecute.subst(iop) +}}; + +// Primary format for integer operate instructions: +def format IntegerOpCc(code, icValue, ivValue, xcValue, xvValue, *opt_flags) {{ + orig_code = code + cblk = CodeBlock(code) + checkPriv = (code.find('checkPriv') != -1) + code.replace('checkPriv', '') + if checkPriv: + code.replace('checkPriv;', 'if(!xc->regs.miscRegFile.pstateFields.priv) throw privileged_opcode;') + else: + code.replace('checkPriv;', '') + for (marker, value) in (('ivValue', ivValue), ('icValue', icValue), + ('xvValue', xvValue), ('xcValue', xcValue)): + code.replace(marker, value) + iop = InstObjParams(name, Name, 'SparcStaticInst', cblk, opt_flags) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecodeWithMnemonic.subst(iop) + exec_output = IntegerExecute.subst(iop) +}}; diff --git a/arch/sparc/isa_desc/formats/mem.format b/arch/sparc/isa_desc/formats/mem.format new file mode 100644 index 000000000..abc00b6f2 --- /dev/null +++ b/arch/sparc/isa_desc/formats/mem.format @@ -0,0 +1,78 @@ +//////////////////////////////////////////////////////////////////// +// +// Mem instructions +// + +output header {{ + /** + * Base class for integer operations. + */ + class Mem : public SparcStaticInst + { + protected: + + /// Constructor + Mem(const char *mnem, MachInst _machInst, OpClass __opClass) : SparcStaticInst(mnem, _machInst, __opClass) + { + } + + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; + }; +}}; + +output decoder {{ + std::string Mem::generateDisassembly(Addr pc, const SymbolTable *symtab) const + { + return "Disassembly of integer instruction\n"; + } +}}; + +def template MemExecute {{ + Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const + { + //Attempt to execute the instruction + try + { + + %(op_decl)s; + %(op_rd)s; + ea_code + %(code)s; + } + //If we have an exception for some reason, + //deal with it + catch(SparcException except) + { + //Deal with exception + return No_Fault; + } + + //Write the resulting state to the execution context + %(op_wb)s; + + return No_Fault; + } +}}; + +// Primary format for integer operate instructions: +def format Mem(code, *opt_flags) {{ + orig_code = code + cblk = CodeBlock(code) + iop = InstObjParams(name, Name, 'SparcStaticInst', cblk, opt_flags) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecodeWithMnemonic.subst(iop) + exec_output = MemExecute.subst(iop) + exec_output.replace('ea_code', 'EA = I ? (R1 + SIMM13) : R1 + R2;'); +}}; + +def format Cas(code, *opt_flags) {{ + orig_code = code + cblk = CodeBlock(code) + iop = InstObjParams(name, Name, 'SparcStaticInst', cblk, opt_flags) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecodeWithMnemonic.subst(iop) + exec_output = MemExecute.subst(iop) + exec_output.replace('ea_code', 'EA = R1;'); +}}; diff --git a/arch/sparc/isa_desc/formats/noop.format b/arch/sparc/isa_desc/formats/noop.format new file mode 100644 index 000000000..bc83e3261 --- /dev/null +++ b/arch/sparc/isa_desc/formats/noop.format @@ -0,0 +1,47 @@ +//////////////////////////////////////////////////////////////////// +// +// Noop instruction +// + +output header {{ + /** + * Base class for integer operations. + */ + class Noop : public SparcStaticInst + { + protected: + + /// Constructor + Noop(const char *mnem, MachInst _machInst, OpClass __opClass) : SparcStaticInst(mnem, _machInst, __opClass) + { + } + + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; + }; +}}; + +output decoder {{ + std::string Noop::generateDisassembly(Addr pc, const SymbolTable *symtab) const + { + return "Disassembly of integer instruction\n"; + } +}}; + +def template NoopExecute {{ + Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const + { + //Nothing to see here, move along + return No_Fault; + } +}}; + +// Primary format for integer operate instructions: +def format Noop(code, *opt_flags) {{ + orig_code = code + cblk = CodeBlock(code) + iop = InstObjParams(name, Name, 'SparcStaticInst', cblk, opt_flags) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecodeWithMnemonic.subst(iop) + exec_output = NoopExecute.subst(iop) +}}; diff --git a/arch/sparc/isa_desc/formats/trap.format b/arch/sparc/isa_desc/formats/trap.format new file mode 100644 index 000000000..bee77fe69 --- /dev/null +++ b/arch/sparc/isa_desc/formats/trap.format @@ -0,0 +1,53 @@ +//////////////////////////////////////////////////////////////////// +// +// Trap instructions +// + +output header {{ + /** + * Base class for integer operations. + */ + class Trap : public SparcStaticInst + { + protected: + + /// Constructor + Trap(const char *mnem, MachInst _machInst, OpClass __opClass) : SparcStaticInst(mnem, _machInst, __opClass) + { + } + + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; + }; +}}; + +output decoder {{ + std::string Trap::generateDisassembly(Addr pc, const SymbolTable *symtab) const + { + return "Disassembly of integer instruction\n"; + } +}}; + +def template TrapExecute {{ + Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const + { + //Call into the trap handler with the appropriate fault + return No_Fault; + } + + //Write the resulting state to the execution context + %(op_wb)s; + + return No_Fault; + } +}}; + +// Primary format for integer operate instructions: +def format Trap(code, *opt_flags) {{ + orig_code = code + cblk = CodeBlock(code) + iop = InstObjParams(name, Name, 'SparcStaticInst', cblk, opt_flags) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecodeWithMnemonic.subst(iop) + exec_output = TrapExecute.subst(iop) +}}; diff --git a/arch/sparc/isa_desc/includes.h b/arch/sparc/isa_desc/includes.h new file mode 100644 index 000000000..ff7cb7d1d --- /dev/null +++ b/arch/sparc/isa_desc/includes.h @@ -0,0 +1,40 @@ +//////////////////////////////////////////////////////////////////// +// +// Output include file directives. +// + +output header {{ +#include +#include +#include + +#include "cpu/static_inst.hh" +#include "traps.hh" +#include "mem/mem_req.hh" // some constructors use MemReq flags +}}; + +output decoder {{ +#include "base/cprintf.hh" +#include "base/loader/symtab.hh" +#include "cpu/exec_context.hh" // for Jump::branchTarget() + +#include +#if defined(linux) +#include +#endif +}}; + +output exec {{ +#include +#if defined(linux) +#include +#endif + +#ifdef FULL_SYSTEM +//#include "arch/alpha/pseudo_inst.hh" +#endif +#include "cpu/base.hh" +#include "cpu/exetrace.hh" +#include "sim/sim_exit.hh" +}}; + From 89596f0cfa223a2f2836caa56ed79b8a0996f740 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 24 Jan 2006 19:57:17 -0500 Subject: [PATCH 002/180] Some stuff aparently didn't get committed which was from before the new repository was created. SConscript: There is a new SConscript in the arch/alpha directory which has the alpha specific files. To add files for an arch, a similar file should be created. arch/isa_parser.py: The isa parser now supports include directives. These are done with ##include build/SConstruct: The target directory is passed on so that the architecture specific SConscript can have it. Also, sparc was added as a valid architecture type. arch/alpha/SConscript: This SConscript adds the alpha specific source arch/sparc/isa_desc/operands.h: This sets up the operand types that the sparc isa uses arch/sparc/isa_traits.cc: Implementation of sparc specific things, like a register file with windows build/build_options/default/SPARC_SE: The default options for a sparc syscall emulation build. --HG-- extra : convert_revision : 1afedae61dc8cae0d59d3bf1d41420d929be2efd --- SConscript | 80 ++-- arch/alpha/SConscript | 488 +++++++++++++++++++++++++ arch/isa_parser.py | 51 ++- arch/sparc/isa_desc/operands.h | 33 ++ arch/sparc/isa_traits.cc | 57 +++ arch/sparc/isa_traits.hh | 528 +++++++++++++++++++++++++++ build/SConstruct | 6 +- build/build_options/default/SPARC_SE | 2 + 8 files changed, 1211 insertions(+), 34 deletions(-) create mode 100644 arch/alpha/SConscript create mode 100644 arch/sparc/isa_desc/operands.h create mode 100644 arch/sparc/isa_traits.cc create mode 100644 arch/sparc/isa_traits.hh create mode 100644 build/build_options/default/SPARC_SE diff --git a/SConscript b/SConscript index 677a06d1f..7ea1e7638 100644 --- a/SConscript +++ b/SConscript @@ -43,15 +43,8 @@ Import('env') ################################################### # Base sources used by all configurations. -base_sources = Split(''' - arch/alpha/decoder.cc - arch/alpha/alpha_o3_exec.cc - arch/alpha/fast_cpu_exec.cc - arch/alpha/simple_cpu_exec.cc - arch/alpha/full_cpu_exec.cc - arch/alpha/faults.cc - arch/alpha/isa_traits.cc +base_sources = Split(''' base/circlebuf.cc base/copyright.cc base/cprintf.cc @@ -229,6 +222,14 @@ base_sources = Split(''' sim/stat_control.cc sim/trace_context.cc ''') +# These are now included by the architecture specific SConscript +# arch/alpha/decoder.cc +# arch/alpha/alpha_o3_exec.cc +# arch/alpha/fast_cpu_exec.cc +# arch/alpha/simple_cpu_exec.cc +# arch/alpha/full_cpu_exec.cc +# arch/alpha/faults.cc +# arch/alpha/isa_traits.cc # MySql sources mysql_sources = Split(''' @@ -238,14 +239,6 @@ mysql_sources = Split(''' # Full-system sources full_system_sources = Split(''' - arch/alpha/alpha_memory.cc - arch/alpha/arguments.cc - arch/alpha/ev5.cc - arch/alpha/osfpal.cc - arch/alpha/pseudo_inst.cc - arch/alpha/stacktrace.cc - arch/alpha/vtophys.cc - base/crc.cc base/inet.cc base/remote_gdb.cc @@ -301,6 +294,15 @@ full_system_sources = Split(''' sim/system.cc ''') +# These are now included by the architecture specific SConscript +# arch/alpha/alpha_memory.cc +# arch/alpha/arguments.cc +# arch/alpha/ev5.cc +# arch/alpha/osfpal.cc +# arch/alpha/pseudo_inst.cc +# arch/alpha/stacktrace.cc +# arch/alpha/vtophys.cc + # turbolaser encumbered sources turbolaser_sources = Split(''' encumbered/dev/dma.cc @@ -323,9 +325,6 @@ turbolaser_sources = Split(''' # Syscall emulation (non-full-system) sources syscall_emulation_sources = Split(''' - arch/alpha/alpha_common_syscall_emul.cc - arch/alpha/alpha_linux_process.cc - arch/alpha/alpha_tru64_process.cc cpu/memtest/memtest.cc encumbered/eio/eio.cc encumbered/eio/exolex.cc @@ -334,6 +333,11 @@ syscall_emulation_sources = Split(''' sim/syscall_emul.cc ''') +# These are now included by the architecture specific SConscript +# arch/alpha/alpha_common_syscall_emul.cc +# arch/alpha/alpha_linux_process.cc +# arch/alpha/alpha_tru64_process.cc + targetarch_files = Split(''' alpha_common_syscall_emul.hh alpha_linux_process.hh @@ -354,13 +358,18 @@ targetarch_files = Split(''' vtophys.hh ''') +# Set up bridging headers to the architecture specific versions for f in targetarch_files: - env.Command('targetarch/' + f, 'arch/alpha/' + f, - '''echo '#include "arch/alpha/%s"' > $TARGET''' % f) + env.Command('targetarch/' + f, 'arch/%s/%s' % (env['TARGET_ISA'], f), + '''echo '#include "arch/%s/%s"' > $TARGET''' % (env['TARGET_ISA'], f)) +# Let the target architecture define what sources it needs +arch_source = SConscript('arch/%s/SConscript' % env['TARGET_ISA'], + build_dir = 'build/%s/' % env['BUILD_DIR'], + exports = 'env', duplicate = False) # Set up complete list of sources based on configuration. -sources = base_sources +sources = base_sources + arch_source if env['FULL_SYSTEM']: sources += full_system_sources @@ -388,15 +397,24 @@ env.Command(Split('base/traceflags.hh base/traceflags.cc'), 'python $SOURCE $TARGET.base') # several files are generated from arch/$TARGET_ISA/isa_desc. -env.Command(Split('''arch/alpha/decoder.cc - arch/alpha/decoder.hh - arch/alpha/alpha_o3_exec.cc - arch/alpha/fast_cpu_exec.cc - arch/alpha/simple_cpu_exec.cc - arch/alpha/full_cpu_exec.cc'''), - Split('''arch/alpha/isa_desc - arch/isa_parser.py'''), - '$SRCDIR/arch/isa_parser.py $SOURCE $TARGET.dir arch/alpha') +env.Command(Split(''' + arch/%s/decoder.cc + arch/%s/decoder.hh + arch/%s/alpha_o3_exec.cc + arch/%s/fast_cpu_exec.cc + arch/%s/simple_cpu_exec.cc + arch/%s/full_cpu_exec.cc''' % + (env['TARGET_ISA'], + env['TARGET_ISA'], + env['TARGET_ISA'], + env['TARGET_ISA'], + env['TARGET_ISA'], + env['TARGET_ISA'])), + Split(''' + arch/%s/isa_desc + arch/isa_parser.py''' % + env['TARGET_ISA']), + '$SRCDIR/arch/isa_parser.py $SOURCE $TARGET.dir arch/%s' % env['TARGET_ISA']) # libelf build is described in its own SConscript file. diff --git a/arch/alpha/SConscript b/arch/alpha/SConscript new file mode 100644 index 000000000..2c98125bc --- /dev/null +++ b/arch/alpha/SConscript @@ -0,0 +1,488 @@ +# -*- mode:python -*- + +# Copyright (c) 2004-2005 The Regents of The University of Michigan +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import os +import sys +from os.path import isdir + +# This file defines how to build a particular configuration of M5 +# based on variable settings in the 'env' build environment. + +# Import build environment variable from SConstruct. +Import('env') + +################################################### +# +# Define needed sources. +# +################################################### + +# Base sources used by all configurations. +arch_base_sources = Split(''' + arch/alpha/decoder.cc + arch/alpha/alpha_o3_exec.cc + arch/alpha/fast_cpu_exec.cc + arch/alpha/simple_cpu_exec.cc + arch/alpha/full_cpu_exec.cc + arch/alpha/faults.cc + arch/alpha/isa_traits.cc + ''') + +# base/circlebuf.cc +# base/copyright.cc +# base/cprintf.cc +# base/embedfile.cc +# base/fast_alloc.cc +# base/fifo_buffer.cc +# base/hostinfo.cc +# base/hybrid_pred.cc +# base/inifile.cc +# base/intmath.cc +# base/match.cc +# base/misc.cc +# base/output.cc +# base/pollevent.cc +# base/range.cc +# base/random.cc +# base/sat_counter.cc +# base/socket.cc +# base/statistics.cc +# base/str.cc +# base/time.cc +# base/trace.cc +# base/traceflags.cc +# base/userinfo.cc +# base/compression/lzss_compression.cc +# base/loader/aout_object.cc +# base/loader/ecoff_object.cc +# base/loader/elf_object.cc +# base/loader/object_file.cc +# base/loader/symtab.cc +# base/stats/events.cc +# base/stats/statdb.cc +# base/stats/visit.cc +# base/stats/text.cc +# +# cpu/base.cc +# cpu/base_dyn_inst.cc +# cpu/exec_context.cc +# cpu/exetrace.cc +# cpu/pc_event.cc +# cpu/static_inst.cc +# cpu/o3/2bit_local_pred.cc +# cpu/o3/alpha_dyn_inst.cc +# cpu/o3/alpha_cpu.cc +# cpu/o3/alpha_cpu_builder.cc +# cpu/o3/bpred_unit.cc +# cpu/o3/btb.cc +# cpu/o3/commit.cc +# cpu/o3/decode.cc +# cpu/o3/fetch.cc +# cpu/o3/free_list.cc +# cpu/o3/cpu.cc +# cpu/o3/iew.cc +# cpu/o3/inst_queue.cc +# cpu/o3/ldstq.cc +# cpu/o3/mem_dep_unit.cc +# cpu/o3/ras.cc +# cpu/o3/rename.cc +# cpu/o3/rename_map.cc +# cpu/o3/rob.cc +# cpu/o3/sat_counter.cc +# cpu/o3/store_set.cc +# cpu/o3/tournament_pred.cc +# cpu/fast/cpu.cc +# cpu/sampler/sampler.cc +# cpu/simple/cpu.cc +# cpu/trace/reader/mem_trace_reader.cc +# cpu/trace/reader/ibm_reader.cc +# cpu/trace/reader/itx_reader.cc +# cpu/trace/reader/m5_reader.cc +# cpu/trace/opt_cpu.cc +# cpu/trace/trace_cpu.cc +# +# encumbered/cpu/full/bpred.cc +# encumbered/cpu/full/commit.cc +# encumbered/cpu/full/cpu.cc +# encumbered/cpu/full/create_vector.cc +# encumbered/cpu/full/cv_spec_state.cc +# encumbered/cpu/full/dd_queue.cc +# encumbered/cpu/full/dep_link.cc +# encumbered/cpu/full/dispatch.cc +# encumbered/cpu/full/dyn_inst.cc +# encumbered/cpu/full/execute.cc +# encumbered/cpu/full/fetch.cc +# encumbered/cpu/full/floss_reasons.cc +# encumbered/cpu/full/fu_pool.cc +# encumbered/cpu/full/inst_fifo.cc +# encumbered/cpu/full/instpipe.cc +# encumbered/cpu/full/issue.cc +# encumbered/cpu/full/ls_queue.cc +# encumbered/cpu/full/machine_queue.cc +# encumbered/cpu/full/pipetrace.cc +# encumbered/cpu/full/readyq.cc +# encumbered/cpu/full/reg_info.cc +# encumbered/cpu/full/rob_station.cc +# encumbered/cpu/full/spec_memory.cc +# encumbered/cpu/full/spec_state.cc +# encumbered/cpu/full/storebuffer.cc +# encumbered/cpu/full/writeback.cc +# encumbered/cpu/full/iq/iq_station.cc +# encumbered/cpu/full/iq/iqueue.cc +# encumbered/cpu/full/iq/segmented/chain_info.cc +# encumbered/cpu/full/iq/segmented/chain_wire.cc +# encumbered/cpu/full/iq/segmented/iq_seg.cc +# encumbered/cpu/full/iq/segmented/iq_segmented.cc +# encumbered/cpu/full/iq/segmented/seg_chain.cc +# encumbered/cpu/full/iq/seznec/iq_seznec.cc +# encumbered/cpu/full/iq/standard/iq_standard.cc +# encumbered/mem/functional/main.cc +# +# mem/base_hier.cc +# mem/base_mem.cc +# mem/hier_params.cc +# mem/mem_cmd.cc +# mem/mem_debug.cc +# mem/mem_req.cc +# mem/memory_interface.cc +# mem/bus/base_interface.cc +# mem/bus/bus.cc +# mem/bus/bus_bridge.cc +# mem/bus/bus_bridge_master.cc +# mem/bus/bus_bridge_slave.cc +# mem/bus/bus_interface.cc +# mem/bus/dma_bus_interface.cc +# mem/bus/dma_interface.cc +# mem/bus/master_interface.cc +# mem/bus/slave_interface.cc +# mem/cache/base_cache.cc +# mem/cache/cache.cc +# mem/cache/cache_builder.cc +# mem/cache/coherence/coherence_protocol.cc +# mem/cache/coherence/uni_coherence.cc +# mem/cache/miss/blocking_buffer.cc +# mem/cache/miss/miss_queue.cc +# mem/cache/miss/mshr.cc +# mem/cache/miss/mshr_queue.cc +# mem/cache/prefetch/base_prefetcher.cc +# mem/cache/prefetch/prefetcher.cc +# mem/cache/prefetch/tagged_prefetcher.cc +# mem/cache/tags/base_tags.cc +# mem/cache/tags/cache_tags.cc +# mem/cache/tags/fa_lru.cc +# mem/cache/tags/iic.cc +# mem/cache/tags/lru.cc +# mem/cache/tags/repl/gen.cc +# mem/cache/tags/repl/repl.cc +# mem/cache/tags/split.cc +# mem/cache/tags/split_lru.cc +# mem/cache/tags/split_lifo.cc +# mem/functional/functional.cc +# mem/timing/base_memory.cc +# mem/timing/memory_builder.cc +# mem/timing/simple_mem_bank.cc +# mem/trace/itx_writer.cc +# mem/trace/mem_trace_writer.cc +# mem/trace/m5_writer.cc +# +# python/pyconfig.cc +# python/embedded_py.cc +# +# sim/builder.cc +# sim/configfile.cc +# sim/debug.cc +# sim/eventq.cc +# sim/main.cc +# sim/param.cc +# sim/profile.cc +# sim/root.cc +# sim/serialize.cc +# sim/sim_events.cc +# sim/sim_exit.cc +# sim/sim_object.cc +# sim/startup.cc +# sim/stat_context.cc +# sim/stat_control.cc +# sim/trace_context.cc +# ''') + +# MySql sources +arch_mysql_sources = Split(''' + ''') +# base/mysql.cc +# base/stats/mysql.cc +# ''') + +# Full-system sources +arch_full_system_sources = Split(''' + arch/alpha/alpha_memory.cc + arch/alpha/arguments.cc + arch/alpha/ev5.cc + arch/alpha/osfpal.cc + arch/alpha/pseudo_inst.cc + arch/alpha/stacktrace.cc + arch/alpha/vtophys.cc + ''') + +# base/crc.cc +# base/inet.cc +# base/remote_gdb.cc +# +# cpu/intr_control.cc +# cpu/profile.cc +# +# dev/alpha_console.cc +# dev/baddev.cc +# dev/simconsole.cc +# dev/disk_image.cc +# dev/etherbus.cc +# dev/etherdump.cc +# dev/etherint.cc +# dev/etherlink.cc +# dev/etherpkt.cc +# dev/ethertap.cc +# dev/ide_ctrl.cc +# dev/ide_disk.cc +# dev/io_device.cc +# dev/ns_gige.cc +# dev/pciconfigall.cc +# dev/pcidev.cc +# dev/pcifake.cc +# dev/pktfifo.cc +# dev/platform.cc +# dev/sinic.cc +# dev/simple_disk.cc +# dev/tsunami.cc +# dev/tsunami_cchip.cc +# dev/isa_fake.cc +# dev/tsunami_io.cc +# dev/tsunami_pchip.cc +# dev/uart.cc +# dev/uart8250.cc +# +# kern/kernel_binning.cc +# kern/kernel_stats.cc +# kern/system_events.cc +# kern/freebsd/freebsd_system.cc +# kern/linux/linux_syscalls.cc +# kern/linux/linux_system.cc +# kern/linux/printk.cc +# kern/tru64/dump_mbuf.cc +# kern/tru64/printf.cc +# kern/tru64/tru64_events.cc +# kern/tru64/tru64_syscalls.cc +# kern/tru64/tru64_system.cc +# +# mem/functional/memory_control.cc +# mem/functional/physical.cc +# +# sim/system.cc +# ''') + +# turbolaser encumbered sources +arch_turbolaser_sources = Split(''' + ''') +# encumbered/dev/dma.cc +# encumbered/dev/etherdev.cc +# encumbered/dev/scsi.cc +# encumbered/dev/scsi_ctrl.cc +# encumbered/dev/scsi_disk.cc +# encumbered/dev/scsi_none.cc +# encumbered/dev/tlaser_clock.cc +# encumbered/dev/tlaser_ipi.cc +# encumbered/dev/tlaser_mbox.cc +# encumbered/dev/tlaser_mc146818.cc +# encumbered/dev/tlaser_node.cc +# encumbered/dev/tlaser_pcia.cc +# encumbered/dev/tlaser_pcidev.cc +# encumbered/dev/tlaser_serial.cc +# encumbered/dev/turbolaser.cc +# encumbered/dev/uart8530.cc +# ''') + +# Syscall emulation (non-full-system) sources +arch_syscall_emulation_sources = Split(''' + arch/alpha/alpha_common_syscall_emul.cc + arch/alpha/alpha_linux_process.cc + arch/alpha/alpha_tru64_process.cc + ''') +# cpu/memtest/memtest.cc +# encumbered/eio/eio.cc +# encumbered/eio/exolex.cc +# encumbered/eio/libexo.cc +# sim/process.cc +# sim/syscall_emul.cc +# ''') + +#targetarch_files = Split(''' +# alpha_common_syscall_emul.hh +# alpha_linux_process.hh +# alpha_memory.hh +# alpha_tru64_process.hh +# aout_machdep.h +# arguments.hh +# byte_swap.hh +# ecoff_machdep.h +# ev5.hh +# faults.hh +# isa_fullsys_traits.hh +# isa_traits.hh +# osfpal.hh +# pseudo_inst.hh +# stacktrace.hh +# vptr.hh +# vtophys.hh +# ''') + +#for f in targetarch_files: +# env.Command('targetarch/' + f, 'arch/alpha/' + f, +# '''echo '#include "arch/alpha/%s"' > $TARGET''' % f) + + +# Set up complete list of sources based on configuration. +sources = arch_base_sources + +if env['FULL_SYSTEM']: + sources += arch_full_system_sources + if env['ALPHA_TLASER']: + sources += arch_turbolaser_sources +else: + sources += arch_syscall_emulation_sources + +if env['USE_MYSQL']: + sources += arch_mysql_sources + +for opt in env.ExportOptions: + env.ConfigFile(opt) + +################################################### +# +# Special build rules. +# +################################################### + +# base/traceflags.{cc,hh} are generated from base/traceflags.py. +# $TARGET.base will expand to "/base/traceflags". +# env.Command(Split('base/traceflags.hh base/traceflags.cc'), +# 'base/traceflags.py', +# 'python $SOURCE $TARGET.base') + +# several files are generated from arch/$TARGET_ISA/isa_desc. +#env.Command(Split('''decoder.cc +# decoder.hh +# alpha_o3_exec.cc +# fast_cpu_exec.cc +# simple_cpu_exec.cc +# full_cpu_exec.cc'''), +# Split('''isa_desc +# ../isa_parser.py'''), +# '$SRCDIR/arch/isa_parser.py $SOURCE $TARGET.dir arch/alpha') + + +# libelf build is described in its own SConscript file. +# SConscript-local is the per-config build, which just copies some +# header files into a place where they can be found. +# SConscript('libelf/SConscript-local', exports = 'env', duplicate=0) +# SConscript('python/SConscript', exports = ['env'], duplicate=0) + +# This function adds the specified sources to the given build +# environment, and returns a list of all the corresponding SCons +# Object nodes (including an extra one for date.cc). We explicitly +# add the Object nodes so we can set up special dependencies for +# date.cc. +# def make_objs(sources, env): +# objs = [env.Object(s) for s in sources] +# # make date.cc depend on all other objects so it always gets +# # recompiled whenever anything else does +# date_obj = env.Object('base/date.cc') +# base/traceflags.{cc,hh} are generated from base/traceflags.py. +# $TARGET.base will expand to "/base/traceflags". +# env.Command(Split('base/traceflags.hh base/traceflags.cc'), +# 'base/traceflags.py', +# 'python $SOURCE $TARGET.base') +# +# Split('''arch/alpha/isa_desc +# arch/isa_parser.py'''), +# env.Depends(date_obj, objs) +# objs.append(date_obj) +# return objs + +################################################### +# +# Define binaries. Each different build type (debug, opt, etc.) gets +# a slightly different build environment. +# +################################################### + +# Include file paths are rooted in this directory. SCons will +# automatically expand '.' to refer to both the source directory and +# the corresponding build directory to pick up generated include +# files. +# env.Append(CPPPATH='.') + +# Debug binary +# debugEnv = env.Copy(OBJSUFFIX='.do') +# debugEnv.Label = 'debug' +# debugEnv.Append(CCFLAGS=Split('-g -gstabs+ -O0')) +# debugEnv.Append(CPPDEFINES='DEBUG') +# tlist = debugEnv.Program(target = 'm5.debug', +# source = make_objs(sources, debugEnv)) +# debugEnv.M5Binary = tlist[0] + +# Optimized binary +# optEnv = env.Copy() +# optEnv.Label = 'opt' +# optEnv.Append(CCFLAGS=Split('-g -O5')) +# tlist = optEnv.Program(target = 'm5.opt', +# source = make_objs(sources, optEnv)) +# optEnv.M5Binary = tlist[0] + +# "Fast" binary +# fastEnv = env.Copy(OBJSUFFIX='.fo') +# fastEnv.Label = 'fast' +# fastEnv.Append(CCFLAGS=Split('-O5')) +# fastEnv.Append(CPPDEFINES='NDEBUG') +# fastEnv.Program(target = 'm5.fast.unstripped', +# source = make_objs(sources, fastEnv)) +# tlist = fastEnv.Command(target = 'm5.fast', +# source = 'm5.fast.unstripped', +# action = 'strip $SOURCE -o $TARGET') +# fastEnv.M5Binary = tlist[0] + +# Profiled binary +# profEnv = env.Copy(OBJSUFFIX='.po') +# profEnv.Label = 'prof' +# profEnv.Append(CCFLAGS=Split('-O5 -g -pg'), LINKFLAGS='-pg') +# tlist = profEnv.Program(target = 'm5.prof', +# source = make_objs(sources, profEnv)) +# profEnv.M5Binary = tlist[0] +# +# envList = [debugEnv, optEnv, fastEnv, profEnv] +# +# Return('envList') +Return('sources') diff --git a/arch/isa_parser.py b/arch/isa_parser.py index 8f4c6bce7..6a8935963 100755 --- a/arch/isa_parser.py +++ b/arch/isa_parser.py @@ -91,6 +91,14 @@ tokens = reserved + ( # C preprocessor directives 'CPPDIRECTIVE' + +# The following are matched but never returned. commented out to +# suppress PLY warning + # newfile directive +# 'NEWFILE', + + # endfile directive +# 'ENDFILE' ) # Regular expressions for token matching @@ -149,10 +157,20 @@ def t_CODELIT(t): return t def t_CPPDIRECTIVE(t): - r'^\#.*\n' + r'^\#[^\#].*\n' t.lineno += t.value.count('\n') return t +def t_NEWFILE(t): + r'^\#\#newfile[ /t]*\"[A-Za-z0-9\\/-_.]*\"' + global fileNameStack + fileNameStack.append((t.value[11:-1], t.lineno)) + t.lineno = 0 + +def t_ENDFILE(t): + r'^\#\#endfile' + (filename, t.lineno) = fileNameStack.pop() + # # The functions t_NEWLINE, t_ignore, and t_error are # special for the lex module. @@ -852,7 +870,12 @@ def fixPythonIndentation(s): # Error handler. Just call exit. Output formatted to work under # Emacs compile-mode. def error(lineno, string): - sys.exit("%s:%d: %s" % (input_filename, lineno, string)) + global fileNameStack + spaces = "" + for (filename, line) in fileNameStack[0:-1]: + print spaces + "In file included from " + filename + spaces += " " + sys.exit(spaces + "%s:%d: %s" % (fileNameStack[-1][0], lineno, string)) # Like error(), but include a Python stack backtrace (for processing # Python exceptions). @@ -1601,6 +1624,25 @@ def update_if_needed(file, contents): f.write(contents) f.close() +# This regular expression matches include directives +regExp = re.compile('(?P^[ \t]*##include[ \t]*\"[ \t]*(?P[A-Za-z0-9\\/-_.]*)[ \t]*\"[ \t]*\n)', re.MULTILINE) + +def preprocess_isa_desc(isa_desc): + # Find any includes and include them + + # Look for an include + m = re.search(regExp, isa_desc) + while m: + filename = m.group('filename') + print 'Including file "%s"' % filename + includeFile = open(filename) + includecontents = includeFile.read() + isa_desc = isa_desc[:m.start('include')] + '##newfile "' + filename + '"\n' + includecontents + '##endfile\n' + isa_desc[m.end('include'):] + # Look for the next include + m = re.search(regExp, isa_desc) + return isa_desc + + # # Read in and parse the ISA description. # @@ -1608,12 +1650,17 @@ def parse_isa_desc(isa_desc_file, output_dir, include_path): # set a global var for the input filename... used in error messages global input_filename input_filename = isa_desc_file + global fileNameStack + fileNameStack = [(input_filename, 1)] # Suck the ISA description file in. input = open(isa_desc_file) isa_desc = input.read() input.close() + # Perform Preprocessing + isa_desc = preprocess_isa_desc(isa_desc) + # Parse it. (isa_name, namespace, global_code, namespace_code) = yacc.parse(isa_desc) diff --git a/arch/sparc/isa_desc/operands.h b/arch/sparc/isa_desc/operands.h new file mode 100644 index 000000000..77de6c9c4 --- /dev/null +++ b/arch/sparc/isa_desc/operands.h @@ -0,0 +1,33 @@ +def operand_types {{ + 'sb' : ('signed int', 8), + 'ub' : ('unsigned int', 8), + 'shw' : ('signed int', 16), + 'uhw' : ('unsigned int', 16), + 'sw' : ('signed int', 32), + 'uw' : ('unsigned int', 32), + 'sdw' : ('signed int', 64), + 'udw' : ('unsigned int', 64), + 'sf' : ('float', 32), + 'df' : ('float', 64), + 'qf' : ('float', 128) +}}; + +def operands {{ + # Int regs default to unsigned, but code should not count on this. + # For clarity, descriptions that depend on unsigned behavior should + # explicitly specify '.uq'. + 'Rd': IntRegOperandTraits('udw', 'RD', 'IsInteger', 1), + 'Rs1': IntRegOperandTraits('udw', 'RS1', 'IsInteger', 2), + 'Rs2': IntRegOperandTraits('udw', 'RS2', 'IsInteger', 3), + #'Fa': FloatRegOperandTraits('df', 'FA', 'IsFloating', 1), + #'Fb': FloatRegOperandTraits('df', 'FB', 'IsFloating', 2), + #'Fc': FloatRegOperandTraits('df', 'FC', 'IsFloating', 3), + 'Mem': MemOperandTraits('udw', None, + ('IsMemRef', 'IsLoad', 'IsStore'), 4) + #'NPC': NPCOperandTraits('uq', None, ( None, None, 'IsControl' ), 4), + #'Runiq': ControlRegOperandTraits('uq', 'Uniq', None, 1), + #'FPCR': ControlRegOperandTraits('uq', 'Fpcr', None, 1), + # The next two are hacks for non-full-system call-pal emulation + #'R0': IntRegOperandTraits('uq', '0', None, 1), + #'R16': IntRegOperandTraits('uq', '16', None, 1) +}}; diff --git a/arch/sparc/isa_traits.cc b/arch/sparc/isa_traits.cc new file mode 100644 index 000000000..c7a25f88d --- /dev/null +++ b/arch/sparc/isa_traits.cc @@ -0,0 +1,57 @@ +/* + * 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/isa_traits.hh" +#include "cpu/static_inst.hh" +#include "sim/serialize.hh" + +// Alpha UNOP (ldq_u r31,0(r0)) +const MachInst SPARCISA::NoopMachInst = 0x2ffe0000; + +void +SPARCISA::RegFile::serialize(std::ostream &os) +{ + intRegFile.serialize(os); + floatRegFile.serialize(os); + miscRegs.serialize(os); + SERIALIZE_SCALAR(pc); + SERIALIZE_SCALAR(npc); +} + + +void +AlphaISA::RegFile::unserialize(Checkpoint *cp, const std::string §ion) +{ + intRegFile.unserialize(cp, section); + floatRegFile.unserialize(cp, section); + miscRegs.unserialize(cp, section); + UNSERIALIZE_SCALAR(pc); + UNSERIALIZE_SCALAR(npc); +} + +#endif //FULL_SYSTEM diff --git a/arch/sparc/isa_traits.hh b/arch/sparc/isa_traits.hh new file mode 100644 index 000000000..9513b99fc --- /dev/null +++ b/arch/sparc/isa_traits.hh @@ -0,0 +1,528 @@ +/* + * Copyright (c) 2003-2005 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __ARCH_SPARC_ISA_TRAITS_HH__ +#define __ARCH_SPARC_ISA_TRAITS_HH__ + +#include "arch/sparc/faults.hh" +#include "base/misc.hh" +#include "sim/host.hh" + +class FastCPU; +//class FullCPU; +//class Checkpoint; + +#define TARGET_SPARC + +template class StaticInst; +template class StaticInstPtr; + +//namespace EV5 +//{ +// int DTB_ASN_ASN(uint64_t reg); +// int ITB_ASN_ASN(uint64_t reg); +//} + +class SPARCISA +{ + public: + + typedef uint32_t MachInst; + typedef uint64_t Addr; + typedef uint8_t RegIndex; + + enum + { + MemoryEnd = 0xffffffffffffffffULL, + + NumFloatRegs = 32, + NumMiscRegs = 32, + + MaxRegsOfAnyType = 32, + // Static instruction parameters + MaxInstSrcRegs = 3, + MaxInstDestRegs = 2, + + // Maximum trap level + MaxTL = 4 + + // semantically meaningful register indices + ZeroReg = 0, // architecturally meaningful + // the rest of these depend on the ABI + } + typedef uint64_t IntReg; + + class IntRegFile + { + private: + //For right now, let's pretend the register file is static + IntReg regs[32]; + public: + IntReg & operator [] (RegIndex index) + { + //Don't allow indexes outside of the 32 registers + index &= 0x1F + return regs[index]; + } + }; + + void inline serialize(std::ostream & os) + { + SERIALIZE_ARRAY(regs, 32); + } + + void inline unserialize(Checkpoint &*cp, const std::string §ion) + { + UNSERIALIZE_ARRAY(regs, 32); + } + + class FloatRegFile + { + private: + //By using the largest data type, we ensure everything + //is aligned correctly in memory + union + { + double double rawRegs[16]; + uint64_t regDump[32]; + }; + class QuadRegs + { + private: + FloatRegFile * parent; + public: + QuadRegs(FloatRegFile * p) : parent(p) {;} + double double & operator [] (RegIndex index) + { + //Quad floats are index by the single + //precision register the start on, + //and only 16 should be accessed + index = (index >> 2) & 0xF; + return parent->rawRegs[index]; + } + }; + class DoubleRegs + { + private: + FloatRegFile * parent; + public: + DoubleRegs(FloatRegFile * p) : parent(p) {;} + double & operator [] (RegIndex index) + { + //Double floats are index by the single + //precision register the start on, + //and only 32 should be accessed + index = (index >> 1) & 0x1F + return ((double [])parent->rawRegs)[index]; + } + } + class SingleRegs + { + private: + FloatRegFile * parent; + public: + SingleRegs(FloatRegFile * p) : parent(p) {;} + double & operator [] (RegFile index) + { + //Only 32 single floats should be accessed + index &= 0x1F + return ((float [])parent->rawRegs)[index]; + } + } + public: + void inline serialize(std::ostream & os) + { + SERIALIZE_ARRAY(regDump, 32); + } + + void inline unserialize(Checkpoint &* cp, std::string & section) + { + UNSERIALIZE_ARRAY(regDump, 32); + } + + QuadRegs quadRegs; + DoubleRegs doubleRegs; + SingleRegs singleRegs; + FloatRegFile() : quadRegs(this), doubleRegs(this), singleRegs(this) + {;} + }; + + // control register file contents + typedef uint64_t MiscReg; + // The control registers, broken out into fields + class MiscRegFile + { + public: + union + { + uint16_t pstate; // Process State Register + struct + { + uint16_t ag:1; // Alternate Globals + uint16_t ie:1; // Interrupt enable + uint16_t priv:1; // Privelege mode + uint16_t am:1; // Address mask + uint16_t pef:1; // PSTATE enable floating-point + uint16_t red:1; // RED (reset, error, debug) state + uint16_t mm:2; // Memory Model + uint16_t tle:1; // Trap little-endian + uint16_t cle:1; // Current little-endian + } pstateFields; + } + uint64_t tba; // Trap Base Address + union + { + uint64_t y; // Y (used in obsolete multiplication) + struct + { + uint64_t value:32; // The actual value stored in y + const uint64_t :32; // reserved bits + } yFields; + } + uint8_t pil; // Process Interrupt Register + uint8_t cwp; // Current Window Pointer + uint16_t tt[MaxTL]; // Trap Type (Type of trap which occured on the previous level) + union + { + uint8_t ccr; // Condition Code Register + struct + { + union + { + uint8_t icc:4; // 32-bit condition codes + struct + { + uint8_t c:1; // Carry + uint8_t v:1; // Overflow + uint8_t z:1; // Zero + uint8_t n:1; // Negative + } iccFields:4; + } :4; + union + { + uint8_t xcc:4; // 64-bit condition codes + struct + { + uint8_t c:1; // Carry + uint8_t v:1; // Overflow + uint8_t z:1; // Zero + uint8_t n:1; // Negative + } xccFields:4; + } :4; + } ccrFields; + } + uint8_t asi; // Address Space Identifier + uint8_t tl; // Trap Level + uint64_t tpc[MaxTL]; // Trap Program Counter (value from previous trap level) + uint64_t tnpc[MaxTL]; // Trap Next Program Counter (value from previous trap level) + union + { + uint64_t tstate[MaxTL]; // Trap State + struct + { + //Values are from previous trap level + uint64_t cwp:5; // Current Window Pointer + const uint64_t :2; // Reserved bits + uint64_t pstate:10; // Process State + const uint64_t :6; // Reserved bits + uint64_t asi:8; // Address Space Identifier + uint64_t ccr:8; // Condition Code Register + } tstateFields[MaxTL]; + } + union + { + uint64_t tick; // Hardware clock-tick counter + struct + { + uint64_t counter:63; // Clock-tick count + uint64_t npt:1; // Non-priveleged trap + } tickFields; + } + uint8_t cansave; // Savable windows + uint8_t canrestore; // Restorable windows + uint8_t otherwin; // Other windows + uint8_t cleanwin; // Clean windows + union + { + uint8_t wstate; // Window State + struct + { + uint8_t normal:3; // Bits TT<4:2> are set to on a normal + // register window trap + uint8_t other:3; // Bits TT<4:2> are set to on an "otherwin" + // register window trap + } wstateFields; + } + union + { + uint64_t ver; // Version + struct + { + uint64_t maxwin:5; // Max CWP value + const uint64_t :2; // Reserved bits + uint64_t maxtl:8; // Maximum trap level + const uint64_t :8; // Reserved bits + uint64_t mask:8; // Processor mask set revision number + uint64_t impl:16; // Implementation identification number + uint64_t manuf:16; // Manufacturer code + } verFields; + } + union + { + uint64_t fsr; // Floating-Point State Register + struct + { + union + { + uint64_t cexc:5; // Current excpetion + struct + { + uint64_t nxc:1; // Inexact + uint64_t dzc:1; // Divide by zero + uint64_t ufc:1; // Underflow + uint64_t ofc:1; // Overflow + uint64_t nvc:1; // Invalid operand + } cexecFields:5; + } :5; + union + { + uint64_t aexc:5; // Accrued exception + struct + { + uint64_t nxc:1; // Inexact + uint64_t dzc:1; // Divide by zero + uint64_t ufc:1; // Underflow + uint64_t ofc:1; // Overflow + uint64_t nvc:1; // Invalid operand + } aexecFields:5; + } :5; + uint64_t fcc0:2; // Floating-Point condtion codes + const uint64_t :1; // Reserved bits + uint64_t qne:1; // Deferred trap queue not empty + // with no queue, it should read 0 + uint64_t ftt:3; // Floating-Point trap type + uint64_t ver:3; // Version (of the FPU) + const uint64_t :2; // Reserved bits + uint64_t ns:1; // Nonstandard floating point + union + { + uint64_t tem:5; // Trap Enable Mask + struct + { + uint64_t nxm:1; // Inexact + uint64_t dzm:1; // Divide by zero + uint64_t ufm:1; // Underflow + uint64_t ofm:1; // Overflow + uint64_t nvm:1; // Invalid operand + } temFields:5; + } :5; + const uint64_t :2; // Reserved bits + uint64_t rd:2; // Rounding direction + uint64_t fcc1:2; // Floating-Point condition codes + uint64_t fcc2:2; // Floating-Point condition codes + uint64_t fcc3:2; // Floating-Point condition codes + const uint64_t :26; // Reserved bits + } fsrFields; + } + union + { + uint8_t fprs; // Floating-Point Register State + struct + { + dl:1; // Dirty lower + du:1; // Dirty upper + fef:1; // FPRS enable floating-Point + } fprsFields; + }; + + void serialize(std::ostream & os) + { + SERIALIZE_SCALAR(pstate); + SERIAlIZE_SCALAR(tba); + SERIALIZE_SCALAR(y); + SERIALIZE_SCALAR(pil); + SERIALIZE_SCALAR(cwp); + SERIALIZE_ARRAY(tt, MaxTL); + SERIALIZE_SCALAR(ccr); + SERIALIZE_SCALAR(asi); + SERIALIZE_SCALAR(tl); + SERIALIZE_SCALAR(tpc); + SERIALIZE_SCALAR(tnpc); + SERIALIZE_ARRAY(tstate, MaxTL); + SERIALIZE_SCALAR(tick); + SERIALIZE_SCALAR(cansave); + SERIALIZE_SCALAR(canrestore); + SERIALIZE_SCALAR(otherwin); + SERIALIZE_SCALAR(cleanwin); + SERIALIZE_SCALAR(wstate); + SERIALIZE_SCALAR(ver); + SERIALIZE_SCALAR(fsr); + SERIALIZE_SCALAR(fprs); + } + + void unserialize(Checkpoint &* cp, std::string & section) + { + UNSERIALIZE_SCALAR(pstate); + UNSERIAlIZE_SCALAR(tba); + UNSERIALIZE_SCALAR(y); + UNSERIALIZE_SCALAR(pil); + UNSERIALIZE_SCALAR(cwp); + UNSERIALIZE_ARRAY(tt, MaxTL); + UNSERIALIZE_SCALAR(ccr); + UNSERIALIZE_SCALAR(asi); + UNSERIALIZE_SCALAR(tl); + UNSERIALIZE_SCALAR(tpc); + UNSERIALIZE_SCALAR(tnpc); + UNSERIALIZE_ARRAY(tstate, MaxTL); + UNSERIALIZE_SCALAR(tick); + UNSERIALIZE_SCALAR(cansave); + UNSERIALIZE_SCALAR(canrestore); + UNSERIALIZE_SCALAR(otherwin); + UNSERIALIZE_SCALAR(cleanwin); + UNSERIALIZE_SCALAR(wstate); + UNSERIALIZE_SCALAR(ver); + UNSERIALIZE_SCALAR(fsr); + UNSERIALIZE_SCALAR(fprs); + } + }; + + typedef union + { + IntReg intreg; + FloatReg fpreg; + MiscReg ctrlreg; + } AnyReg; + + struct RegFile + { + IntRegFile intRegFile; // (signed) integer register file + FloatRegFile floatRegFile; // floating point register file + MiscRegFile miscRegFile; // control register file + + Addr pc; // Program Counter + Addr npc; // Next Program Counter + + void serialize(std::ostream &os); + void unserialize(Checkpoint *cp, const std::string §ion); + }; + + static StaticInstPtr decodeInst(MachInst); + + // return a no-op instruction... used for instruction fetch faults + static const MachInst NoopMachInst; + + // Instruction address compression hooks + static inline Addr realPCToFetchPC(const Addr &addr) + { + return addr; + } + + static inline Addr fetchPCToRealPC(const Addr &addr) + { + return addr; + } + + // the size of "fetched" instructions (not necessarily the size + // of real instructions for PISA) + static inline size_t fetchInstSize() + { + return sizeof(MachInst); + } + + /** + * Function to insure ISA semantics about 0 registers. + * @param xc The execution context. + */ + template + static void zeroRegisters(XC *xc); +}; + + +typedef SPARCISA TheISA; + +typedef TheISA::MachInst MachInst; +typedef TheISA::Addr Addr; +typedef TheISA::RegIndex RegIndex; +typedef TheISA::IntReg IntReg; +typedef TheISA::IntRegFile IntRegFile; +typedef TheISA::FloatReg FloatReg; +typedef TheISA::FloatRegFile FloatRegFile; +typedef TheISA::MiscReg MiscReg; +typedef TheISA::MiscRegFile MiscRegFile; +typedef TheISA::AnyReg AnyReg; +typedef TheISA::RegFile RegFile; + +const int VMPageSize = TheISA::VMPageSize; +const int LogVMPageSize = TheISA::LogVMPageSize; +const int ZeroReg = TheISA::ZeroReg; +const int BranchPredAddrShiftAmt = TheISA::BranchPredAddrShiftAmt; +const int MaxAddr = (Addr)-1; + +#ifndef FULL_SYSTEM +class SyscallReturn { + public: + template + SyscallReturn(T v, bool s) + { + retval = (uint64_t)v; + success = s; + } + + template + SyscallReturn(T v) + { + success = (v >= 0); + retval = (uint64_t)v; + } + + ~SyscallReturn() {} + + SyscallReturn& operator=(const SyscallReturn& s) { + retval = s.retval; + success = s.success; + return *this; + } + + bool successful() { return success; } + uint64_t value() { return retval; } + + + private: + uint64_t retval; + bool success; +}; + +#endif + + +#ifdef FULL_SYSTEM + +#include "arch/alpha/ev5.hh" +#endif + +#endif // __ARCH_SPARC_ISA_TRAITS_HH__ diff --git a/build/SConstruct b/build/SConstruct index 45461b0af..72b0930e1 100644 --- a/build/SConstruct +++ b/build/SConstruct @@ -223,7 +223,7 @@ env = conf.Finish() # value becomes sticky). sticky_opts = Options(args=ARGUMENTS) sticky_opts.AddOptions( - EnumOption('TARGET_ISA', 'Target ISA', 'alpha', ('alpha')), + EnumOption('TARGET_ISA', 'Target ISA', 'alpha', ('alpha', 'sparc')), BoolOption('FULL_SYSTEM', 'Full-system support', False), BoolOption('ALPHA_TLASER', 'Model Alpha TurboLaser platform (vs. Tsunami)', False), @@ -320,6 +320,10 @@ base_env = env for build_dir in build_dirs: # Make a copy of the default environment to use for this config. env = base_env.Copy() + + # Record what build_dir was in the environment + env.Append(BUILD_DIR=build_dir); + # Set env according to the build directory config. sticky_opts.files = [] diff --git a/build/build_options/default/SPARC_SE b/build/build_options/default/SPARC_SE new file mode 100644 index 000000000..3b256fc34 --- /dev/null +++ b/build/build_options/default/SPARC_SE @@ -0,0 +1,2 @@ +TARGET_ISA = 'sparc' +FULL_SYSTEM = 0 From 90aa2dbfc226f6b34165603b38f102312008c23c Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Wed, 25 Jan 2006 14:43:47 -0500 Subject: [PATCH 003/180] initial changes to decoder.hh and copied files from arch/sparc directory arch/mips/isa_desc/bitfields.h: arch/mips/isa_desc/formats.h: arch/mips/isa_desc/formats/basic.format: arch/mips/isa_desc/formats/branch.format: arch/mips/isa_desc/formats/integerop.format: arch/mips/isa_desc/formats/mem.format: arch/mips/isa_desc/formats/noop.format: arch/mips/isa_desc/formats/trap.format: arch/mips/isa_desc/includes.h: arch/mips/isa_desc/operands.h: arch/mips/isa_traits.cc: arch/mips/isa_traits.hh: copied from sparc ISA directory arch/mips/isa_desc/decoder.h: decoder I started to work on... --HG-- rename : arch/sparc/isa_desc/bitfields.h => arch/mips/isa_desc/bitfields.h rename : arch/sparc/isa_desc/decoder.h => arch/mips/isa_desc/decoder.h rename : arch/sparc/isa_desc/formats.h => arch/mips/isa_desc/formats.h rename : arch/sparc/isa_desc/formats/basic.format => arch/mips/isa_desc/formats/basic.format rename : arch/sparc/isa_desc/formats/branch.format => arch/mips/isa_desc/formats/branch.format rename : arch/sparc/isa_desc/formats/integerop.format => arch/mips/isa_desc/formats/integerop.format rename : arch/sparc/isa_desc/formats/mem.format => arch/mips/isa_desc/formats/mem.format rename : arch/sparc/isa_desc/formats/noop.format => arch/mips/isa_desc/formats/noop.format rename : arch/sparc/isa_desc/formats/trap.format => arch/mips/isa_desc/formats/trap.format rename : arch/sparc/isa_desc/includes.h => arch/mips/isa_desc/includes.h rename : arch/sparc/isa_desc/operands.h => arch/mips/isa_desc/operands.h rename : arch/sparc/isa_traits.cc => arch/mips/isa_traits.cc rename : arch/sparc/isa_traits.hh => arch/mips/isa_traits.hh extra : convert_revision : d4f281960ecf2dce479fb665469c6f2c5dd3063e --- arch/{sparc => mips}/isa_desc/bitfields.h | 0 arch/mips/isa_desc/decoder.h | 991 ++++++++++++++++++ arch/{sparc => mips}/isa_desc/formats.h | 0 .../isa_desc/formats/basic.format | 0 .../isa_desc/formats/branch.format | 0 .../isa_desc/formats/integerop.format | 0 .../isa_desc/formats/mem.format | 0 .../isa_desc/formats/noop.format | 0 .../isa_desc/formats/trap.format | 0 arch/{sparc => mips}/isa_desc/includes.h | 0 arch/{sparc => mips}/isa_desc/operands.h | 0 arch/{sparc => mips}/isa_traits.cc | 0 arch/{sparc => mips}/isa_traits.hh | 0 arch/sparc/isa_desc/decoder.h | 638 ----------- 14 files changed, 991 insertions(+), 638 deletions(-) rename arch/{sparc => mips}/isa_desc/bitfields.h (100%) create mode 100644 arch/mips/isa_desc/decoder.h rename arch/{sparc => mips}/isa_desc/formats.h (100%) rename arch/{sparc => mips}/isa_desc/formats/basic.format (100%) rename arch/{sparc => mips}/isa_desc/formats/branch.format (100%) rename arch/{sparc => mips}/isa_desc/formats/integerop.format (100%) rename arch/{sparc => mips}/isa_desc/formats/mem.format (100%) rename arch/{sparc => mips}/isa_desc/formats/noop.format (100%) rename arch/{sparc => mips}/isa_desc/formats/trap.format (100%) rename arch/{sparc => mips}/isa_desc/includes.h (100%) rename arch/{sparc => mips}/isa_desc/operands.h (100%) rename arch/{sparc => mips}/isa_traits.cc (100%) rename arch/{sparc => mips}/isa_traits.hh (100%) delete mode 100644 arch/sparc/isa_desc/decoder.h diff --git a/arch/sparc/isa_desc/bitfields.h b/arch/mips/isa_desc/bitfields.h similarity index 100% rename from arch/sparc/isa_desc/bitfields.h rename to arch/mips/isa_desc/bitfields.h diff --git a/arch/mips/isa_desc/decoder.h b/arch/mips/isa_desc/decoder.h new file mode 100644 index 000000000..5d71968ce --- /dev/null +++ b/arch/mips/isa_desc/decoder.h @@ -0,0 +1,991 @@ +//////////////////////////////////////////////////////////////////// +// +// The actual MIPS32 ISA decoder +// ----------------------------- +// The following instructions are specified in the MIPS32 ISA +// Specification. Decoding closely follows the style specified +// in the MIPS32 ISAthe specification document starting with Table +// A-2 (document available @ www.mips.com) +// +// +decode OPCODE_HI default FailUnimpl::unknown() { + + // Derived From ... Table A-2 MIPS32 ISA Manual + 0x0: decode OPCODE_LO { + + 0x0: decode SPECIAL { + 0x0:; + 0x1:; + 0x2:; + 0x3:; + 0x4:; + 0x5:; + 0x6:; + } + + 0x1: decode REGIMM { + 0x0:; + 0x1:; + 0x2:; + 0x3:; + 0x4:; + 0x5:; + 0x6:; + } + + format Jump { + 0x2: j({{ }}); + 0x3: jal({{ }}); + } + + format Branch { + 0x4: beq({{ }}); + 0x5: bne({{ }}); + 0x6: blez({{ }}); + 0x7: bgtz({{ }}); + } + }; + + 0x1: decode OPCODE_LO { + format IntImmediate { + 0x0: addi({{ }}); + 0x1: addiu({{ }}); + 0x2: slti({{ }}); + 0x3: sltiu({{ }}); + 0x4: andi({{ }}); + 0x5: ori({{ }}); + 0x6: xori({{ }}); + 0x7: lui({{ }}); + }; + }; + + 0x2: decode OPCODE_LO { + format FailUnimpl{ + 0x0: coprocessor_op({{ }}); + 0x1: coprocessor_op({{ }}); + 0x2: coprocessor_op({{ }}); + 0x3: coprocessor_op({{ }}); + }; + + //MIPS obsolete instructions + 0x4: beql({{ }}); + 0x5: bnel({{ }}); + 0x6: blezl({{ }}); + 0x7: bgtzl({{ }}); + }; + + 0x3: decode OPCODE_LO { + format FailUnimpl{ + 0x0: reserved({{ }}) + 0x1: reserved({{ }}) + 0x2: reserved({{ }}) + 0x3: reserved({{ }}) + 0x5: reserved({{ }}) + 0x6: reserved({{ }}) + }; + + 4: decode SPECIAL2 { + 0x0:; + 0x1:; + 0x2:; + 0x3:; + 0x4:; + 0x5:; + 0x6:; + } + + 7: decode SPECIAL3 { + 0x0:; + 0x1:; + 0x2:; + 0x3:; + 0x4:; + 0x5:; + 0x6:; + } + }; + + 0x4: decode OPCODE_LO { + format LoadMemory{ + 0x0: lb({{ }}); + 0x1: lh({{ }}); + 0x2: lwl({{ }}); + 0x3: lw({{ }}); + 0x4: lbu({{ }}); + 0x5: lhu({{ }}); + 0x6: lhu({{ }}); + }; + + 0x7: FailUnimpl::reserved({{ }}); + }; + + 0x5: decode OPCODE_LO { + format StoreMemory{ + 0x0: sb({{ }}); + 0x1: sh({{ }}); + 0x2: swl({{ }}); + 0x3: sw({{ }}); + 0x6: swr({{ }}); + }; + + format FailUnimpl{ + 0x4: reserved({{ }}); + 0x5: reserved({{ }}); + 0x2: cache({{ }}); + }; + + }; + + 0x6: decode OPCODE_LO { + format LoadMemory{ + 0x0: ll({{ }}); + 0x1: lwc1({{ }}); + 0x5: ldc1({{ }}); + }; + + format FailUnimpl{ + 0x2: lwc2({{ }}); + 0x3: pref({{ }}); + 0x4: reserved({{ }}); + 0x6: ldc2({{ }}); + 0x7: reserved({{ }}); + }; + + }; + + 0x7: decode OPCODE_LO { + format StoreMemory{ + 0x0: sc({{ }}); + 0x1: swc1({{ }}); + 0x5: sdc1({{ }}); + }; + + format FailUnimpl{ + 0x2: swc2({{ }}); + 0x3: reserved({{ }}); + 0x4: reserved({{ }}); + 0x6: sdc2({{ }}); + 0x7: reserved({{ }}); + }; + + }; + + + //Table 3-1 CPU Arithmetic Instructions ( ) + format IntegerOperate { + + 0x10: decode INTFUNC { // integer arithmetic operations + + //ADD Add Word + + //ADDI Add Immediate Word + + //ADDIU Add Immediate Unsigned Word + + //ADDU Add Unsigned Word + + 0x00: addl({{ Rc.sl = Ra.sl + Rb_or_imm.sl; }}); + 0x40: addlv({{ + uint32_t tmp = Ra.sl + Rb_or_imm.sl; + // signed overflow occurs when operands have same sign + // and sign of result does not match. + if (Ra.sl<31:> == Rb_or_imm.sl<31:> && tmp<31:> != Ra.sl<31:>) + fault = Integer_Overflow_Fault; + Rc.sl = tmp; + }}); + 0x02: s4addl({{ Rc.sl = (Ra.sl << 2) + Rb_or_imm.sl; }}); + 0x12: s8addl({{ Rc.sl = (Ra.sl << 3) + Rb_or_imm.sl; }}); + + 0x20: addq({{ Rc = Ra + Rb_or_imm; }}); + 0x60: addqv({{ + uint64_t tmp = Ra + Rb_or_imm; + // signed overflow occurs when operands have same sign + // and sign of result does not match. + if (Ra<63:> == Rb_or_imm<63:> && tmp<63:> != Ra<63:>) + fault = Integer_Overflow_Fault; + Rc = tmp; + }}); + 0x22: s4addq({{ Rc = (Ra << 2) + Rb_or_imm; }}); + 0x32: s8addq({{ Rc = (Ra << 3) + Rb_or_imm; }}); + + 0x09: subl({{ Rc.sl = Ra.sl - Rb_or_imm.sl; }}); + 0x49: sublv({{ + uint32_t tmp = Ra.sl - Rb_or_imm.sl; + // signed overflow detection is same as for add, + // except we need to look at the *complemented* + // sign bit of the subtrahend (Rb), i.e., if the initial + // signs are the *same* then no overflow can occur + if (Ra.sl<31:> != Rb_or_imm.sl<31:> && tmp<31:> != Ra.sl<31:>) + fault = Integer_Overflow_Fault; + Rc.sl = tmp; + }}); + 0x0b: s4subl({{ Rc.sl = (Ra.sl << 2) - Rb_or_imm.sl; }}); + 0x1b: s8subl({{ Rc.sl = (Ra.sl << 3) - Rb_or_imm.sl; }}); + + 0x29: subq({{ Rc = Ra - Rb_or_imm; }}); + 0x69: subqv({{ + uint64_t tmp = Ra - Rb_or_imm; + // signed overflow detection is same as for add, + // except we need to look at the *complemented* + // sign bit of the subtrahend (Rb), i.e., if the initial + // signs are the *same* then no overflow can occur + if (Ra<63:> != Rb_or_imm<63:> && tmp<63:> != Ra<63:>) + fault = Integer_Overflow_Fault; + Rc = tmp; + }}); + 0x2b: s4subq({{ Rc = (Ra << 2) - Rb_or_imm; }}); + 0x3b: s8subq({{ Rc = (Ra << 3) - Rb_or_imm; }}); + + 0x2d: cmpeq({{ Rc = (Ra == Rb_or_imm); }}); + 0x6d: cmple({{ Rc = (Ra.sq <= Rb_or_imm.sq); }}); + 0x4d: cmplt({{ Rc = (Ra.sq < Rb_or_imm.sq); }}); + 0x3d: cmpule({{ Rc = (Ra.uq <= Rb_or_imm.uq); }}); + 0x1d: cmpult({{ Rc = (Ra.uq < Rb_or_imm.uq); }}); + + 0x0f: cmpbge({{ + int hi = 7; + int lo = 0; + uint64_t tmp = 0; + for (int i = 0; i < 8; ++i) { + tmp |= (Ra.uq >= Rb_or_imm.uq) << i; + hi += 8; + lo += 8; + } + Rc = tmp; + }}); + } + + 0x11: decode INTFUNC { // integer logical operations + + 0x00: and({{ Rc = Ra & Rb_or_imm; }}); + 0x08: bic({{ Rc = Ra & ~Rb_or_imm; }}); + 0x20: bis({{ Rc = Ra | Rb_or_imm; }}); + 0x28: ornot({{ Rc = Ra | ~Rb_or_imm; }}); + 0x40: xor({{ Rc = Ra ^ Rb_or_imm; }}); + 0x48: eqv({{ Rc = Ra ^ ~Rb_or_imm; }}); + + // conditional moves + 0x14: cmovlbs({{ Rc = ((Ra & 1) == 1) ? Rb_or_imm : Rc; }}); + 0x16: cmovlbc({{ Rc = ((Ra & 1) == 0) ? Rb_or_imm : Rc; }}); + 0x24: cmoveq({{ Rc = (Ra == 0) ? Rb_or_imm : Rc; }}); + 0x26: cmovne({{ Rc = (Ra != 0) ? Rb_or_imm : Rc; }}); + 0x44: cmovlt({{ Rc = (Ra.sq < 0) ? Rb_or_imm : Rc; }}); + 0x46: cmovge({{ Rc = (Ra.sq >= 0) ? Rb_or_imm : Rc; }}); + 0x64: cmovle({{ Rc = (Ra.sq <= 0) ? Rb_or_imm : Rc; }}); + 0x66: cmovgt({{ Rc = (Ra.sq > 0) ? Rb_or_imm : Rc; }}); + + // For AMASK, RA must be R31. + 0x61: decode RA { + 31: amask({{ Rc = Rb_or_imm & ~ULL(0x17); }}); + } + + // For IMPLVER, RA must be R31 and the B operand + // must be the immediate value 1. + 0x6c: decode RA { + 31: decode IMM { + 1: decode INTIMM { + // return EV5 for FULL_SYSTEM and EV6 otherwise + 1: implver({{ +#if FULL_SYSTEM + Rc = 1; +#else + Rc = 2; +#endif + }}); + } + } + } + +#if FULL_SYSTEM + // The mysterious 11.25... + 0x25: WarnUnimpl::eleven25(); +#endif + } + + 0x12: decode INTFUNC { + 0x39: sll({{ Rc = Ra << Rb_or_imm<5:0>; }}); + 0x34: srl({{ Rc = Ra.uq >> Rb_or_imm<5:0>; }}); + 0x3c: sra({{ Rc = Ra.sq >> Rb_or_imm<5:0>; }}); + + 0x02: mskbl({{ Rc = Ra & ~(mask( 8) << (Rb_or_imm<2:0> * 8)); }}); + 0x12: mskwl({{ Rc = Ra & ~(mask(16) << (Rb_or_imm<2:0> * 8)); }}); + 0x22: mskll({{ Rc = Ra & ~(mask(32) << (Rb_or_imm<2:0> * 8)); }}); + 0x32: mskql({{ Rc = Ra & ~(mask(64) << (Rb_or_imm<2:0> * 8)); }}); + + 0x52: mskwh({{ + int bv = Rb_or_imm<2:0>; + Rc = bv ? (Ra & ~(mask(16) >> (64 - 8 * bv))) : Ra; + }}); + 0x62: msklh({{ + int bv = Rb_or_imm<2:0>; + Rc = bv ? (Ra & ~(mask(32) >> (64 - 8 * bv))) : Ra; + }}); + 0x72: mskqh({{ + int bv = Rb_or_imm<2:0>; + Rc = bv ? (Ra & ~(mask(64) >> (64 - 8 * bv))) : Ra; + }}); + + 0x06: extbl({{ Rc = (Ra.uq >> (Rb_or_imm<2:0> * 8))< 7:0>; }}); + 0x16: extwl({{ Rc = (Ra.uq >> (Rb_or_imm<2:0> * 8))<15:0>; }}); + 0x26: extll({{ Rc = (Ra.uq >> (Rb_or_imm<2:0> * 8))<31:0>; }}); + 0x36: extql({{ Rc = (Ra.uq >> (Rb_or_imm<2:0> * 8)); }}); + + 0x5a: extwh({{ + Rc = (Ra << (64 - (Rb_or_imm<2:0> * 8))<5:0>)<15:0>; }}); + 0x6a: extlh({{ + Rc = (Ra << (64 - (Rb_or_imm<2:0> * 8))<5:0>)<31:0>; }}); + 0x7a: extqh({{ + Rc = (Ra << (64 - (Rb_or_imm<2:0> * 8))<5:0>); }}); + + 0x0b: insbl({{ Rc = Ra< 7:0> << (Rb_or_imm<2:0> * 8); }}); + 0x1b: inswl({{ Rc = Ra<15:0> << (Rb_or_imm<2:0> * 8); }}); + 0x2b: insll({{ Rc = Ra<31:0> << (Rb_or_imm<2:0> * 8); }}); + 0x3b: insql({{ Rc = Ra << (Rb_or_imm<2:0> * 8); }}); + + 0x57: inswh({{ + int bv = Rb_or_imm<2:0>; + Rc = bv ? (Ra.uq<15:0> >> (64 - 8 * bv)) : 0; + }}); + 0x67: inslh({{ + int bv = Rb_or_imm<2:0>; + Rc = bv ? (Ra.uq<31:0> >> (64 - 8 * bv)) : 0; + }}); + 0x77: insqh({{ + int bv = Rb_or_imm<2:0>; + Rc = bv ? (Ra.uq >> (64 - 8 * bv)) : 0; + }}); + + 0x30: zap({{ + uint64_t zapmask = 0; + for (int i = 0; i < 8; ++i) { + if (Rb_or_imm) + zapmask |= (mask(8) << (i * 8)); + } + Rc = Ra & ~zapmask; + }}); + 0x31: zapnot({{ + uint64_t zapmask = 0; + for (int i = 0; i < 8; ++i) { + if (!Rb_or_imm) + zapmask |= (mask(8) << (i * 8)); + } + Rc = Ra & ~zapmask; + }}); + } + + 0x13: decode INTFUNC { // integer multiplies + 0x00: mull({{ Rc.sl = Ra.sl * Rb_or_imm.sl; }}, IntMultOp); + 0x20: mulq({{ Rc = Ra * Rb_or_imm; }}, IntMultOp); + 0x30: umulh({{ + uint64_t hi, lo; + mul128(Ra, Rb_or_imm, hi, lo); + Rc = hi; + }}, IntMultOp); + 0x40: mullv({{ + // 32-bit multiply with trap on overflow + int64_t Rax = Ra.sl; // sign extended version of Ra.sl + int64_t Rbx = Rb_or_imm.sl; + int64_t tmp = Rax * Rbx; + // To avoid overflow, all the upper 32 bits must match + // the sign bit of the lower 32. We code this as + // checking the upper 33 bits for all 0s or all 1s. + uint64_t sign_bits = tmp<63:31>; + if (sign_bits != 0 && sign_bits != mask(33)) + fault = Integer_Overflow_Fault; + Rc.sl = tmp<31:0>; + }}, IntMultOp); + 0x60: mulqv({{ + // 64-bit multiply with trap on overflow + uint64_t hi, lo; + mul128(Ra, Rb_or_imm, hi, lo); + // all the upper 64 bits must match the sign bit of + // the lower 64 + if (!((hi == 0 && lo<63:> == 0) || + (hi == mask(64) && lo<63:> == 1))) + fault = Integer_Overflow_Fault; + Rc = lo; + }}, IntMultOp); + } + + 0x1c: decode INTFUNC { + 0x00: decode RA { 31: sextb({{ Rc.sb = Rb_or_imm< 7:0>; }}); } + 0x01: decode RA { 31: sextw({{ Rc.sw = Rb_or_imm<15:0>; }}); } + 0x32: ctlz({{ + uint64_t count = 0; + uint64_t temp = Rb; + if (temp<63:32>) temp >>= 32; else count += 32; + if (temp<31:16>) temp >>= 16; else count += 16; + if (temp<15:8>) temp >>= 8; else count += 8; + if (temp<7:4>) temp >>= 4; else count += 4; + if (temp<3:2>) temp >>= 2; else count += 2; + if (temp<1:1>) temp >>= 1; else count += 1; + if ((temp<0:0>) != 0x1) count += 1; + Rc = count; + }}, IntAluOp); + + 0x33: cttz({{ + uint64_t count = 0; + uint64_t temp = Rb; + if (!(temp<31:0>)) { temp >>= 32; count += 32; } + if (!(temp<15:0>)) { temp >>= 16; count += 16; } + if (!(temp<7:0>)) { temp >>= 8; count += 8; } + if (!(temp<3:0>)) { temp >>= 4; count += 4; } + if (!(temp<1:0>)) { temp >>= 2; count += 2; } + if (!(temp<0:0> & ULL(0x1))) count += 1; + Rc = count; + }}, IntAluOp); + + format FailUnimpl { + 0x30: ctpop(); + 0x31: perr(); + 0x34: unpkbw(); + 0x35: unpkbl(); + 0x36: pkwb(); + 0x37: pklb(); + 0x38: minsb8(); + 0x39: minsw4(); + 0x3a: minub8(); + 0x3b: minuw4(); + 0x3c: maxub8(); + 0x3d: maxuw4(); + 0x3e: maxsb8(); + 0x3f: maxsw4(); + } + + format BasicOperateWithNopCheck { + 0x70: decode RB { + 31: ftoit({{ Rc = Fa.uq; }}, FloatCvtOp); + } + 0x78: decode RB { + 31: ftois({{ Rc.sl = t_to_s(Fa.uq); }}, + FloatCvtOp); + } + } + } + } + + //Table 3-2 CPU Branch and Jump Instructions ( ) + //Table 3-10 Obsolete CPU Branch Instructions ( ) + + //Table 3-3 CPU Instruction Control Instructions ( ) + + //Table 3-4 CPU Load, Store, and Memory Control Instructions ( ) + + //Table 3-5 CPU Logical Instructions ( ) + + //Table 3-6 CPU Insert/Extract Instructions ( ) + + //Table 3-7 CPU Move Instructions ( ) + + //Table 3-9 CPU Trap Instructions ( ) + + //Table 3-11 FPU Arithmetic Instructions ( ) + + //Table 3-12 FPU Branch Instructions ( ) + //Table 3-17 Obsolete FPU Branch Instructions () + + //Table 3-13 FPU Compare Instructions ( ) + + //Table 3-14 FPU Convert Instructions ( ) + + //Table 3-15 FPU Load, Store, and Memory Control Instructions ( ) + + //Table 3-16 FPU Move Instructions ( ) + + //Tables 3-18 thru 3-22 are Co-Processor Instructions ( ) + + //Table 3-23 Privileged Instructions ( ) + + //Table 3-24 EJTAG Instructions ( ) + + + + + format LoadAddress { + 0x08: lda({{ Ra = Rb + disp; }}); + 0x09: ldah({{ Ra = Rb + (disp << 16); }}); + } + + format LoadOrNop { + 0x0a: ldbu({{ EA = Rb + disp; }}, {{ Ra.uq = Mem.ub; }}); + 0x0c: ldwu({{ EA = Rb + disp; }}, {{ Ra.uq = Mem.uw; }}); + 0x0b: ldq_u({{ EA = (Rb + disp) & ~7; }}, {{ Ra = Mem.uq; }}); + 0x23: ldt({{ EA = Rb + disp; }}, {{ Fa = Mem.df; }}); + 0x2a: ldl_l({{ EA = Rb + disp; }}, {{ Ra.sl = Mem.sl; }}, LOCKED); + 0x2b: ldq_l({{ EA = Rb + disp; }}, {{ Ra.uq = Mem.uq; }}, LOCKED); + 0x20: copy_load({{EA = Ra;}}, + {{fault = xc->copySrcTranslate(EA);}}, + IsMemRef, IsLoad, IsCopy); + } + + format LoadOrPrefetch { + 0x28: ldl({{ EA = Rb + disp; }}, {{ Ra.sl = Mem.sl; }}); + 0x29: ldq({{ EA = Rb + disp; }}, {{ Ra.uq = Mem.uq; }}, EVICT_NEXT); + // IsFloating flag on lds gets the prefetch to disassemble + // using f31 instead of r31... funcitonally it's unnecessary + 0x22: lds({{ EA = Rb + disp; }}, {{ Fa.uq = s_to_t(Mem.ul); }}, + PF_EXCLUSIVE, IsFloating); + } + + format Store { + 0x0e: stb({{ EA = Rb + disp; }}, {{ Mem.ub = Ra<7:0>; }}); + 0x0d: stw({{ EA = Rb + disp; }}, {{ Mem.uw = Ra<15:0>; }}); + 0x2c: stl({{ EA = Rb + disp; }}, {{ Mem.ul = Ra<31:0>; }}); + 0x2d: stq({{ EA = Rb + disp; }}, {{ Mem.uq = Ra.uq; }}); + 0x0f: stq_u({{ EA = (Rb + disp) & ~7; }}, {{ Mem.uq = Ra.uq; }}); + 0x26: sts({{ EA = Rb + disp; }}, {{ Mem.ul = t_to_s(Fa.uq); }}); + 0x27: stt({{ EA = Rb + disp; }}, {{ Mem.df = Fa; }}); + 0x24: copy_store({{EA = Rb;}}, + {{fault = xc->copy(EA);}}, + IsMemRef, IsStore, IsCopy); + } + + format StoreCond { + 0x2e: stl_c({{ EA = Rb + disp; }}, {{ Mem.ul = Ra<31:0>; }}, + {{ + uint64_t tmp = Mem_write_result; + // see stq_c + Ra = (tmp == 0 || tmp == 1) ? tmp : Ra; + }}, LOCKED); + 0x2f: stq_c({{ EA = Rb + disp; }}, {{ Mem.uq = Ra; }}, + {{ + uint64_t tmp = Mem_write_result; + // If the write operation returns 0 or 1, then + // this was a conventional store conditional, + // and the value indicates the success/failure + // of the operation. If another value is + // returned, then this was a Turbolaser + // mailbox access, and we don't update the + // result register at all. + Ra = (tmp == 0 || tmp == 1) ? tmp : Ra; + }}, LOCKED); + } + + + + // Conditional branches. + format CondBranch { + 0x39: beq({{ cond = (Ra == 0); }}); + 0x3d: bne({{ cond = (Ra != 0); }}); + 0x3e: bge({{ cond = (Ra.sq >= 0); }}); + 0x3f: bgt({{ cond = (Ra.sq > 0); }}); + 0x3b: ble({{ cond = (Ra.sq <= 0); }}); + 0x3a: blt({{ cond = (Ra.sq < 0); }}); + 0x38: blbc({{ cond = ((Ra & 1) == 0); }}); + 0x3c: blbs({{ cond = ((Ra & 1) == 1); }}); + + 0x31: fbeq({{ cond = (Fa == 0); }}); + 0x35: fbne({{ cond = (Fa != 0); }}); + 0x36: fbge({{ cond = (Fa >= 0); }}); + 0x37: fbgt({{ cond = (Fa > 0); }}); + 0x33: fble({{ cond = (Fa <= 0); }}); + 0x32: fblt({{ cond = (Fa < 0); }}); + } + + // unconditional branches + format UncondBranch { + 0x30: br(); + 0x34: bsr(IsCall); + } + + // indirect branches + 0x1a: decode JMPFUNC { + format Jump { + 0: jmp(); + 1: jsr(IsCall); + 2: ret(IsReturn); + 3: jsr_coroutine(IsCall, IsReturn); + } + } + + // Square root and integer-to-FP moves + 0x14: decode FP_SHORTFUNC { + // Integer to FP register moves must have RB == 31 + 0x4: decode RB { + 31: decode FP_FULLFUNC { + format BasicOperateWithNopCheck { + 0x004: itofs({{ Fc.uq = s_to_t(Ra.ul); }}, FloatCvtOp); + 0x024: itoft({{ Fc.uq = Ra.uq; }}, FloatCvtOp); + 0x014: FailUnimpl::itoff(); // VAX-format conversion + } + } + } + + // Square root instructions must have FA == 31 + 0xb: decode FA { + 31: decode FP_TYPEFUNC { + format FloatingPointOperate { +#if SS_COMPATIBLE_FP + 0x0b: sqrts({{ + if (Fb < 0.0) + fault = Arithmetic_Fault; + Fc = sqrt(Fb); + }}, FloatSqrtOp); +#else + 0x0b: sqrts({{ + if (Fb.sf < 0.0) + fault = Arithmetic_Fault; + Fc.sf = sqrt(Fb.sf); + }}, FloatSqrtOp); +#endif + 0x2b: sqrtt({{ + if (Fb < 0.0) + fault = Arithmetic_Fault; + Fc = sqrt(Fb); + }}, FloatSqrtOp); + } + } + } + + // VAX-format sqrtf and sqrtg are not implemented + 0xa: FailUnimpl::sqrtfg(); + } + + // IEEE floating point + 0x16: decode FP_SHORTFUNC_TOP2 { + // The top two bits of the short function code break this + // space into four groups: binary ops, compares, reserved, and + // conversions. See Table 4-12 of AHB. There are different + // special cases in these different groups, so we decode on + // these top two bits first just to select a decode strategy. + // Most of these instructions may have various trapping and + // rounding mode flags set; these are decoded in the + // FloatingPointDecode template used by the + // FloatingPointOperate format. + + // add/sub/mul/div: just decode on the short function code + // and source type. All valid trapping and rounding modes apply. + 0: decode FP_TRAPMODE { + // check for valid trapping modes here + 0,1,5,7: decode FP_TYPEFUNC { + format FloatingPointOperate { +#if SS_COMPATIBLE_FP + 0x00: adds({{ Fc = Fa + Fb; }}); + 0x01: subs({{ Fc = Fa - Fb; }}); + 0x02: muls({{ Fc = Fa * Fb; }}, FloatMultOp); + 0x03: divs({{ Fc = Fa / Fb; }}, FloatDivOp); +#else + 0x00: adds({{ Fc.sf = Fa.sf + Fb.sf; }}); + 0x01: subs({{ Fc.sf = Fa.sf - Fb.sf; }}); + 0x02: muls({{ Fc.sf = Fa.sf * Fb.sf; }}, FloatMultOp); + 0x03: divs({{ Fc.sf = Fa.sf / Fb.sf; }}, FloatDivOp); +#endif + + 0x20: addt({{ Fc = Fa + Fb; }}); + 0x21: subt({{ Fc = Fa - Fb; }}); + 0x22: mult({{ Fc = Fa * Fb; }}, FloatMultOp); + 0x23: divt({{ Fc = Fa / Fb; }}, FloatDivOp); + } + } + } + + // Floating-point compare instructions must have the default + // rounding mode, and may use the default trapping mode or + // /SU. Both trapping modes are treated the same by M5; the + // only difference on the real hardware (as far a I can tell) + // is that without /SU you'd get an imprecise trap if you + // tried to compare a NaN with something else (instead of an + // "unordered" result). + 1: decode FP_FULLFUNC { + format BasicOperateWithNopCheck { + 0x0a5, 0x5a5: cmpteq({{ Fc = (Fa == Fb) ? 2.0 : 0.0; }}, + FloatCmpOp); + 0x0a7, 0x5a7: cmptle({{ Fc = (Fa <= Fb) ? 2.0 : 0.0; }}, + FloatCmpOp); + 0x0a6, 0x5a6: cmptlt({{ Fc = (Fa < Fb) ? 2.0 : 0.0; }}, + FloatCmpOp); + 0x0a4, 0x5a4: cmptun({{ // unordered + Fc = (!(Fa < Fb) && !(Fa == Fb) && !(Fa > Fb)) ? 2.0 : 0.0; + }}, FloatCmpOp); + } + } + + // The FP-to-integer and integer-to-FP conversion insts + // require that FA be 31. + 3: decode FA { + 31: decode FP_TYPEFUNC { + format FloatingPointOperate { + 0x2f: decode FP_ROUNDMODE { + format FPFixedRounding { + // "chopped" i.e. round toward zero + 0: cvttq({{ Fc.sq = (int64_t)trunc(Fb); }}, + Chopped); + // round to minus infinity + 1: cvttq({{ Fc.sq = (int64_t)floor(Fb); }}, + MinusInfinity); + } + default: cvttq({{ Fc.sq = (int64_t)nearbyint(Fb); }}); + } + + // The cvtts opcode is overloaded to be cvtst if the trap + // mode is 2 or 6 (which are not valid otherwise) + 0x2c: decode FP_FULLFUNC { + format BasicOperateWithNopCheck { + // trap on denorm version "cvtst/s" is + // simulated same as cvtst + 0x2ac, 0x6ac: cvtst({{ Fc = Fb.sf; }}); + } + default: cvtts({{ Fc.sf = Fb; }}); + } + + // The trapping mode for integer-to-FP conversions + // must be /SUI or nothing; /U and /SU are not + // allowed. The full set of rounding modes are + // supported though. + 0x3c: decode FP_TRAPMODE { + 0,7: cvtqs({{ Fc.sf = Fb.sq; }}); + } + 0x3e: decode FP_TRAPMODE { + 0,7: cvtqt({{ Fc = Fb.sq; }}); + } + } + } + } + } + + // misc FP operate + 0x17: decode FP_FULLFUNC { + format BasicOperateWithNopCheck { + 0x010: cvtlq({{ + Fc.sl = (Fb.uq<63:62> << 30) | Fb.uq<58:29>; + }}); + 0x030: cvtql({{ + Fc.uq = (Fb.uq<31:30> << 62) | (Fb.uq<29:0> << 29); + }}); + + // We treat the precise & imprecise trapping versions of + // cvtql identically. + 0x130, 0x530: cvtqlv({{ + // To avoid overflow, all the upper 32 bits must match + // the sign bit of the lower 32. We code this as + // checking the upper 33 bits for all 0s or all 1s. + uint64_t sign_bits = Fb.uq<63:31>; + if (sign_bits != 0 && sign_bits != mask(33)) + fault = Integer_Overflow_Fault; + Fc.uq = (Fb.uq<31:30> << 62) | (Fb.uq<29:0> << 29); + }}); + + 0x020: cpys({{ // copy sign + Fc.uq = (Fa.uq<63:> << 63) | Fb.uq<62:0>; + }}); + 0x021: cpysn({{ // copy sign negated + Fc.uq = (~Fa.uq<63:> << 63) | Fb.uq<62:0>; + }}); + 0x022: cpyse({{ // copy sign and exponent + Fc.uq = (Fa.uq<63:52> << 52) | Fb.uq<51:0>; + }}); + + 0x02a: fcmoveq({{ Fc = (Fa == 0) ? Fb : Fc; }}); + 0x02b: fcmovne({{ Fc = (Fa != 0) ? Fb : Fc; }}); + 0x02c: fcmovlt({{ Fc = (Fa < 0) ? Fb : Fc; }}); + 0x02d: fcmovge({{ Fc = (Fa >= 0) ? Fb : Fc; }}); + 0x02e: fcmovle({{ Fc = (Fa <= 0) ? Fb : Fc; }}); + 0x02f: fcmovgt({{ Fc = (Fa > 0) ? Fb : Fc; }}); + + 0x024: mt_fpcr({{ FPCR = Fa.uq; }}); + 0x025: mf_fpcr({{ Fa.uq = FPCR; }}); + } + } + + // miscellaneous mem-format ops + 0x18: decode MEMFUNC { + format WarnUnimpl { + 0x8000: fetch(); + 0xa000: fetch_m(); + 0xe800: ecb(); + } + + format MiscPrefetch { + 0xf800: wh64({{ EA = Rb & ~ULL(63); }}, + {{ xc->writeHint(EA, 64, memAccessFlags); }}, + IsMemRef, IsDataPrefetch, IsStore, MemWriteOp, + NO_FAULT); + } + + format BasicOperate { + 0xc000: rpcc({{ +#if FULL_SYSTEM + /* Rb is a fake dependency so here is a fun way to get + * the parser to understand that. + */ + Ra = xc->readIpr(MipsISA::IPR_CC, fault) + (Rb & 0); + +#else + Ra = curTick; +#endif + }}); + + // All of the barrier instructions below do nothing in + // their execute() methods (hence the empty code blocks). + // All of their functionality is hard-coded in the + // pipeline based on the flags IsSerializing, + // IsMemBarrier, and IsWriteBarrier. In the current + // detailed CPU model, the execute() function only gets + // called at fetch, so there's no way to generate pipeline + // behavior at any other stage. Once we go to an + // exec-in-exec CPU model we should be able to get rid of + // these flags and implement this behavior via the + // execute() methods. + + // trapb is just a barrier on integer traps, where excb is + // a barrier on integer and FP traps. "EXCB is thus a + // superset of TRAPB." (Mips ARM, Sec 4.11.4) We treat + // them the same though. + 0x0000: trapb({{ }}, IsSerializing, IsSerializeBefore, No_OpClass); + 0x0400: excb({{ }}, IsSerializing, IsSerializeBefore, No_OpClass); + 0x4000: mb({{ }}, IsMemBarrier, MemReadOp); + 0x4400: wmb({{ }}, IsWriteBarrier, MemWriteOp); + } + +#if FULL_SYSTEM + format BasicOperate { + 0xe000: rc({{ + Ra = xc->readIntrFlag(); + xc->setIntrFlag(0); + }}, IsNonSpeculative); + 0xf000: rs({{ + Ra = xc->readIntrFlag(); + xc->setIntrFlag(1); + }}, IsNonSpeculative); + } +#else + format FailUnimpl { + 0xe000: rc(); + 0xf000: rs(); + } +#endif + } + +#if FULL_SYSTEM + 0x00: CallPal::call_pal({{ + if (!palValid || + (palPriv + && xc->readIpr(MipsISA::IPR_ICM, fault) != MipsISA::mode_kernel)) { + // invalid pal function code, or attempt to do privileged + // PAL call in non-kernel mode + fault = Unimplemented_Opcode_Fault; + } + else { + // check to see if simulator wants to do something special + // on this PAL call (including maybe suppress it) + bool dopal = xc->simPalCheck(palFunc); + + if (dopal) { + MipsISA::swap_palshadow(&xc->xcBase()->regs, true); + xc->setIpr(MipsISA::IPR_EXC_ADDR, NPC); + NPC = xc->readIpr(MipsISA::IPR_PAL_BASE, fault) + palOffset; + } + } + }}, IsNonSpeculative); +#else + 0x00: decode PALFUNC { + format EmulatedCallPal { + 0x00: halt ({{ + SimExit(curTick, "halt instruction encountered"); + }}, IsNonSpeculative); + 0x83: callsys({{ + xc->syscall(); + }}, IsNonSpeculative, IsSerializeAfter); + // Read uniq reg into ABI return value register (r0) + 0x9e: rduniq({{ R0 = Runiq; }}); + // Write uniq reg with value from ABI arg register (r16) + 0x9f: wruniq({{ Runiq = R16; }}); + } + } +#endif + +#if FULL_SYSTEM + format HwLoadStore { + 0x1b: decode HW_LDST_QUAD { + 0: hw_ld({{ EA = (Rb + disp) & ~3; }}, {{ Ra = Mem.ul; }}, L); + 1: hw_ld({{ EA = (Rb + disp) & ~7; }}, {{ Ra = Mem.uq; }}, Q); + } + + 0x1f: decode HW_LDST_COND { + 0: decode HW_LDST_QUAD { + 0: hw_st({{ EA = (Rb + disp) & ~3; }}, + {{ Mem.ul = Ra<31:0>; }}, L); + 1: hw_st({{ EA = (Rb + disp) & ~7; }}, + {{ Mem.uq = Ra.uq; }}, Q); + } + + 1: FailUnimpl::hw_st_cond(); + } + } + + format HwMoveIPR { + 0x19: hw_mfpr({{ + // this instruction is only valid in PAL mode + if (!xc->inPalMode()) { + fault = Unimplemented_Opcode_Fault; + } + else { + Ra = xc->readIpr(ipr_index, fault); + } + }}); + 0x1d: hw_mtpr({{ + // this instruction is only valid in PAL mode + if (!xc->inPalMode()) { + fault = Unimplemented_Opcode_Fault; + } + else { + xc->setIpr(ipr_index, Ra); + if (traceData) { traceData->setData(Ra); } + } + }}); + } + + format BasicOperate { + 0x1e: hw_rei({{ xc->hwrei(); }}, IsSerializing, IsSerializeBefore); + + // M5 special opcodes use the reserved 0x01 opcode space + 0x01: decode M5FUNC { + 0x00: arm({{ + MipsPseudo::arm(xc->xcBase()); + }}, IsNonSpeculative); + 0x01: quiesce({{ + MipsPseudo::quiesce(xc->xcBase()); + }}, IsNonSpeculative); + 0x10: ivlb({{ + MipsPseudo::ivlb(xc->xcBase()); + }}, No_OpClass, IsNonSpeculative); + 0x11: ivle({{ + MipsPseudo::ivle(xc->xcBase()); + }}, No_OpClass, IsNonSpeculative); + 0x20: m5exit_old({{ + MipsPseudo::m5exit_old(xc->xcBase()); + }}, No_OpClass, IsNonSpeculative); + 0x21: m5exit({{ + MipsPseudo::m5exit(xc->xcBase()); + }}, No_OpClass, IsNonSpeculative); + 0x30: initparam({{ Ra = xc->xcBase()->cpu->system->init_param; }}); + 0x40: resetstats({{ + MipsPseudo::resetstats(xc->xcBase()); + }}, IsNonSpeculative); + 0x41: dumpstats({{ + MipsPseudo::dumpstats(xc->xcBase()); + }}, IsNonSpeculative); + 0x42: dumpresetstats({{ + MipsPseudo::dumpresetstats(xc->xcBase()); + }}, IsNonSpeculative); + 0x43: m5checkpoint({{ + MipsPseudo::m5checkpoint(xc->xcBase()); + }}, IsNonSpeculative); + 0x50: m5readfile({{ + MipsPseudo::readfile(xc->xcBase()); + }}, IsNonSpeculative); + 0x51: m5break({{ + MipsPseudo::debugbreak(xc->xcBase()); + }}, IsNonSpeculative); + 0x52: m5switchcpu({{ + MipsPseudo::switchcpu(xc->xcBase()); + }}, IsNonSpeculative); + 0x53: m5addsymbol({{ + MipsPseudo::addsymbol(xc->xcBase()); + }}, IsNonSpeculative); + + } + } +#endif +} + diff --git a/arch/sparc/isa_desc/formats.h b/arch/mips/isa_desc/formats.h similarity index 100% rename from arch/sparc/isa_desc/formats.h rename to arch/mips/isa_desc/formats.h diff --git a/arch/sparc/isa_desc/formats/basic.format b/arch/mips/isa_desc/formats/basic.format similarity index 100% rename from arch/sparc/isa_desc/formats/basic.format rename to arch/mips/isa_desc/formats/basic.format diff --git a/arch/sparc/isa_desc/formats/branch.format b/arch/mips/isa_desc/formats/branch.format similarity index 100% rename from arch/sparc/isa_desc/formats/branch.format rename to arch/mips/isa_desc/formats/branch.format diff --git a/arch/sparc/isa_desc/formats/integerop.format b/arch/mips/isa_desc/formats/integerop.format similarity index 100% rename from arch/sparc/isa_desc/formats/integerop.format rename to arch/mips/isa_desc/formats/integerop.format diff --git a/arch/sparc/isa_desc/formats/mem.format b/arch/mips/isa_desc/formats/mem.format similarity index 100% rename from arch/sparc/isa_desc/formats/mem.format rename to arch/mips/isa_desc/formats/mem.format diff --git a/arch/sparc/isa_desc/formats/noop.format b/arch/mips/isa_desc/formats/noop.format similarity index 100% rename from arch/sparc/isa_desc/formats/noop.format rename to arch/mips/isa_desc/formats/noop.format diff --git a/arch/sparc/isa_desc/formats/trap.format b/arch/mips/isa_desc/formats/trap.format similarity index 100% rename from arch/sparc/isa_desc/formats/trap.format rename to arch/mips/isa_desc/formats/trap.format diff --git a/arch/sparc/isa_desc/includes.h b/arch/mips/isa_desc/includes.h similarity index 100% rename from arch/sparc/isa_desc/includes.h rename to arch/mips/isa_desc/includes.h diff --git a/arch/sparc/isa_desc/operands.h b/arch/mips/isa_desc/operands.h similarity index 100% rename from arch/sparc/isa_desc/operands.h rename to arch/mips/isa_desc/operands.h diff --git a/arch/sparc/isa_traits.cc b/arch/mips/isa_traits.cc similarity index 100% rename from arch/sparc/isa_traits.cc rename to arch/mips/isa_traits.cc diff --git a/arch/sparc/isa_traits.hh b/arch/mips/isa_traits.hh similarity index 100% rename from arch/sparc/isa_traits.hh rename to arch/mips/isa_traits.hh diff --git a/arch/sparc/isa_desc/decoder.h b/arch/sparc/isa_desc/decoder.h deleted file mode 100644 index 06834ecc3..000000000 --- a/arch/sparc/isa_desc/decoder.h +++ /dev/null @@ -1,638 +0,0 @@ -//////////////////////////////////////////////////////////////////// -// -// The actual decoder specification -// - -decode OP default Trap::unknown({{illegal_instruction}}) { - - 0x0: decode OP2 { - 0x0: Trap::illtrap({{illegal_instruction}}); //ILLTRAP - 0x1: Branch::bpcc({{ - switch((CC12 << 1) | CC02) - { - case 1: case 3: - throw illegal_instruction; - case 0: - if(passesCondition(xc->regs.MiscRegs.ccrFields.icc, COND2)) - ;//branchHere - break; - case 2: - if(passesCondition(xc->regs.MiscRegs.ccrFields.xcc, COND2)) - ;//branchHere - break; - } - }});//BPcc - 0x2: Branch::bicc({{ - if(passesCondition(xc->regs.MiscRegs.ccrFields.icc, COND2)) - ;//branchHere - }});//Bicc - 0x3: Branch::bpr({{ - switch(RCOND) - { - case 0: case 4: - throw illegal_instruction; - case 1: - if(Rs1 == 0) ;//branchHere - break; - case 2: - if(Rs1 <= 0) ;//branchHere - break; - case 3: - if(Rs1 < 0) ;//branchHere - break; - case 5: - if(Rs1 != 0) ;//branchHere - break; - case 6: - if(Rs1 > 0) ;//branchHere - break; - case 7: - if(Rs1 >= 0) ;//branchHere - break; - } - }}); //BPr - 0x4: IntegerOp::sethi({{Rd = (IMM22 << 10) & 0xFFFFFC00;}}); //SETHI (or NOP if rd == 0 and imm == 0) - 0x5: Trap::fbpfcc({{throw fp_disabled;}}); //FBPfcc - 0x6: Trap::fbfcc({{throw fp_disabled;}}); //FBfcc - } - 0x1: Branch::call({{ - //branch here - Rd = xc->pc; - }}); - 0x2: decode OP3 { - format IntegerOp { - 0x00: add({{ - INT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); - Rd = Rs1.sdw + val2; - }});//ADD - 0x01: and({{ - UINT64 val2 = (I ? SIMM13.sdw : Rs2.udw); - Rd = Rs1.udw & val2; - }});//AND - 0x02: or({{ - UINT64 val2 = (I ? SIMM13.sdw : Rs2.udw); - Rd = Rs1.udw | val2; - }});//OR - 0x03: xor({{ - UINT64 val2 = (I ? SIMM13.sdw : Rs2.udw); - Rd = Rs1.udw ^ val2; - }});//XOR - 0x04: sub({{ - INT64 val2 = ~((UINT64)(I ? SIMM13.sdw : Rs2.udw))+1; - Rd = Rs1.sdw + val2; - }});//SUB - 0x05: andn({{ - UINT64 val2 = (I ? SIMM13.sdw : Rs2.udw); - Rd = Rs1.udw & ~val2; - }});//ANDN - 0x06: orn({{ - UINT64 val2 = (I ? SIMM13.sdw : Rs2.udw); - Rd = Rs1.udw | ~val2; - }});//ORN - 0x07: xnor({{ - UINT64 val2 = (I ? SIMM13.sdw : Rs2.udw); - Rd = ~(Rs1.udw ^ val2); - }});//XNOR - 0x08: addc({{ - INT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); - INT64 carryin = xc->regs.MiscRegs.ccrfields.iccfields.c; - Rd = Rs1.sdw + val2 + carryin; - }});//ADDC - 0x09: mulx({{ - INT64 val2 = (I ? SIMM13.sdw : Rs2); - Rd = Rs1 * val2; - }});//MULX - 0x0A: umul({{ - UINT64 resTemp, val2 = (I ? SIMM13.sdw : Rs2.udw); - Rd = resTemp = Rs1.udw<31:0> * val2<31:0>; - xc->regs.MiscRegs.yFields.value = resTemp<63:32>; - }});//UMUL - 0x0B: smul({{ - INT64 resTemp, val2 = (I ? SIMM13.sdw : Rs2.sdw); - rd.sdw = resTemp = Rs1.sdw<31:0> * val2<31:0>; - xc->regs.MiscRegs.yFields.value = resTemp<63:32>; - }});//SMUL - 0x0C: subc({{ - INT64 val2 = ~((INT64)(I ? SIMM13.sdw : Rs2.sdw))+1; - INT64 carryin = xc->regs.MiscRegs.ccrfields.iccfields.c; - Rd.sdw = Rs1.sdw + val2 + carryin; - }});//SUBC - 0x0D: udivx({{ - UINT64 val2 = (I ? SIMM13.sdw : Rs2.udw); - if(val2 == 0) throw division_by_zero; - Rd.udw = Rs1.udw / val2; - }});//UDIVX - 0x0E: udiv({{ - UINT32 resTemp, val2 = (I ? SIMM13.sw : Rs2.udw<31:0>); - if(val2 == 0) throw division_by_zero; - resTemp = (UINT64)((xc->regs.MiscRegs.yFields.value << 32) | Rs1.udw<31:0>) / val2; - INT32 overflow = (resTemp<63:32> != 0); - if(overflow) rd.udw = resTemp = 0xFFFFFFFF; - else rd.udw = resTemp; - }}); //UDIV - 0x0F: sdiv({{ - INT32 resTemp, val2 = (I ? SIMM13.sw : Rs2.sdw<31:0>); - if(val2 == 0) throw division_by_zero; - Rd.sdw = resTemp = (INT64)((xc->regs.MiscRegs.yFields.value << 32) | Rs1.sdw<31:0>) / val2; - INT32 overflow = (resTemp<63:31> != 0); - INT32 underflow = (resTemp<63:> && resTemp<62:31> != 0xFFFFFFFF); - if(overflow) rd.udw = resTemp = 0x7FFFFFFF; - else if(underflow) rd.udw = resTemp = 0xFFFFFFFF80000000; - else rd.udw = resTemp; - }});//SDIV - } - format IntegerOpCc { - 0x10: addcc({{ - INT64 resTemp, val2 = (I ? SIMM13.sdw : Rs2); - Rd = resTemp = Rs1 + val2;}}, - {{((Rs1 & 0xFFFFFFFF + val2 & 0xFFFFFFFF) >> 31)}}, - {{Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>}}, - {{((Rs1 >> 1) + (val2 >> 1) + (Rs1 & val2 & 0x1))<63:>}}, - {{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}} - );//ADDcc - 0x11: andcc({{ - INT64 val2 = (I ? SIMM13.sdw : Rs2); - Rd = Rs1 & val2;}} - ,{{0}},{{0}},{{0}},{{0}});//ANDcc - 0x12: orcc({{ - INT64 val2 = (I ? SIMM13.sdw : Rs2); - Rd = Rs1 | val2;}} - ,{{0}},{{0}},{{0}},{{0}});//ORcc - 0x13: xorcc({{ - INT64 val2 = (I ? SIMM13.sdw : Rs2); - Rd = Rs1 ^ val2;}} - ,{{0}},{{0}},{{0}},{{0}});//XORcc - 0x14: subcc({{ - INT64 resTemp, val2 = (INT64)(I ? SIMM13.sdw : Rs2); - Rd = resTemp = Rs1 - val2;}}, - {{((Rs1 & 0xFFFFFFFF + (~val2) & 0xFFFFFFFF + 1) >> 31)}}, - {{Rs1<31:> != val2<31:> && Rs1<31:> != resTemp<31:>}}, - {{((Rs1 >> 1) + (~val2) >> 1) + ((Rs1 | ~val2) & 0x1))<63:>}}, - {{Rs1<63:> != val2<63:> && Rs1<63:> != resTemp<63:>}} - );//SUBcc - 0x15: andncc({{ - INT64 val2 = (I ? SIMM13.sdw : Rs2); - Rd = Rs1 & ~val2;}} - ,{{0}},{{0}},{{0}},{{0}});//ANDNcc - 0x16: orncc({{ - INT64 val2 = (I ? SIMM13.sdw : Rs2); - Rd = Rs1 | ~val2;}} - ,{{0}},{{0}},{{0}},{{0}});//ORNcc - 0x17: xnorcc({{ - INT64 val2 = (I ? SIMM13.sdw : Rs2); - Rd = ~(Rs1 ^ val2);}} - ,{{0}},{{0}},{{0}},{{0}});//XNORcc - 0x18: addccc({{ - INT64 resTemp, val2 = (I ? SIMM13.sdw : Rs2); - INT64 carryin = xc->regs.MiscRegs.ccrfields.iccfields.c; - Rd = resTemp = Rs1 + val2 + carryin;}}, - {{((Rs1 & 0xFFFFFFFF + val2 & 0xFFFFFFFF) >> 31 + carryin)}}, - {{Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>}}, - {{((Rs1 >> 1) + (val2 >> 1) + ((Rs1 & val2) | (carryin & (Rs1 | val2)) & 0x1))<63:>}}, - {{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}} - );//ADDCcc - 0x1A: umulcc({{ - UINT64 resTemp, val2 = (I ? SIMM13.sdw : Rs2); - Rd = resTemp = Rs1.udw<31:0> * val2<31:0>; - xc->regs.MiscRegs.yFields.value = resTemp<63:32>;}} - ,{{0}},{{0}},{{0}},{{0}});//UMULcc - 0x1B: smulcc({{ - INT64 resTemp, val2 = (I ? SIMM13.sdw : Rs2); - Rd = resTemp = Rs1.sdw<31:0> * val2<31:0>; - xc->regs.MiscRegs.yFields.value = resTemp<63:32>;}} - ,{{0}},{{0}},{{0}},{{0}});//SMULcc - 0x1C: subccc({{ - INT64 resTemp, val2 = (INT64)(I ? SIMM13.sdw : Rs2); - INT64 carryin = xc->regs.MiscRegs.ccrfields.iccfields.c; - Rd = resTemp = Rs1 + ~(val2 + carryin) + 1;}}, - {{((Rs1 & 0xFFFFFFFF + (~(val2 + carryin)) & 0xFFFFFFFF + 1) >> 31)}}, - {{Rs1<31:> != val2<31:> && Rs1<31:> != resTemp<31:>}}, - {{((Rs1 >> 1) + (~(val2 + carryin)) >> 1) + ((Rs1 | ~(val2+carryin)) & 0x1))<63:>}}, - {{Rs1<63:> != val2<63:> && Rs1<63:> != resTemp<63:>}} - );//SUBCcc - 0x1D: udivxcc({{ - UINT64 val2 = (I ? SIMM13.sdw : Rs2.udw); - if(val2 == 0) throw division_by_zero; - Rd.udw = Rs1.udw / val2;}} - ,{{0}},{{0}},{{0}},{{0}});//UDIVXcc - 0x1E: udivcc({{ - UINT32 resTemp, val2 = (I ? SIMM13.sw : Rs2.udw<31:0>); - if(val2 == 0) throw division_by_zero; - resTemp = (UINT64)((xc->regs.MiscRegs.yFields.value << 32) | Rs1.udw<31:0>) / val2; - INT32 overflow = (resTemp<63:32> != 0); - if(overflow) rd.udw = resTemp = 0xFFFFFFFF; - else rd.udw = resTemp;}}, - {{0}}, - {{overflow}}, - {{0}}, - {{0}} - );//UDIVcc - 0x1F: sdivcc({{ - INT32 resTemp, val2 = (I ? SIMM13.sw : Rs2.sdw<31:0>); - if(val2 == 0) throw division_by_zero; - Rd.sdw = resTemp = (INT64)((xc->regs.MiscRegs.yFields.value << 32) | Rs1.sdw<31:0>) / val2; - INT32 overflow = (resTemp<63:31> != 0); - INT32 underflow = (resTemp<63:> && resTemp<62:31> != 0xFFFFFFFF); - if(overflow) rd.udw = resTemp = 0x7FFFFFFF; - else if(underflow) rd.udw = resTemp = 0xFFFFFFFF80000000; - else rd.udw = resTemp;}}, - {{0}}, - {{overflow || underflow}}, - {{0}}, - {{0}} - );//SDIVcc - 0x20: taddcc({{ - INT64 resTemp, val2 = (I ? SIMM13.sdw : Rs2); - Rd = resTemp = Rs1 + val2; - INT32 overflow = Rs1<1:0> || val2<1:0> || (Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>);}}, - {{((Rs1 & 0xFFFFFFFF + val2 & 0xFFFFFFFF) >> 31)}}, - {{overflow}}, - {{((Rs1 >> 1) + (val2 >> 1) + (Rs1 & val2 & 0x1))<63:>}}, - {{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}} - );//TADDcc - 0x21: tsubcc({{ - INT64 resTemp, val2 = (I ? SIMM13.sdw : Rs2); - Rd = resTemp = Rs1 + val2; - INT32 overflow = Rs1<1:0> || val2<1:0> || (Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>);}}, - {{(Rs1 & 0xFFFFFFFF + val2 & 0xFFFFFFFF) >> 31)}}, - {{overflow}}, - {{((Rs1 >> 1) + (val2 >> 1) + (Rs1 & val2 & 0x1))<63:>}}, - {{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}} - );//TSUBcc - 0x22: taddcctv({{ - INT64 resTemp, val2 = (I ? SIMM13.sdw : Rs2); - Rd = resTemp = Rs1 + val2; - INT32 overflow = Rs1<1:0> || val2<1:0> || (Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>); - if(overflow) throw tag_overflow;}}, - {{((Rs1 & 0xFFFFFFFF + val2 & 0xFFFFFFFF) >> 31)}}, - {{overflow}}, - {{((Rs1 >> 1) + (val2 >> 1) + (Rs1 & val2 & 0x1))<63:>}}, - {{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}} - );//TADDccTV - 0x23: tsubcctv({{ - INT64 resTemp, val2 = (I ? SIMM13.sdw : Rs2); - Rd = resTemp = Rs1 + val2; - INT32 overflow = Rs1<1:0> || val2<1:0> || (Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>); - if(overflow) throw tag_overflow;}}, - {{((Rs1 & 0xFFFFFFFF + val2 & 0xFFFFFFFF) >> 31)}}, - {{overflow}}, - {{((Rs1 >> 1) + (val2 >> 1) + (Rs1 & val2 & 0x1))<63:>}}, - {{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}} - );//TSUBccTV - 0x24: mulscc({{ - INT64 resTemp, multiplicand = (I ? SIMM13.sdw : Rs2); - INT32 multiplier = Rs1<31:0>; - INT32 savedLSB = Rs1<0:>; - multiplier = multipler<31:1> | - ((xc->regs.MiscRegs.ccrFields.iccFields.n - ^ xc->regs.MiscRegs.ccrFields.iccFields.v) << 32); - if(!xc->regs.MiscRegs.yFields.value<0:>) - multiplicand = 0; - Rd = resTemp = multiplicand + multiplier; - xc->regs.MiscRegs.yFields.value = xc->regs.MiscRegs.yFields.value<31:1> | (savedLSB << 31);}}, - {{((multiplicand & 0xFFFFFFFF + multiplier & 0xFFFFFFFF) >> 31)}}, - {{multiplicand<31:> == multiplier<31:> && multiplier<31:> != resTemp<31:>}}, - {{((multiplicand >> 1) + (multiplier >> 1) + (multiplicand & multiplier & 0x1))<63:>}}, - {{multiplicand<63:> == multiplier<63:> && multiplier<63:> != resTemp<63:>}} - );//MULScc - } - format IntegerOp - { - 0x25: decode X { - 0x0: sll({{Rd = Rs1 << (I ? SHCNT32 : Rs2<4:0>);}}); //SLL - 0x1: sllx({{Rd = Rs1 << (I ? SHCNT64 : Rs2<5:0>);}}); //SLLX - } - 0x26: decode X { - 0x0: srl({{Rd = Rs1.udw<31:0> >> (I ? SHCNT32 : Rs2<4:0>);}}); //SRL - 0x1: srlx({{Rd = Rs1.udw >> (I ? SHCNT64 : Rs2<5:0>);}});//SRLX - } - 0x27: decode X { - 0x0: sra({{Rd = Rs1.sdw<31:0> >> (I ? SHCNT32 : Rs2<4:0>);}}); //SRA - 0x1: srax({{Rd = Rs1.sdw >> (I ? SHCNT64 : Rs2<5:0>);}});//SRAX - } - 0x28: decode RS1 { - 0x0: rdy({{Rd = xc->regs.MiscRegs.yFields.value;}}); //RDY - 0x2: rdccr({{Rd = xc->regs.MiscRegs.ccr;}}); //RDCCR - 0x3: rdasi({{Rd = xc->regs.MiscRegs.asi;}}); //RDASI - 0x4: rdtick({{ - if(xc->regs.MiscRegs.pstateFields.priv == 0 && - xc->regs.MiscRegs.tickFields.npt == 1) - throw privileged_action; - Rd = xc->regs.MiscRegs.tick; - }});//RDTICK - 0x5: rdpc({{Rd = xc->regs.pc;}}); //RDPC - 0x6: rdfprs({{Rd = xc->regs.MiscRegs.fprs;}}); //RDFPRS - 0xF: decode I { - 0x0: Noop::membar({{//Membar isn't needed yet}}); //MEMBAR - 0x1: Noop::stbar({{//Stbar isn/'t needed yet}}); //STBAR - } - } - - 0x2A: decode RS1 { - 0x0: rdprtpc({{checkPriv Rd = xc->regs.MiscRegs.tpc[xc->regs.MiscRegs.tl];}}); - 0x1: rdprtnpc({{checkPriv Rd = xc->regs.MiscRegs.tnpc[xc->regs.MiscRegs.tl];}}); - 0x2: rdprtstate({{checkPriv Rd = xc->regs.MiscRegs.tstate[xc->regs.MiscRegs.tl];}}); - 0x3: rdprtt({{checkPriv Rd = xc->regs.MiscRegs.tt[xc->regs.MiscRegs.tl];}}); - 0x4: rdprtick({{checkPriv Rd = xc->regs.MiscRegs.tick;}}); - 0x5: rdprtba({{checkPriv Rd = xc->regs.MiscRegs.tba;}}); - 0x6: rdprpstate({{checkPriv Rd = xc->regs.MiscRegs.pstate;}}); - 0x7: rdprtl({{checkPriv Rd = xc->regs.MiscRegs.tl;}}); - 0x8: rdprpil({{checkPriv Rd = xc->regs.MiscRegs.pil;}}); - 0x9: rdprcwp({{checkPriv Rd = xc->regs.MiscRegs.cwp;}}); - 0xA: rdprcansave({{checkPriv Rd = xc->regs.MiscRegs.cansave;}}); - 0xB: rdprcanrestore({{checkPriv Rd = xc->regs.MiscRegs.canrestore;}}); - 0xC: rdprcleanwin({{checkPriv Rd = xc->regs.MiscRegs.cleanwin;}}); - 0xD: rdprotherwin({{checkPriv Rd = xc->regs.MiscRegs.otherwin;}}); - 0xE: rdprwstate({{checkPriv Rd = xc->regs.MiscRegs.wstate;}}); - 0xF: rdprfq({{throw illegal_instruction;}}); //The floating point queue isn't implemented right now. - } - 0x2B: BasicOperate::flushw({{\\window toilet}}); //FLUSHW - 0x2C: movcc({{ - ccBank = (CC24 << 2) | (CC14 << 1) | (CC04 << 0); - switch(ccBank) - { - case 0: case 1: case 2: case 3: - throw fp_disabled; - break; - case 5: case 7: - throw illegal_instruction; - break; - case 4: - if(passesCondition(xc->regs.MiscRegs.ccrFields.icc, COND4)) - Rd = (I ? SIMM11.sdw : RS2); - break; - case 6: - if(passesCondition(xc->regs.MiscRegs.ccrFields.xcc, COND4)) - Rd = (I ? SIMM11.sdw : RS2); - break; - } - }});//MOVcc - 0x2D: sdivx({{ - INT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); - if(val2 == 0) throw division_by_zero; - Rd.sdw = Rs1.sdw / val2; - }});//SDIVX - 0x2E: decode RS1 { - 0x0: IntegerOp::popc({{ - INT64 count = 0, val2 = (I ? SIMM13.sdw : Rs2.sdw); - UINT8 oneBits[] = {0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4} - for(unsigned int x = 0; x < 16; x++) - { - count += oneBits[val2 & 0xF]; - val2 >> 4; - } - }});//POPC - } - 0x2F: movr({{ - UINT64 val2 = (I ? SIMM10.sdw : Rs2.sdw); - switch(RCOND) - { - case 0: case 4: - throw illegal_instruction; - break; - case 1: - if(Rs1 == 0) Rd = val2; - break; - case 2: - if(Rs1 <= 0) Rd = val2; - break; - case 3: - if(Rs1 = 0) Rd = val2; - break; - case 5: - if(Rs1 != 0) Rd = val2; - break; - case 6: - if(Rs1 > 0) Rd = val2; - break; - case 7: - if(Rs1 >= 0) Rd = val2; - break; - } - }});//MOVR - 0x30: decode RD { - 0x0: wry({{ - UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); - xc->regs.MiscRegs.y = Rs1 ^ val2; - }});//WRY - 0x2: wrccr({{ - UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); - xc->regs.MiscRegs.ccr = Rs1 ^ val2; - }});//WRCCR - 0x3: wrasi({{ - UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); - xc->regs.MiscRegs.asi = Rs1 ^ val2; - }});//WRASI - 0x6: wrfprs({{ - UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); - xc->regs.MiscRegs.asi = Rs1 ^ val2; - }});//WRFPRS - 0xF: Trap::sir({{software_initiated_reset}}); //SIR - } - 0x31: decode FCN { - 0x0: BasicOperate::saved({{\\Boogy Boogy}}); //SAVED - 0x1: BasicOperate::restored({{\\Boogy Boogy}}); //RESTORED - } - 0x32: decode RD { - 0x0: wrprtpc({{checkPriv - UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); - xc->regs.MiscRegs.tpc[xc->regs.MiscRegs.tl] = Rs1 ^ val2; - }}); - 0x1: wrprtnpc({{checkPriv - UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); - xc->regs.MiscRegs.tnpc[xc->regs.MiscRegs.tl] = Rs1 ^ val2; - }}); - 0x2: wrprtstate({{checkPriv - UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); - xc->regs.MiscRegs.tstate[xc->regs.MiscRegs.tl] = Rs1 ^ val2; - }}); - 0x3: wrprtt({{checkPriv - UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); - xc->regs.MiscRegs.tt[xc->regs.MiscRegs.tl] = Rs1 ^ val2; - }}); - 0x4: wrprtick({{checkPriv - UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); - xc->regs.MiscRegs.tick = Rs1 ^ val2; - }}); - 0x5: wrprtba({{checkPriv - UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); - xc->regs.MiscRegs.tba = Rs1 ^ val2; - }}); - 0x6: wrprpstate({{checkPriv - UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); - xc->regs.MiscRegs.pstate = Rs1 ^ val2; - }}); - 0x7: wrprtl({{checkPriv - UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); - xc->regs.MiscRegs.tl = Rs1 ^ val2; - }}); - 0x8: wrprpil({{checkPriv - UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); - xc->regs.MiscRegs.pil = Rs1 ^ val2; - }}); - 0x9: wrprcwp({{checkPriv - UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); - xc->regs.MiscRegs.cwp = Rs1 ^ val2; - }}); - 0xA: wrprcansave({{checkPriv - UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); - xc->regs.MiscRegs.cansave = Rs1 ^ val2; - }}); - 0xB: wrprcanrestore({{checkPriv - UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); - xc->regs.MiscRegs.canrestore = Rs1 ^ val2; - }}); - 0xC: wrprcleanwin({{checkPriv - UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); - xc->regs.MiscRegs.cleanwin = Rs1 ^ val2; - }}); - 0xD: wrprotherwin({{checkPriv - UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); - xc->regs.MiscRegs.otherwin = Rs1 ^ val2; - }}); - 0xE: wrprwstate({{checkPriv - UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); - xc->regs.MiscRegs.wstate = Rs1 ^ val2; - }}); - } - - 0x34: Trap::fpop1({{Throw fp_disabled;}}); //FPOP1 - 0x35: Trap::fpop2({{Throw fp_disabled;}}); //FPOP2 - - - 0x38: Branch::jmpl({{//Stuff}}); //JMPL - 0x39: Branch::return({{//Other Stuff}}); //RETURN - 0x3A: Trap::tcc({{ - switch((CC14 << 1) | (CC04 << 0)) - { - case 1: case 3: - throw illegal_instruction; - case 0: - if(passesCondition(xc->regs.MiscRegs.ccrFields.icc, machInst<25:28>)) - throw trap_instruction; - break; - case 2: - if(passesCondition(xc->regs.MiscRegs.ccrFields.xcc, machInst<25:28>)) - throw trap_instruction; - break; - } - }}); //Tcc - 0x3B: BasicOperate::flush({{//Lala}}); //FLUSH - 0x3C: BasicOperate::save({{//leprechauns); //SAVE - 0x3D: BasicOperate::restore({{//Eat my short int}}); //RESTORE - 0x3E: decode FCN { - 0x1: BasicOperate::done({{//Done thing}}); //DONE - 0x2: BasicOperate::retry({{//Retry thing}}); //RETRY - } - } - } - 0x3: decode OP3 { - format Mem { - 0x00: lduw({{Rd.uw = Mem.uw;}}); //LDUW - 0x01: ldub({{Rd.ub = Mem.ub;}}); //LDUB - 0x02: lduh({{Rd.uhw = Mem.uhw;}}); //LDUH - 0x03: ldd({{ - UINT64 val = Mem.udw; - setIntReg(RD & (~1), val<31:0>); - setIntReg(RD | 1, val<63:32>); - }});//LDD - 0x04: stw({{Mem.sw = Rd.sw;}}); //STW - 0x05: stb({{Mem.sb = Rd.sb;}}); //STB - 0x06: sth({{Mem.shw = Rd.shw;}}); //STH - 0x07: std({{ - Mem.udw = readIntReg(RD & (~1))<31:0> | (readIntReg(RD | 1)<31:0> << 32); - }});//STD - 0x08: ldsw({{Rd.sw = Mem.sw;}}); //LDSW - 0x09: ldsb({{Rd.sb = Mem.sb;}}); //LDSB - 0x0A: ldsh({{Rd.shw = Mem.shw;}}); //LDSH - 0x0B: ldx({{Rd.udw = Mem.udw;}}); //LDX - - 0x0D: ldstub({{ - Rd.ub = Mem.ub; - Mem.ub = 0xFF; - }}); //LDSTUB - 0x0E: stx({{Rd.udw = Mem.udw;}}); //STX - 0x0F: swap({{ - UINT32 temp = Rd.uw; - Rd.uw = Mem.uw; - Mem.uw = temp; - }}); //SWAP - 0x10: lduwa({{Rd.uw = Mem.uw;}}); //LDUWA - 0x11: lduba({{Rd.ub = Mem.ub;}}); //LDUBA - 0x12: lduha({{Rd.uhw = Mem.uhw;}}); //LDUHA - 0x13: ldda({{ - UINT64 val = Mem.udw; - setIntReg(RD & (~1), val<31:0>); - setIntReg(RD | 1, val<63:32>); - }}); //LDDA - 0x14: stwa({{Mem.uw = Rd.uw;}}); //STWA - 0x15: stba({{Mem.ub = Rd.ub;}}); //STBA - 0x16: stha({{Mem.uhw = Rd.uhw;}}); //STHA - 0x17: stda({{ - Mem.udw = readIntReg(RD & (~1))<31:0> | (readIntReg(RD | 1)<31:0> << 32); - }}); //STDA - 0x18: ldswa({{Rd.sw = Mem.sw;}}); //LDSWA - 0x19: ldsba({{Rd.sb = Mem.sb;}}); //LDSBA - 0x1A: ldsha({{Rd.shw = Mem.shw;}}); //LDSHA - 0x1B: ldxa({{Rd.sdw = Mem.sdw;}}); //LDXA - - 0x1D: ldstuba({{ - Rd.ub = Mem.ub; - Mem.ub = 0xFF; - }}); //LDSTUBA - 0x1E: stxa({{Mem.sdw = Rd.sdw}}); //STXA - 0x1F: swapa({{ - UINT32 temp = Rd.uw; - Rd.uw = Mem.uw; - Mem.uw = temp; - }}); //SWAPA - 0x20: Trap::ldf({{throw fp_disabled;}}); //LDF - 0x21: decode X { - 0x0: Trap::ldfsr({{throw fp_disabled;}}); //LDFSR - 0x1: Trap::ldxfsr({{throw fp_disabled;}}); //LDXFSR - } - 0x22: Trap::ldqf({{throw fp_disabled;}}); //LDQF - 0x23: Trap::lddf({{throw fp_disabled;}}); //LDDF - 0x24: Trap::stf({{throw fp_disabled;}}); //STF - 0x25: decode X { - 0x0: Trap::stfsr({{throw fp_disabled;}}); //STFSR - 0x1: Trap::stxfsr({{throw fp_disabled;}}); //STXFSR - } - 0x26: Trap::stqf({{throw fp_disabled;}}); //STQF - 0x27: Trap::stdf({{throw fp_disabled;}}); //STDF - - - - - - 0x2D: Noop::prefetch({{ }}); //PREFETCH - - - 0x30: Trap::ldfa({{throw fp_disabled;}}); //LDFA - - 0x32: Trap::ldqfa({{throw fp_disabled;}}); //LDQFA - 0x33: Trap::lddfa({{throw fp_disabled;}}); //LDDFA - 0x34: Trap::stfa({{throw fp_disabled;}}); //STFA - 0x35: Trap::stqfa({{throw fp_disabled;}}); //STQFA - 0x36: Trap::stdfa({{throw fp_disabled;}}); //STDFA - - - - - - 0x3C: Cas::casa( - {{UINT64 val = Mem.uw; - if(Rs2.uw == val) - Mem.uw = Rd.uw; - Rd.uw = val; - }}); //CASA - 0x3D: Noop::prefetcha({{ }}); //PREFETCHA - 0x3E: Cas::casxa( - {{UINT64 val = Mem.udw; - if(Rs2 == val) - Mem.udw = Rd; - Rd = val; - }}); //CASXA - } - } -} From 14fc0996e3d349c03c1e0afcb09df3679891dea5 Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Wed, 25 Jan 2006 17:06:23 -0500 Subject: [PATCH 004/180] first version of my decoder function skeleton - this will decode the instructions but not doing anything to create the C++ object yet (the 1st of many steps!) arch/mips/isa_desc/bitfields.h: initial bitfield constants ... copied some from original alpha bitfields arch/mips/isa_desc/decoder.h: decoder function skeleton pt.1 - this will decode the instructions but not doing anything to create the C++ object yet (the 1st of many steps!) --HG-- extra : convert_revision : 2b9a0f8160c78b17f9d3d5eaf5af5a4d2f074761 --- arch/mips/isa_desc/bitfields.h | 110 ++-- arch/mips/isa_desc/decoder.h | 1051 ++++++-------------------------- 2 files changed, 250 insertions(+), 911 deletions(-) diff --git a/arch/mips/isa_desc/bitfields.h b/arch/mips/isa_desc/bitfields.h index b0ac57575..7fce190ce 100644 --- a/arch/mips/isa_desc/bitfields.h +++ b/arch/mips/isa_desc/bitfields.h @@ -3,48 +3,70 @@ // Bitfield definitions. // -// Bitfields are shared liberally between instruction formats, so they are -// simply defined alphabetically +// Universal (format-independent) fields +def bitfield OPCODE_HI <31:29>; +def bitfield OPCODE_LO <28:26>; -def bitfield A <29>; -def bitfield CC02 <20>; -def bitfield CC03 <25>; -def bitfield CC04 <11>; -def bitfield CC12 <21>; -def bitfield CC13 <26>; -def bitfield CC14 <12>; -def bitfield CC2 <18>; -def bitfield CMASK <6:4>; -def bitfield COND2 <28:25>; -def bitfield COND4 <17:14>; -def bitfield D16HI <21:20>; -def bitfield D16LO <13:0>; -def bitfield DISP19 <18:0>; -def bitfield DISP22 <21:0>; -def bitfield DISP30 <29:0>; -def bitfield FCN <29:26>; -def bitfield I <13>; -def bitfield IMM_ASI <12:5>; -def bitfield IMM22 <21:0>; -def bitfield MMASK <3:0>; -def bitfield OP <31:30>; -def bitfield OP2 <24:22>; -def bitfield OP3 <24:19>; -def bitfield OPF <13:5>; -def bitfield OPF_CC <13:11>; -def bitfield OPF_LOW5 <9:5>; -def bitfield OPF_LOW6 <10:5>; -def bitfield P <19>; -def bitfield RCOND2 <27:25>; -def bitfield RCOND3 <12:10>; -def bitfield RCOND4 <12:10>; -def bitfield RD <29:25>; -def bitfield RS1 <18:14>; -def bitfield RS2 <4:0>; -def bitfield SHCNT32 <4:0>; -def bitfield SHCNT64 <5:0>; -def bitfield SIMM10 <9:0>; -def bitfield SIMM11 <10:0>; -def bitfield SIMM13 <12:0>; -def bitfield SW_TRAP <6:0>; -def bitfield X <12>; +def bitfield SPECIAL_HI < 5: 3>; +def bitfield SPECIAL_HI < 2: 0>; + +def bitfield REGIMM_HI <20:19>; +def bitfield REGIMM_LO <18:16>; + +def bitfield RS <25:21>; +def bitfield RT <20:16>; + +// Integer operate format(s>; +def bitfield INTIMM <15: 0>; // integer immediate (literal) +def bitfield IMM <12:12>; // immediate flag +def bitfield INTFUNC <11: 5>; // function code +def bitfield RD <15:11>; // dest reg + +// Memory format +def signed bitfield MEMDISP <15: 0>; // displacement +def bitfield MEMFUNC <15: 0>; // function code (same field, unsigned) + +// Memory-format jumps +def bitfield JMPFUNC <15:14>; // function code (disp<15:14>) +def bitfield JMPHINT <13: 0>; // tgt Icache idx hint (disp<13:0>) + +// Branch format +def signed bitfield BRDISP <20: 0>; // displacement + +// Floating-point operate format +def bitfield FMT <25:21>; +def bitfield FT <20:16>; +def bitfield FS <15:11>; +def bitfield FD <10: 6>; + +def bitfield FP_FULLFUNC <15: 5>; // complete function code + def bitfield FP_TRAPMODE <15:13>; // trapping mode + def bitfield FP_ROUNDMODE <12:11>; // rounding mode + def bitfield FP_TYPEFUNC <10: 5>; // type+func: handiest for decoding + def bitfield FP_SRCTYPE <10: 9>; // source reg type + def bitfield FP_SHORTFUNC < 8: 5>; // short function code + def bitfield FP_SHORTFUNC_TOP2 <8:7>; // top 2 bits of short func code + +// PALcode format +def bitfield PALFUNC <25: 0>; // function code + +// EV5 PAL instructions: +// HW_LD/HW_ST +def bitfield HW_LDST_PHYS <15>; // address is physical +def bitfield HW_LDST_ALT <14>; // use ALT_MODE IPR +def bitfield HW_LDST_WRTCK <13>; // HW_LD only: fault if no write acc +def bitfield HW_LDST_QUAD <12>; // size: 0=32b, 1=64b +def bitfield HW_LDST_VPTE <11>; // HW_LD only: is PTE fetch +def bitfield HW_LDST_LOCK <10>; // HW_LD only: is load locked +def bitfield HW_LDST_COND <10>; // HW_ST only: is store conditional +def signed bitfield HW_LDST_DISP <9:0>; // signed displacement + +// HW_REI +def bitfield HW_REI_TYP <15:14>; // type: stalling vs. non-stallingk +def bitfield HW_REI_MBZ <13: 0>; // must be zero + +// HW_MTPR/MW_MFPR +def bitfield HW_IPR_IDX <15:0>; // IPR index + +// M5 instructions +def bitfield M5FUNC <7:0>; diff --git a/arch/mips/isa_desc/decoder.h b/arch/mips/isa_desc/decoder.h index 5d71968ce..235ff1ef6 100644 --- a/arch/mips/isa_desc/decoder.h +++ b/arch/mips/isa_desc/decoder.h @@ -7,30 +7,154 @@ // in the MIPS32 ISAthe specification document starting with Table // A-2 (document available @ www.mips.com) // -// +//@todo: Distinguish "unknown/future" use insts from "reserved" +// ones decode OPCODE_HI default FailUnimpl::unknown() { // Derived From ... Table A-2 MIPS32 ISA Manual - 0x0: decode OPCODE_LO { + 0x0: decode OPCODE_LO default FailUnimpl::reserved(){ - 0x0: decode SPECIAL { - 0x0:; - 0x1:; - 0x2:; - 0x3:; - 0x4:; - 0x5:; - 0x6:; + 0x0: decode SPECIAL_HI { + 0x0: decode SPECIAL_LO { + 0x1: decode MOVCI { + format Move { + 0: movc({{ }}); + 1: movt({{ }}); + } + } + + format ShiftRotate { + //Table A-3 Note: "1. Specific encodings of the rt, rd, and sa fields + //are used to distinguish among the SLL, NOP, SSNOP and EHB functions." + 0x0: sll({{ }}); + + 0x2: decode SRL { + 0: srl({{ }}); + 1: rotr({{ }}); + } + + 0x3: sar({{ }}); + + 0x4: sllv({{ }}); + + 0x6: decode SRLV { + 0: srlv({{ }}); + 1: rotrv({{ }}); + } + + 0x7: srav({{ }}); + } + } + + 0x1: decode SPECIAL_LO { + + //Table A-3 Note: "Specific encodings of the hint field are used + //to distinguish JR from JR.HB and JALR from JALR.HB" + format Jump { + 0x0: jr({{ }}); + 0x1: jalr({{ }}); + } + + format Move { + 0x2: movz({{ }}); + 0x3: movn({{ }}); + } + + 0x4: Syscall::syscall({{ }}); + 0x5: Break::break({{ }}); + 0x7: Synchronize::synch({{ }}); + } + + 0x2: decode SPECIAL_LO { + format MultDiv { + 0x0: mfhi({{ }}); + 0x1: mthi({{ }}); + 0x2: mflo({{ }}); + 0x3: mtlo({{ }}); + } + }; + + 0x3: decode SPECIAL_LO { + format MultDiv { + 0x0: mult({{ }}); + 0x1: multu({{ }}); + 0x2: div({{ }}); + 0x3: divu({{ }}); + } + }; + + 0x4: decode SPECIAL_LO { + format Arithmetic { + 0x0: add({{ }}); + 0x1: addu({{ }}); + 0x2: sub({{ }}); + 0x3: subu({{ }}); + } + + format Logical { + 0x0: and({{ }}); + 0x1: or({{ }}); + 0x2: xor({{ }}); + 0x3: nor({{ }}); + } + } + + 0x5: decode SPECIAL_LO { + format SetInstructions{ + 0x2: slt({{ }}); + 0x3: sltu({{ }}); + } + }; + + 0x6: decode SPECIAL_LO { + format Trap { + 0x0: tge({{ }}); + 0x1: tgeu({{ }}); + 0x2: tlt({{ }}); + 0x3: tltu({{ }}); + 0x4: teq({{ }}); + 0x6: tne({{ }}); + } + } } - 0x1: decode REGIMM { - 0x0:; - 0x1:; - 0x2:; - 0x3:; - 0x4:; - 0x5:; - 0x6:; + 0x1: decode REGIMM_HI { + 0x0: decode REGIMM_LO { + format Branch { + 0x0: bltz({{ }}); + 0x1: bgez({{ }}); + + //MIPS obsolete instructions + 0x2: bltzl({{ }}); + 0x3: bgezl({{ }}); + } + } + + 0x1: decode REGIMM_LO { + format Trap { + 0x0: tgei({{ }}); + 0x1: tgeiu({{ }}); + 0x2: tlti({{ }}); + 0x3: tltiu({{ }}); + 0x4: teqi({{ }}); + 0x6: tnei({{ }}); + } + } + + 0x2: decode REGIMM_LO { + format Branch { + 0x0: bltzal({{ }}); + 0x1: bgezal({{ }}); + + //MIPS obsolete instructions + 0x2: bltzall({{ }}); + 0x3: bgezall({{ }}); + } + } + + 0x3: decode REGIMM_LO { + 0x7: synci({{ }}); + } } format Jump { @@ -46,7 +170,7 @@ decode OPCODE_HI default FailUnimpl::unknown() { } }; - 0x1: decode OPCODE_LO { + 0x1: decode OPCODE_LO default FailUnimpl::reserved(){ format IntImmediate { 0x0: addi({{ }}); 0x1: addiu({{ }}); @@ -59,29 +183,39 @@ decode OPCODE_HI default FailUnimpl::unknown() { }; }; - 0x2: decode OPCODE_LO { - format FailUnimpl{ - 0x0: coprocessor_op({{ }}); - 0x1: coprocessor_op({{ }}); - 0x2: coprocessor_op({{ }}); - 0x3: coprocessor_op({{ }}); - }; + 0x2: decode OPCODE_LO default FailUnimpl::reserved(){ - //MIPS obsolete instructions - 0x4: beql({{ }}); - 0x5: bnel({{ }}); - 0x6: blezl({{ }}); - 0x7: bgtzl({{ }}); + 0x0: decode RS { + //Table A-11 MIPS32 COP0 Encoding of rs Field + } + + 0x1: decode RS { + //Table A-13 MIPS32 COP1 Encoding of rs Field + } + + 0x2: decode RS { + //Table A-19 MIPS32 COP2 Encoding of rs Field + } + + 0x3: decode FUNCTION_HI { + //Table A-20 MIPS64 COP1X Encoding of Function Field 1 + } + + //MIPS obsolete instructions + 0x4: beql({{ }}); + 0x5: bnel({{ }}); + 0x6: blezl({{ }}); + 0x7: bgtzl({{ }}); }; - 0x3: decode OPCODE_LO { + 0x3: decode OPCODE_LO default FailUnimpl::reserved(){ format FailUnimpl{ - 0x0: reserved({{ }}) - 0x1: reserved({{ }}) - 0x2: reserved({{ }}) - 0x3: reserved({{ }}) - 0x5: reserved({{ }}) - 0x6: reserved({{ }}) + 0x0: reserved_inst_exception({{ }}) + 0x1: reserved_inst_exception({{ }}) + 0x2: reserved_inst_exception({{ }}) + 0x3: reserved_inst_exception({{ }}) + 0x5: reserved_inst_exception({{ }}) + 0x6: reserved_inst_exception({{ }}) }; 4: decode SPECIAL2 { @@ -105,7 +239,7 @@ decode OPCODE_HI default FailUnimpl::unknown() { } }; - 0x4: decode OPCODE_LO { + 0x4: decode OPCODE_LO default FailUnimpl::reserved(){ format LoadMemory{ 0x0: lb({{ }}); 0x1: lh({{ }}); @@ -116,10 +250,10 @@ decode OPCODE_HI default FailUnimpl::unknown() { 0x6: lhu({{ }}); }; - 0x7: FailUnimpl::reserved({{ }}); + 0x7: FailUnimpl::reserved_inst_exception({{ }}); }; - 0x5: decode OPCODE_LO { + 0x5: decode OPCODE_LO default FailUnimpl::reserved(){ format StoreMemory{ 0x0: sb({{ }}); 0x1: sh({{ }}); @@ -129,14 +263,14 @@ decode OPCODE_HI default FailUnimpl::unknown() { }; format FailUnimpl{ - 0x4: reserved({{ }}); - 0x5: reserved({{ }}); + 0x4: reserved_inst_exception({{ }}); + 0x5: reserved_inst_exception({{ }}); 0x2: cache({{ }}); }; }; - 0x6: decode OPCODE_LO { + 0x6: decode OPCODE_LO default FailUnimpl::reserved(){ format LoadMemory{ 0x0: ll({{ }}); 0x1: lwc1({{ }}); @@ -146,14 +280,14 @@ decode OPCODE_HI default FailUnimpl::unknown() { format FailUnimpl{ 0x2: lwc2({{ }}); 0x3: pref({{ }}); - 0x4: reserved({{ }}); + 0x4: reserved_inst_exception({{ }}); 0x6: ldc2({{ }}); - 0x7: reserved({{ }}); + 0x7: reserved_inst_exception({{ }}); }; }; - 0x7: decode OPCODE_LO { + 0x7: decode OPCODE_LO default FailUnimpl::reserved(){ format StoreMemory{ 0x0: sc({{ }}); 0x1: swc1({{ }}); @@ -162,830 +296,13 @@ decode OPCODE_HI default FailUnimpl::unknown() { format FailUnimpl{ 0x2: swc2({{ }}); - 0x3: reserved({{ }}); - 0x4: reserved({{ }}); + 0x3: reserved_inst_exception({{ }}); + 0x4: reserved_inst_exception({{ }}); 0x6: sdc2({{ }}); - 0x7: reserved({{ }}); + 0x7: reserved_inst_exception({{ }}); }; }; - - //Table 3-1 CPU Arithmetic Instructions ( ) - format IntegerOperate { - - 0x10: decode INTFUNC { // integer arithmetic operations - - //ADD Add Word - - //ADDI Add Immediate Word - - //ADDIU Add Immediate Unsigned Word - - //ADDU Add Unsigned Word - - 0x00: addl({{ Rc.sl = Ra.sl + Rb_or_imm.sl; }}); - 0x40: addlv({{ - uint32_t tmp = Ra.sl + Rb_or_imm.sl; - // signed overflow occurs when operands have same sign - // and sign of result does not match. - if (Ra.sl<31:> == Rb_or_imm.sl<31:> && tmp<31:> != Ra.sl<31:>) - fault = Integer_Overflow_Fault; - Rc.sl = tmp; - }}); - 0x02: s4addl({{ Rc.sl = (Ra.sl << 2) + Rb_or_imm.sl; }}); - 0x12: s8addl({{ Rc.sl = (Ra.sl << 3) + Rb_or_imm.sl; }}); - - 0x20: addq({{ Rc = Ra + Rb_or_imm; }}); - 0x60: addqv({{ - uint64_t tmp = Ra + Rb_or_imm; - // signed overflow occurs when operands have same sign - // and sign of result does not match. - if (Ra<63:> == Rb_or_imm<63:> && tmp<63:> != Ra<63:>) - fault = Integer_Overflow_Fault; - Rc = tmp; - }}); - 0x22: s4addq({{ Rc = (Ra << 2) + Rb_or_imm; }}); - 0x32: s8addq({{ Rc = (Ra << 3) + Rb_or_imm; }}); - - 0x09: subl({{ Rc.sl = Ra.sl - Rb_or_imm.sl; }}); - 0x49: sublv({{ - uint32_t tmp = Ra.sl - Rb_or_imm.sl; - // signed overflow detection is same as for add, - // except we need to look at the *complemented* - // sign bit of the subtrahend (Rb), i.e., if the initial - // signs are the *same* then no overflow can occur - if (Ra.sl<31:> != Rb_or_imm.sl<31:> && tmp<31:> != Ra.sl<31:>) - fault = Integer_Overflow_Fault; - Rc.sl = tmp; - }}); - 0x0b: s4subl({{ Rc.sl = (Ra.sl << 2) - Rb_or_imm.sl; }}); - 0x1b: s8subl({{ Rc.sl = (Ra.sl << 3) - Rb_or_imm.sl; }}); - - 0x29: subq({{ Rc = Ra - Rb_or_imm; }}); - 0x69: subqv({{ - uint64_t tmp = Ra - Rb_or_imm; - // signed overflow detection is same as for add, - // except we need to look at the *complemented* - // sign bit of the subtrahend (Rb), i.e., if the initial - // signs are the *same* then no overflow can occur - if (Ra<63:> != Rb_or_imm<63:> && tmp<63:> != Ra<63:>) - fault = Integer_Overflow_Fault; - Rc = tmp; - }}); - 0x2b: s4subq({{ Rc = (Ra << 2) - Rb_or_imm; }}); - 0x3b: s8subq({{ Rc = (Ra << 3) - Rb_or_imm; }}); - - 0x2d: cmpeq({{ Rc = (Ra == Rb_or_imm); }}); - 0x6d: cmple({{ Rc = (Ra.sq <= Rb_or_imm.sq); }}); - 0x4d: cmplt({{ Rc = (Ra.sq < Rb_or_imm.sq); }}); - 0x3d: cmpule({{ Rc = (Ra.uq <= Rb_or_imm.uq); }}); - 0x1d: cmpult({{ Rc = (Ra.uq < Rb_or_imm.uq); }}); - - 0x0f: cmpbge({{ - int hi = 7; - int lo = 0; - uint64_t tmp = 0; - for (int i = 0; i < 8; ++i) { - tmp |= (Ra.uq >= Rb_or_imm.uq) << i; - hi += 8; - lo += 8; - } - Rc = tmp; - }}); - } - - 0x11: decode INTFUNC { // integer logical operations - - 0x00: and({{ Rc = Ra & Rb_or_imm; }}); - 0x08: bic({{ Rc = Ra & ~Rb_or_imm; }}); - 0x20: bis({{ Rc = Ra | Rb_or_imm; }}); - 0x28: ornot({{ Rc = Ra | ~Rb_or_imm; }}); - 0x40: xor({{ Rc = Ra ^ Rb_or_imm; }}); - 0x48: eqv({{ Rc = Ra ^ ~Rb_or_imm; }}); - - // conditional moves - 0x14: cmovlbs({{ Rc = ((Ra & 1) == 1) ? Rb_or_imm : Rc; }}); - 0x16: cmovlbc({{ Rc = ((Ra & 1) == 0) ? Rb_or_imm : Rc; }}); - 0x24: cmoveq({{ Rc = (Ra == 0) ? Rb_or_imm : Rc; }}); - 0x26: cmovne({{ Rc = (Ra != 0) ? Rb_or_imm : Rc; }}); - 0x44: cmovlt({{ Rc = (Ra.sq < 0) ? Rb_or_imm : Rc; }}); - 0x46: cmovge({{ Rc = (Ra.sq >= 0) ? Rb_or_imm : Rc; }}); - 0x64: cmovle({{ Rc = (Ra.sq <= 0) ? Rb_or_imm : Rc; }}); - 0x66: cmovgt({{ Rc = (Ra.sq > 0) ? Rb_or_imm : Rc; }}); - - // For AMASK, RA must be R31. - 0x61: decode RA { - 31: amask({{ Rc = Rb_or_imm & ~ULL(0x17); }}); - } - - // For IMPLVER, RA must be R31 and the B operand - // must be the immediate value 1. - 0x6c: decode RA { - 31: decode IMM { - 1: decode INTIMM { - // return EV5 for FULL_SYSTEM and EV6 otherwise - 1: implver({{ -#if FULL_SYSTEM - Rc = 1; -#else - Rc = 2; -#endif - }}); - } - } - } - -#if FULL_SYSTEM - // The mysterious 11.25... - 0x25: WarnUnimpl::eleven25(); -#endif - } - - 0x12: decode INTFUNC { - 0x39: sll({{ Rc = Ra << Rb_or_imm<5:0>; }}); - 0x34: srl({{ Rc = Ra.uq >> Rb_or_imm<5:0>; }}); - 0x3c: sra({{ Rc = Ra.sq >> Rb_or_imm<5:0>; }}); - - 0x02: mskbl({{ Rc = Ra & ~(mask( 8) << (Rb_or_imm<2:0> * 8)); }}); - 0x12: mskwl({{ Rc = Ra & ~(mask(16) << (Rb_or_imm<2:0> * 8)); }}); - 0x22: mskll({{ Rc = Ra & ~(mask(32) << (Rb_or_imm<2:0> * 8)); }}); - 0x32: mskql({{ Rc = Ra & ~(mask(64) << (Rb_or_imm<2:0> * 8)); }}); - - 0x52: mskwh({{ - int bv = Rb_or_imm<2:0>; - Rc = bv ? (Ra & ~(mask(16) >> (64 - 8 * bv))) : Ra; - }}); - 0x62: msklh({{ - int bv = Rb_or_imm<2:0>; - Rc = bv ? (Ra & ~(mask(32) >> (64 - 8 * bv))) : Ra; - }}); - 0x72: mskqh({{ - int bv = Rb_or_imm<2:0>; - Rc = bv ? (Ra & ~(mask(64) >> (64 - 8 * bv))) : Ra; - }}); - - 0x06: extbl({{ Rc = (Ra.uq >> (Rb_or_imm<2:0> * 8))< 7:0>; }}); - 0x16: extwl({{ Rc = (Ra.uq >> (Rb_or_imm<2:0> * 8))<15:0>; }}); - 0x26: extll({{ Rc = (Ra.uq >> (Rb_or_imm<2:0> * 8))<31:0>; }}); - 0x36: extql({{ Rc = (Ra.uq >> (Rb_or_imm<2:0> * 8)); }}); - - 0x5a: extwh({{ - Rc = (Ra << (64 - (Rb_or_imm<2:0> * 8))<5:0>)<15:0>; }}); - 0x6a: extlh({{ - Rc = (Ra << (64 - (Rb_or_imm<2:0> * 8))<5:0>)<31:0>; }}); - 0x7a: extqh({{ - Rc = (Ra << (64 - (Rb_or_imm<2:0> * 8))<5:0>); }}); - - 0x0b: insbl({{ Rc = Ra< 7:0> << (Rb_or_imm<2:0> * 8); }}); - 0x1b: inswl({{ Rc = Ra<15:0> << (Rb_or_imm<2:0> * 8); }}); - 0x2b: insll({{ Rc = Ra<31:0> << (Rb_or_imm<2:0> * 8); }}); - 0x3b: insql({{ Rc = Ra << (Rb_or_imm<2:0> * 8); }}); - - 0x57: inswh({{ - int bv = Rb_or_imm<2:0>; - Rc = bv ? (Ra.uq<15:0> >> (64 - 8 * bv)) : 0; - }}); - 0x67: inslh({{ - int bv = Rb_or_imm<2:0>; - Rc = bv ? (Ra.uq<31:0> >> (64 - 8 * bv)) : 0; - }}); - 0x77: insqh({{ - int bv = Rb_or_imm<2:0>; - Rc = bv ? (Ra.uq >> (64 - 8 * bv)) : 0; - }}); - - 0x30: zap({{ - uint64_t zapmask = 0; - for (int i = 0; i < 8; ++i) { - if (Rb_or_imm) - zapmask |= (mask(8) << (i * 8)); - } - Rc = Ra & ~zapmask; - }}); - 0x31: zapnot({{ - uint64_t zapmask = 0; - for (int i = 0; i < 8; ++i) { - if (!Rb_or_imm) - zapmask |= (mask(8) << (i * 8)); - } - Rc = Ra & ~zapmask; - }}); - } - - 0x13: decode INTFUNC { // integer multiplies - 0x00: mull({{ Rc.sl = Ra.sl * Rb_or_imm.sl; }}, IntMultOp); - 0x20: mulq({{ Rc = Ra * Rb_or_imm; }}, IntMultOp); - 0x30: umulh({{ - uint64_t hi, lo; - mul128(Ra, Rb_or_imm, hi, lo); - Rc = hi; - }}, IntMultOp); - 0x40: mullv({{ - // 32-bit multiply with trap on overflow - int64_t Rax = Ra.sl; // sign extended version of Ra.sl - int64_t Rbx = Rb_or_imm.sl; - int64_t tmp = Rax * Rbx; - // To avoid overflow, all the upper 32 bits must match - // the sign bit of the lower 32. We code this as - // checking the upper 33 bits for all 0s or all 1s. - uint64_t sign_bits = tmp<63:31>; - if (sign_bits != 0 && sign_bits != mask(33)) - fault = Integer_Overflow_Fault; - Rc.sl = tmp<31:0>; - }}, IntMultOp); - 0x60: mulqv({{ - // 64-bit multiply with trap on overflow - uint64_t hi, lo; - mul128(Ra, Rb_or_imm, hi, lo); - // all the upper 64 bits must match the sign bit of - // the lower 64 - if (!((hi == 0 && lo<63:> == 0) || - (hi == mask(64) && lo<63:> == 1))) - fault = Integer_Overflow_Fault; - Rc = lo; - }}, IntMultOp); - } - - 0x1c: decode INTFUNC { - 0x00: decode RA { 31: sextb({{ Rc.sb = Rb_or_imm< 7:0>; }}); } - 0x01: decode RA { 31: sextw({{ Rc.sw = Rb_or_imm<15:0>; }}); } - 0x32: ctlz({{ - uint64_t count = 0; - uint64_t temp = Rb; - if (temp<63:32>) temp >>= 32; else count += 32; - if (temp<31:16>) temp >>= 16; else count += 16; - if (temp<15:8>) temp >>= 8; else count += 8; - if (temp<7:4>) temp >>= 4; else count += 4; - if (temp<3:2>) temp >>= 2; else count += 2; - if (temp<1:1>) temp >>= 1; else count += 1; - if ((temp<0:0>) != 0x1) count += 1; - Rc = count; - }}, IntAluOp); - - 0x33: cttz({{ - uint64_t count = 0; - uint64_t temp = Rb; - if (!(temp<31:0>)) { temp >>= 32; count += 32; } - if (!(temp<15:0>)) { temp >>= 16; count += 16; } - if (!(temp<7:0>)) { temp >>= 8; count += 8; } - if (!(temp<3:0>)) { temp >>= 4; count += 4; } - if (!(temp<1:0>)) { temp >>= 2; count += 2; } - if (!(temp<0:0> & ULL(0x1))) count += 1; - Rc = count; - }}, IntAluOp); - - format FailUnimpl { - 0x30: ctpop(); - 0x31: perr(); - 0x34: unpkbw(); - 0x35: unpkbl(); - 0x36: pkwb(); - 0x37: pklb(); - 0x38: minsb8(); - 0x39: minsw4(); - 0x3a: minub8(); - 0x3b: minuw4(); - 0x3c: maxub8(); - 0x3d: maxuw4(); - 0x3e: maxsb8(); - 0x3f: maxsw4(); - } - - format BasicOperateWithNopCheck { - 0x70: decode RB { - 31: ftoit({{ Rc = Fa.uq; }}, FloatCvtOp); - } - 0x78: decode RB { - 31: ftois({{ Rc.sl = t_to_s(Fa.uq); }}, - FloatCvtOp); - } - } - } - } - - //Table 3-2 CPU Branch and Jump Instructions ( ) - //Table 3-10 Obsolete CPU Branch Instructions ( ) - - //Table 3-3 CPU Instruction Control Instructions ( ) - - //Table 3-4 CPU Load, Store, and Memory Control Instructions ( ) - - //Table 3-5 CPU Logical Instructions ( ) - - //Table 3-6 CPU Insert/Extract Instructions ( ) - - //Table 3-7 CPU Move Instructions ( ) - - //Table 3-9 CPU Trap Instructions ( ) - - //Table 3-11 FPU Arithmetic Instructions ( ) - - //Table 3-12 FPU Branch Instructions ( ) - //Table 3-17 Obsolete FPU Branch Instructions () - - //Table 3-13 FPU Compare Instructions ( ) - - //Table 3-14 FPU Convert Instructions ( ) - - //Table 3-15 FPU Load, Store, and Memory Control Instructions ( ) - - //Table 3-16 FPU Move Instructions ( ) - - //Tables 3-18 thru 3-22 are Co-Processor Instructions ( ) - - //Table 3-23 Privileged Instructions ( ) - - //Table 3-24 EJTAG Instructions ( ) - - - - - format LoadAddress { - 0x08: lda({{ Ra = Rb + disp; }}); - 0x09: ldah({{ Ra = Rb + (disp << 16); }}); - } - - format LoadOrNop { - 0x0a: ldbu({{ EA = Rb + disp; }}, {{ Ra.uq = Mem.ub; }}); - 0x0c: ldwu({{ EA = Rb + disp; }}, {{ Ra.uq = Mem.uw; }}); - 0x0b: ldq_u({{ EA = (Rb + disp) & ~7; }}, {{ Ra = Mem.uq; }}); - 0x23: ldt({{ EA = Rb + disp; }}, {{ Fa = Mem.df; }}); - 0x2a: ldl_l({{ EA = Rb + disp; }}, {{ Ra.sl = Mem.sl; }}, LOCKED); - 0x2b: ldq_l({{ EA = Rb + disp; }}, {{ Ra.uq = Mem.uq; }}, LOCKED); - 0x20: copy_load({{EA = Ra;}}, - {{fault = xc->copySrcTranslate(EA);}}, - IsMemRef, IsLoad, IsCopy); - } - - format LoadOrPrefetch { - 0x28: ldl({{ EA = Rb + disp; }}, {{ Ra.sl = Mem.sl; }}); - 0x29: ldq({{ EA = Rb + disp; }}, {{ Ra.uq = Mem.uq; }}, EVICT_NEXT); - // IsFloating flag on lds gets the prefetch to disassemble - // using f31 instead of r31... funcitonally it's unnecessary - 0x22: lds({{ EA = Rb + disp; }}, {{ Fa.uq = s_to_t(Mem.ul); }}, - PF_EXCLUSIVE, IsFloating); - } - - format Store { - 0x0e: stb({{ EA = Rb + disp; }}, {{ Mem.ub = Ra<7:0>; }}); - 0x0d: stw({{ EA = Rb + disp; }}, {{ Mem.uw = Ra<15:0>; }}); - 0x2c: stl({{ EA = Rb + disp; }}, {{ Mem.ul = Ra<31:0>; }}); - 0x2d: stq({{ EA = Rb + disp; }}, {{ Mem.uq = Ra.uq; }}); - 0x0f: stq_u({{ EA = (Rb + disp) & ~7; }}, {{ Mem.uq = Ra.uq; }}); - 0x26: sts({{ EA = Rb + disp; }}, {{ Mem.ul = t_to_s(Fa.uq); }}); - 0x27: stt({{ EA = Rb + disp; }}, {{ Mem.df = Fa; }}); - 0x24: copy_store({{EA = Rb;}}, - {{fault = xc->copy(EA);}}, - IsMemRef, IsStore, IsCopy); - } - - format StoreCond { - 0x2e: stl_c({{ EA = Rb + disp; }}, {{ Mem.ul = Ra<31:0>; }}, - {{ - uint64_t tmp = Mem_write_result; - // see stq_c - Ra = (tmp == 0 || tmp == 1) ? tmp : Ra; - }}, LOCKED); - 0x2f: stq_c({{ EA = Rb + disp; }}, {{ Mem.uq = Ra; }}, - {{ - uint64_t tmp = Mem_write_result; - // If the write operation returns 0 or 1, then - // this was a conventional store conditional, - // and the value indicates the success/failure - // of the operation. If another value is - // returned, then this was a Turbolaser - // mailbox access, and we don't update the - // result register at all. - Ra = (tmp == 0 || tmp == 1) ? tmp : Ra; - }}, LOCKED); - } - - - - // Conditional branches. - format CondBranch { - 0x39: beq({{ cond = (Ra == 0); }}); - 0x3d: bne({{ cond = (Ra != 0); }}); - 0x3e: bge({{ cond = (Ra.sq >= 0); }}); - 0x3f: bgt({{ cond = (Ra.sq > 0); }}); - 0x3b: ble({{ cond = (Ra.sq <= 0); }}); - 0x3a: blt({{ cond = (Ra.sq < 0); }}); - 0x38: blbc({{ cond = ((Ra & 1) == 0); }}); - 0x3c: blbs({{ cond = ((Ra & 1) == 1); }}); - - 0x31: fbeq({{ cond = (Fa == 0); }}); - 0x35: fbne({{ cond = (Fa != 0); }}); - 0x36: fbge({{ cond = (Fa >= 0); }}); - 0x37: fbgt({{ cond = (Fa > 0); }}); - 0x33: fble({{ cond = (Fa <= 0); }}); - 0x32: fblt({{ cond = (Fa < 0); }}); - } - - // unconditional branches - format UncondBranch { - 0x30: br(); - 0x34: bsr(IsCall); - } - - // indirect branches - 0x1a: decode JMPFUNC { - format Jump { - 0: jmp(); - 1: jsr(IsCall); - 2: ret(IsReturn); - 3: jsr_coroutine(IsCall, IsReturn); - } - } - - // Square root and integer-to-FP moves - 0x14: decode FP_SHORTFUNC { - // Integer to FP register moves must have RB == 31 - 0x4: decode RB { - 31: decode FP_FULLFUNC { - format BasicOperateWithNopCheck { - 0x004: itofs({{ Fc.uq = s_to_t(Ra.ul); }}, FloatCvtOp); - 0x024: itoft({{ Fc.uq = Ra.uq; }}, FloatCvtOp); - 0x014: FailUnimpl::itoff(); // VAX-format conversion - } - } - } - - // Square root instructions must have FA == 31 - 0xb: decode FA { - 31: decode FP_TYPEFUNC { - format FloatingPointOperate { -#if SS_COMPATIBLE_FP - 0x0b: sqrts({{ - if (Fb < 0.0) - fault = Arithmetic_Fault; - Fc = sqrt(Fb); - }}, FloatSqrtOp); -#else - 0x0b: sqrts({{ - if (Fb.sf < 0.0) - fault = Arithmetic_Fault; - Fc.sf = sqrt(Fb.sf); - }}, FloatSqrtOp); -#endif - 0x2b: sqrtt({{ - if (Fb < 0.0) - fault = Arithmetic_Fault; - Fc = sqrt(Fb); - }}, FloatSqrtOp); - } - } - } - - // VAX-format sqrtf and sqrtg are not implemented - 0xa: FailUnimpl::sqrtfg(); - } - - // IEEE floating point - 0x16: decode FP_SHORTFUNC_TOP2 { - // The top two bits of the short function code break this - // space into four groups: binary ops, compares, reserved, and - // conversions. See Table 4-12 of AHB. There are different - // special cases in these different groups, so we decode on - // these top two bits first just to select a decode strategy. - // Most of these instructions may have various trapping and - // rounding mode flags set; these are decoded in the - // FloatingPointDecode template used by the - // FloatingPointOperate format. - - // add/sub/mul/div: just decode on the short function code - // and source type. All valid trapping and rounding modes apply. - 0: decode FP_TRAPMODE { - // check for valid trapping modes here - 0,1,5,7: decode FP_TYPEFUNC { - format FloatingPointOperate { -#if SS_COMPATIBLE_FP - 0x00: adds({{ Fc = Fa + Fb; }}); - 0x01: subs({{ Fc = Fa - Fb; }}); - 0x02: muls({{ Fc = Fa * Fb; }}, FloatMultOp); - 0x03: divs({{ Fc = Fa / Fb; }}, FloatDivOp); -#else - 0x00: adds({{ Fc.sf = Fa.sf + Fb.sf; }}); - 0x01: subs({{ Fc.sf = Fa.sf - Fb.sf; }}); - 0x02: muls({{ Fc.sf = Fa.sf * Fb.sf; }}, FloatMultOp); - 0x03: divs({{ Fc.sf = Fa.sf / Fb.sf; }}, FloatDivOp); -#endif - - 0x20: addt({{ Fc = Fa + Fb; }}); - 0x21: subt({{ Fc = Fa - Fb; }}); - 0x22: mult({{ Fc = Fa * Fb; }}, FloatMultOp); - 0x23: divt({{ Fc = Fa / Fb; }}, FloatDivOp); - } - } - } - - // Floating-point compare instructions must have the default - // rounding mode, and may use the default trapping mode or - // /SU. Both trapping modes are treated the same by M5; the - // only difference on the real hardware (as far a I can tell) - // is that without /SU you'd get an imprecise trap if you - // tried to compare a NaN with something else (instead of an - // "unordered" result). - 1: decode FP_FULLFUNC { - format BasicOperateWithNopCheck { - 0x0a5, 0x5a5: cmpteq({{ Fc = (Fa == Fb) ? 2.0 : 0.0; }}, - FloatCmpOp); - 0x0a7, 0x5a7: cmptle({{ Fc = (Fa <= Fb) ? 2.0 : 0.0; }}, - FloatCmpOp); - 0x0a6, 0x5a6: cmptlt({{ Fc = (Fa < Fb) ? 2.0 : 0.0; }}, - FloatCmpOp); - 0x0a4, 0x5a4: cmptun({{ // unordered - Fc = (!(Fa < Fb) && !(Fa == Fb) && !(Fa > Fb)) ? 2.0 : 0.0; - }}, FloatCmpOp); - } - } - - // The FP-to-integer and integer-to-FP conversion insts - // require that FA be 31. - 3: decode FA { - 31: decode FP_TYPEFUNC { - format FloatingPointOperate { - 0x2f: decode FP_ROUNDMODE { - format FPFixedRounding { - // "chopped" i.e. round toward zero - 0: cvttq({{ Fc.sq = (int64_t)trunc(Fb); }}, - Chopped); - // round to minus infinity - 1: cvttq({{ Fc.sq = (int64_t)floor(Fb); }}, - MinusInfinity); - } - default: cvttq({{ Fc.sq = (int64_t)nearbyint(Fb); }}); - } - - // The cvtts opcode is overloaded to be cvtst if the trap - // mode is 2 or 6 (which are not valid otherwise) - 0x2c: decode FP_FULLFUNC { - format BasicOperateWithNopCheck { - // trap on denorm version "cvtst/s" is - // simulated same as cvtst - 0x2ac, 0x6ac: cvtst({{ Fc = Fb.sf; }}); - } - default: cvtts({{ Fc.sf = Fb; }}); - } - - // The trapping mode for integer-to-FP conversions - // must be /SUI or nothing; /U and /SU are not - // allowed. The full set of rounding modes are - // supported though. - 0x3c: decode FP_TRAPMODE { - 0,7: cvtqs({{ Fc.sf = Fb.sq; }}); - } - 0x3e: decode FP_TRAPMODE { - 0,7: cvtqt({{ Fc = Fb.sq; }}); - } - } - } - } - } - - // misc FP operate - 0x17: decode FP_FULLFUNC { - format BasicOperateWithNopCheck { - 0x010: cvtlq({{ - Fc.sl = (Fb.uq<63:62> << 30) | Fb.uq<58:29>; - }}); - 0x030: cvtql({{ - Fc.uq = (Fb.uq<31:30> << 62) | (Fb.uq<29:0> << 29); - }}); - - // We treat the precise & imprecise trapping versions of - // cvtql identically. - 0x130, 0x530: cvtqlv({{ - // To avoid overflow, all the upper 32 bits must match - // the sign bit of the lower 32. We code this as - // checking the upper 33 bits for all 0s or all 1s. - uint64_t sign_bits = Fb.uq<63:31>; - if (sign_bits != 0 && sign_bits != mask(33)) - fault = Integer_Overflow_Fault; - Fc.uq = (Fb.uq<31:30> << 62) | (Fb.uq<29:0> << 29); - }}); - - 0x020: cpys({{ // copy sign - Fc.uq = (Fa.uq<63:> << 63) | Fb.uq<62:0>; - }}); - 0x021: cpysn({{ // copy sign negated - Fc.uq = (~Fa.uq<63:> << 63) | Fb.uq<62:0>; - }}); - 0x022: cpyse({{ // copy sign and exponent - Fc.uq = (Fa.uq<63:52> << 52) | Fb.uq<51:0>; - }}); - - 0x02a: fcmoveq({{ Fc = (Fa == 0) ? Fb : Fc; }}); - 0x02b: fcmovne({{ Fc = (Fa != 0) ? Fb : Fc; }}); - 0x02c: fcmovlt({{ Fc = (Fa < 0) ? Fb : Fc; }}); - 0x02d: fcmovge({{ Fc = (Fa >= 0) ? Fb : Fc; }}); - 0x02e: fcmovle({{ Fc = (Fa <= 0) ? Fb : Fc; }}); - 0x02f: fcmovgt({{ Fc = (Fa > 0) ? Fb : Fc; }}); - - 0x024: mt_fpcr({{ FPCR = Fa.uq; }}); - 0x025: mf_fpcr({{ Fa.uq = FPCR; }}); - } - } - - // miscellaneous mem-format ops - 0x18: decode MEMFUNC { - format WarnUnimpl { - 0x8000: fetch(); - 0xa000: fetch_m(); - 0xe800: ecb(); - } - - format MiscPrefetch { - 0xf800: wh64({{ EA = Rb & ~ULL(63); }}, - {{ xc->writeHint(EA, 64, memAccessFlags); }}, - IsMemRef, IsDataPrefetch, IsStore, MemWriteOp, - NO_FAULT); - } - - format BasicOperate { - 0xc000: rpcc({{ -#if FULL_SYSTEM - /* Rb is a fake dependency so here is a fun way to get - * the parser to understand that. - */ - Ra = xc->readIpr(MipsISA::IPR_CC, fault) + (Rb & 0); - -#else - Ra = curTick; -#endif - }}); - - // All of the barrier instructions below do nothing in - // their execute() methods (hence the empty code blocks). - // All of their functionality is hard-coded in the - // pipeline based on the flags IsSerializing, - // IsMemBarrier, and IsWriteBarrier. In the current - // detailed CPU model, the execute() function only gets - // called at fetch, so there's no way to generate pipeline - // behavior at any other stage. Once we go to an - // exec-in-exec CPU model we should be able to get rid of - // these flags and implement this behavior via the - // execute() methods. - - // trapb is just a barrier on integer traps, where excb is - // a barrier on integer and FP traps. "EXCB is thus a - // superset of TRAPB." (Mips ARM, Sec 4.11.4) We treat - // them the same though. - 0x0000: trapb({{ }}, IsSerializing, IsSerializeBefore, No_OpClass); - 0x0400: excb({{ }}, IsSerializing, IsSerializeBefore, No_OpClass); - 0x4000: mb({{ }}, IsMemBarrier, MemReadOp); - 0x4400: wmb({{ }}, IsWriteBarrier, MemWriteOp); - } - -#if FULL_SYSTEM - format BasicOperate { - 0xe000: rc({{ - Ra = xc->readIntrFlag(); - xc->setIntrFlag(0); - }}, IsNonSpeculative); - 0xf000: rs({{ - Ra = xc->readIntrFlag(); - xc->setIntrFlag(1); - }}, IsNonSpeculative); - } -#else - format FailUnimpl { - 0xe000: rc(); - 0xf000: rs(); - } -#endif - } - -#if FULL_SYSTEM - 0x00: CallPal::call_pal({{ - if (!palValid || - (palPriv - && xc->readIpr(MipsISA::IPR_ICM, fault) != MipsISA::mode_kernel)) { - // invalid pal function code, or attempt to do privileged - // PAL call in non-kernel mode - fault = Unimplemented_Opcode_Fault; - } - else { - // check to see if simulator wants to do something special - // on this PAL call (including maybe suppress it) - bool dopal = xc->simPalCheck(palFunc); - - if (dopal) { - MipsISA::swap_palshadow(&xc->xcBase()->regs, true); - xc->setIpr(MipsISA::IPR_EXC_ADDR, NPC); - NPC = xc->readIpr(MipsISA::IPR_PAL_BASE, fault) + palOffset; - } - } - }}, IsNonSpeculative); -#else - 0x00: decode PALFUNC { - format EmulatedCallPal { - 0x00: halt ({{ - SimExit(curTick, "halt instruction encountered"); - }}, IsNonSpeculative); - 0x83: callsys({{ - xc->syscall(); - }}, IsNonSpeculative, IsSerializeAfter); - // Read uniq reg into ABI return value register (r0) - 0x9e: rduniq({{ R0 = Runiq; }}); - // Write uniq reg with value from ABI arg register (r16) - 0x9f: wruniq({{ Runiq = R16; }}); - } - } -#endif - -#if FULL_SYSTEM - format HwLoadStore { - 0x1b: decode HW_LDST_QUAD { - 0: hw_ld({{ EA = (Rb + disp) & ~3; }}, {{ Ra = Mem.ul; }}, L); - 1: hw_ld({{ EA = (Rb + disp) & ~7; }}, {{ Ra = Mem.uq; }}, Q); - } - - 0x1f: decode HW_LDST_COND { - 0: decode HW_LDST_QUAD { - 0: hw_st({{ EA = (Rb + disp) & ~3; }}, - {{ Mem.ul = Ra<31:0>; }}, L); - 1: hw_st({{ EA = (Rb + disp) & ~7; }}, - {{ Mem.uq = Ra.uq; }}, Q); - } - - 1: FailUnimpl::hw_st_cond(); - } - } - - format HwMoveIPR { - 0x19: hw_mfpr({{ - // this instruction is only valid in PAL mode - if (!xc->inPalMode()) { - fault = Unimplemented_Opcode_Fault; - } - else { - Ra = xc->readIpr(ipr_index, fault); - } - }}); - 0x1d: hw_mtpr({{ - // this instruction is only valid in PAL mode - if (!xc->inPalMode()) { - fault = Unimplemented_Opcode_Fault; - } - else { - xc->setIpr(ipr_index, Ra); - if (traceData) { traceData->setData(Ra); } - } - }}); - } - - format BasicOperate { - 0x1e: hw_rei({{ xc->hwrei(); }}, IsSerializing, IsSerializeBefore); - - // M5 special opcodes use the reserved 0x01 opcode space - 0x01: decode M5FUNC { - 0x00: arm({{ - MipsPseudo::arm(xc->xcBase()); - }}, IsNonSpeculative); - 0x01: quiesce({{ - MipsPseudo::quiesce(xc->xcBase()); - }}, IsNonSpeculative); - 0x10: ivlb({{ - MipsPseudo::ivlb(xc->xcBase()); - }}, No_OpClass, IsNonSpeculative); - 0x11: ivle({{ - MipsPseudo::ivle(xc->xcBase()); - }}, No_OpClass, IsNonSpeculative); - 0x20: m5exit_old({{ - MipsPseudo::m5exit_old(xc->xcBase()); - }}, No_OpClass, IsNonSpeculative); - 0x21: m5exit({{ - MipsPseudo::m5exit(xc->xcBase()); - }}, No_OpClass, IsNonSpeculative); - 0x30: initparam({{ Ra = xc->xcBase()->cpu->system->init_param; }}); - 0x40: resetstats({{ - MipsPseudo::resetstats(xc->xcBase()); - }}, IsNonSpeculative); - 0x41: dumpstats({{ - MipsPseudo::dumpstats(xc->xcBase()); - }}, IsNonSpeculative); - 0x42: dumpresetstats({{ - MipsPseudo::dumpresetstats(xc->xcBase()); - }}, IsNonSpeculative); - 0x43: m5checkpoint({{ - MipsPseudo::m5checkpoint(xc->xcBase()); - }}, IsNonSpeculative); - 0x50: m5readfile({{ - MipsPseudo::readfile(xc->xcBase()); - }}, IsNonSpeculative); - 0x51: m5break({{ - MipsPseudo::debugbreak(xc->xcBase()); - }}, IsNonSpeculative); - 0x52: m5switchcpu({{ - MipsPseudo::switchcpu(xc->xcBase()); - }}, IsNonSpeculative); - 0x53: m5addsymbol({{ - MipsPseudo::addsymbol(xc->xcBase()); - }}, IsNonSpeculative); - - } - } -#endif } From 4be1f418bc4bd6d3b63b913e3ac57519acf4584a Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Wed, 25 Jan 2006 17:36:38 -0500 Subject: [PATCH 005/180] more changes to the decoder ... Now does special 3 table arch/mips/isa_desc/bitfields.h: Change from table names to actual bitfield name ... --HG-- extra : convert_revision : ead69065eb9c3e9c4ea4f67587a6fb07091898ed --- arch/mips/isa_desc/bitfields.h | 23 +++++++++++++----- arch/mips/isa_desc/decoder.h | 43 ++++++++++++++++++++-------------- 2 files changed, 43 insertions(+), 23 deletions(-) diff --git a/arch/mips/isa_desc/bitfields.h b/arch/mips/isa_desc/bitfields.h index 7fce190ce..793889150 100644 --- a/arch/mips/isa_desc/bitfields.h +++ b/arch/mips/isa_desc/bitfields.h @@ -7,14 +7,25 @@ def bitfield OPCODE_HI <31:29>; def bitfield OPCODE_LO <28:26>; -def bitfield SPECIAL_HI < 5: 3>; -def bitfield SPECIAL_HI < 2: 0>; +def bitfield FUNCTION_HI < 5: 3>; +def bitfield FUNCTION_LO < 2: 0>; -def bitfield REGIMM_HI <20:19>; -def bitfield REGIMM_LO <18:16>; +def bitfield RT <20:16>; +def bitfield RT_HI <20:19>; +def bitfield RT_LO <18:16>; -def bitfield RS <25:21>; -def bitfield RT <20:16>; +def bitfield RS <25:21>; +def bitfield RS_HI <25:24>; +def bitfield RS_LO <23:21>; + +def bitfield MOVCI <>; +def bitfield SRL <>; +def bitfield SRLV <>; +def bitfield SA <>; + +def bitfield BSHFL <>; +def bitfield BSHFL_HI <>; +def bitfield BSHFL_LO <>; // Integer operate format(s>; def bitfield INTIMM <15: 0>; // integer immediate (literal) diff --git a/arch/mips/isa_desc/decoder.h b/arch/mips/isa_desc/decoder.h index 235ff1ef6..1afd0f9d9 100644 --- a/arch/mips/isa_desc/decoder.h +++ b/arch/mips/isa_desc/decoder.h @@ -14,8 +14,8 @@ decode OPCODE_HI default FailUnimpl::unknown() { // Derived From ... Table A-2 MIPS32 ISA Manual 0x0: decode OPCODE_LO default FailUnimpl::reserved(){ - 0x0: decode SPECIAL_HI { - 0x0: decode SPECIAL_LO { + 0x0: decode FUNCTION_HI { + 0x0: decode FUNCTION_LO { 0x1: decode MOVCI { format Move { 0: movc({{ }}); @@ -46,7 +46,7 @@ decode OPCODE_HI default FailUnimpl::unknown() { } } - 0x1: decode SPECIAL_LO { + 0x1: decode FUNCTION_LO { //Table A-3 Note: "Specific encodings of the hint field are used //to distinguish JR from JR.HB and JALR from JALR.HB" @@ -65,7 +65,7 @@ decode OPCODE_HI default FailUnimpl::unknown() { 0x7: Synchronize::synch({{ }}); } - 0x2: decode SPECIAL_LO { + 0x2: decode FUNCTION_LO { format MultDiv { 0x0: mfhi({{ }}); 0x1: mthi({{ }}); @@ -74,7 +74,7 @@ decode OPCODE_HI default FailUnimpl::unknown() { } }; - 0x3: decode SPECIAL_LO { + 0x3: decode FUNCTION_LO { format MultDiv { 0x0: mult({{ }}); 0x1: multu({{ }}); @@ -83,7 +83,7 @@ decode OPCODE_HI default FailUnimpl::unknown() { } }; - 0x4: decode SPECIAL_LO { + 0x4: decode FUNCTION_LO { format Arithmetic { 0x0: add({{ }}); 0x1: addu({{ }}); @@ -99,14 +99,14 @@ decode OPCODE_HI default FailUnimpl::unknown() { } } - 0x5: decode SPECIAL_LO { + 0x5: decode FUNCTION_LO { format SetInstructions{ 0x2: slt({{ }}); 0x3: sltu({{ }}); } }; - 0x6: decode SPECIAL_LO { + 0x6: decode FUNCTION_LO { format Trap { 0x0: tge({{ }}); 0x1: tgeu({{ }}); @@ -218,7 +218,7 @@ decode OPCODE_HI default FailUnimpl::unknown() { 0x6: reserved_inst_exception({{ }}) }; - 4: decode SPECIAL2 { + 0x4: decode FUNCTION_HI { 0x0:; 0x1:; 0x2:; @@ -228,14 +228,23 @@ decode OPCODE_HI default FailUnimpl::unknown() { 0x6:; } - 7: decode SPECIAL3 { - 0x0:; - 0x1:; - 0x2:; - 0x3:; - 0x4:; - 0x5:; - 0x6:; + 0x7: decode FUNCTION_HI { + //Table A-6 MIPS32 SPECIAL31 Encoding of Function Field for Release 2 of the Architecture + 0x0: decode FUNCTION_LO { + 0x1: ext({{ }}); + 0x4: ins({{ }}); + } + + 0x4: decode SA { + //Table A-10 MIPS32 BSHFL Encoding of sa Field + 0x02: wsbh({{ }}); + 0x10: seb({{ }}); + 0x18: seh({{ }}); + } + + 0x6: decode FUNCTION_LO { + 0x7: rdhwr({{ }}); + } } }; From efc4620de1c3e70159c67c6bc858f1b785baba97 Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Thu, 26 Jan 2006 01:34:43 -0500 Subject: [PATCH 006/180] decoder skeleton code: this should be able to read any MIPS instruction and decode it but NOT produce any C++ class object. All of the code literals are empty as of now. As much as possible instructions were organized into relevant "formats" and also references to the tables I used from the MIPS manual were noted via appropriate comments. --HG-- extra : convert_revision : 9b44fb40e900061a4cdb290b6a5aaceb9750ae13 --- arch/mips/isa_desc/decoder.h | 352 ++++++++++++++++++++++++++++++----- 1 file changed, 305 insertions(+), 47 deletions(-) diff --git a/arch/mips/isa_desc/decoder.h b/arch/mips/isa_desc/decoder.h index 1afd0f9d9..7e911cb45 100644 --- a/arch/mips/isa_desc/decoder.h +++ b/arch/mips/isa_desc/decoder.h @@ -185,20 +185,291 @@ decode OPCODE_HI default FailUnimpl::unknown() { 0x2: decode OPCODE_LO default FailUnimpl::reserved(){ - 0x0: decode RS { - //Table A-11 MIPS32 COP0 Encoding of rs Field + //Table A-11 MIPS32 COP0 Encoding of rs Field + 0x0: decode RS_MSB { + 0x0: decode RS { + 0x0: mfc0({{ }}); + 0xC: mtc0({{ }}); + 0xA: rdpgpr({{ }}); + + 0xB: decode SC { + 0x0: di({{ }}); + 0x1: ei({{ }}); + } + + 0xE: wrpgpr({{ }}); + } + + //Table A-12 MIPS32 COP0 Encoding of Function Field When rs=CO + 0x1: decode FUNCTION { + 0x01: tlbr({{ }}); + 0x02: tlbwi({{ }}); + 0x06: tlbwr({{ }}); + 0x08: tlbp({{ }}); + 0x18: eret({{ }}); + 0x1F: deret({{ }}); + 0x20: wait({{ }}); + } } - 0x1: decode RS { - //Table A-13 MIPS32 COP1 Encoding of rs Field + //Table A-13 MIPS32 COP1 Encoding of rs Field + 0x1: decode RS_MSB { + + 0x0: decode RS_HI { + 0x0: decode RS_LO { + 0x0: mfc1({{ }}); + 0x2: cfc1({{ }}); + 0x3: mfhc1({{ }}); + 0x4: mtc1({{ }}); + 0x6: ctc1({{ }}); + 0x7: mftc1({{ }}); + } + + 0x1: decode ND { + 0x0: decode TF { + 0x0: bc1f({{ }}); + 0x1: bc1t({{ }}); + } + + 0x1: decode TF { + 0x0: bc1fl({{ }}); + 0x1: bc1tl({{ }}); + } + } + } + + 0x1: decode RS_HI { + 0x2: decode RS_LO { + + //Table A-14 MIPS32 COP1 Encoding of Function Field When rs=S + //(( single-word )) + 0x0: decode RS_HI { + 0x0: decode RS_LO { + 0x0: add_fmt({{ }}); + 0x1: sub_fmt({{ }}); + 0x2: mul_fmt({{ }}); + 0x3: div_fmt({{ }}); + 0x4: sqrt_fmt({{ }}); + 0x5: abs_fmt({{ }}); + 0x6: mov_fmt({{ }}); + 0x7: neg_fmt({{ }}); + } + + 0x1: decode RS_LO { + //only legal for 64 bit + format mode64 { + 0x0: round_l({{ }}); + 0x1: trunc_l({{ }}); + 0x2: ceil_l({{ }}); + 0x3: floor_l({{ }}); + } + + 0x4: round_w({{ }}); + 0x5: trunc_w({{ }}); + 0x6: ceil_w({{ }}); + 0x7: floor_w({{ }}); + } + + 0x2: decode RS_LO { + 0x1: decode MOVCF { + 0x0: movf_fmt({{ }}); + 0x1: movt_fmt({{ }}); + } + + 0x2: movz({{ }}); + 0x3: movn({{ }}); + + format mode64 { + 0x2: recip({{ }}); + 0x3: rsqrt{{ }}); + } + } + + 0x4: decode RS_LO { + 0x1: cvt_d({{ }}); + 0x4: cvt_w({{ }}); + + //only legal for 64 bit + format mode64 { + 0x5: cvt_l({{ }}); + 0x6: cvt_ps({{ }}); + } + } + } + + //Table A-15 MIPS32 COP1 Encoding of Function Field When rs=D + 0x1: decode RS_HI { + 0x0: decode RS_LO { + 0x0: add_fmt({{ }}); + 0x1: sub_fmt({{ }}); + 0x2: mul_fmt({{ }}); + 0x3: div_fmt({{ }}); + 0x4: sqrt_fmt({{ }}); + 0x5: abs_fmt({{ }}); + 0x6: mov_fmt({{ }}); + 0x7: neg_fmt({{ }}); + } + + 0x1: decode RS_LO { + //only legal for 64 bit + format mode64 { + 0x0: round_l({{ }}); + 0x1: trunc_l({{ }}); + 0x2: ceil_l({{ }}); + 0x3: floor_l({{ }}); + } + + 0x4: round_w({{ }}); + 0x5: trunc_w({{ }}); + 0x6: ceil_w({{ }}); + 0x7: floor_w({{ }}); + } + + 0x2: decode RS_LO { + 0x1: decode MOVCF { + 0x0: movf_fmt({{ }}); + 0x1: movt_fmt({{ }}); + } + + 0x2: movz({{ }}); + 0x3: movn({{ }}); + + format mode64 { + 0x5: recip({{ }}); + 0x6: rsqrt{{ }}); + } + } + + 0x4: decode RS_LO { + 0x0: cvt_s({{ }}); + 0x4: cvt_w({{ }}); + + //only legal for 64 bit + format mode64 { + 0x5: cvt_l({{ }}); + } + } + } + + //Table A-16 MIPS32 COP1 Encoding of Function Field When rs=W + 0x4: decode FUNCTION { + 0x10: cvt_s({{ }}); + 0x10: cvt_d({{ }}); + } + + //Table A-16 MIPS32 COP1 Encoding of Function Field When rs=L1 + //Note: "1. Format type L is legal only if 64-bit floating point operations + //are enabled." + 0x5: decode FUNCTION_HI { + 0x10: cvt_s({{ }}); + 0x11: cvt_d({{ }}); + } + + //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 { + 0x0: add_fmt({{ }}); + 0x1: sub_fmt({{ }}); + 0x2: mul_fmt({{ }}); + 0x5: abs_fmt({{ }}); + 0x6: mov_fmt({{ }}); + 0x7: neg_fmt({{ }}); + } + + 0x2: decode RS_LO { + 0x1: decode MOVCF { + 0x0: movf_fmt({{ }}); + 0x1: movt_fmt({{ }}); + } + + 0x2: movz({{ }}); + 0x3: movn({{ }}); + } + + 0x4: decode RS_LO { + 0x0: cvt_s_pu({{ }}); + } + + 0x5: decode RS_LO { + 0x0: cvt_s_pl({{ }}); + 0x4: pll_s_pl({{ }}); + 0x5: plu_s_pl({{ }}); + 0x6: pul_s_pl({{ }}); + 0x7: puu_s_pl({{ }}); + } + } } - 0x2: decode RS { - //Table A-19 MIPS32 COP2 Encoding of rs Field + //Table A-19 MIPS32 COP2 Encoding of rs Field + 0x2: decode RS_MSB { + 0x0: decode RS_HI { + 0x0: decode RS_LO { + 0x0: mfc2({{ }}); + 0x2: cfc2({{ }}); + 0x3: mfhc2({{ }}); + 0x4: mtc2({{ }}); + 0x6: ctc2({{ }}); + 0x7: mftc2({{ }}); + } + + 0x1: decode ND { + 0x0: decode TF { + 0x0: bc2f({{ }}); + 0x1: bc2t({{ }}); + } + + 0x1: decode TF { + 0x0: bc2fl({{ }}); + 0x1: bc2tl({{ }}); + } + } + } } + //Table A-20 MIPS64 COP1X Encoding of Function Field 1 + //Note: "COP1X instructions are legal only if 64-bit floating point + //operations are enabled." 0x3: decode FUNCTION_HI { - //Table A-20 MIPS64 COP1X Encoding of Function Field 1 + 0x0: decode FUNCTION_LO { + 0x0: lwxc1({{ }}); + 0x1: ldxc1({{ }}); + 0x5: luxc1({{ }}); + } + + 0x1: decode FUNCTION_LO { + 0x0: swxc1({{ }}); + 0x1: sdxc1({{ }}); + 0x5: suxc1({{ }}); + 0x7: prefx({{ }}); + } + + 0x3: alnv_ps({{ }}); + + 0x4: decode FUNCTION_LO { + 0x0: madd_s({{ }}); + 0x1: madd_d({{ }}); + 0x6: madd_ps({{ }}); + } + + 0x5: decode FUNCTION_LO { + 0x0: msub_s({{ }}); + 0x1: msub_d({{ }}); + 0x6: msub_ps({{ }}); + } + + 0x6: decode FUNCTION_LO { + 0x0: nmadd_s({{ }}); + 0x1: nmadd_d({{ }}); + 0x6: nmadd_ps({{ }}); + } + + 0x7: decode FUNCTION_LO { + 0x0: nmsub_s({{ }}); + 0x1: nmsub_d({{ }}); + 0x6: nmsub_ps({{ }}); + } } //MIPS obsolete instructions @@ -209,34 +480,38 @@ decode OPCODE_HI default FailUnimpl::unknown() { }; 0x3: decode OPCODE_LO default FailUnimpl::reserved(){ - format FailUnimpl{ - 0x0: reserved_inst_exception({{ }}) - 0x1: reserved_inst_exception({{ }}) - 0x2: reserved_inst_exception({{ }}) - 0x3: reserved_inst_exception({{ }}) - 0x5: reserved_inst_exception({{ }}) - 0x6: reserved_inst_exception({{ }}) - }; + //Table A-5 MIPS32 SPECIAL2 Encoding of Function Field 0x4: decode FUNCTION_HI { - 0x0:; - 0x1:; - 0x2:; - 0x3:; - 0x4:; - 0x5:; - 0x6:; + + 0x0: decode FUNCTION_LO { + 0x0: madd({{ }}); + 0x1: maddu({{ }}); + 0x2: mult({{ }}); + 0x4: msub({{ }}); + 0x5: msubu({{ }}); + } + + 0x4: decode FUNCTION_LO { + 0x0: clz({{ }}); + 0x1: clo({{ }}); + } + + 0x7: decode FUNCTION_LO { + 0x7: sdbbp({{ }}); + } } + //Table A-6 MIPS32 SPECIAL3 Encoding of Function Field for Release 2 of the Architecture 0x7: decode FUNCTION_HI { - //Table A-6 MIPS32 SPECIAL31 Encoding of Function Field for Release 2 of the Architecture + 0x0: decode FUNCTION_LO { 0x1: ext({{ }}); 0x4: ins({{ }}); } + //Table A-10 MIPS32 BSHFL Encoding of sa Field 0x4: decode SA { - //Table A-10 MIPS32 BSHFL Encoding of sa Field 0x02: wsbh({{ }}); 0x10: seb({{ }}); 0x18: seh({{ }}); @@ -259,7 +534,7 @@ decode OPCODE_HI default FailUnimpl::unknown() { 0x6: lhu({{ }}); }; - 0x7: FailUnimpl::reserved_inst_exception({{ }}); + 0x7: FailUnimpl::reserved({{ }}); }; 0x5: decode OPCODE_LO default FailUnimpl::reserved(){ @@ -272,9 +547,9 @@ decode OPCODE_HI default FailUnimpl::unknown() { }; format FailUnimpl{ - 0x4: reserved_inst_exception({{ }}); - 0x5: reserved_inst_exception({{ }}); - 0x2: cache({{ }}); + 0x4: reserved({{ }}); + 0x5: reserved({{ }}); + 0x7: cache({{ }}); }; }; @@ -285,15 +560,6 @@ decode OPCODE_HI default FailUnimpl::unknown() { 0x1: lwc1({{ }}); 0x5: ldc1({{ }}); }; - - format FailUnimpl{ - 0x2: lwc2({{ }}); - 0x3: pref({{ }}); - 0x4: reserved_inst_exception({{ }}); - 0x6: ldc2({{ }}); - 0x7: reserved_inst_exception({{ }}); - }; - }; 0x7: decode OPCODE_LO default FailUnimpl::reserved(){ @@ -303,15 +569,7 @@ decode OPCODE_HI default FailUnimpl::unknown() { 0x5: sdc1({{ }}); }; - format FailUnimpl{ - 0x2: swc2({{ }}); - 0x3: reserved_inst_exception({{ }}); - 0x4: reserved_inst_exception({{ }}); - 0x6: sdc2({{ }}); - 0x7: reserved_inst_exception({{ }}); - }; - - }; - + } } + From 2bc106a8e7672cbb625dd8790ab8d8dddaf5e852 Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Thu, 26 Jan 2006 16:19:44 -0500 Subject: [PATCH 007/180] "sparc" -> "mips" arch/mips/isa_desc/formats.h: arch/mips/isa_desc/formats/basic.format: arch/mips/isa_desc/formats/branch.format: arch/mips/isa_desc/formats/integerop.format: arch/mips/isa_desc/formats/mem.format: arch/mips/isa_desc/formats/noop.format: arch/mips/isa_desc/formats/trap.format: arch/mips/isa_traits.cc: arch/mips/isa_traits.hh: changing "sparc" strings to "mips" everywhere --HG-- extra : convert_revision : eaecf9eeac26e3ef0726deef2fb5d7e9ad172984 --- arch/mips/isa_desc/formats.h | 15 +++++++++------ arch/mips/isa_desc/formats/basic.format | 2 +- arch/mips/isa_desc/formats/branch.format | 8 ++++---- arch/mips/isa_desc/formats/integerop.format | 10 +++++----- arch/mips/isa_desc/formats/mem.format | 10 +++++----- arch/mips/isa_desc/formats/noop.format | 6 +++--- arch/mips/isa_desc/formats/trap.format | 6 +++--- arch/mips/isa_traits.cc | 9 +++++---- arch/mips/isa_traits.hh | 18 +++++++++--------- 9 files changed, 44 insertions(+), 40 deletions(-) diff --git a/arch/mips/isa_desc/formats.h b/arch/mips/isa_desc/formats.h index 733a093f5..404314c7a 100644 --- a/arch/mips/isa_desc/formats.h +++ b/arch/mips/isa_desc/formats.h @@ -1,19 +1,22 @@ //Include the basic format //Templates from this format are used later -##include "m5/arch/sparc/isa_desc/formats/basic.format" +##include "m5/arch/mips/isa_desc/formats/basic.format" //Include the integerOp and integerOpCc format -##include "m5/arch/sparc/isa_desc/formats/integerop.format" +##include "m5/arch/mips/isa_desc/formats/integerop.format" + +//Include the floatOp format +##include "m5/arch/mips/isa_desc/formats/floatop.format" //Include the mem format -##include "m5/arch/sparc/isa_desc/formats/mem.format" +##include "m5/arch/mips/isa_desc/formats/mem.format" //Include the trap format -##include "m5/arch/sparc/isa_desc/formats/trap.format" +##include "m5/arch/mips/isa_desc/formats/trap.format" //Include the branch format -##include "m5/arch/sparc/isa_desc/formats/branch.format" +##include "m5/arch/mips/isa_desc/formats/branch.format" //Include the noop format -##include "m5/arch/sparc/isa_desc/formats/noop.format" +##include "m5/arch/mips/isa_desc/formats/noop.format" diff --git a/arch/mips/isa_desc/formats/basic.format b/arch/mips/isa_desc/formats/basic.format index 1994df41c..8fba9845a 100644 --- a/arch/mips/isa_desc/formats/basic.format +++ b/arch/mips/isa_desc/formats/basic.format @@ -57,7 +57,7 @@ def template BasicDecodeWithMnemonic {{ // The most basic instruction format... used only for a few misc. insts def format BasicOperate(code, *flags) {{ - iop = InstObjParams(name, Name, 'SparcStaticInst', CodeBlock(code), flags) + iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags) header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) decode_block = BasicDecode.subst(iop) diff --git a/arch/mips/isa_desc/formats/branch.format b/arch/mips/isa_desc/formats/branch.format index c4c0a90af..5327f30e8 100644 --- a/arch/mips/isa_desc/formats/branch.format +++ b/arch/mips/isa_desc/formats/branch.format @@ -7,12 +7,12 @@ output header {{ /** * Base class for integer operations. */ - class Branch : public SparcStaticInst + class Branch : public MipsStaticInst { protected: /// Constructor - Branch(const char *mnem, MachInst _machInst, OpClass __opClass) : SparcStaticInst(mnem, _machInst, __opClass) + Branch(const char *mnem, MachInst _machInst, OpClass __opClass) : MipsStaticInst(mnem, _machInst, __opClass) { } @@ -41,7 +41,7 @@ def template BranchExecute {{ } //If we have an exception for some reason, //deal with it - catch(SparcException except) + catch(MipsException except) { //Deal with exception return No_Fault; @@ -58,7 +58,7 @@ def template BranchExecute {{ def format Branch(code, *opt_flags) {{ orig_code = code cblk = CodeBlock(code) - iop = InstObjParams(name, Name, 'SparcStaticInst', cblk, opt_flags) + iop = InstObjParams(name, Name, 'MipsStaticInst', cblk, opt_flags) header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) decode_block = BasicDecodeWithMnemonic.subst(iop) diff --git a/arch/mips/isa_desc/formats/integerop.format b/arch/mips/isa_desc/formats/integerop.format index 275a346d3..6fa7feed3 100644 --- a/arch/mips/isa_desc/formats/integerop.format +++ b/arch/mips/isa_desc/formats/integerop.format @@ -7,12 +7,12 @@ output header {{ /** * Base class for integer operations. */ - class IntegerOp : public SparcStaticInst + class IntegerOp : public MipsStaticInst { protected: /// Constructor - IntegerOp(const char *mnem, MachInst _machInst, OpClass __opClass) : SparcStaticInst(mnem, _machInst, __opClass) + IntegerOp(const char *mnem, MachInst _machInst, OpClass __opClass) : MipsStaticInst(mnem, _machInst, __opClass) { } @@ -46,7 +46,7 @@ def template IntegerExecute {{ } //If we have an exception for some reason, //deal with it - catch(SparcException except) + catch(MipsException except) { //Deal with exception return No_Fault; @@ -82,7 +82,7 @@ def format IntegerOp(code, *opt_flags) {{ for (marker, value) in (('ivValue', '0'), ('icValue', '0'), ('xvValue', '0'), ('xcValue', '0')): code.replace(marker, value) - iop = InstObjParams(name, Name, 'SparcStaticInst', cblk, opt_flags) + iop = InstObjParams(name, Name, 'MipsStaticInst', cblk, opt_flags) header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) decode_block = BasicDecodeWithMnemonic.subst(iop) @@ -102,7 +102,7 @@ def format IntegerOpCc(code, icValue, ivValue, xcValue, xvValue, *opt_flags) {{ for (marker, value) in (('ivValue', ivValue), ('icValue', icValue), ('xvValue', xvValue), ('xcValue', xcValue)): code.replace(marker, value) - iop = InstObjParams(name, Name, 'SparcStaticInst', cblk, opt_flags) + iop = InstObjParams(name, Name, 'MipsStaticInst', cblk, opt_flags) header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) decode_block = BasicDecodeWithMnemonic.subst(iop) diff --git a/arch/mips/isa_desc/formats/mem.format b/arch/mips/isa_desc/formats/mem.format index abc00b6f2..5ed5237c5 100644 --- a/arch/mips/isa_desc/formats/mem.format +++ b/arch/mips/isa_desc/formats/mem.format @@ -7,12 +7,12 @@ output header {{ /** * Base class for integer operations. */ - class Mem : public SparcStaticInst + class Mem : public MipsStaticInst { protected: /// Constructor - Mem(const char *mnem, MachInst _machInst, OpClass __opClass) : SparcStaticInst(mnem, _machInst, __opClass) + Mem(const char *mnem, MachInst _machInst, OpClass __opClass) : MipsStaticInst(mnem, _machInst, __opClass) { } @@ -41,7 +41,7 @@ def template MemExecute {{ } //If we have an exception for some reason, //deal with it - catch(SparcException except) + catch(MipsException except) { //Deal with exception return No_Fault; @@ -58,7 +58,7 @@ def template MemExecute {{ def format Mem(code, *opt_flags) {{ orig_code = code cblk = CodeBlock(code) - iop = InstObjParams(name, Name, 'SparcStaticInst', cblk, opt_flags) + iop = InstObjParams(name, Name, 'MipsStaticInst', cblk, opt_flags) header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) decode_block = BasicDecodeWithMnemonic.subst(iop) @@ -69,7 +69,7 @@ def format Mem(code, *opt_flags) {{ def format Cas(code, *opt_flags) {{ orig_code = code cblk = CodeBlock(code) - iop = InstObjParams(name, Name, 'SparcStaticInst', cblk, opt_flags) + iop = InstObjParams(name, Name, 'MipsStaticInst', cblk, opt_flags) header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) decode_block = BasicDecodeWithMnemonic.subst(iop) diff --git a/arch/mips/isa_desc/formats/noop.format b/arch/mips/isa_desc/formats/noop.format index bc83e3261..b1ece654d 100644 --- a/arch/mips/isa_desc/formats/noop.format +++ b/arch/mips/isa_desc/formats/noop.format @@ -7,12 +7,12 @@ output header {{ /** * Base class for integer operations. */ - class Noop : public SparcStaticInst + class Noop : public MipsStaticInst { protected: /// Constructor - Noop(const char *mnem, MachInst _machInst, OpClass __opClass) : SparcStaticInst(mnem, _machInst, __opClass) + Noop(const char *mnem, MachInst _machInst, OpClass __opClass) : MipsStaticInst(mnem, _machInst, __opClass) { } @@ -39,7 +39,7 @@ def template NoopExecute {{ def format Noop(code, *opt_flags) {{ orig_code = code cblk = CodeBlock(code) - iop = InstObjParams(name, Name, 'SparcStaticInst', cblk, opt_flags) + iop = InstObjParams(name, Name, 'MipsStaticInst', cblk, opt_flags) header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) decode_block = BasicDecodeWithMnemonic.subst(iop) diff --git a/arch/mips/isa_desc/formats/trap.format b/arch/mips/isa_desc/formats/trap.format index bee77fe69..78f8d87b0 100644 --- a/arch/mips/isa_desc/formats/trap.format +++ b/arch/mips/isa_desc/formats/trap.format @@ -7,12 +7,12 @@ output header {{ /** * Base class for integer operations. */ - class Trap : public SparcStaticInst + class Trap : public MipsStaticInst { protected: /// Constructor - Trap(const char *mnem, MachInst _machInst, OpClass __opClass) : SparcStaticInst(mnem, _machInst, __opClass) + Trap(const char *mnem, MachInst _machInst, OpClass __opClass) : MipsStaticInst(mnem, _machInst, __opClass) { } @@ -45,7 +45,7 @@ def template TrapExecute {{ def format Trap(code, *opt_flags) {{ orig_code = code cblk = CodeBlock(code) - iop = InstObjParams(name, Name, 'SparcStaticInst', cblk, opt_flags) + iop = InstObjParams(name, Name, 'MipsStaticInst', cblk, opt_flags) header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) decode_block = BasicDecodeWithMnemonic.subst(iop) diff --git a/arch/mips/isa_traits.cc b/arch/mips/isa_traits.cc index c7a25f88d..90a85feb6 100644 --- a/arch/mips/isa_traits.cc +++ b/arch/mips/isa_traits.cc @@ -26,15 +26,16 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "arch/sparc/isa_traits.hh" +#include "arch/mips/isa_traits.hh" #include "cpu/static_inst.hh" #include "sim/serialize.hh" // Alpha UNOP (ldq_u r31,0(r0)) -const MachInst SPARCISA::NoopMachInst = 0x2ffe0000; +// @todo: fix to MIPS specific +const MachInst MipsISA::NoopMachInst = 0x2ffe0000; void -SPARCISA::RegFile::serialize(std::ostream &os) +MipsISA::RegFile::serialize(std::ostream &os) { intRegFile.serialize(os); floatRegFile.serialize(os); @@ -45,7 +46,7 @@ SPARCISA::RegFile::serialize(std::ostream &os) void -AlphaISA::RegFile::unserialize(Checkpoint *cp, const std::string §ion) +MipsISA::RegFile::unserialize(Checkpoint *cp, const std::string §ion) { intRegFile.unserialize(cp, section); floatRegFile.unserialize(cp, section); diff --git a/arch/mips/isa_traits.hh b/arch/mips/isa_traits.hh index 9513b99fc..e8401cefb 100644 --- a/arch/mips/isa_traits.hh +++ b/arch/mips/isa_traits.hh @@ -26,18 +26,18 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef __ARCH_SPARC_ISA_TRAITS_HH__ -#define __ARCH_SPARC_ISA_TRAITS_HH__ +#ifndef __ARCH_MIPS_ISA_TRAITS_HH__ +#define __ARCH_MIPS_ISA_TRAITS_HH__ -#include "arch/sparc/faults.hh" +#include "arch/mips/faults.hh" #include "base/misc.hh" #include "sim/host.hh" class FastCPU; -//class FullCPU; -//class Checkpoint; +class FullCPU; +class Checkpoint; -#define TARGET_SPARC +#define TARGET_MIPS template class StaticInst; template class StaticInstPtr; @@ -48,7 +48,7 @@ template class StaticInstPtr; // int ITB_ASN_ASN(uint64_t reg); //} -class SPARCISA +class MipsISA { public: @@ -463,7 +463,7 @@ class SPARCISA }; -typedef SPARCISA TheISA; +typedef MIPSISA TheISA; typedef TheISA::MachInst MachInst; typedef TheISA::Addr Addr; @@ -525,4 +525,4 @@ class SyscallReturn { #include "arch/alpha/ev5.hh" #endif -#endif // __ARCH_SPARC_ISA_TRAITS_HH__ +#endif // __ARCH_MIPS_ISA_TRAITS_HH__ From 0162c52f17b92d7e834d7a5299e36f62f4a00230 Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Thu, 26 Jan 2006 17:07:01 -0500 Subject: [PATCH 008/180] bitfields definition to support current decoder.h --HG-- extra : convert_revision : 75ccc53181b857605d051024d86ef62ec43f3b7f --- arch/mips/isa_desc/bitfields.h | 74 ++++++++++------------------------ 1 file changed, 21 insertions(+), 53 deletions(-) diff --git a/arch/mips/isa_desc/bitfields.h b/arch/mips/isa_desc/bitfields.h index 793889150..f0d6fc8d7 100644 --- a/arch/mips/isa_desc/bitfields.h +++ b/arch/mips/isa_desc/bitfields.h @@ -3,7 +3,6 @@ // Bitfield definitions. // -// Universal (format-independent) fields def bitfield OPCODE_HI <31:29>; def bitfield OPCODE_LO <28:26>; @@ -18,66 +17,35 @@ def bitfield RS <25:21>; def bitfield RS_HI <25:24>; def bitfield RS_LO <23:21>; -def bitfield MOVCI <>; -def bitfield SRL <>; -def bitfield SRLV <>; -def bitfield SA <>; - -def bitfield BSHFL <>; -def bitfield BSHFL_HI <>; -def bitfield BSHFL_LO <>; - -// Integer operate format(s>; -def bitfield INTIMM <15: 0>; // integer immediate (literal) -def bitfield IMM <12:12>; // immediate flag -def bitfield INTFUNC <11: 5>; // function code -def bitfield RD <15:11>; // dest reg - -// Memory format -def signed bitfield MEMDISP <15: 0>; // displacement -def bitfield MEMFUNC <15: 0>; // function code (same field, unsigned) - -// Memory-format jumps -def bitfield JMPFUNC <15:14>; // function code (disp<15:14>) -def bitfield JMPHINT <13: 0>; // tgt Icache idx hint (disp<13:0>) - -// Branch format -def signed bitfield BRDISP <20: 0>; // displacement +def bitfield RD <15:11>; // Floating-point operate format def bitfield FMT <25:21>; -def bitfield FT <20:16>; -def bitfield FS <15:11>; -def bitfield FD <10: 6>; +def bitfield FT <20:16>; +def bitfield FS <15:11>; +def bitfield FD <10:6>; -def bitfield FP_FULLFUNC <15: 5>; // complete function code - def bitfield FP_TRAPMODE <15:13>; // trapping mode - def bitfield FP_ROUNDMODE <12:11>; // rounding mode - def bitfield FP_TYPEFUNC <10: 5>; // type+func: handiest for decoding - def bitfield FP_SRCTYPE <10: 9>; // source reg type - def bitfield FP_SHORTFUNC < 8: 5>; // short function code - def bitfield FP_SHORTFUNC_TOP2 <8:7>; // top 2 bits of short func code +def bitfield MOVCI <16:16>; +def bitfield MOVCF <16:16>; +def bitfield SRL <21:21>; +def bitfield SRLV < 6: 6>; +def bitfield SA <10: 6>; -// PALcode format -def bitfield PALFUNC <25: 0>; // function code +// Interrupts +def bitfield SC < 5: 5>; -// EV5 PAL instructions: -// HW_LD/HW_ST -def bitfield HW_LDST_PHYS <15>; // address is physical -def bitfield HW_LDST_ALT <14>; // use ALT_MODE IPR -def bitfield HW_LDST_WRTCK <13>; // HW_LD only: fault if no write acc -def bitfield HW_LDST_QUAD <12>; // size: 0=32b, 1=64b -def bitfield HW_LDST_VPTE <11>; // HW_LD only: is PTE fetch -def bitfield HW_LDST_LOCK <10>; // HW_LD only: is load locked -def bitfield HW_LDST_COND <10>; // HW_ST only: is store conditional -def signed bitfield HW_LDST_DISP <9:0>; // signed displacement +// Integer operate format(s>; +def bitfield INTIMM <15: 0>; // integer immediate (literal) -// HW_REI -def bitfield HW_REI_TYP <15:14>; // type: stalling vs. non-stallingk -def bitfield HW_REI_MBZ <13: 0>; // must be zero +// Branch format +def bitfield OFFSET <15: 0>; // displacement -// HW_MTPR/MW_MFPR -def bitfield HW_IPR_IDX <15:0>; // IPR index +// Memory-format jumps +def bitfield JMPTARG <25: 0>; +def bitfield JMPHINT <10: 6>; + +def bitfield SYSCALLCODE <25: 6>; +def bitfield TRAPCODE <15:13>; // M5 instructions def bitfield M5FUNC <7:0>; From 8b783f8ad2e0d00ddbdc93b81af7bb381dbf8d3d Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Sun, 29 Jan 2006 17:25:54 -0500 Subject: [PATCH 009/180] sparc files that were removed from revision 1.888 --HG-- extra : convert_revision : f285a442b64eee183f7d0f6c203f0b0aa7ea8586 --- arch/sparc/isa_desc/base.h | 82 +++ arch/sparc/isa_desc/bitfields.h | 50 ++ arch/sparc/isa_desc/decoder.h | 638 +++++++++++++++++++ arch/sparc/isa_desc/formats.h | 19 + arch/sparc/isa_desc/formats/basic.format | 65 ++ arch/sparc/isa_desc/formats/branch.format | 66 ++ arch/sparc/isa_desc/formats/integerop.format | 110 ++++ arch/sparc/isa_desc/formats/mem.format | 78 +++ arch/sparc/isa_desc/formats/noop.format | 47 ++ arch/sparc/isa_desc/formats/trap.format | 53 ++ arch/sparc/isa_desc/includes.h | 40 ++ arch/sparc/isa_desc/isa_desc | 61 ++ arch/sparc/isa_desc/operands.h | 33 + arch/sparc/isa_traits.hh | 528 +++++++++++++++ 14 files changed, 1870 insertions(+) create mode 100644 arch/sparc/isa_desc/base.h create mode 100644 arch/sparc/isa_desc/bitfields.h create mode 100644 arch/sparc/isa_desc/decoder.h create mode 100644 arch/sparc/isa_desc/formats.h create mode 100644 arch/sparc/isa_desc/formats/basic.format create mode 100644 arch/sparc/isa_desc/formats/branch.format create mode 100644 arch/sparc/isa_desc/formats/integerop.format create mode 100644 arch/sparc/isa_desc/formats/mem.format create mode 100644 arch/sparc/isa_desc/formats/noop.format create mode 100644 arch/sparc/isa_desc/formats/trap.format create mode 100644 arch/sparc/isa_desc/includes.h create mode 100644 arch/sparc/isa_desc/isa_desc create mode 100644 arch/sparc/isa_desc/operands.h create mode 100644 arch/sparc/isa_traits.hh diff --git a/arch/sparc/isa_desc/base.h b/arch/sparc/isa_desc/base.h new file mode 100644 index 000000000..b504f1906 --- /dev/null +++ b/arch/sparc/isa_desc/base.h @@ -0,0 +1,82 @@ +//////////////////////////////////////////////////////////////////// +// +// Base class for sparc instructions, and some support functions +// + +output header {{ + /** + * Base class for all SPARC static instructions. + */ + class SparcStaticInst : public StaticInst + { + protected: + + // Constructor. + SparcStaticInst(const char *mnem, MachInst _machInst, OpClass __opClass) + : StaticInst(mnem, _machInst, __opClass) + { + } + + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; + }; + + bool passesCondition(struct {uint8_t c:1; uint8_t v:1; uint8_t z:1; uint8_t n:1} codes, uint8_t condition); +}}; + +output decoder {{ + + std::string SparcStaticInst::generateDisassembly(Addr pc, const SymbolTable *symtab) const + { + std::stringstream ss; + + ccprintf(ss, "%-10s ", mnemonic); + + // just print the first two source regs... if there's + // a third one, it's a read-modify-write dest (Rc), + // e.g. for CMOVxx + if(_numSrcRegs > 0) + { + printReg(ss, _srcRegIdx[0]); + } + if(_numSrcRegs > 1) + { + ss << ","; + printReg(ss, _srcRegIdx[1]); + } + + // just print the first dest... if there's a second one, + // it's generally implicit + if(_numDestRegs > 0) + { + if(_numSrcRegs > 0) + ss << ","; + printReg(ss, _destRegIdx[0]); + } + + return ss.str(); + } + + bool passesCondition(struct {uint8_t c:1; uint8_t v:1; uint8_t z:1; uint8_t n:1} codes, uint8_t condition) + { + switch(condition) + { + case 0b1000: return true; + case 0b0000: return false; + case 0b1001: return !codes.z; + case 0b0001: return codes.z; + case 0b1010: return !(codes.z | (codes.n ^ codes.v)); + case 0b0010: return codes.z | (codes.n ^ codes.v); + case 0b1011: return !(codes.n ^ codes.v); + case 0b0011: return (codes.n ^ codes.v); + case 0b1100: return !(codes.c | codes.z); + case 0b0100: return (codes.c | codes.z); + case 0b1101: return !codes.c; + case 0b0101: return codes.c; + case 0b1110: return !codes.n; + case 0b0110: return codes.n; + case 0b1111: return !codes.v; + case 0b0111: return codes.v; + } + } +}}; + diff --git a/arch/sparc/isa_desc/bitfields.h b/arch/sparc/isa_desc/bitfields.h new file mode 100644 index 000000000..b0ac57575 --- /dev/null +++ b/arch/sparc/isa_desc/bitfields.h @@ -0,0 +1,50 @@ +//////////////////////////////////////////////////////////////////// +// +// Bitfield definitions. +// + +// Bitfields are shared liberally between instruction formats, so they are +// simply defined alphabetically + +def bitfield A <29>; +def bitfield CC02 <20>; +def bitfield CC03 <25>; +def bitfield CC04 <11>; +def bitfield CC12 <21>; +def bitfield CC13 <26>; +def bitfield CC14 <12>; +def bitfield CC2 <18>; +def bitfield CMASK <6:4>; +def bitfield COND2 <28:25>; +def bitfield COND4 <17:14>; +def bitfield D16HI <21:20>; +def bitfield D16LO <13:0>; +def bitfield DISP19 <18:0>; +def bitfield DISP22 <21:0>; +def bitfield DISP30 <29:0>; +def bitfield FCN <29:26>; +def bitfield I <13>; +def bitfield IMM_ASI <12:5>; +def bitfield IMM22 <21:0>; +def bitfield MMASK <3:0>; +def bitfield OP <31:30>; +def bitfield OP2 <24:22>; +def bitfield OP3 <24:19>; +def bitfield OPF <13:5>; +def bitfield OPF_CC <13:11>; +def bitfield OPF_LOW5 <9:5>; +def bitfield OPF_LOW6 <10:5>; +def bitfield P <19>; +def bitfield RCOND2 <27:25>; +def bitfield RCOND3 <12:10>; +def bitfield RCOND4 <12:10>; +def bitfield RD <29:25>; +def bitfield RS1 <18:14>; +def bitfield RS2 <4:0>; +def bitfield SHCNT32 <4:0>; +def bitfield SHCNT64 <5:0>; +def bitfield SIMM10 <9:0>; +def bitfield SIMM11 <10:0>; +def bitfield SIMM13 <12:0>; +def bitfield SW_TRAP <6:0>; +def bitfield X <12>; diff --git a/arch/sparc/isa_desc/decoder.h b/arch/sparc/isa_desc/decoder.h new file mode 100644 index 000000000..06834ecc3 --- /dev/null +++ b/arch/sparc/isa_desc/decoder.h @@ -0,0 +1,638 @@ +//////////////////////////////////////////////////////////////////// +// +// The actual decoder specification +// + +decode OP default Trap::unknown({{illegal_instruction}}) { + + 0x0: decode OP2 { + 0x0: Trap::illtrap({{illegal_instruction}}); //ILLTRAP + 0x1: Branch::bpcc({{ + switch((CC12 << 1) | CC02) + { + case 1: case 3: + throw illegal_instruction; + case 0: + if(passesCondition(xc->regs.MiscRegs.ccrFields.icc, COND2)) + ;//branchHere + break; + case 2: + if(passesCondition(xc->regs.MiscRegs.ccrFields.xcc, COND2)) + ;//branchHere + break; + } + }});//BPcc + 0x2: Branch::bicc({{ + if(passesCondition(xc->regs.MiscRegs.ccrFields.icc, COND2)) + ;//branchHere + }});//Bicc + 0x3: Branch::bpr({{ + switch(RCOND) + { + case 0: case 4: + throw illegal_instruction; + case 1: + if(Rs1 == 0) ;//branchHere + break; + case 2: + if(Rs1 <= 0) ;//branchHere + break; + case 3: + if(Rs1 < 0) ;//branchHere + break; + case 5: + if(Rs1 != 0) ;//branchHere + break; + case 6: + if(Rs1 > 0) ;//branchHere + break; + case 7: + if(Rs1 >= 0) ;//branchHere + break; + } + }}); //BPr + 0x4: IntegerOp::sethi({{Rd = (IMM22 << 10) & 0xFFFFFC00;}}); //SETHI (or NOP if rd == 0 and imm == 0) + 0x5: Trap::fbpfcc({{throw fp_disabled;}}); //FBPfcc + 0x6: Trap::fbfcc({{throw fp_disabled;}}); //FBfcc + } + 0x1: Branch::call({{ + //branch here + Rd = xc->pc; + }}); + 0x2: decode OP3 { + format IntegerOp { + 0x00: add({{ + INT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); + Rd = Rs1.sdw + val2; + }});//ADD + 0x01: and({{ + UINT64 val2 = (I ? SIMM13.sdw : Rs2.udw); + Rd = Rs1.udw & val2; + }});//AND + 0x02: or({{ + UINT64 val2 = (I ? SIMM13.sdw : Rs2.udw); + Rd = Rs1.udw | val2; + }});//OR + 0x03: xor({{ + UINT64 val2 = (I ? SIMM13.sdw : Rs2.udw); + Rd = Rs1.udw ^ val2; + }});//XOR + 0x04: sub({{ + INT64 val2 = ~((UINT64)(I ? SIMM13.sdw : Rs2.udw))+1; + Rd = Rs1.sdw + val2; + }});//SUB + 0x05: andn({{ + UINT64 val2 = (I ? SIMM13.sdw : Rs2.udw); + Rd = Rs1.udw & ~val2; + }});//ANDN + 0x06: orn({{ + UINT64 val2 = (I ? SIMM13.sdw : Rs2.udw); + Rd = Rs1.udw | ~val2; + }});//ORN + 0x07: xnor({{ + UINT64 val2 = (I ? SIMM13.sdw : Rs2.udw); + Rd = ~(Rs1.udw ^ val2); + }});//XNOR + 0x08: addc({{ + INT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); + INT64 carryin = xc->regs.MiscRegs.ccrfields.iccfields.c; + Rd = Rs1.sdw + val2 + carryin; + }});//ADDC + 0x09: mulx({{ + INT64 val2 = (I ? SIMM13.sdw : Rs2); + Rd = Rs1 * val2; + }});//MULX + 0x0A: umul({{ + UINT64 resTemp, val2 = (I ? SIMM13.sdw : Rs2.udw); + Rd = resTemp = Rs1.udw<31:0> * val2<31:0>; + xc->regs.MiscRegs.yFields.value = resTemp<63:32>; + }});//UMUL + 0x0B: smul({{ + INT64 resTemp, val2 = (I ? SIMM13.sdw : Rs2.sdw); + rd.sdw = resTemp = Rs1.sdw<31:0> * val2<31:0>; + xc->regs.MiscRegs.yFields.value = resTemp<63:32>; + }});//SMUL + 0x0C: subc({{ + INT64 val2 = ~((INT64)(I ? SIMM13.sdw : Rs2.sdw))+1; + INT64 carryin = xc->regs.MiscRegs.ccrfields.iccfields.c; + Rd.sdw = Rs1.sdw + val2 + carryin; + }});//SUBC + 0x0D: udivx({{ + UINT64 val2 = (I ? SIMM13.sdw : Rs2.udw); + if(val2 == 0) throw division_by_zero; + Rd.udw = Rs1.udw / val2; + }});//UDIVX + 0x0E: udiv({{ + UINT32 resTemp, val2 = (I ? SIMM13.sw : Rs2.udw<31:0>); + if(val2 == 0) throw division_by_zero; + resTemp = (UINT64)((xc->regs.MiscRegs.yFields.value << 32) | Rs1.udw<31:0>) / val2; + INT32 overflow = (resTemp<63:32> != 0); + if(overflow) rd.udw = resTemp = 0xFFFFFFFF; + else rd.udw = resTemp; + }}); //UDIV + 0x0F: sdiv({{ + INT32 resTemp, val2 = (I ? SIMM13.sw : Rs2.sdw<31:0>); + if(val2 == 0) throw division_by_zero; + Rd.sdw = resTemp = (INT64)((xc->regs.MiscRegs.yFields.value << 32) | Rs1.sdw<31:0>) / val2; + INT32 overflow = (resTemp<63:31> != 0); + INT32 underflow = (resTemp<63:> && resTemp<62:31> != 0xFFFFFFFF); + if(overflow) rd.udw = resTemp = 0x7FFFFFFF; + else if(underflow) rd.udw = resTemp = 0xFFFFFFFF80000000; + else rd.udw = resTemp; + }});//SDIV + } + format IntegerOpCc { + 0x10: addcc({{ + INT64 resTemp, val2 = (I ? SIMM13.sdw : Rs2); + Rd = resTemp = Rs1 + val2;}}, + {{((Rs1 & 0xFFFFFFFF + val2 & 0xFFFFFFFF) >> 31)}}, + {{Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>}}, + {{((Rs1 >> 1) + (val2 >> 1) + (Rs1 & val2 & 0x1))<63:>}}, + {{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}} + );//ADDcc + 0x11: andcc({{ + INT64 val2 = (I ? SIMM13.sdw : Rs2); + Rd = Rs1 & val2;}} + ,{{0}},{{0}},{{0}},{{0}});//ANDcc + 0x12: orcc({{ + INT64 val2 = (I ? SIMM13.sdw : Rs2); + Rd = Rs1 | val2;}} + ,{{0}},{{0}},{{0}},{{0}});//ORcc + 0x13: xorcc({{ + INT64 val2 = (I ? SIMM13.sdw : Rs2); + Rd = Rs1 ^ val2;}} + ,{{0}},{{0}},{{0}},{{0}});//XORcc + 0x14: subcc({{ + INT64 resTemp, val2 = (INT64)(I ? SIMM13.sdw : Rs2); + Rd = resTemp = Rs1 - val2;}}, + {{((Rs1 & 0xFFFFFFFF + (~val2) & 0xFFFFFFFF + 1) >> 31)}}, + {{Rs1<31:> != val2<31:> && Rs1<31:> != resTemp<31:>}}, + {{((Rs1 >> 1) + (~val2) >> 1) + ((Rs1 | ~val2) & 0x1))<63:>}}, + {{Rs1<63:> != val2<63:> && Rs1<63:> != resTemp<63:>}} + );//SUBcc + 0x15: andncc({{ + INT64 val2 = (I ? SIMM13.sdw : Rs2); + Rd = Rs1 & ~val2;}} + ,{{0}},{{0}},{{0}},{{0}});//ANDNcc + 0x16: orncc({{ + INT64 val2 = (I ? SIMM13.sdw : Rs2); + Rd = Rs1 | ~val2;}} + ,{{0}},{{0}},{{0}},{{0}});//ORNcc + 0x17: xnorcc({{ + INT64 val2 = (I ? SIMM13.sdw : Rs2); + Rd = ~(Rs1 ^ val2);}} + ,{{0}},{{0}},{{0}},{{0}});//XNORcc + 0x18: addccc({{ + INT64 resTemp, val2 = (I ? SIMM13.sdw : Rs2); + INT64 carryin = xc->regs.MiscRegs.ccrfields.iccfields.c; + Rd = resTemp = Rs1 + val2 + carryin;}}, + {{((Rs1 & 0xFFFFFFFF + val2 & 0xFFFFFFFF) >> 31 + carryin)}}, + {{Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>}}, + {{((Rs1 >> 1) + (val2 >> 1) + ((Rs1 & val2) | (carryin & (Rs1 | val2)) & 0x1))<63:>}}, + {{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}} + );//ADDCcc + 0x1A: umulcc({{ + UINT64 resTemp, val2 = (I ? SIMM13.sdw : Rs2); + Rd = resTemp = Rs1.udw<31:0> * val2<31:0>; + xc->regs.MiscRegs.yFields.value = resTemp<63:32>;}} + ,{{0}},{{0}},{{0}},{{0}});//UMULcc + 0x1B: smulcc({{ + INT64 resTemp, val2 = (I ? SIMM13.sdw : Rs2); + Rd = resTemp = Rs1.sdw<31:0> * val2<31:0>; + xc->regs.MiscRegs.yFields.value = resTemp<63:32>;}} + ,{{0}},{{0}},{{0}},{{0}});//SMULcc + 0x1C: subccc({{ + INT64 resTemp, val2 = (INT64)(I ? SIMM13.sdw : Rs2); + INT64 carryin = xc->regs.MiscRegs.ccrfields.iccfields.c; + Rd = resTemp = Rs1 + ~(val2 + carryin) + 1;}}, + {{((Rs1 & 0xFFFFFFFF + (~(val2 + carryin)) & 0xFFFFFFFF + 1) >> 31)}}, + {{Rs1<31:> != val2<31:> && Rs1<31:> != resTemp<31:>}}, + {{((Rs1 >> 1) + (~(val2 + carryin)) >> 1) + ((Rs1 | ~(val2+carryin)) & 0x1))<63:>}}, + {{Rs1<63:> != val2<63:> && Rs1<63:> != resTemp<63:>}} + );//SUBCcc + 0x1D: udivxcc({{ + UINT64 val2 = (I ? SIMM13.sdw : Rs2.udw); + if(val2 == 0) throw division_by_zero; + Rd.udw = Rs1.udw / val2;}} + ,{{0}},{{0}},{{0}},{{0}});//UDIVXcc + 0x1E: udivcc({{ + UINT32 resTemp, val2 = (I ? SIMM13.sw : Rs2.udw<31:0>); + if(val2 == 0) throw division_by_zero; + resTemp = (UINT64)((xc->regs.MiscRegs.yFields.value << 32) | Rs1.udw<31:0>) / val2; + INT32 overflow = (resTemp<63:32> != 0); + if(overflow) rd.udw = resTemp = 0xFFFFFFFF; + else rd.udw = resTemp;}}, + {{0}}, + {{overflow}}, + {{0}}, + {{0}} + );//UDIVcc + 0x1F: sdivcc({{ + INT32 resTemp, val2 = (I ? SIMM13.sw : Rs2.sdw<31:0>); + if(val2 == 0) throw division_by_zero; + Rd.sdw = resTemp = (INT64)((xc->regs.MiscRegs.yFields.value << 32) | Rs1.sdw<31:0>) / val2; + INT32 overflow = (resTemp<63:31> != 0); + INT32 underflow = (resTemp<63:> && resTemp<62:31> != 0xFFFFFFFF); + if(overflow) rd.udw = resTemp = 0x7FFFFFFF; + else if(underflow) rd.udw = resTemp = 0xFFFFFFFF80000000; + else rd.udw = resTemp;}}, + {{0}}, + {{overflow || underflow}}, + {{0}}, + {{0}} + );//SDIVcc + 0x20: taddcc({{ + INT64 resTemp, val2 = (I ? SIMM13.sdw : Rs2); + Rd = resTemp = Rs1 + val2; + INT32 overflow = Rs1<1:0> || val2<1:0> || (Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>);}}, + {{((Rs1 & 0xFFFFFFFF + val2 & 0xFFFFFFFF) >> 31)}}, + {{overflow}}, + {{((Rs1 >> 1) + (val2 >> 1) + (Rs1 & val2 & 0x1))<63:>}}, + {{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}} + );//TADDcc + 0x21: tsubcc({{ + INT64 resTemp, val2 = (I ? SIMM13.sdw : Rs2); + Rd = resTemp = Rs1 + val2; + INT32 overflow = Rs1<1:0> || val2<1:0> || (Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>);}}, + {{(Rs1 & 0xFFFFFFFF + val2 & 0xFFFFFFFF) >> 31)}}, + {{overflow}}, + {{((Rs1 >> 1) + (val2 >> 1) + (Rs1 & val2 & 0x1))<63:>}}, + {{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}} + );//TSUBcc + 0x22: taddcctv({{ + INT64 resTemp, val2 = (I ? SIMM13.sdw : Rs2); + Rd = resTemp = Rs1 + val2; + INT32 overflow = Rs1<1:0> || val2<1:0> || (Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>); + if(overflow) throw tag_overflow;}}, + {{((Rs1 & 0xFFFFFFFF + val2 & 0xFFFFFFFF) >> 31)}}, + {{overflow}}, + {{((Rs1 >> 1) + (val2 >> 1) + (Rs1 & val2 & 0x1))<63:>}}, + {{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}} + );//TADDccTV + 0x23: tsubcctv({{ + INT64 resTemp, val2 = (I ? SIMM13.sdw : Rs2); + Rd = resTemp = Rs1 + val2; + INT32 overflow = Rs1<1:0> || val2<1:0> || (Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>); + if(overflow) throw tag_overflow;}}, + {{((Rs1 & 0xFFFFFFFF + val2 & 0xFFFFFFFF) >> 31)}}, + {{overflow}}, + {{((Rs1 >> 1) + (val2 >> 1) + (Rs1 & val2 & 0x1))<63:>}}, + {{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}} + );//TSUBccTV + 0x24: mulscc({{ + INT64 resTemp, multiplicand = (I ? SIMM13.sdw : Rs2); + INT32 multiplier = Rs1<31:0>; + INT32 savedLSB = Rs1<0:>; + multiplier = multipler<31:1> | + ((xc->regs.MiscRegs.ccrFields.iccFields.n + ^ xc->regs.MiscRegs.ccrFields.iccFields.v) << 32); + if(!xc->regs.MiscRegs.yFields.value<0:>) + multiplicand = 0; + Rd = resTemp = multiplicand + multiplier; + xc->regs.MiscRegs.yFields.value = xc->regs.MiscRegs.yFields.value<31:1> | (savedLSB << 31);}}, + {{((multiplicand & 0xFFFFFFFF + multiplier & 0xFFFFFFFF) >> 31)}}, + {{multiplicand<31:> == multiplier<31:> && multiplier<31:> != resTemp<31:>}}, + {{((multiplicand >> 1) + (multiplier >> 1) + (multiplicand & multiplier & 0x1))<63:>}}, + {{multiplicand<63:> == multiplier<63:> && multiplier<63:> != resTemp<63:>}} + );//MULScc + } + format IntegerOp + { + 0x25: decode X { + 0x0: sll({{Rd = Rs1 << (I ? SHCNT32 : Rs2<4:0>);}}); //SLL + 0x1: sllx({{Rd = Rs1 << (I ? SHCNT64 : Rs2<5:0>);}}); //SLLX + } + 0x26: decode X { + 0x0: srl({{Rd = Rs1.udw<31:0> >> (I ? SHCNT32 : Rs2<4:0>);}}); //SRL + 0x1: srlx({{Rd = Rs1.udw >> (I ? SHCNT64 : Rs2<5:0>);}});//SRLX + } + 0x27: decode X { + 0x0: sra({{Rd = Rs1.sdw<31:0> >> (I ? SHCNT32 : Rs2<4:0>);}}); //SRA + 0x1: srax({{Rd = Rs1.sdw >> (I ? SHCNT64 : Rs2<5:0>);}});//SRAX + } + 0x28: decode RS1 { + 0x0: rdy({{Rd = xc->regs.MiscRegs.yFields.value;}}); //RDY + 0x2: rdccr({{Rd = xc->regs.MiscRegs.ccr;}}); //RDCCR + 0x3: rdasi({{Rd = xc->regs.MiscRegs.asi;}}); //RDASI + 0x4: rdtick({{ + if(xc->regs.MiscRegs.pstateFields.priv == 0 && + xc->regs.MiscRegs.tickFields.npt == 1) + throw privileged_action; + Rd = xc->regs.MiscRegs.tick; + }});//RDTICK + 0x5: rdpc({{Rd = xc->regs.pc;}}); //RDPC + 0x6: rdfprs({{Rd = xc->regs.MiscRegs.fprs;}}); //RDFPRS + 0xF: decode I { + 0x0: Noop::membar({{//Membar isn't needed yet}}); //MEMBAR + 0x1: Noop::stbar({{//Stbar isn/'t needed yet}}); //STBAR + } + } + + 0x2A: decode RS1 { + 0x0: rdprtpc({{checkPriv Rd = xc->regs.MiscRegs.tpc[xc->regs.MiscRegs.tl];}}); + 0x1: rdprtnpc({{checkPriv Rd = xc->regs.MiscRegs.tnpc[xc->regs.MiscRegs.tl];}}); + 0x2: rdprtstate({{checkPriv Rd = xc->regs.MiscRegs.tstate[xc->regs.MiscRegs.tl];}}); + 0x3: rdprtt({{checkPriv Rd = xc->regs.MiscRegs.tt[xc->regs.MiscRegs.tl];}}); + 0x4: rdprtick({{checkPriv Rd = xc->regs.MiscRegs.tick;}}); + 0x5: rdprtba({{checkPriv Rd = xc->regs.MiscRegs.tba;}}); + 0x6: rdprpstate({{checkPriv Rd = xc->regs.MiscRegs.pstate;}}); + 0x7: rdprtl({{checkPriv Rd = xc->regs.MiscRegs.tl;}}); + 0x8: rdprpil({{checkPriv Rd = xc->regs.MiscRegs.pil;}}); + 0x9: rdprcwp({{checkPriv Rd = xc->regs.MiscRegs.cwp;}}); + 0xA: rdprcansave({{checkPriv Rd = xc->regs.MiscRegs.cansave;}}); + 0xB: rdprcanrestore({{checkPriv Rd = xc->regs.MiscRegs.canrestore;}}); + 0xC: rdprcleanwin({{checkPriv Rd = xc->regs.MiscRegs.cleanwin;}}); + 0xD: rdprotherwin({{checkPriv Rd = xc->regs.MiscRegs.otherwin;}}); + 0xE: rdprwstate({{checkPriv Rd = xc->regs.MiscRegs.wstate;}}); + 0xF: rdprfq({{throw illegal_instruction;}}); //The floating point queue isn't implemented right now. + } + 0x2B: BasicOperate::flushw({{\\window toilet}}); //FLUSHW + 0x2C: movcc({{ + ccBank = (CC24 << 2) | (CC14 << 1) | (CC04 << 0); + switch(ccBank) + { + case 0: case 1: case 2: case 3: + throw fp_disabled; + break; + case 5: case 7: + throw illegal_instruction; + break; + case 4: + if(passesCondition(xc->regs.MiscRegs.ccrFields.icc, COND4)) + Rd = (I ? SIMM11.sdw : RS2); + break; + case 6: + if(passesCondition(xc->regs.MiscRegs.ccrFields.xcc, COND4)) + Rd = (I ? SIMM11.sdw : RS2); + break; + } + }});//MOVcc + 0x2D: sdivx({{ + INT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); + if(val2 == 0) throw division_by_zero; + Rd.sdw = Rs1.sdw / val2; + }});//SDIVX + 0x2E: decode RS1 { + 0x0: IntegerOp::popc({{ + INT64 count = 0, val2 = (I ? SIMM13.sdw : Rs2.sdw); + UINT8 oneBits[] = {0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4} + for(unsigned int x = 0; x < 16; x++) + { + count += oneBits[val2 & 0xF]; + val2 >> 4; + } + }});//POPC + } + 0x2F: movr({{ + UINT64 val2 = (I ? SIMM10.sdw : Rs2.sdw); + switch(RCOND) + { + case 0: case 4: + throw illegal_instruction; + break; + case 1: + if(Rs1 == 0) Rd = val2; + break; + case 2: + if(Rs1 <= 0) Rd = val2; + break; + case 3: + if(Rs1 = 0) Rd = val2; + break; + case 5: + if(Rs1 != 0) Rd = val2; + break; + case 6: + if(Rs1 > 0) Rd = val2; + break; + case 7: + if(Rs1 >= 0) Rd = val2; + break; + } + }});//MOVR + 0x30: decode RD { + 0x0: wry({{ + UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); + xc->regs.MiscRegs.y = Rs1 ^ val2; + }});//WRY + 0x2: wrccr({{ + UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); + xc->regs.MiscRegs.ccr = Rs1 ^ val2; + }});//WRCCR + 0x3: wrasi({{ + UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); + xc->regs.MiscRegs.asi = Rs1 ^ val2; + }});//WRASI + 0x6: wrfprs({{ + UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); + xc->regs.MiscRegs.asi = Rs1 ^ val2; + }});//WRFPRS + 0xF: Trap::sir({{software_initiated_reset}}); //SIR + } + 0x31: decode FCN { + 0x0: BasicOperate::saved({{\\Boogy Boogy}}); //SAVED + 0x1: BasicOperate::restored({{\\Boogy Boogy}}); //RESTORED + } + 0x32: decode RD { + 0x0: wrprtpc({{checkPriv + UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); + xc->regs.MiscRegs.tpc[xc->regs.MiscRegs.tl] = Rs1 ^ val2; + }}); + 0x1: wrprtnpc({{checkPriv + UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); + xc->regs.MiscRegs.tnpc[xc->regs.MiscRegs.tl] = Rs1 ^ val2; + }}); + 0x2: wrprtstate({{checkPriv + UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); + xc->regs.MiscRegs.tstate[xc->regs.MiscRegs.tl] = Rs1 ^ val2; + }}); + 0x3: wrprtt({{checkPriv + UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); + xc->regs.MiscRegs.tt[xc->regs.MiscRegs.tl] = Rs1 ^ val2; + }}); + 0x4: wrprtick({{checkPriv + UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); + xc->regs.MiscRegs.tick = Rs1 ^ val2; + }}); + 0x5: wrprtba({{checkPriv + UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); + xc->regs.MiscRegs.tba = Rs1 ^ val2; + }}); + 0x6: wrprpstate({{checkPriv + UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); + xc->regs.MiscRegs.pstate = Rs1 ^ val2; + }}); + 0x7: wrprtl({{checkPriv + UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); + xc->regs.MiscRegs.tl = Rs1 ^ val2; + }}); + 0x8: wrprpil({{checkPriv + UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); + xc->regs.MiscRegs.pil = Rs1 ^ val2; + }}); + 0x9: wrprcwp({{checkPriv + UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); + xc->regs.MiscRegs.cwp = Rs1 ^ val2; + }}); + 0xA: wrprcansave({{checkPriv + UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); + xc->regs.MiscRegs.cansave = Rs1 ^ val2; + }}); + 0xB: wrprcanrestore({{checkPriv + UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); + xc->regs.MiscRegs.canrestore = Rs1 ^ val2; + }}); + 0xC: wrprcleanwin({{checkPriv + UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); + xc->regs.MiscRegs.cleanwin = Rs1 ^ val2; + }}); + 0xD: wrprotherwin({{checkPriv + UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); + xc->regs.MiscRegs.otherwin = Rs1 ^ val2; + }}); + 0xE: wrprwstate({{checkPriv + UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); + xc->regs.MiscRegs.wstate = Rs1 ^ val2; + }}); + } + + 0x34: Trap::fpop1({{Throw fp_disabled;}}); //FPOP1 + 0x35: Trap::fpop2({{Throw fp_disabled;}}); //FPOP2 + + + 0x38: Branch::jmpl({{//Stuff}}); //JMPL + 0x39: Branch::return({{//Other Stuff}}); //RETURN + 0x3A: Trap::tcc({{ + switch((CC14 << 1) | (CC04 << 0)) + { + case 1: case 3: + throw illegal_instruction; + case 0: + if(passesCondition(xc->regs.MiscRegs.ccrFields.icc, machInst<25:28>)) + throw trap_instruction; + break; + case 2: + if(passesCondition(xc->regs.MiscRegs.ccrFields.xcc, machInst<25:28>)) + throw trap_instruction; + break; + } + }}); //Tcc + 0x3B: BasicOperate::flush({{//Lala}}); //FLUSH + 0x3C: BasicOperate::save({{//leprechauns); //SAVE + 0x3D: BasicOperate::restore({{//Eat my short int}}); //RESTORE + 0x3E: decode FCN { + 0x1: BasicOperate::done({{//Done thing}}); //DONE + 0x2: BasicOperate::retry({{//Retry thing}}); //RETRY + } + } + } + 0x3: decode OP3 { + format Mem { + 0x00: lduw({{Rd.uw = Mem.uw;}}); //LDUW + 0x01: ldub({{Rd.ub = Mem.ub;}}); //LDUB + 0x02: lduh({{Rd.uhw = Mem.uhw;}}); //LDUH + 0x03: ldd({{ + UINT64 val = Mem.udw; + setIntReg(RD & (~1), val<31:0>); + setIntReg(RD | 1, val<63:32>); + }});//LDD + 0x04: stw({{Mem.sw = Rd.sw;}}); //STW + 0x05: stb({{Mem.sb = Rd.sb;}}); //STB + 0x06: sth({{Mem.shw = Rd.shw;}}); //STH + 0x07: std({{ + Mem.udw = readIntReg(RD & (~1))<31:0> | (readIntReg(RD | 1)<31:0> << 32); + }});//STD + 0x08: ldsw({{Rd.sw = Mem.sw;}}); //LDSW + 0x09: ldsb({{Rd.sb = Mem.sb;}}); //LDSB + 0x0A: ldsh({{Rd.shw = Mem.shw;}}); //LDSH + 0x0B: ldx({{Rd.udw = Mem.udw;}}); //LDX + + 0x0D: ldstub({{ + Rd.ub = Mem.ub; + Mem.ub = 0xFF; + }}); //LDSTUB + 0x0E: stx({{Rd.udw = Mem.udw;}}); //STX + 0x0F: swap({{ + UINT32 temp = Rd.uw; + Rd.uw = Mem.uw; + Mem.uw = temp; + }}); //SWAP + 0x10: lduwa({{Rd.uw = Mem.uw;}}); //LDUWA + 0x11: lduba({{Rd.ub = Mem.ub;}}); //LDUBA + 0x12: lduha({{Rd.uhw = Mem.uhw;}}); //LDUHA + 0x13: ldda({{ + UINT64 val = Mem.udw; + setIntReg(RD & (~1), val<31:0>); + setIntReg(RD | 1, val<63:32>); + }}); //LDDA + 0x14: stwa({{Mem.uw = Rd.uw;}}); //STWA + 0x15: stba({{Mem.ub = Rd.ub;}}); //STBA + 0x16: stha({{Mem.uhw = Rd.uhw;}}); //STHA + 0x17: stda({{ + Mem.udw = readIntReg(RD & (~1))<31:0> | (readIntReg(RD | 1)<31:0> << 32); + }}); //STDA + 0x18: ldswa({{Rd.sw = Mem.sw;}}); //LDSWA + 0x19: ldsba({{Rd.sb = Mem.sb;}}); //LDSBA + 0x1A: ldsha({{Rd.shw = Mem.shw;}}); //LDSHA + 0x1B: ldxa({{Rd.sdw = Mem.sdw;}}); //LDXA + + 0x1D: ldstuba({{ + Rd.ub = Mem.ub; + Mem.ub = 0xFF; + }}); //LDSTUBA + 0x1E: stxa({{Mem.sdw = Rd.sdw}}); //STXA + 0x1F: swapa({{ + UINT32 temp = Rd.uw; + Rd.uw = Mem.uw; + Mem.uw = temp; + }}); //SWAPA + 0x20: Trap::ldf({{throw fp_disabled;}}); //LDF + 0x21: decode X { + 0x0: Trap::ldfsr({{throw fp_disabled;}}); //LDFSR + 0x1: Trap::ldxfsr({{throw fp_disabled;}}); //LDXFSR + } + 0x22: Trap::ldqf({{throw fp_disabled;}}); //LDQF + 0x23: Trap::lddf({{throw fp_disabled;}}); //LDDF + 0x24: Trap::stf({{throw fp_disabled;}}); //STF + 0x25: decode X { + 0x0: Trap::stfsr({{throw fp_disabled;}}); //STFSR + 0x1: Trap::stxfsr({{throw fp_disabled;}}); //STXFSR + } + 0x26: Trap::stqf({{throw fp_disabled;}}); //STQF + 0x27: Trap::stdf({{throw fp_disabled;}}); //STDF + + + + + + 0x2D: Noop::prefetch({{ }}); //PREFETCH + + + 0x30: Trap::ldfa({{throw fp_disabled;}}); //LDFA + + 0x32: Trap::ldqfa({{throw fp_disabled;}}); //LDQFA + 0x33: Trap::lddfa({{throw fp_disabled;}}); //LDDFA + 0x34: Trap::stfa({{throw fp_disabled;}}); //STFA + 0x35: Trap::stqfa({{throw fp_disabled;}}); //STQFA + 0x36: Trap::stdfa({{throw fp_disabled;}}); //STDFA + + + + + + 0x3C: Cas::casa( + {{UINT64 val = Mem.uw; + if(Rs2.uw == val) + Mem.uw = Rd.uw; + Rd.uw = val; + }}); //CASA + 0x3D: Noop::prefetcha({{ }}); //PREFETCHA + 0x3E: Cas::casxa( + {{UINT64 val = Mem.udw; + if(Rs2 == val) + Mem.udw = Rd; + Rd = val; + }}); //CASXA + } + } +} diff --git a/arch/sparc/isa_desc/formats.h b/arch/sparc/isa_desc/formats.h new file mode 100644 index 000000000..733a093f5 --- /dev/null +++ b/arch/sparc/isa_desc/formats.h @@ -0,0 +1,19 @@ +//Include the basic format +//Templates from this format are used later +##include "m5/arch/sparc/isa_desc/formats/basic.format" + +//Include the integerOp and integerOpCc format +##include "m5/arch/sparc/isa_desc/formats/integerop.format" + +//Include the mem format +##include "m5/arch/sparc/isa_desc/formats/mem.format" + +//Include the trap format +##include "m5/arch/sparc/isa_desc/formats/trap.format" + +//Include the branch format +##include "m5/arch/sparc/isa_desc/formats/branch.format" + +//Include the noop format +##include "m5/arch/sparc/isa_desc/formats/noop.format" + diff --git a/arch/sparc/isa_desc/formats/basic.format b/arch/sparc/isa_desc/formats/basic.format new file mode 100644 index 000000000..1994df41c --- /dev/null +++ b/arch/sparc/isa_desc/formats/basic.format @@ -0,0 +1,65 @@ + +// Declarations for execute() methods. +def template BasicExecDeclare {{ + Fault execute(%(CPU_exec_context)s *, Trace::InstRecord *) const; +}}; + +// Basic instruction class declaration template. +def template BasicDeclare {{ + /** + * Static instruction class for "%(mnemonic)s". + */ + class %(class_name)s : public %(base_class)s + { + public: + /// Constructor. + %(class_name)s(MachInst machInst); + %(BasicExecDeclare)s + }; +}}; + +// Basic instruction class constructor template. +def template BasicConstructor {{ + inline %(class_name)s::%(class_name)s(MachInst machInst) : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s) + { + %(constructor)s; + } +}}; + +// Basic instruction class execute method template. +def template BasicExecute {{ + Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const + { + Fault fault = No_Fault; + + %(fp_enable_check)s; + %(op_decl)s; + %(op_rd)s; + %(code)s; + + if(fault == No_Fault) + { + %(op_wb)s; + } + return fault; + } +}}; + +// Basic decode template. +def template BasicDecode {{ + return new %(class_name)s(machInst); +}}; + +// Basic decode template, passing mnemonic in as string arg to constructor. +def template BasicDecodeWithMnemonic {{ + return new %(class_name)s("%(mnemonic)s", machInst); +}}; + +// The most basic instruction format... used only for a few misc. insts +def format BasicOperate(code, *flags) {{ + iop = InstObjParams(name, Name, 'SparcStaticInst', CodeBlock(code), flags) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecode.subst(iop) + exec_output = BasicExecute.subst(iop) +}}; diff --git a/arch/sparc/isa_desc/formats/branch.format b/arch/sparc/isa_desc/formats/branch.format new file mode 100644 index 000000000..c4c0a90af --- /dev/null +++ b/arch/sparc/isa_desc/formats/branch.format @@ -0,0 +1,66 @@ +//////////////////////////////////////////////////////////////////// +// +// Branch instructions +// + +output header {{ + /** + * Base class for integer operations. + */ + class Branch : public SparcStaticInst + { + protected: + + /// Constructor + Branch(const char *mnem, MachInst _machInst, OpClass __opClass) : SparcStaticInst(mnem, _machInst, __opClass) + { + } + + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; + }; +}}; + +output decoder {{ + std::string Branch::generateDisassembly(Addr pc, const SymbolTable *symtab) const + { + return "Disassembly of integer instruction\n"; + } +}}; + +def template BranchExecute {{ + Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const + { + //Attempt to execute the instruction + try + { + checkPriv; + + %(op_decl)s; + %(op_rd)s; + %(code)s; + } + //If we have an exception for some reason, + //deal with it + catch(SparcException except) + { + //Deal with exception + return No_Fault; + } + + //Write the resulting state to the execution context + %(op_wb)s; + + return No_Fault; + } +}}; + +// Primary format for integer operate instructions: +def format Branch(code, *opt_flags) {{ + orig_code = code + cblk = CodeBlock(code) + iop = InstObjParams(name, Name, 'SparcStaticInst', cblk, opt_flags) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecodeWithMnemonic.subst(iop) + exec_output = BranchExecute.subst(iop) +}}; diff --git a/arch/sparc/isa_desc/formats/integerop.format b/arch/sparc/isa_desc/formats/integerop.format new file mode 100644 index 000000000..275a346d3 --- /dev/null +++ b/arch/sparc/isa_desc/formats/integerop.format @@ -0,0 +1,110 @@ +//////////////////////////////////////////////////////////////////// +// +// Integer operate instructions +// + +output header {{ + /** + * Base class for integer operations. + */ + class IntegerOp : public SparcStaticInst + { + protected: + + /// Constructor + IntegerOp(const char *mnem, MachInst _machInst, OpClass __opClass) : SparcStaticInst(mnem, _machInst, __opClass) + { + } + + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; + }; +}}; + +output decoder {{ + std::string IntegerOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const + { + return "Disassembly of integer instruction\n"; + } +}}; + +def template IntegerExecute {{ + Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const + { + //These are set to constants when the execute method + //is generated + bool useCc = ; + bool checkPriv = ; + + //Attempt to execute the instruction + try + { + checkPriv; + + %(op_decl)s; + %(op_rd)s; + %(code)s; + } + //If we have an exception for some reason, + //deal with it + catch(SparcException except) + { + //Deal with exception + return No_Fault; + } + + //Write the resulting state to the execution context + %(op_wb)s; + if(useCc) + { + xc->regs.miscRegFile.ccrFields.iccFields.n = Rd & (1 << 63); + xc->regs.miscRegFile.ccrFields.iccFields.z = (Rd == 0); + xc->regs.miscRegFile.ccrFields.iccFields.v = ivValue; + xc->regs.miscRegFile.ccrFields.iccFields.c = icValue; + xc->regs.miscRegFile.ccrFields.xccFields.n = Rd & (1 << 31); + xc->regs.miscRegFile.ccrFields.xccFields.z = ((Rd & 0xFFFFFFFF) == 0); + xc->regs.miscRegFile.ccrFields.xccFields.v = xvValue; + xc->regs.miscRegFile.ccrFields.xccFields.c = xcValue; + } + return No_Fault; + } +}}; + +// Primary format for integer operate instructions: +def format IntegerOp(code, *opt_flags) {{ + orig_code = code + cblk = CodeBlock(code) + checkPriv = (code.find('checkPriv') != -1) + code.replace('checkPriv', '') + if checkPriv: + code.replace('checkPriv;', 'if(!xc->regs.miscRegFile.pstateFields.priv) throw privileged_opcode;') + else: + code.replace('checkPriv;', '') + for (marker, value) in (('ivValue', '0'), ('icValue', '0'), + ('xvValue', '0'), ('xcValue', '0')): + code.replace(marker, value) + iop = InstObjParams(name, Name, 'SparcStaticInst', cblk, opt_flags) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecodeWithMnemonic.subst(iop) + exec_output = IntegerExecute.subst(iop) +}}; + +// Primary format for integer operate instructions: +def format IntegerOpCc(code, icValue, ivValue, xcValue, xvValue, *opt_flags) {{ + orig_code = code + cblk = CodeBlock(code) + checkPriv = (code.find('checkPriv') != -1) + code.replace('checkPriv', '') + if checkPriv: + code.replace('checkPriv;', 'if(!xc->regs.miscRegFile.pstateFields.priv) throw privileged_opcode;') + else: + code.replace('checkPriv;', '') + for (marker, value) in (('ivValue', ivValue), ('icValue', icValue), + ('xvValue', xvValue), ('xcValue', xcValue)): + code.replace(marker, value) + iop = InstObjParams(name, Name, 'SparcStaticInst', cblk, opt_flags) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecodeWithMnemonic.subst(iop) + exec_output = IntegerExecute.subst(iop) +}}; diff --git a/arch/sparc/isa_desc/formats/mem.format b/arch/sparc/isa_desc/formats/mem.format new file mode 100644 index 000000000..abc00b6f2 --- /dev/null +++ b/arch/sparc/isa_desc/formats/mem.format @@ -0,0 +1,78 @@ +//////////////////////////////////////////////////////////////////// +// +// Mem instructions +// + +output header {{ + /** + * Base class for integer operations. + */ + class Mem : public SparcStaticInst + { + protected: + + /// Constructor + Mem(const char *mnem, MachInst _machInst, OpClass __opClass) : SparcStaticInst(mnem, _machInst, __opClass) + { + } + + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; + }; +}}; + +output decoder {{ + std::string Mem::generateDisassembly(Addr pc, const SymbolTable *symtab) const + { + return "Disassembly of integer instruction\n"; + } +}}; + +def template MemExecute {{ + Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const + { + //Attempt to execute the instruction + try + { + + %(op_decl)s; + %(op_rd)s; + ea_code + %(code)s; + } + //If we have an exception for some reason, + //deal with it + catch(SparcException except) + { + //Deal with exception + return No_Fault; + } + + //Write the resulting state to the execution context + %(op_wb)s; + + return No_Fault; + } +}}; + +// Primary format for integer operate instructions: +def format Mem(code, *opt_flags) {{ + orig_code = code + cblk = CodeBlock(code) + iop = InstObjParams(name, Name, 'SparcStaticInst', cblk, opt_flags) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecodeWithMnemonic.subst(iop) + exec_output = MemExecute.subst(iop) + exec_output.replace('ea_code', 'EA = I ? (R1 + SIMM13) : R1 + R2;'); +}}; + +def format Cas(code, *opt_flags) {{ + orig_code = code + cblk = CodeBlock(code) + iop = InstObjParams(name, Name, 'SparcStaticInst', cblk, opt_flags) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecodeWithMnemonic.subst(iop) + exec_output = MemExecute.subst(iop) + exec_output.replace('ea_code', 'EA = R1;'); +}}; diff --git a/arch/sparc/isa_desc/formats/noop.format b/arch/sparc/isa_desc/formats/noop.format new file mode 100644 index 000000000..bc83e3261 --- /dev/null +++ b/arch/sparc/isa_desc/formats/noop.format @@ -0,0 +1,47 @@ +//////////////////////////////////////////////////////////////////// +// +// Noop instruction +// + +output header {{ + /** + * Base class for integer operations. + */ + class Noop : public SparcStaticInst + { + protected: + + /// Constructor + Noop(const char *mnem, MachInst _machInst, OpClass __opClass) : SparcStaticInst(mnem, _machInst, __opClass) + { + } + + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; + }; +}}; + +output decoder {{ + std::string Noop::generateDisassembly(Addr pc, const SymbolTable *symtab) const + { + return "Disassembly of integer instruction\n"; + } +}}; + +def template NoopExecute {{ + Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const + { + //Nothing to see here, move along + return No_Fault; + } +}}; + +// Primary format for integer operate instructions: +def format Noop(code, *opt_flags) {{ + orig_code = code + cblk = CodeBlock(code) + iop = InstObjParams(name, Name, 'SparcStaticInst', cblk, opt_flags) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecodeWithMnemonic.subst(iop) + exec_output = NoopExecute.subst(iop) +}}; diff --git a/arch/sparc/isa_desc/formats/trap.format b/arch/sparc/isa_desc/formats/trap.format new file mode 100644 index 000000000..bee77fe69 --- /dev/null +++ b/arch/sparc/isa_desc/formats/trap.format @@ -0,0 +1,53 @@ +//////////////////////////////////////////////////////////////////// +// +// Trap instructions +// + +output header {{ + /** + * Base class for integer operations. + */ + class Trap : public SparcStaticInst + { + protected: + + /// Constructor + Trap(const char *mnem, MachInst _machInst, OpClass __opClass) : SparcStaticInst(mnem, _machInst, __opClass) + { + } + + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; + }; +}}; + +output decoder {{ + std::string Trap::generateDisassembly(Addr pc, const SymbolTable *symtab) const + { + return "Disassembly of integer instruction\n"; + } +}}; + +def template TrapExecute {{ + Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const + { + //Call into the trap handler with the appropriate fault + return No_Fault; + } + + //Write the resulting state to the execution context + %(op_wb)s; + + return No_Fault; + } +}}; + +// Primary format for integer operate instructions: +def format Trap(code, *opt_flags) {{ + orig_code = code + cblk = CodeBlock(code) + iop = InstObjParams(name, Name, 'SparcStaticInst', cblk, opt_flags) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecodeWithMnemonic.subst(iop) + exec_output = TrapExecute.subst(iop) +}}; diff --git a/arch/sparc/isa_desc/includes.h b/arch/sparc/isa_desc/includes.h new file mode 100644 index 000000000..ff7cb7d1d --- /dev/null +++ b/arch/sparc/isa_desc/includes.h @@ -0,0 +1,40 @@ +//////////////////////////////////////////////////////////////////// +// +// Output include file directives. +// + +output header {{ +#include +#include +#include + +#include "cpu/static_inst.hh" +#include "traps.hh" +#include "mem/mem_req.hh" // some constructors use MemReq flags +}}; + +output decoder {{ +#include "base/cprintf.hh" +#include "base/loader/symtab.hh" +#include "cpu/exec_context.hh" // for Jump::branchTarget() + +#include +#if defined(linux) +#include +#endif +}}; + +output exec {{ +#include +#if defined(linux) +#include +#endif + +#ifdef FULL_SYSTEM +//#include "arch/alpha/pseudo_inst.hh" +#endif +#include "cpu/base.hh" +#include "cpu/exetrace.hh" +#include "sim/sim_exit.hh" +}}; + diff --git a/arch/sparc/isa_desc/isa_desc b/arch/sparc/isa_desc/isa_desc new file mode 100644 index 000000000..1a5cc4a56 --- /dev/null +++ b/arch/sparc/isa_desc/isa_desc @@ -0,0 +1,61 @@ +// -*- mode:c++ -*- + +//Copyright (c) 2003, 2004, 2005 +//The Regents of The University of Michigan +//All Rights Reserved + +//This code is part of the M5 simulator, developed by Nathan Binkert, +//Erik Hallnor, Steve Raasch, and Steve Reinhardt, with contributions +//from Ron Dreslinski, Dave Greene, Lisa Hsu, Kevin Lim, Ali Saidi, +//and Andrew Schultz. + +//Permission is granted to use, copy, create derivative works and +//redistribute this software and such derivative works for any purpose, +//so long as the copyright notice above, this grant of permission, and +//the disclaimer below appear in all copies made; and so long as the +//name of The University of Michigan is not used in any advertising or +//publicity pertaining to the use or distribution of this software +//without specific, written prior authorization. + +//THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION FROM THE +//UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY PURPOSE, AND WITHOUT +//WARRANTY BY THE UNIVERSITY OF MICHIGAN OF ANY KIND, EITHER EXPRESS OR +//IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED WARRANTIES OF +//MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE REGENTS OF +//THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE FOR ANY DAMAGES, +//INCLUDING DIRECT, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +//DAMAGES, WITH RESPECT TO ANY CLAIM ARISING OUT OF OR IN CONNECTION +//WITH THE USE OF THE SOFTWARE, EVEN IF IT HAS BEEN OR IS HEREAFTER +//ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +//////////////////////////////////////////////////////////////////// +// +// SPARC ISA description file. +// +//////////////////////////////////////////////////////////////////// + +//Include the C++ include directives +##include "m5/arch/sparc/isa_desc/includes.h" + +//////////////////////////////////////////////////////////////////// +// +// Namespace statement. Everything below this line will be in the +// SparcISAInst namespace. +// + +namespace SparcISA; + +//Include the bitfield definitions +##include "m5/arch/sparc/isa_desc/bitfields.h" + +//Include the operand_types and operand definitions +##include "m5/arch/sparc/isa_desc/operands.h" + +//Include the base class for sparc instructions, and some support code +##include "m5/arch/sparc/isa_desc/base.h" + +//Include the definitions for the instruction formats +##include "m5/arch/sparc/isa_desc/formats.h" + +//Include the decoder definition +##include "m5/arch/sparc/isa_desc/decoder.h" diff --git a/arch/sparc/isa_desc/operands.h b/arch/sparc/isa_desc/operands.h new file mode 100644 index 000000000..77de6c9c4 --- /dev/null +++ b/arch/sparc/isa_desc/operands.h @@ -0,0 +1,33 @@ +def operand_types {{ + 'sb' : ('signed int', 8), + 'ub' : ('unsigned int', 8), + 'shw' : ('signed int', 16), + 'uhw' : ('unsigned int', 16), + 'sw' : ('signed int', 32), + 'uw' : ('unsigned int', 32), + 'sdw' : ('signed int', 64), + 'udw' : ('unsigned int', 64), + 'sf' : ('float', 32), + 'df' : ('float', 64), + 'qf' : ('float', 128) +}}; + +def operands {{ + # Int regs default to unsigned, but code should not count on this. + # For clarity, descriptions that depend on unsigned behavior should + # explicitly specify '.uq'. + 'Rd': IntRegOperandTraits('udw', 'RD', 'IsInteger', 1), + 'Rs1': IntRegOperandTraits('udw', 'RS1', 'IsInteger', 2), + 'Rs2': IntRegOperandTraits('udw', 'RS2', 'IsInteger', 3), + #'Fa': FloatRegOperandTraits('df', 'FA', 'IsFloating', 1), + #'Fb': FloatRegOperandTraits('df', 'FB', 'IsFloating', 2), + #'Fc': FloatRegOperandTraits('df', 'FC', 'IsFloating', 3), + 'Mem': MemOperandTraits('udw', None, + ('IsMemRef', 'IsLoad', 'IsStore'), 4) + #'NPC': NPCOperandTraits('uq', None, ( None, None, 'IsControl' ), 4), + #'Runiq': ControlRegOperandTraits('uq', 'Uniq', None, 1), + #'FPCR': ControlRegOperandTraits('uq', 'Fpcr', None, 1), + # The next two are hacks for non-full-system call-pal emulation + #'R0': IntRegOperandTraits('uq', '0', None, 1), + #'R16': IntRegOperandTraits('uq', '16', None, 1) +}}; diff --git a/arch/sparc/isa_traits.hh b/arch/sparc/isa_traits.hh new file mode 100644 index 000000000..9513b99fc --- /dev/null +++ b/arch/sparc/isa_traits.hh @@ -0,0 +1,528 @@ +/* + * Copyright (c) 2003-2005 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __ARCH_SPARC_ISA_TRAITS_HH__ +#define __ARCH_SPARC_ISA_TRAITS_HH__ + +#include "arch/sparc/faults.hh" +#include "base/misc.hh" +#include "sim/host.hh" + +class FastCPU; +//class FullCPU; +//class Checkpoint; + +#define TARGET_SPARC + +template class StaticInst; +template class StaticInstPtr; + +//namespace EV5 +//{ +// int DTB_ASN_ASN(uint64_t reg); +// int ITB_ASN_ASN(uint64_t reg); +//} + +class SPARCISA +{ + public: + + typedef uint32_t MachInst; + typedef uint64_t Addr; + typedef uint8_t RegIndex; + + enum + { + MemoryEnd = 0xffffffffffffffffULL, + + NumFloatRegs = 32, + NumMiscRegs = 32, + + MaxRegsOfAnyType = 32, + // Static instruction parameters + MaxInstSrcRegs = 3, + MaxInstDestRegs = 2, + + // Maximum trap level + MaxTL = 4 + + // semantically meaningful register indices + ZeroReg = 0, // architecturally meaningful + // the rest of these depend on the ABI + } + typedef uint64_t IntReg; + + class IntRegFile + { + private: + //For right now, let's pretend the register file is static + IntReg regs[32]; + public: + IntReg & operator [] (RegIndex index) + { + //Don't allow indexes outside of the 32 registers + index &= 0x1F + return regs[index]; + } + }; + + void inline serialize(std::ostream & os) + { + SERIALIZE_ARRAY(regs, 32); + } + + void inline unserialize(Checkpoint &*cp, const std::string §ion) + { + UNSERIALIZE_ARRAY(regs, 32); + } + + class FloatRegFile + { + private: + //By using the largest data type, we ensure everything + //is aligned correctly in memory + union + { + double double rawRegs[16]; + uint64_t regDump[32]; + }; + class QuadRegs + { + private: + FloatRegFile * parent; + public: + QuadRegs(FloatRegFile * p) : parent(p) {;} + double double & operator [] (RegIndex index) + { + //Quad floats are index by the single + //precision register the start on, + //and only 16 should be accessed + index = (index >> 2) & 0xF; + return parent->rawRegs[index]; + } + }; + class DoubleRegs + { + private: + FloatRegFile * parent; + public: + DoubleRegs(FloatRegFile * p) : parent(p) {;} + double & operator [] (RegIndex index) + { + //Double floats are index by the single + //precision register the start on, + //and only 32 should be accessed + index = (index >> 1) & 0x1F + return ((double [])parent->rawRegs)[index]; + } + } + class SingleRegs + { + private: + FloatRegFile * parent; + public: + SingleRegs(FloatRegFile * p) : parent(p) {;} + double & operator [] (RegFile index) + { + //Only 32 single floats should be accessed + index &= 0x1F + return ((float [])parent->rawRegs)[index]; + } + } + public: + void inline serialize(std::ostream & os) + { + SERIALIZE_ARRAY(regDump, 32); + } + + void inline unserialize(Checkpoint &* cp, std::string & section) + { + UNSERIALIZE_ARRAY(regDump, 32); + } + + QuadRegs quadRegs; + DoubleRegs doubleRegs; + SingleRegs singleRegs; + FloatRegFile() : quadRegs(this), doubleRegs(this), singleRegs(this) + {;} + }; + + // control register file contents + typedef uint64_t MiscReg; + // The control registers, broken out into fields + class MiscRegFile + { + public: + union + { + uint16_t pstate; // Process State Register + struct + { + uint16_t ag:1; // Alternate Globals + uint16_t ie:1; // Interrupt enable + uint16_t priv:1; // Privelege mode + uint16_t am:1; // Address mask + uint16_t pef:1; // PSTATE enable floating-point + uint16_t red:1; // RED (reset, error, debug) state + uint16_t mm:2; // Memory Model + uint16_t tle:1; // Trap little-endian + uint16_t cle:1; // Current little-endian + } pstateFields; + } + uint64_t tba; // Trap Base Address + union + { + uint64_t y; // Y (used in obsolete multiplication) + struct + { + uint64_t value:32; // The actual value stored in y + const uint64_t :32; // reserved bits + } yFields; + } + uint8_t pil; // Process Interrupt Register + uint8_t cwp; // Current Window Pointer + uint16_t tt[MaxTL]; // Trap Type (Type of trap which occured on the previous level) + union + { + uint8_t ccr; // Condition Code Register + struct + { + union + { + uint8_t icc:4; // 32-bit condition codes + struct + { + uint8_t c:1; // Carry + uint8_t v:1; // Overflow + uint8_t z:1; // Zero + uint8_t n:1; // Negative + } iccFields:4; + } :4; + union + { + uint8_t xcc:4; // 64-bit condition codes + struct + { + uint8_t c:1; // Carry + uint8_t v:1; // Overflow + uint8_t z:1; // Zero + uint8_t n:1; // Negative + } xccFields:4; + } :4; + } ccrFields; + } + uint8_t asi; // Address Space Identifier + uint8_t tl; // Trap Level + uint64_t tpc[MaxTL]; // Trap Program Counter (value from previous trap level) + uint64_t tnpc[MaxTL]; // Trap Next Program Counter (value from previous trap level) + union + { + uint64_t tstate[MaxTL]; // Trap State + struct + { + //Values are from previous trap level + uint64_t cwp:5; // Current Window Pointer + const uint64_t :2; // Reserved bits + uint64_t pstate:10; // Process State + const uint64_t :6; // Reserved bits + uint64_t asi:8; // Address Space Identifier + uint64_t ccr:8; // Condition Code Register + } tstateFields[MaxTL]; + } + union + { + uint64_t tick; // Hardware clock-tick counter + struct + { + uint64_t counter:63; // Clock-tick count + uint64_t npt:1; // Non-priveleged trap + } tickFields; + } + uint8_t cansave; // Savable windows + uint8_t canrestore; // Restorable windows + uint8_t otherwin; // Other windows + uint8_t cleanwin; // Clean windows + union + { + uint8_t wstate; // Window State + struct + { + uint8_t normal:3; // Bits TT<4:2> are set to on a normal + // register window trap + uint8_t other:3; // Bits TT<4:2> are set to on an "otherwin" + // register window trap + } wstateFields; + } + union + { + uint64_t ver; // Version + struct + { + uint64_t maxwin:5; // Max CWP value + const uint64_t :2; // Reserved bits + uint64_t maxtl:8; // Maximum trap level + const uint64_t :8; // Reserved bits + uint64_t mask:8; // Processor mask set revision number + uint64_t impl:16; // Implementation identification number + uint64_t manuf:16; // Manufacturer code + } verFields; + } + union + { + uint64_t fsr; // Floating-Point State Register + struct + { + union + { + uint64_t cexc:5; // Current excpetion + struct + { + uint64_t nxc:1; // Inexact + uint64_t dzc:1; // Divide by zero + uint64_t ufc:1; // Underflow + uint64_t ofc:1; // Overflow + uint64_t nvc:1; // Invalid operand + } cexecFields:5; + } :5; + union + { + uint64_t aexc:5; // Accrued exception + struct + { + uint64_t nxc:1; // Inexact + uint64_t dzc:1; // Divide by zero + uint64_t ufc:1; // Underflow + uint64_t ofc:1; // Overflow + uint64_t nvc:1; // Invalid operand + } aexecFields:5; + } :5; + uint64_t fcc0:2; // Floating-Point condtion codes + const uint64_t :1; // Reserved bits + uint64_t qne:1; // Deferred trap queue not empty + // with no queue, it should read 0 + uint64_t ftt:3; // Floating-Point trap type + uint64_t ver:3; // Version (of the FPU) + const uint64_t :2; // Reserved bits + uint64_t ns:1; // Nonstandard floating point + union + { + uint64_t tem:5; // Trap Enable Mask + struct + { + uint64_t nxm:1; // Inexact + uint64_t dzm:1; // Divide by zero + uint64_t ufm:1; // Underflow + uint64_t ofm:1; // Overflow + uint64_t nvm:1; // Invalid operand + } temFields:5; + } :5; + const uint64_t :2; // Reserved bits + uint64_t rd:2; // Rounding direction + uint64_t fcc1:2; // Floating-Point condition codes + uint64_t fcc2:2; // Floating-Point condition codes + uint64_t fcc3:2; // Floating-Point condition codes + const uint64_t :26; // Reserved bits + } fsrFields; + } + union + { + uint8_t fprs; // Floating-Point Register State + struct + { + dl:1; // Dirty lower + du:1; // Dirty upper + fef:1; // FPRS enable floating-Point + } fprsFields; + }; + + void serialize(std::ostream & os) + { + SERIALIZE_SCALAR(pstate); + SERIAlIZE_SCALAR(tba); + SERIALIZE_SCALAR(y); + SERIALIZE_SCALAR(pil); + SERIALIZE_SCALAR(cwp); + SERIALIZE_ARRAY(tt, MaxTL); + SERIALIZE_SCALAR(ccr); + SERIALIZE_SCALAR(asi); + SERIALIZE_SCALAR(tl); + SERIALIZE_SCALAR(tpc); + SERIALIZE_SCALAR(tnpc); + SERIALIZE_ARRAY(tstate, MaxTL); + SERIALIZE_SCALAR(tick); + SERIALIZE_SCALAR(cansave); + SERIALIZE_SCALAR(canrestore); + SERIALIZE_SCALAR(otherwin); + SERIALIZE_SCALAR(cleanwin); + SERIALIZE_SCALAR(wstate); + SERIALIZE_SCALAR(ver); + SERIALIZE_SCALAR(fsr); + SERIALIZE_SCALAR(fprs); + } + + void unserialize(Checkpoint &* cp, std::string & section) + { + UNSERIALIZE_SCALAR(pstate); + UNSERIAlIZE_SCALAR(tba); + UNSERIALIZE_SCALAR(y); + UNSERIALIZE_SCALAR(pil); + UNSERIALIZE_SCALAR(cwp); + UNSERIALIZE_ARRAY(tt, MaxTL); + UNSERIALIZE_SCALAR(ccr); + UNSERIALIZE_SCALAR(asi); + UNSERIALIZE_SCALAR(tl); + UNSERIALIZE_SCALAR(tpc); + UNSERIALIZE_SCALAR(tnpc); + UNSERIALIZE_ARRAY(tstate, MaxTL); + UNSERIALIZE_SCALAR(tick); + UNSERIALIZE_SCALAR(cansave); + UNSERIALIZE_SCALAR(canrestore); + UNSERIALIZE_SCALAR(otherwin); + UNSERIALIZE_SCALAR(cleanwin); + UNSERIALIZE_SCALAR(wstate); + UNSERIALIZE_SCALAR(ver); + UNSERIALIZE_SCALAR(fsr); + UNSERIALIZE_SCALAR(fprs); + } + }; + + typedef union + { + IntReg intreg; + FloatReg fpreg; + MiscReg ctrlreg; + } AnyReg; + + struct RegFile + { + IntRegFile intRegFile; // (signed) integer register file + FloatRegFile floatRegFile; // floating point register file + MiscRegFile miscRegFile; // control register file + + Addr pc; // Program Counter + Addr npc; // Next Program Counter + + void serialize(std::ostream &os); + void unserialize(Checkpoint *cp, const std::string §ion); + }; + + static StaticInstPtr decodeInst(MachInst); + + // return a no-op instruction... used for instruction fetch faults + static const MachInst NoopMachInst; + + // Instruction address compression hooks + static inline Addr realPCToFetchPC(const Addr &addr) + { + return addr; + } + + static inline Addr fetchPCToRealPC(const Addr &addr) + { + return addr; + } + + // the size of "fetched" instructions (not necessarily the size + // of real instructions for PISA) + static inline size_t fetchInstSize() + { + return sizeof(MachInst); + } + + /** + * Function to insure ISA semantics about 0 registers. + * @param xc The execution context. + */ + template + static void zeroRegisters(XC *xc); +}; + + +typedef SPARCISA TheISA; + +typedef TheISA::MachInst MachInst; +typedef TheISA::Addr Addr; +typedef TheISA::RegIndex RegIndex; +typedef TheISA::IntReg IntReg; +typedef TheISA::IntRegFile IntRegFile; +typedef TheISA::FloatReg FloatReg; +typedef TheISA::FloatRegFile FloatRegFile; +typedef TheISA::MiscReg MiscReg; +typedef TheISA::MiscRegFile MiscRegFile; +typedef TheISA::AnyReg AnyReg; +typedef TheISA::RegFile RegFile; + +const int VMPageSize = TheISA::VMPageSize; +const int LogVMPageSize = TheISA::LogVMPageSize; +const int ZeroReg = TheISA::ZeroReg; +const int BranchPredAddrShiftAmt = TheISA::BranchPredAddrShiftAmt; +const int MaxAddr = (Addr)-1; + +#ifndef FULL_SYSTEM +class SyscallReturn { + public: + template + SyscallReturn(T v, bool s) + { + retval = (uint64_t)v; + success = s; + } + + template + SyscallReturn(T v) + { + success = (v >= 0); + retval = (uint64_t)v; + } + + ~SyscallReturn() {} + + SyscallReturn& operator=(const SyscallReturn& s) { + retval = s.retval; + success = s.success; + return *this; + } + + bool successful() { return success; } + uint64_t value() { return retval; } + + + private: + uint64_t retval; + bool success; +}; + +#endif + + +#ifdef FULL_SYSTEM + +#include "arch/alpha/ev5.hh" +#endif + +#endif // __ARCH_SPARC_ISA_TRAITS_HH__ From ad1e46203b2355af86d183c2d89a39a3ee29c72b Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Mon, 30 Jan 2006 14:32:00 -0500 Subject: [PATCH 010/180] Make the M5 Emacs C style default to inserting spaces instead of tabs so using different editors is consistent util/emacs/m5-c-style.el: Default to inserting spaces instead of tabs so using different editors is consistent --HG-- extra : convert_revision : 719e5e980e088b0f4787b198de18cddceabd0140 --- util/emacs/m5-c-style.el | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/util/emacs/m5-c-style.el b/util/emacs/m5-c-style.el index b9d16a4b1..9578e3dbe 100644 --- a/util/emacs/m5-c-style.el +++ b/util/emacs/m5-c-style.el @@ -1,4 +1,4 @@ -; Copyright (c) 2003-2004 The Regents of The University of Michigan +; Copyright (c) 2003-2004, 2006 The Regents of The University of Michigan ; All rights reserved. ; ; Redistribution and use in source and binary forms, with or without @@ -29,6 +29,7 @@ (c-add-style "m5" '((c-basic-offset . 4) + (indent-tabs-mode . nil) (c-offsets-alist . ((substatement-open . 0) (inline-open . 0) (block-open . -4) From 993934f4cbf8880dfb4906bec8a84a4f3ed380ac Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Tue, 31 Jan 2006 13:52:23 -0500 Subject: [PATCH 011/180] Add a scaner for .isa files. Ordering it turns out is rather important here, so it has to be defined before the rule to that calls isa_parser.py --HG-- extra : convert_revision : dbba3c7ee71ca8ca1fcbf5ee65ae83b4ecb63649 --- SConscript | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/SConscript b/SConscript index 7ea1e7638..5b4361298 100644 --- a/SConscript +++ b/SConscript @@ -384,6 +384,25 @@ if env['USE_MYSQL']: for opt in env.ExportOptions: env.ConfigFile(opt) +################################################### +# +# Add an SCons scanner for ISA files +# +################################################### +def ISAScan(): + return SCons.Scanner.Classic("ISAScan", + "$ISASUFFIXES", + "SRCDIR", + '^[ \t]*##[ \t]*include[ \t]*"([^>"]+)"') + +def ISAPath(env, dir, a=None): + return (Dir(env['SRCDIR']), Dir('.')) + +iscan = Scanner(function = ISAScan().scan, skeys = [".isa", ".ISA"], + path_function = ISAPath) +env.Append(SCANNERS = iscan) + + ################################################### # # Special build rules. From a236a3ade7a59d6708fc1c59e88e94b6c6b59ce6 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Wed, 1 Feb 2006 13:13:05 -0500 Subject: [PATCH 012/180] Fix a mistake, need to import SCons.Scanner --HG-- extra : convert_revision : c6b15c162e9826c6c00dbbf52fb8aa8819d56c23 --- SConscript | 2 ++ 1 file changed, 2 insertions(+) diff --git a/SConscript b/SConscript index 5b4361298..98dfad217 100644 --- a/SConscript +++ b/SConscript @@ -389,6 +389,8 @@ for opt in env.ExportOptions: # Add an SCons scanner for ISA files # ################################################### +import SCons.Scanner + def ISAScan(): return SCons.Scanner.Classic("ISAScan", "$ISASUFFIXES", From 2939a7089ad89e38b24f96143dbd3c4292ac0287 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 3 Feb 2006 00:16:44 -0500 Subject: [PATCH 013/180] byte_swap.hh was removed from arch/alpha/, and replaced by sim/byteswap.hh. The new file uses LittleEndianGuest and BigEndianGuest namespaces to allow selecting the appropriate functions. arch/alpha/alpha_linux_process.cc: arch/alpha/alpha_tru64_process.cc: Added the endianness namespace. This may change. cpu/exec_context.hh: Changed the include path for byteswap, and forced LittleEndianness for lack of a better solution. cpu/o3/alpha_cpu.hh: Forced LittleEndianness, for lack of a better solution. cpu/o3/alpha_cpu_impl.hh: Cleared away some commented out code. cpu/o3/fetch_impl.hh: Changed the include patch for byteswap, and forced LittleEndianness for lack of a better solution. cpu/simple/cpu.cc: Added an include for byteswap.hh, and fixed the SimpleCPU to LittleEndian. This cpu only does alpha, so that's fine. dev/disk_image.cc: Changed the include path of byteswap.hh kern/freebsd/freebsd_system.cc: kern/linux/linux_system.cc: Added an include for byteswap.hh, and forced LittleEndianness for lack of a better solution. sim/system.cc: Forced LittleEndianness for lack of a better solution. --HG-- extra : convert_revision : b95d3e1265a825e04bd77622a3ac09fbac6bd206 --- arch/alpha/alpha_linux_process.cc | 3 + arch/alpha/alpha_tru64_process.cc | 3 + cpu/exec_context.hh | 6 +- cpu/o3/alpha_cpu.hh | 4 +- cpu/o3/alpha_cpu_impl.hh | 3 - cpu/o3/fetch_impl.hh | 4 +- cpu/simple/cpu.cc | 3 + dev/disk_image.cc | 2 +- kern/freebsd/freebsd_system.cc | 5 +- kern/linux/linux_system.cc | 3 +- sim/byteswap.hh | 141 ++++++++++++++++++++++++++++++ sim/system.cc | 6 +- 12 files changed, 166 insertions(+), 17 deletions(-) create mode 100644 sim/byteswap.hh diff --git a/arch/alpha/alpha_linux_process.cc b/arch/alpha/alpha_linux_process.cc index 83b0b5e5a..16cbf3841 100644 --- a/arch/alpha/alpha_linux_process.cc +++ b/arch/alpha/alpha_linux_process.cc @@ -26,6 +26,9 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +namespace LittleEndian {} +using namespace LittleEndian; + #include #include #include // for host open() flags diff --git a/arch/alpha/alpha_tru64_process.cc b/arch/alpha/alpha_tru64_process.cc index b7a1c7d59..d57054dfd 100644 --- a/arch/alpha/alpha_tru64_process.cc +++ b/arch/alpha/alpha_tru64_process.cc @@ -26,6 +26,9 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +namespace LittleEndian {} +using namespace LittleEndian; + #include #include #if defined(__OpenBSD__) diff --git a/cpu/exec_context.hh b/cpu/exec_context.hh index 6f38a6960..2bde053b2 100644 --- a/cpu/exec_context.hh +++ b/cpu/exec_context.hh @@ -34,7 +34,7 @@ #include "mem/mem_req.hh" #include "sim/host.hh" #include "sim/serialize.hh" -#include "targetarch/byte_swap.hh" +#include "sim/byteswap.hh" // forward declaration: see functional_memory.hh class FunctionalMemory; @@ -269,7 +269,7 @@ class ExecContext Fault error; error = mem->read(req, data); - data = gtoh(data); + data = LittleEndianGuest::gtoh(data); return error; } @@ -319,7 +319,7 @@ class ExecContext } #endif - return mem->write(req, (T)htog(data)); + return mem->write(req, (T)LittleEndianGuest::htog(data)); } virtual bool misspeculating(); diff --git a/cpu/o3/alpha_cpu.hh b/cpu/o3/alpha_cpu.hh index cba57d189..164da4968 100644 --- a/cpu/o3/alpha_cpu.hh +++ b/cpu/o3/alpha_cpu.hh @@ -220,7 +220,7 @@ class AlphaFullCPU : public FullO3CPU Fault error; error = this->mem->read(req, data); - data = gtoh(data); + data = LittleEndianGuest::gtoh(data); return error; } @@ -277,7 +277,7 @@ class AlphaFullCPU : public FullO3CPU #endif - return this->mem->write(req, (T)htog(data)); + return this->mem->write(req, (T)LittleEndianGuest::htog(data)); } template diff --git a/cpu/o3/alpha_cpu_impl.hh b/cpu/o3/alpha_cpu_impl.hh index 2a764740b..3b16975a9 100644 --- a/cpu/o3/alpha_cpu_impl.hh +++ b/cpu/o3/alpha_cpu_impl.hh @@ -42,9 +42,6 @@ #if FULL_SYSTEM #include "arch/alpha/osfpal.hh" #include "arch/alpha/isa_traits.hh" -//#include "arch/alpha/ev5.hh" - -//using namespace EV5; #endif template diff --git a/cpu/o3/fetch_impl.hh b/cpu/o3/fetch_impl.hh index c943fd36a..1a8411cc1 100644 --- a/cpu/o3/fetch_impl.hh +++ b/cpu/o3/fetch_impl.hh @@ -30,7 +30,7 @@ #define OPCODE(X) (X >> 26) & 0x3f -#include "arch/alpha/byte_swap.hh" +#include "sim/byteswap.hh" #include "cpu/exetrace.hh" #include "mem/base_mem.hh" #include "mem/mem_interface.hh" @@ -535,7 +535,7 @@ SimpleFetch::fetch() assert(offset <= cacheBlkSize - instSize); // Get the instruction from the array of the cache line. - inst = gtoh(*reinterpret_cast + inst = LittleEndianGuest::gtoh(*reinterpret_cast (&cacheData[offset])); // Create a new DynInst from the instruction fetched. diff --git a/cpu/simple/cpu.cc b/cpu/simple/cpu.cc index a7f4fa499..70217f0bb 100644 --- a/cpu/simple/cpu.cc +++ b/cpu/simple/cpu.cc @@ -54,6 +54,7 @@ #include "kern/kernel_stats.hh" #include "mem/base_mem.hh" #include "mem/mem_interface.hh" +#include "sim/byteswap.hh" #include "sim/builder.hh" #include "sim/debug.hh" #include "sim/host.hh" @@ -74,6 +75,8 @@ #endif // FULL_SYSTEM using namespace std; +//The SimpleCPU does alpha only +using namespace LittleEndianGuest; SimpleCPU::TickEvent::TickEvent(SimpleCPU *c, int w) diff --git a/dev/disk_image.cc b/dev/disk_image.cc index 106723c55..447c54697 100644 --- a/dev/disk_image.cc +++ b/dev/disk_image.cc @@ -46,7 +46,7 @@ #include "dev/disk_image.hh" #include "sim/builder.hh" #include "sim/sim_exit.hh" -#include "targetarch/byte_swap.hh" +#include "sim/byteswap.hh" using namespace std; diff --git a/kern/freebsd/freebsd_system.cc b/kern/freebsd/freebsd_system.cc index 283713d40..f3fe84e00 100644 --- a/kern/freebsd/freebsd_system.cc +++ b/kern/freebsd/freebsd_system.cc @@ -39,6 +39,7 @@ #include "mem/functional/memory_control.hh" #include "mem/functional/physical.hh" #include "sim/builder.hh" +#include "sim/byteswap.hh" #include "targetarch/vtophys.hh" #define TIMER_FREQUENCY 1193180 @@ -82,8 +83,8 @@ FreebsdSystem::doCalibrateClocks(ExecContext *xc) uint8_t *ppc = physmem->dma_addr(ppc_paddr, sizeof(uint32_t)); uint8_t *timer = physmem->dma_addr(timer_paddr, sizeof(uint32_t)); - *(uint32_t *)ppc = htog((uint32_t)Clock::Frequency); - *(uint32_t *)timer = htog((uint32_t)TIMER_FREQUENCY); + *(uint32_t *)ppc = LittleEndianGuest::htog((uint32_t)Clock::Frequency); + *(uint32_t *)timer = LittleEndianGuest::htog((uint32_t)TIMER_FREQUENCY); } diff --git a/kern/linux/linux_system.cc b/kern/linux/linux_system.cc index 1144b9bdd..26a4c0d3e 100644 --- a/kern/linux/linux_system.cc +++ b/kern/linux/linux_system.cc @@ -44,6 +44,7 @@ #include "mem/functional/memory_control.hh" #include "mem/functional/physical.hh" #include "sim/builder.hh" +#include "sim/byteswap.hh" #include "dev/platform.hh" #include "targetarch/arguments.hh" #include "targetarch/vtophys.hh" @@ -100,7 +101,7 @@ LinuxSystem::LinuxSystem(Params *p) char *dp264_mv = (char *)physmem->dma_addr(paddr, sizeof(uint64_t)); if (dp264_mv) { - *(uint32_t*)(dp264_mv+0x18) = htog((uint32_t)127); + *(uint32_t*)(dp264_mv+0x18) = LittleEndianGuest::htog((uint32_t)127); } else panic("could not translate dp264_mv addr\n"); diff --git a/sim/byteswap.hh b/sim/byteswap.hh new file mode 100644 index 000000000..12d63b6b6 --- /dev/null +++ b/sim/byteswap.hh @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2004 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. + */ + +//The purpose of this file is to provide endainness conversion utility +//functions. Depending on the endianness of the guest system, either +//the LittleEndianGuest or BigEndianGuest namespace is used. + +#ifndef __SIM_BYTE_SWAP_HH__ +#define __SIM_BYTE_SWAP_HH__ + +#include "sim/host.hh" + +// This lets us figure out what the byte order of the host system is +#if defined(linux) +#include +#else +#include +#endif + +//These functions actually perform the swapping for parameters +//of various bit lengths +static inline uint64_t +swap_byte64(uint64_t x) +{ + return (uint64_t)((((uint64_t)(x) & 0xff) << 56) | + ((uint64_t)(x) & 0xff00ULL) << 40 | + ((uint64_t)(x) & 0xff0000ULL) << 24 | + ((uint64_t)(x) & 0xff000000ULL) << 8 | + ((uint64_t)(x) & 0xff00000000ULL) >> 8 | + ((uint64_t)(x) & 0xff0000000000ULL) >> 24 | + ((uint64_t)(x) & 0xff000000000000ULL) >> 40 | + ((uint64_t)(x) & 0xff00000000000000ULL) >> 56) ; +} + +static inline uint32_t +swap_byte32(uint32_t x) +{ + return (uint32_t)(((uint32_t)(x) & 0xff) << 24 | + ((uint32_t)(x) & 0xff00) << 8 | ((uint32_t)(x) & 0xff0000) >> 8 | + ((uint32_t)(x) & 0xff000000) >> 24); + +} + +static inline uint16_t +swap_byte16(uint16_t x) +{ + return (uint16_t)(((uint16_t)(x) & 0xff) << 8 | + ((uint16_t)(x) & 0xff00) >> 8); +} + +//This lets the compiler figure out how to call the swap_byte functions above +//for different data types. +static inline uint64_t swap_byte(uint64_t x) {return swap_byte64(x);} \ +static inline int64_t swap_byte(int64_t x) {return swap_byte64((uint64_t)x);} \ +static inline uint32_t swap_byte(uint32_t x) {return swap_byte32(x);} \ +static inline int32_t swap_byte(int32_t x) {return swap_byte32((uint32_t)x);} \ +static inline uint16_t swap_byte(uint16_t x) {return swap_byte32(x);} \ +static inline int16_t swap_byte(int16_t x) {return swap_byte16((uint16_t)x);} \ +static inline uint8_t swap_byte(uint8_t x) {return x;} \ +static inline int8_t swap_byte(int8_t x) {return x;} \ +static inline double swap_byte(double x) {return swap_byte64((uint64_t)x);} \ +static inline float swap_byte(float x) {return swap_byte32((uint32_t)x);} + +//The conversion functions with fixed endianness on both ends don't need to +//be in a namespace +template static inline T betole(T value) {return swap_byte(value);} +template static inline T letobe(T value) {return swap_byte(value);} + +//For conversions not involving the guest system, we can define the functions +//conditionally based on the BYTE_ORDER macro and outside of the namespaces +#if BYTE_ORDER == BIG_ENDIAN +template static inline T htole(T value) {return swap_byte(value);} +template static inline T letoh(T value) {return swap_byte(value);} +template static inline T htobe(T value) {return value;} +template static inline T betoh(T value) {return value;} +#elif BYTE_ORDER == LITTLE_ENDIAN +template static inline T htole(T value) {return value;} +template static inline T letoh(T value) {return value;} +template static inline T htobe(T value) {return swap_byte(value);} +template static inline T betoh(T value) {return swap_byte(value);} +#else + #error Invalid Endianess +#endif + +namespace BigEndianGuest +{ + template + static inline T gtole(T value) {return betole(value);} + template + static inline T letog(T value) {return letobe(value);} + template + static inline T gtobe(T value) {return value;} + template + static inline T betog(T value) {return value;} + template + static inline T htog(T value) {return htobe(value);} + template + static inline T gtoh(T value) {return betoh(value);} +} + +namespace LittleEndianGuest +{ + template + static inline T gtole(T value) {return value;} + template + static inline T letog(T value) {return value;} + template + static inline T gtobe(T value) {return letobe(value);} + template + static inline T betog(T value) {return betole(value);} + template + static inline T htog(T value) {return htole(value);} + template + static inline T gtoh(T value) {return letoh(value);} +} +#endif // __SIM_BYTE_SWAP_HH__ diff --git a/sim/system.cc b/sim/system.cc index 4bcc89c56..a69bf27f1 100644 --- a/sim/system.cc +++ b/sim/system.cc @@ -152,8 +152,8 @@ System::System(Params *p) if (!hwrpb) panic("could not translate hwrpb addr\n"); - *(uint64_t*)(hwrpb+0x50) = htog(params->system_type); - *(uint64_t*)(hwrpb+0x58) = htog(params->system_rev); + *(uint64_t*)(hwrpb+0x50) = LittleEndianGuest::htog(params->system_type); + *(uint64_t*)(hwrpb+0x58) = LittleEndianGuest::htog(params->system_rev); } else panic("could not find hwrpb\n"); @@ -249,7 +249,7 @@ System::setAlphaAccess(Addr access) if (!m5AlphaAccess) panic("could not translate m5AlphaAccess addr\n"); - *m5AlphaAccess = htog(EV5::Phys2K0Seg(access)); + *m5AlphaAccess = LittleEndianGuest::htog(EV5::Phys2K0Seg(access)); } else panic("could not find m5AlphaAccess\n"); } From f7a75d872b4bf94aafcfcb5f773afda75f7c3499 Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Fri, 3 Feb 2006 03:38:27 -0500 Subject: [PATCH 014/180] Checkin (Merge?) files ... Added a few new format files arch/mips/isa/formats/fpop.format: Floating Point Formats arch/mips/isa/formats/tlb.format: TLB Ops Format arch/mips/isa/mips.isa: Name change to mips.isa --HG-- rename : arch/mips/isa_desc/bitfields.h => arch/mips/isa/bitfields.h rename : arch/mips/isa_desc/decoder.h => arch/mips/isa/decoder.h rename : arch/mips/isa_desc/formats.h => arch/mips/isa/formats.h rename : arch/mips/isa_desc/formats/basic.format => arch/mips/isa/formats/basic.format rename : arch/mips/isa_desc/formats/branch.format => arch/mips/isa/formats/branch.format rename : arch/mips/isa_desc/formats/integerop.format => arch/mips/isa/formats/integerop.format rename : arch/mips/isa_desc/formats/mem.format => arch/mips/isa/formats/mem.format rename : arch/mips/isa_desc/formats/noop.format => arch/mips/isa/formats/noop.format rename : arch/mips/isa_desc/formats/trap.format => arch/mips/isa/formats/trap.format rename : arch/mips/isa_desc/includes.h => arch/mips/isa/includes.h rename : arch/mips/isa_desc/operands.h => arch/mips/isa/operands.h extra : convert_revision : 069a24da405b613f688e693fd038ac7a30a4faed --- arch/mips/{isa_desc => isa}/bitfields.h | 0 arch/mips/{isa_desc => isa}/decoder.h | 0 arch/mips/{isa_desc => isa}/formats.h | 0 .../{isa_desc => isa}/formats/basic.format | 0 .../{isa_desc => isa}/formats/branch.format | 0 arch/mips/isa/formats/fpop.format | 110 ++++++++++++++++++ .../formats/integerop.format | 0 .../mips/{isa_desc => isa}/formats/mem.format | 0 .../{isa_desc => isa}/formats/noop.format | 0 arch/mips/isa/formats/tlb.format | 53 +++++++++ .../{isa_desc => isa}/formats/trap.format | 0 arch/mips/{isa_desc => isa}/includes.h | 0 arch/mips/isa/mips.isa | 52 +++++++++ arch/mips/{isa_desc => isa}/operands.h | 0 14 files changed, 215 insertions(+) rename arch/mips/{isa_desc => isa}/bitfields.h (100%) rename arch/mips/{isa_desc => isa}/decoder.h (100%) rename arch/mips/{isa_desc => isa}/formats.h (100%) rename arch/mips/{isa_desc => isa}/formats/basic.format (100%) rename arch/mips/{isa_desc => isa}/formats/branch.format (100%) create mode 100644 arch/mips/isa/formats/fpop.format rename arch/mips/{isa_desc => isa}/formats/integerop.format (100%) rename arch/mips/{isa_desc => isa}/formats/mem.format (100%) rename arch/mips/{isa_desc => isa}/formats/noop.format (100%) create mode 100644 arch/mips/isa/formats/tlb.format rename arch/mips/{isa_desc => isa}/formats/trap.format (100%) rename arch/mips/{isa_desc => isa}/includes.h (100%) create mode 100644 arch/mips/isa/mips.isa rename arch/mips/{isa_desc => isa}/operands.h (100%) diff --git a/arch/mips/isa_desc/bitfields.h b/arch/mips/isa/bitfields.h similarity index 100% rename from arch/mips/isa_desc/bitfields.h rename to arch/mips/isa/bitfields.h diff --git a/arch/mips/isa_desc/decoder.h b/arch/mips/isa/decoder.h similarity index 100% rename from arch/mips/isa_desc/decoder.h rename to arch/mips/isa/decoder.h diff --git a/arch/mips/isa_desc/formats.h b/arch/mips/isa/formats.h similarity index 100% rename from arch/mips/isa_desc/formats.h rename to arch/mips/isa/formats.h diff --git a/arch/mips/isa_desc/formats/basic.format b/arch/mips/isa/formats/basic.format similarity index 100% rename from arch/mips/isa_desc/formats/basic.format rename to arch/mips/isa/formats/basic.format diff --git a/arch/mips/isa_desc/formats/branch.format b/arch/mips/isa/formats/branch.format similarity index 100% rename from arch/mips/isa_desc/formats/branch.format rename to arch/mips/isa/formats/branch.format diff --git a/arch/mips/isa/formats/fpop.format b/arch/mips/isa/formats/fpop.format new file mode 100644 index 000000000..a058eea19 --- /dev/null +++ b/arch/mips/isa/formats/fpop.format @@ -0,0 +1,110 @@ +//////////////////////////////////////////////////////////////////// +// +// Floating Point operate instructions +// + +output header {{ + /** + * Base class for integer operations. + */ + class FPOp : public MipsStaticInst + { + protected: + + /// Constructor + FPOp(const char *mnem, MachInst _machInst, OpClass __opClass) : MipsStaticInst(mnem, _machInst, __opClass) + { + } + + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; + }; +}}; + +output decoder {{ + std::string FPOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const + { + return "Disassembly of integer instruction\n"; + } +}}; + +def template IntegerExecute {{ + Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const + { + //These are set to constants when the execute method + //is generated + bool useCc = ; + bool checkPriv = ; + + //Attempt to execute the instruction + try + { + checkPriv; + + %(op_decl)s; + %(op_rd)s; + %(code)s; + } + //If we have an exception for some reason, + //deal with it + catch(MipsException except) + { + //Deal with exception + return No_Fault; + } + + //Write the resulting state to the execution context + %(op_wb)s; + if(useCc) + { + xc->regs.miscRegFile.ccrFields.iccFields.n = Rd & (1 << 63); + xc->regs.miscRegFile.ccrFields.iccFields.z = (Rd == 0); + xc->regs.miscRegFile.ccrFields.iccFields.v = ivValue; + xc->regs.miscRegFile.ccrFields.iccFields.c = icValue; + xc->regs.miscRegFile.ccrFields.xccFields.n = Rd & (1 << 31); + xc->regs.miscRegFile.ccrFields.xccFields.z = ((Rd & 0xFFFFFFFF) == 0); + xc->regs.miscRegFile.ccrFields.xccFields.v = xvValue; + xc->regs.miscRegFile.ccrFields.xccFields.c = xcValue; + } + return No_Fault; + } +}}; + +// Primary format for integer operate instructions: +def format FPOp(code, *opt_flags) {{ + orig_code = code + cblk = CodeBlock(code) + checkPriv = (code.find('checkPriv') != -1) + code.replace('checkPriv', '') + if checkPriv: + code.replace('checkPriv;', 'if(!xc->regs.miscRegFile.pstateFields.priv) throw privileged_opcode;') + else: + code.replace('checkPriv;', '') + for (marker, value) in (('ivValue', '0'), ('icValue', '0'), + ('xvValue', '0'), ('xcValue', '0')): + code.replace(marker, value) + iop = InstObjParams(name, Name, 'MipsStaticInst', cblk, opt_flags) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecodeWithMnemonic.subst(iop) + exec_output = IntegerExecute.subst(iop) +}}; + +// Primary format for integer operate instructions: +def format FPOpCc(code, icValue, ivValue, xcValue, xvValue, *opt_flags) {{ + orig_code = code + cblk = CodeBlock(code) + checkPriv = (code.find('checkPriv') != -1) + code.replace('checkPriv', '') + if checkPriv: + code.replace('checkPriv;', 'if(!xc->regs.miscRegFile.pstateFields.priv) throw privileged_opcode;') + else: + code.replace('checkPriv;', '') + for (marker, value) in (('ivValue', ivValue), ('icValue', icValue), + ('xvValue', xvValue), ('xcValue', xcValue)): + code.replace(marker, value) + iop = InstObjParams(name, Name, 'MipsStaticInst', cblk, opt_flags) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecodeWithMnemonic.subst(iop) + exec_output = IntegerExecute.subst(iop) +}}; diff --git a/arch/mips/isa_desc/formats/integerop.format b/arch/mips/isa/formats/integerop.format similarity index 100% rename from arch/mips/isa_desc/formats/integerop.format rename to arch/mips/isa/formats/integerop.format diff --git a/arch/mips/isa_desc/formats/mem.format b/arch/mips/isa/formats/mem.format similarity index 100% rename from arch/mips/isa_desc/formats/mem.format rename to arch/mips/isa/formats/mem.format diff --git a/arch/mips/isa_desc/formats/noop.format b/arch/mips/isa/formats/noop.format similarity index 100% rename from arch/mips/isa_desc/formats/noop.format rename to arch/mips/isa/formats/noop.format diff --git a/arch/mips/isa/formats/tlb.format b/arch/mips/isa/formats/tlb.format new file mode 100644 index 000000000..f5e4076f2 --- /dev/null +++ b/arch/mips/isa/formats/tlb.format @@ -0,0 +1,53 @@ +//////////////////////////////////////////////////////////////////// +// +// TlbOp instructions +// + +output header {{ + /** + * Base class for integer operations. + */ + class TlbOp : public MipsStaticInst + { + protected: + + /// Constructor + TlbOp(const char *mnem, MachInst _machInst, OpClass __opClass) : MipsStaticInst(mnem, _machInst, __opClass) + { + } + + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; + }; +}}; + +output decoder {{ + std::string TlbOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const + { + return "Disassembly of integer instruction\n"; + } +}}; + +def template TlbOpExecute {{ + Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const + { + //Call into the trap handler with the appropriate fault + return No_Fault; + } + + //Write the resulting state to the execution context + %(op_wb)s; + + return No_Fault; + } +}}; + +// Primary format for integer operate instructions: +def format TlbOp(code, *opt_flags) {{ + orig_code = code + cblk = CodeBlock(code) + iop = InstObjParams(name, Name, 'MipsStaticInst', cblk, opt_flags) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecodeWithMnemonic.subst(iop) + exec_output = TlbOpExecute.subst(iop) +}}; diff --git a/arch/mips/isa_desc/formats/trap.format b/arch/mips/isa/formats/trap.format similarity index 100% rename from arch/mips/isa_desc/formats/trap.format rename to arch/mips/isa/formats/trap.format diff --git a/arch/mips/isa_desc/includes.h b/arch/mips/isa/includes.h similarity index 100% rename from arch/mips/isa_desc/includes.h rename to arch/mips/isa/includes.h diff --git a/arch/mips/isa/mips.isa b/arch/mips/isa/mips.isa new file mode 100644 index 000000000..a8c71872b --- /dev/null +++ b/arch/mips/isa/mips.isa @@ -0,0 +1,52 @@ +// -*- mode:c++ -*- + +// 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 "m5/arch/sparc/isa_desc/includes.h" + +//////////////////////////////////////////////////////////////////// +// +// Namespace statement. Everything below this line will be in the +// MipsISAInst namespace. +// + +namespace MipsISA; + +//Include the bitfield definitions +##include "m5/arch/mips/isa_desc/bitfields.h" + +//Include the operand_types and operand definitions +##include "m5/arch/mips/isa_desc/operands.h" + +//Include the base class for mips instructions, and some support code +##include "m5/arch/mips/isa_desc/base.h" + +//Include the definitions for the instruction formats +##include "m5/arch/mips/isa_desc/formats.h" + +//Include the decoder definition +##include "m5/arch/mips/isa_desc/decoder.h" diff --git a/arch/mips/isa_desc/operands.h b/arch/mips/isa/operands.h similarity index 100% rename from arch/mips/isa_desc/operands.h rename to arch/mips/isa/operands.h From de1f3a7b6bd21845faaf48c8fa509a432c01c165 Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Fri, 3 Feb 2006 03:39:08 -0500 Subject: [PATCH 015/180] Rename: arch/mips/isa/formats/tlb.format -> arch/mips/isa/formats/tlbop.format --HG-- rename : arch/mips/isa/formats/tlb.format => arch/mips/isa/formats/tlbop.format extra : convert_revision : 5b1cfba4a5b687c9a271e1a3f67f75e3fa6c2dde --- arch/mips/isa/formats/{tlb.format => tlbop.format} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename arch/mips/isa/formats/{tlb.format => tlbop.format} (100%) diff --git a/arch/mips/isa/formats/tlb.format b/arch/mips/isa/formats/tlbop.format similarity index 100% rename from arch/mips/isa/formats/tlb.format rename to arch/mips/isa/formats/tlbop.format From 1e222c1502f8cf40535fed23b3f51c5f25a6c29f Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Fri, 3 Feb 2006 03:56:57 -0500 Subject: [PATCH 016/180] .h -> .def --HG-- rename : arch/mips/isa/bitfields.h => arch/mips/isa/bitfields.def rename : arch/mips/isa/decoder.h => arch/mips/isa/decoder.def rename : arch/mips/isa/formats.h => arch/mips/isa/formats.def rename : arch/mips/isa/operands.h => arch/mips/isa/operands.def extra : convert_revision : 45cb5485311d51982ebcaf1c7eec34e8751c31f5 --- arch/mips/isa/{bitfields.h => bitfields.def} | 8 +- arch/mips/isa/decoder.def | 575 +++++++++++++++++++ arch/mips/isa/decoder.h | 575 ------------------- arch/mips/isa/{formats.h => formats.def} | 0 arch/mips/isa/{operands.h => operands.def} | 0 5 files changed, 579 insertions(+), 579 deletions(-) rename arch/mips/isa/{bitfields.h => bitfields.def} (88%) create mode 100644 arch/mips/isa/decoder.def delete mode 100644 arch/mips/isa/decoder.h rename arch/mips/isa/{formats.h => formats.def} (100%) rename arch/mips/isa/{operands.h => operands.def} (100%) diff --git a/arch/mips/isa/bitfields.h b/arch/mips/isa/bitfields.def similarity index 88% rename from arch/mips/isa/bitfields.h rename to arch/mips/isa/bitfields.def index f0d6fc8d7..0a9497899 100644 --- a/arch/mips/isa/bitfields.h +++ b/arch/mips/isa/bitfields.def @@ -41,11 +41,11 @@ def bitfield INTIMM <15: 0>; // integer immediate (literal) def bitfield OFFSET <15: 0>; // displacement // Memory-format jumps -def bitfield JMPTARG <25: 0>; -def bitfield JMPHINT <10: 6>; +def bitfield JMPTARG <25: 0>; +def bitfield JMPHINT <10: 6>; -def bitfield SYSCALLCODE <25: 6>; -def bitfield TRAPCODE <15:13>; +def bitfield SYSCALLCODE <25: 6>; +def bitfield TRAPCODE <15:13>; // M5 instructions def bitfield M5FUNC <7:0>; diff --git a/arch/mips/isa/decoder.def b/arch/mips/isa/decoder.def new file mode 100644 index 000000000..49066c9bf --- /dev/null +++ b/arch/mips/isa/decoder.def @@ -0,0 +1,575 @@ +//////////////////////////////////////////////////////////////////// +// +// The actual MIPS32 ISA decoder +// ----------------------------- +// The following instructions are specified in the MIPS32 ISA +// Specification. Decoding closely follows the style specified +// in the MIPS32 ISAthe specification document starting with Table +// A-2 (document available @ www.mips.com) +// +//@todo: Distinguish "unknown/future" use insts from "reserved" +// ones +decode OPCODE_HI default FailUnimpl::unknown() { + + // Derived From ... Table A-2 MIPS32 ISA Manual + 0x0: decode OPCODE_LO default FailUnimpl::reserved(){ + + 0x0: decode FUNCTION_HI { + 0x0: decode FUNCTION_LO { + 0x1: decode MOVCI { + format Move { + 0: movc({{ }}); + 1: movt({{ }}); + } + } + + format ShiftRotate { + //Table A-3 Note: "1. Specific encodings of the rt, rd, and sa fields + //are used to distinguish among the SLL, NOP, SSNOP and EHB functions." + 0x0: sll({{ }}); + + 0x2: decode SRL { + 0: srl({{ }}); + 1: rotr({{ }}); + } + + 0x3: sar({{ }}); + + 0x4: sllv({{ }}); + + 0x6: decode SRLV { + 0: srlv({{ }}); + 1: rotrv({{ }}); + } + + 0x7: srav({{ }}); + } + } + + 0x1: decode FUNCTION_LO { + + //Table A-3 Note: "Specific encodings of the hint field are used + //to distinguish JR from JR.HB and JALR from JALR.HB" + format Jump { + 0x0: jr({{ }}); + 0x1: jalr({{ }}); + } + + format Move { + 0x2: movz({{ }}); + 0x3: movn({{ }}); + } + + 0x4: Syscall::syscall({{ }}); + 0x5: Break::break({{ }}); + 0x7: Synchronize::synch({{ }}); + } + + 0x2: decode FUNCTION_LO { + format MultDiv { + 0x0: mfhi({{ }}); + 0x1: mthi({{ }}); + 0x2: mflo({{ }}); + 0x3: mtlo({{ }}); + } + }; + + 0x3: decode FUNCTION_LO { + format MultDiv { + 0x0: mult({{ }}); + 0x1: multu({{ }}); + 0x2: div({{ }}); + 0x3: divu({{ }}); + } + }; + + 0x4: decode FUNCTION_LO { + format Arithmetic { + 0x0: add({{ }}); + 0x1: addu({{ }}); + 0x2: sub({{ }}); + 0x3: subu({{ }}); + } + + format Logical { + 0x0: and({{ }}); + 0x1: or({{ }}); + 0x2: xor({{ }}); + 0x3: nor({{ }}); + } + } + + 0x5: decode FUNCTION_LO { + format SetInstructions{ + 0x2: slt({{ }}); + 0x3: sltu({{ }}); + } + }; + + 0x6: decode FUNCTION_LO { + format Trap { + 0x0: tge({{ }}); + 0x1: tgeu({{ }}); + 0x2: tlt({{ }}); + 0x3: tltu({{ }}); + 0x4: teq({{ }}); + 0x6: tne({{ }}); + } + } + } + + 0x1: decode REGIMM_HI { + 0x0: decode REGIMM_LO { + format Branch { + 0x0: bltz({{ }}); + 0x1: bgez({{ }}); + + //MIPS obsolete instructions + 0x2: bltzl({{ }}); + 0x3: bgezl({{ }}); + } + } + + 0x1: decode REGIMM_LO { + format Trap { + 0x0: tgei({{ }}); + 0x1: tgeiu({{ }}); + 0x2: tlti({{ }}); + 0x3: tltiu({{ }}); + 0x4: teqi({{ }}); + 0x6: tnei({{ }}); + } + } + + 0x2: decode REGIMM_LO { + format Branch { + 0x0: bltzal({{ }}); + 0x1: bgezal({{ }}); + + //MIPS obsolete instructions + 0x2: bltzall({{ }}); + 0x3: bgezall({{ }}); + } + } + + 0x3: decode REGIMM_LO { + 0x7: synci({{ }}); + } + } + + format Jump { + 0x2: j({{ }}); + 0x3: jal({{ }}); + } + + format Branch { + 0x4: beq({{ }}); + 0x5: bne({{ }}); + 0x6: blez({{ }}); + 0x7: bgtz({{ }}); + } + }; + + 0x1: decode OPCODE_LO default FailUnimpl::reserved(){ + format IntImmediate { + 0x0: addi({{ }}); + 0x1: addiu({{ }}); + 0x2: slti({{ }}); + 0x3: sltiu({{ }}); + 0x4: andi({{ }}); + 0x5: ori({{ }}); + 0x6: xori({{ }}); + 0x7: lui({{ }}); + }; + }; + + 0x2: decode OPCODE_LO default FailUnimpl::reserved(){ + + //Table A-11 MIPS32 COP0 Encoding of rs Field + 0x0: decode RS_MSB { + 0x0: decode RS { + 0x0: mfc0({{ }}); + 0xC: mtc0({{ }}); + 0xA: rdpgpr({{ }}); + + 0xB: decode SC { + 0x0: di({{ }}); + 0x1: ei({{ }}); + } + + 0xE: wrpgpr({{ }}); + } + + //Table A-12 MIPS32 COP0 Encoding of Function Field When rs=CO + 0x1: decode FUNCTION { + 0x01: tlbr({{ }}); + 0x02: tlbwi({{ }}); + 0x06: tlbwr({{ }}); + 0x08: tlbp({{ }}); + 0x18: eret({{ }}); + 0x1F: deret({{ }}); + 0x20: wait({{ }}); + } + } + + //Table A-13 MIPS32 COP1 Encoding of rs Field + 0x1: decode RS_MSB { + + 0x0: decode RS_HI { + 0x0: decode RS_LO { + 0x0: mfc1({{ }}); + 0x2: cfc1({{ }}); + 0x3: mfhc1({{ }}); + 0x4: mtc1({{ }}); + 0x6: ctc1({{ }}); + 0x7: mftc1({{ }}); + } + + 0x1: decode ND { + 0x0: decode TF { + 0x0: bc1f({{ }}); + 0x1: bc1t({{ }}); + } + + 0x1: decode TF { + 0x0: bc1fl({{ }}); + 0x1: bc1tl({{ }}); + } + } + } + + 0x1: decode RS_HI { + 0x2: decode RS_LO { + + //Table A-14 MIPS32 COP1 Encoding of Function Field When rs=S + //(( single-word )) + 0x0: decode RS_HI { + 0x0: decode RS_LO { + 0x0: add_fmt({{ }}); + 0x1: sub_fmt({{ }}); + 0x2: mul_fmt({{ }}); + 0x3: div_fmt({{ }}); + 0x4: sqrt_fmt({{ }}); + 0x5: abs_fmt({{ }}); + 0x6: mov_fmt({{ }}); + 0x7: neg_fmt({{ }}); + } + + 0x1: decode RS_LO { + //only legal for 64 bit + format mode64 { + 0x0: round_l({{ }}); + 0x1: trunc_l({{ }}); + 0x2: ceil_l({{ }}); + 0x3: floor_l({{ }}); + } + + 0x4: round_w({{ }}); + 0x5: trunc_w({{ }}); + 0x6: ceil_w({{ }}); + 0x7: floor_w({{ }}); + } + + 0x2: decode RS_LO { + 0x1: decode MOVCF { + 0x0: movf_fmt({{ }}); + 0x1: movt_fmt({{ }}); + } + + 0x2: movz({{ }}); + 0x3: movn({{ }}); + + format mode64 { + 0x2: recip({{ }}); + 0x3: rsqrt{{ }}); + } + } + + 0x4: decode RS_LO { + 0x1: cvt_d({{ }}); + 0x4: cvt_w({{ }}); + + //only legal for 64 bit + format mode64 { + 0x5: cvt_l({{ }}); + 0x6: cvt_ps({{ }}); + } + } + } + + //Table A-15 MIPS32 COP1 Encoding of Function Field When rs=D + 0x1: decode RS_HI { + 0x0: decode RS_LO { + 0x0: add_fmt({{ }}); + 0x1: sub_fmt({{ }}); + 0x2: mul_fmt({{ }}); + 0x3: div_fmt({{ }}); + 0x4: sqrt_fmt({{ }}); + 0x5: abs_fmt({{ }}); + 0x6: mov_fmt({{ }}); + 0x7: neg_fmt({{ }}); + } + + 0x1: decode RS_LO { + //only legal for 64 bit + format mode64 { + 0x0: round_l({{ }}); + 0x1: trunc_l({{ }}); + 0x2: ceil_l({{ }}); + 0x3: floor_l({{ }}); + } + + 0x4: round_w({{ }}); + 0x5: trunc_w({{ }}); + 0x6: ceil_w({{ }}); + 0x7: floor_w({{ }}); + } + + 0x2: decode RS_LO { + 0x1: decode MOVCF { + 0x0: movf_fmt({{ }}); + 0x1: movt_fmt({{ }}); + } + + 0x2: movz({{ }}); + 0x3: movn({{ }}); + + format mode64 { + 0x5: recip({{ }}); + 0x6: rsqrt{{ }}); + } + } + + 0x4: decode RS_LO { + 0x0: cvt_s({{ }}); + 0x4: cvt_w({{ }}); + + //only legal for 64 bit + format mode64 { + 0x5: cvt_l({{ }}); + } + } + } + + //Table A-16 MIPS32 COP1 Encoding of Function Field When rs=W + 0x4: decode FUNCTION { + 0x10: cvt_s({{ }}); + 0x10: cvt_d({{ }}); + } + + //Table A-16 MIPS32 COP1 Encoding of Function Field When rs=L1 + //Note: "1. Format type L is legal only if 64-bit floating point operations + //are enabled." + 0x5: decode FUNCTION_HI { + 0x10: cvt_s({{ }}); + 0x11: cvt_d({{ }}); + } + + //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 { + 0x0: add_fmt({{ }}); + 0x1: sub_fmt({{ }}); + 0x2: mul_fmt({{ }}); + 0x5: abs_fmt({{ }}); + 0x6: mov_fmt({{ }}); + 0x7: neg_fmt({{ }}); + } + + 0x2: decode RS_LO { + 0x1: decode MOVCF { + 0x0: movf_fmt({{ }}); + 0x1: movt_fmt({{ }}); + } + + 0x2: movz({{ }}); + 0x3: movn({{ }}); + } + + 0x4: decode RS_LO { + 0x0: cvt_s_pu({{ }}); + } + + 0x5: decode RS_LO { + 0x0: cvt_s_pl({{ }}); + 0x4: pll_s_pl({{ }}); + 0x5: plu_s_pl({{ }}); + 0x6: pul_s_pl({{ }}); + 0x7: puu_s_pl({{ }}); + } + } + } + + //Table A-19 MIPS32 COP2 Encoding of rs Field + 0x2: decode RS_MSB { + 0x0: decode RS_HI { + 0x0: decode RS_LO { + 0x0: mfc2({{ }}); + 0x2: cfc2({{ }}); + 0x3: mfhc2({{ }}); + 0x4: mtc2({{ }}); + 0x6: ctc2({{ }}); + 0x7: mftc2({{ }}); + } + + 0x1: decode ND { + 0x0: decode TF { + 0x0: bc2f({{ }}); + 0x1: bc2t({{ }}); + } + + 0x1: decode TF { + 0x0: bc2fl({{ }}); + 0x1: bc2tl({{ }}); + } + } + } + } + + //Table A-20 MIPS64 COP1X Encoding of Function Field 1 + //Note: "COP1X instructions are legal only if 64-bit floating point + //operations are enabled." + 0x3: decode FUNCTION_HI { + 0x0: decode FUNCTION_LO { + 0x0: lwxc1({{ }}); + 0x1: ldxc1({{ }}); + 0x5: luxc1({{ }}); + } + + 0x1: decode FUNCTION_LO { + 0x0: swxc1({{ }}); + 0x1: sdxc1({{ }}); + 0x5: suxc1({{ }}); + 0x7: prefx({{ }}); + } + + 0x3: alnv_ps({{ }}); + + 0x4: decode FUNCTION_LO { + 0x0: madd_s({{ }}); + 0x1: madd_d({{ }}); + 0x6: madd_ps({{ }}); + } + + 0x5: decode FUNCTION_LO { + 0x0: msub_s({{ }}); + 0x1: msub_d({{ }}); + 0x6: msub_ps({{ }}); + } + + 0x6: decode FUNCTION_LO { + 0x0: nmadd_s({{ }}); + 0x1: nmadd_d({{ }}); + 0x6: nmadd_ps({{ }}); + } + + 0x7: decode FUNCTION_LO { + 0x0: nmsub_s({{ }}); + 0x1: nmsub_d({{ }}); + 0x6: nmsub_ps({{ }}); + } + } + + //MIPS obsolete instructions + 0x4: beql({{ }}); + 0x5: bnel({{ }}); + 0x6: blezl({{ }}); + 0x7: bgtzl({{ }}); + }; + + 0x3: decode OPCODE_LO default FailUnimpl::reserved(){ + + //Table A-5 MIPS32 SPECIAL2 Encoding of Function Field + 0x4: decode FUNCTION_HI { + + 0x0: decode FUNCTION_LO { + 0x0: madd({{ }}); + 0x1: maddu({{ }}); + 0x2: mult({{ }}); + 0x4: msub({{ }}); + 0x5: msubu({{ }}); + } + + 0x4: decode FUNCTION_LO { + 0x0: clz({{ }}); + 0x1: clo({{ }}); + } + + 0x7: decode FUNCTION_LO { + 0x7: sdbbp({{ }}); + } + } + + //Table A-6 MIPS32 SPECIAL3 Encoding of Function Field for Release 2 of the Architecture + 0x7: decode FUNCTION_HI { + + 0x0: decode FUNCTION_LO { + 0x1: ext({{ }}); + 0x4: ins({{ }}); + } + + //Table A-10 MIPS32 BSHFL Encoding of sa Field + 0x4: decode SA { + 0x02: wsbh({{ }}); + 0x10: seb({{ }}); + 0x18: seh({{ }}); + } + + 0x6: decode FUNCTION_LO { + 0x7: rdhwr({{ }}); + } + } + }; + + 0x4: decode OPCODE_LO default FailUnimpl::reserved(){ + format LoadMemory{ + 0x0: lb({{ }}); + 0x1: lh({{ }}); + 0x2: lwl({{ }}); + 0x3: lw({{ }}); + 0x4: lbu({{ }}); + 0x5: lhu({{ }}); + 0x6: lhu({{ }}); + }; + + 0x7: FailUnimpl::reserved({{ }}); + }; + + 0x5: decode OPCODE_LO default FailUnimpl::reserved(){ + format StoreMemory{ + 0x0: sb({{ }}); + 0x1: sh({{ }}); + 0x2: swl({{ }}); + 0x3: sw({{ }}); + 0x6: swr({{ }}); + }; + + format FailUnimpl{ + 0x4: reserved({{ }}); + 0x5: reserved({{ }}); + 0x7: cache({{ }}); + }; + + }; + + 0x6: decode OPCODE_LO default FailUnimpl::reserved(){ + format LoadMemory{ + 0x0: ll({{ }}); + 0x1: lwc1({{ }}); + 0x5: ldc1({{ }}); + }; + }; + + 0x7: decode OPCODE_LO default FailUnimpl::reserved(){ + format StoreMemory{ + 0x0: sc({{ }}); + 0x1: swc1({{ }}); + 0x5: sdc1({{ }}); + }; + + } +} + + diff --git a/arch/mips/isa/decoder.h b/arch/mips/isa/decoder.h deleted file mode 100644 index 7e911cb45..000000000 --- a/arch/mips/isa/decoder.h +++ /dev/null @@ -1,575 +0,0 @@ -//////////////////////////////////////////////////////////////////// -// -// The actual MIPS32 ISA decoder -// ----------------------------- -// The following instructions are specified in the MIPS32 ISA -// Specification. Decoding closely follows the style specified -// in the MIPS32 ISAthe specification document starting with Table -// A-2 (document available @ www.mips.com) -// -//@todo: Distinguish "unknown/future" use insts from "reserved" -// ones -decode OPCODE_HI default FailUnimpl::unknown() { - - // Derived From ... Table A-2 MIPS32 ISA Manual - 0x0: decode OPCODE_LO default FailUnimpl::reserved(){ - - 0x0: decode FUNCTION_HI { - 0x0: decode FUNCTION_LO { - 0x1: decode MOVCI { - format Move { - 0: movc({{ }}); - 1: movt({{ }}); - } - } - - format ShiftRotate { - //Table A-3 Note: "1. Specific encodings of the rt, rd, and sa fields - //are used to distinguish among the SLL, NOP, SSNOP and EHB functions." - 0x0: sll({{ }}); - - 0x2: decode SRL { - 0: srl({{ }}); - 1: rotr({{ }}); - } - - 0x3: sar({{ }}); - - 0x4: sllv({{ }}); - - 0x6: decode SRLV { - 0: srlv({{ }}); - 1: rotrv({{ }}); - } - - 0x7: srav({{ }}); - } - } - - 0x1: decode FUNCTION_LO { - - //Table A-3 Note: "Specific encodings of the hint field are used - //to distinguish JR from JR.HB and JALR from JALR.HB" - format Jump { - 0x0: jr({{ }}); - 0x1: jalr({{ }}); - } - - format Move { - 0x2: movz({{ }}); - 0x3: movn({{ }}); - } - - 0x4: Syscall::syscall({{ }}); - 0x5: Break::break({{ }}); - 0x7: Synchronize::synch({{ }}); - } - - 0x2: decode FUNCTION_LO { - format MultDiv { - 0x0: mfhi({{ }}); - 0x1: mthi({{ }}); - 0x2: mflo({{ }}); - 0x3: mtlo({{ }}); - } - }; - - 0x3: decode FUNCTION_LO { - format MultDiv { - 0x0: mult({{ }}); - 0x1: multu({{ }}); - 0x2: div({{ }}); - 0x3: divu({{ }}); - } - }; - - 0x4: decode FUNCTION_LO { - format Arithmetic { - 0x0: add({{ }}); - 0x1: addu({{ }}); - 0x2: sub({{ }}); - 0x3: subu({{ }}); - } - - format Logical { - 0x0: and({{ }}); - 0x1: or({{ }}); - 0x2: xor({{ }}); - 0x3: nor({{ }}); - } - } - - 0x5: decode FUNCTION_LO { - format SetInstructions{ - 0x2: slt({{ }}); - 0x3: sltu({{ }}); - } - }; - - 0x6: decode FUNCTION_LO { - format Trap { - 0x0: tge({{ }}); - 0x1: tgeu({{ }}); - 0x2: tlt({{ }}); - 0x3: tltu({{ }}); - 0x4: teq({{ }}); - 0x6: tne({{ }}); - } - } - } - - 0x1: decode REGIMM_HI { - 0x0: decode REGIMM_LO { - format Branch { - 0x0: bltz({{ }}); - 0x1: bgez({{ }}); - - //MIPS obsolete instructions - 0x2: bltzl({{ }}); - 0x3: bgezl({{ }}); - } - } - - 0x1: decode REGIMM_LO { - format Trap { - 0x0: tgei({{ }}); - 0x1: tgeiu({{ }}); - 0x2: tlti({{ }}); - 0x3: tltiu({{ }}); - 0x4: teqi({{ }}); - 0x6: tnei({{ }}); - } - } - - 0x2: decode REGIMM_LO { - format Branch { - 0x0: bltzal({{ }}); - 0x1: bgezal({{ }}); - - //MIPS obsolete instructions - 0x2: bltzall({{ }}); - 0x3: bgezall({{ }}); - } - } - - 0x3: decode REGIMM_LO { - 0x7: synci({{ }}); - } - } - - format Jump { - 0x2: j({{ }}); - 0x3: jal({{ }}); - } - - format Branch { - 0x4: beq({{ }}); - 0x5: bne({{ }}); - 0x6: blez({{ }}); - 0x7: bgtz({{ }}); - } - }; - - 0x1: decode OPCODE_LO default FailUnimpl::reserved(){ - format IntImmediate { - 0x0: addi({{ }}); - 0x1: addiu({{ }}); - 0x2: slti({{ }}); - 0x3: sltiu({{ }}); - 0x4: andi({{ }}); - 0x5: ori({{ }}); - 0x6: xori({{ }}); - 0x7: lui({{ }}); - }; - }; - - 0x2: decode OPCODE_LO default FailUnimpl::reserved(){ - - //Table A-11 MIPS32 COP0 Encoding of rs Field - 0x0: decode RS_MSB { - 0x0: decode RS { - 0x0: mfc0({{ }}); - 0xC: mtc0({{ }}); - 0xA: rdpgpr({{ }}); - - 0xB: decode SC { - 0x0: di({{ }}); - 0x1: ei({{ }}); - } - - 0xE: wrpgpr({{ }}); - } - - //Table A-12 MIPS32 COP0 Encoding of Function Field When rs=CO - 0x1: decode FUNCTION { - 0x01: tlbr({{ }}); - 0x02: tlbwi({{ }}); - 0x06: tlbwr({{ }}); - 0x08: tlbp({{ }}); - 0x18: eret({{ }}); - 0x1F: deret({{ }}); - 0x20: wait({{ }}); - } - } - - //Table A-13 MIPS32 COP1 Encoding of rs Field - 0x1: decode RS_MSB { - - 0x0: decode RS_HI { - 0x0: decode RS_LO { - 0x0: mfc1({{ }}); - 0x2: cfc1({{ }}); - 0x3: mfhc1({{ }}); - 0x4: mtc1({{ }}); - 0x6: ctc1({{ }}); - 0x7: mftc1({{ }}); - } - - 0x1: decode ND { - 0x0: decode TF { - 0x0: bc1f({{ }}); - 0x1: bc1t({{ }}); - } - - 0x1: decode TF { - 0x0: bc1fl({{ }}); - 0x1: bc1tl({{ }}); - } - } - } - - 0x1: decode RS_HI { - 0x2: decode RS_LO { - - //Table A-14 MIPS32 COP1 Encoding of Function Field When rs=S - //(( single-word )) - 0x0: decode RS_HI { - 0x0: decode RS_LO { - 0x0: add_fmt({{ }}); - 0x1: sub_fmt({{ }}); - 0x2: mul_fmt({{ }}); - 0x3: div_fmt({{ }}); - 0x4: sqrt_fmt({{ }}); - 0x5: abs_fmt({{ }}); - 0x6: mov_fmt({{ }}); - 0x7: neg_fmt({{ }}); - } - - 0x1: decode RS_LO { - //only legal for 64 bit - format mode64 { - 0x0: round_l({{ }}); - 0x1: trunc_l({{ }}); - 0x2: ceil_l({{ }}); - 0x3: floor_l({{ }}); - } - - 0x4: round_w({{ }}); - 0x5: trunc_w({{ }}); - 0x6: ceil_w({{ }}); - 0x7: floor_w({{ }}); - } - - 0x2: decode RS_LO { - 0x1: decode MOVCF { - 0x0: movf_fmt({{ }}); - 0x1: movt_fmt({{ }}); - } - - 0x2: movz({{ }}); - 0x3: movn({{ }}); - - format mode64 { - 0x2: recip({{ }}); - 0x3: rsqrt{{ }}); - } - } - - 0x4: decode RS_LO { - 0x1: cvt_d({{ }}); - 0x4: cvt_w({{ }}); - - //only legal for 64 bit - format mode64 { - 0x5: cvt_l({{ }}); - 0x6: cvt_ps({{ }}); - } - } - } - - //Table A-15 MIPS32 COP1 Encoding of Function Field When rs=D - 0x1: decode RS_HI { - 0x0: decode RS_LO { - 0x0: add_fmt({{ }}); - 0x1: sub_fmt({{ }}); - 0x2: mul_fmt({{ }}); - 0x3: div_fmt({{ }}); - 0x4: sqrt_fmt({{ }}); - 0x5: abs_fmt({{ }}); - 0x6: mov_fmt({{ }}); - 0x7: neg_fmt({{ }}); - } - - 0x1: decode RS_LO { - //only legal for 64 bit - format mode64 { - 0x0: round_l({{ }}); - 0x1: trunc_l({{ }}); - 0x2: ceil_l({{ }}); - 0x3: floor_l({{ }}); - } - - 0x4: round_w({{ }}); - 0x5: trunc_w({{ }}); - 0x6: ceil_w({{ }}); - 0x7: floor_w({{ }}); - } - - 0x2: decode RS_LO { - 0x1: decode MOVCF { - 0x0: movf_fmt({{ }}); - 0x1: movt_fmt({{ }}); - } - - 0x2: movz({{ }}); - 0x3: movn({{ }}); - - format mode64 { - 0x5: recip({{ }}); - 0x6: rsqrt{{ }}); - } - } - - 0x4: decode RS_LO { - 0x0: cvt_s({{ }}); - 0x4: cvt_w({{ }}); - - //only legal for 64 bit - format mode64 { - 0x5: cvt_l({{ }}); - } - } - } - - //Table A-16 MIPS32 COP1 Encoding of Function Field When rs=W - 0x4: decode FUNCTION { - 0x10: cvt_s({{ }}); - 0x10: cvt_d({{ }}); - } - - //Table A-16 MIPS32 COP1 Encoding of Function Field When rs=L1 - //Note: "1. Format type L is legal only if 64-bit floating point operations - //are enabled." - 0x5: decode FUNCTION_HI { - 0x10: cvt_s({{ }}); - 0x11: cvt_d({{ }}); - } - - //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 { - 0x0: add_fmt({{ }}); - 0x1: sub_fmt({{ }}); - 0x2: mul_fmt({{ }}); - 0x5: abs_fmt({{ }}); - 0x6: mov_fmt({{ }}); - 0x7: neg_fmt({{ }}); - } - - 0x2: decode RS_LO { - 0x1: decode MOVCF { - 0x0: movf_fmt({{ }}); - 0x1: movt_fmt({{ }}); - } - - 0x2: movz({{ }}); - 0x3: movn({{ }}); - } - - 0x4: decode RS_LO { - 0x0: cvt_s_pu({{ }}); - } - - 0x5: decode RS_LO { - 0x0: cvt_s_pl({{ }}); - 0x4: pll_s_pl({{ }}); - 0x5: plu_s_pl({{ }}); - 0x6: pul_s_pl({{ }}); - 0x7: puu_s_pl({{ }}); - } - } - } - - //Table A-19 MIPS32 COP2 Encoding of rs Field - 0x2: decode RS_MSB { - 0x0: decode RS_HI { - 0x0: decode RS_LO { - 0x0: mfc2({{ }}); - 0x2: cfc2({{ }}); - 0x3: mfhc2({{ }}); - 0x4: mtc2({{ }}); - 0x6: ctc2({{ }}); - 0x7: mftc2({{ }}); - } - - 0x1: decode ND { - 0x0: decode TF { - 0x0: bc2f({{ }}); - 0x1: bc2t({{ }}); - } - - 0x1: decode TF { - 0x0: bc2fl({{ }}); - 0x1: bc2tl({{ }}); - } - } - } - } - - //Table A-20 MIPS64 COP1X Encoding of Function Field 1 - //Note: "COP1X instructions are legal only if 64-bit floating point - //operations are enabled." - 0x3: decode FUNCTION_HI { - 0x0: decode FUNCTION_LO { - 0x0: lwxc1({{ }}); - 0x1: ldxc1({{ }}); - 0x5: luxc1({{ }}); - } - - 0x1: decode FUNCTION_LO { - 0x0: swxc1({{ }}); - 0x1: sdxc1({{ }}); - 0x5: suxc1({{ }}); - 0x7: prefx({{ }}); - } - - 0x3: alnv_ps({{ }}); - - 0x4: decode FUNCTION_LO { - 0x0: madd_s({{ }}); - 0x1: madd_d({{ }}); - 0x6: madd_ps({{ }}); - } - - 0x5: decode FUNCTION_LO { - 0x0: msub_s({{ }}); - 0x1: msub_d({{ }}); - 0x6: msub_ps({{ }}); - } - - 0x6: decode FUNCTION_LO { - 0x0: nmadd_s({{ }}); - 0x1: nmadd_d({{ }}); - 0x6: nmadd_ps({{ }}); - } - - 0x7: decode FUNCTION_LO { - 0x0: nmsub_s({{ }}); - 0x1: nmsub_d({{ }}); - 0x6: nmsub_ps({{ }}); - } - } - - //MIPS obsolete instructions - 0x4: beql({{ }}); - 0x5: bnel({{ }}); - 0x6: blezl({{ }}); - 0x7: bgtzl({{ }}); - }; - - 0x3: decode OPCODE_LO default FailUnimpl::reserved(){ - - //Table A-5 MIPS32 SPECIAL2 Encoding of Function Field - 0x4: decode FUNCTION_HI { - - 0x0: decode FUNCTION_LO { - 0x0: madd({{ }}); - 0x1: maddu({{ }}); - 0x2: mult({{ }}); - 0x4: msub({{ }}); - 0x5: msubu({{ }}); - } - - 0x4: decode FUNCTION_LO { - 0x0: clz({{ }}); - 0x1: clo({{ }}); - } - - 0x7: decode FUNCTION_LO { - 0x7: sdbbp({{ }}); - } - } - - //Table A-6 MIPS32 SPECIAL3 Encoding of Function Field for Release 2 of the Architecture - 0x7: decode FUNCTION_HI { - - 0x0: decode FUNCTION_LO { - 0x1: ext({{ }}); - 0x4: ins({{ }}); - } - - //Table A-10 MIPS32 BSHFL Encoding of sa Field - 0x4: decode SA { - 0x02: wsbh({{ }}); - 0x10: seb({{ }}); - 0x18: seh({{ }}); - } - - 0x6: decode FUNCTION_LO { - 0x7: rdhwr({{ }}); - } - } - }; - - 0x4: decode OPCODE_LO default FailUnimpl::reserved(){ - format LoadMemory{ - 0x0: lb({{ }}); - 0x1: lh({{ }}); - 0x2: lwl({{ }}); - 0x3: lw({{ }}); - 0x4: lbu({{ }}); - 0x5: lhu({{ }}); - 0x6: lhu({{ }}); - }; - - 0x7: FailUnimpl::reserved({{ }}); - }; - - 0x5: decode OPCODE_LO default FailUnimpl::reserved(){ - format StoreMemory{ - 0x0: sb({{ }}); - 0x1: sh({{ }}); - 0x2: swl({{ }}); - 0x3: sw({{ }}); - 0x6: swr({{ }}); - }; - - format FailUnimpl{ - 0x4: reserved({{ }}); - 0x5: reserved({{ }}); - 0x7: cache({{ }}); - }; - - }; - - 0x6: decode OPCODE_LO default FailUnimpl::reserved(){ - format LoadMemory{ - 0x0: ll({{ }}); - 0x1: lwc1({{ }}); - 0x5: ldc1({{ }}); - }; - }; - - 0x7: decode OPCODE_LO default FailUnimpl::reserved(){ - format StoreMemory{ - 0x0: sc({{ }}); - 0x1: swc1({{ }}); - 0x5: sdc1({{ }}); - }; - - } -} - - diff --git a/arch/mips/isa/formats.h b/arch/mips/isa/formats.def similarity index 100% rename from arch/mips/isa/formats.h rename to arch/mips/isa/formats.def diff --git a/arch/mips/isa/operands.h b/arch/mips/isa/operands.def similarity index 100% rename from arch/mips/isa/operands.h rename to arch/mips/isa/operands.def From 035b443093cc969c79e67285b0f421a7f12edf33 Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Fri, 3 Feb 2006 23:04:06 -0500 Subject: [PATCH 017/180] mainly added minor support for the basic arithmetic operations (add, mult, shift) arch/mips/isa/bitfields.def: Add comment, move definition up in file arch/mips/isa/decoder.def: add basic arithmetic operations arch/mips/isa/formats/fp.format: change Integer -> FP words arch/mips/isa/formats/int.format: Add derived IntImm class arch/mips/isa/operands.def: change to MIPS sytle operands --HG-- rename : arch/mips/isa/formats/fpop.format => arch/mips/isa/formats/fp.format rename : arch/mips/isa/formats/integerop.format => arch/mips/isa/formats/int.format extra : convert_revision : a95da47bc981e56a9898421da4eeb9c442d1dc15 --- arch/mips/isa/bitfields.def | 8 +- arch/mips/isa/decoder.def | 195 ++++++++++-------- .../isa/formats/{fpop.format => fp.format} | 2 +- .../formats/{integerop.format => int.format} | 26 ++- arch/mips/isa/operands.def | 21 +- 5 files changed, 151 insertions(+), 101 deletions(-) rename arch/mips/isa/formats/{fpop.format => fp.format} (99%) rename arch/mips/isa/formats/{integerop.format => int.format} (83%) diff --git a/arch/mips/isa/bitfields.def b/arch/mips/isa/bitfields.def index 0a9497899..2b5cd62f1 100644 --- a/arch/mips/isa/bitfields.def +++ b/arch/mips/isa/bitfields.def @@ -9,6 +9,7 @@ def bitfield OPCODE_LO <28:26>; def bitfield FUNCTION_HI < 5: 3>; def bitfield FUNCTION_LO < 2: 0>; +// Integer operate format def bitfield RT <20:16>; def bitfield RT_HI <20:19>; def bitfield RT_LO <18:16>; @@ -19,8 +20,10 @@ def bitfield RS_LO <23:21>; def bitfield RD <15:11>; +def bitfield INTIMM <15: 0>; // integer immediate (literal) + // Floating-point operate format -def bitfield FMT <25:21>; +def bitfield FMT <25:21>; def bitfield FT <20:16>; def bitfield FS <15:11>; def bitfield FD <10:6>; @@ -34,9 +37,6 @@ def bitfield SA <10: 6>; // Interrupts def bitfield SC < 5: 5>; -// Integer operate format(s>; -def bitfield INTIMM <15: 0>; // integer immediate (literal) - // Branch format def bitfield OFFSET <15: 0>; // displacement diff --git a/arch/mips/isa/decoder.def b/arch/mips/isa/decoder.def index 49066c9bf..8453b542c 100644 --- a/arch/mips/isa/decoder.def +++ b/arch/mips/isa/decoder.def @@ -18,31 +18,37 @@ decode OPCODE_HI default FailUnimpl::unknown() { 0x0: decode FUNCTION_LO { 0x1: decode MOVCI { format Move { - 0: movc({{ }}); - 1: movt({{ }}); + 0: movf({{ if( FPConditionCode(CC) == 0) Rd = Rs}}); + 1: movt({{ if( FPConditionCode(CC) == 1) Rd = Rs}}); } } - format ShiftRotate { + format BasicOp { + //Table A-3 Note: "1. Specific encodings of the rt, rd, and sa fields //are used to distinguish among the SLL, NOP, SSNOP and EHB functions." - 0x0: sll({{ }}); + + 0x0: sll({{ Rd = Rt.uw << SA; }}); 0x2: decode SRL { - 0: srl({{ }}); - 1: rotr({{ }}); + 0: srl({{ Rd = Rt.uw >> SA; }}); + + //Hardcoded assuming 32-bit ISA, probably need parameter here + 1: rotr({{ Rd = (Rt.uw << (32 - SA)) | (Rt.uw >> SA);}}); } - 0x3: sar({{ }}); - - 0x4: sllv({{ }}); + 0x3: sra({{ Rd = Rt.sw >> SA; }}); + + 0x4: sllv({{ Rd = Rt.uw << Rs<4:0>; }}); 0x6: decode SRLV { - 0: srlv({{ }}); - 1: rotrv({{ }}); + 0: srlv({{ Rd = Rt.uw >> Rs<4:0>; }}); + + //Hardcoded assuming 32-bit ISA, probably need parameter here + 1: rotrv({{ Rd = (Rt.uw << (32 - Rs<4:0>)) | (Rt.uw >> Rs<4:0>);}}); } - 0x7: srav({{ }}); + 0x7: srav({{ Rd = Rt.sw >> Rs<4:0>; }}); } } @@ -51,22 +57,24 @@ decode OPCODE_HI default FailUnimpl::unknown() { //Table A-3 Note: "Specific encodings of the hint field are used //to distinguish JR from JR.HB and JALR from JALR.HB" format Jump { - 0x0: jr({{ }}); - 0x1: jalr({{ }}); + 0x0: jr(IsReturn); + 0x1: jalr(IsCall,IsReturn); } format Move { - 0x2: movz({{ }}); - 0x3: movn({{ }}); + 0x2: movz({{ if (Rt == 0) Rd = Rs; }}); + 0x3: movn({{ if (Rt != 0) Rd = Rs; }}); } - 0x4: Syscall::syscall({{ }}); - 0x5: Break::break({{ }}); - 0x7: Synchronize::synch({{ }}); + format Trap { + 0x4: Syscall::syscall({{ xc->syscall()}},IsNonSpeculative); + 0x5: Break::break({{ }}); + 0x7: Synchronize::sync({{ }}); + } } 0x2: decode FUNCTION_LO { - format MultDiv { + format IntOp { 0x0: mfhi({{ }}); 0x1: mthi({{ }}); 0x2: mflo({{ }}); @@ -75,34 +83,31 @@ decode OPCODE_HI default FailUnimpl::unknown() { }; 0x3: decode FUNCTION_LO { - format MultDiv { - 0x0: mult({{ }}); - 0x1: multu({{ }}); - 0x2: div({{ }}); - 0x3: divu({{ }}); + format IntOp { + 0x0: mult({{ Rd.sw = Rs.sw * Rt.sw; }}); + 0x1: multu({{ Rd.sw = Rs.uw * Rt.uw;}}); + 0x2: div({{ Rd.sw = Rs.sw / Rt.sw;}}); + 0x3: divu({{ Rd.sw = Rs.sw / Rt.uw;}}); } }; 0x4: decode FUNCTION_LO { - format Arithmetic { - 0x0: add({{ }}); - 0x1: addu({{ }}); - 0x2: sub({{ }}); - 0x3: subu({{ }}); - } - - format Logical { - 0x0: and({{ }}); - 0x1: or({{ }}); - 0x2: xor({{ }}); - 0x3: nor({{ }}); + format IntOp { + 0x0: add({{ Rd.sw = Rs.sw + Rt.sw;}}); + 0x1: addu({{ Rd.uw = Rs.uw + Rt.uw;}}); + 0x2: sub({{ Rd.sw = Rs.sw - Rt.sw;}}); + 0x3: subu({{ Rd.uw = Rs.uw - Rt.uw;}}); + 0x4: and({{ Rd.sw = Rs.uw & Rt.uw;}}); + 0x5: or({{ Rd.sw = Rs.uw | Rt.uw;}}); + 0x6: xor({{ Rd.sw = Rs.uw ^ Rt.uw;}}); + 0x7: nor({{ Rd.sw = ~(Rs.uw | Rt.uw);}}); } } 0x5: decode FUNCTION_LO { - format SetInstructions{ - 0x2: slt({{ }}); - 0x3: sltu({{ }}); + format IntOp{ + 0x2: slt({{ Rd.sw = ( Rs.sw < Rt.sw ) ? 1 : 0}}); + 0x3: sltu({{ Rd.uw = ( Rs.uw < Rt.uw ) ? 1 : 0}}); } }; @@ -153,13 +158,15 @@ decode OPCODE_HI default FailUnimpl::unknown() { } 0x3: decode REGIMM_LO { - 0x7: synci({{ }}); + format Trap { + 0x7: synci({{ }}); + } } } format Jump { - 0x2: j({{ }}); - 0x3: jal({{ }}); + 0x2: j(); + 0x3: jal(IsCall); } format Branch { @@ -171,14 +178,17 @@ decode OPCODE_HI default FailUnimpl::unknown() { }; 0x1: decode OPCODE_LO default FailUnimpl::reserved(){ - format IntImmediate { - 0x0: addi({{ }}); - 0x1: addiu({{ }}); - 0x2: slti({{ }}); - 0x3: sltiu({{ }}); - 0x4: andi({{ }}); - 0x5: ori({{ }}); - 0x6: xori({{ }}); + format IntOp { + 0x0: addi({{ Rt.sw = Rs.sw + INTIMM; }}); + 0x1: addiu({{ Rt.uw = Rs.uw + INTIMM;}}); + 0x2: slti({{ Rt.sw = ( Rs.sw < INTIMM ) ? 1 : 0 }}); + 0x3: sltiu({{ Rt.uw = ( Rs.uw < INTIMM ) ? 1 : 0 }}); + 0x4: andi({{ Rt.sw = Rs.sw & INTIMM;}}); + 0x5: ori({{ Rt.sw = Rs.sw | INTIMM;}}); + 0x6: xori({{ Rt.sw = Rs.sw ^ INTIMM;}}); + }; + + format Memory { 0x7: lui({{ }}); }; }; @@ -193,8 +203,10 @@ decode OPCODE_HI default FailUnimpl::unknown() { 0xA: rdpgpr({{ }}); 0xB: decode SC { - 0x0: di({{ }}); - 0x1: ei({{ }}); + format BasicOp { + 0x0: di({{ }}); + 0x1: ei({{ }}); + } } 0xE: wrpgpr({{ }}); @@ -202,13 +214,18 @@ decode OPCODE_HI default FailUnimpl::unknown() { //Table A-12 MIPS32 COP0 Encoding of Function Field When rs=CO 0x1: decode FUNCTION { - 0x01: tlbr({{ }}); - 0x02: tlbwi({{ }}); - 0x06: tlbwr({{ }}); - 0x08: tlbp({{ }}); - 0x18: eret({{ }}); - 0x1F: deret({{ }}); - 0x20: wait({{ }}); + format Trap { + 0x01: tlbr({{ }}); + 0x02: tlbwi({{ }}); + 0x06: tlbwr({{ }}); + 0x08: tlbp({{ }}); + } + + format BasicOp { + 0x18: eret({{ }}); + 0x1F: deret({{ }}); + 0x20: wait({{ }}); + } } } @@ -227,13 +244,17 @@ decode OPCODE_HI default FailUnimpl::unknown() { 0x1: decode ND { 0x0: decode TF { - 0x0: bc1f({{ }}); - 0x1: bc1t({{ }}); + format Branch { + 0x0: bc1f({{ }}); + 0x1: bc1t({{ }}); + } } 0x1: decode TF { - 0x0: bc1fl({{ }}); - 0x1: bc1tl({{ }}); + format Branch { + 0x0: bc1fl({{ }}); + 0x1: bc1tl({{ }}); + } } } } @@ -276,8 +297,10 @@ decode OPCODE_HI default FailUnimpl::unknown() { 0x1: movt_fmt({{ }}); } - 0x2: movz({{ }}); - 0x3: movn({{ }}); + format Move { + 0x2: movz({{ if (Rt == 0) Rd = Rs; }}); + 0x3: movn({{ if (Rt != 0) Rd = Rs; }}); + } format mode64 { 0x2: recip({{ }}); @@ -331,8 +354,10 @@ decode OPCODE_HI default FailUnimpl::unknown() { 0x1: movt_fmt({{ }}); } - 0x2: movz({{ }}); - 0x3: movn({{ }}); + format Move { + 0x2: movz({{ if (Rt == 0) Rd = Rs; }}); + 0x3: movn({{ if (Rt != 0) Rd = Rs; }}); + } format mode64 { 0x5: recip({{ }}); @@ -384,8 +409,6 @@ decode OPCODE_HI default FailUnimpl::unknown() { 0x1: movt_fmt({{ }}); } - 0x2: movz({{ }}); - 0x3: movn({{ }}); } 0x4: decode RS_LO { @@ -416,13 +439,17 @@ decode OPCODE_HI default FailUnimpl::unknown() { 0x1: decode ND { 0x0: decode TF { - 0x0: bc2f({{ }}); - 0x1: bc2t({{ }}); + format Branch { + 0x0: bc2f({{ }}); + 0x1: bc2t({{ }}); + } } 0x1: decode TF { - 0x0: bc2fl({{ }}); - 0x1: bc2tl({{ }}); + format Branch { + 0x0: bc2fl({{ }}); + 0x1: bc2tl({{ }}); + } } } } @@ -479,7 +506,7 @@ decode OPCODE_HI default FailUnimpl::unknown() { 0x7: bgtzl({{ }}); }; - 0x3: decode OPCODE_LO default FailUnimpl::reserved(){ + 0x3: decode OPCODE_LO default FailUnimpl::reserved() { //Table A-5 MIPS32 SPECIAL2 Encoding of Function Field 0x4: decode FUNCTION_HI { @@ -523,8 +550,8 @@ decode OPCODE_HI default FailUnimpl::unknown() { } }; - 0x4: decode OPCODE_LO default FailUnimpl::reserved(){ - format LoadMemory{ + 0x4: decode OPCODE_LO default FailUnimpl::reserved() { + format Memory { 0x0: lb({{ }}); 0x1: lh({{ }}); 0x2: lwl({{ }}); @@ -537,8 +564,8 @@ decode OPCODE_HI default FailUnimpl::unknown() { 0x7: FailUnimpl::reserved({{ }}); }; - 0x5: decode OPCODE_LO default FailUnimpl::reserved(){ - format StoreMemory{ + 0x5: decode OPCODE_LO default FailUnimpl::reserved() { + format Memory { 0x0: sb({{ }}); 0x1: sh({{ }}); 0x2: swl({{ }}); @@ -546,7 +573,7 @@ decode OPCODE_HI default FailUnimpl::unknown() { 0x6: swr({{ }}); }; - format FailUnimpl{ + format FailUnimpl { 0x4: reserved({{ }}); 0x5: reserved({{ }}); 0x7: cache({{ }}); @@ -554,16 +581,16 @@ decode OPCODE_HI default FailUnimpl::unknown() { }; - 0x6: decode OPCODE_LO default FailUnimpl::reserved(){ - format LoadMemory{ + 0x6: decode OPCODE_LO default FailUnimpl::reserved() { + format Memory { 0x0: ll({{ }}); 0x1: lwc1({{ }}); 0x5: ldc1({{ }}); }; }; - 0x7: decode OPCODE_LO default FailUnimpl::reserved(){ - format StoreMemory{ + 0x7: decode OPCODE_LO default FailUnimpl::reserved() { + format Memory { 0x0: sc({{ }}); 0x1: swc1({{ }}); 0x5: sdc1({{ }}); diff --git a/arch/mips/isa/formats/fpop.format b/arch/mips/isa/formats/fp.format similarity index 99% rename from arch/mips/isa/formats/fpop.format rename to arch/mips/isa/formats/fp.format index a058eea19..707109fc2 100644 --- a/arch/mips/isa/formats/fpop.format +++ b/arch/mips/isa/formats/fp.format @@ -27,7 +27,7 @@ output decoder {{ } }}; -def template IntegerExecute {{ +def template FPExecute {{ Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const { //These are set to constants when the execute method diff --git a/arch/mips/isa/formats/integerop.format b/arch/mips/isa/formats/int.format similarity index 83% rename from arch/mips/isa/formats/integerop.format rename to arch/mips/isa/formats/int.format index 6fa7feed3..9b2d8d38e 100644 --- a/arch/mips/isa/formats/integerop.format +++ b/arch/mips/isa/formats/int.format @@ -7,7 +7,7 @@ output header {{ /** * Base class for integer operations. */ - class IntegerOp : public MipsStaticInst + class IntOp : public MipsStaticInst { protected: @@ -18,16 +18,36 @@ output header {{ std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; }; + + /** + * Derived class for integer immediate operations. + */ + class IntImm : public IntOp + { + protected: + + /// Constructor + IntegerImm(const char *mnem, MachInst _machInst, OpClass __opClass) : MipsStaticInst(mnem, _machInst, __opClass) + { + } + + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; + }; }}; output decoder {{ - std::string IntegerOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const + std::string IntOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const { return "Disassembly of integer instruction\n"; } + + std::string IntImm::generateDisassembly(Addr pc, const SymbolTable *symtab) const + { + return "Disassembly of integer immediate instruction\n"; + } }}; -def template IntegerExecute {{ +def template IntExecute {{ Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const { //These are set to constants when the execute method diff --git a/arch/mips/isa/operands.def b/arch/mips/isa/operands.def index 77de6c9c4..16d8fbceb 100644 --- a/arch/mips/isa/operands.def +++ b/arch/mips/isa/operands.def @@ -13,17 +13,20 @@ def operand_types {{ }}; def operands {{ - # Int regs default to unsigned, but code should not count on this. - # For clarity, descriptions that depend on unsigned behavior should - # explicitly specify '.uq'. - 'Rd': IntRegOperandTraits('udw', 'RD', 'IsInteger', 1), - 'Rs1': IntRegOperandTraits('udw', 'RS1', 'IsInteger', 2), - 'Rs2': IntRegOperandTraits('udw', 'RS2', 'IsInteger', 3), - #'Fa': FloatRegOperandTraits('df', 'FA', 'IsFloating', 1), - #'Fb': FloatRegOperandTraits('df', 'FB', 'IsFloating', 2), - #'Fc': FloatRegOperandTraits('df', 'FC', 'IsFloating', 3), + 'Rd': IntRegOperandTraits('uw', 'RD', 'IsInteger', 1), + 'Rs': IntRegOperandTraits('uw', 'RS', 'IsInteger', 2), + 'Rt': IntRegOperandTraits('uw', 'RT', 'IsInteger', 3), + + 'IntImm': IntRegOperandTraits('uw', 'INTIMM', 'IsInteger', 3), + 'Sa': IntRegOperandTraits('uw', 'SA', 'IsInteger', 4), + + 'Fd': FloatRegOperandTraits('sf', 'FD', 'IsFloating', 1), + 'Fs': FloatRegOperandTraits('sf', 'FS', 'IsFloating', 2), + 'Ft': FloatRegOperandTraits('sf', 'FT', 'IsFloating', 3), + 'Mem': MemOperandTraits('udw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 4) + #'NPC': NPCOperandTraits('uq', None, ( None, None, 'IsControl' ), 4), #'Runiq': ControlRegOperandTraits('uq', 'Uniq', None, 1), #'FPCR': ControlRegOperandTraits('uq', 'Fpcr', None, 1), From 6d2807ded8660f241aaecd28ff716c1d91f8b5a0 Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Sat, 4 Feb 2006 18:59:44 -0500 Subject: [PATCH 018/180] 1st full draft switch statement actions for all integer arithmetic operations and the majority of the load & store operations (not all of FP-Ops), Output,Format, & Template code needs to be adjusted to correctly take these "decoder.h" inputs ... --HG-- extra : convert_revision : 3dcde1f2f587e2766fd61231a93d34d1d7727356 --- arch/mips/isa/decoder.def | 167 ++++++++++++++++++++++++-------------- 1 file changed, 104 insertions(+), 63 deletions(-) diff --git a/arch/mips/isa/decoder.def b/arch/mips/isa/decoder.def index 8453b542c..878c90ca5 100644 --- a/arch/mips/isa/decoder.def +++ b/arch/mips/isa/decoder.def @@ -18,8 +18,8 @@ decode OPCODE_HI default FailUnimpl::unknown() { 0x0: decode FUNCTION_LO { 0x1: decode MOVCI { format Move { - 0: movf({{ if( FPConditionCode(CC) == 0) Rd = Rs}}); - 1: movt({{ if( FPConditionCode(CC) == 1) Rd = Rs}}); + 0: movf({{ if( xc->miscRegs.fpcr == 0) Rd = Rs}}); + 1: movt({{ if( xc->miscRegs.fpcr == 1) Rd = Rs}}); } } @@ -67,27 +67,45 @@ decode OPCODE_HI default FailUnimpl::unknown() { } format Trap { - 0x4: Syscall::syscall({{ xc->syscall()}},IsNonSpeculative); - 0x5: Break::break({{ }}); - 0x7: Synchronize::sync({{ }}); + 0x4: syscall({{ xc->syscall()}},IsNonSpeculative); + 0x5: break({{ }}); + 0x7: sync({{ }}); } } 0x2: decode FUNCTION_LO { - format IntOp { - 0x0: mfhi({{ }}); - 0x1: mthi({{ }}); - 0x2: mflo({{ }}); - 0x3: mtlo({{ }}); + format BasicOp { + 0x0: mfhi({{ Rd = xc->miscRegs.Hi; }}); + 0x1: mthi({{ xc->miscRegs.Hi = Rs; }}); + 0x2: mflo({{ Rd = xc->miscRegs.Lo; }}); + 0x3: mtlo({{ xc->miscRegs.Lo = Rs; }}); } }; 0x3: decode FUNCTION_LO { format IntOp { - 0x0: mult({{ Rd.sw = Rs.sw * Rt.sw; }}); - 0x1: multu({{ Rd.sw = Rs.uw * Rt.uw;}}); - 0x2: div({{ Rd.sw = Rs.sw / Rt.sw;}}); - 0x3: divu({{ Rd.sw = Rs.sw / Rt.uw;}}); + 0x0: mult({{ + INT64 temp1 = Rs.sw * Rt.sw; + xc->miscRegs.Hi->temp1<63:32>; + xc->miscRegs.Lo->temp1<31:0> + }}); + + 0x1: multu({{ + INT64 temp1 = Rs.uw * Rt.uw; + xc->miscRegs.Hi->temp1<63:32>; + xc->miscRegs.Lo->temp1<31:0> + Rd.sw = Rs.uw * Rt.uw; + }}); + + 0x2: div({{ + xc->miscRegs.Hi = Rs.sw % Rt.sw; + xc->miscRegs.Lo = Rs.sw / Rt.sw; + }}); + + 0x3: divu({{ + xc->miscRegs.Hi = Rs.uw % Rt.uw; + xc->miscRegs.Lo = Rs.uw / Rt.uw; + }}); } }; @@ -126,12 +144,12 @@ decode OPCODE_HI default FailUnimpl::unknown() { 0x1: decode REGIMM_HI { 0x0: decode REGIMM_LO { format Branch { - 0x0: bltz({{ }}); - 0x1: bgez({{ }}); + 0x0: bltz({{ cond = (Rs.sq < 0); }}); + 0x1: bgez({{ cond = (Rs.sq >= 0); }}); //MIPS obsolete instructions - 0x2: bltzl({{ }}); - 0x3: bgezl({{ }}); + 0x2: bltzl({{ cond = (Rs.sq < 0); }}); + 0x3: bgezl({{ cond = (Rs.sq >= 0); }}); } } @@ -148,12 +166,12 @@ decode OPCODE_HI default FailUnimpl::unknown() { 0x2: decode REGIMM_LO { format Branch { - 0x0: bltzal({{ }}); - 0x1: bgezal({{ }}); + 0x0: bltzal({{ cond = (Rs.sq < 0); }}); + 0x1: bgezal({{ cond = (Rs.sq >= 0); }}); //MIPS obsolete instructions - 0x2: bltzall({{ }}); - 0x3: bgezall({{ }}); + 0x2: bltzall({{ cond = (Rs.sq < 0); }}); + 0x3: bgezall({{ cond = (Rs.sq >= 0); }}); } } @@ -170,10 +188,10 @@ decode OPCODE_HI default FailUnimpl::unknown() { } format Branch { - 0x4: beq({{ }}); - 0x5: bne({{ }}); - 0x6: blez({{ }}); - 0x7: bgtz({{ }}); + 0x4: beq({{ cond = (Rs.sq == 0); }}); + 0x5: bne({{ cond = (Rs.sq != 0); }}); + 0x6: blez({{ cond = (Rs.sq <= 0); }}); + 0x7: bgtz({{ cond = (Rs.sq > 0); }}); } }; @@ -186,10 +204,7 @@ decode OPCODE_HI default FailUnimpl::unknown() { 0x4: andi({{ Rt.sw = Rs.sw & INTIMM;}}); 0x5: ori({{ Rt.sw = Rs.sw | INTIMM;}}); 0x6: xori({{ Rt.sw = Rs.sw ^ INTIMM;}}); - }; - - format Memory { - 0x7: lui({{ }}); + 0x7: lui({{ Rt = INTIMM << 16}}); }; }; @@ -245,15 +260,15 @@ decode OPCODE_HI default FailUnimpl::unknown() { 0x1: decode ND { 0x0: decode TF { format Branch { - 0x0: bc1f({{ }}); - 0x1: bc1t({{ }}); + 0x0: bc1f({{ cond = (xc->miscRegs.fpcr == 0); }}); + 0x1: bc1t({{ cond = (xc->miscRegs.fpcr == 1); }}); } } 0x1: decode TF { format Branch { - 0x0: bc1fl({{ }}); - 0x1: bc1tl({{ }}); + 0x0: bc1fl({{ cond = (xc->miscRegs.fpcr == 0); }}); + 0x1: bc1tl({{ cond = (xc->miscRegs.fpcr == 1); }}); } } } @@ -440,15 +455,15 @@ decode OPCODE_HI default FailUnimpl::unknown() { 0x1: decode ND { 0x0: decode TF { format Branch { - 0x0: bc2f({{ }}); - 0x1: bc2t({{ }}); + 0x0: bc2f({{ cond = (xc->miscRegs.cop2cc == 0); }}, COP2); + 0x1: bc2t({{ cond = (xc->miscRegs.cop2cc == 1); }}, COP2}}); } } 0x1: decode TF { format Branch { - 0x0: bc2fl({{ }}); - 0x1: bc2tl({{ }}); + 0x0: bc2fl({{ cond = (xc->miscRegs.cop2cc == 0); }}, COP2}}); + 0x1: bc2tl({{ cond = (xc->miscRegs.cop2cc == 1); }}, COP2}}); } } } @@ -500,10 +515,10 @@ decode OPCODE_HI default FailUnimpl::unknown() { } //MIPS obsolete instructions - 0x4: beql({{ }}); - 0x5: bnel({{ }}); - 0x6: blezl({{ }}); - 0x7: bgtzl({{ }}); + 0x4: beql({{ cond = (Rs.sq == 0); }}); + 0x5: bnel({{ cond = (Rs.sq != 0); }}); + 0x6: blezl({{ cond = (Rs.sq <= 0); }}); + 0x7: bgtzl({{ cond = (Rs.sq > 0); }}); }; 0x3: decode OPCODE_LO default FailUnimpl::reserved() { @@ -512,11 +527,37 @@ decode OPCODE_HI default FailUnimpl::unknown() { 0x4: decode FUNCTION_HI { 0x0: decode FUNCTION_LO { - 0x0: madd({{ }}); - 0x1: maddu({{ }}); - 0x2: mult({{ }}); - 0x4: msub({{ }}); - 0x5: msubu({{ }}); + format IntOp { + 0x0: madd({{ + INT64 temp1 = Hi.sw << 32 | Lo.sw >> 32; + temp1 = temp1 + (Rs.sw * Rt.sw); + xc->miscRegs.Hi->temp1<63:32>; + xc->miscRegs.Lo->temp1<31:0> + }}); + + 0x1: maddu({{ + INT64 temp1 = Hi.uw << 32 | Lo.uw >> 32; + temp1 = temp1 + (Rs.uw * Rt.uw); + xc->miscRegs.Hi->temp1<63:32>; + xc->miscRegs.Lo->temp1<31:0> + }}); + + 0x2: mul({{ Rd.sw = Rs.sw * Rt.sw; }}); + + 0x4: msub({{ + INT64 temp1 = Hi.sw << 32 | Lo.sw >> 32; + temp1 = temp1 - (Rs.sw * Rt.sw); + xc->miscRegs.Hi->temp1<63:32>; + xc->miscRegs.Lo->temp1<31:0> + }}); + + 0x5: msubu({{ + INT64 temp1 = Hi.uw << 32 | Lo.uw >> 32; + temp1 = temp1 - (Rs.uw * Rt.uw); + xc->miscRegs.Hi->temp1<63:32>; + xc->miscRegs.Lo->temp1<31:0> + }}); + } } 0x4: decode FUNCTION_LO { @@ -552,13 +593,13 @@ decode OPCODE_HI default FailUnimpl::unknown() { 0x4: decode OPCODE_LO default FailUnimpl::reserved() { format Memory { - 0x0: lb({{ }}); - 0x1: lh({{ }}); - 0x2: lwl({{ }}); - 0x3: lw({{ }}); - 0x4: lbu({{ }}); - 0x5: lhu({{ }}); - 0x6: lhu({{ }}); + 0x0: lb({{ EA = Rs + disp; }}, {{ Rb.sw = Mem.sb; }}); + 0x1: lh({{ EA = Rs + disp; }}, {{ Rb.sw = Mem.sh; }}); + 0x2: lwl({{ EA = Rs + disp; }}, {{ Rb.sw = Mem.sw; }}, WordAlign); + 0x3: lw({{ EA = Rs + disp; }}, {{ Rb.uq = Mem.sb; }}); + 0x4: lbu({{ EA = Rs + disp; }}, {{ Rb.uw = Mem.ub; }}); + 0x5: lhu({{ EA = Rs + disp; }}, {{ Rb.uw = Mem.uh; }}); + 0x6: lwr({{ EA = Rs + disp; }}, {{ Rb.uw = Mem.uw; }}, WordAlign); }; 0x7: FailUnimpl::reserved({{ }}); @@ -566,11 +607,11 @@ decode OPCODE_HI default FailUnimpl::unknown() { 0x5: decode OPCODE_LO default FailUnimpl::reserved() { format Memory { - 0x0: sb({{ }}); - 0x1: sh({{ }}); - 0x2: swl({{ }}); - 0x3: sw({{ }}); - 0x6: swr({{ }}); + 0x0: sb({{ EA = Rs + disp; }}, {{ Mem.ub = Rt<7:0>; }}); + 0x1: sh({{ EA = Rs + disp; }},{{ Mem.uh = Rt<15:0>; }}); + 0x2: swl({{ EA = Rs + disp; }},{{ Mem.ub = Rt<31:0>; }},WordAlign); + 0x3: sw({{ EA = Rs + disp; }},{{ Mem.ub = Rt<31:0>; }}); + 0x6: swr({{ EA = Rs + disp; }},{{ Mem.ub = Rt<31:0>; }},WordAlign); }; format FailUnimpl { @@ -584,16 +625,16 @@ decode OPCODE_HI default FailUnimpl::unknown() { 0x6: decode OPCODE_LO default FailUnimpl::reserved() { format Memory { 0x0: ll({{ }}); - 0x1: lwc1({{ }}); - 0x5: ldc1({{ }}); + 0x1: lwc1({{ EA = Rs + disp; }},{{ Ft<31:0> = Mem.uf; }}); + 0x5: ldc1({{ EA = Rs + disp; }},{{ Ft<63:0> = Mem.df; }}); }; }; 0x7: decode OPCODE_LO default FailUnimpl::reserved() { format Memory { 0x0: sc({{ }}); - 0x1: swc1({{ }}); - 0x5: sdc1({{ }}); + 0x1: swc1({{ EA = Rs + disp; }},{{ Mem.uf = Ft<31:0>; }}); + 0x5: sdc1({{ EA = Rs + disp; }},{{ Mem.df = Ft<63:0>; }}); }; } From d30262d480b8a167470c17a35aecc727ea933a22 Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Tue, 7 Feb 2006 18:36:08 -0500 Subject: [PATCH 019/180] name changes ... minor IntOP format change arch/mips/isa/formats/int.format: Looks like Integer Ops with Immediates may not need their own separate class because all those instructions are distinct from their reg-reg counterparts --HG-- rename : arch/mips/isa/bitfields.def => arch/mips/isa/bitfields.isa rename : arch/mips/isa/decoder.def => arch/mips/isa/decoder.isa rename : arch/mips/isa/formats.def => arch/mips/isa/formats.isa rename : arch/mips/isa/includes.h => arch/mips/isa/includes.isa rename : arch/mips/isa/operands.def => arch/mips/isa/operands.isa extra : convert_revision : 8e354b4232b28c0264d98d333d55ef8b5a6589cc --- .../mips/isa/{bitfields.def => bitfields.isa} | 8 +- arch/mips/isa/decoder.def | 643 ------------------ arch/mips/isa/decoder.isa | 643 ++++++++++++++++++ arch/mips/isa/{formats.def => formats.isa} | 0 arch/mips/isa/formats/int.format | 65 +- arch/mips/isa/{includes.h => includes.isa} | 0 arch/mips/isa/{operands.def => operands.isa} | 4 +- 7 files changed, 652 insertions(+), 711 deletions(-) rename arch/mips/isa/{bitfields.def => bitfields.isa} (88%) delete mode 100644 arch/mips/isa/decoder.def create mode 100644 arch/mips/isa/decoder.isa rename arch/mips/isa/{formats.def => formats.isa} (100%) rename arch/mips/isa/{includes.h => includes.isa} (100%) rename arch/mips/isa/{operands.def => operands.isa} (94%) diff --git a/arch/mips/isa/bitfields.def b/arch/mips/isa/bitfields.isa similarity index 88% rename from arch/mips/isa/bitfields.def rename to arch/mips/isa/bitfields.isa index 2b5cd62f1..94a8a6467 100644 --- a/arch/mips/isa/bitfields.def +++ b/arch/mips/isa/bitfields.isa @@ -41,11 +41,11 @@ def bitfield SC < 5: 5>; def bitfield OFFSET <15: 0>; // displacement // Memory-format jumps -def bitfield JMPTARG <25: 0>; -def bitfield JMPHINT <10: 6>; +def bitfield JMPTARG <25: 0>; +def bitfield JMPHINT <10: 6>; -def bitfield SYSCALLCODE <25: 6>; -def bitfield TRAPCODE <15:13>; +def bitfield SYSCALLCODE <25: 6>; +def bitfield TRAPCODE <15:13>; // M5 instructions def bitfield M5FUNC <7:0>; diff --git a/arch/mips/isa/decoder.def b/arch/mips/isa/decoder.def deleted file mode 100644 index 878c90ca5..000000000 --- a/arch/mips/isa/decoder.def +++ /dev/null @@ -1,643 +0,0 @@ -//////////////////////////////////////////////////////////////////// -// -// The actual MIPS32 ISA decoder -// ----------------------------- -// The following instructions are specified in the MIPS32 ISA -// Specification. Decoding closely follows the style specified -// in the MIPS32 ISAthe specification document starting with Table -// A-2 (document available @ www.mips.com) -// -//@todo: Distinguish "unknown/future" use insts from "reserved" -// ones -decode OPCODE_HI default FailUnimpl::unknown() { - - // Derived From ... Table A-2 MIPS32 ISA Manual - 0x0: decode OPCODE_LO default FailUnimpl::reserved(){ - - 0x0: decode FUNCTION_HI { - 0x0: decode FUNCTION_LO { - 0x1: decode MOVCI { - format Move { - 0: movf({{ if( xc->miscRegs.fpcr == 0) Rd = Rs}}); - 1: movt({{ if( xc->miscRegs.fpcr == 1) Rd = Rs}}); - } - } - - format BasicOp { - - //Table A-3 Note: "1. Specific encodings of the rt, rd, and sa fields - //are used to distinguish among the SLL, NOP, SSNOP and EHB functions." - - 0x0: sll({{ Rd = Rt.uw << SA; }}); - - 0x2: decode SRL { - 0: srl({{ Rd = Rt.uw >> SA; }}); - - //Hardcoded assuming 32-bit ISA, probably need parameter here - 1: rotr({{ Rd = (Rt.uw << (32 - SA)) | (Rt.uw >> SA);}}); - } - - 0x3: sra({{ Rd = Rt.sw >> SA; }}); - - 0x4: sllv({{ Rd = Rt.uw << Rs<4:0>; }}); - - 0x6: decode SRLV { - 0: srlv({{ Rd = Rt.uw >> Rs<4:0>; }}); - - //Hardcoded assuming 32-bit ISA, probably need parameter here - 1: rotrv({{ Rd = (Rt.uw << (32 - Rs<4:0>)) | (Rt.uw >> Rs<4:0>);}}); - } - - 0x7: srav({{ Rd = Rt.sw >> Rs<4:0>; }}); - } - } - - 0x1: decode FUNCTION_LO { - - //Table A-3 Note: "Specific encodings of the hint field are used - //to distinguish JR from JR.HB and JALR from JALR.HB" - format Jump { - 0x0: jr(IsReturn); - 0x1: jalr(IsCall,IsReturn); - } - - format Move { - 0x2: movz({{ if (Rt == 0) Rd = Rs; }}); - 0x3: movn({{ if (Rt != 0) Rd = Rs; }}); - } - - format Trap { - 0x4: syscall({{ xc->syscall()}},IsNonSpeculative); - 0x5: break({{ }}); - 0x7: sync({{ }}); - } - } - - 0x2: decode FUNCTION_LO { - format BasicOp { - 0x0: mfhi({{ Rd = xc->miscRegs.Hi; }}); - 0x1: mthi({{ xc->miscRegs.Hi = Rs; }}); - 0x2: mflo({{ Rd = xc->miscRegs.Lo; }}); - 0x3: mtlo({{ xc->miscRegs.Lo = Rs; }}); - } - }; - - 0x3: decode FUNCTION_LO { - format IntOp { - 0x0: mult({{ - INT64 temp1 = Rs.sw * Rt.sw; - xc->miscRegs.Hi->temp1<63:32>; - xc->miscRegs.Lo->temp1<31:0> - }}); - - 0x1: multu({{ - INT64 temp1 = Rs.uw * Rt.uw; - xc->miscRegs.Hi->temp1<63:32>; - xc->miscRegs.Lo->temp1<31:0> - Rd.sw = Rs.uw * Rt.uw; - }}); - - 0x2: div({{ - xc->miscRegs.Hi = Rs.sw % Rt.sw; - xc->miscRegs.Lo = Rs.sw / Rt.sw; - }}); - - 0x3: divu({{ - xc->miscRegs.Hi = Rs.uw % Rt.uw; - xc->miscRegs.Lo = Rs.uw / Rt.uw; - }}); - } - }; - - 0x4: decode FUNCTION_LO { - format IntOp { - 0x0: add({{ Rd.sw = Rs.sw + Rt.sw;}}); - 0x1: addu({{ Rd.uw = Rs.uw + Rt.uw;}}); - 0x2: sub({{ Rd.sw = Rs.sw - Rt.sw;}}); - 0x3: subu({{ Rd.uw = Rs.uw - Rt.uw;}}); - 0x4: and({{ Rd.sw = Rs.uw & Rt.uw;}}); - 0x5: or({{ Rd.sw = Rs.uw | Rt.uw;}}); - 0x6: xor({{ Rd.sw = Rs.uw ^ Rt.uw;}}); - 0x7: nor({{ Rd.sw = ~(Rs.uw | Rt.uw);}}); - } - } - - 0x5: decode FUNCTION_LO { - format IntOp{ - 0x2: slt({{ Rd.sw = ( Rs.sw < Rt.sw ) ? 1 : 0}}); - 0x3: sltu({{ Rd.uw = ( Rs.uw < Rt.uw ) ? 1 : 0}}); - } - }; - - 0x6: decode FUNCTION_LO { - format Trap { - 0x0: tge({{ }}); - 0x1: tgeu({{ }}); - 0x2: tlt({{ }}); - 0x3: tltu({{ }}); - 0x4: teq({{ }}); - 0x6: tne({{ }}); - } - } - } - - 0x1: decode REGIMM_HI { - 0x0: decode REGIMM_LO { - format Branch { - 0x0: bltz({{ cond = (Rs.sq < 0); }}); - 0x1: bgez({{ cond = (Rs.sq >= 0); }}); - - //MIPS obsolete instructions - 0x2: bltzl({{ cond = (Rs.sq < 0); }}); - 0x3: bgezl({{ cond = (Rs.sq >= 0); }}); - } - } - - 0x1: decode REGIMM_LO { - format Trap { - 0x0: tgei({{ }}); - 0x1: tgeiu({{ }}); - 0x2: tlti({{ }}); - 0x3: tltiu({{ }}); - 0x4: teqi({{ }}); - 0x6: tnei({{ }}); - } - } - - 0x2: decode REGIMM_LO { - format Branch { - 0x0: bltzal({{ cond = (Rs.sq < 0); }}); - 0x1: bgezal({{ cond = (Rs.sq >= 0); }}); - - //MIPS obsolete instructions - 0x2: bltzall({{ cond = (Rs.sq < 0); }}); - 0x3: bgezall({{ cond = (Rs.sq >= 0); }}); - } - } - - 0x3: decode REGIMM_LO { - format Trap { - 0x7: synci({{ }}); - } - } - } - - format Jump { - 0x2: j(); - 0x3: jal(IsCall); - } - - format Branch { - 0x4: beq({{ cond = (Rs.sq == 0); }}); - 0x5: bne({{ cond = (Rs.sq != 0); }}); - 0x6: blez({{ cond = (Rs.sq <= 0); }}); - 0x7: bgtz({{ cond = (Rs.sq > 0); }}); - } - }; - - 0x1: decode OPCODE_LO default FailUnimpl::reserved(){ - format IntOp { - 0x0: addi({{ Rt.sw = Rs.sw + INTIMM; }}); - 0x1: addiu({{ Rt.uw = Rs.uw + INTIMM;}}); - 0x2: slti({{ Rt.sw = ( Rs.sw < INTIMM ) ? 1 : 0 }}); - 0x3: sltiu({{ Rt.uw = ( Rs.uw < INTIMM ) ? 1 : 0 }}); - 0x4: andi({{ Rt.sw = Rs.sw & INTIMM;}}); - 0x5: ori({{ Rt.sw = Rs.sw | INTIMM;}}); - 0x6: xori({{ Rt.sw = Rs.sw ^ INTIMM;}}); - 0x7: lui({{ Rt = INTIMM << 16}}); - }; - }; - - 0x2: decode OPCODE_LO default FailUnimpl::reserved(){ - - //Table A-11 MIPS32 COP0 Encoding of rs Field - 0x0: decode RS_MSB { - 0x0: decode RS { - 0x0: mfc0({{ }}); - 0xC: mtc0({{ }}); - 0xA: rdpgpr({{ }}); - - 0xB: decode SC { - format BasicOp { - 0x0: di({{ }}); - 0x1: ei({{ }}); - } - } - - 0xE: wrpgpr({{ }}); - } - - //Table A-12 MIPS32 COP0 Encoding of Function Field When rs=CO - 0x1: decode FUNCTION { - format Trap { - 0x01: tlbr({{ }}); - 0x02: tlbwi({{ }}); - 0x06: tlbwr({{ }}); - 0x08: tlbp({{ }}); - } - - format BasicOp { - 0x18: eret({{ }}); - 0x1F: deret({{ }}); - 0x20: wait({{ }}); - } - } - } - - //Table A-13 MIPS32 COP1 Encoding of rs Field - 0x1: decode RS_MSB { - - 0x0: decode RS_HI { - 0x0: decode RS_LO { - 0x0: mfc1({{ }}); - 0x2: cfc1({{ }}); - 0x3: mfhc1({{ }}); - 0x4: mtc1({{ }}); - 0x6: ctc1({{ }}); - 0x7: mftc1({{ }}); - } - - 0x1: decode ND { - 0x0: decode TF { - format Branch { - 0x0: bc1f({{ cond = (xc->miscRegs.fpcr == 0); }}); - 0x1: bc1t({{ cond = (xc->miscRegs.fpcr == 1); }}); - } - } - - 0x1: decode TF { - format Branch { - 0x0: bc1fl({{ cond = (xc->miscRegs.fpcr == 0); }}); - 0x1: bc1tl({{ cond = (xc->miscRegs.fpcr == 1); }}); - } - } - } - } - - 0x1: decode RS_HI { - 0x2: decode RS_LO { - - //Table A-14 MIPS32 COP1 Encoding of Function Field When rs=S - //(( single-word )) - 0x0: decode RS_HI { - 0x0: decode RS_LO { - 0x0: add_fmt({{ }}); - 0x1: sub_fmt({{ }}); - 0x2: mul_fmt({{ }}); - 0x3: div_fmt({{ }}); - 0x4: sqrt_fmt({{ }}); - 0x5: abs_fmt({{ }}); - 0x6: mov_fmt({{ }}); - 0x7: neg_fmt({{ }}); - } - - 0x1: decode RS_LO { - //only legal for 64 bit - format mode64 { - 0x0: round_l({{ }}); - 0x1: trunc_l({{ }}); - 0x2: ceil_l({{ }}); - 0x3: floor_l({{ }}); - } - - 0x4: round_w({{ }}); - 0x5: trunc_w({{ }}); - 0x6: ceil_w({{ }}); - 0x7: floor_w({{ }}); - } - - 0x2: decode RS_LO { - 0x1: decode MOVCF { - 0x0: movf_fmt({{ }}); - 0x1: movt_fmt({{ }}); - } - - format Move { - 0x2: movz({{ if (Rt == 0) Rd = Rs; }}); - 0x3: movn({{ if (Rt != 0) Rd = Rs; }}); - } - - format mode64 { - 0x2: recip({{ }}); - 0x3: rsqrt{{ }}); - } - } - - 0x4: decode RS_LO { - 0x1: cvt_d({{ }}); - 0x4: cvt_w({{ }}); - - //only legal for 64 bit - format mode64 { - 0x5: cvt_l({{ }}); - 0x6: cvt_ps({{ }}); - } - } - } - - //Table A-15 MIPS32 COP1 Encoding of Function Field When rs=D - 0x1: decode RS_HI { - 0x0: decode RS_LO { - 0x0: add_fmt({{ }}); - 0x1: sub_fmt({{ }}); - 0x2: mul_fmt({{ }}); - 0x3: div_fmt({{ }}); - 0x4: sqrt_fmt({{ }}); - 0x5: abs_fmt({{ }}); - 0x6: mov_fmt({{ }}); - 0x7: neg_fmt({{ }}); - } - - 0x1: decode RS_LO { - //only legal for 64 bit - format mode64 { - 0x0: round_l({{ }}); - 0x1: trunc_l({{ }}); - 0x2: ceil_l({{ }}); - 0x3: floor_l({{ }}); - } - - 0x4: round_w({{ }}); - 0x5: trunc_w({{ }}); - 0x6: ceil_w({{ }}); - 0x7: floor_w({{ }}); - } - - 0x2: decode RS_LO { - 0x1: decode MOVCF { - 0x0: movf_fmt({{ }}); - 0x1: movt_fmt({{ }}); - } - - format Move { - 0x2: movz({{ if (Rt == 0) Rd = Rs; }}); - 0x3: movn({{ if (Rt != 0) Rd = Rs; }}); - } - - format mode64 { - 0x5: recip({{ }}); - 0x6: rsqrt{{ }}); - } - } - - 0x4: decode RS_LO { - 0x0: cvt_s({{ }}); - 0x4: cvt_w({{ }}); - - //only legal for 64 bit - format mode64 { - 0x5: cvt_l({{ }}); - } - } - } - - //Table A-16 MIPS32 COP1 Encoding of Function Field When rs=W - 0x4: decode FUNCTION { - 0x10: cvt_s({{ }}); - 0x10: cvt_d({{ }}); - } - - //Table A-16 MIPS32 COP1 Encoding of Function Field When rs=L1 - //Note: "1. Format type L is legal only if 64-bit floating point operations - //are enabled." - 0x5: decode FUNCTION_HI { - 0x10: cvt_s({{ }}); - 0x11: cvt_d({{ }}); - } - - //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 { - 0x0: add_fmt({{ }}); - 0x1: sub_fmt({{ }}); - 0x2: mul_fmt({{ }}); - 0x5: abs_fmt({{ }}); - 0x6: mov_fmt({{ }}); - 0x7: neg_fmt({{ }}); - } - - 0x2: decode RS_LO { - 0x1: decode MOVCF { - 0x0: movf_fmt({{ }}); - 0x1: movt_fmt({{ }}); - } - - } - - 0x4: decode RS_LO { - 0x0: cvt_s_pu({{ }}); - } - - 0x5: decode RS_LO { - 0x0: cvt_s_pl({{ }}); - 0x4: pll_s_pl({{ }}); - 0x5: plu_s_pl({{ }}); - 0x6: pul_s_pl({{ }}); - 0x7: puu_s_pl({{ }}); - } - } - } - - //Table A-19 MIPS32 COP2 Encoding of rs Field - 0x2: decode RS_MSB { - 0x0: decode RS_HI { - 0x0: decode RS_LO { - 0x0: mfc2({{ }}); - 0x2: cfc2({{ }}); - 0x3: mfhc2({{ }}); - 0x4: mtc2({{ }}); - 0x6: ctc2({{ }}); - 0x7: mftc2({{ }}); - } - - 0x1: decode ND { - 0x0: decode TF { - format Branch { - 0x0: bc2f({{ cond = (xc->miscRegs.cop2cc == 0); }}, COP2); - 0x1: bc2t({{ cond = (xc->miscRegs.cop2cc == 1); }}, COP2}}); - } - } - - 0x1: decode TF { - format Branch { - 0x0: bc2fl({{ cond = (xc->miscRegs.cop2cc == 0); }}, COP2}}); - 0x1: bc2tl({{ cond = (xc->miscRegs.cop2cc == 1); }}, COP2}}); - } - } - } - } - } - - //Table A-20 MIPS64 COP1X Encoding of Function Field 1 - //Note: "COP1X instructions are legal only if 64-bit floating point - //operations are enabled." - 0x3: decode FUNCTION_HI { - 0x0: decode FUNCTION_LO { - 0x0: lwxc1({{ }}); - 0x1: ldxc1({{ }}); - 0x5: luxc1({{ }}); - } - - 0x1: decode FUNCTION_LO { - 0x0: swxc1({{ }}); - 0x1: sdxc1({{ }}); - 0x5: suxc1({{ }}); - 0x7: prefx({{ }}); - } - - 0x3: alnv_ps({{ }}); - - 0x4: decode FUNCTION_LO { - 0x0: madd_s({{ }}); - 0x1: madd_d({{ }}); - 0x6: madd_ps({{ }}); - } - - 0x5: decode FUNCTION_LO { - 0x0: msub_s({{ }}); - 0x1: msub_d({{ }}); - 0x6: msub_ps({{ }}); - } - - 0x6: decode FUNCTION_LO { - 0x0: nmadd_s({{ }}); - 0x1: nmadd_d({{ }}); - 0x6: nmadd_ps({{ }}); - } - - 0x7: decode FUNCTION_LO { - 0x0: nmsub_s({{ }}); - 0x1: nmsub_d({{ }}); - 0x6: nmsub_ps({{ }}); - } - } - - //MIPS obsolete instructions - 0x4: beql({{ cond = (Rs.sq == 0); }}); - 0x5: bnel({{ cond = (Rs.sq != 0); }}); - 0x6: blezl({{ cond = (Rs.sq <= 0); }}); - 0x7: bgtzl({{ cond = (Rs.sq > 0); }}); - }; - - 0x3: decode OPCODE_LO default FailUnimpl::reserved() { - - //Table A-5 MIPS32 SPECIAL2 Encoding of Function Field - 0x4: decode FUNCTION_HI { - - 0x0: decode FUNCTION_LO { - format IntOp { - 0x0: madd({{ - INT64 temp1 = Hi.sw << 32 | Lo.sw >> 32; - temp1 = temp1 + (Rs.sw * Rt.sw); - xc->miscRegs.Hi->temp1<63:32>; - xc->miscRegs.Lo->temp1<31:0> - }}); - - 0x1: maddu({{ - INT64 temp1 = Hi.uw << 32 | Lo.uw >> 32; - temp1 = temp1 + (Rs.uw * Rt.uw); - xc->miscRegs.Hi->temp1<63:32>; - xc->miscRegs.Lo->temp1<31:0> - }}); - - 0x2: mul({{ Rd.sw = Rs.sw * Rt.sw; }}); - - 0x4: msub({{ - INT64 temp1 = Hi.sw << 32 | Lo.sw >> 32; - temp1 = temp1 - (Rs.sw * Rt.sw); - xc->miscRegs.Hi->temp1<63:32>; - xc->miscRegs.Lo->temp1<31:0> - }}); - - 0x5: msubu({{ - INT64 temp1 = Hi.uw << 32 | Lo.uw >> 32; - temp1 = temp1 - (Rs.uw * Rt.uw); - xc->miscRegs.Hi->temp1<63:32>; - xc->miscRegs.Lo->temp1<31:0> - }}); - } - } - - 0x4: decode FUNCTION_LO { - 0x0: clz({{ }}); - 0x1: clo({{ }}); - } - - 0x7: decode FUNCTION_LO { - 0x7: sdbbp({{ }}); - } - } - - //Table A-6 MIPS32 SPECIAL3 Encoding of Function Field for Release 2 of the Architecture - 0x7: decode FUNCTION_HI { - - 0x0: decode FUNCTION_LO { - 0x1: ext({{ }}); - 0x4: ins({{ }}); - } - - //Table A-10 MIPS32 BSHFL Encoding of sa Field - 0x4: decode SA { - 0x02: wsbh({{ }}); - 0x10: seb({{ }}); - 0x18: seh({{ }}); - } - - 0x6: decode FUNCTION_LO { - 0x7: rdhwr({{ }}); - } - } - }; - - 0x4: decode OPCODE_LO default FailUnimpl::reserved() { - format Memory { - 0x0: lb({{ EA = Rs + disp; }}, {{ Rb.sw = Mem.sb; }}); - 0x1: lh({{ EA = Rs + disp; }}, {{ Rb.sw = Mem.sh; }}); - 0x2: lwl({{ EA = Rs + disp; }}, {{ Rb.sw = Mem.sw; }}, WordAlign); - 0x3: lw({{ EA = Rs + disp; }}, {{ Rb.uq = Mem.sb; }}); - 0x4: lbu({{ EA = Rs + disp; }}, {{ Rb.uw = Mem.ub; }}); - 0x5: lhu({{ EA = Rs + disp; }}, {{ Rb.uw = Mem.uh; }}); - 0x6: lwr({{ EA = Rs + disp; }}, {{ Rb.uw = Mem.uw; }}, WordAlign); - }; - - 0x7: FailUnimpl::reserved({{ }}); - }; - - 0x5: decode OPCODE_LO default FailUnimpl::reserved() { - format Memory { - 0x0: sb({{ EA = Rs + disp; }}, {{ Mem.ub = Rt<7:0>; }}); - 0x1: sh({{ EA = Rs + disp; }},{{ Mem.uh = Rt<15:0>; }}); - 0x2: swl({{ EA = Rs + disp; }},{{ Mem.ub = Rt<31:0>; }},WordAlign); - 0x3: sw({{ EA = Rs + disp; }},{{ Mem.ub = Rt<31:0>; }}); - 0x6: swr({{ EA = Rs + disp; }},{{ Mem.ub = Rt<31:0>; }},WordAlign); - }; - - format FailUnimpl { - 0x4: reserved({{ }}); - 0x5: reserved({{ }}); - 0x7: cache({{ }}); - }; - - }; - - 0x6: decode OPCODE_LO default FailUnimpl::reserved() { - format Memory { - 0x0: ll({{ }}); - 0x1: lwc1({{ EA = Rs + disp; }},{{ Ft<31:0> = Mem.uf; }}); - 0x5: ldc1({{ EA = Rs + disp; }},{{ Ft<63:0> = Mem.df; }}); - }; - }; - - 0x7: decode OPCODE_LO default FailUnimpl::reserved() { - format Memory { - 0x0: sc({{ }}); - 0x1: swc1({{ EA = Rs + disp; }},{{ Mem.uf = Ft<31:0>; }}); - 0x5: sdc1({{ EA = Rs + disp; }},{{ Mem.df = Ft<63:0>; }}); - }; - - } -} - - diff --git a/arch/mips/isa/decoder.isa b/arch/mips/isa/decoder.isa new file mode 100644 index 000000000..f0c3fc562 --- /dev/null +++ b/arch/mips/isa/decoder.isa @@ -0,0 +1,643 @@ +//////////////////////////////////////////////////////////////////// +// +// The actual MIPS32 ISA decoder +// ----------------------------- +// The following instructions are specified in the MIPS32 ISA +// Specification. Decoding closely follows the style specified +// in the MIPS32 ISAthe specification document starting with Table +// A-2 (document available @ www.mips.com) +// +//@todo: Distinguish "unknown/future" use insts from "reserved" +// ones +decode OPCODE_HI default FailUnimpl::unknown() { + + // Derived From ... Table A-2 MIPS32 ISA Manual + 0x0: decode OPCODE_LO default FailUnimpl::reserved(){ + + 0x0: decode FUNCTION_HI { + 0x0: decode FUNCTION_LO { + 0x1: decode MOVCI { + format Move { + 0: movf({{ if( xc->miscRegs.fpcr == 0) Rd = Rs}}); + 1: movt({{ if( xc->miscRegs.fpcr == 1) Rd = Rs}}); + } + } + + format BasicOp { + + //Table A-3 Note: "1. Specific encodings of the rt, rd, and sa fields + //are used to distinguish among the SLL, NOP, SSNOP and EHB functions." + + 0x0: sll({{ Rd = Rt.uw << SA; }}); + + 0x2: decode SRL { + 0: srl({{ Rd = Rt.uw >> SA; }}); + + //Hardcoded assuming 32-bit ISA, probably need parameter here + 1: rotr({{ Rd = (Rt.uw << (32 - SA)) | (Rt.uw >> SA);}}); + } + + 0x3: sra({{ Rd = Rt.sw >> SA; }}); + + 0x4: sllv({{ Rd = Rt.uw << Rs<4:0>; }}); + + 0x6: decode SRLV { + 0: srlv({{ Rd = Rt.uw >> Rs<4:0>; }}); + + //Hardcoded assuming 32-bit ISA, probably need parameter here + 1: rotrv({{ Rd = (Rt.uw << (32 - Rs<4:0>)) | (Rt.uw >> Rs<4:0>);}}); + } + + 0x7: srav({{ Rd = Rt.sw >> Rs<4:0>; }}); + } + } + + 0x1: decode FUNCTION_LO { + + //Table A-3 Note: "Specific encodings of the hint field are used + //to distinguish JR from JR.HB and JALR from JALR.HB" + format Jump { + 0x0: jr(IsReturn); + 0x1: jalr(IsCall,IsReturn); + } + + format Move { + 0x2: movz({{ if (Rt == 0) Rd = Rs; }}); + 0x3: movn({{ if (Rt != 0) Rd = Rs; }}); + } + + format Trap { + 0x4: syscall({{ xc->syscall()}},IsNonSpeculative); + 0x5: break({{ }}); + 0x7: sync({{ }}); + } + } + + 0x2: decode FUNCTION_LO { + format BasicOp { + 0x0: mfhi({{ Rd = xc->miscRegs.Hi; }}); + 0x1: mthi({{ xc->miscRegs.Hi = Rs; }}); + 0x2: mflo({{ Rd = xc->miscRegs.Lo; }}); + 0x3: mtlo({{ xc->miscRegs.Lo = Rs; }}); + } + }; + + 0x3: decode FUNCTION_LO { + format IntOp { + 0x0: mult({{ + INT64 temp1 = Rs.sw * Rt.sw; + xc->miscRegs.Hi->temp1<63:32>; + xc->miscRegs.Lo->temp1<31:0> + }}); + + 0x1: multu({{ + INT64 temp1 = Rs.uw * Rt.uw; + xc->miscRegs.Hi->temp1<63:32>; + xc->miscRegs.Lo->temp1<31:0> + Rd.sw = Rs.uw * Rt.uw; + }}); + + 0x2: div({{ + xc->miscRegs.Hi = Rs.sw % Rt.sw; + xc->miscRegs.Lo = Rs.sw / Rt.sw; + }}); + + 0x3: divu({{ + xc->miscRegs.Hi = Rs.uw % Rt.uw; + xc->miscRegs.Lo = Rs.uw / Rt.uw; + }}); + } + }; + + 0x4: decode FUNCTION_LO { + format IntOp { + 0x0: add({{ Rd.sw = Rs.sw + Rt.sw;}}); + 0x1: addu({{ Rd.uw = Rs.uw + Rt.uw;}}); + 0x2: sub({{ Rd.sw = Rs.sw - Rt.sw;}}); + 0x3: subu({{ Rd.uw = Rs.uw - Rt.uw;}}); + 0x4: and({{ Rd.sw = Rs.uw & Rt.uw;}}); + 0x5: or({{ Rd.sw = Rs.uw | Rt.uw;}}); + 0x6: xor({{ Rd.sw = Rs.uw ^ Rt.uw;}}); + 0x7: nor({{ Rd.sw = ~(Rs.uw | Rt.uw);}}); + } + } + + 0x5: decode FUNCTION_LO { + format IntOp{ + 0x2: slt({{ Rd.sw = ( Rs.sw < Rt.sw ) ? 1 : 0}}); + 0x3: sltu({{ Rd.uw = ( Rs.uw < Rt.uw ) ? 1 : 0}}); + } + }; + + 0x6: decode FUNCTION_LO { + format Trap { + 0x0: tge({{ }}); + 0x1: tgeu({{ }}); + 0x2: tlt({{ }}); + 0x3: tltu({{ }}); + 0x4: teq({{ }}); + 0x6: tne({{ }}); + } + } + } + + 0x1: decode REGIMM_HI { + 0x0: decode REGIMM_LO { + format Branch { + 0x0: bltz({{ cond = (Rs.sq < 0); }}); + 0x1: bgez({{ cond = (Rs.sq >= 0); }}); + + //MIPS obsolete instructions + 0x2: bltzl({{ cond = (Rs.sq < 0); }}); + 0x3: bgezl({{ cond = (Rs.sq >= 0); }}); + } + } + + 0x1: decode REGIMM_LO { + format Trap { + 0x0: tgei({{ }}); + 0x1: tgeiu({{ }}); + 0x2: tlti({{ }}); + 0x3: tltiu({{ }}); + 0x4: teqi({{ }}); + 0x6: tnei({{ }}); + } + } + + 0x2: decode REGIMM_LO { + format Branch { + 0x0: bltzal({{ cond = (Rs.sq < 0); }}); + 0x1: bgezal({{ cond = (Rs.sq >= 0); }}); + + //MIPS obsolete instructions + 0x2: bltzall({{ cond = (Rs.sq < 0); }}); + 0x3: bgezall({{ cond = (Rs.sq >= 0); }}); + } + } + + 0x3: decode REGIMM_LO { + format Trap { + 0x7: synci({{ }}); + } + } + } + + format Jump { + 0x2: j(); + 0x3: jal(IsCall); + } + + format Branch { + 0x4: beq({{ cond = (Rs.sq == 0); }}); + 0x5: bne({{ cond = (Rs.sq != 0); }}); + 0x6: blez({{ cond = (Rs.sq <= 0); }}); + 0x7: bgtz({{ cond = (Rs.sq > 0); }}); + } + }; + + 0x1: decode OPCODE_LO default FailUnimpl::reserved(){ + format IntOp { + 0x0: addi({{ Rt.sw = Rs.sw + INTIMM; }}); + 0x1: addiu({{ Rt.uw = Rs.uw + INTIMM;}}); + 0x2: slti({{ Rt.sw = ( Rs.sw < INTIMM ) ? 1 : 0 }}); + 0x3: sltiu({{ Rt.uw = ( Rs.uw < INTIMM ) ? 1 : 0 }}); + 0x4: andi({{ Rt.sw = Rs.sw & INTIMM;}}); + 0x5: ori({{ Rt.sw = Rs.sw | INTIMM;}}); + 0x6: xori({{ Rt.sw = Rs.sw ^ INTIMM;}}); + 0x7: lui({{ Rt = INTIMM << 16}}); + }; + }; + + 0x2: decode OPCODE_LO default FailUnimpl::reserved(){ + + //Table A-11 MIPS32 COP0 Encoding of rs Field + 0x0: decode RS_MSB { + 0x0: decode RS { + 0x0: mfc0({{ }}); + 0xC: mtc0({{ }}); + 0xA: rdpgpr({{ }}); + + 0xB: decode SC { + format BasicOp { + 0x0: di({{ }}); + 0x1: ei({{ }}); + } + } + + 0xE: wrpgpr({{ }}); + } + + //Table A-12 MIPS32 COP0 Encoding of Function Field When rs=CO + 0x1: decode FUNCTION { + format Trap { + 0x01: tlbr({{ }}); + 0x02: tlbwi({{ }}); + 0x06: tlbwr({{ }}); + 0x08: tlbp({{ }}); + } + + format BasicOp { + 0x18: eret({{ }}); + 0x1F: deret({{ }}); + 0x20: wait({{ }}); + } + } + } + + //Table A-13 MIPS32 COP1 Encoding of rs Field + 0x1: decode RS_MSB { + + 0x0: decode RS_HI { + 0x0: decode RS_LO { + 0x0: mfc1({{ }}); + 0x2: cfc1({{ }}); + 0x3: mfhc1({{ }}); + 0x4: mtc1({{ }}); + 0x6: ctc1({{ }}); + 0x7: mftc1({{ }}); + } + + 0x1: decode ND { + 0x0: decode TF { + format Branch { + 0x0: bc1f({{ cond = (xc->miscRegs.fpcr == 0); }}); + 0x1: bc1t({{ cond = (xc->miscRegs.fpcr == 1); }}); + } + } + + 0x1: decode TF { + format Branch { + 0x0: bc1fl({{ cond = (xc->miscRegs.fpcr == 0); }}); + 0x1: bc1tl({{ cond = (xc->miscRegs.fpcr == 1); }}); + } + } + } + } + + 0x1: decode RS_HI { + 0x2: decode RS_LO { + + //Table A-14 MIPS32 COP1 Encoding of Function Field When rs=S + //(( single-word )) + 0x0: decode RS_HI { + 0x0: decode RS_LO { + 0x0: add_fmt({{ }}); + 0x1: sub_fmt({{ }}); + 0x2: mul_fmt({{ }}); + 0x3: div_fmt({{ }}); + 0x4: sqrt_fmt({{ }}); + 0x5: abs_fmt({{ }}); + 0x6: mov_fmt({{ }}); + 0x7: neg_fmt({{ }}); + } + + 0x1: decode RS_LO { + //only legal for 64 bit + format mode64 { + 0x0: round_l({{ }}); + 0x1: trunc_l({{ }}); + 0x2: ceil_l({{ }}); + 0x3: floor_l({{ }}); + } + + 0x4: round_w({{ }}); + 0x5: trunc_w({{ }}); + 0x6: ceil_w({{ }}); + 0x7: floor_w({{ }}); + } + + 0x2: decode RS_LO { + 0x1: decode MOVCF { + 0x0: movf_fmt({{ }}); + 0x1: movt_fmt({{ }}); + } + + format Move { + 0x2: movz({{ if (Rt == 0) Rd = Rs; }}); + 0x3: movn({{ if (Rt != 0) Rd = Rs; }}); + } + + format mode64 { + 0x2: recip({{ }}); + 0x3: rsqrt{{ }}); + } + } + + 0x4: decode RS_LO { + 0x1: cvt_d({{ }}); + 0x4: cvt_w({{ }}); + + //only legal for 64 bit + format mode64 { + 0x5: cvt_l({{ }}); + 0x6: cvt_ps({{ }}); + } + } + } + + //Table A-15 MIPS32 COP1 Encoding of Function Field When rs=D + 0x1: decode RS_HI { + 0x0: decode RS_LO { + 0x0: add_fmt({{ }}); + 0x1: sub_fmt({{ }}); + 0x2: mul_fmt({{ }}); + 0x3: div_fmt({{ }}); + 0x4: sqrt_fmt({{ }}); + 0x5: abs_fmt({{ }}); + 0x6: mov_fmt({{ }}); + 0x7: neg_fmt({{ }}); + } + + 0x1: decode RS_LO { + //only legal for 64 bit + format mode64 { + 0x0: round_l({{ }}); + 0x1: trunc_l({{ }}); + 0x2: ceil_l({{ }}); + 0x3: floor_l({{ }}); + } + + 0x4: round_w({{ }}); + 0x5: trunc_w({{ }}); + 0x6: ceil_w({{ }}); + 0x7: floor_w({{ }}); + } + + 0x2: decode RS_LO { + 0x1: decode MOVCF { + 0x0: movf_fmt({{ }}); + 0x1: movt_fmt({{ }}); + } + + format Move { + 0x2: movz({{ if (Rt == 0) Rd = Rs; }}); + 0x3: movn({{ if (Rt != 0) Rd = Rs; }}); + } + + format mode64 { + 0x5: recip({{ }}); + 0x6: rsqrt{{ }}); + } + } + + 0x4: decode RS_LO { + 0x0: cvt_s({{ }}); + 0x4: cvt_w({{ }}); + + //only legal for 64 bit + format mode64 { + 0x5: cvt_l({{ }}); + } + } + } + + //Table A-16 MIPS32 COP1 Encoding of Function Field When rs=W + 0x4: decode FUNCTION { + 0x10: cvt_s({{ }}); + 0x10: cvt_d({{ }}); + } + + //Table A-16 MIPS32 COP1 Encoding of Function Field When rs=L1 + //Note: "1. Format type L is legal only if 64-bit floating point operations + //are enabled." + 0x5: decode FUNCTION_HI { + 0x10: cvt_s({{ }}); + 0x11: cvt_d({{ }}); + } + + //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 { + 0x0: add_fmt({{ }}); + 0x1: sub_fmt({{ }}); + 0x2: mul_fmt({{ }}); + 0x5: abs_fmt({{ }}); + 0x6: mov_fmt({{ }}); + 0x7: neg_fmt({{ }}); + } + + 0x2: decode RS_LO { + 0x1: decode MOVCF { + 0x0: movf_fmt({{ }}); + 0x1: movt_fmt({{ }}); + } + + } + + 0x4: decode RS_LO { + 0x0: cvt_s_pu({{ }}); + } + + 0x5: decode RS_LO { + 0x0: cvt_s_pl({{ }}); + 0x4: pll_s_pl({{ }}); + 0x5: plu_s_pl({{ }}); + 0x6: pul_s_pl({{ }}); + 0x7: puu_s_pl({{ }}); + } + } + } + + //Table A-19 MIPS32 COP2 Encoding of rs Field + 0x2: decode RS_MSB { + 0x0: decode RS_HI { + 0x0: decode RS_LO { + 0x0: mfc2({{ }}); + 0x2: cfc2({{ }}); + 0x3: mfhc2({{ }}); + 0x4: mtc2({{ }}); + 0x6: ctc2({{ }}); + 0x7: mftc2({{ }}); + } + + 0x1: decode ND { + 0x0: decode TF { + format Branch { + 0x0: bc2f({{ cond = (xc->miscRegs.cop2cc == 0); }}, COP2); + 0x1: bc2t({{ cond = (xc->miscRegs.cop2cc == 1); }}, COP2}}); + } + } + + 0x1: decode TF { + format Branch { + 0x0: bc2fl({{ cond = (xc->miscRegs.cop2cc == 0); }}, COP2}}); + 0x1: bc2tl({{ cond = (xc->miscRegs.cop2cc == 1); }}, COP2}}); + } + } + } + } + } + + //Table A-20 MIPS64 COP1X Encoding of Function Field 1 + //Note: "COP1X instructions are legal only if 64-bit floating point + //operations are enabled." + 0x3: decode FUNCTION_HI { + 0x0: decode FUNCTION_LO { + 0x0: lwxc1({{ }}); + 0x1: ldxc1({{ }}); + 0x5: luxc1({{ }}); + } + + 0x1: decode FUNCTION_LO { + 0x0: swxc1({{ }}); + 0x1: sdxc1({{ }}); + 0x5: suxc1({{ }}); + 0x7: prefx({{ }}); + } + + 0x3: alnv_ps({{ }}); + + 0x4: decode FUNCTION_LO { + 0x0: madd_s({{ }}); + 0x1: madd_d({{ }}); + 0x6: madd_ps({{ }}); + } + + 0x5: decode FUNCTION_LO { + 0x0: msub_s({{ }}); + 0x1: msub_d({{ }}); + 0x6: msub_ps({{ }}); + } + + 0x6: decode FUNCTION_LO { + 0x0: nmadd_s({{ }}); + 0x1: nmadd_d({{ }}); + 0x6: nmadd_ps({{ }}); + } + + 0x7: decode FUNCTION_LO { + 0x0: nmsub_s({{ }}); + 0x1: nmsub_d({{ }}); + 0x6: nmsub_ps({{ }}); + } + } + + //MIPS obsolete instructions + 0x4: beql({{ cond = (Rs.sq == 0); }}); + 0x5: bnel({{ cond = (Rs.sq != 0); }}); + 0x6: blezl({{ cond = (Rs.sq <= 0); }}); + 0x7: bgtzl({{ cond = (Rs.sq > 0); }}); + }; + + 0x3: decode OPCODE_LO default FailUnimpl::reserved() { + + //Table A-5 MIPS32 SPECIAL2 Encoding of Function Field + 0x4: decode FUNCTION_HI { + + 0x0: decode FUNCTION_LO { + format IntOp { + 0x0: madd({{ + INT64 temp1 = Hi.sw << 32 | Lo.sw >> 32; + temp1 = temp1 + (Rs.sw * Rt.sw); + xc->miscRegs.Hi->temp1<63:32>; + xc->miscRegs.Lo->temp1<31:0> + }}); + + 0x1: maddu({{ + INT64 temp1 = Hi.uw << 32 | Lo.uw >> 32; + temp1 = temp1 + (Rs.uw * Rt.uw); + xc->miscRegs.Hi->temp1<63:32>; + xc->miscRegs.Lo->temp1<31:0> + }}); + + 0x2: mul({{ Rd.sw = Rs.sw * Rt.sw; }}); + + 0x4: msub({{ + INT64 temp1 = Hi.sw << 32 | Lo.sw >> 32; + temp1 = temp1 - (Rs.sw * Rt.sw); + xc->miscRegs.Hi->temp1<63:32>; + xc->miscRegs.Lo->temp1<31:0> + }}); + + 0x5: msubu({{ + INT64 temp1 = Hi.uw << 32 | Lo.uw >> 32; + temp1 = temp1 - (Rs.uw * Rt.uw); + xc->miscRegs.Hi->temp1<63:32>; + xc->miscRegs.Lo->temp1<31:0> + }}); + } + } + + 0x4: decode FUNCTION_LO { + 0x0: clz({{ }}); + 0x1: clo({{ }}); + } + + 0x7: decode FUNCTION_LO { + 0x7: sdbbp({{ }}); + } + } + + //Table A-6 MIPS32 SPECIAL3 Encoding of Function Field for Release 2 of the Architecture + 0x7: decode FUNCTION_HI { + + 0x0: decode FUNCTION_LO { + 0x1: ext({{ }}); + 0x4: ins({{ }}); + } + + //Table A-10 MIPS32 BSHFL Encoding of sa Field + 0x4: decode SA { + 0x02: wsbh({{ }}); + 0x10: seb({{ }}); + 0x18: seh({{ }}); + } + + 0x6: decode FUNCTION_LO { + 0x7: rdhwr({{ }}); + } + } + }; + + 0x4: decode OPCODE_LO default FailUnimpl::reserved() { + format Memory { + 0x0: lb({{ EA = Rs + disp; }}, {{ Rb.sw = Mem.sb; }}); + 0x1: lh({{ EA = Rs + disp; }}, {{ Rb.sw = Mem.sh; }}); + 0x2: lwl({{ EA = Rs + disp; }}, {{ Rb.sw = Mem.sw; }}, WordAlign); + 0x3: lw({{ EA = Rs + disp; }}, {{ Rb.uq = Mem.sb; }}); + 0x4: lbu({{ EA = Rs + disp; }}, {{ Rb.uw = Mem.ub; }}); + 0x5: lhu({{ EA = Rs + disp; }}, {{ Rb.uw = Mem.uh; }}); + 0x6: lwr({{ EA = Rs + disp; }}, {{ Rb.uw = Mem.uw; }}, WordAlign); + }; + + 0x7: FailUnimpl::reserved({{ }}); + }; + + 0x5: decode OPCODE_LO default FailUnimpl::reserved() { + format Memory { + 0x0: sb({{ EA = Rs + disp; }}, {{ Mem.ub = Rt<7:0>; }}); + 0x1: sh({{ EA = Rs + disp; }},{{ Mem.uh = Rt<15:0>; }}); + 0x2: swl({{ EA = Rs + disp; }},{{ Mem.ub = Rt<31:0>; }},WordAlign); + 0x3: sw({{ EA = Rs + disp; }},{{ Mem.ub = Rt<31:0>; }}); + 0x6: swr({{ EA = Rs + disp; }},{{ Mem.ub = Rt<31:0>; }},WordAlign); + }; + + format FailUnimpl { + 0x4: reserved({{ }}); + 0x5: reserved({{ }}); + 0x7: cache({{ }}); + }; + + }; + + 0x6: decode OPCODE_LO default FailUnimpl::reserved() { + format Memory { + 0x0: ll({{ }}); + 0x1: lwc1({{ EA = Rs + disp; }},{{ Ft<31:0> = Mem.uf; }}); + 0x5: ldc1({{ EA = Rs + disp; }},{{ Ft<63:0> = Mem.df; }}); + }; + }; + + 0x7: decode OPCODE_LO default FailUnimpl::reserved() { + format Memory { + 0x0: sc({{ }}); + 0x1: swc1({{ EA = Rs + disp; }},{{ Mem.uf = Ft<31:0>; }}); + 0x5: sdc1({{ EA = Rs + disp; }},{{ Mem.df = Ft<63:0>; }}); + }; + + } +} + + diff --git a/arch/mips/isa/formats.def b/arch/mips/isa/formats.isa similarity index 100% rename from arch/mips/isa/formats.def rename to arch/mips/isa/formats.isa diff --git a/arch/mips/isa/formats/int.format b/arch/mips/isa/formats/int.format index 9b2d8d38e..edfdddb18 100644 --- a/arch/mips/isa/formats/int.format +++ b/arch/mips/isa/formats/int.format @@ -19,20 +19,6 @@ output header {{ std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; }; - /** - * Derived class for integer immediate operations. - */ - class IntImm : public IntOp - { - protected: - - /// Constructor - IntegerImm(const char *mnem, MachInst _machInst, OpClass __opClass) : MipsStaticInst(mnem, _machInst, __opClass) - { - } - - std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; - }; }}; output decoder {{ @@ -41,7 +27,7 @@ output decoder {{ return "Disassembly of integer instruction\n"; } - std::string IntImm::generateDisassembly(Addr pc, const SymbolTable *symtab) const + std::string IntImmOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const { return "Disassembly of integer immediate instruction\n"; } @@ -50,16 +36,9 @@ output decoder {{ def template IntExecute {{ Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const { - //These are set to constants when the execute method - //is generated - bool useCc = ; - bool checkPriv = ; - //Attempt to execute the instruction try { - checkPriv; - %(op_decl)s; %(op_rd)s; %(code)s; @@ -74,34 +53,15 @@ def template IntExecute {{ //Write the resulting state to the execution context %(op_wb)s; - if(useCc) - { - xc->regs.miscRegFile.ccrFields.iccFields.n = Rd & (1 << 63); - xc->regs.miscRegFile.ccrFields.iccFields.z = (Rd == 0); - xc->regs.miscRegFile.ccrFields.iccFields.v = ivValue; - xc->regs.miscRegFile.ccrFields.iccFields.c = icValue; - xc->regs.miscRegFile.ccrFields.xccFields.n = Rd & (1 << 31); - xc->regs.miscRegFile.ccrFields.xccFields.z = ((Rd & 0xFFFFFFFF) == 0); - xc->regs.miscRegFile.ccrFields.xccFields.v = xvValue; - xc->regs.miscRegFile.ccrFields.xccFields.c = xcValue; - } + return No_Fault; } }}; // Primary format for integer operate instructions: -def format IntegerOp(code, *opt_flags) {{ +def format IntOp(code, *opt_flags) {{ orig_code = code cblk = CodeBlock(code) - checkPriv = (code.find('checkPriv') != -1) - code.replace('checkPriv', '') - if checkPriv: - code.replace('checkPriv;', 'if(!xc->regs.miscRegFile.pstateFields.priv) throw privileged_opcode;') - else: - code.replace('checkPriv;', '') - for (marker, value) in (('ivValue', '0'), ('icValue', '0'), - ('xvValue', '0'), ('xcValue', '0')): - code.replace(marker, value) iop = InstObjParams(name, Name, 'MipsStaticInst', cblk, opt_flags) header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) @@ -109,22 +69,3 @@ def format IntegerOp(code, *opt_flags) {{ exec_output = IntegerExecute.subst(iop) }}; -// Primary format for integer operate instructions: -def format IntegerOpCc(code, icValue, ivValue, xcValue, xvValue, *opt_flags) {{ - orig_code = code - cblk = CodeBlock(code) - checkPriv = (code.find('checkPriv') != -1) - code.replace('checkPriv', '') - if checkPriv: - code.replace('checkPriv;', 'if(!xc->regs.miscRegFile.pstateFields.priv) throw privileged_opcode;') - else: - code.replace('checkPriv;', '') - for (marker, value) in (('ivValue', ivValue), ('icValue', icValue), - ('xvValue', xvValue), ('xcValue', xcValue)): - code.replace(marker, value) - iop = InstObjParams(name, Name, 'MipsStaticInst', cblk, opt_flags) - header_output = BasicDeclare.subst(iop) - decoder_output = BasicConstructor.subst(iop) - decode_block = BasicDecodeWithMnemonic.subst(iop) - exec_output = IntegerExecute.subst(iop) -}}; diff --git a/arch/mips/isa/includes.h b/arch/mips/isa/includes.isa similarity index 100% rename from arch/mips/isa/includes.h rename to arch/mips/isa/includes.isa diff --git a/arch/mips/isa/operands.def b/arch/mips/isa/operands.isa similarity index 94% rename from arch/mips/isa/operands.def rename to arch/mips/isa/operands.isa index 16d8fbceb..58fa2d3cf 100644 --- a/arch/mips/isa/operands.def +++ b/arch/mips/isa/operands.isa @@ -17,8 +17,8 @@ def operands {{ 'Rs': IntRegOperandTraits('uw', 'RS', 'IsInteger', 2), 'Rt': IntRegOperandTraits('uw', 'RT', 'IsInteger', 3), - 'IntImm': IntRegOperandTraits('uw', 'INTIMM', 'IsInteger', 3), - 'Sa': IntRegOperandTraits('uw', 'SA', 'IsInteger', 4), + 'IntImm': IntRegOperandTraits('uw', 'INTIMM', 'IsInteger', 3), + 'Sa': IntRegOperandTraits('uw', 'SA', 'IsInteger', 4), 'Fd': FloatRegOperandTraits('sf', 'FD', 'IsFloating', 1), 'Fs': FloatRegOperandTraits('sf', 'FS', 'IsFloating', 2), From 7219693f4c425b5da1557823f92da13edda6b71a Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Tue, 7 Feb 2006 19:28:19 -0500 Subject: [PATCH 020/180] Actually we do need a separate class for Integer Ops with Immediates!!! The extra class is needed because of the necessisty of an immediate member variable. Also, added some 'very modest' python code to choose between the IntOp and the IntImmOp based on the instruction name ... --HG-- extra : convert_revision : f109c12418202a99b40e270360134e8335739836 --- arch/mips/isa/formats/int.format | 57 ++++++++++++++++---------------- 1 file changed, 28 insertions(+), 29 deletions(-) diff --git a/arch/mips/isa/formats/int.format b/arch/mips/isa/formats/int.format index edfdddb18..5b8df54e9 100644 --- a/arch/mips/isa/formats/int.format +++ b/arch/mips/isa/formats/int.format @@ -12,7 +12,22 @@ output header {{ protected: /// Constructor - IntegerOp(const char *mnem, MachInst _machInst, OpClass __opClass) : MipsStaticInst(mnem, _machInst, __opClass) + IntegerOp(const char *mnem, MachInst _machInst, OpClass __opClass) : + MipsStaticInst(mnem, _machInst, __opClass) + { + } + + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; + }; + + class IntImmOp : public MipsStaticInst + { + protected: + uint16_t imm; + + /// Constructor + IntegerOp(const char *mnem, MachInst _machInst, OpClass __opClass) : + MipsStaticInst(mnem, _machInst, __opClass),imm(INTIMM) { } @@ -33,39 +48,23 @@ output decoder {{ } }}; -def template IntExecute {{ - Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const - { - //Attempt to execute the instruction - try - { - %(op_decl)s; - %(op_rd)s; - %(code)s; - } - //If we have an exception for some reason, - //deal with it - catch(MipsException except) - { - //Deal with exception - return No_Fault; - } - - //Write the resulting state to the execution context - %(op_wb)s; - - return No_Fault; - } -}}; - // Primary format for integer operate instructions: def format IntOp(code, *opt_flags) {{ orig_code = code cblk = CodeBlock(code) - iop = InstObjParams(name, Name, 'MipsStaticInst', cblk, opt_flags) + + //Figure out if we are creating a IntImmOp or a IntOp + strlen = len(name) + if ( name[strlen-1] = 'i' or ( name[strlen-2:] = 'iu')) + iop = InstObjParams(name, Name, 'IntOp', cblk, opt_flags) + else: + iop = InstObjParams(name, Name, 'IntImmOp', cblk, opt_flags) + header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) - decode_block = BasicDecodeWithMnemonic.subst(iop) - exec_output = IntegerExecute.subst(iop) + decode_block = OperateNopCheckDecode.subst(iop) + exec_output = BasicExecute.subst(iop) }}; + + From 82f2ae56ed27b25f163db5ac4f2ccf0612640b07 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 8 Feb 2006 01:03:55 -0500 Subject: [PATCH 021/180] Alot of changes to push towards ISA independence. Highlights are renaming of the isa_desc files, movement of byte_swap.hh into sim, and the creation of arch/isa_traits.hh SConscript: Moved some files out of targetarch. The either no longer need to be there, never needed to be there, or should be referred to directly in arch/alpha due to there strictly alpha content. arch/alpha/isa_traits.hh: Added alpha's endianness to it's isa_traits.hh arch/mips/isa_traits.hh: Added MIPS endianness to it's isa_traits.hh arch/sparc/isa_traits.hh: Added SPARCs endianess to it's isa_traits.hh build/SConstruct: Added MIPS as a valid architecture cpu/exec_context.hh: Included arch/isa_traits.hh to bring in the endianness of the system. cpu/o3/alpha_cpu.hh: Included arch/isa_traits.hh to bring in the systems endianness, and removed the hardcoding of little endianness cpu/o3/fetch_impl.hh: kern/freebsd/freebsd_system.cc: Included arch/isa_traits.hh to bring in the systems endianness, and removed the hardcoding to little endianness. sim/system.cc: Included arch/isa_traits.hh to bring in the systems endianness, and removed the hardcoding to little endian. --HG-- extra : convert_revision : b1ab34b7569db531cd1c74f273b24222e63f9007 --- SConscript | 11 +++++++---- arch/alpha/isa_traits.hh | 3 +++ arch/mips/isa_traits.hh | 4 ++++ arch/sparc/isa_traits.hh | 4 ++++ build/SConstruct | 2 +- cpu/exec_context.hh | 1 + cpu/o3/alpha_cpu.hh | 6 ++++-- cpu/o3/fetch_impl.hh | 4 ++-- kern/freebsd/freebsd_system.cc | 5 +++-- sim/system.cc | 8 +++++--- 10 files changed, 34 insertions(+), 14 deletions(-) diff --git a/SConscript b/SConscript index 98dfad217..56a4e3610 100644 --- a/SConscript +++ b/SConscript @@ -339,24 +339,24 @@ syscall_emulation_sources = Split(''' # arch/alpha/alpha_tru64_process.cc targetarch_files = Split(''' - alpha_common_syscall_emul.hh alpha_linux_process.hh alpha_memory.hh alpha_tru64_process.hh aout_machdep.h arguments.hh - byte_swap.hh ecoff_machdep.h ev5.hh faults.hh isa_fullsys_traits.hh isa_traits.hh - osfpal.hh pseudo_inst.hh stacktrace.hh vptr.hh vtophys.hh ''') +# osfpal.hh +# byte_swap.hh +# alpha_common_syscall_emul.hh # Set up bridging headers to the architecture specific versions for f in targetarch_files: @@ -368,6 +368,9 @@ arch_source = SConscript('arch/%s/SConscript' % env['TARGET_ISA'], build_dir = 'build/%s/' % env['BUILD_DIR'], exports = 'env', duplicate = False) +# Add a flag defining what THE_ISA should be for all compilation +env.Append(CPPDEFINES=[('THE_ISA','%s_ISA' % env['TARGET_ISA'].upper())]) + # Set up complete list of sources based on configuration. sources = base_sources + arch_source @@ -432,7 +435,7 @@ env.Command(Split(''' env['TARGET_ISA'], env['TARGET_ISA'])), Split(''' - arch/%s/isa_desc + arch/%s/isa/main.isa arch/isa_parser.py''' % env['TARGET_ISA']), '$SRCDIR/arch/isa_parser.py $SOURCE $TARGET.dir arch/%s' % env['TARGET_ISA']) diff --git a/arch/alpha/isa_traits.hh b/arch/alpha/isa_traits.hh index 2570d12f0..a17cde49b 100644 --- a/arch/alpha/isa_traits.hh +++ b/arch/alpha/isa_traits.hh @@ -29,6 +29,9 @@ #ifndef __ARCH_ALPHA_ISA_TRAITS_HH__ #define __ARCH_ALPHA_ISA_TRAITS_HH__ +namespace LittleEndianGuest {} +using namespace LittleEndianGuest; + #include "arch/alpha/faults.hh" #include "base/misc.hh" #include "config/full_system.hh" diff --git a/arch/mips/isa_traits.hh b/arch/mips/isa_traits.hh index e8401cefb..55e9c0dcb 100644 --- a/arch/mips/isa_traits.hh +++ b/arch/mips/isa_traits.hh @@ -29,6 +29,10 @@ #ifndef __ARCH_MIPS_ISA_TRAITS_HH__ #define __ARCH_MIPS_ISA_TRAITS_HH__ +//This makes sure the big endian versions of certain functions are used. +namespace LittleEndianGuest {} +using namespace LittleEndianGuest + #include "arch/mips/faults.hh" #include "base/misc.hh" #include "sim/host.hh" diff --git a/arch/sparc/isa_traits.hh b/arch/sparc/isa_traits.hh index 9513b99fc..7dd49aed9 100644 --- a/arch/sparc/isa_traits.hh +++ b/arch/sparc/isa_traits.hh @@ -29,6 +29,10 @@ #ifndef __ARCH_SPARC_ISA_TRAITS_HH__ #define __ARCH_SPARC_ISA_TRAITS_HH__ +//This makes sure the big endian versions of certain functions are used. +namespace BigEndianGuest {} +using namespace BigEndianGuest; + #include "arch/sparc/faults.hh" #include "base/misc.hh" #include "sim/host.hh" diff --git a/build/SConstruct b/build/SConstruct index 72b0930e1..c552e5639 100644 --- a/build/SConstruct +++ b/build/SConstruct @@ -223,7 +223,7 @@ env = conf.Finish() # value becomes sticky). sticky_opts = Options(args=ARGUMENTS) sticky_opts.AddOptions( - EnumOption('TARGET_ISA', 'Target ISA', 'alpha', ('alpha', 'sparc')), + EnumOption('TARGET_ISA', 'Target ISA', 'alpha', ('alpha', 'sparc', 'mips')), BoolOption('FULL_SYSTEM', 'Full-system support', False), BoolOption('ALPHA_TLASER', 'Model Alpha TurboLaser platform (vs. Tsunami)', False), diff --git a/cpu/exec_context.hh b/cpu/exec_context.hh index 2bde053b2..846be831a 100644 --- a/cpu/exec_context.hh +++ b/cpu/exec_context.hh @@ -34,6 +34,7 @@ #include "mem/mem_req.hh" #include "sim/host.hh" #include "sim/serialize.hh" +#include "arch/isa_traits.hh" #include "sim/byteswap.hh" // forward declaration: see functional_memory.hh diff --git a/cpu/o3/alpha_cpu.hh b/cpu/o3/alpha_cpu.hh index 164da4968..1e1a72af0 100644 --- a/cpu/o3/alpha_cpu.hh +++ b/cpu/o3/alpha_cpu.hh @@ -33,6 +33,8 @@ #define __CPU_O3_CPU_ALPHA_FULL_CPU_HH__ #include "cpu/o3/cpu.hh" +#include "arch/isa_traits.hh" +#include "sim/byteswap.hh" template class AlphaFullCPU : public FullO3CPU @@ -220,7 +222,7 @@ class AlphaFullCPU : public FullO3CPU Fault error; error = this->mem->read(req, data); - data = LittleEndianGuest::gtoh(data); + data = gtoh(data); return error; } @@ -277,7 +279,7 @@ class AlphaFullCPU : public FullO3CPU #endif - return this->mem->write(req, (T)LittleEndianGuest::htog(data)); + return this->mem->write(req, (T)::htog(data)); } template diff --git a/cpu/o3/fetch_impl.hh b/cpu/o3/fetch_impl.hh index 1a8411cc1..cd1ed1351 100644 --- a/cpu/o3/fetch_impl.hh +++ b/cpu/o3/fetch_impl.hh @@ -29,7 +29,7 @@ // Remove this later; used only for debugging. #define OPCODE(X) (X >> 26) & 0x3f - +#include "arch/isa_traits.hh" #include "sim/byteswap.hh" #include "cpu/exetrace.hh" #include "mem/base_mem.hh" @@ -535,7 +535,7 @@ SimpleFetch::fetch() assert(offset <= cacheBlkSize - instSize); // Get the instruction from the array of the cache line. - inst = LittleEndianGuest::gtoh(*reinterpret_cast + inst = gtoh(*reinterpret_cast (&cacheData[offset])); // Create a new DynInst from the instruction fetched. diff --git a/kern/freebsd/freebsd_system.cc b/kern/freebsd/freebsd_system.cc index f3fe84e00..dbf60a3fc 100644 --- a/kern/freebsd/freebsd_system.cc +++ b/kern/freebsd/freebsd_system.cc @@ -39,6 +39,7 @@ #include "mem/functional/memory_control.hh" #include "mem/functional/physical.hh" #include "sim/builder.hh" +#include "arch/isa_traits.hh" #include "sim/byteswap.hh" #include "targetarch/vtophys.hh" @@ -83,8 +84,8 @@ FreebsdSystem::doCalibrateClocks(ExecContext *xc) uint8_t *ppc = physmem->dma_addr(ppc_paddr, sizeof(uint32_t)); uint8_t *timer = physmem->dma_addr(timer_paddr, sizeof(uint32_t)); - *(uint32_t *)ppc = LittleEndianGuest::htog((uint32_t)Clock::Frequency); - *(uint32_t *)timer = LittleEndianGuest::htog((uint32_t)TIMER_FREQUENCY); + *(uint32_t *)ppc = htog((uint32_t)Clock::Frequency); + *(uint32_t *)timer = htog((uint32_t)TIMER_FREQUENCY); } diff --git a/sim/system.cc b/sim/system.cc index a69bf27f1..990145826 100644 --- a/sim/system.cc +++ b/sim/system.cc @@ -35,6 +35,8 @@ #include "mem/functional/physical.hh" #include "targetarch/vtophys.hh" #include "sim/builder.hh" +#include "arch/isa_traits.hh" +#include "sim/byteswap.hh" #include "sim/system.hh" #include "base/trace.hh" @@ -152,8 +154,8 @@ System::System(Params *p) if (!hwrpb) panic("could not translate hwrpb addr\n"); - *(uint64_t*)(hwrpb+0x50) = LittleEndianGuest::htog(params->system_type); - *(uint64_t*)(hwrpb+0x58) = LittleEndianGuest::htog(params->system_rev); + *(uint64_t*)(hwrpb+0x50) = htog(params->system_type); + *(uint64_t*)(hwrpb+0x58) = htog(params->system_rev); } else panic("could not find hwrpb\n"); @@ -249,7 +251,7 @@ System::setAlphaAccess(Addr access) if (!m5AlphaAccess) panic("could not translate m5AlphaAccess addr\n"); - *m5AlphaAccess = LittleEndianGuest::htog(EV5::Phys2K0Seg(access)); + *m5AlphaAccess = htog(EV5::Phys2K0Seg(access)); } else panic("could not find m5AlphaAccess\n"); } From e59fdcdd3953145dde03edc45ea20549c7cd57da Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 8 Feb 2006 01:57:47 -0500 Subject: [PATCH 022/180] Some fixups arch/alpha/alpha_linux_process.cc: arch/alpha/alpha_tru64_process.cc: Replaced the namespace declaration with including arch/alpha/isa_traits.hh --HG-- extra : convert_revision : 07cb73a9f30f0e165809668f9baff6a3e3f94580 --- arch/alpha/alpha_linux_process.cc | 4 +--- arch/alpha/alpha_tru64_process.cc | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/arch/alpha/alpha_linux_process.cc b/arch/alpha/alpha_linux_process.cc index 16cbf3841..8f114955f 100644 --- a/arch/alpha/alpha_linux_process.cc +++ b/arch/alpha/alpha_linux_process.cc @@ -26,9 +26,6 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -namespace LittleEndian {} -using namespace LittleEndian; - #include #include #include // for host open() flags @@ -45,6 +42,7 @@ using namespace LittleEndian; #include "sim/process.hh" #include "sim/sim_events.hh" +#include "arch/alpha/isa_traits.hh" #include "arch/alpha/alpha_common_syscall_emul.hh" #include "sim/syscall_emul.hh" #include "sim/root.hh" // for curTick & ticksPerSecond diff --git a/arch/alpha/alpha_tru64_process.cc b/arch/alpha/alpha_tru64_process.cc index d57054dfd..6d790b173 100644 --- a/arch/alpha/alpha_tru64_process.cc +++ b/arch/alpha/alpha_tru64_process.cc @@ -26,9 +26,6 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -namespace LittleEndian {} -using namespace LittleEndian; - #include #include #if defined(__OpenBSD__) @@ -44,6 +41,7 @@ using namespace LittleEndian; #include // for memset() #include +#include "arch/alpha/isa_traits.hh" #include "arch/alpha/alpha_common_syscall_emul.hh" #include "arch/alpha/alpha_tru64_process.hh" #include "base/trace.hh" From f444a7e799a1a4ccfe2650217a9d5b6f5e3e65a0 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 8 Feb 2006 02:17:47 -0500 Subject: [PATCH 023/180] Moved the alpha isa_desc to conform to the new naming system. --HG-- rename : arch/alpha/isa_desc => arch/alpha/isa/main.isa extra : convert_revision : a3cc14c202ae606db270c2c29847170d90c05216 --- arch/alpha/isa/main.isa | 2723 ++++++++++++++++++++++++++++++++++++++ arch/alpha/isa_desc | 2737 --------------------------------------- 2 files changed, 2723 insertions(+), 2737 deletions(-) create mode 100644 arch/alpha/isa/main.isa delete mode 100644 arch/alpha/isa_desc diff --git a/arch/alpha/isa/main.isa b/arch/alpha/isa/main.isa new file mode 100644 index 000000000..eb4aad033 --- /dev/null +++ b/arch/alpha/isa/main.isa @@ -0,0 +1,2723 @@ +// -*- mode:c++ -*- + +// 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. + +output header {{ +#include +#include +#include + +#include "config/ss_compatible_fp.hh" +#include "cpu/static_inst.hh" +#include "mem/mem_req.hh" // some constructors use MemReq flags +}}; + +output decoder {{ +#include "base/cprintf.hh" +#include "base/fenv.hh" +#include "base/loader/symtab.hh" +#include "config/ss_compatible_fp.hh" +#include "cpu/exec_context.hh" // for Jump::branchTarget() + +#include +}}; + +output exec {{ +#include + +#if FULL_SYSTEM +#include "arch/alpha/pseudo_inst.hh" +#endif +#include "base/fenv.hh" +#include "config/ss_compatible_fp.hh" +#include "cpu/base.hh" +#include "cpu/exetrace.hh" +#include "sim/sim_exit.hh" +}}; + +//////////////////////////////////////////////////////////////////// +// +// Namespace statement. Everything below this line will be in the +// AlphaISAInst namespace. +// + + +namespace AlphaISA; + +//////////////////////////////////////////////////////////////////// +// +// Bitfield definitions. +// + +// Universal (format-independent) fields +def bitfield OPCODE <31:26>; +def bitfield RA <25:21>; +def bitfield RB <20:16>; + +// Memory format +def signed bitfield MEMDISP <15: 0>; // displacement +def bitfield MEMFUNC <15: 0>; // function code (same field, unsigned) + +// Memory-format jumps +def bitfield JMPFUNC <15:14>; // function code (disp<15:14>) +def bitfield JMPHINT <13: 0>; // tgt Icache idx hint (disp<13:0>) + +// Branch format +def signed bitfield BRDISP <20: 0>; // displacement + +// Integer operate format(s>; +def bitfield INTIMM <20:13>; // integer immediate (literal) +def bitfield IMM <12:12>; // immediate flag +def bitfield INTFUNC <11: 5>; // function code +def bitfield RC < 4: 0>; // dest reg + +// Floating-point operate format +def bitfield FA <25:21>; +def bitfield FB <20:16>; +def bitfield FP_FULLFUNC <15: 5>; // complete function code + def bitfield FP_TRAPMODE <15:13>; // trapping mode + def bitfield FP_ROUNDMODE <12:11>; // rounding mode + def bitfield FP_TYPEFUNC <10: 5>; // type+func: handiest for decoding + def bitfield FP_SRCTYPE <10: 9>; // source reg type + def bitfield FP_SHORTFUNC < 8: 5>; // short function code + def bitfield FP_SHORTFUNC_TOP2 <8:7>; // top 2 bits of short func code +def bitfield FC < 4: 0>; // dest reg + +// PALcode format +def bitfield PALFUNC <25: 0>; // function code + +// EV5 PAL instructions: +// HW_LD/HW_ST +def bitfield HW_LDST_PHYS <15>; // address is physical +def bitfield HW_LDST_ALT <14>; // use ALT_MODE IPR +def bitfield HW_LDST_WRTCK <13>; // HW_LD only: fault if no write acc +def bitfield HW_LDST_QUAD <12>; // size: 0=32b, 1=64b +def bitfield HW_LDST_VPTE <11>; // HW_LD only: is PTE fetch +def bitfield HW_LDST_LOCK <10>; // HW_LD only: is load locked +def bitfield HW_LDST_COND <10>; // HW_ST only: is store conditional +def signed bitfield HW_LDST_DISP <9:0>; // signed displacement + +// HW_REI +def bitfield HW_REI_TYP <15:14>; // type: stalling vs. non-stallingk +def bitfield HW_REI_MBZ <13: 0>; // must be zero + +// HW_MTPR/MW_MFPR +def bitfield HW_IPR_IDX <15:0>; // IPR index + +// M5 instructions +def bitfield M5FUNC <7:0>; + +def operand_types {{ + 'sb' : ('signed int', 8), + 'ub' : ('unsigned int', 8), + 'sw' : ('signed int', 16), + 'uw' : ('unsigned int', 16), + 'sl' : ('signed int', 32), + 'ul' : ('unsigned int', 32), + 'sq' : ('signed int', 64), + 'uq' : ('unsigned int', 64), + 'sf' : ('float', 32), + 'df' : ('float', 64) +}}; + +def operands {{ + # Int regs default to unsigned, but code should not count on this. + # For clarity, descriptions that depend on unsigned behavior should + # explicitly specify '.uq'. + 'Ra': IntRegOperandTraits('uq', 'RA', 'IsInteger', 1), + 'Rb': IntRegOperandTraits('uq', 'RB', 'IsInteger', 2), + 'Rc': IntRegOperandTraits('uq', 'RC', 'IsInteger', 3), + 'Fa': FloatRegOperandTraits('df', 'FA', 'IsFloating', 1), + 'Fb': FloatRegOperandTraits('df', 'FB', 'IsFloating', 2), + 'Fc': FloatRegOperandTraits('df', 'FC', 'IsFloating', 3), + 'Mem': MemOperandTraits('uq', None, + ('IsMemRef', 'IsLoad', 'IsStore'), 4), + 'NPC': NPCOperandTraits('uq', None, ( None, None, 'IsControl' ), 4), + 'Runiq': ControlRegOperandTraits('uq', 'Uniq', None, 1), + 'FPCR': ControlRegOperandTraits('uq', 'Fpcr', None, 1), + # The next two are hacks for non-full-system call-pal emulation + 'R0': IntRegOperandTraits('uq', '0', None, 1), + 'R16': IntRegOperandTraits('uq', '16', None, 1) +}}; + +//////////////////////////////////////////////////////////////////// +// +// Basic instruction classes/templates/formats etc. +// + +output header {{ +// uncomment the following to get SimpleScalar-compatible disassembly +// (useful for diffing output traces). +// #define SS_COMPATIBLE_DISASSEMBLY + + /** + * Base class for all Alpha static instructions. + */ + class AlphaStaticInst : public StaticInst + { + protected: + + /// Make AlphaISA register dependence tags directly visible in + /// this class and derived classes. Maybe these should really + /// live here and not in the AlphaISA namespace. + enum DependenceTags { + FP_Base_DepTag = AlphaISA::FP_Base_DepTag, + Fpcr_DepTag = AlphaISA::Fpcr_DepTag, + Uniq_DepTag = AlphaISA::Uniq_DepTag, + IPR_Base_DepTag = AlphaISA::IPR_Base_DepTag + }; + + /// Constructor. + AlphaStaticInst(const char *mnem, MachInst _machInst, + OpClass __opClass) + : StaticInst(mnem, _machInst, __opClass) + { + } + + /// Print a register name for disassembly given the unique + /// dependence tag number (FP or int). + void printReg(std::ostream &os, int reg) const; + + std::string + generateDisassembly(Addr pc, const SymbolTable *symtab) const; + }; +}}; + +output decoder {{ + void + AlphaStaticInst::printReg(std::ostream &os, int reg) const + { + if (reg < FP_Base_DepTag) { + ccprintf(os, "r%d", reg); + } + else { + ccprintf(os, "f%d", reg - FP_Base_DepTag); + } + } + + std::string + AlphaStaticInst::generateDisassembly(Addr pc, + const SymbolTable *symtab) const + { + std::stringstream ss; + + ccprintf(ss, "%-10s ", mnemonic); + + // just print the first two source regs... if there's + // a third one, it's a read-modify-write dest (Rc), + // e.g. for CMOVxx + if (_numSrcRegs > 0) { + printReg(ss, _srcRegIdx[0]); + } + if (_numSrcRegs > 1) { + ss << ","; + printReg(ss, _srcRegIdx[1]); + } + + // just print the first dest... if there's a second one, + // it's generally implicit + if (_numDestRegs > 0) { + if (_numSrcRegs > 0) + ss << ","; + printReg(ss, _destRegIdx[0]); + } + + return ss.str(); + } +}}; + +// Declarations for execute() methods. +def template BasicExecDeclare {{ + Fault execute(%(CPU_exec_context)s *, Trace::InstRecord *) const; +}}; + +// Basic instruction class declaration template. +def template BasicDeclare {{ + /** + * Static instruction class for "%(mnemonic)s". + */ + class %(class_name)s : public %(base_class)s + { + public: + /// Constructor. + %(class_name)s(MachInst machInst); + + %(BasicExecDeclare)s + }; +}}; + +// Basic instruction class constructor template. +def template BasicConstructor {{ + inline %(class_name)s::%(class_name)s(MachInst machInst) + : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s) + { + %(constructor)s; + } +}}; + +// Basic instruction class execute method template. +def template BasicExecute {{ + Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + Fault fault = No_Fault; + + %(fp_enable_check)s; + %(op_decl)s; + %(op_rd)s; + %(code)s; + + if (fault == No_Fault) { + %(op_wb)s; + } + + return fault; + } +}}; + +// Basic decode template. +def template BasicDecode {{ + return new %(class_name)s(machInst); +}}; + +// Basic decode template, passing mnemonic in as string arg to constructor. +def template BasicDecodeWithMnemonic {{ + return new %(class_name)s("%(mnemonic)s", machInst); +}}; + +// The most basic instruction format... used only for a few misc. insts +def format BasicOperate(code, *flags) {{ + iop = InstObjParams(name, Name, 'AlphaStaticInst', CodeBlock(code), flags) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecode.subst(iop) + exec_output = BasicExecute.subst(iop) +}}; + + + +//////////////////////////////////////////////////////////////////// +// +// Nop +// + +output header {{ + /** + * Static instruction class for no-ops. This is a leaf class. + */ + class Nop : public AlphaStaticInst + { + /// Disassembly of original instruction. + const std::string originalDisassembly; + + public: + /// Constructor + Nop(const std::string _originalDisassembly, MachInst _machInst) + : AlphaStaticInst("nop", _machInst, No_OpClass), + originalDisassembly(_originalDisassembly) + { + flags[IsNop] = true; + } + + ~Nop() { } + + std::string + generateDisassembly(Addr pc, const SymbolTable *symtab) const; + + %(BasicExecDeclare)s + }; +}}; + +output decoder {{ + std::string Nop::generateDisassembly(Addr pc, + const SymbolTable *symtab) const + { +#ifdef SS_COMPATIBLE_DISASSEMBLY + return originalDisassembly; +#else + return csprintf("%-10s (%s)", "nop", originalDisassembly); +#endif + } + + /// Helper function for decoding nops. Substitute Nop object + /// for original inst passed in as arg (and delete latter). + inline + AlphaStaticInst * + makeNop(AlphaStaticInst *inst) + { + AlphaStaticInst *nop = new Nop(inst->disassemble(0), inst->machInst); + delete inst; + return nop; + } +}}; + +output exec {{ + Fault + Nop::execute(%(CPU_exec_context)s *, Trace::InstRecord *) const + { + return No_Fault; + } +}}; + +// integer & FP operate instructions use Rc as dest, so check for +// Rc == 31 to detect nops +def template OperateNopCheckDecode {{ + { + AlphaStaticInst *i = new %(class_name)s(machInst); + if (RC == 31) { + i = makeNop(i); + } + return i; + } +}}; + +// Like BasicOperate format, but generates NOP if RC/FC == 31 +def format BasicOperateWithNopCheck(code, *opt_args) {{ + iop = InstObjParams(name, Name, 'AlphaStaticInst', CodeBlock(code), + opt_args) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = OperateNopCheckDecode.subst(iop) + exec_output = BasicExecute.subst(iop) +}}; + + +//////////////////////////////////////////////////////////////////// +// +// Integer operate instructions +// + +output header {{ + /** + * Base class for integer immediate instructions. + */ + class IntegerImm : public AlphaStaticInst + { + protected: + /// Immediate operand value (unsigned 8-bit int). + uint8_t imm; + + /// Constructor + IntegerImm(const char *mnem, MachInst _machInst, OpClass __opClass) + : AlphaStaticInst(mnem, _machInst, __opClass), imm(INTIMM) + { + } + + std::string + generateDisassembly(Addr pc, const SymbolTable *symtab) const; + }; +}}; + +output decoder {{ + std::string + IntegerImm::generateDisassembly(Addr pc, const SymbolTable *symtab) const + { + std::stringstream ss; + + ccprintf(ss, "%-10s ", mnemonic); + + // just print the first source reg... if there's + // a second one, it's a read-modify-write dest (Rc), + // e.g. for CMOVxx + if (_numSrcRegs > 0) { + printReg(ss, _srcRegIdx[0]); + ss << ","; + } + + ss << (int)imm; + + if (_numDestRegs > 0) { + ss << ","; + printReg(ss, _destRegIdx[0]); + } + + return ss.str(); + } +}}; + + +def template RegOrImmDecode {{ + { + AlphaStaticInst *i = + (IMM) ? (AlphaStaticInst *)new %(class_name)sImm(machInst) + : (AlphaStaticInst *)new %(class_name)s(machInst); + if (RC == 31) { + i = makeNop(i); + } + return i; + } +}}; + +// Primary format for integer operate instructions: +// - Generates both reg-reg and reg-imm versions if Rb_or_imm is used. +// - Generates NOP if RC == 31. +def format IntegerOperate(code, *opt_flags) {{ + # If the code block contains 'Rb_or_imm', we define two instructions, + # one using 'Rb' and one using 'imm', and have the decoder select + # the right one. + uses_imm = (code.find('Rb_or_imm') != -1) + if uses_imm: + orig_code = code + # base code is reg version: + # rewrite by substituting 'Rb' for 'Rb_or_imm' + code = re.sub(r'Rb_or_imm', 'Rb', orig_code) + # generate immediate version by substituting 'imm' + # note that imm takes no extenstion, so we extend + # the regexp to replace any extension as well + imm_code = re.sub(r'Rb_or_imm(\.\w+)?', 'imm', orig_code) + + # generate declaration for register version + cblk = CodeBlock(code) + iop = InstObjParams(name, Name, 'AlphaStaticInst', cblk, opt_flags) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + exec_output = BasicExecute.subst(iop) + + if uses_imm: + # append declaration for imm version + imm_cblk = CodeBlock(imm_code) + imm_iop = InstObjParams(name, Name + 'Imm', 'IntegerImm', imm_cblk, + opt_flags) + header_output += BasicDeclare.subst(imm_iop) + decoder_output += BasicConstructor.subst(imm_iop) + exec_output += BasicExecute.subst(imm_iop) + # decode checks IMM bit to pick correct version + decode_block = RegOrImmDecode.subst(iop) + else: + # no imm version: just check for nop + decode_block = OperateNopCheckDecode.subst(iop) +}}; + + +//////////////////////////////////////////////////////////////////// +// +// Floating-point instructions +// +// Note that many FP-type instructions which do not support all the +// various rounding & trapping modes use the simpler format +// BasicOperateWithNopCheck. +// + +output exec {{ + /// Check "FP enabled" machine status bit. Called when executing any FP + /// instruction in full-system mode. + /// @retval Full-system mode: No_Fault if FP is enabled, Fen_Fault + /// if not. Non-full-system mode: always returns No_Fault. +#if FULL_SYSTEM + inline Fault checkFpEnableFault(%(CPU_exec_context)s *xc) + { + Fault fault = No_Fault; // dummy... this ipr access should not fault + if (!EV5::ICSR_FPE(xc->readIpr(AlphaISA::IPR_ICSR, fault))) { + fault = Fen_Fault; + } + return fault; + } +#else + inline Fault checkFpEnableFault(%(CPU_exec_context)s *xc) + { + return No_Fault; + } +#endif +}}; + +output header {{ + /** + * Base class for general floating-point instructions. Includes + * support for various Alpha rounding and trapping modes. Only FP + * instructions that require this support are derived from this + * class; the rest derive directly from AlphaStaticInst. + */ + class AlphaFP : public AlphaStaticInst + { + public: + /// Alpha FP rounding modes. + enum RoundingMode { + Chopped = 0, ///< round toward zero + Minus_Infinity = 1, ///< round toward minus infinity + Normal = 2, ///< round to nearest (default) + Dynamic = 3, ///< use FPCR setting (in instruction) + Plus_Infinity = 3 ///< round to plus inifinity (in FPCR) + }; + + /// Alpha FP trapping modes. + /// For instructions that produce integer results, the + /// "Underflow Enable" modes really mean "Overflow Enable", and + /// the assembly modifier is V rather than U. + enum TrappingMode { + /// default: nothing enabled + Imprecise = 0, ///< no modifier + /// underflow/overflow traps enabled, inexact disabled + Underflow_Imprecise = 1, ///< /U or /V + Underflow_Precise = 5, ///< /SU or /SV + /// underflow/overflow and inexact traps enabled + Underflow_Inexact_Precise = 7 ///< /SUI or /SVI + }; + + protected: + /// Map Alpha rounding mode to C99 constants from . + static const int alphaToC99RoundingMode[]; + + /// Map enum RoundingMode values to disassembly suffixes. + static const char *roundingModeSuffix[]; + /// Map enum TrappingMode values to FP disassembly suffixes. + static const char *fpTrappingModeSuffix[]; + /// Map enum TrappingMode values to integer disassembly suffixes. + static const char *intTrappingModeSuffix[]; + + /// This instruction's rounding mode. + RoundingMode roundingMode; + /// This instruction's trapping mode. + TrappingMode trappingMode; + + /// Have we warned about this instruction's unsupported + /// rounding mode (if applicable)? + mutable bool warnedOnRounding; + + /// Have we warned about this instruction's unsupported + /// trapping mode (if applicable)? + mutable bool warnedOnTrapping; + + /// Constructor + AlphaFP(const char *mnem, MachInst _machInst, OpClass __opClass) + : AlphaStaticInst(mnem, _machInst, __opClass), + roundingMode((enum RoundingMode)FP_ROUNDMODE), + trappingMode((enum TrappingMode)FP_TRAPMODE), + warnedOnRounding(false), + warnedOnTrapping(false) + { + } + + int getC99RoundingMode(uint64_t fpcr_val) const; + + // This differs from the AlphaStaticInst version only in + // printing suffixes for non-default rounding & trapping modes. + std::string + generateDisassembly(Addr pc, const SymbolTable *symtab) const; + }; + +}}; + + +output decoder {{ + int + AlphaFP::getC99RoundingMode(uint64_t fpcr_val) const + { + if (roundingMode == Dynamic) { + return alphaToC99RoundingMode[bits(fpcr_val, 59, 58)]; + } + else { + return alphaToC99RoundingMode[roundingMode]; + } + } + + std::string + AlphaFP::generateDisassembly(Addr pc, const SymbolTable *symtab) const + { + std::string mnem_str(mnemonic); + +#ifndef SS_COMPATIBLE_DISASSEMBLY + std::string suffix(""); + suffix += ((_destRegIdx[0] >= FP_Base_DepTag) + ? fpTrappingModeSuffix[trappingMode] + : intTrappingModeSuffix[trappingMode]); + suffix += roundingModeSuffix[roundingMode]; + + if (suffix != "") { + mnem_str = csprintf("%s/%s", mnemonic, suffix); + } +#endif + + std::stringstream ss; + ccprintf(ss, "%-10s ", mnem_str.c_str()); + + // just print the first two source regs... if there's + // a third one, it's a read-modify-write dest (Rc), + // e.g. for CMOVxx + if (_numSrcRegs > 0) { + printReg(ss, _srcRegIdx[0]); + } + if (_numSrcRegs > 1) { + ss << ","; + printReg(ss, _srcRegIdx[1]); + } + + // just print the first dest... if there's a second one, + // it's generally implicit + if (_numDestRegs > 0) { + if (_numSrcRegs > 0) + ss << ","; + printReg(ss, _destRegIdx[0]); + } + + return ss.str(); + } + + const int AlphaFP::alphaToC99RoundingMode[] = { + FE_TOWARDZERO, // Chopped + FE_DOWNWARD, // Minus_Infinity + FE_TONEAREST, // Normal + FE_UPWARD // Dynamic in inst, Plus_Infinity in FPCR + }; + + const char *AlphaFP::roundingModeSuffix[] = { "c", "m", "", "d" }; + // mark invalid trapping modes, but don't fail on them, because + // you could decode anything on a misspeculated path + const char *AlphaFP::fpTrappingModeSuffix[] = + { "", "u", "INVTM2", "INVTM3", "INVTM4", "su", "INVTM6", "sui" }; + const char *AlphaFP::intTrappingModeSuffix[] = + { "", "v", "INVTM2", "INVTM3", "INVTM4", "sv", "INVTM6", "svi" }; +}}; + +// FP instruction class execute method template. Handles non-standard +// rounding modes. +def template FloatingPointExecute {{ + Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + if (trappingMode != Imprecise && !warnedOnTrapping) { + warn("%s: non-standard trapping mode not supported", + generateDisassembly(0, NULL)); + warnedOnTrapping = true; + } + + Fault fault = No_Fault; + + %(fp_enable_check)s; + %(op_decl)s; + %(op_rd)s; +#if USE_FENV + if (roundingMode == Normal) { + %(code)s; + } else { + fesetround(getC99RoundingMode(xc->readFpcr())); + %(code)s; + fesetround(FE_TONEAREST); + } +#else + if (roundingMode != Normal && !warnedOnRounding) { + warn("%s: non-standard rounding mode not supported", + generateDisassembly(0, NULL)); + warnedOnRounding = true; + } + %(code)s; +#endif + + if (fault == No_Fault) { + %(op_wb)s; + } + + return fault; + } +}}; + +// FP instruction class execute method template where no dynamic +// rounding mode control is needed. Like BasicExecute, but includes +// check & warning for non-standard trapping mode. +def template FPFixedRoundingExecute {{ + Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + if (trappingMode != Imprecise && !warnedOnTrapping) { + warn("%s: non-standard trapping mode not supported", + generateDisassembly(0, NULL)); + warnedOnTrapping = true; + } + + Fault fault = No_Fault; + + %(fp_enable_check)s; + %(op_decl)s; + %(op_rd)s; + %(code)s; + + if (fault == No_Fault) { + %(op_wb)s; + } + + return fault; + } +}}; + +def template FloatingPointDecode {{ + { + AlphaStaticInst *i = new %(class_name)s(machInst); + if (FC == 31) { + i = makeNop(i); + } + return i; + } +}}; + +// General format for floating-point operate instructions: +// - Checks trapping and rounding mode flags. Trapping modes +// currently unimplemented (will fail). +// - Generates NOP if FC == 31. +def format FloatingPointOperate(code, *opt_args) {{ + iop = InstObjParams(name, Name, 'AlphaFP', CodeBlock(code), opt_args) + decode_block = FloatingPointDecode.subst(iop) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + exec_output = FloatingPointExecute.subst(iop) +}}; + +// Special format for cvttq where rounding mode is pre-decoded +def format FPFixedRounding(code, class_suffix, *opt_args) {{ + Name += class_suffix + iop = InstObjParams(name, Name, 'AlphaFP', CodeBlock(code), opt_args) + decode_block = FloatingPointDecode.subst(iop) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + exec_output = FPFixedRoundingExecute.subst(iop) +}}; + +//////////////////////////////////////////////////////////////////// +// +// Memory-format instructions: LoadAddress, Load, Store +// + +output header {{ + /** + * Base class for general Alpha memory-format instructions. + */ + class Memory : public AlphaStaticInst + { + protected: + + /// Memory request flags. See mem_req_base.hh. + unsigned memAccessFlags; + /// Pointer to EAComp object. + const StaticInstPtr eaCompPtr; + /// Pointer to MemAcc object. + const StaticInstPtr memAccPtr; + + /// Constructor + Memory(const char *mnem, MachInst _machInst, OpClass __opClass, + StaticInstPtr _eaCompPtr = nullStaticInstPtr, + StaticInstPtr _memAccPtr = nullStaticInstPtr) + : AlphaStaticInst(mnem, _machInst, __opClass), + memAccessFlags(0), eaCompPtr(_eaCompPtr), memAccPtr(_memAccPtr) + { + } + + std::string + generateDisassembly(Addr pc, const SymbolTable *symtab) const; + + public: + + const StaticInstPtr &eaCompInst() const { return eaCompPtr; } + const StaticInstPtr &memAccInst() const { return memAccPtr; } + }; + + /** + * Base class for memory-format instructions using a 32-bit + * displacement (i.e. most of them). + */ + class MemoryDisp32 : public Memory + { + protected: + /// Displacement for EA calculation (signed). + int32_t disp; + + /// Constructor. + MemoryDisp32(const char *mnem, MachInst _machInst, OpClass __opClass, + StaticInstPtr _eaCompPtr = nullStaticInstPtr, + StaticInstPtr _memAccPtr = nullStaticInstPtr) + : Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr), + disp(MEMDISP) + { + } + }; + + + /** + * Base class for a few miscellaneous memory-format insts + * that don't interpret the disp field: wh64, fetch, fetch_m, ecb. + * None of these instructions has a destination register either. + */ + class MemoryNoDisp : public Memory + { + protected: + /// Constructor + MemoryNoDisp(const char *mnem, MachInst _machInst, OpClass __opClass, + StaticInstPtr _eaCompPtr = nullStaticInstPtr, + StaticInstPtr _memAccPtr = nullStaticInstPtr) + : Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr) + { + } + + std::string + generateDisassembly(Addr pc, const SymbolTable *symtab) const; + }; +}}; + + +output decoder {{ + std::string + Memory::generateDisassembly(Addr pc, const SymbolTable *symtab) const + { + return csprintf("%-10s %c%d,%d(r%d)", mnemonic, + flags[IsFloating] ? 'f' : 'r', RA, MEMDISP, RB); + } + + std::string + MemoryNoDisp::generateDisassembly(Addr pc, const SymbolTable *symtab) const + { + return csprintf("%-10s (r%d)", mnemonic, RB); + } +}}; + +def format LoadAddress(code) {{ + iop = InstObjParams(name, Name, 'MemoryDisp32', CodeBlock(code)) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecode.subst(iop) + exec_output = BasicExecute.subst(iop) +}}; + + +def template LoadStoreDeclare {{ + /** + * Static instruction class for "%(mnemonic)s". + */ + class %(class_name)s : public %(base_class)s + { + protected: + + /** + * "Fake" effective address computation class for "%(mnemonic)s". + */ + class EAComp : public %(base_class)s + { + public: + /// Constructor + EAComp(MachInst machInst); + + %(BasicExecDeclare)s + }; + + /** + * "Fake" memory access instruction class for "%(mnemonic)s". + */ + class MemAcc : public %(base_class)s + { + public: + /// Constructor + MemAcc(MachInst machInst); + + %(BasicExecDeclare)s + }; + + public: + + /// Constructor. + %(class_name)s(MachInst machInst); + + %(BasicExecDeclare)s + }; +}}; + +def template LoadStoreConstructor {{ + /** TODO: change op_class to AddrGenOp or something (requires + * creating new member of OpClass enum in op_class.hh, updating + * config files, etc.). */ + inline %(class_name)s::EAComp::EAComp(MachInst machInst) + : %(base_class)s("%(mnemonic)s (EAComp)", machInst, IntAluOp) + { + %(ea_constructor)s; + } + + inline %(class_name)s::MemAcc::MemAcc(MachInst machInst) + : %(base_class)s("%(mnemonic)s (MemAcc)", machInst, %(op_class)s) + { + %(memacc_constructor)s; + } + + inline %(class_name)s::%(class_name)s(MachInst machInst) + : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, + new EAComp(machInst), new MemAcc(machInst)) + { + %(constructor)s; + } +}}; + + +def template EACompExecute {{ + Fault + %(class_name)s::EAComp::execute(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + Addr EA; + Fault fault = No_Fault; + + %(fp_enable_check)s; + %(op_decl)s; + %(op_rd)s; + %(code)s; + + if (fault == No_Fault) { + %(op_wb)s; + xc->setEA(EA); + } + + return fault; + } +}}; + +def template MemAccExecute {{ + Fault + %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + Addr EA; + Fault fault = No_Fault; + + %(fp_enable_check)s; + %(op_decl)s; + %(op_nonmem_rd)s; + EA = xc->getEA(); + + if (fault == No_Fault) { + %(op_mem_rd)s; + %(code)s; + } + + if (fault == No_Fault) { + %(op_mem_wb)s; + } + + if (fault == No_Fault) { + %(postacc_code)s; + } + + if (fault == No_Fault) { + %(op_nonmem_wb)s; + } + + return fault; + } +}}; + + +def template LoadStoreExecute {{ + Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + Addr EA; + Fault fault = No_Fault; + + %(fp_enable_check)s; + %(op_decl)s; + %(op_nonmem_rd)s; + %(ea_code)s; + + if (fault == No_Fault) { + %(op_mem_rd)s; + %(memacc_code)s; + } + + if (fault == No_Fault) { + %(op_mem_wb)s; + } + + if (fault == No_Fault) { + %(postacc_code)s; + } + + if (fault == No_Fault) { + %(op_nonmem_wb)s; + } + + return fault; + } +}}; + + +def template PrefetchExecute {{ + Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + Addr EA; + Fault fault = No_Fault; + + %(fp_enable_check)s; + %(op_decl)s; + %(op_nonmem_rd)s; + %(ea_code)s; + + if (fault == No_Fault) { + xc->prefetch(EA, memAccessFlags); + } + + return No_Fault; + } +}}; + +// load instructions use Ra as dest, so check for +// Ra == 31 to detect nops +def template LoadNopCheckDecode {{ + { + AlphaStaticInst *i = new %(class_name)s(machInst); + if (RA == 31) { + i = makeNop(i); + } + return i; + } +}}; + + +// for some load instructions, Ra == 31 indicates a prefetch (not a nop) +def template LoadPrefetchCheckDecode {{ + { + if (RA != 31) { + return new %(class_name)s(machInst); + } + else { + return new %(class_name)sPrefetch(machInst); + } + } +}}; + + +let {{ +def LoadStoreBase(name, Name, ea_code, memacc_code, postacc_code = '', + base_class = 'MemoryDisp32', flags = [], + decode_template = BasicDecode, + exec_template = LoadStoreExecute): + # Segregate flags into instruction flags (handled by InstObjParams) + # and memory access flags (handled here). + + # Would be nice to autogenerate this list, but oh well. + valid_mem_flags = ['LOCKED', 'NO_FAULT', 'EVICT_NEXT', 'PF_EXCLUSIVE'] + mem_flags = [f for f in flags if f in valid_mem_flags] + inst_flags = [f for f in flags if f not in valid_mem_flags] + + # add hook to get effective addresses into execution trace output. + ea_code += '\nif (traceData) { traceData->setAddr(EA); }\n' + + # generate code block objects + ea_cblk = CodeBlock(ea_code) + memacc_cblk = CodeBlock(memacc_code) + postacc_cblk = CodeBlock(postacc_code) + + # Some CPU models execute the memory operation as an atomic unit, + # while others want to separate them into an effective address + # computation and a memory access operation. As a result, we need + # to generate three StaticInst objects. Note that the latter two + # are nested inside the larger "atomic" one. + + # generate InstObjParams for EAComp object + ea_iop = InstObjParams(name, Name, base_class, ea_cblk, inst_flags) + + # generate InstObjParams for MemAcc object + memacc_iop = InstObjParams(name, Name, base_class, memacc_cblk, inst_flags) + # in the split execution model, the MemAcc portion is responsible + # for the post-access code. + memacc_iop.postacc_code = postacc_cblk.code + + # generate InstObjParams for unified execution + cblk = CodeBlock(ea_code + memacc_code + postacc_code) + iop = InstObjParams(name, Name, base_class, cblk, inst_flags) + + iop.ea_constructor = ea_cblk.constructor + iop.ea_code = ea_cblk.code + iop.memacc_constructor = memacc_cblk.constructor + iop.memacc_code = memacc_cblk.code + iop.postacc_code = postacc_cblk.code + + if mem_flags: + s = '\n\tmemAccessFlags = ' + string.join(mem_flags, '|') + ';' + iop.constructor += s + memacc_iop.constructor += s + + # (header_output, decoder_output, decode_block, exec_output) + return (LoadStoreDeclare.subst(iop), LoadStoreConstructor.subst(iop), + decode_template.subst(iop), + EACompExecute.subst(ea_iop) + + MemAccExecute.subst(memacc_iop) + + exec_template.subst(iop)) +}}; + + +def format LoadOrNop(ea_code, memacc_code, *flags) {{ + (header_output, decoder_output, decode_block, exec_output) = \ + LoadStoreBase(name, Name, ea_code, memacc_code, flags = flags, + decode_template = LoadNopCheckDecode) +}}; + + +// Note that the flags passed in apply only to the prefetch version +def format LoadOrPrefetch(ea_code, memacc_code, *pf_flags) {{ + # declare the load instruction object and generate the decode block + (header_output, decoder_output, decode_block, exec_output) = \ + LoadStoreBase(name, Name, ea_code, memacc_code, + decode_template = LoadPrefetchCheckDecode) + + # Declare the prefetch instruction object. + + # convert flags from tuple to list to make them mutable + pf_flags = list(pf_flags) + ['IsMemRef', 'IsLoad', 'IsDataPrefetch', 'MemReadOp', 'NO_FAULT'] + + (pf_header_output, pf_decoder_output, _, pf_exec_output) = \ + LoadStoreBase(name, Name + 'Prefetch', ea_code, '', + flags = pf_flags, exec_template = PrefetchExecute) + + header_output += pf_header_output + decoder_output += pf_decoder_output + exec_output += pf_exec_output +}}; + + +def format Store(ea_code, memacc_code, *flags) {{ + (header_output, decoder_output, decode_block, exec_output) = \ + LoadStoreBase(name, Name, ea_code, memacc_code, flags = flags) +}}; + + +def format StoreCond(ea_code, memacc_code, postacc_code, *flags) {{ + (header_output, decoder_output, decode_block, exec_output) = \ + LoadStoreBase(name, Name, ea_code, memacc_code, postacc_code, + flags = flags) +}}; + + +// Use 'MemoryNoDisp' as base: for wh64, fetch, ecb +def format MiscPrefetch(ea_code, memacc_code, *flags) {{ + (header_output, decoder_output, decode_block, exec_output) = \ + LoadStoreBase(name, Name, ea_code, memacc_code, flags = flags, + base_class = 'MemoryNoDisp') +}}; + + +//////////////////////////////////////////////////////////////////// +// +// Control transfer instructions +// + +output header {{ + + /** + * Base class for instructions whose disassembly is not purely a + * function of the machine instruction (i.e., it depends on the + * PC). This class overrides the disassemble() method to check + * the PC and symbol table values before re-using a cached + * disassembly string. This is necessary for branches and jumps, + * where the disassembly string includes the target address (which + * may depend on the PC and/or symbol table). + */ + class PCDependentDisassembly : public AlphaStaticInst + { + protected: + /// Cached program counter from last disassembly + mutable Addr cachedPC; + /// Cached symbol table pointer from last disassembly + mutable const SymbolTable *cachedSymtab; + + /// Constructor + PCDependentDisassembly(const char *mnem, MachInst _machInst, + OpClass __opClass) + : AlphaStaticInst(mnem, _machInst, __opClass), + cachedPC(0), cachedSymtab(0) + { + } + + const std::string & + disassemble(Addr pc, const SymbolTable *symtab) const; + }; + + /** + * Base class for branches (PC-relative control transfers), + * conditional or unconditional. + */ + class Branch : public PCDependentDisassembly + { + protected: + /// Displacement to target address (signed). + int32_t disp; + + /// Constructor. + Branch(const char *mnem, MachInst _machInst, OpClass __opClass) + : PCDependentDisassembly(mnem, _machInst, __opClass), + disp(BRDISP << 2) + { + } + + Addr branchTarget(Addr branchPC) const; + + std::string + generateDisassembly(Addr pc, const SymbolTable *symtab) const; + }; + + /** + * Base class for jumps (register-indirect control transfers). In + * the Alpha ISA, these are always unconditional. + */ + class Jump : public PCDependentDisassembly + { + protected: + + /// Displacement to target address (signed). + int32_t disp; + + public: + /// Constructor + Jump(const char *mnem, MachInst _machInst, OpClass __opClass) + : PCDependentDisassembly(mnem, _machInst, __opClass), + disp(BRDISP) + { + } + + Addr branchTarget(ExecContext *xc) const; + + std::string + generateDisassembly(Addr pc, const SymbolTable *symtab) const; + }; +}}; + +output decoder {{ + Addr + Branch::branchTarget(Addr branchPC) const + { + return branchPC + 4 + disp; + } + + Addr + Jump::branchTarget(ExecContext *xc) const + { + Addr NPC = xc->readPC() + 4; + uint64_t Rb = xc->readIntReg(_srcRegIdx[0]); + return (Rb & ~3) | (NPC & 1); + } + + const std::string & + PCDependentDisassembly::disassemble(Addr pc, + const SymbolTable *symtab) const + { + if (!cachedDisassembly || + pc != cachedPC || symtab != cachedSymtab) + { + if (cachedDisassembly) + delete cachedDisassembly; + + cachedDisassembly = + new std::string(generateDisassembly(pc, symtab)); + cachedPC = pc; + cachedSymtab = symtab; + } + + return *cachedDisassembly; + } + + std::string + Branch::generateDisassembly(Addr pc, const SymbolTable *symtab) const + { + std::stringstream ss; + + ccprintf(ss, "%-10s ", mnemonic); + + // There's only one register arg (RA), but it could be + // either a source (the condition for conditional + // branches) or a destination (the link reg for + // unconditional branches) + if (_numSrcRegs > 0) { + printReg(ss, _srcRegIdx[0]); + ss << ","; + } + else if (_numDestRegs > 0) { + printReg(ss, _destRegIdx[0]); + ss << ","; + } + +#ifdef SS_COMPATIBLE_DISASSEMBLY + if (_numSrcRegs == 0 && _numDestRegs == 0) { + printReg(ss, 31); + ss << ","; + } +#endif + + Addr target = pc + 4 + disp; + + std::string str; + if (symtab && symtab->findSymbol(target, str)) + ss << str; + else + ccprintf(ss, "0x%x", target); + + return ss.str(); + } + + std::string + Jump::generateDisassembly(Addr pc, const SymbolTable *symtab) const + { + std::stringstream ss; + + ccprintf(ss, "%-10s ", mnemonic); + +#ifdef SS_COMPATIBLE_DISASSEMBLY + if (_numDestRegs == 0) { + printReg(ss, 31); + ss << ","; + } +#endif + + if (_numDestRegs > 0) { + printReg(ss, _destRegIdx[0]); + ss << ","; + } + + ccprintf(ss, "(r%d)", RB); + + return ss.str(); + } +}}; + +def template JumpOrBranchDecode {{ + return (RA == 31) + ? (StaticInst *)new %(class_name)s(machInst) + : (StaticInst *)new %(class_name)sAndLink(machInst); +}}; + +def format CondBranch(code) {{ + code = 'bool cond;\n' + code + '\nif (cond) NPC = NPC + disp;\n'; + iop = InstObjParams(name, Name, 'Branch', CodeBlock(code), + ('IsDirectControl', 'IsCondControl')) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecode.subst(iop) + exec_output = BasicExecute.subst(iop) +}}; + +let {{ +def UncondCtrlBase(name, Name, base_class, npc_expr, flags): + # Declare basic control transfer w/o link (i.e. link reg is R31) + nolink_code = 'NPC = %s;\n' % npc_expr + nolink_iop = InstObjParams(name, Name, base_class, + CodeBlock(nolink_code), flags) + header_output = BasicDeclare.subst(nolink_iop) + decoder_output = BasicConstructor.subst(nolink_iop) + exec_output = BasicExecute.subst(nolink_iop) + + # Generate declaration of '*AndLink' version, append to decls + link_code = 'Ra = NPC & ~3;\n' + nolink_code + link_iop = InstObjParams(name, Name + 'AndLink', base_class, + CodeBlock(link_code), flags) + header_output += BasicDeclare.subst(link_iop) + decoder_output += BasicConstructor.subst(link_iop) + exec_output += BasicExecute.subst(link_iop) + + # need to use link_iop for the decode template since it is expecting + # the shorter version of class_name (w/o "AndLink") + + return (header_output, decoder_output, + JumpOrBranchDecode.subst(nolink_iop), exec_output) +}}; + +def format UncondBranch(*flags) {{ + flags += ('IsUncondControl', 'IsDirectControl') + (header_output, decoder_output, decode_block, exec_output) = \ + UncondCtrlBase(name, Name, 'Branch', 'NPC + disp', flags) +}}; + +def format Jump(*flags) {{ + flags += ('IsUncondControl', 'IsIndirectControl') + (header_output, decoder_output, decode_block, exec_output) = \ + UncondCtrlBase(name, Name, 'Jump', '(Rb & ~3) | (NPC & 1)', flags) +}}; + + +//////////////////////////////////////////////////////////////////// +// +// PAL calls +// + +output header {{ + /** + * Base class for emulated call_pal calls (used only in + * non-full-system mode). + */ + class EmulatedCallPal : public AlphaStaticInst + { + protected: + + /// Constructor. + EmulatedCallPal(const char *mnem, MachInst _machInst, + OpClass __opClass) + : AlphaStaticInst(mnem, _machInst, __opClass) + { + } + + std::string + generateDisassembly(Addr pc, const SymbolTable *symtab) const; + }; +}}; + +output decoder {{ + std::string + EmulatedCallPal::generateDisassembly(Addr pc, + const SymbolTable *symtab) const + { +#ifdef SS_COMPATIBLE_DISASSEMBLY + return csprintf("%s %s", "call_pal", mnemonic); +#else + return csprintf("%-10s %s", "call_pal", mnemonic); +#endif + } +}}; + +def format EmulatedCallPal(code, *flags) {{ + iop = InstObjParams(name, Name, 'EmulatedCallPal', CodeBlock(code), flags) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecode.subst(iop) + exec_output = BasicExecute.subst(iop) +}}; + +output header {{ + /** + * Base class for full-system-mode call_pal instructions. + * Probably could turn this into a leaf class and get rid of the + * parser template. + */ + class CallPalBase : public AlphaStaticInst + { + protected: + int palFunc; ///< Function code part of instruction + int palOffset; ///< Target PC, offset from IPR_PAL_BASE + bool palValid; ///< is the function code valid? + bool palPriv; ///< is this call privileged? + + /// Constructor. + CallPalBase(const char *mnem, MachInst _machInst, + OpClass __opClass); + + std::string + generateDisassembly(Addr pc, const SymbolTable *symtab) const; + }; +}}; + +output decoder {{ + inline + CallPalBase::CallPalBase(const char *mnem, MachInst _machInst, + OpClass __opClass) + : AlphaStaticInst(mnem, _machInst, __opClass), + palFunc(PALFUNC) + { + // From the 21164 HRM (paraphrased): + // Bit 7 of the function code (mask 0x80) indicates + // whether the call is privileged (bit 7 == 0) or + // unprivileged (bit 7 == 1). The privileged call table + // starts at 0x2000, the unprivielged call table starts at + // 0x3000. Bits 5-0 (mask 0x3f) are used to calculate the + // offset. + const int palPrivMask = 0x80; + const int palOffsetMask = 0x3f; + + // Pal call is invalid unless all other bits are 0 + palValid = ((machInst & ~(palPrivMask | palOffsetMask)) == 0); + palPriv = ((machInst & palPrivMask) == 0); + int shortPalFunc = (machInst & palOffsetMask); + // Add 1 to base to set pal-mode bit + palOffset = (palPriv ? 0x2001 : 0x3001) + (shortPalFunc << 6); + } + + std::string + CallPalBase::generateDisassembly(Addr pc, const SymbolTable *symtab) const + { + return csprintf("%-10s %#x", "call_pal", palFunc); + } +}}; + +def format CallPal(code, *flags) {{ + iop = InstObjParams(name, Name, 'CallPalBase', CodeBlock(code), flags) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecode.subst(iop) + exec_output = BasicExecute.subst(iop) +}}; + +//////////////////////////////////////////////////////////////////// +// +// hw_ld, hw_st +// + +output header {{ + /** + * Base class for hw_ld and hw_st. + */ + class HwLoadStore : public Memory + { + protected: + + /// Displacement for EA calculation (signed). + int16_t disp; + + /// Constructor + HwLoadStore(const char *mnem, MachInst _machInst, OpClass __opClass, + StaticInstPtr _eaCompPtr = nullStaticInstPtr, + StaticInstPtr _memAccPtr = nullStaticInstPtr); + + std::string + generateDisassembly(Addr pc, const SymbolTable *symtab) const; + }; +}}; + + +output decoder {{ + inline + HwLoadStore::HwLoadStore(const char *mnem, MachInst _machInst, + OpClass __opClass, + StaticInstPtr _eaCompPtr, + StaticInstPtr _memAccPtr) + : Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr), + disp(HW_LDST_DISP) + { + memAccessFlags = 0; + if (HW_LDST_PHYS) memAccessFlags |= PHYSICAL; + if (HW_LDST_ALT) memAccessFlags |= ALTMODE; + if (HW_LDST_VPTE) memAccessFlags |= VPTE; + if (HW_LDST_LOCK) memAccessFlags |= LOCKED; + } + + std::string + HwLoadStore::generateDisassembly(Addr pc, const SymbolTable *symtab) const + { +#ifdef SS_COMPATIBLE_DISASSEMBLY + return csprintf("%-10s r%d,%d(r%d)", mnemonic, RA, disp, RB); +#else + // HW_LDST_LOCK and HW_LDST_COND are the same bit. + const char *lock_str = + (HW_LDST_LOCK) ? (flags[IsLoad] ? ",LOCK" : ",COND") : ""; + + return csprintf("%-10s r%d,%d(r%d)%s%s%s%s%s", + mnemonic, RA, disp, RB, + HW_LDST_PHYS ? ",PHYS" : "", + HW_LDST_ALT ? ",ALT" : "", + HW_LDST_QUAD ? ",QUAD" : "", + HW_LDST_VPTE ? ",VPTE" : "", + lock_str); +#endif + } +}}; + +def format HwLoadStore(ea_code, memacc_code, class_ext, *flags) {{ + (header_output, decoder_output, decode_block, exec_output) = \ + LoadStoreBase(name, Name + class_ext, ea_code, memacc_code, + flags = flags, base_class = 'HwLoadStore') +}}; + + +def format HwStoreCond(ea_code, memacc_code, postacc_code, class_ext, *flags) {{ + (header_output, decoder_output, decode_block, exec_output) = \ + LoadStoreBase(name, Name + class_ext, ea_code, memacc_code, + postacc_code, flags = flags, base_class = 'HwLoadStore') +}}; + + +output header {{ + /** + * Base class for hw_mfpr and hw_mtpr. + */ + class HwMoveIPR : public AlphaStaticInst + { + protected: + /// Index of internal processor register. + int ipr_index; + + /// Constructor + HwMoveIPR(const char *mnem, MachInst _machInst, OpClass __opClass) + : AlphaStaticInst(mnem, _machInst, __opClass), + ipr_index(HW_IPR_IDX) + { + } + + std::string + generateDisassembly(Addr pc, const SymbolTable *symtab) const; + }; +}}; + +output decoder {{ + std::string + HwMoveIPR::generateDisassembly(Addr pc, const SymbolTable *symtab) const + { + if (_numSrcRegs > 0) { + // must be mtpr + return csprintf("%-10s r%d,IPR(%#x)", + mnemonic, RA, ipr_index); + } + else { + // must be mfpr + return csprintf("%-10s IPR(%#x),r%d", + mnemonic, ipr_index, RA); + } + } +}}; + +def format HwMoveIPR(code) {{ + iop = InstObjParams(name, Name, 'HwMoveIPR', CodeBlock(code), + ['IprAccessOp']) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecode.subst(iop) + exec_output = BasicExecute.subst(iop) +}}; + + +//////////////////////////////////////////////////////////////////// +// +// Unimplemented instructions +// + +output header {{ + /** + * Static instruction class for unimplemented instructions that + * cause simulator termination. Note that these are recognized + * (legal) instructions that the simulator does not support; the + * 'Unknown' class is used for unrecognized/illegal instructions. + * This is a leaf class. + */ + class FailUnimplemented : public AlphaStaticInst + { + public: + /// Constructor + FailUnimplemented(const char *_mnemonic, MachInst _machInst) + : AlphaStaticInst(_mnemonic, _machInst, No_OpClass) + { + // don't call execute() (which panics) if we're on a + // speculative path + flags[IsNonSpeculative] = true; + } + + %(BasicExecDeclare)s + + std::string + generateDisassembly(Addr pc, const SymbolTable *symtab) const; + }; + + /** + * Base class for unimplemented instructions that cause a warning + * to be printed (but do not terminate simulation). This + * implementation is a little screwy in that it will print a + * warning for each instance of a particular unimplemented machine + * instruction, not just for each unimplemented opcode. Should + * probably make the 'warned' flag a static member of the derived + * class. + */ + class WarnUnimplemented : public AlphaStaticInst + { + private: + /// Have we warned on this instruction yet? + mutable bool warned; + + public: + /// Constructor + WarnUnimplemented(const char *_mnemonic, MachInst _machInst) + : AlphaStaticInst(_mnemonic, _machInst, No_OpClass), warned(false) + { + // don't call execute() (which panics) if we're on a + // speculative path + flags[IsNonSpeculative] = true; + } + + %(BasicExecDeclare)s + + std::string + generateDisassembly(Addr pc, const SymbolTable *symtab) const; + }; +}}; + +output decoder {{ + std::string + FailUnimplemented::generateDisassembly(Addr pc, + const SymbolTable *symtab) const + { + return csprintf("%-10s (unimplemented)", mnemonic); + } + + std::string + WarnUnimplemented::generateDisassembly(Addr pc, + const SymbolTable *symtab) const + { +#ifdef SS_COMPATIBLE_DISASSEMBLY + return csprintf("%-10s", mnemonic); +#else + return csprintf("%-10s (unimplemented)", mnemonic); +#endif + } +}}; + +output exec {{ + Fault + FailUnimplemented::execute(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + panic("attempt to execute unimplemented instruction '%s' " + "(inst 0x%08x, opcode 0x%x)", mnemonic, machInst, OPCODE); + return Unimplemented_Opcode_Fault; + } + + Fault + WarnUnimplemented::execute(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + if (!warned) { + warn("instruction '%s' unimplemented\n", mnemonic); + warned = true; + } + + return No_Fault; + } +}}; + + +def format FailUnimpl() {{ + iop = InstObjParams(name, 'FailUnimplemented') + decode_block = BasicDecodeWithMnemonic.subst(iop) +}}; + +def format WarnUnimpl() {{ + iop = InstObjParams(name, 'WarnUnimplemented') + decode_block = BasicDecodeWithMnemonic.subst(iop) +}}; + +output header {{ + /** + * Static instruction class for unknown (illegal) instructions. + * These cause simulator termination if they are executed in a + * non-speculative mode. This is a leaf class. + */ + class Unknown : public AlphaStaticInst + { + public: + /// Constructor + Unknown(MachInst _machInst) + : AlphaStaticInst("unknown", _machInst, No_OpClass) + { + // don't call execute() (which panics) if we're on a + // speculative path + flags[IsNonSpeculative] = true; + } + + %(BasicExecDeclare)s + + std::string + generateDisassembly(Addr pc, const SymbolTable *symtab) const; + }; +}}; + +//////////////////////////////////////////////////////////////////// +// +// Unknown instructions +// + +output decoder {{ + std::string + Unknown::generateDisassembly(Addr pc, const SymbolTable *symtab) const + { + return csprintf("%-10s (inst 0x%x, opcode 0x%x)", + "unknown", machInst, OPCODE); + } +}}; + +output exec {{ + Fault + Unknown::execute(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + panic("attempt to execute unknown instruction " + "(inst 0x%08x, opcode 0x%x)", machInst, OPCODE); + return Unimplemented_Opcode_Fault; + } +}}; + +def format Unknown() {{ + decode_block = 'return new Unknown(machInst);\n' +}}; + +//////////////////////////////////////////////////////////////////// +// +// Utility functions for execute methods +// + +output exec {{ + + /// Return opa + opb, summing carry into third arg. + inline uint64_t + addc(uint64_t opa, uint64_t opb, int &carry) + { + uint64_t res = opa + opb; + if (res < opa || res < opb) + ++carry; + return res; + } + + /// Multiply two 64-bit values (opa * opb), returning the 128-bit + /// product in res_hi and res_lo. + inline void + mul128(uint64_t opa, uint64_t opb, uint64_t &res_hi, uint64_t &res_lo) + { + // do a 64x64 --> 128 multiply using four 32x32 --> 64 multiplies + uint64_t opa_hi = opa<63:32>; + uint64_t opa_lo = opa<31:0>; + uint64_t opb_hi = opb<63:32>; + uint64_t opb_lo = opb<31:0>; + + res_lo = opa_lo * opb_lo; + + // The middle partial products logically belong in bit + // positions 95 to 32. Thus the lower 32 bits of each product + // sum into the upper 32 bits of the low result, while the + // upper 32 sum into the low 32 bits of the upper result. + uint64_t partial1 = opa_hi * opb_lo; + uint64_t partial2 = opa_lo * opb_hi; + + uint64_t partial1_lo = partial1<31:0> << 32; + uint64_t partial1_hi = partial1<63:32>; + uint64_t partial2_lo = partial2<31:0> << 32; + uint64_t partial2_hi = partial2<63:32>; + + // Add partial1_lo and partial2_lo to res_lo, keeping track + // of any carries out + int carry_out = 0; + res_lo = addc(partial1_lo, res_lo, carry_out); + res_lo = addc(partial2_lo, res_lo, carry_out); + + // Now calculate the high 64 bits... + res_hi = (opa_hi * opb_hi) + partial1_hi + partial2_hi + carry_out; + } + + /// Map 8-bit S-floating exponent to 11-bit T-floating exponent. + /// See Table 2-2 of Alpha AHB. + inline int + map_s(int old_exp) + { + int hibit = old_exp<7:>; + int lobits = old_exp<6:0>; + + if (hibit == 1) { + return (lobits == 0x7f) ? 0x7ff : (0x400 | lobits); + } + else { + return (lobits == 0) ? 0 : (0x380 | lobits); + } + } + + /// Convert a 32-bit S-floating value to the equivalent 64-bit + /// representation to be stored in an FP reg. + inline uint64_t + s_to_t(uint32_t s_val) + { + uint64_t tmp = s_val; + return (tmp<31:> << 63 // sign bit + | (uint64_t)map_s(tmp<30:23>) << 52 // exponent + | tmp<22:0> << 29); // fraction + } + + /// Convert a 64-bit T-floating value to the equivalent 32-bit + /// S-floating representation to be stored in memory. + inline int32_t + t_to_s(uint64_t t_val) + { + return (t_val<63:62> << 30 // sign bit & hi exp bit + | t_val<58:29>); // rest of exp & fraction + } +}}; + +//////////////////////////////////////////////////////////////////// +// +// The actual decoder specification +// + +decode OPCODE default Unknown::unknown() { + + format LoadAddress { + 0x08: lda({{ Ra = Rb + disp; }}); + 0x09: ldah({{ Ra = Rb + (disp << 16); }}); + } + + format LoadOrNop { + 0x0a: ldbu({{ EA = Rb + disp; }}, {{ Ra.uq = Mem.ub; }}); + 0x0c: ldwu({{ EA = Rb + disp; }}, {{ Ra.uq = Mem.uw; }}); + 0x0b: ldq_u({{ EA = (Rb + disp) & ~7; }}, {{ Ra = Mem.uq; }}); + 0x23: ldt({{ EA = Rb + disp; }}, {{ Fa = Mem.df; }}); + 0x2a: ldl_l({{ EA = Rb + disp; }}, {{ Ra.sl = Mem.sl; }}, LOCKED); + 0x2b: ldq_l({{ EA = Rb + disp; }}, {{ Ra.uq = Mem.uq; }}, LOCKED); + 0x20: copy_load({{EA = Ra;}}, + {{fault = xc->copySrcTranslate(EA);}}, + IsMemRef, IsLoad, IsCopy); + } + + format LoadOrPrefetch { + 0x28: ldl({{ EA = Rb + disp; }}, {{ Ra.sl = Mem.sl; }}); + 0x29: ldq({{ EA = Rb + disp; }}, {{ Ra.uq = Mem.uq; }}, EVICT_NEXT); + // IsFloating flag on lds gets the prefetch to disassemble + // using f31 instead of r31... funcitonally it's unnecessary + 0x22: lds({{ EA = Rb + disp; }}, {{ Fa.uq = s_to_t(Mem.ul); }}, + PF_EXCLUSIVE, IsFloating); + } + + format Store { + 0x0e: stb({{ EA = Rb + disp; }}, {{ Mem.ub = Ra<7:0>; }}); + 0x0d: stw({{ EA = Rb + disp; }}, {{ Mem.uw = Ra<15:0>; }}); + 0x2c: stl({{ EA = Rb + disp; }}, {{ Mem.ul = Ra<31:0>; }}); + 0x2d: stq({{ EA = Rb + disp; }}, {{ Mem.uq = Ra.uq; }}); + 0x0f: stq_u({{ EA = (Rb + disp) & ~7; }}, {{ Mem.uq = Ra.uq; }}); + 0x26: sts({{ EA = Rb + disp; }}, {{ Mem.ul = t_to_s(Fa.uq); }}); + 0x27: stt({{ EA = Rb + disp; }}, {{ Mem.df = Fa; }}); + 0x24: copy_store({{EA = Rb;}}, + {{fault = xc->copy(EA);}}, + IsMemRef, IsStore, IsCopy); + } + + format StoreCond { + 0x2e: stl_c({{ EA = Rb + disp; }}, {{ Mem.ul = Ra<31:0>; }}, + {{ + uint64_t tmp = Mem_write_result; + // see stq_c + Ra = (tmp == 0 || tmp == 1) ? tmp : Ra; + }}, LOCKED); + 0x2f: stq_c({{ EA = Rb + disp; }}, {{ Mem.uq = Ra; }}, + {{ + uint64_t tmp = Mem_write_result; + // If the write operation returns 0 or 1, then + // this was a conventional store conditional, + // and the value indicates the success/failure + // of the operation. If another value is + // returned, then this was a Turbolaser + // mailbox access, and we don't update the + // result register at all. + Ra = (tmp == 0 || tmp == 1) ? tmp : Ra; + }}, LOCKED); + } + + format IntegerOperate { + + 0x10: decode INTFUNC { // integer arithmetic operations + + 0x00: addl({{ Rc.sl = Ra.sl + Rb_or_imm.sl; }}); + 0x40: addlv({{ + uint32_t tmp = Ra.sl + Rb_or_imm.sl; + // signed overflow occurs when operands have same sign + // and sign of result does not match. + if (Ra.sl<31:> == Rb_or_imm.sl<31:> && tmp<31:> != Ra.sl<31:>) + fault = Integer_Overflow_Fault; + Rc.sl = tmp; + }}); + 0x02: s4addl({{ Rc.sl = (Ra.sl << 2) + Rb_or_imm.sl; }}); + 0x12: s8addl({{ Rc.sl = (Ra.sl << 3) + Rb_or_imm.sl; }}); + + 0x20: addq({{ Rc = Ra + Rb_or_imm; }}); + 0x60: addqv({{ + uint64_t tmp = Ra + Rb_or_imm; + // signed overflow occurs when operands have same sign + // and sign of result does not match. + if (Ra<63:> == Rb_or_imm<63:> && tmp<63:> != Ra<63:>) + fault = Integer_Overflow_Fault; + Rc = tmp; + }}); + 0x22: s4addq({{ Rc = (Ra << 2) + Rb_or_imm; }}); + 0x32: s8addq({{ Rc = (Ra << 3) + Rb_or_imm; }}); + + 0x09: subl({{ Rc.sl = Ra.sl - Rb_or_imm.sl; }}); + 0x49: sublv({{ + uint32_t tmp = Ra.sl - Rb_or_imm.sl; + // signed overflow detection is same as for add, + // except we need to look at the *complemented* + // sign bit of the subtrahend (Rb), i.e., if the initial + // signs are the *same* then no overflow can occur + if (Ra.sl<31:> != Rb_or_imm.sl<31:> && tmp<31:> != Ra.sl<31:>) + fault = Integer_Overflow_Fault; + Rc.sl = tmp; + }}); + 0x0b: s4subl({{ Rc.sl = (Ra.sl << 2) - Rb_or_imm.sl; }}); + 0x1b: s8subl({{ Rc.sl = (Ra.sl << 3) - Rb_or_imm.sl; }}); + + 0x29: subq({{ Rc = Ra - Rb_or_imm; }}); + 0x69: subqv({{ + uint64_t tmp = Ra - Rb_or_imm; + // signed overflow detection is same as for add, + // except we need to look at the *complemented* + // sign bit of the subtrahend (Rb), i.e., if the initial + // signs are the *same* then no overflow can occur + if (Ra<63:> != Rb_or_imm<63:> && tmp<63:> != Ra<63:>) + fault = Integer_Overflow_Fault; + Rc = tmp; + }}); + 0x2b: s4subq({{ Rc = (Ra << 2) - Rb_or_imm; }}); + 0x3b: s8subq({{ Rc = (Ra << 3) - Rb_or_imm; }}); + + 0x2d: cmpeq({{ Rc = (Ra == Rb_or_imm); }}); + 0x6d: cmple({{ Rc = (Ra.sq <= Rb_or_imm.sq); }}); + 0x4d: cmplt({{ Rc = (Ra.sq < Rb_or_imm.sq); }}); + 0x3d: cmpule({{ Rc = (Ra.uq <= Rb_or_imm.uq); }}); + 0x1d: cmpult({{ Rc = (Ra.uq < Rb_or_imm.uq); }}); + + 0x0f: cmpbge({{ + int hi = 7; + int lo = 0; + uint64_t tmp = 0; + for (int i = 0; i < 8; ++i) { + tmp |= (Ra.uq >= Rb_or_imm.uq) << i; + hi += 8; + lo += 8; + } + Rc = tmp; + }}); + } + + 0x11: decode INTFUNC { // integer logical operations + + 0x00: and({{ Rc = Ra & Rb_or_imm; }}); + 0x08: bic({{ Rc = Ra & ~Rb_or_imm; }}); + 0x20: bis({{ Rc = Ra | Rb_or_imm; }}); + 0x28: ornot({{ Rc = Ra | ~Rb_or_imm; }}); + 0x40: xor({{ Rc = Ra ^ Rb_or_imm; }}); + 0x48: eqv({{ Rc = Ra ^ ~Rb_or_imm; }}); + + // conditional moves + 0x14: cmovlbs({{ Rc = ((Ra & 1) == 1) ? Rb_or_imm : Rc; }}); + 0x16: cmovlbc({{ Rc = ((Ra & 1) == 0) ? Rb_or_imm : Rc; }}); + 0x24: cmoveq({{ Rc = (Ra == 0) ? Rb_or_imm : Rc; }}); + 0x26: cmovne({{ Rc = (Ra != 0) ? Rb_or_imm : Rc; }}); + 0x44: cmovlt({{ Rc = (Ra.sq < 0) ? Rb_or_imm : Rc; }}); + 0x46: cmovge({{ Rc = (Ra.sq >= 0) ? Rb_or_imm : Rc; }}); + 0x64: cmovle({{ Rc = (Ra.sq <= 0) ? Rb_or_imm : Rc; }}); + 0x66: cmovgt({{ Rc = (Ra.sq > 0) ? Rb_or_imm : Rc; }}); + + // For AMASK, RA must be R31. + 0x61: decode RA { + 31: amask({{ Rc = Rb_or_imm & ~ULL(0x17); }}); + } + + // For IMPLVER, RA must be R31 and the B operand + // must be the immediate value 1. + 0x6c: decode RA { + 31: decode IMM { + 1: decode INTIMM { + // return EV5 for FULL_SYSTEM and EV6 otherwise + 1: implver({{ +#if FULL_SYSTEM + Rc = 1; +#else + Rc = 2; +#endif + }}); + } + } + } + +#if FULL_SYSTEM + // The mysterious 11.25... + 0x25: WarnUnimpl::eleven25(); +#endif + } + + 0x12: decode INTFUNC { + 0x39: sll({{ Rc = Ra << Rb_or_imm<5:0>; }}); + 0x34: srl({{ Rc = Ra.uq >> Rb_or_imm<5:0>; }}); + 0x3c: sra({{ Rc = Ra.sq >> Rb_or_imm<5:0>; }}); + + 0x02: mskbl({{ Rc = Ra & ~(mask( 8) << (Rb_or_imm<2:0> * 8)); }}); + 0x12: mskwl({{ Rc = Ra & ~(mask(16) << (Rb_or_imm<2:0> * 8)); }}); + 0x22: mskll({{ Rc = Ra & ~(mask(32) << (Rb_or_imm<2:0> * 8)); }}); + 0x32: mskql({{ Rc = Ra & ~(mask(64) << (Rb_or_imm<2:0> * 8)); }}); + + 0x52: mskwh({{ + int bv = Rb_or_imm<2:0>; + Rc = bv ? (Ra & ~(mask(16) >> (64 - 8 * bv))) : Ra; + }}); + 0x62: msklh({{ + int bv = Rb_or_imm<2:0>; + Rc = bv ? (Ra & ~(mask(32) >> (64 - 8 * bv))) : Ra; + }}); + 0x72: mskqh({{ + int bv = Rb_or_imm<2:0>; + Rc = bv ? (Ra & ~(mask(64) >> (64 - 8 * bv))) : Ra; + }}); + + 0x06: extbl({{ Rc = (Ra.uq >> (Rb_or_imm<2:0> * 8))< 7:0>; }}); + 0x16: extwl({{ Rc = (Ra.uq >> (Rb_or_imm<2:0> * 8))<15:0>; }}); + 0x26: extll({{ Rc = (Ra.uq >> (Rb_or_imm<2:0> * 8))<31:0>; }}); + 0x36: extql({{ Rc = (Ra.uq >> (Rb_or_imm<2:0> * 8)); }}); + + 0x5a: extwh({{ + Rc = (Ra << (64 - (Rb_or_imm<2:0> * 8))<5:0>)<15:0>; }}); + 0x6a: extlh({{ + Rc = (Ra << (64 - (Rb_or_imm<2:0> * 8))<5:0>)<31:0>; }}); + 0x7a: extqh({{ + Rc = (Ra << (64 - (Rb_or_imm<2:0> * 8))<5:0>); }}); + + 0x0b: insbl({{ Rc = Ra< 7:0> << (Rb_or_imm<2:0> * 8); }}); + 0x1b: inswl({{ Rc = Ra<15:0> << (Rb_or_imm<2:0> * 8); }}); + 0x2b: insll({{ Rc = Ra<31:0> << (Rb_or_imm<2:0> * 8); }}); + 0x3b: insql({{ Rc = Ra << (Rb_or_imm<2:0> * 8); }}); + + 0x57: inswh({{ + int bv = Rb_or_imm<2:0>; + Rc = bv ? (Ra.uq<15:0> >> (64 - 8 * bv)) : 0; + }}); + 0x67: inslh({{ + int bv = Rb_or_imm<2:0>; + Rc = bv ? (Ra.uq<31:0> >> (64 - 8 * bv)) : 0; + }}); + 0x77: insqh({{ + int bv = Rb_or_imm<2:0>; + Rc = bv ? (Ra.uq >> (64 - 8 * bv)) : 0; + }}); + + 0x30: zap({{ + uint64_t zapmask = 0; + for (int i = 0; i < 8; ++i) { + if (Rb_or_imm) + zapmask |= (mask(8) << (i * 8)); + } + Rc = Ra & ~zapmask; + }}); + 0x31: zapnot({{ + uint64_t zapmask = 0; + for (int i = 0; i < 8; ++i) { + if (!Rb_or_imm) + zapmask |= (mask(8) << (i * 8)); + } + Rc = Ra & ~zapmask; + }}); + } + + 0x13: decode INTFUNC { // integer multiplies + 0x00: mull({{ Rc.sl = Ra.sl * Rb_or_imm.sl; }}, IntMultOp); + 0x20: mulq({{ Rc = Ra * Rb_or_imm; }}, IntMultOp); + 0x30: umulh({{ + uint64_t hi, lo; + mul128(Ra, Rb_or_imm, hi, lo); + Rc = hi; + }}, IntMultOp); + 0x40: mullv({{ + // 32-bit multiply with trap on overflow + int64_t Rax = Ra.sl; // sign extended version of Ra.sl + int64_t Rbx = Rb_or_imm.sl; + int64_t tmp = Rax * Rbx; + // To avoid overflow, all the upper 32 bits must match + // the sign bit of the lower 32. We code this as + // checking the upper 33 bits for all 0s or all 1s. + uint64_t sign_bits = tmp<63:31>; + if (sign_bits != 0 && sign_bits != mask(33)) + fault = Integer_Overflow_Fault; + Rc.sl = tmp<31:0>; + }}, IntMultOp); + 0x60: mulqv({{ + // 64-bit multiply with trap on overflow + uint64_t hi, lo; + mul128(Ra, Rb_or_imm, hi, lo); + // all the upper 64 bits must match the sign bit of + // the lower 64 + if (!((hi == 0 && lo<63:> == 0) || + (hi == mask(64) && lo<63:> == 1))) + fault = Integer_Overflow_Fault; + Rc = lo; + }}, IntMultOp); + } + + 0x1c: decode INTFUNC { + 0x00: decode RA { 31: sextb({{ Rc.sb = Rb_or_imm< 7:0>; }}); } + 0x01: decode RA { 31: sextw({{ Rc.sw = Rb_or_imm<15:0>; }}); } + 0x32: ctlz({{ + uint64_t count = 0; + uint64_t temp = Rb; + if (temp<63:32>) temp >>= 32; else count += 32; + if (temp<31:16>) temp >>= 16; else count += 16; + if (temp<15:8>) temp >>= 8; else count += 8; + if (temp<7:4>) temp >>= 4; else count += 4; + if (temp<3:2>) temp >>= 2; else count += 2; + if (temp<1:1>) temp >>= 1; else count += 1; + if ((temp<0:0>) != 0x1) count += 1; + Rc = count; + }}, IntAluOp); + + 0x33: cttz({{ + uint64_t count = 0; + uint64_t temp = Rb; + if (!(temp<31:0>)) { temp >>= 32; count += 32; } + if (!(temp<15:0>)) { temp >>= 16; count += 16; } + if (!(temp<7:0>)) { temp >>= 8; count += 8; } + if (!(temp<3:0>)) { temp >>= 4; count += 4; } + if (!(temp<1:0>)) { temp >>= 2; count += 2; } + if (!(temp<0:0> & ULL(0x1))) count += 1; + Rc = count; + }}, IntAluOp); + + format FailUnimpl { + 0x30: ctpop(); + 0x31: perr(); + 0x34: unpkbw(); + 0x35: unpkbl(); + 0x36: pkwb(); + 0x37: pklb(); + 0x38: minsb8(); + 0x39: minsw4(); + 0x3a: minub8(); + 0x3b: minuw4(); + 0x3c: maxub8(); + 0x3d: maxuw4(); + 0x3e: maxsb8(); + 0x3f: maxsw4(); + } + + format BasicOperateWithNopCheck { + 0x70: decode RB { + 31: ftoit({{ Rc = Fa.uq; }}, FloatCvtOp); + } + 0x78: decode RB { + 31: ftois({{ Rc.sl = t_to_s(Fa.uq); }}, + FloatCvtOp); + } + } + } + } + + // Conditional branches. + format CondBranch { + 0x39: beq({{ cond = (Ra == 0); }}); + 0x3d: bne({{ cond = (Ra != 0); }}); + 0x3e: bge({{ cond = (Ra.sq >= 0); }}); + 0x3f: bgt({{ cond = (Ra.sq > 0); }}); + 0x3b: ble({{ cond = (Ra.sq <= 0); }}); + 0x3a: blt({{ cond = (Ra.sq < 0); }}); + 0x38: blbc({{ cond = ((Ra & 1) == 0); }}); + 0x3c: blbs({{ cond = ((Ra & 1) == 1); }}); + + 0x31: fbeq({{ cond = (Fa == 0); }}); + 0x35: fbne({{ cond = (Fa != 0); }}); + 0x36: fbge({{ cond = (Fa >= 0); }}); + 0x37: fbgt({{ cond = (Fa > 0); }}); + 0x33: fble({{ cond = (Fa <= 0); }}); + 0x32: fblt({{ cond = (Fa < 0); }}); + } + + // unconditional branches + format UncondBranch { + 0x30: br(); + 0x34: bsr(IsCall); + } + + // indirect branches + 0x1a: decode JMPFUNC { + format Jump { + 0: jmp(); + 1: jsr(IsCall); + 2: ret(IsReturn); + 3: jsr_coroutine(IsCall, IsReturn); + } + } + + // Square root and integer-to-FP moves + 0x14: decode FP_SHORTFUNC { + // Integer to FP register moves must have RB == 31 + 0x4: decode RB { + 31: decode FP_FULLFUNC { + format BasicOperateWithNopCheck { + 0x004: itofs({{ Fc.uq = s_to_t(Ra.ul); }}, FloatCvtOp); + 0x024: itoft({{ Fc.uq = Ra.uq; }}, FloatCvtOp); + 0x014: FailUnimpl::itoff(); // VAX-format conversion + } + } + } + + // Square root instructions must have FA == 31 + 0xb: decode FA { + 31: decode FP_TYPEFUNC { + format FloatingPointOperate { +#if SS_COMPATIBLE_FP + 0x0b: sqrts({{ + if (Fb < 0.0) + fault = Arithmetic_Fault; + Fc = sqrt(Fb); + }}, FloatSqrtOp); +#else + 0x0b: sqrts({{ + if (Fb.sf < 0.0) + fault = Arithmetic_Fault; + Fc.sf = sqrt(Fb.sf); + }}, FloatSqrtOp); +#endif + 0x2b: sqrtt({{ + if (Fb < 0.0) + fault = Arithmetic_Fault; + Fc = sqrt(Fb); + }}, FloatSqrtOp); + } + } + } + + // VAX-format sqrtf and sqrtg are not implemented + 0xa: FailUnimpl::sqrtfg(); + } + + // IEEE floating point + 0x16: decode FP_SHORTFUNC_TOP2 { + // The top two bits of the short function code break this + // space into four groups: binary ops, compares, reserved, and + // conversions. See Table 4-12 of AHB. There are different + // special cases in these different groups, so we decode on + // these top two bits first just to select a decode strategy. + // Most of these instructions may have various trapping and + // rounding mode flags set; these are decoded in the + // FloatingPointDecode template used by the + // FloatingPointOperate format. + + // add/sub/mul/div: just decode on the short function code + // and source type. All valid trapping and rounding modes apply. + 0: decode FP_TRAPMODE { + // check for valid trapping modes here + 0,1,5,7: decode FP_TYPEFUNC { + format FloatingPointOperate { +#if SS_COMPATIBLE_FP + 0x00: adds({{ Fc = Fa + Fb; }}); + 0x01: subs({{ Fc = Fa - Fb; }}); + 0x02: muls({{ Fc = Fa * Fb; }}, FloatMultOp); + 0x03: divs({{ Fc = Fa / Fb; }}, FloatDivOp); +#else + 0x00: adds({{ Fc.sf = Fa.sf + Fb.sf; }}); + 0x01: subs({{ Fc.sf = Fa.sf - Fb.sf; }}); + 0x02: muls({{ Fc.sf = Fa.sf * Fb.sf; }}, FloatMultOp); + 0x03: divs({{ Fc.sf = Fa.sf / Fb.sf; }}, FloatDivOp); +#endif + + 0x20: addt({{ Fc = Fa + Fb; }}); + 0x21: subt({{ Fc = Fa - Fb; }}); + 0x22: mult({{ Fc = Fa * Fb; }}, FloatMultOp); + 0x23: divt({{ Fc = Fa / Fb; }}, FloatDivOp); + } + } + } + + // Floating-point compare instructions must have the default + // rounding mode, and may use the default trapping mode or + // /SU. Both trapping modes are treated the same by M5; the + // only difference on the real hardware (as far a I can tell) + // is that without /SU you'd get an imprecise trap if you + // tried to compare a NaN with something else (instead of an + // "unordered" result). + 1: decode FP_FULLFUNC { + format BasicOperateWithNopCheck { + 0x0a5, 0x5a5: cmpteq({{ Fc = (Fa == Fb) ? 2.0 : 0.0; }}, + FloatCmpOp); + 0x0a7, 0x5a7: cmptle({{ Fc = (Fa <= Fb) ? 2.0 : 0.0; }}, + FloatCmpOp); + 0x0a6, 0x5a6: cmptlt({{ Fc = (Fa < Fb) ? 2.0 : 0.0; }}, + FloatCmpOp); + 0x0a4, 0x5a4: cmptun({{ // unordered + Fc = (!(Fa < Fb) && !(Fa == Fb) && !(Fa > Fb)) ? 2.0 : 0.0; + }}, FloatCmpOp); + } + } + + // The FP-to-integer and integer-to-FP conversion insts + // require that FA be 31. + 3: decode FA { + 31: decode FP_TYPEFUNC { + format FloatingPointOperate { + 0x2f: decode FP_ROUNDMODE { + format FPFixedRounding { + // "chopped" i.e. round toward zero + 0: cvttq({{ Fc.sq = (int64_t)trunc(Fb); }}, + Chopped); + // round to minus infinity + 1: cvttq({{ Fc.sq = (int64_t)floor(Fb); }}, + MinusInfinity); + } + default: cvttq({{ Fc.sq = (int64_t)nearbyint(Fb); }}); + } + + // The cvtts opcode is overloaded to be cvtst if the trap + // mode is 2 or 6 (which are not valid otherwise) + 0x2c: decode FP_FULLFUNC { + format BasicOperateWithNopCheck { + // trap on denorm version "cvtst/s" is + // simulated same as cvtst + 0x2ac, 0x6ac: cvtst({{ Fc = Fb.sf; }}); + } + default: cvtts({{ Fc.sf = Fb; }}); + } + + // The trapping mode for integer-to-FP conversions + // must be /SUI or nothing; /U and /SU are not + // allowed. The full set of rounding modes are + // supported though. + 0x3c: decode FP_TRAPMODE { + 0,7: cvtqs({{ Fc.sf = Fb.sq; }}); + } + 0x3e: decode FP_TRAPMODE { + 0,7: cvtqt({{ Fc = Fb.sq; }}); + } + } + } + } + } + + // misc FP operate + 0x17: decode FP_FULLFUNC { + format BasicOperateWithNopCheck { + 0x010: cvtlq({{ + Fc.sl = (Fb.uq<63:62> << 30) | Fb.uq<58:29>; + }}); + 0x030: cvtql({{ + Fc.uq = (Fb.uq<31:30> << 62) | (Fb.uq<29:0> << 29); + }}); + + // We treat the precise & imprecise trapping versions of + // cvtql identically. + 0x130, 0x530: cvtqlv({{ + // To avoid overflow, all the upper 32 bits must match + // the sign bit of the lower 32. We code this as + // checking the upper 33 bits for all 0s or all 1s. + uint64_t sign_bits = Fb.uq<63:31>; + if (sign_bits != 0 && sign_bits != mask(33)) + fault = Integer_Overflow_Fault; + Fc.uq = (Fb.uq<31:30> << 62) | (Fb.uq<29:0> << 29); + }}); + + 0x020: cpys({{ // copy sign + Fc.uq = (Fa.uq<63:> << 63) | Fb.uq<62:0>; + }}); + 0x021: cpysn({{ // copy sign negated + Fc.uq = (~Fa.uq<63:> << 63) | Fb.uq<62:0>; + }}); + 0x022: cpyse({{ // copy sign and exponent + Fc.uq = (Fa.uq<63:52> << 52) | Fb.uq<51:0>; + }}); + + 0x02a: fcmoveq({{ Fc = (Fa == 0) ? Fb : Fc; }}); + 0x02b: fcmovne({{ Fc = (Fa != 0) ? Fb : Fc; }}); + 0x02c: fcmovlt({{ Fc = (Fa < 0) ? Fb : Fc; }}); + 0x02d: fcmovge({{ Fc = (Fa >= 0) ? Fb : Fc; }}); + 0x02e: fcmovle({{ Fc = (Fa <= 0) ? Fb : Fc; }}); + 0x02f: fcmovgt({{ Fc = (Fa > 0) ? Fb : Fc; }}); + + 0x024: mt_fpcr({{ FPCR = Fa.uq; }}); + 0x025: mf_fpcr({{ Fa.uq = FPCR; }}); + } + } + + // miscellaneous mem-format ops + 0x18: decode MEMFUNC { + format WarnUnimpl { + 0x8000: fetch(); + 0xa000: fetch_m(); + 0xe800: ecb(); + } + + format MiscPrefetch { + 0xf800: wh64({{ EA = Rb & ~ULL(63); }}, + {{ xc->writeHint(EA, 64, memAccessFlags); }}, + IsMemRef, IsDataPrefetch, IsStore, MemWriteOp, + NO_FAULT); + } + + format BasicOperate { + 0xc000: rpcc({{ +#if FULL_SYSTEM + /* Rb is a fake dependency so here is a fun way to get + * the parser to understand that. + */ + Ra = xc->readIpr(AlphaISA::IPR_CC, fault) + (Rb & 0); + +#else + Ra = curTick; +#endif + }}); + + // All of the barrier instructions below do nothing in + // their execute() methods (hence the empty code blocks). + // All of their functionality is hard-coded in the + // pipeline based on the flags IsSerializing, + // IsMemBarrier, and IsWriteBarrier. In the current + // detailed CPU model, the execute() function only gets + // called at fetch, so there's no way to generate pipeline + // behavior at any other stage. Once we go to an + // exec-in-exec CPU model we should be able to get rid of + // these flags and implement this behavior via the + // execute() methods. + + // trapb is just a barrier on integer traps, where excb is + // a barrier on integer and FP traps. "EXCB is thus a + // superset of TRAPB." (Alpha ARM, Sec 4.11.4) We treat + // them the same though. + 0x0000: trapb({{ }}, IsSerializing, No_OpClass); + 0x0400: excb({{ }}, IsSerializing, No_OpClass); + 0x4000: mb({{ }}, IsMemBarrier, MemReadOp); + 0x4400: wmb({{ }}, IsWriteBarrier, MemWriteOp); + } + +#if FULL_SYSTEM + format BasicOperate { + 0xe000: rc({{ + Ra = xc->readIntrFlag(); + xc->setIntrFlag(0); + }}, IsNonSpeculative); + 0xf000: rs({{ + Ra = xc->readIntrFlag(); + xc->setIntrFlag(1); + }}, IsNonSpeculative); + } +#else + format FailUnimpl { + 0xe000: rc(); + 0xf000: rs(); + } +#endif + } + +#if FULL_SYSTEM + 0x00: CallPal::call_pal({{ + if (!palValid || + (palPriv + && xc->readIpr(AlphaISA::IPR_ICM, fault) != AlphaISA::mode_kernel)) { + // invalid pal function code, or attempt to do privileged + // PAL call in non-kernel mode + fault = Unimplemented_Opcode_Fault; + } + else { + // check to see if simulator wants to do something special + // on this PAL call (including maybe suppress it) + bool dopal = xc->simPalCheck(palFunc); + + if (dopal) { + AlphaISA::swap_palshadow(&xc->xcBase()->regs, true); + xc->setIpr(AlphaISA::IPR_EXC_ADDR, NPC); + NPC = xc->readIpr(AlphaISA::IPR_PAL_BASE, fault) + palOffset; + } + } + }}, IsNonSpeculative); +#else + 0x00: decode PALFUNC { + format EmulatedCallPal { + 0x00: halt ({{ + SimExit(curTick, "halt instruction encountered"); + }}, IsNonSpeculative); + 0x83: callsys({{ + xc->syscall(); + }}, IsNonSpeculative); + // Read uniq reg into ABI return value register (r0) + 0x9e: rduniq({{ R0 = Runiq; }}); + // Write uniq reg with value from ABI arg register (r16) + 0x9f: wruniq({{ Runiq = R16; }}); + } + } +#endif + +#if FULL_SYSTEM + format HwLoadStore { + 0x1b: decode HW_LDST_QUAD { + 0: hw_ld({{ EA = (Rb + disp) & ~3; }}, {{ Ra = Mem.ul; }}, L); + 1: hw_ld({{ EA = (Rb + disp) & ~7; }}, {{ Ra = Mem.uq; }}, Q); + } + + 0x1f: decode HW_LDST_COND { + 0: decode HW_LDST_QUAD { + 0: hw_st({{ EA = (Rb + disp) & ~3; }}, + {{ Mem.ul = Ra<31:0>; }}, L); + 1: hw_st({{ EA = (Rb + disp) & ~7; }}, + {{ Mem.uq = Ra.uq; }}, Q); + } + + 1: FailUnimpl::hw_st_cond(); + } + } + + format HwMoveIPR { + 0x19: hw_mfpr({{ + // this instruction is only valid in PAL mode + if (!xc->inPalMode()) { + fault = Unimplemented_Opcode_Fault; + } + else { + Ra = xc->readIpr(ipr_index, fault); + } + }}); + 0x1d: hw_mtpr({{ + // this instruction is only valid in PAL mode + if (!xc->inPalMode()) { + fault = Unimplemented_Opcode_Fault; + } + else { + xc->setIpr(ipr_index, Ra); + if (traceData) { traceData->setData(Ra); } + } + }}); + } + + format BasicOperate { + 0x1e: hw_rei({{ xc->hwrei(); }}, IsSerializing); + + // M5 special opcodes use the reserved 0x01 opcode space + 0x01: decode M5FUNC { + 0x00: arm({{ + AlphaPseudo::arm(xc->xcBase()); + }}, IsNonSpeculative); + 0x01: quiesce({{ + AlphaPseudo::quiesce(xc->xcBase()); + }}, IsNonSpeculative); + 0x10: ivlb({{ + AlphaPseudo::ivlb(xc->xcBase()); + }}, No_OpClass, IsNonSpeculative); + 0x11: ivle({{ + AlphaPseudo::ivle(xc->xcBase()); + }}, No_OpClass, IsNonSpeculative); + 0x20: m5exit_old({{ + AlphaPseudo::m5exit_old(xc->xcBase()); + }}, No_OpClass, IsNonSpeculative); + 0x21: m5exit({{ + AlphaPseudo::m5exit(xc->xcBase()); + }}, No_OpClass, IsNonSpeculative); + 0x30: initparam({{ Ra = xc->xcBase()->cpu->system->init_param; }}); + 0x40: resetstats({{ + AlphaPseudo::resetstats(xc->xcBase()); + }}, IsNonSpeculative); + 0x41: dumpstats({{ + AlphaPseudo::dumpstats(xc->xcBase()); + }}, IsNonSpeculative); + 0x42: dumpresetstats({{ + AlphaPseudo::dumpresetstats(xc->xcBase()); + }}, IsNonSpeculative); + 0x43: m5checkpoint({{ + AlphaPseudo::m5checkpoint(xc->xcBase()); + }}, IsNonSpeculative); + 0x50: m5readfile({{ + AlphaPseudo::readfile(xc->xcBase()); + }}, IsNonSpeculative); + 0x51: m5break({{ + AlphaPseudo::debugbreak(xc->xcBase()); + }}, IsNonSpeculative); + 0x52: m5switchcpu({{ + AlphaPseudo::switchcpu(xc->xcBase()); + }}, IsNonSpeculative); + 0x53: m5addsymbol({{ + AlphaPseudo::addsymbol(xc->xcBase()); + }}, IsNonSpeculative); + + } + } +#endif +} diff --git a/arch/alpha/isa_desc b/arch/alpha/isa_desc deleted file mode 100644 index c998b1a0a..000000000 --- a/arch/alpha/isa_desc +++ /dev/null @@ -1,2737 +0,0 @@ -// -*- mode:c++ -*- - -//Copyright (c) 2003, 2004, 2005 -//The Regents of The University of Michigan -//All Rights Reserved - -//This code is part of the M5 simulator, developed by Nathan Binkert, -//Erik Hallnor, Steve Raasch, and Steve Reinhardt, with contributions -//from Ron Dreslinski, Dave Greene, Lisa Hsu, Kevin Lim, Ali Saidi, -//and Andrew Schultz. - -//Permission is granted to use, copy, create derivative works and -//redistribute this software and such derivative works for any purpose, -//so long as the copyright notice above, this grant of permission, and -//the disclaimer below appear in all copies made; and so long as the -//name of The University of Michigan is not used in any advertising or -//publicity pertaining to the use or distribution of this software -//without specific, written prior authorization. - -//THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION FROM THE -//UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY PURPOSE, AND WITHOUT -//WARRANTY BY THE UNIVERSITY OF MICHIGAN OF ANY KIND, EITHER EXPRESS OR -//IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED WARRANTIES OF -//MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE REGENTS OF -//THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE FOR ANY DAMAGES, -//INCLUDING DIRECT, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL -//DAMAGES, WITH RESPECT TO ANY CLAIM ARISING OUT OF OR IN CONNECTION -//WITH THE USE OF THE SOFTWARE, EVEN IF IT HAS BEEN OR IS HEREAFTER -//ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - -//////////////////////////////////////////////////////////////////// -// -// Alpha ISA description file. -// -//////////////////////////////////////////////////////////////////// - - -//////////////////////////////////////////////////////////////////// -// -// Output include file directives. -// - -output header {{ -#include -#include -#include - -#include "config/ss_compatible_fp.hh" -#include "cpu/static_inst.hh" -#include "mem/mem_req.hh" // some constructors use MemReq flags -}}; - -output decoder {{ -#include "base/cprintf.hh" -#include "base/fenv.hh" -#include "base/loader/symtab.hh" -#include "config/ss_compatible_fp.hh" -#include "cpu/exec_context.hh" // for Jump::branchTarget() - -#include -}}; - -output exec {{ -#include - -#if FULL_SYSTEM -#include "arch/alpha/pseudo_inst.hh" -#endif -#include "base/fenv.hh" -#include "config/ss_compatible_fp.hh" -#include "cpu/base.hh" -#include "cpu/exetrace.hh" -#include "sim/sim_exit.hh" -}}; - -//////////////////////////////////////////////////////////////////// -// -// Namespace statement. Everything below this line will be in the -// AlphaISAInst namespace. -// - - -namespace AlphaISA; - -//////////////////////////////////////////////////////////////////// -// -// Bitfield definitions. -// - -// Universal (format-independent) fields -def bitfield OPCODE <31:26>; -def bitfield RA <25:21>; -def bitfield RB <20:16>; - -// Memory format -def signed bitfield MEMDISP <15: 0>; // displacement -def bitfield MEMFUNC <15: 0>; // function code (same field, unsigned) - -// Memory-format jumps -def bitfield JMPFUNC <15:14>; // function code (disp<15:14>) -def bitfield JMPHINT <13: 0>; // tgt Icache idx hint (disp<13:0>) - -// Branch format -def signed bitfield BRDISP <20: 0>; // displacement - -// Integer operate format(s>; -def bitfield INTIMM <20:13>; // integer immediate (literal) -def bitfield IMM <12:12>; // immediate flag -def bitfield INTFUNC <11: 5>; // function code -def bitfield RC < 4: 0>; // dest reg - -// Floating-point operate format -def bitfield FA <25:21>; -def bitfield FB <20:16>; -def bitfield FP_FULLFUNC <15: 5>; // complete function code - def bitfield FP_TRAPMODE <15:13>; // trapping mode - def bitfield FP_ROUNDMODE <12:11>; // rounding mode - def bitfield FP_TYPEFUNC <10: 5>; // type+func: handiest for decoding - def bitfield FP_SRCTYPE <10: 9>; // source reg type - def bitfield FP_SHORTFUNC < 8: 5>; // short function code - def bitfield FP_SHORTFUNC_TOP2 <8:7>; // top 2 bits of short func code -def bitfield FC < 4: 0>; // dest reg - -// PALcode format -def bitfield PALFUNC <25: 0>; // function code - -// EV5 PAL instructions: -// HW_LD/HW_ST -def bitfield HW_LDST_PHYS <15>; // address is physical -def bitfield HW_LDST_ALT <14>; // use ALT_MODE IPR -def bitfield HW_LDST_WRTCK <13>; // HW_LD only: fault if no write acc -def bitfield HW_LDST_QUAD <12>; // size: 0=32b, 1=64b -def bitfield HW_LDST_VPTE <11>; // HW_LD only: is PTE fetch -def bitfield HW_LDST_LOCK <10>; // HW_LD only: is load locked -def bitfield HW_LDST_COND <10>; // HW_ST only: is store conditional -def signed bitfield HW_LDST_DISP <9:0>; // signed displacement - -// HW_REI -def bitfield HW_REI_TYP <15:14>; // type: stalling vs. non-stallingk -def bitfield HW_REI_MBZ <13: 0>; // must be zero - -// HW_MTPR/MW_MFPR -def bitfield HW_IPR_IDX <15:0>; // IPR index - -// M5 instructions -def bitfield M5FUNC <7:0>; - -def operand_types {{ - 'sb' : ('signed int', 8), - 'ub' : ('unsigned int', 8), - 'sw' : ('signed int', 16), - 'uw' : ('unsigned int', 16), - 'sl' : ('signed int', 32), - 'ul' : ('unsigned int', 32), - 'sq' : ('signed int', 64), - 'uq' : ('unsigned int', 64), - 'sf' : ('float', 32), - 'df' : ('float', 64) -}}; - -def operands {{ - # Int regs default to unsigned, but code should not count on this. - # For clarity, descriptions that depend on unsigned behavior should - # explicitly specify '.uq'. - 'Ra': IntRegOperandTraits('uq', 'RA', 'IsInteger', 1), - 'Rb': IntRegOperandTraits('uq', 'RB', 'IsInteger', 2), - 'Rc': IntRegOperandTraits('uq', 'RC', 'IsInteger', 3), - 'Fa': FloatRegOperandTraits('df', 'FA', 'IsFloating', 1), - 'Fb': FloatRegOperandTraits('df', 'FB', 'IsFloating', 2), - 'Fc': FloatRegOperandTraits('df', 'FC', 'IsFloating', 3), - 'Mem': MemOperandTraits('uq', None, - ('IsMemRef', 'IsLoad', 'IsStore'), 4), - 'NPC': NPCOperandTraits('uq', None, ( None, None, 'IsControl' ), 4), - 'Runiq': ControlRegOperandTraits('uq', 'Uniq', None, 1), - 'FPCR': ControlRegOperandTraits('uq', 'Fpcr', None, 1), - # The next two are hacks for non-full-system call-pal emulation - 'R0': IntRegOperandTraits('uq', '0', None, 1), - 'R16': IntRegOperandTraits('uq', '16', None, 1) -}}; - -//////////////////////////////////////////////////////////////////// -// -// Basic instruction classes/templates/formats etc. -// - -output header {{ -// uncomment the following to get SimpleScalar-compatible disassembly -// (useful for diffing output traces). -// #define SS_COMPATIBLE_DISASSEMBLY - - /** - * Base class for all Alpha static instructions. - */ - class AlphaStaticInst : public StaticInst - { - protected: - - /// Make AlphaISA register dependence tags directly visible in - /// this class and derived classes. Maybe these should really - /// live here and not in the AlphaISA namespace. - enum DependenceTags { - FP_Base_DepTag = AlphaISA::FP_Base_DepTag, - Fpcr_DepTag = AlphaISA::Fpcr_DepTag, - Uniq_DepTag = AlphaISA::Uniq_DepTag, - IPR_Base_DepTag = AlphaISA::IPR_Base_DepTag - }; - - /// Constructor. - AlphaStaticInst(const char *mnem, MachInst _machInst, - OpClass __opClass) - : StaticInst(mnem, _machInst, __opClass) - { - } - - /// Print a register name for disassembly given the unique - /// dependence tag number (FP or int). - void printReg(std::ostream &os, int reg) const; - - std::string - generateDisassembly(Addr pc, const SymbolTable *symtab) const; - }; -}}; - -output decoder {{ - void - AlphaStaticInst::printReg(std::ostream &os, int reg) const - { - if (reg < FP_Base_DepTag) { - ccprintf(os, "r%d", reg); - } - else { - ccprintf(os, "f%d", reg - FP_Base_DepTag); - } - } - - std::string - AlphaStaticInst::generateDisassembly(Addr pc, - const SymbolTable *symtab) const - { - std::stringstream ss; - - ccprintf(ss, "%-10s ", mnemonic); - - // just print the first two source regs... if there's - // a third one, it's a read-modify-write dest (Rc), - // e.g. for CMOVxx - if (_numSrcRegs > 0) { - printReg(ss, _srcRegIdx[0]); - } - if (_numSrcRegs > 1) { - ss << ","; - printReg(ss, _srcRegIdx[1]); - } - - // just print the first dest... if there's a second one, - // it's generally implicit - if (_numDestRegs > 0) { - if (_numSrcRegs > 0) - ss << ","; - printReg(ss, _destRegIdx[0]); - } - - return ss.str(); - } -}}; - -// Declarations for execute() methods. -def template BasicExecDeclare {{ - Fault execute(%(CPU_exec_context)s *, Trace::InstRecord *) const; -}}; - -// Basic instruction class declaration template. -def template BasicDeclare {{ - /** - * Static instruction class for "%(mnemonic)s". - */ - class %(class_name)s : public %(base_class)s - { - public: - /// Constructor. - %(class_name)s(MachInst machInst); - - %(BasicExecDeclare)s - }; -}}; - -// Basic instruction class constructor template. -def template BasicConstructor {{ - inline %(class_name)s::%(class_name)s(MachInst machInst) - : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s) - { - %(constructor)s; - } -}}; - -// Basic instruction class execute method template. -def template BasicExecute {{ - Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, - Trace::InstRecord *traceData) const - { - Fault fault = No_Fault; - - %(fp_enable_check)s; - %(op_decl)s; - %(op_rd)s; - %(code)s; - - if (fault == No_Fault) { - %(op_wb)s; - } - - return fault; - } -}}; - -// Basic decode template. -def template BasicDecode {{ - return new %(class_name)s(machInst); -}}; - -// Basic decode template, passing mnemonic in as string arg to constructor. -def template BasicDecodeWithMnemonic {{ - return new %(class_name)s("%(mnemonic)s", machInst); -}}; - -// The most basic instruction format... used only for a few misc. insts -def format BasicOperate(code, *flags) {{ - iop = InstObjParams(name, Name, 'AlphaStaticInst', CodeBlock(code), flags) - header_output = BasicDeclare.subst(iop) - decoder_output = BasicConstructor.subst(iop) - decode_block = BasicDecode.subst(iop) - exec_output = BasicExecute.subst(iop) -}}; - - - -//////////////////////////////////////////////////////////////////// -// -// Nop -// - -output header {{ - /** - * Static instruction class for no-ops. This is a leaf class. - */ - class Nop : public AlphaStaticInst - { - /// Disassembly of original instruction. - const std::string originalDisassembly; - - public: - /// Constructor - Nop(const std::string _originalDisassembly, MachInst _machInst) - : AlphaStaticInst("nop", _machInst, No_OpClass), - originalDisassembly(_originalDisassembly) - { - flags[IsNop] = true; - } - - ~Nop() { } - - std::string - generateDisassembly(Addr pc, const SymbolTable *symtab) const; - - %(BasicExecDeclare)s - }; -}}; - -output decoder {{ - std::string Nop::generateDisassembly(Addr pc, - const SymbolTable *symtab) const - { -#ifdef SS_COMPATIBLE_DISASSEMBLY - return originalDisassembly; -#else - return csprintf("%-10s (%s)", "nop", originalDisassembly); -#endif - } - - /// Helper function for decoding nops. Substitute Nop object - /// for original inst passed in as arg (and delete latter). - inline - AlphaStaticInst * - makeNop(AlphaStaticInst *inst) - { - AlphaStaticInst *nop = new Nop(inst->disassemble(0), inst->machInst); - delete inst; - return nop; - } -}}; - -output exec {{ - Fault - Nop::execute(%(CPU_exec_context)s *, Trace::InstRecord *) const - { - return No_Fault; - } -}}; - -// integer & FP operate instructions use Rc as dest, so check for -// Rc == 31 to detect nops -def template OperateNopCheckDecode {{ - { - AlphaStaticInst *i = new %(class_name)s(machInst); - if (RC == 31) { - i = makeNop(i); - } - return i; - } -}}; - -// Like BasicOperate format, but generates NOP if RC/FC == 31 -def format BasicOperateWithNopCheck(code, *opt_args) {{ - iop = InstObjParams(name, Name, 'AlphaStaticInst', CodeBlock(code), - opt_args) - header_output = BasicDeclare.subst(iop) - decoder_output = BasicConstructor.subst(iop) - decode_block = OperateNopCheckDecode.subst(iop) - exec_output = BasicExecute.subst(iop) -}}; - - -//////////////////////////////////////////////////////////////////// -// -// Integer operate instructions -// - -output header {{ - /** - * Base class for integer immediate instructions. - */ - class IntegerImm : public AlphaStaticInst - { - protected: - /// Immediate operand value (unsigned 8-bit int). - uint8_t imm; - - /// Constructor - IntegerImm(const char *mnem, MachInst _machInst, OpClass __opClass) - : AlphaStaticInst(mnem, _machInst, __opClass), imm(INTIMM) - { - } - - std::string - generateDisassembly(Addr pc, const SymbolTable *symtab) const; - }; -}}; - -output decoder {{ - std::string - IntegerImm::generateDisassembly(Addr pc, const SymbolTable *symtab) const - { - std::stringstream ss; - - ccprintf(ss, "%-10s ", mnemonic); - - // just print the first source reg... if there's - // a second one, it's a read-modify-write dest (Rc), - // e.g. for CMOVxx - if (_numSrcRegs > 0) { - printReg(ss, _srcRegIdx[0]); - ss << ","; - } - - ss << (int)imm; - - if (_numDestRegs > 0) { - ss << ","; - printReg(ss, _destRegIdx[0]); - } - - return ss.str(); - } -}}; - - -def template RegOrImmDecode {{ - { - AlphaStaticInst *i = - (IMM) ? (AlphaStaticInst *)new %(class_name)sImm(machInst) - : (AlphaStaticInst *)new %(class_name)s(machInst); - if (RC == 31) { - i = makeNop(i); - } - return i; - } -}}; - -// Primary format for integer operate instructions: -// - Generates both reg-reg and reg-imm versions if Rb_or_imm is used. -// - Generates NOP if RC == 31. -def format IntegerOperate(code, *opt_flags) {{ - # If the code block contains 'Rb_or_imm', we define two instructions, - # one using 'Rb' and one using 'imm', and have the decoder select - # the right one. - uses_imm = (code.find('Rb_or_imm') != -1) - if uses_imm: - orig_code = code - # base code is reg version: - # rewrite by substituting 'Rb' for 'Rb_or_imm' - code = re.sub(r'Rb_or_imm', 'Rb', orig_code) - # generate immediate version by substituting 'imm' - # note that imm takes no extenstion, so we extend - # the regexp to replace any extension as well - imm_code = re.sub(r'Rb_or_imm(\.\w+)?', 'imm', orig_code) - - # generate declaration for register version - cblk = CodeBlock(code) - iop = InstObjParams(name, Name, 'AlphaStaticInst', cblk, opt_flags) - header_output = BasicDeclare.subst(iop) - decoder_output = BasicConstructor.subst(iop) - exec_output = BasicExecute.subst(iop) - - if uses_imm: - # append declaration for imm version - imm_cblk = CodeBlock(imm_code) - imm_iop = InstObjParams(name, Name + 'Imm', 'IntegerImm', imm_cblk, - opt_flags) - header_output += BasicDeclare.subst(imm_iop) - decoder_output += BasicConstructor.subst(imm_iop) - exec_output += BasicExecute.subst(imm_iop) - # decode checks IMM bit to pick correct version - decode_block = RegOrImmDecode.subst(iop) - else: - # no imm version: just check for nop - decode_block = OperateNopCheckDecode.subst(iop) -}}; - - -//////////////////////////////////////////////////////////////////// -// -// Floating-point instructions -// -// Note that many FP-type instructions which do not support all the -// various rounding & trapping modes use the simpler format -// BasicOperateWithNopCheck. -// - -output exec {{ - /// Check "FP enabled" machine status bit. Called when executing any FP - /// instruction in full-system mode. - /// @retval Full-system mode: No_Fault if FP is enabled, Fen_Fault - /// if not. Non-full-system mode: always returns No_Fault. -#if FULL_SYSTEM - inline Fault checkFpEnableFault(%(CPU_exec_context)s *xc) - { - Fault fault = No_Fault; // dummy... this ipr access should not fault - if (!EV5::ICSR_FPE(xc->readIpr(AlphaISA::IPR_ICSR, fault))) { - fault = Fen_Fault; - } - return fault; - } -#else - inline Fault checkFpEnableFault(%(CPU_exec_context)s *xc) - { - return No_Fault; - } -#endif -}}; - -output header {{ - /** - * Base class for general floating-point instructions. Includes - * support for various Alpha rounding and trapping modes. Only FP - * instructions that require this support are derived from this - * class; the rest derive directly from AlphaStaticInst. - */ - class AlphaFP : public AlphaStaticInst - { - public: - /// Alpha FP rounding modes. - enum RoundingMode { - Chopped = 0, ///< round toward zero - Minus_Infinity = 1, ///< round toward minus infinity - Normal = 2, ///< round to nearest (default) - Dynamic = 3, ///< use FPCR setting (in instruction) - Plus_Infinity = 3 ///< round to plus inifinity (in FPCR) - }; - - /// Alpha FP trapping modes. - /// For instructions that produce integer results, the - /// "Underflow Enable" modes really mean "Overflow Enable", and - /// the assembly modifier is V rather than U. - enum TrappingMode { - /// default: nothing enabled - Imprecise = 0, ///< no modifier - /// underflow/overflow traps enabled, inexact disabled - Underflow_Imprecise = 1, ///< /U or /V - Underflow_Precise = 5, ///< /SU or /SV - /// underflow/overflow and inexact traps enabled - Underflow_Inexact_Precise = 7 ///< /SUI or /SVI - }; - - protected: - /// Map Alpha rounding mode to C99 constants from . - static const int alphaToC99RoundingMode[]; - - /// Map enum RoundingMode values to disassembly suffixes. - static const char *roundingModeSuffix[]; - /// Map enum TrappingMode values to FP disassembly suffixes. - static const char *fpTrappingModeSuffix[]; - /// Map enum TrappingMode values to integer disassembly suffixes. - static const char *intTrappingModeSuffix[]; - - /// This instruction's rounding mode. - RoundingMode roundingMode; - /// This instruction's trapping mode. - TrappingMode trappingMode; - - /// Have we warned about this instruction's unsupported - /// rounding mode (if applicable)? - mutable bool warnedOnRounding; - - /// Have we warned about this instruction's unsupported - /// trapping mode (if applicable)? - mutable bool warnedOnTrapping; - - /// Constructor - AlphaFP(const char *mnem, MachInst _machInst, OpClass __opClass) - : AlphaStaticInst(mnem, _machInst, __opClass), - roundingMode((enum RoundingMode)FP_ROUNDMODE), - trappingMode((enum TrappingMode)FP_TRAPMODE), - warnedOnRounding(false), - warnedOnTrapping(false) - { - } - - int getC99RoundingMode(uint64_t fpcr_val) const; - - // This differs from the AlphaStaticInst version only in - // printing suffixes for non-default rounding & trapping modes. - std::string - generateDisassembly(Addr pc, const SymbolTable *symtab) const; - }; - -}}; - - -output decoder {{ - int - AlphaFP::getC99RoundingMode(uint64_t fpcr_val) const - { - if (roundingMode == Dynamic) { - return alphaToC99RoundingMode[bits(fpcr_val, 59, 58)]; - } - else { - return alphaToC99RoundingMode[roundingMode]; - } - } - - std::string - AlphaFP::generateDisassembly(Addr pc, const SymbolTable *symtab) const - { - std::string mnem_str(mnemonic); - -#ifndef SS_COMPATIBLE_DISASSEMBLY - std::string suffix(""); - suffix += ((_destRegIdx[0] >= FP_Base_DepTag) - ? fpTrappingModeSuffix[trappingMode] - : intTrappingModeSuffix[trappingMode]); - suffix += roundingModeSuffix[roundingMode]; - - if (suffix != "") { - mnem_str = csprintf("%s/%s", mnemonic, suffix); - } -#endif - - std::stringstream ss; - ccprintf(ss, "%-10s ", mnem_str.c_str()); - - // just print the first two source regs... if there's - // a third one, it's a read-modify-write dest (Rc), - // e.g. for CMOVxx - if (_numSrcRegs > 0) { - printReg(ss, _srcRegIdx[0]); - } - if (_numSrcRegs > 1) { - ss << ","; - printReg(ss, _srcRegIdx[1]); - } - - // just print the first dest... if there's a second one, - // it's generally implicit - if (_numDestRegs > 0) { - if (_numSrcRegs > 0) - ss << ","; - printReg(ss, _destRegIdx[0]); - } - - return ss.str(); - } - - const int AlphaFP::alphaToC99RoundingMode[] = { - FE_TOWARDZERO, // Chopped - FE_DOWNWARD, // Minus_Infinity - FE_TONEAREST, // Normal - FE_UPWARD // Dynamic in inst, Plus_Infinity in FPCR - }; - - const char *AlphaFP::roundingModeSuffix[] = { "c", "m", "", "d" }; - // mark invalid trapping modes, but don't fail on them, because - // you could decode anything on a misspeculated path - const char *AlphaFP::fpTrappingModeSuffix[] = - { "", "u", "INVTM2", "INVTM3", "INVTM4", "su", "INVTM6", "sui" }; - const char *AlphaFP::intTrappingModeSuffix[] = - { "", "v", "INVTM2", "INVTM3", "INVTM4", "sv", "INVTM6", "svi" }; -}}; - -// FP instruction class execute method template. Handles non-standard -// rounding modes. -def template FloatingPointExecute {{ - Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, - Trace::InstRecord *traceData) const - { - if (trappingMode != Imprecise && !warnedOnTrapping) { - warn("%s: non-standard trapping mode not supported", - generateDisassembly(0, NULL)); - warnedOnTrapping = true; - } - - Fault fault = No_Fault; - - %(fp_enable_check)s; - %(op_decl)s; - %(op_rd)s; -#if USE_FENV - if (roundingMode == Normal) { - %(code)s; - } else { - fesetround(getC99RoundingMode(xc->readFpcr())); - %(code)s; - fesetround(FE_TONEAREST); - } -#else - if (roundingMode != Normal && !warnedOnRounding) { - warn("%s: non-standard rounding mode not supported", - generateDisassembly(0, NULL)); - warnedOnRounding = true; - } - %(code)s; -#endif - - if (fault == No_Fault) { - %(op_wb)s; - } - - return fault; - } -}}; - -// FP instruction class execute method template where no dynamic -// rounding mode control is needed. Like BasicExecute, but includes -// check & warning for non-standard trapping mode. -def template FPFixedRoundingExecute {{ - Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, - Trace::InstRecord *traceData) const - { - if (trappingMode != Imprecise && !warnedOnTrapping) { - warn("%s: non-standard trapping mode not supported", - generateDisassembly(0, NULL)); - warnedOnTrapping = true; - } - - Fault fault = No_Fault; - - %(fp_enable_check)s; - %(op_decl)s; - %(op_rd)s; - %(code)s; - - if (fault == No_Fault) { - %(op_wb)s; - } - - return fault; - } -}}; - -def template FloatingPointDecode {{ - { - AlphaStaticInst *i = new %(class_name)s(machInst); - if (FC == 31) { - i = makeNop(i); - } - return i; - } -}}; - -// General format for floating-point operate instructions: -// - Checks trapping and rounding mode flags. Trapping modes -// currently unimplemented (will fail). -// - Generates NOP if FC == 31. -def format FloatingPointOperate(code, *opt_args) {{ - iop = InstObjParams(name, Name, 'AlphaFP', CodeBlock(code), opt_args) - decode_block = FloatingPointDecode.subst(iop) - header_output = BasicDeclare.subst(iop) - decoder_output = BasicConstructor.subst(iop) - exec_output = FloatingPointExecute.subst(iop) -}}; - -// Special format for cvttq where rounding mode is pre-decoded -def format FPFixedRounding(code, class_suffix, *opt_args) {{ - Name += class_suffix - iop = InstObjParams(name, Name, 'AlphaFP', CodeBlock(code), opt_args) - decode_block = FloatingPointDecode.subst(iop) - header_output = BasicDeclare.subst(iop) - decoder_output = BasicConstructor.subst(iop) - exec_output = FPFixedRoundingExecute.subst(iop) -}}; - -//////////////////////////////////////////////////////////////////// -// -// Memory-format instructions: LoadAddress, Load, Store -// - -output header {{ - /** - * Base class for general Alpha memory-format instructions. - */ - class Memory : public AlphaStaticInst - { - protected: - - /// Memory request flags. See mem_req_base.hh. - unsigned memAccessFlags; - /// Pointer to EAComp object. - const StaticInstPtr eaCompPtr; - /// Pointer to MemAcc object. - const StaticInstPtr memAccPtr; - - /// Constructor - Memory(const char *mnem, MachInst _machInst, OpClass __opClass, - StaticInstPtr _eaCompPtr = nullStaticInstPtr, - StaticInstPtr _memAccPtr = nullStaticInstPtr) - : AlphaStaticInst(mnem, _machInst, __opClass), - memAccessFlags(0), eaCompPtr(_eaCompPtr), memAccPtr(_memAccPtr) - { - } - - std::string - generateDisassembly(Addr pc, const SymbolTable *symtab) const; - - public: - - const StaticInstPtr &eaCompInst() const { return eaCompPtr; } - const StaticInstPtr &memAccInst() const { return memAccPtr; } - }; - - /** - * Base class for memory-format instructions using a 32-bit - * displacement (i.e. most of them). - */ - class MemoryDisp32 : public Memory - { - protected: - /// Displacement for EA calculation (signed). - int32_t disp; - - /// Constructor. - MemoryDisp32(const char *mnem, MachInst _machInst, OpClass __opClass, - StaticInstPtr _eaCompPtr = nullStaticInstPtr, - StaticInstPtr _memAccPtr = nullStaticInstPtr) - : Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr), - disp(MEMDISP) - { - } - }; - - - /** - * Base class for a few miscellaneous memory-format insts - * that don't interpret the disp field: wh64, fetch, fetch_m, ecb. - * None of these instructions has a destination register either. - */ - class MemoryNoDisp : public Memory - { - protected: - /// Constructor - MemoryNoDisp(const char *mnem, MachInst _machInst, OpClass __opClass, - StaticInstPtr _eaCompPtr = nullStaticInstPtr, - StaticInstPtr _memAccPtr = nullStaticInstPtr) - : Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr) - { - } - - std::string - generateDisassembly(Addr pc, const SymbolTable *symtab) const; - }; -}}; - - -output decoder {{ - std::string - Memory::generateDisassembly(Addr pc, const SymbolTable *symtab) const - { - return csprintf("%-10s %c%d,%d(r%d)", mnemonic, - flags[IsFloating] ? 'f' : 'r', RA, MEMDISP, RB); - } - - std::string - MemoryNoDisp::generateDisassembly(Addr pc, const SymbolTable *symtab) const - { - return csprintf("%-10s (r%d)", mnemonic, RB); - } -}}; - -def format LoadAddress(code) {{ - iop = InstObjParams(name, Name, 'MemoryDisp32', CodeBlock(code)) - header_output = BasicDeclare.subst(iop) - decoder_output = BasicConstructor.subst(iop) - decode_block = BasicDecode.subst(iop) - exec_output = BasicExecute.subst(iop) -}}; - - -def template LoadStoreDeclare {{ - /** - * Static instruction class for "%(mnemonic)s". - */ - class %(class_name)s : public %(base_class)s - { - protected: - - /** - * "Fake" effective address computation class for "%(mnemonic)s". - */ - class EAComp : public %(base_class)s - { - public: - /// Constructor - EAComp(MachInst machInst); - - %(BasicExecDeclare)s - }; - - /** - * "Fake" memory access instruction class for "%(mnemonic)s". - */ - class MemAcc : public %(base_class)s - { - public: - /// Constructor - MemAcc(MachInst machInst); - - %(BasicExecDeclare)s - }; - - public: - - /// Constructor. - %(class_name)s(MachInst machInst); - - %(BasicExecDeclare)s - }; -}}; - -def template LoadStoreConstructor {{ - /** TODO: change op_class to AddrGenOp or something (requires - * creating new member of OpClass enum in op_class.hh, updating - * config files, etc.). */ - inline %(class_name)s::EAComp::EAComp(MachInst machInst) - : %(base_class)s("%(mnemonic)s (EAComp)", machInst, IntAluOp) - { - %(ea_constructor)s; - } - - inline %(class_name)s::MemAcc::MemAcc(MachInst machInst) - : %(base_class)s("%(mnemonic)s (MemAcc)", machInst, %(op_class)s) - { - %(memacc_constructor)s; - } - - inline %(class_name)s::%(class_name)s(MachInst machInst) - : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, - new EAComp(machInst), new MemAcc(machInst)) - { - %(constructor)s; - } -}}; - - -def template EACompExecute {{ - Fault - %(class_name)s::EAComp::execute(%(CPU_exec_context)s *xc, - Trace::InstRecord *traceData) const - { - Addr EA; - Fault fault = No_Fault; - - %(fp_enable_check)s; - %(op_decl)s; - %(op_rd)s; - %(code)s; - - if (fault == No_Fault) { - %(op_wb)s; - xc->setEA(EA); - } - - return fault; - } -}}; - -def template MemAccExecute {{ - Fault - %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc, - Trace::InstRecord *traceData) const - { - Addr EA; - Fault fault = No_Fault; - - %(fp_enable_check)s; - %(op_decl)s; - %(op_nonmem_rd)s; - EA = xc->getEA(); - - if (fault == No_Fault) { - %(op_mem_rd)s; - %(code)s; - } - - if (fault == No_Fault) { - %(op_mem_wb)s; - } - - if (fault == No_Fault) { - %(postacc_code)s; - } - - if (fault == No_Fault) { - %(op_nonmem_wb)s; - } - - return fault; - } -}}; - - -def template LoadStoreExecute {{ - Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, - Trace::InstRecord *traceData) const - { - Addr EA; - Fault fault = No_Fault; - - %(fp_enable_check)s; - %(op_decl)s; - %(op_nonmem_rd)s; - %(ea_code)s; - - if (fault == No_Fault) { - %(op_mem_rd)s; - %(memacc_code)s; - } - - if (fault == No_Fault) { - %(op_mem_wb)s; - } - - if (fault == No_Fault) { - %(postacc_code)s; - } - - if (fault == No_Fault) { - %(op_nonmem_wb)s; - } - - return fault; - } -}}; - - -def template PrefetchExecute {{ - Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, - Trace::InstRecord *traceData) const - { - Addr EA; - Fault fault = No_Fault; - - %(fp_enable_check)s; - %(op_decl)s; - %(op_nonmem_rd)s; - %(ea_code)s; - - if (fault == No_Fault) { - xc->prefetch(EA, memAccessFlags); - } - - return No_Fault; - } -}}; - -// load instructions use Ra as dest, so check for -// Ra == 31 to detect nops -def template LoadNopCheckDecode {{ - { - AlphaStaticInst *i = new %(class_name)s(machInst); - if (RA == 31) { - i = makeNop(i); - } - return i; - } -}}; - - -// for some load instructions, Ra == 31 indicates a prefetch (not a nop) -def template LoadPrefetchCheckDecode {{ - { - if (RA != 31) { - return new %(class_name)s(machInst); - } - else { - return new %(class_name)sPrefetch(machInst); - } - } -}}; - - -let {{ -def LoadStoreBase(name, Name, ea_code, memacc_code, postacc_code = '', - base_class = 'MemoryDisp32', flags = [], - decode_template = BasicDecode, - exec_template = LoadStoreExecute): - # Segregate flags into instruction flags (handled by InstObjParams) - # and memory access flags (handled here). - - # Would be nice to autogenerate this list, but oh well. - valid_mem_flags = ['LOCKED', 'NO_FAULT', 'EVICT_NEXT', 'PF_EXCLUSIVE'] - mem_flags = [f for f in flags if f in valid_mem_flags] - inst_flags = [f for f in flags if f not in valid_mem_flags] - - # add hook to get effective addresses into execution trace output. - ea_code += '\nif (traceData) { traceData->setAddr(EA); }\n' - - # generate code block objects - ea_cblk = CodeBlock(ea_code) - memacc_cblk = CodeBlock(memacc_code) - postacc_cblk = CodeBlock(postacc_code) - - # Some CPU models execute the memory operation as an atomic unit, - # while others want to separate them into an effective address - # computation and a memory access operation. As a result, we need - # to generate three StaticInst objects. Note that the latter two - # are nested inside the larger "atomic" one. - - # generate InstObjParams for EAComp object - ea_iop = InstObjParams(name, Name, base_class, ea_cblk, inst_flags) - - # generate InstObjParams for MemAcc object - memacc_iop = InstObjParams(name, Name, base_class, memacc_cblk, inst_flags) - # in the split execution model, the MemAcc portion is responsible - # for the post-access code. - memacc_iop.postacc_code = postacc_cblk.code - - # generate InstObjParams for unified execution - cblk = CodeBlock(ea_code + memacc_code + postacc_code) - iop = InstObjParams(name, Name, base_class, cblk, inst_flags) - - iop.ea_constructor = ea_cblk.constructor - iop.ea_code = ea_cblk.code - iop.memacc_constructor = memacc_cblk.constructor - iop.memacc_code = memacc_cblk.code - iop.postacc_code = postacc_cblk.code - - if mem_flags: - s = '\n\tmemAccessFlags = ' + string.join(mem_flags, '|') + ';' - iop.constructor += s - memacc_iop.constructor += s - - # (header_output, decoder_output, decode_block, exec_output) - return (LoadStoreDeclare.subst(iop), LoadStoreConstructor.subst(iop), - decode_template.subst(iop), - EACompExecute.subst(ea_iop) - + MemAccExecute.subst(memacc_iop) - + exec_template.subst(iop)) -}}; - - -def format LoadOrNop(ea_code, memacc_code, *flags) {{ - (header_output, decoder_output, decode_block, exec_output) = \ - LoadStoreBase(name, Name, ea_code, memacc_code, flags = flags, - decode_template = LoadNopCheckDecode) -}}; - - -// Note that the flags passed in apply only to the prefetch version -def format LoadOrPrefetch(ea_code, memacc_code, *pf_flags) {{ - # declare the load instruction object and generate the decode block - (header_output, decoder_output, decode_block, exec_output) = \ - LoadStoreBase(name, Name, ea_code, memacc_code, - decode_template = LoadPrefetchCheckDecode) - - # Declare the prefetch instruction object. - - # convert flags from tuple to list to make them mutable - pf_flags = list(pf_flags) + ['IsMemRef', 'IsLoad', 'IsDataPrefetch', 'MemReadOp', 'NO_FAULT'] - - (pf_header_output, pf_decoder_output, _, pf_exec_output) = \ - LoadStoreBase(name, Name + 'Prefetch', ea_code, '', - flags = pf_flags, exec_template = PrefetchExecute) - - header_output += pf_header_output - decoder_output += pf_decoder_output - exec_output += pf_exec_output -}}; - - -def format Store(ea_code, memacc_code, *flags) {{ - (header_output, decoder_output, decode_block, exec_output) = \ - LoadStoreBase(name, Name, ea_code, memacc_code, flags = flags) -}}; - - -def format StoreCond(ea_code, memacc_code, postacc_code, *flags) {{ - (header_output, decoder_output, decode_block, exec_output) = \ - LoadStoreBase(name, Name, ea_code, memacc_code, postacc_code, - flags = flags) -}}; - - -// Use 'MemoryNoDisp' as base: for wh64, fetch, ecb -def format MiscPrefetch(ea_code, memacc_code, *flags) {{ - (header_output, decoder_output, decode_block, exec_output) = \ - LoadStoreBase(name, Name, ea_code, memacc_code, flags = flags, - base_class = 'MemoryNoDisp') -}}; - - -//////////////////////////////////////////////////////////////////// -// -// Control transfer instructions -// - -output header {{ - - /** - * Base class for instructions whose disassembly is not purely a - * function of the machine instruction (i.e., it depends on the - * PC). This class overrides the disassemble() method to check - * the PC and symbol table values before re-using a cached - * disassembly string. This is necessary for branches and jumps, - * where the disassembly string includes the target address (which - * may depend on the PC and/or symbol table). - */ - class PCDependentDisassembly : public AlphaStaticInst - { - protected: - /// Cached program counter from last disassembly - mutable Addr cachedPC; - /// Cached symbol table pointer from last disassembly - mutable const SymbolTable *cachedSymtab; - - /// Constructor - PCDependentDisassembly(const char *mnem, MachInst _machInst, - OpClass __opClass) - : AlphaStaticInst(mnem, _machInst, __opClass), - cachedPC(0), cachedSymtab(0) - { - } - - const std::string & - disassemble(Addr pc, const SymbolTable *symtab) const; - }; - - /** - * Base class for branches (PC-relative control transfers), - * conditional or unconditional. - */ - class Branch : public PCDependentDisassembly - { - protected: - /// Displacement to target address (signed). - int32_t disp; - - /// Constructor. - Branch(const char *mnem, MachInst _machInst, OpClass __opClass) - : PCDependentDisassembly(mnem, _machInst, __opClass), - disp(BRDISP << 2) - { - } - - Addr branchTarget(Addr branchPC) const; - - std::string - generateDisassembly(Addr pc, const SymbolTable *symtab) const; - }; - - /** - * Base class for jumps (register-indirect control transfers). In - * the Alpha ISA, these are always unconditional. - */ - class Jump : public PCDependentDisassembly - { - protected: - - /// Displacement to target address (signed). - int32_t disp; - - public: - /// Constructor - Jump(const char *mnem, MachInst _machInst, OpClass __opClass) - : PCDependentDisassembly(mnem, _machInst, __opClass), - disp(BRDISP) - { - } - - Addr branchTarget(ExecContext *xc) const; - - std::string - generateDisassembly(Addr pc, const SymbolTable *symtab) const; - }; -}}; - -output decoder {{ - Addr - Branch::branchTarget(Addr branchPC) const - { - return branchPC + 4 + disp; - } - - Addr - Jump::branchTarget(ExecContext *xc) const - { - Addr NPC = xc->readPC() + 4; - uint64_t Rb = xc->readIntReg(_srcRegIdx[0]); - return (Rb & ~3) | (NPC & 1); - } - - const std::string & - PCDependentDisassembly::disassemble(Addr pc, - const SymbolTable *symtab) const - { - if (!cachedDisassembly || - pc != cachedPC || symtab != cachedSymtab) - { - if (cachedDisassembly) - delete cachedDisassembly; - - cachedDisassembly = - new std::string(generateDisassembly(pc, symtab)); - cachedPC = pc; - cachedSymtab = symtab; - } - - return *cachedDisassembly; - } - - std::string - Branch::generateDisassembly(Addr pc, const SymbolTable *symtab) const - { - std::stringstream ss; - - ccprintf(ss, "%-10s ", mnemonic); - - // There's only one register arg (RA), but it could be - // either a source (the condition for conditional - // branches) or a destination (the link reg for - // unconditional branches) - if (_numSrcRegs > 0) { - printReg(ss, _srcRegIdx[0]); - ss << ","; - } - else if (_numDestRegs > 0) { - printReg(ss, _destRegIdx[0]); - ss << ","; - } - -#ifdef SS_COMPATIBLE_DISASSEMBLY - if (_numSrcRegs == 0 && _numDestRegs == 0) { - printReg(ss, 31); - ss << ","; - } -#endif - - Addr target = pc + 4 + disp; - - std::string str; - if (symtab && symtab->findSymbol(target, str)) - ss << str; - else - ccprintf(ss, "0x%x", target); - - return ss.str(); - } - - std::string - Jump::generateDisassembly(Addr pc, const SymbolTable *symtab) const - { - std::stringstream ss; - - ccprintf(ss, "%-10s ", mnemonic); - -#ifdef SS_COMPATIBLE_DISASSEMBLY - if (_numDestRegs == 0) { - printReg(ss, 31); - ss << ","; - } -#endif - - if (_numDestRegs > 0) { - printReg(ss, _destRegIdx[0]); - ss << ","; - } - - ccprintf(ss, "(r%d)", RB); - - return ss.str(); - } -}}; - -def template JumpOrBranchDecode {{ - return (RA == 31) - ? (StaticInst *)new %(class_name)s(machInst) - : (StaticInst *)new %(class_name)sAndLink(machInst); -}}; - -def format CondBranch(code) {{ - code = 'bool cond;\n' + code + '\nif (cond) NPC = NPC + disp;\n'; - iop = InstObjParams(name, Name, 'Branch', CodeBlock(code), - ('IsDirectControl', 'IsCondControl')) - header_output = BasicDeclare.subst(iop) - decoder_output = BasicConstructor.subst(iop) - decode_block = BasicDecode.subst(iop) - exec_output = BasicExecute.subst(iop) -}}; - -let {{ -def UncondCtrlBase(name, Name, base_class, npc_expr, flags): - # Declare basic control transfer w/o link (i.e. link reg is R31) - nolink_code = 'NPC = %s;\n' % npc_expr - nolink_iop = InstObjParams(name, Name, base_class, - CodeBlock(nolink_code), flags) - header_output = BasicDeclare.subst(nolink_iop) - decoder_output = BasicConstructor.subst(nolink_iop) - exec_output = BasicExecute.subst(nolink_iop) - - # Generate declaration of '*AndLink' version, append to decls - link_code = 'Ra = NPC & ~3;\n' + nolink_code - link_iop = InstObjParams(name, Name + 'AndLink', base_class, - CodeBlock(link_code), flags) - header_output += BasicDeclare.subst(link_iop) - decoder_output += BasicConstructor.subst(link_iop) - exec_output += BasicExecute.subst(link_iop) - - # need to use link_iop for the decode template since it is expecting - # the shorter version of class_name (w/o "AndLink") - - return (header_output, decoder_output, - JumpOrBranchDecode.subst(nolink_iop), exec_output) -}}; - -def format UncondBranch(*flags) {{ - flags += ('IsUncondControl', 'IsDirectControl') - (header_output, decoder_output, decode_block, exec_output) = \ - UncondCtrlBase(name, Name, 'Branch', 'NPC + disp', flags) -}}; - -def format Jump(*flags) {{ - flags += ('IsUncondControl', 'IsIndirectControl') - (header_output, decoder_output, decode_block, exec_output) = \ - UncondCtrlBase(name, Name, 'Jump', '(Rb & ~3) | (NPC & 1)', flags) -}}; - - -//////////////////////////////////////////////////////////////////// -// -// PAL calls -// - -output header {{ - /** - * Base class for emulated call_pal calls (used only in - * non-full-system mode). - */ - class EmulatedCallPal : public AlphaStaticInst - { - protected: - - /// Constructor. - EmulatedCallPal(const char *mnem, MachInst _machInst, - OpClass __opClass) - : AlphaStaticInst(mnem, _machInst, __opClass) - { - } - - std::string - generateDisassembly(Addr pc, const SymbolTable *symtab) const; - }; -}}; - -output decoder {{ - std::string - EmulatedCallPal::generateDisassembly(Addr pc, - const SymbolTable *symtab) const - { -#ifdef SS_COMPATIBLE_DISASSEMBLY - return csprintf("%s %s", "call_pal", mnemonic); -#else - return csprintf("%-10s %s", "call_pal", mnemonic); -#endif - } -}}; - -def format EmulatedCallPal(code, *flags) {{ - iop = InstObjParams(name, Name, 'EmulatedCallPal', CodeBlock(code), flags) - header_output = BasicDeclare.subst(iop) - decoder_output = BasicConstructor.subst(iop) - decode_block = BasicDecode.subst(iop) - exec_output = BasicExecute.subst(iop) -}}; - -output header {{ - /** - * Base class for full-system-mode call_pal instructions. - * Probably could turn this into a leaf class and get rid of the - * parser template. - */ - class CallPalBase : public AlphaStaticInst - { - protected: - int palFunc; ///< Function code part of instruction - int palOffset; ///< Target PC, offset from IPR_PAL_BASE - bool palValid; ///< is the function code valid? - bool palPriv; ///< is this call privileged? - - /// Constructor. - CallPalBase(const char *mnem, MachInst _machInst, - OpClass __opClass); - - std::string - generateDisassembly(Addr pc, const SymbolTable *symtab) const; - }; -}}; - -output decoder {{ - inline - CallPalBase::CallPalBase(const char *mnem, MachInst _machInst, - OpClass __opClass) - : AlphaStaticInst(mnem, _machInst, __opClass), - palFunc(PALFUNC) - { - // From the 21164 HRM (paraphrased): - // Bit 7 of the function code (mask 0x80) indicates - // whether the call is privileged (bit 7 == 0) or - // unprivileged (bit 7 == 1). The privileged call table - // starts at 0x2000, the unprivielged call table starts at - // 0x3000. Bits 5-0 (mask 0x3f) are used to calculate the - // offset. - const int palPrivMask = 0x80; - const int palOffsetMask = 0x3f; - - // Pal call is invalid unless all other bits are 0 - palValid = ((machInst & ~(palPrivMask | palOffsetMask)) == 0); - palPriv = ((machInst & palPrivMask) == 0); - int shortPalFunc = (machInst & palOffsetMask); - // Add 1 to base to set pal-mode bit - palOffset = (palPriv ? 0x2001 : 0x3001) + (shortPalFunc << 6); - } - - std::string - CallPalBase::generateDisassembly(Addr pc, const SymbolTable *symtab) const - { - return csprintf("%-10s %#x", "call_pal", palFunc); - } -}}; - -def format CallPal(code, *flags) {{ - iop = InstObjParams(name, Name, 'CallPalBase', CodeBlock(code), flags) - header_output = BasicDeclare.subst(iop) - decoder_output = BasicConstructor.subst(iop) - decode_block = BasicDecode.subst(iop) - exec_output = BasicExecute.subst(iop) -}}; - -//////////////////////////////////////////////////////////////////// -// -// hw_ld, hw_st -// - -output header {{ - /** - * Base class for hw_ld and hw_st. - */ - class HwLoadStore : public Memory - { - protected: - - /// Displacement for EA calculation (signed). - int16_t disp; - - /// Constructor - HwLoadStore(const char *mnem, MachInst _machInst, OpClass __opClass, - StaticInstPtr _eaCompPtr = nullStaticInstPtr, - StaticInstPtr _memAccPtr = nullStaticInstPtr); - - std::string - generateDisassembly(Addr pc, const SymbolTable *symtab) const; - }; -}}; - - -output decoder {{ - inline - HwLoadStore::HwLoadStore(const char *mnem, MachInst _machInst, - OpClass __opClass, - StaticInstPtr _eaCompPtr, - StaticInstPtr _memAccPtr) - : Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr), - disp(HW_LDST_DISP) - { - memAccessFlags = 0; - if (HW_LDST_PHYS) memAccessFlags |= PHYSICAL; - if (HW_LDST_ALT) memAccessFlags |= ALTMODE; - if (HW_LDST_VPTE) memAccessFlags |= VPTE; - if (HW_LDST_LOCK) memAccessFlags |= LOCKED; - } - - std::string - HwLoadStore::generateDisassembly(Addr pc, const SymbolTable *symtab) const - { -#ifdef SS_COMPATIBLE_DISASSEMBLY - return csprintf("%-10s r%d,%d(r%d)", mnemonic, RA, disp, RB); -#else - // HW_LDST_LOCK and HW_LDST_COND are the same bit. - const char *lock_str = - (HW_LDST_LOCK) ? (flags[IsLoad] ? ",LOCK" : ",COND") : ""; - - return csprintf("%-10s r%d,%d(r%d)%s%s%s%s%s", - mnemonic, RA, disp, RB, - HW_LDST_PHYS ? ",PHYS" : "", - HW_LDST_ALT ? ",ALT" : "", - HW_LDST_QUAD ? ",QUAD" : "", - HW_LDST_VPTE ? ",VPTE" : "", - lock_str); -#endif - } -}}; - -def format HwLoadStore(ea_code, memacc_code, class_ext, *flags) {{ - (header_output, decoder_output, decode_block, exec_output) = \ - LoadStoreBase(name, Name + class_ext, ea_code, memacc_code, - flags = flags, base_class = 'HwLoadStore') -}}; - - -def format HwStoreCond(ea_code, memacc_code, postacc_code, class_ext, *flags) {{ - (header_output, decoder_output, decode_block, exec_output) = \ - LoadStoreBase(name, Name + class_ext, ea_code, memacc_code, - postacc_code, flags = flags, base_class = 'HwLoadStore') -}}; - - -output header {{ - /** - * Base class for hw_mfpr and hw_mtpr. - */ - class HwMoveIPR : public AlphaStaticInst - { - protected: - /// Index of internal processor register. - int ipr_index; - - /// Constructor - HwMoveIPR(const char *mnem, MachInst _machInst, OpClass __opClass) - : AlphaStaticInst(mnem, _machInst, __opClass), - ipr_index(HW_IPR_IDX) - { - } - - std::string - generateDisassembly(Addr pc, const SymbolTable *symtab) const; - }; -}}; - -output decoder {{ - std::string - HwMoveIPR::generateDisassembly(Addr pc, const SymbolTable *symtab) const - { - if (_numSrcRegs > 0) { - // must be mtpr - return csprintf("%-10s r%d,IPR(%#x)", - mnemonic, RA, ipr_index); - } - else { - // must be mfpr - return csprintf("%-10s IPR(%#x),r%d", - mnemonic, ipr_index, RA); - } - } -}}; - -def format HwMoveIPR(code) {{ - iop = InstObjParams(name, Name, 'HwMoveIPR', CodeBlock(code), - ['IprAccessOp']) - header_output = BasicDeclare.subst(iop) - decoder_output = BasicConstructor.subst(iop) - decode_block = BasicDecode.subst(iop) - exec_output = BasicExecute.subst(iop) -}}; - - -//////////////////////////////////////////////////////////////////// -// -// Unimplemented instructions -// - -output header {{ - /** - * Static instruction class for unimplemented instructions that - * cause simulator termination. Note that these are recognized - * (legal) instructions that the simulator does not support; the - * 'Unknown' class is used for unrecognized/illegal instructions. - * This is a leaf class. - */ - class FailUnimplemented : public AlphaStaticInst - { - public: - /// Constructor - FailUnimplemented(const char *_mnemonic, MachInst _machInst) - : AlphaStaticInst(_mnemonic, _machInst, No_OpClass) - { - // don't call execute() (which panics) if we're on a - // speculative path - flags[IsNonSpeculative] = true; - } - - %(BasicExecDeclare)s - - std::string - generateDisassembly(Addr pc, const SymbolTable *symtab) const; - }; - - /** - * Base class for unimplemented instructions that cause a warning - * to be printed (but do not terminate simulation). This - * implementation is a little screwy in that it will print a - * warning for each instance of a particular unimplemented machine - * instruction, not just for each unimplemented opcode. Should - * probably make the 'warned' flag a static member of the derived - * class. - */ - class WarnUnimplemented : public AlphaStaticInst - { - private: - /// Have we warned on this instruction yet? - mutable bool warned; - - public: - /// Constructor - WarnUnimplemented(const char *_mnemonic, MachInst _machInst) - : AlphaStaticInst(_mnemonic, _machInst, No_OpClass), warned(false) - { - // don't call execute() (which panics) if we're on a - // speculative path - flags[IsNonSpeculative] = true; - } - - %(BasicExecDeclare)s - - std::string - generateDisassembly(Addr pc, const SymbolTable *symtab) const; - }; -}}; - -output decoder {{ - std::string - FailUnimplemented::generateDisassembly(Addr pc, - const SymbolTable *symtab) const - { - return csprintf("%-10s (unimplemented)", mnemonic); - } - - std::string - WarnUnimplemented::generateDisassembly(Addr pc, - const SymbolTable *symtab) const - { -#ifdef SS_COMPATIBLE_DISASSEMBLY - return csprintf("%-10s", mnemonic); -#else - return csprintf("%-10s (unimplemented)", mnemonic); -#endif - } -}}; - -output exec {{ - Fault - FailUnimplemented::execute(%(CPU_exec_context)s *xc, - Trace::InstRecord *traceData) const - { - panic("attempt to execute unimplemented instruction '%s' " - "(inst 0x%08x, opcode 0x%x)", mnemonic, machInst, OPCODE); - return Unimplemented_Opcode_Fault; - } - - Fault - WarnUnimplemented::execute(%(CPU_exec_context)s *xc, - Trace::InstRecord *traceData) const - { - if (!warned) { - warn("instruction '%s' unimplemented\n", mnemonic); - warned = true; - } - - return No_Fault; - } -}}; - - -def format FailUnimpl() {{ - iop = InstObjParams(name, 'FailUnimplemented') - decode_block = BasicDecodeWithMnemonic.subst(iop) -}}; - -def format WarnUnimpl() {{ - iop = InstObjParams(name, 'WarnUnimplemented') - decode_block = BasicDecodeWithMnemonic.subst(iop) -}}; - -output header {{ - /** - * Static instruction class for unknown (illegal) instructions. - * These cause simulator termination if they are executed in a - * non-speculative mode. This is a leaf class. - */ - class Unknown : public AlphaStaticInst - { - public: - /// Constructor - Unknown(MachInst _machInst) - : AlphaStaticInst("unknown", _machInst, No_OpClass) - { - // don't call execute() (which panics) if we're on a - // speculative path - flags[IsNonSpeculative] = true; - } - - %(BasicExecDeclare)s - - std::string - generateDisassembly(Addr pc, const SymbolTable *symtab) const; - }; -}}; - -//////////////////////////////////////////////////////////////////// -// -// Unknown instructions -// - -output decoder {{ - std::string - Unknown::generateDisassembly(Addr pc, const SymbolTable *symtab) const - { - return csprintf("%-10s (inst 0x%x, opcode 0x%x)", - "unknown", machInst, OPCODE); - } -}}; - -output exec {{ - Fault - Unknown::execute(%(CPU_exec_context)s *xc, - Trace::InstRecord *traceData) const - { - panic("attempt to execute unknown instruction " - "(inst 0x%08x, opcode 0x%x)", machInst, OPCODE); - return Unimplemented_Opcode_Fault; - } -}}; - -def format Unknown() {{ - decode_block = 'return new Unknown(machInst);\n' -}}; - -//////////////////////////////////////////////////////////////////// -// -// Utility functions for execute methods -// - -output exec {{ - - /// Return opa + opb, summing carry into third arg. - inline uint64_t - addc(uint64_t opa, uint64_t opb, int &carry) - { - uint64_t res = opa + opb; - if (res < opa || res < opb) - ++carry; - return res; - } - - /// Multiply two 64-bit values (opa * opb), returning the 128-bit - /// product in res_hi and res_lo. - inline void - mul128(uint64_t opa, uint64_t opb, uint64_t &res_hi, uint64_t &res_lo) - { - // do a 64x64 --> 128 multiply using four 32x32 --> 64 multiplies - uint64_t opa_hi = opa<63:32>; - uint64_t opa_lo = opa<31:0>; - uint64_t opb_hi = opb<63:32>; - uint64_t opb_lo = opb<31:0>; - - res_lo = opa_lo * opb_lo; - - // The middle partial products logically belong in bit - // positions 95 to 32. Thus the lower 32 bits of each product - // sum into the upper 32 bits of the low result, while the - // upper 32 sum into the low 32 bits of the upper result. - uint64_t partial1 = opa_hi * opb_lo; - uint64_t partial2 = opa_lo * opb_hi; - - uint64_t partial1_lo = partial1<31:0> << 32; - uint64_t partial1_hi = partial1<63:32>; - uint64_t partial2_lo = partial2<31:0> << 32; - uint64_t partial2_hi = partial2<63:32>; - - // Add partial1_lo and partial2_lo to res_lo, keeping track - // of any carries out - int carry_out = 0; - res_lo = addc(partial1_lo, res_lo, carry_out); - res_lo = addc(partial2_lo, res_lo, carry_out); - - // Now calculate the high 64 bits... - res_hi = (opa_hi * opb_hi) + partial1_hi + partial2_hi + carry_out; - } - - /// Map 8-bit S-floating exponent to 11-bit T-floating exponent. - /// See Table 2-2 of Alpha AHB. - inline int - map_s(int old_exp) - { - int hibit = old_exp<7:>; - int lobits = old_exp<6:0>; - - if (hibit == 1) { - return (lobits == 0x7f) ? 0x7ff : (0x400 | lobits); - } - else { - return (lobits == 0) ? 0 : (0x380 | lobits); - } - } - - /// Convert a 32-bit S-floating value to the equivalent 64-bit - /// representation to be stored in an FP reg. - inline uint64_t - s_to_t(uint32_t s_val) - { - uint64_t tmp = s_val; - return (tmp<31:> << 63 // sign bit - | (uint64_t)map_s(tmp<30:23>) << 52 // exponent - | tmp<22:0> << 29); // fraction - } - - /// Convert a 64-bit T-floating value to the equivalent 32-bit - /// S-floating representation to be stored in memory. - inline int32_t - t_to_s(uint64_t t_val) - { - return (t_val<63:62> << 30 // sign bit & hi exp bit - | t_val<58:29>); // rest of exp & fraction - } -}}; - -//////////////////////////////////////////////////////////////////// -// -// The actual decoder specification -// - -decode OPCODE default Unknown::unknown() { - - format LoadAddress { - 0x08: lda({{ Ra = Rb + disp; }}); - 0x09: ldah({{ Ra = Rb + (disp << 16); }}); - } - - format LoadOrNop { - 0x0a: ldbu({{ EA = Rb + disp; }}, {{ Ra.uq = Mem.ub; }}); - 0x0c: ldwu({{ EA = Rb + disp; }}, {{ Ra.uq = Mem.uw; }}); - 0x0b: ldq_u({{ EA = (Rb + disp) & ~7; }}, {{ Ra = Mem.uq; }}); - 0x23: ldt({{ EA = Rb + disp; }}, {{ Fa = Mem.df; }}); - 0x2a: ldl_l({{ EA = Rb + disp; }}, {{ Ra.sl = Mem.sl; }}, LOCKED); - 0x2b: ldq_l({{ EA = Rb + disp; }}, {{ Ra.uq = Mem.uq; }}, LOCKED); - 0x20: copy_load({{EA = Ra;}}, - {{fault = xc->copySrcTranslate(EA);}}, - IsMemRef, IsLoad, IsCopy); - } - - format LoadOrPrefetch { - 0x28: ldl({{ EA = Rb + disp; }}, {{ Ra.sl = Mem.sl; }}); - 0x29: ldq({{ EA = Rb + disp; }}, {{ Ra.uq = Mem.uq; }}, EVICT_NEXT); - // IsFloating flag on lds gets the prefetch to disassemble - // using f31 instead of r31... funcitonally it's unnecessary - 0x22: lds({{ EA = Rb + disp; }}, {{ Fa.uq = s_to_t(Mem.ul); }}, - PF_EXCLUSIVE, IsFloating); - } - - format Store { - 0x0e: stb({{ EA = Rb + disp; }}, {{ Mem.ub = Ra<7:0>; }}); - 0x0d: stw({{ EA = Rb + disp; }}, {{ Mem.uw = Ra<15:0>; }}); - 0x2c: stl({{ EA = Rb + disp; }}, {{ Mem.ul = Ra<31:0>; }}); - 0x2d: stq({{ EA = Rb + disp; }}, {{ Mem.uq = Ra.uq; }}); - 0x0f: stq_u({{ EA = (Rb + disp) & ~7; }}, {{ Mem.uq = Ra.uq; }}); - 0x26: sts({{ EA = Rb + disp; }}, {{ Mem.ul = t_to_s(Fa.uq); }}); - 0x27: stt({{ EA = Rb + disp; }}, {{ Mem.df = Fa; }}); - 0x24: copy_store({{EA = Rb;}}, - {{fault = xc->copy(EA);}}, - IsMemRef, IsStore, IsCopy); - } - - format StoreCond { - 0x2e: stl_c({{ EA = Rb + disp; }}, {{ Mem.ul = Ra<31:0>; }}, - {{ - uint64_t tmp = Mem_write_result; - // see stq_c - Ra = (tmp == 0 || tmp == 1) ? tmp : Ra; - }}, LOCKED); - 0x2f: stq_c({{ EA = Rb + disp; }}, {{ Mem.uq = Ra; }}, - {{ - uint64_t tmp = Mem_write_result; - // If the write operation returns 0 or 1, then - // this was a conventional store conditional, - // and the value indicates the success/failure - // of the operation. If another value is - // returned, then this was a Turbolaser - // mailbox access, and we don't update the - // result register at all. - Ra = (tmp == 0 || tmp == 1) ? tmp : Ra; - }}, LOCKED); - } - - format IntegerOperate { - - 0x10: decode INTFUNC { // integer arithmetic operations - - 0x00: addl({{ Rc.sl = Ra.sl + Rb_or_imm.sl; }}); - 0x40: addlv({{ - uint32_t tmp = Ra.sl + Rb_or_imm.sl; - // signed overflow occurs when operands have same sign - // and sign of result does not match. - if (Ra.sl<31:> == Rb_or_imm.sl<31:> && tmp<31:> != Ra.sl<31:>) - fault = Integer_Overflow_Fault; - Rc.sl = tmp; - }}); - 0x02: s4addl({{ Rc.sl = (Ra.sl << 2) + Rb_or_imm.sl; }}); - 0x12: s8addl({{ Rc.sl = (Ra.sl << 3) + Rb_or_imm.sl; }}); - - 0x20: addq({{ Rc = Ra + Rb_or_imm; }}); - 0x60: addqv({{ - uint64_t tmp = Ra + Rb_or_imm; - // signed overflow occurs when operands have same sign - // and sign of result does not match. - if (Ra<63:> == Rb_or_imm<63:> && tmp<63:> != Ra<63:>) - fault = Integer_Overflow_Fault; - Rc = tmp; - }}); - 0x22: s4addq({{ Rc = (Ra << 2) + Rb_or_imm; }}); - 0x32: s8addq({{ Rc = (Ra << 3) + Rb_or_imm; }}); - - 0x09: subl({{ Rc.sl = Ra.sl - Rb_or_imm.sl; }}); - 0x49: sublv({{ - uint32_t tmp = Ra.sl - Rb_or_imm.sl; - // signed overflow detection is same as for add, - // except we need to look at the *complemented* - // sign bit of the subtrahend (Rb), i.e., if the initial - // signs are the *same* then no overflow can occur - if (Ra.sl<31:> != Rb_or_imm.sl<31:> && tmp<31:> != Ra.sl<31:>) - fault = Integer_Overflow_Fault; - Rc.sl = tmp; - }}); - 0x0b: s4subl({{ Rc.sl = (Ra.sl << 2) - Rb_or_imm.sl; }}); - 0x1b: s8subl({{ Rc.sl = (Ra.sl << 3) - Rb_or_imm.sl; }}); - - 0x29: subq({{ Rc = Ra - Rb_or_imm; }}); - 0x69: subqv({{ - uint64_t tmp = Ra - Rb_or_imm; - // signed overflow detection is same as for add, - // except we need to look at the *complemented* - // sign bit of the subtrahend (Rb), i.e., if the initial - // signs are the *same* then no overflow can occur - if (Ra<63:> != Rb_or_imm<63:> && tmp<63:> != Ra<63:>) - fault = Integer_Overflow_Fault; - Rc = tmp; - }}); - 0x2b: s4subq({{ Rc = (Ra << 2) - Rb_or_imm; }}); - 0x3b: s8subq({{ Rc = (Ra << 3) - Rb_or_imm; }}); - - 0x2d: cmpeq({{ Rc = (Ra == Rb_or_imm); }}); - 0x6d: cmple({{ Rc = (Ra.sq <= Rb_or_imm.sq); }}); - 0x4d: cmplt({{ Rc = (Ra.sq < Rb_or_imm.sq); }}); - 0x3d: cmpule({{ Rc = (Ra.uq <= Rb_or_imm.uq); }}); - 0x1d: cmpult({{ Rc = (Ra.uq < Rb_or_imm.uq); }}); - - 0x0f: cmpbge({{ - int hi = 7; - int lo = 0; - uint64_t tmp = 0; - for (int i = 0; i < 8; ++i) { - tmp |= (Ra.uq >= Rb_or_imm.uq) << i; - hi += 8; - lo += 8; - } - Rc = tmp; - }}); - } - - 0x11: decode INTFUNC { // integer logical operations - - 0x00: and({{ Rc = Ra & Rb_or_imm; }}); - 0x08: bic({{ Rc = Ra & ~Rb_or_imm; }}); - 0x20: bis({{ Rc = Ra | Rb_or_imm; }}); - 0x28: ornot({{ Rc = Ra | ~Rb_or_imm; }}); - 0x40: xor({{ Rc = Ra ^ Rb_or_imm; }}); - 0x48: eqv({{ Rc = Ra ^ ~Rb_or_imm; }}); - - // conditional moves - 0x14: cmovlbs({{ Rc = ((Ra & 1) == 1) ? Rb_or_imm : Rc; }}); - 0x16: cmovlbc({{ Rc = ((Ra & 1) == 0) ? Rb_or_imm : Rc; }}); - 0x24: cmoveq({{ Rc = (Ra == 0) ? Rb_or_imm : Rc; }}); - 0x26: cmovne({{ Rc = (Ra != 0) ? Rb_or_imm : Rc; }}); - 0x44: cmovlt({{ Rc = (Ra.sq < 0) ? Rb_or_imm : Rc; }}); - 0x46: cmovge({{ Rc = (Ra.sq >= 0) ? Rb_or_imm : Rc; }}); - 0x64: cmovle({{ Rc = (Ra.sq <= 0) ? Rb_or_imm : Rc; }}); - 0x66: cmovgt({{ Rc = (Ra.sq > 0) ? Rb_or_imm : Rc; }}); - - // For AMASK, RA must be R31. - 0x61: decode RA { - 31: amask({{ Rc = Rb_or_imm & ~ULL(0x17); }}); - } - - // For IMPLVER, RA must be R31 and the B operand - // must be the immediate value 1. - 0x6c: decode RA { - 31: decode IMM { - 1: decode INTIMM { - // return EV5 for FULL_SYSTEM and EV6 otherwise - 1: implver({{ -#if FULL_SYSTEM - Rc = 1; -#else - Rc = 2; -#endif - }}); - } - } - } - -#if FULL_SYSTEM - // The mysterious 11.25... - 0x25: WarnUnimpl::eleven25(); -#endif - } - - 0x12: decode INTFUNC { - 0x39: sll({{ Rc = Ra << Rb_or_imm<5:0>; }}); - 0x34: srl({{ Rc = Ra.uq >> Rb_or_imm<5:0>; }}); - 0x3c: sra({{ Rc = Ra.sq >> Rb_or_imm<5:0>; }}); - - 0x02: mskbl({{ Rc = Ra & ~(mask( 8) << (Rb_or_imm<2:0> * 8)); }}); - 0x12: mskwl({{ Rc = Ra & ~(mask(16) << (Rb_or_imm<2:0> * 8)); }}); - 0x22: mskll({{ Rc = Ra & ~(mask(32) << (Rb_or_imm<2:0> * 8)); }}); - 0x32: mskql({{ Rc = Ra & ~(mask(64) << (Rb_or_imm<2:0> * 8)); }}); - - 0x52: mskwh({{ - int bv = Rb_or_imm<2:0>; - Rc = bv ? (Ra & ~(mask(16) >> (64 - 8 * bv))) : Ra; - }}); - 0x62: msklh({{ - int bv = Rb_or_imm<2:0>; - Rc = bv ? (Ra & ~(mask(32) >> (64 - 8 * bv))) : Ra; - }}); - 0x72: mskqh({{ - int bv = Rb_or_imm<2:0>; - Rc = bv ? (Ra & ~(mask(64) >> (64 - 8 * bv))) : Ra; - }}); - - 0x06: extbl({{ Rc = (Ra.uq >> (Rb_or_imm<2:0> * 8))< 7:0>; }}); - 0x16: extwl({{ Rc = (Ra.uq >> (Rb_or_imm<2:0> * 8))<15:0>; }}); - 0x26: extll({{ Rc = (Ra.uq >> (Rb_or_imm<2:0> * 8))<31:0>; }}); - 0x36: extql({{ Rc = (Ra.uq >> (Rb_or_imm<2:0> * 8)); }}); - - 0x5a: extwh({{ - Rc = (Ra << (64 - (Rb_or_imm<2:0> * 8))<5:0>)<15:0>; }}); - 0x6a: extlh({{ - Rc = (Ra << (64 - (Rb_or_imm<2:0> * 8))<5:0>)<31:0>; }}); - 0x7a: extqh({{ - Rc = (Ra << (64 - (Rb_or_imm<2:0> * 8))<5:0>); }}); - - 0x0b: insbl({{ Rc = Ra< 7:0> << (Rb_or_imm<2:0> * 8); }}); - 0x1b: inswl({{ Rc = Ra<15:0> << (Rb_or_imm<2:0> * 8); }}); - 0x2b: insll({{ Rc = Ra<31:0> << (Rb_or_imm<2:0> * 8); }}); - 0x3b: insql({{ Rc = Ra << (Rb_or_imm<2:0> * 8); }}); - - 0x57: inswh({{ - int bv = Rb_or_imm<2:0>; - Rc = bv ? (Ra.uq<15:0> >> (64 - 8 * bv)) : 0; - }}); - 0x67: inslh({{ - int bv = Rb_or_imm<2:0>; - Rc = bv ? (Ra.uq<31:0> >> (64 - 8 * bv)) : 0; - }}); - 0x77: insqh({{ - int bv = Rb_or_imm<2:0>; - Rc = bv ? (Ra.uq >> (64 - 8 * bv)) : 0; - }}); - - 0x30: zap({{ - uint64_t zapmask = 0; - for (int i = 0; i < 8; ++i) { - if (Rb_or_imm) - zapmask |= (mask(8) << (i * 8)); - } - Rc = Ra & ~zapmask; - }}); - 0x31: zapnot({{ - uint64_t zapmask = 0; - for (int i = 0; i < 8; ++i) { - if (!Rb_or_imm) - zapmask |= (mask(8) << (i * 8)); - } - Rc = Ra & ~zapmask; - }}); - } - - 0x13: decode INTFUNC { // integer multiplies - 0x00: mull({{ Rc.sl = Ra.sl * Rb_or_imm.sl; }}, IntMultOp); - 0x20: mulq({{ Rc = Ra * Rb_or_imm; }}, IntMultOp); - 0x30: umulh({{ - uint64_t hi, lo; - mul128(Ra, Rb_or_imm, hi, lo); - Rc = hi; - }}, IntMultOp); - 0x40: mullv({{ - // 32-bit multiply with trap on overflow - int64_t Rax = Ra.sl; // sign extended version of Ra.sl - int64_t Rbx = Rb_or_imm.sl; - int64_t tmp = Rax * Rbx; - // To avoid overflow, all the upper 32 bits must match - // the sign bit of the lower 32. We code this as - // checking the upper 33 bits for all 0s or all 1s. - uint64_t sign_bits = tmp<63:31>; - if (sign_bits != 0 && sign_bits != mask(33)) - fault = Integer_Overflow_Fault; - Rc.sl = tmp<31:0>; - }}, IntMultOp); - 0x60: mulqv({{ - // 64-bit multiply with trap on overflow - uint64_t hi, lo; - mul128(Ra, Rb_or_imm, hi, lo); - // all the upper 64 bits must match the sign bit of - // the lower 64 - if (!((hi == 0 && lo<63:> == 0) || - (hi == mask(64) && lo<63:> == 1))) - fault = Integer_Overflow_Fault; - Rc = lo; - }}, IntMultOp); - } - - 0x1c: decode INTFUNC { - 0x00: decode RA { 31: sextb({{ Rc.sb = Rb_or_imm< 7:0>; }}); } - 0x01: decode RA { 31: sextw({{ Rc.sw = Rb_or_imm<15:0>; }}); } - 0x32: ctlz({{ - uint64_t count = 0; - uint64_t temp = Rb; - if (temp<63:32>) temp >>= 32; else count += 32; - if (temp<31:16>) temp >>= 16; else count += 16; - if (temp<15:8>) temp >>= 8; else count += 8; - if (temp<7:4>) temp >>= 4; else count += 4; - if (temp<3:2>) temp >>= 2; else count += 2; - if (temp<1:1>) temp >>= 1; else count += 1; - if ((temp<0:0>) != 0x1) count += 1; - Rc = count; - }}, IntAluOp); - - 0x33: cttz({{ - uint64_t count = 0; - uint64_t temp = Rb; - if (!(temp<31:0>)) { temp >>= 32; count += 32; } - if (!(temp<15:0>)) { temp >>= 16; count += 16; } - if (!(temp<7:0>)) { temp >>= 8; count += 8; } - if (!(temp<3:0>)) { temp >>= 4; count += 4; } - if (!(temp<1:0>)) { temp >>= 2; count += 2; } - if (!(temp<0:0> & ULL(0x1))) count += 1; - Rc = count; - }}, IntAluOp); - - format FailUnimpl { - 0x30: ctpop(); - 0x31: perr(); - 0x34: unpkbw(); - 0x35: unpkbl(); - 0x36: pkwb(); - 0x37: pklb(); - 0x38: minsb8(); - 0x39: minsw4(); - 0x3a: minub8(); - 0x3b: minuw4(); - 0x3c: maxub8(); - 0x3d: maxuw4(); - 0x3e: maxsb8(); - 0x3f: maxsw4(); - } - - format BasicOperateWithNopCheck { - 0x70: decode RB { - 31: ftoit({{ Rc = Fa.uq; }}, FloatCvtOp); - } - 0x78: decode RB { - 31: ftois({{ Rc.sl = t_to_s(Fa.uq); }}, - FloatCvtOp); - } - } - } - } - - // Conditional branches. - format CondBranch { - 0x39: beq({{ cond = (Ra == 0); }}); - 0x3d: bne({{ cond = (Ra != 0); }}); - 0x3e: bge({{ cond = (Ra.sq >= 0); }}); - 0x3f: bgt({{ cond = (Ra.sq > 0); }}); - 0x3b: ble({{ cond = (Ra.sq <= 0); }}); - 0x3a: blt({{ cond = (Ra.sq < 0); }}); - 0x38: blbc({{ cond = ((Ra & 1) == 0); }}); - 0x3c: blbs({{ cond = ((Ra & 1) == 1); }}); - - 0x31: fbeq({{ cond = (Fa == 0); }}); - 0x35: fbne({{ cond = (Fa != 0); }}); - 0x36: fbge({{ cond = (Fa >= 0); }}); - 0x37: fbgt({{ cond = (Fa > 0); }}); - 0x33: fble({{ cond = (Fa <= 0); }}); - 0x32: fblt({{ cond = (Fa < 0); }}); - } - - // unconditional branches - format UncondBranch { - 0x30: br(); - 0x34: bsr(IsCall); - } - - // indirect branches - 0x1a: decode JMPFUNC { - format Jump { - 0: jmp(); - 1: jsr(IsCall); - 2: ret(IsReturn); - 3: jsr_coroutine(IsCall, IsReturn); - } - } - - // Square root and integer-to-FP moves - 0x14: decode FP_SHORTFUNC { - // Integer to FP register moves must have RB == 31 - 0x4: decode RB { - 31: decode FP_FULLFUNC { - format BasicOperateWithNopCheck { - 0x004: itofs({{ Fc.uq = s_to_t(Ra.ul); }}, FloatCvtOp); - 0x024: itoft({{ Fc.uq = Ra.uq; }}, FloatCvtOp); - 0x014: FailUnimpl::itoff(); // VAX-format conversion - } - } - } - - // Square root instructions must have FA == 31 - 0xb: decode FA { - 31: decode FP_TYPEFUNC { - format FloatingPointOperate { -#if SS_COMPATIBLE_FP - 0x0b: sqrts({{ - if (Fb < 0.0) - fault = Arithmetic_Fault; - Fc = sqrt(Fb); - }}, FloatSqrtOp); -#else - 0x0b: sqrts({{ - if (Fb.sf < 0.0) - fault = Arithmetic_Fault; - Fc.sf = sqrt(Fb.sf); - }}, FloatSqrtOp); -#endif - 0x2b: sqrtt({{ - if (Fb < 0.0) - fault = Arithmetic_Fault; - Fc = sqrt(Fb); - }}, FloatSqrtOp); - } - } - } - - // VAX-format sqrtf and sqrtg are not implemented - 0xa: FailUnimpl::sqrtfg(); - } - - // IEEE floating point - 0x16: decode FP_SHORTFUNC_TOP2 { - // The top two bits of the short function code break this - // space into four groups: binary ops, compares, reserved, and - // conversions. See Table 4-12 of AHB. There are different - // special cases in these different groups, so we decode on - // these top two bits first just to select a decode strategy. - // Most of these instructions may have various trapping and - // rounding mode flags set; these are decoded in the - // FloatingPointDecode template used by the - // FloatingPointOperate format. - - // add/sub/mul/div: just decode on the short function code - // and source type. All valid trapping and rounding modes apply. - 0: decode FP_TRAPMODE { - // check for valid trapping modes here - 0,1,5,7: decode FP_TYPEFUNC { - format FloatingPointOperate { -#if SS_COMPATIBLE_FP - 0x00: adds({{ Fc = Fa + Fb; }}); - 0x01: subs({{ Fc = Fa - Fb; }}); - 0x02: muls({{ Fc = Fa * Fb; }}, FloatMultOp); - 0x03: divs({{ Fc = Fa / Fb; }}, FloatDivOp); -#else - 0x00: adds({{ Fc.sf = Fa.sf + Fb.sf; }}); - 0x01: subs({{ Fc.sf = Fa.sf - Fb.sf; }}); - 0x02: muls({{ Fc.sf = Fa.sf * Fb.sf; }}, FloatMultOp); - 0x03: divs({{ Fc.sf = Fa.sf / Fb.sf; }}, FloatDivOp); -#endif - - 0x20: addt({{ Fc = Fa + Fb; }}); - 0x21: subt({{ Fc = Fa - Fb; }}); - 0x22: mult({{ Fc = Fa * Fb; }}, FloatMultOp); - 0x23: divt({{ Fc = Fa / Fb; }}, FloatDivOp); - } - } - } - - // Floating-point compare instructions must have the default - // rounding mode, and may use the default trapping mode or - // /SU. Both trapping modes are treated the same by M5; the - // only difference on the real hardware (as far a I can tell) - // is that without /SU you'd get an imprecise trap if you - // tried to compare a NaN with something else (instead of an - // "unordered" result). - 1: decode FP_FULLFUNC { - format BasicOperateWithNopCheck { - 0x0a5, 0x5a5: cmpteq({{ Fc = (Fa == Fb) ? 2.0 : 0.0; }}, - FloatCmpOp); - 0x0a7, 0x5a7: cmptle({{ Fc = (Fa <= Fb) ? 2.0 : 0.0; }}, - FloatCmpOp); - 0x0a6, 0x5a6: cmptlt({{ Fc = (Fa < Fb) ? 2.0 : 0.0; }}, - FloatCmpOp); - 0x0a4, 0x5a4: cmptun({{ // unordered - Fc = (!(Fa < Fb) && !(Fa == Fb) && !(Fa > Fb)) ? 2.0 : 0.0; - }}, FloatCmpOp); - } - } - - // The FP-to-integer and integer-to-FP conversion insts - // require that FA be 31. - 3: decode FA { - 31: decode FP_TYPEFUNC { - format FloatingPointOperate { - 0x2f: decode FP_ROUNDMODE { - format FPFixedRounding { - // "chopped" i.e. round toward zero - 0: cvttq({{ Fc.sq = (int64_t)trunc(Fb); }}, - Chopped); - // round to minus infinity - 1: cvttq({{ Fc.sq = (int64_t)floor(Fb); }}, - MinusInfinity); - } - default: cvttq({{ Fc.sq = (int64_t)nearbyint(Fb); }}); - } - - // The cvtts opcode is overloaded to be cvtst if the trap - // mode is 2 or 6 (which are not valid otherwise) - 0x2c: decode FP_FULLFUNC { - format BasicOperateWithNopCheck { - // trap on denorm version "cvtst/s" is - // simulated same as cvtst - 0x2ac, 0x6ac: cvtst({{ Fc = Fb.sf; }}); - } - default: cvtts({{ Fc.sf = Fb; }}); - } - - // The trapping mode for integer-to-FP conversions - // must be /SUI or nothing; /U and /SU are not - // allowed. The full set of rounding modes are - // supported though. - 0x3c: decode FP_TRAPMODE { - 0,7: cvtqs({{ Fc.sf = Fb.sq; }}); - } - 0x3e: decode FP_TRAPMODE { - 0,7: cvtqt({{ Fc = Fb.sq; }}); - } - } - } - } - } - - // misc FP operate - 0x17: decode FP_FULLFUNC { - format BasicOperateWithNopCheck { - 0x010: cvtlq({{ - Fc.sl = (Fb.uq<63:62> << 30) | Fb.uq<58:29>; - }}); - 0x030: cvtql({{ - Fc.uq = (Fb.uq<31:30> << 62) | (Fb.uq<29:0> << 29); - }}); - - // We treat the precise & imprecise trapping versions of - // cvtql identically. - 0x130, 0x530: cvtqlv({{ - // To avoid overflow, all the upper 32 bits must match - // the sign bit of the lower 32. We code this as - // checking the upper 33 bits for all 0s or all 1s. - uint64_t sign_bits = Fb.uq<63:31>; - if (sign_bits != 0 && sign_bits != mask(33)) - fault = Integer_Overflow_Fault; - Fc.uq = (Fb.uq<31:30> << 62) | (Fb.uq<29:0> << 29); - }}); - - 0x020: cpys({{ // copy sign - Fc.uq = (Fa.uq<63:> << 63) | Fb.uq<62:0>; - }}); - 0x021: cpysn({{ // copy sign negated - Fc.uq = (~Fa.uq<63:> << 63) | Fb.uq<62:0>; - }}); - 0x022: cpyse({{ // copy sign and exponent - Fc.uq = (Fa.uq<63:52> << 52) | Fb.uq<51:0>; - }}); - - 0x02a: fcmoveq({{ Fc = (Fa == 0) ? Fb : Fc; }}); - 0x02b: fcmovne({{ Fc = (Fa != 0) ? Fb : Fc; }}); - 0x02c: fcmovlt({{ Fc = (Fa < 0) ? Fb : Fc; }}); - 0x02d: fcmovge({{ Fc = (Fa >= 0) ? Fb : Fc; }}); - 0x02e: fcmovle({{ Fc = (Fa <= 0) ? Fb : Fc; }}); - 0x02f: fcmovgt({{ Fc = (Fa > 0) ? Fb : Fc; }}); - - 0x024: mt_fpcr({{ FPCR = Fa.uq; }}); - 0x025: mf_fpcr({{ Fa.uq = FPCR; }}); - } - } - - // miscellaneous mem-format ops - 0x18: decode MEMFUNC { - format WarnUnimpl { - 0x8000: fetch(); - 0xa000: fetch_m(); - 0xe800: ecb(); - } - - format MiscPrefetch { - 0xf800: wh64({{ EA = Rb & ~ULL(63); }}, - {{ xc->writeHint(EA, 64, memAccessFlags); }}, - IsMemRef, IsDataPrefetch, IsStore, MemWriteOp, - NO_FAULT); - } - - format BasicOperate { - 0xc000: rpcc({{ -#if FULL_SYSTEM - /* Rb is a fake dependency so here is a fun way to get - * the parser to understand that. - */ - Ra = xc->readIpr(AlphaISA::IPR_CC, fault) + (Rb & 0); - -#else - Ra = curTick; -#endif - }}); - - // All of the barrier instructions below do nothing in - // their execute() methods (hence the empty code blocks). - // All of their functionality is hard-coded in the - // pipeline based on the flags IsSerializing, - // IsMemBarrier, and IsWriteBarrier. In the current - // detailed CPU model, the execute() function only gets - // called at fetch, so there's no way to generate pipeline - // behavior at any other stage. Once we go to an - // exec-in-exec CPU model we should be able to get rid of - // these flags and implement this behavior via the - // execute() methods. - - // trapb is just a barrier on integer traps, where excb is - // a barrier on integer and FP traps. "EXCB is thus a - // superset of TRAPB." (Alpha ARM, Sec 4.11.4) We treat - // them the same though. - 0x0000: trapb({{ }}, IsSerializing, No_OpClass); - 0x0400: excb({{ }}, IsSerializing, No_OpClass); - 0x4000: mb({{ }}, IsMemBarrier, MemReadOp); - 0x4400: wmb({{ }}, IsWriteBarrier, MemWriteOp); - } - -#if FULL_SYSTEM - format BasicOperate { - 0xe000: rc({{ - Ra = xc->readIntrFlag(); - xc->setIntrFlag(0); - }}, IsNonSpeculative); - 0xf000: rs({{ - Ra = xc->readIntrFlag(); - xc->setIntrFlag(1); - }}, IsNonSpeculative); - } -#else - format FailUnimpl { - 0xe000: rc(); - 0xf000: rs(); - } -#endif - } - -#if FULL_SYSTEM - 0x00: CallPal::call_pal({{ - if (!palValid || - (palPriv - && xc->readIpr(AlphaISA::IPR_ICM, fault) != AlphaISA::mode_kernel)) { - // invalid pal function code, or attempt to do privileged - // PAL call in non-kernel mode - fault = Unimplemented_Opcode_Fault; - } - else { - // check to see if simulator wants to do something special - // on this PAL call (including maybe suppress it) - bool dopal = xc->simPalCheck(palFunc); - - if (dopal) { - AlphaISA::swap_palshadow(&xc->xcBase()->regs, true); - xc->setIpr(AlphaISA::IPR_EXC_ADDR, NPC); - NPC = xc->readIpr(AlphaISA::IPR_PAL_BASE, fault) + palOffset; - } - } - }}, IsNonSpeculative); -#else - 0x00: decode PALFUNC { - format EmulatedCallPal { - 0x00: halt ({{ - SimExit(curTick, "halt instruction encountered"); - }}, IsNonSpeculative); - 0x83: callsys({{ - xc->syscall(); - }}, IsNonSpeculative); - // Read uniq reg into ABI return value register (r0) - 0x9e: rduniq({{ R0 = Runiq; }}); - // Write uniq reg with value from ABI arg register (r16) - 0x9f: wruniq({{ Runiq = R16; }}); - } - } -#endif - -#if FULL_SYSTEM - format HwLoadStore { - 0x1b: decode HW_LDST_QUAD { - 0: hw_ld({{ EA = (Rb + disp) & ~3; }}, {{ Ra = Mem.ul; }}, L); - 1: hw_ld({{ EA = (Rb + disp) & ~7; }}, {{ Ra = Mem.uq; }}, Q); - } - - 0x1f: decode HW_LDST_COND { - 0: decode HW_LDST_QUAD { - 0: hw_st({{ EA = (Rb + disp) & ~3; }}, - {{ Mem.ul = Ra<31:0>; }}, L); - 1: hw_st({{ EA = (Rb + disp) & ~7; }}, - {{ Mem.uq = Ra.uq; }}, Q); - } - - 1: FailUnimpl::hw_st_cond(); - } - } - - format HwMoveIPR { - 0x19: hw_mfpr({{ - // this instruction is only valid in PAL mode - if (!xc->inPalMode()) { - fault = Unimplemented_Opcode_Fault; - } - else { - Ra = xc->readIpr(ipr_index, fault); - } - }}); - 0x1d: hw_mtpr({{ - // this instruction is only valid in PAL mode - if (!xc->inPalMode()) { - fault = Unimplemented_Opcode_Fault; - } - else { - xc->setIpr(ipr_index, Ra); - if (traceData) { traceData->setData(Ra); } - } - }}); - } - - format BasicOperate { - 0x1e: hw_rei({{ xc->hwrei(); }}, IsSerializing); - - // M5 special opcodes use the reserved 0x01 opcode space - 0x01: decode M5FUNC { - 0x00: arm({{ - AlphaPseudo::arm(xc->xcBase()); - }}, IsNonSpeculative); - 0x01: quiesce({{ - AlphaPseudo::quiesce(xc->xcBase()); - }}, IsNonSpeculative); - 0x10: ivlb({{ - AlphaPseudo::ivlb(xc->xcBase()); - }}, No_OpClass, IsNonSpeculative); - 0x11: ivle({{ - AlphaPseudo::ivle(xc->xcBase()); - }}, No_OpClass, IsNonSpeculative); - 0x20: m5exit_old({{ - AlphaPseudo::m5exit_old(xc->xcBase()); - }}, No_OpClass, IsNonSpeculative); - 0x21: m5exit({{ - AlphaPseudo::m5exit(xc->xcBase()); - }}, No_OpClass, IsNonSpeculative); - 0x30: initparam({{ Ra = xc->xcBase()->cpu->system->init_param; }}); - 0x40: resetstats({{ - AlphaPseudo::resetstats(xc->xcBase()); - }}, IsNonSpeculative); - 0x41: dumpstats({{ - AlphaPseudo::dumpstats(xc->xcBase()); - }}, IsNonSpeculative); - 0x42: dumpresetstats({{ - AlphaPseudo::dumpresetstats(xc->xcBase()); - }}, IsNonSpeculative); - 0x43: m5checkpoint({{ - AlphaPseudo::m5checkpoint(xc->xcBase()); - }}, IsNonSpeculative); - 0x50: m5readfile({{ - AlphaPseudo::readfile(xc->xcBase()); - }}, IsNonSpeculative); - 0x51: m5break({{ - AlphaPseudo::debugbreak(xc->xcBase()); - }}, IsNonSpeculative); - 0x52: m5switchcpu({{ - AlphaPseudo::switchcpu(xc->xcBase()); - }}, IsNonSpeculative); - 0x53: m5addsymbol({{ - AlphaPseudo::addsymbol(xc->xcBase()); - }}, IsNonSpeculative); - - } - } -#endif -} From 524da7cd20dae5416cd0962a9b9bd49dcf92ee51 Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Wed, 8 Feb 2006 10:40:43 -0500 Subject: [PATCH 024/180] Replace ad-hoc or locally defined power-of-2 tests with isPowerOf2() from intmath.hh. base/sched_list.hh: Use isPowerOf2() from intmath.hh. --HG-- extra : convert_revision : 7b2409531d8ed194aa7e1cfcd1ecb8460c797a16 --- base/sched_list.hh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/base/sched_list.hh b/base/sched_list.hh index 0e2f3ddcb..f794e3514 100644 --- a/base/sched_list.hh +++ b/base/sched_list.hh @@ -30,8 +30,10 @@ #define SCHED_LIST_HH #include +#include "base/intmath.hh" #include "base/misc.hh" + // Any types you use this class for must be covered here... namespace { void ClearEntry(int &i) { i = 0; }; @@ -80,7 +82,7 @@ SchedList::SchedList(unsigned _size) size = _size; // size must be a power of two - if (size & (size-1)) { + if (!isPowerOf2(size)) { panic("SchedList: size must be a power of two"); } From b203d7bd33fd4552c556cf3cea7007d717d04375 Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Wed, 8 Feb 2006 14:50:07 -0500 Subject: [PATCH 025/180] add at least BasicOp Format to most if not all instructions and file name changes ... arch/mips/isa/decoder.isa: add at least BasicOp Format to most if not all instructions --HG-- rename : arch/mips/isa/formats/basic.format => arch/mips/isa/formats/basic.isa rename : arch/mips/isa/formats/branch.format => arch/mips/isa/formats/branch.isa rename : arch/mips/isa/formats/fp.format => arch/mips/isa/formats/fp.isa rename : arch/mips/isa/formats/int.format => arch/mips/isa/formats/int.isa rename : arch/mips/isa/formats/mem.format => arch/mips/isa/formats/mem.isa rename : arch/mips/isa/formats/noop.format => arch/mips/isa/formats/noop.isa rename : arch/mips/isa/formats/tlbop.format => arch/mips/isa/formats/tlbop.isa rename : arch/mips/isa/formats/trap.format => arch/mips/isa/formats/trap.isa rename : arch/mips/isa/mips.isa => arch/mips/isa/main.isa extra : convert_revision : 0b2f3aee13fee3e0e25c0c746af4216c4a596391 --- arch/mips/isa/decoder.isa | 207 ++++++++++-------- .../isa/formats/{basic.format => basic.isa} | 0 .../isa/formats/{branch.format => branch.isa} | 0 arch/mips/isa/formats/{fp.format => fp.isa} | 0 arch/mips/isa/formats/{int.format => int.isa} | 0 arch/mips/isa/formats/{mem.format => mem.isa} | 0 .../isa/formats/{noop.format => noop.isa} | 0 .../isa/formats/{tlbop.format => tlbop.isa} | 0 .../isa/formats/{trap.format => trap.isa} | 0 arch/mips/isa/{mips.isa => main.isa} | 0 10 files changed, 116 insertions(+), 91 deletions(-) rename arch/mips/isa/formats/{basic.format => basic.isa} (100%) rename arch/mips/isa/formats/{branch.format => branch.isa} (100%) rename arch/mips/isa/formats/{fp.format => fp.isa} (100%) rename arch/mips/isa/formats/{int.format => int.isa} (100%) rename arch/mips/isa/formats/{mem.format => mem.isa} (100%) rename arch/mips/isa/formats/{noop.format => noop.isa} (100%) rename arch/mips/isa/formats/{tlbop.format => tlbop.isa} (100%) rename arch/mips/isa/formats/{trap.format => trap.isa} (100%) rename arch/mips/isa/{mips.isa => main.isa} (100%) diff --git a/arch/mips/isa/decoder.isa b/arch/mips/isa/decoder.isa index f0c3fc562..e29b57602 100644 --- a/arch/mips/isa/decoder.isa +++ b/arch/mips/isa/decoder.isa @@ -17,7 +17,7 @@ decode OPCODE_HI default FailUnimpl::unknown() { 0x0: decode FUNCTION_HI { 0x0: decode FUNCTION_LO { 0x1: decode MOVCI { - format Move { + format BasicOp { 0: movf({{ if( xc->miscRegs.fpcr == 0) Rd = Rs}}); 1: movt({{ if( xc->miscRegs.fpcr == 1) Rd = Rs}}); } @@ -61,7 +61,7 @@ decode OPCODE_HI default FailUnimpl::unknown() { 0x1: jalr(IsCall,IsReturn); } - format Move { + format BasicOp { 0x2: movz({{ if (Rt == 0) Rd = Rs; }}); 0x3: movn({{ if (Rt != 0) Rd = Rs; }}); } @@ -75,10 +75,10 @@ decode OPCODE_HI default FailUnimpl::unknown() { 0x2: decode FUNCTION_LO { format BasicOp { - 0x0: mfhi({{ Rd = xc->miscRegs.Hi; }}); - 0x1: mthi({{ xc->miscRegs.Hi = Rs; }}); - 0x2: mflo({{ Rd = xc->miscRegs.Lo; }}); - 0x3: mtlo({{ xc->miscRegs.Lo = Rs; }}); + 0x0: mfhi({{ Rd = xc->miscRegs.hi; }}); + 0x1: mthi({{ xc->miscRegs.hi = Rs; }}); + 0x2: mflo({{ Rd = xc->miscRegs.lo; }}); + 0x3: mtlo({{ xc->miscRegs.lo = Rs; }}); } }; @@ -86,25 +86,25 @@ decode OPCODE_HI default FailUnimpl::unknown() { format IntOp { 0x0: mult({{ INT64 temp1 = Rs.sw * Rt.sw; - xc->miscRegs.Hi->temp1<63:32>; - xc->miscRegs.Lo->temp1<31:0> + xc->miscRegs.hi->temp1<63:32>; + xc->miscRegs.lo->temp1<31:0> }}); 0x1: multu({{ INT64 temp1 = Rs.uw * Rt.uw; - xc->miscRegs.Hi->temp1<63:32>; - xc->miscRegs.Lo->temp1<31:0> + xc->miscRegs.hi->temp1<63:32>; + xc->miscRegs.lo->temp1<31:0> Rd.sw = Rs.uw * Rt.uw; }}); 0x2: div({{ - xc->miscRegs.Hi = Rs.sw % Rt.sw; - xc->miscRegs.Lo = Rs.sw / Rt.sw; + xc->miscRegs.hi = Rs.sw % Rt.sw; + xc->miscRegs.lo = Rs.sw / Rt.sw; }}); 0x3: divu({{ - xc->miscRegs.Hi = Rs.uw % Rt.uw; - xc->miscRegs.Lo = Rs.uw / Rt.uw; + xc->miscRegs.hi = Rs.uw % Rt.uw; + xc->miscRegs.lo = Rs.uw / Rt.uw; }}); } }; @@ -213,9 +213,12 @@ decode OPCODE_HI default FailUnimpl::unknown() { //Table A-11 MIPS32 COP0 Encoding of rs Field 0x0: decode RS_MSB { 0x0: decode RS { - 0x0: mfc0({{ }}); - 0xC: mtc0({{ }}); - 0xA: rdpgpr({{ }}); + + format BasicOp { + 0x0: mfc0({{ }}); + 0xC: mtc0({{ }}); + 0xA: rdpgpr({{ }}); + } 0xB: decode SC { format BasicOp { @@ -224,7 +227,7 @@ decode OPCODE_HI default FailUnimpl::unknown() { } } - 0xE: wrpgpr({{ }}); + 0xE: BasicOp::wrpgpr({{ }}); } //Table A-12 MIPS32 COP0 Encoding of Function Field When rs=CO @@ -281,43 +284,49 @@ decode OPCODE_HI default FailUnimpl::unknown() { //(( single-word )) 0x0: decode RS_HI { 0x0: decode RS_LO { - 0x0: add_fmt({{ }}); - 0x1: sub_fmt({{ }}); - 0x2: mul_fmt({{ }}); - 0x3: div_fmt({{ }}); - 0x4: sqrt_fmt({{ }}); - 0x5: abs_fmt({{ }}); - 0x6: mov_fmt({{ }}); - 0x7: neg_fmt({{ }}); + format FloatOp { + 0x0: add_fmt({{ }}); + 0x1: sub_fmt({{ }}); + 0x2: mul_fmt({{ }}); + 0x3: div_fmt({{ }}); + 0x4: sqrt_fmt({{ }}); + 0x5: abs_fmt({{ }}); + 0x6: mov_fmt({{ }}); + 0x7: neg_fmt({{ }}); + } } 0x1: decode RS_LO { //only legal for 64 bit - format mode64 { + format Float64Op { 0x0: round_l({{ }}); 0x1: trunc_l({{ }}); 0x2: ceil_l({{ }}); 0x3: floor_l({{ }}); } - 0x4: round_w({{ }}); - 0x5: trunc_w({{ }}); - 0x6: ceil_w({{ }}); - 0x7: floor_w({{ }}); + format FloatOp { + 0x4: round_w({{ }}); + 0x5: trunc_w({{ }}); + 0x6: ceil_w({{ }}); + 0x7: floor_w({{ }}); + } } 0x2: decode RS_LO { 0x1: decode MOVCF { - 0x0: movf_fmt({{ }}); - 0x1: movt_fmt({{ }}); + format BasicOp { + 0x0: movf_fmt({{ }}); + 0x1: movt_fmt({{ }}); + } } - format Move { + format BasicOp { 0x2: movz({{ if (Rt == 0) Rd = Rs; }}); 0x3: movn({{ if (Rt != 0) Rd = Rs; }}); } - format mode64 { + format Float64Op { 0x2: recip({{ }}); 0x3: rsqrt{{ }}); } @@ -328,7 +337,7 @@ decode OPCODE_HI default FailUnimpl::unknown() { 0x4: cvt_w({{ }}); //only legal for 64 bit - format mode64 { + format Float64Op { 0x5: cvt_l({{ }}); 0x6: cvt_ps({{ }}); } @@ -444,12 +453,14 @@ decode OPCODE_HI default FailUnimpl::unknown() { 0x2: decode RS_MSB { 0x0: decode RS_HI { 0x0: decode RS_LO { - 0x0: mfc2({{ }}); - 0x2: cfc2({{ }}); - 0x3: mfhc2({{ }}); - 0x4: mtc2({{ }}); - 0x6: ctc2({{ }}); - 0x7: mftc2({{ }}); + format WarnUnimpl { + 0x0: mfc2({{ }}); + 0x2: cfc2({{ }}); + 0x3: mfhc2({{ }}); + 0x4: mtc2({{ }}); + 0x6: ctc2({{ }}); + 0x7: mftc2({{ }}); + } } 0x1: decode ND { @@ -475,50 +486,58 @@ decode OPCODE_HI default FailUnimpl::unknown() { //operations are enabled." 0x3: decode FUNCTION_HI { 0x0: decode FUNCTION_LO { - 0x0: lwxc1({{ }}); - 0x1: ldxc1({{ }}); - 0x5: luxc1({{ }}); + format Memory { + 0x0: lwxc1({{ }}); + 0x1: ldxc1({{ }}); + 0x5: luxc1({{ }}); + } } 0x1: decode FUNCTION_LO { - 0x0: swxc1({{ }}); - 0x1: sdxc1({{ }}); - 0x5: suxc1({{ }}); - 0x7: prefx({{ }}); + format Memory { + 0x0: swxc1({{ }}); + 0x1: sdxc1({{ }}); + 0x5: suxc1({{ }}); + 0x7: prefx({{ }}); + } } - 0x3: alnv_ps({{ }}); + format FloatOp { + 0x3: alnv_ps({{ }}); - 0x4: decode FUNCTION_LO { - 0x0: madd_s({{ }}); - 0x1: madd_d({{ }}); - 0x6: madd_ps({{ }}); - } + 0x4: decode FUNCTION_LO { + 0x0: madd_s({{ }}); + 0x1: madd_d({{ }}); + 0x6: madd_ps({{ }}); + } - 0x5: decode FUNCTION_LO { - 0x0: msub_s({{ }}); - 0x1: msub_d({{ }}); - 0x6: msub_ps({{ }}); - } + 0x5: decode FUNCTION_LO { + 0x0: msub_s({{ }}); + 0x1: msub_d({{ }}); + 0x6: msub_ps({{ }}); + } - 0x6: decode FUNCTION_LO { - 0x0: nmadd_s({{ }}); - 0x1: nmadd_d({{ }}); - 0x6: nmadd_ps({{ }}); - } + 0x6: decode FUNCTION_LO { + 0x0: nmadd_s({{ }}); + 0x1: nmadd_d({{ }}); + 0x6: nmadd_ps({{ }}); + } - 0x7: decode FUNCTION_LO { - 0x0: nmsub_s({{ }}); - 0x1: nmsub_d({{ }}); - 0x6: nmsub_ps({{ }}); + 0x7: decode FUNCTION_LO { + 0x0: nmsub_s({{ }}); + 0x1: nmsub_d({{ }}); + 0x6: nmsub_ps({{ }}); + } } } //MIPS obsolete instructions - 0x4: beql({{ cond = (Rs.sq == 0); }}); - 0x5: bnel({{ cond = (Rs.sq != 0); }}); - 0x6: blezl({{ cond = (Rs.sq <= 0); }}); - 0x7: bgtzl({{ cond = (Rs.sq > 0); }}); + format Branch { + 0x4: beql({{ cond = (Rs.sq == 0); }}); + 0x5: bnel({{ cond = (Rs.sq != 0); }}); + 0x6: blezl({{ cond = (Rs.sq <= 0); }}); + 0x7: bgtzl({{ cond = (Rs.sq > 0); }}); + } }; 0x3: decode OPCODE_LO default FailUnimpl::reserved() { @@ -531,15 +550,15 @@ decode OPCODE_HI default FailUnimpl::unknown() { 0x0: madd({{ INT64 temp1 = Hi.sw << 32 | Lo.sw >> 32; temp1 = temp1 + (Rs.sw * Rt.sw); - xc->miscRegs.Hi->temp1<63:32>; - xc->miscRegs.Lo->temp1<31:0> + xc->miscRegs.hi->temp1<63:32>; + xc->miscRegs.lo->temp1<31:0> }}); 0x1: maddu({{ INT64 temp1 = Hi.uw << 32 | Lo.uw >> 32; temp1 = temp1 + (Rs.uw * Rt.uw); - xc->miscRegs.Hi->temp1<63:32>; - xc->miscRegs.Lo->temp1<31:0> + xc->miscRegs.hi->temp1<63:32>; + xc->miscRegs.lo->temp1<31:0> }}); 0x2: mul({{ Rd.sw = Rs.sw * Rt.sw; }}); @@ -547,26 +566,28 @@ decode OPCODE_HI default FailUnimpl::unknown() { 0x4: msub({{ INT64 temp1 = Hi.sw << 32 | Lo.sw >> 32; temp1 = temp1 - (Rs.sw * Rt.sw); - xc->miscRegs.Hi->temp1<63:32>; - xc->miscRegs.Lo->temp1<31:0> + xc->miscRegs.hi->temp1<63:32>; + xc->miscRegs.lo->temp1<31:0> }}); 0x5: msubu({{ INT64 temp1 = Hi.uw << 32 | Lo.uw >> 32; temp1 = temp1 - (Rs.uw * Rt.uw); - xc->miscRegs.Hi->temp1<63:32>; - xc->miscRegs.Lo->temp1<31:0> + xc->miscRegs.hi->temp1<63:32>; + xc->miscRegs.lo->temp1<31:0> }}); } } 0x4: decode FUNCTION_LO { - 0x0: clz({{ }}); - 0x1: clo({{ }}); + format BasicOp { + 0x0: clz({{ }}); + 0x1: clo({{ }}); + } } 0x7: decode FUNCTION_LO { - 0x7: sdbbp({{ }}); + 0x7: BasicOp::sdbbp({{ }}); } } @@ -574,19 +595,23 @@ decode OPCODE_HI default FailUnimpl::unknown() { 0x7: decode FUNCTION_HI { 0x0: decode FUNCTION_LO { - 0x1: ext({{ }}); - 0x4: ins({{ }}); + format Branch { + 0x1: ext({{ }}); + 0x4: ins({{ }}); + } } //Table A-10 MIPS32 BSHFL Encoding of sa Field 0x4: decode SA { - 0x02: wsbh({{ }}); - 0x10: seb({{ }}); - 0x18: seh({{ }}); + format BasicOp { + 0x02: wsbh({{ }}); + 0x10: seb({{ }}); + 0x18: seh({{ }}); + } } 0x6: decode FUNCTION_LO { - 0x7: rdhwr({{ }}); + 0x7: BasicOp::rdhwr({{ }}); } } }; @@ -614,7 +639,7 @@ decode OPCODE_HI default FailUnimpl::unknown() { 0x6: swr({{ EA = Rs + disp; }},{{ Mem.ub = Rt<31:0>; }},WordAlign); }; - format FailUnimpl { + format WarnUnimpl { 0x4: reserved({{ }}); 0x5: reserved({{ }}); 0x7: cache({{ }}); diff --git a/arch/mips/isa/formats/basic.format b/arch/mips/isa/formats/basic.isa similarity index 100% rename from arch/mips/isa/formats/basic.format rename to arch/mips/isa/formats/basic.isa diff --git a/arch/mips/isa/formats/branch.format b/arch/mips/isa/formats/branch.isa similarity index 100% rename from arch/mips/isa/formats/branch.format rename to arch/mips/isa/formats/branch.isa diff --git a/arch/mips/isa/formats/fp.format b/arch/mips/isa/formats/fp.isa similarity index 100% rename from arch/mips/isa/formats/fp.format rename to arch/mips/isa/formats/fp.isa diff --git a/arch/mips/isa/formats/int.format b/arch/mips/isa/formats/int.isa similarity index 100% rename from arch/mips/isa/formats/int.format rename to arch/mips/isa/formats/int.isa diff --git a/arch/mips/isa/formats/mem.format b/arch/mips/isa/formats/mem.isa similarity index 100% rename from arch/mips/isa/formats/mem.format rename to arch/mips/isa/formats/mem.isa diff --git a/arch/mips/isa/formats/noop.format b/arch/mips/isa/formats/noop.isa similarity index 100% rename from arch/mips/isa/formats/noop.format rename to arch/mips/isa/formats/noop.isa diff --git a/arch/mips/isa/formats/tlbop.format b/arch/mips/isa/formats/tlbop.isa similarity index 100% rename from arch/mips/isa/formats/tlbop.format rename to arch/mips/isa/formats/tlbop.isa diff --git a/arch/mips/isa/formats/trap.format b/arch/mips/isa/formats/trap.isa similarity index 100% rename from arch/mips/isa/formats/trap.format rename to arch/mips/isa/formats/trap.isa diff --git a/arch/mips/isa/mips.isa b/arch/mips/isa/main.isa similarity index 100% rename from arch/mips/isa/mips.isa rename to arch/mips/isa/main.isa From b6d21b7a34dd98b20694c62ba7facb031ce2feca Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Wed, 8 Feb 2006 16:24:04 -0500 Subject: [PATCH 026/180] Code for more "BasicOp" instructions ... formats for all instructions in place ... Edits to Branch Format arch/mips/isa/decoder.isa: Code for di,ei,seb,seh,clz,and clo .... Every instruction has a format now (of course these are initial formats are still subject to change!) arch/mips/isa/formats/branch.isa: Format Branch in MIPS similar to Alpha Format --HG-- extra : convert_revision : 2118a1d9668610b1e9f1dea66d878b7b36c1ac7e --- arch/mips/isa/decoder.isa | 147 +++++++++++++++++++------------ arch/mips/isa/formats/branch.isa | 18 ++-- 2 files changed, 102 insertions(+), 63 deletions(-) diff --git a/arch/mips/isa/decoder.isa b/arch/mips/isa/decoder.isa index e29b57602..54a9f1cb5 100644 --- a/arch/mips/isa/decoder.isa +++ b/arch/mips/isa/decoder.isa @@ -222,8 +222,8 @@ decode OPCODE_HI default FailUnimpl::unknown() { 0xB: decode SC { format BasicOp { - 0x0: di({{ }}); - 0x1: ei({{ }}); + 0x0: di({{ Rt.sw = xc->miscRegs.statusReg; statusReg[IE] = 0;}}); + 0x1: ei({{ Rt.sw = xc->miscRegs.statusReg; statusReg[IE] = 1;}}); } } @@ -239,7 +239,7 @@ decode OPCODE_HI default FailUnimpl::unknown() { 0x08: tlbp({{ }}); } - format BasicOp { + format WarnUnimpl { 0x18: eret({{ }}); 0x1F: deret({{ }}); 0x20: wait({{ }}); @@ -252,12 +252,14 @@ decode OPCODE_HI default FailUnimpl::unknown() { 0x0: decode RS_HI { 0x0: decode RS_LO { - 0x0: mfc1({{ }}); - 0x2: cfc1({{ }}); - 0x3: mfhc1({{ }}); - 0x4: mtc1({{ }}); - 0x6: ctc1({{ }}); - 0x7: mftc1({{ }}); + format FloatOp { + 0x0: mfc1({{ }}); + 0x2: cfc1({{ }}); + 0x3: mfhc1({{ }}); + 0x4: mtc1({{ }}); + 0x6: ctc1({{ }}); + 0x7: mftc1({{ }}); + } } 0x1: decode ND { @@ -315,7 +317,7 @@ decode OPCODE_HI default FailUnimpl::unknown() { 0x2: decode RS_LO { 0x1: decode MOVCF { - format BasicOp { + format FloatOp { 0x0: movf_fmt({{ }}); 0x1: movt_fmt({{ }}); } @@ -347,54 +349,62 @@ decode OPCODE_HI default FailUnimpl::unknown() { //Table A-15 MIPS32 COP1 Encoding of Function Field When rs=D 0x1: decode RS_HI { 0x0: decode RS_LO { - 0x0: add_fmt({{ }}); - 0x1: sub_fmt({{ }}); - 0x2: mul_fmt({{ }}); - 0x3: div_fmt({{ }}); - 0x4: sqrt_fmt({{ }}); - 0x5: abs_fmt({{ }}); - 0x6: mov_fmt({{ }}); - 0x7: neg_fmt({{ }}); + format FloatOp { + 0x0: add_fmt({{ }}); + 0x1: sub_fmt({{ }}); + 0x2: mul_fmt({{ }}); + 0x3: div_fmt({{ }}); + 0x4: sqrt_fmt({{ }}); + 0x5: abs_fmt({{ }}); + 0x6: mov_fmt({{ }}); + 0x7: neg_fmt({{ }}); + } } 0x1: decode RS_LO { //only legal for 64 bit - format mode64 { + format FloatOp64 { 0x0: round_l({{ }}); 0x1: trunc_l({{ }}); 0x2: ceil_l({{ }}); 0x3: floor_l({{ }}); } - 0x4: round_w({{ }}); - 0x5: trunc_w({{ }}); - 0x6: ceil_w({{ }}); - 0x7: floor_w({{ }}); + format FloatOp { + 0x4: round_w({{ }}); + 0x5: trunc_w({{ }}); + 0x6: ceil_w({{ }}); + 0x7: floor_w({{ }}); + } } 0x2: decode RS_LO { 0x1: decode MOVCF { - 0x0: movf_fmt({{ }}); - 0x1: movt_fmt({{ }}); + format FloatOp { + 0x0: movf_fmt({{ }}); + 0x1: movt_fmt({{ }}); + } } - format Move { + format BasicOp { 0x2: movz({{ if (Rt == 0) Rd = Rs; }}); 0x3: movn({{ if (Rt != 0) Rd = Rs; }}); } - format mode64 { + format FloatOp64 { 0x5: recip({{ }}); 0x6: rsqrt{{ }}); } } 0x4: decode RS_LO { - 0x0: cvt_s({{ }}); - 0x4: cvt_w({{ }}); + format FloatOp { + 0x0: cvt_s({{ }}); + 0x4: cvt_w({{ }}); + } //only legal for 64 bit - format mode64 { + format FloatOp64 { 0x5: cvt_l({{ }}); } } @@ -402,16 +412,20 @@ decode OPCODE_HI default FailUnimpl::unknown() { //Table A-16 MIPS32 COP1 Encoding of Function Field When rs=W 0x4: decode FUNCTION { - 0x10: cvt_s({{ }}); - 0x10: cvt_d({{ }}); + format FloatOp { + 0x10: cvt_s({{ }}); + 0x10: cvt_d({{ }}); + } } //Table A-16 MIPS32 COP1 Encoding of Function Field When rs=L1 //Note: "1. Format type L is legal only if 64-bit floating point operations //are enabled." 0x5: decode FUNCTION_HI { - 0x10: cvt_s({{ }}); - 0x11: cvt_d({{ }}); + format FloatOp { + 0x10: cvt_s({{ }}); + 0x11: cvt_d({{ }}); + } } //Table A-17 MIPS64 COP1 Encoding of Function Field When rs=PS1 @@ -419,32 +433,38 @@ decode OPCODE_HI default FailUnimpl::unknown() { //are enabled. " 0x6: decode RS_HI { 0x0: decode RS_LO { - 0x0: add_fmt({{ }}); - 0x1: sub_fmt({{ }}); - 0x2: mul_fmt({{ }}); - 0x5: abs_fmt({{ }}); - 0x6: mov_fmt({{ }}); - 0x7: neg_fmt({{ }}); + format FloatOp64 { + 0x0: add_fmt({{ }}); + 0x1: sub_fmt({{ }}); + 0x2: mul_fmt({{ }}); + 0x5: abs_fmt({{ }}); + 0x6: mov_fmt({{ }}); + 0x7: neg_fmt({{ }}); + } } 0x2: decode RS_LO { 0x1: decode MOVCF { - 0x0: movf_fmt({{ }}); - 0x1: movt_fmt({{ }}); + format FloatOp64 { + 0x0: movf_fmt({{ }}); + 0x1: movt_fmt({{ }}); + } } } 0x4: decode RS_LO { - 0x0: cvt_s_pu({{ }}); + 0x0: FloatOp64::cvt_s_pu({{ }}); } 0x5: decode RS_LO { - 0x0: cvt_s_pl({{ }}); - 0x4: pll_s_pl({{ }}); - 0x5: plu_s_pl({{ }}); - 0x6: pul_s_pl({{ }}); - 0x7: puu_s_pl({{ }}); + format FloatOp64 { + 0x0: cvt_s_pl({{ }}); + 0x4: pll_s_pl({{ }}); + 0x5: plu_s_pl({{ }}); + 0x6: pul_s_pl({{ }}); + 0x7: puu_s_pl({{ }}); + } } } } @@ -581,13 +601,32 @@ decode OPCODE_HI default FailUnimpl::unknown() { 0x4: decode FUNCTION_LO { format BasicOp { - 0x0: clz({{ }}); - 0x1: clo({{ }}); + 0x0: clz({{ + int cnt = 0; + int idx = 0; + while ( Rs.uw!= 1) { + cnt++; + idx--; + } + + Rd.uw = cnt; + }}); + + 0x1: clo({{ + int cnt = 0; + int idx = 0; + while ( Rs.uw!= 0) { + cnt++; + idx--; + } + + Rd.uw = cnt; + }}); } } 0x7: decode FUNCTION_LO { - 0x7: BasicOp::sdbbp({{ }}); + 0x7: WarnUnimpl::sdbbp({{ }}); } } @@ -595,7 +634,7 @@ decode OPCODE_HI default FailUnimpl::unknown() { 0x7: decode FUNCTION_HI { 0x0: decode FUNCTION_LO { - format Branch { + format WarnUnimpl { 0x1: ext({{ }}); 0x4: ins({{ }}); } @@ -605,8 +644,8 @@ decode OPCODE_HI default FailUnimpl::unknown() { 0x4: decode SA { format BasicOp { 0x02: wsbh({{ }}); - 0x10: seb({{ }}); - 0x18: seh({{ }}); + 0x10: seb({{ Rd.sw = /* sext32(Rt<7>,24) | */ Rt<7:0>}}); + 0x18: seh({{ Rd.sw = /* sext32(Rt<15>,16) | */ Rt<15:0>}}); } } diff --git a/arch/mips/isa/formats/branch.isa b/arch/mips/isa/formats/branch.isa index 5327f30e8..a565eb71b 100644 --- a/arch/mips/isa/formats/branch.isa +++ b/arch/mips/isa/formats/branch.isa @@ -54,13 +54,13 @@ def template BranchExecute {{ } }}; -// Primary format for integer operate instructions: -def format Branch(code, *opt_flags) {{ - orig_code = code - cblk = CodeBlock(code) - iop = InstObjParams(name, Name, 'MipsStaticInst', cblk, opt_flags) - header_output = BasicDeclare.subst(iop) - decoder_output = BasicConstructor.subst(iop) - decode_block = BasicDecodeWithMnemonic.subst(iop) - exec_output = BranchExecute.subst(iop) +def format CondBranch(code) {{ + code = 'bool cond;\n' + code + '\nif (cond) NPC = NPC + disp;\n'; + iop = InstObjParams(name, Name, 'Branch', CodeBlock(code), + ('IsDirectControl', 'IsCondControl')) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecode.subst(iop) + exec_output = BasicExecute.subst(iop) }}; + From fb10300c4f23c8f9498f805ea95590e549b35fe5 Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Thu, 9 Feb 2006 04:26:04 -0500 Subject: [PATCH 027/180] more code for instructions... Mainly for coprocessor0 and coprocessor1 move instructions --HG-- extra : convert_revision : 34e017fd0a6f330f2ac17d34af216fc14f09dd42 --- arch/mips/isa/decoder.isa | 71 ++++++++++++++++++++++++++++++++------- 1 file changed, 59 insertions(+), 12 deletions(-) diff --git a/arch/mips/isa/decoder.isa b/arch/mips/isa/decoder.isa index 54a9f1cb5..acd00e70d 100644 --- a/arch/mips/isa/decoder.isa +++ b/arch/mips/isa/decoder.isa @@ -215,19 +215,66 @@ decode OPCODE_HI default FailUnimpl::unknown() { 0x0: decode RS { format BasicOp { - 0x0: mfc0({{ }}); - 0xC: mtc0({{ }}); - 0xA: rdpgpr({{ }}); + 0x0: mfc0({{ + //The contents of the coprocessor 0 register specified by the + //combination of rd and sel are loaded into general register + //rt. Note that not all coprocessor 0 registers support the + //sel field. In those instances, the sel field must be zero. + + if (SEL > 0) + panic("Can't Handle Cop0 with register select yet\n"); + + uint64_t reg_num = Rd.uw; + + Rt = xc->miscRegs.cop0[reg_num]; + }}); + + 0xC: mtc0({{ + //The contents of the coprocessor 0 register specified by the + //combination of rd and sel are loaded into general register + //rt. Note that not all coprocessor 0 registers support the + //sel field. In those instances, the sel field must be zero. + + if (SEL > 0) + panic("Can't Handle Cop0 with register select yet\n"); + + uint64_t reg_num = Rd.uw; + + xc->miscRegs.cop0[reg_num] = Rt; + }}); + + 0xA: rdpgpr({{ + //Accessing Previous Shadow Set Register Number + uint64_t prev = xc->miscRegs.cop0[SRSCtl][PSS]; + uint64_t reg_num = Rt.uw; + + Rd = xc->shadowIntRegFile[prev][reg_num]; + }}); } 0xB: decode SC { format BasicOp { - 0x0: di({{ Rt.sw = xc->miscRegs.statusReg; statusReg[IE] = 0;}}); - 0x1: ei({{ Rt.sw = xc->miscRegs.statusReg; statusReg[IE] = 1;}}); + 0x0: di({{ + //Accessing Coprocessor 0 "Status" Register + Rt.sw = xc->miscRegs.cop0[12]; + xc->miscRegs.cop0[12][INTERRUPT_ENABLE] = 0; + }}); + + 0x1: ei({{ + //Accessing Coprocessor 0 "Status" Register + Rt.sw = xc->miscRegs.cop0[12]; + xc->miscRegs.cop0[12][INTERRUPT_ENABLE] = 1; + }}); } } - 0xE: BasicOp::wrpgpr({{ }}); + 0xE: BasicOp::wrpgpr({{ + //Accessing Previous Shadow Set Register Number + uint64_t prev = xc->miscRegs.cop0[SRSCtl][PSS]; + uint64_t reg_num = Rd.uw; + + xc->shadowIntRegFile[prev][reg_num] = Rt; + }}); } //Table A-12 MIPS32 COP0 Encoding of Function Field When rs=CO @@ -253,12 +300,12 @@ decode OPCODE_HI default FailUnimpl::unknown() { 0x0: decode RS_HI { 0x0: decode RS_LO { format FloatOp { - 0x0: mfc1({{ }}); - 0x2: cfc1({{ }}); - 0x3: mfhc1({{ }}); - 0x4: mtc1({{ }}); - 0x6: ctc1({{ }}); - 0x7: mftc1({{ }}); + 0x0: mfc1({{ Rt = Fs<31:0>; }}); + 0x2: cfc1({{ Rt = xc->miscRegs.fpcr[Fs];}}); + 0x3: mfhc1({{ Rt = Fs<63:32>;}}); + 0x4: mtc1({{ Fs<31:0> = Rt}}); + 0x6: ctc1({{ xc->miscRegs.fpcr[Fs] = Rt;}}); + 0x7: mftc1({{ Fs<63:32> = Rt}}); } } From d3c1cc9f1512260b5434d8f735662b4d9e32af53 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Thu, 9 Feb 2006 13:06:47 -0500 Subject: [PATCH 028/180] A fix for SConscript so it will work with newer versions of scons SConscript: Changed the ISAPath function to take 5 arguments to work with scons 0.97. --HG-- extra : convert_revision : 34fbe131aec9349631b5026d839563380623f3fd --- SConscript | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SConscript b/SConscript index 56a4e3610..589b2a17c 100644 --- a/SConscript +++ b/SConscript @@ -400,7 +400,7 @@ def ISAScan(): "SRCDIR", '^[ \t]*##[ \t]*include[ \t]*"([^>"]+)"') -def ISAPath(env, dir, a=None): +def ISAPath(env, dir, target=None, source=None, a=None): return (Dir(env['SRCDIR']), Dir('.')) iscan = Scanner(function = ISAScan().scan, skeys = [".isa", ".ISA"], From 7d9b93d825dccbb9eb09e76478552a5211c9b70e Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Thu, 9 Feb 2006 13:56:24 -0500 Subject: [PATCH 029/180] Changed the filenames to the new standard again arch/sparc/isa/formats.isa: Changed the file extensions to .isa again. arch/sparc/isa/main.isa: Changed the file extensions to .isa again --HG-- rename : arch/sparc/isa_desc/base.h => arch/sparc/isa/base.isa rename : arch/sparc/isa_desc/bitfields.h => arch/sparc/isa/bitfields.isa rename : arch/sparc/isa_desc/decoder.h => arch/sparc/isa/decoder.isa rename : arch/sparc/isa_desc/formats.h => arch/sparc/isa/formats.isa rename : arch/sparc/isa_desc/formats/basic.format => arch/sparc/isa/formats/basic.isa rename : arch/sparc/isa_desc/formats/branch.format => arch/sparc/isa/formats/branch.isa rename : arch/sparc/isa_desc/formats/integerop.format => arch/sparc/isa/formats/integerop.isa rename : arch/sparc/isa_desc/formats/mem.format => arch/sparc/isa/formats/mem.isa rename : arch/sparc/isa_desc/formats/noop.format => arch/sparc/isa/formats/noop.isa rename : arch/sparc/isa_desc/formats/trap.format => arch/sparc/isa/formats/trap.isa rename : arch/sparc/isa_desc/includes.h => arch/sparc/isa/includes.isa rename : arch/sparc/isa_desc/isa_desc => arch/sparc/isa/main.isa rename : arch/sparc/isa_desc/operands.h => arch/sparc/isa/operands.isa extra : convert_revision : acb087e81d06ca5d67fe9b402423d7930f6ae798 --- arch/sparc/{isa_desc/base.h => isa/base.isa} | 0 .../bitfields.h => isa/bitfields.isa} | 0 .../{isa_desc/decoder.h => isa/decoder.isa} | 0 arch/sparc/isa/formats.isa | 19 ++++++ .../basic.format => isa/formats/basic.isa} | 0 .../branch.format => isa/formats/branch.isa} | 0 .../formats/integerop.isa} | 0 .../mem.format => isa/formats/mem.isa} | 0 .../noop.format => isa/formats/noop.isa} | 0 .../trap.format => isa/formats/trap.isa} | 0 .../{isa_desc/includes.h => isa/includes.isa} | 0 arch/sparc/isa/main.isa | 52 ++++++++++++++++ .../{isa_desc/operands.h => isa/operands.isa} | 0 arch/sparc/isa_desc/formats.h | 19 ------ arch/sparc/isa_desc/isa_desc | 61 ------------------- 15 files changed, 71 insertions(+), 80 deletions(-) rename arch/sparc/{isa_desc/base.h => isa/base.isa} (100%) rename arch/sparc/{isa_desc/bitfields.h => isa/bitfields.isa} (100%) rename arch/sparc/{isa_desc/decoder.h => isa/decoder.isa} (100%) create mode 100644 arch/sparc/isa/formats.isa rename arch/sparc/{isa_desc/formats/basic.format => isa/formats/basic.isa} (100%) rename arch/sparc/{isa_desc/formats/branch.format => isa/formats/branch.isa} (100%) rename arch/sparc/{isa_desc/formats/integerop.format => isa/formats/integerop.isa} (100%) rename arch/sparc/{isa_desc/formats/mem.format => isa/formats/mem.isa} (100%) rename arch/sparc/{isa_desc/formats/noop.format => isa/formats/noop.isa} (100%) rename arch/sparc/{isa_desc/formats/trap.format => isa/formats/trap.isa} (100%) rename arch/sparc/{isa_desc/includes.h => isa/includes.isa} (100%) create mode 100644 arch/sparc/isa/main.isa rename arch/sparc/{isa_desc/operands.h => isa/operands.isa} (100%) delete mode 100644 arch/sparc/isa_desc/formats.h delete mode 100644 arch/sparc/isa_desc/isa_desc diff --git a/arch/sparc/isa_desc/base.h b/arch/sparc/isa/base.isa similarity index 100% rename from arch/sparc/isa_desc/base.h rename to arch/sparc/isa/base.isa diff --git a/arch/sparc/isa_desc/bitfields.h b/arch/sparc/isa/bitfields.isa similarity index 100% rename from arch/sparc/isa_desc/bitfields.h rename to arch/sparc/isa/bitfields.isa diff --git a/arch/sparc/isa_desc/decoder.h b/arch/sparc/isa/decoder.isa similarity index 100% rename from arch/sparc/isa_desc/decoder.h rename to arch/sparc/isa/decoder.isa diff --git a/arch/sparc/isa/formats.isa b/arch/sparc/isa/formats.isa new file mode 100644 index 000000000..a21e1c110 --- /dev/null +++ b/arch/sparc/isa/formats.isa @@ -0,0 +1,19 @@ +//Include the basic format +//Templates from this format are used later +##include "m5/arch/sparc/isa_desc/formats/basic.isa" + +//Include the integerOp and integerOpCc format +##include "m5/arch/sparc/isa_desc/formats/integerop.isa" + +//Include the mem format +##include "m5/arch/sparc/isa_desc/formats/mem.isa" + +//Include the trap format +##include "m5/arch/sparc/isa_desc/formats/trap.isa" + +//Include the branch format +##include "m5/arch/sparc/isa_desc/formats/branch.isa" + +//Include the noop format +##include "m5/arch/sparc/isa_desc/formats/noop.isa" + diff --git a/arch/sparc/isa_desc/formats/basic.format b/arch/sparc/isa/formats/basic.isa similarity index 100% rename from arch/sparc/isa_desc/formats/basic.format rename to arch/sparc/isa/formats/basic.isa diff --git a/arch/sparc/isa_desc/formats/branch.format b/arch/sparc/isa/formats/branch.isa similarity index 100% rename from arch/sparc/isa_desc/formats/branch.format rename to arch/sparc/isa/formats/branch.isa diff --git a/arch/sparc/isa_desc/formats/integerop.format b/arch/sparc/isa/formats/integerop.isa similarity index 100% rename from arch/sparc/isa_desc/formats/integerop.format rename to arch/sparc/isa/formats/integerop.isa diff --git a/arch/sparc/isa_desc/formats/mem.format b/arch/sparc/isa/formats/mem.isa similarity index 100% rename from arch/sparc/isa_desc/formats/mem.format rename to arch/sparc/isa/formats/mem.isa diff --git a/arch/sparc/isa_desc/formats/noop.format b/arch/sparc/isa/formats/noop.isa similarity index 100% rename from arch/sparc/isa_desc/formats/noop.format rename to arch/sparc/isa/formats/noop.isa diff --git a/arch/sparc/isa_desc/formats/trap.format b/arch/sparc/isa/formats/trap.isa similarity index 100% rename from arch/sparc/isa_desc/formats/trap.format rename to arch/sparc/isa/formats/trap.isa diff --git a/arch/sparc/isa_desc/includes.h b/arch/sparc/isa/includes.isa similarity index 100% rename from arch/sparc/isa_desc/includes.h rename to arch/sparc/isa/includes.isa diff --git a/arch/sparc/isa/main.isa b/arch/sparc/isa/main.isa new file mode 100644 index 000000000..8b6166d34 --- /dev/null +++ b/arch/sparc/isa/main.isa @@ -0,0 +1,52 @@ +// -*- mode:c++ -*- + +// 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 "m5/arch/sparc/isa_desc/includes.isa" + +//////////////////////////////////////////////////////////////////// +// +// Namespace statement. Everything below this line will be in the +// SparcISAInst namespace. +// + +namespace SparcISA; + +//Include the bitfield definitions +##include "m5/arch/sparc/isa_desc/bitfields.isa" + +//Include the operand_types and operand definitions +##include "m5/arch/sparc/isa_desc/operands.isa" + +//Include the base class for sparc instructions, and some support code +##include "m5/arch/sparc/isa_desc/base.isa" + +//Include the definitions for the instruction formats +##include "m5/arch/sparc/isa_desc/formats.isa" + +//Include the decoder definition +##include "m5/arch/sparc/isa_desc/decoder.isa" diff --git a/arch/sparc/isa_desc/operands.h b/arch/sparc/isa/operands.isa similarity index 100% rename from arch/sparc/isa_desc/operands.h rename to arch/sparc/isa/operands.isa diff --git a/arch/sparc/isa_desc/formats.h b/arch/sparc/isa_desc/formats.h deleted file mode 100644 index 733a093f5..000000000 --- a/arch/sparc/isa_desc/formats.h +++ /dev/null @@ -1,19 +0,0 @@ -//Include the basic format -//Templates from this format are used later -##include "m5/arch/sparc/isa_desc/formats/basic.format" - -//Include the integerOp and integerOpCc format -##include "m5/arch/sparc/isa_desc/formats/integerop.format" - -//Include the mem format -##include "m5/arch/sparc/isa_desc/formats/mem.format" - -//Include the trap format -##include "m5/arch/sparc/isa_desc/formats/trap.format" - -//Include the branch format -##include "m5/arch/sparc/isa_desc/formats/branch.format" - -//Include the noop format -##include "m5/arch/sparc/isa_desc/formats/noop.format" - diff --git a/arch/sparc/isa_desc/isa_desc b/arch/sparc/isa_desc/isa_desc deleted file mode 100644 index 1a5cc4a56..000000000 --- a/arch/sparc/isa_desc/isa_desc +++ /dev/null @@ -1,61 +0,0 @@ -// -*- mode:c++ -*- - -//Copyright (c) 2003, 2004, 2005 -//The Regents of The University of Michigan -//All Rights Reserved - -//This code is part of the M5 simulator, developed by Nathan Binkert, -//Erik Hallnor, Steve Raasch, and Steve Reinhardt, with contributions -//from Ron Dreslinski, Dave Greene, Lisa Hsu, Kevin Lim, Ali Saidi, -//and Andrew Schultz. - -//Permission is granted to use, copy, create derivative works and -//redistribute this software and such derivative works for any purpose, -//so long as the copyright notice above, this grant of permission, and -//the disclaimer below appear in all copies made; and so long as the -//name of The University of Michigan is not used in any advertising or -//publicity pertaining to the use or distribution of this software -//without specific, written prior authorization. - -//THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION FROM THE -//UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY PURPOSE, AND WITHOUT -//WARRANTY BY THE UNIVERSITY OF MICHIGAN OF ANY KIND, EITHER EXPRESS OR -//IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED WARRANTIES OF -//MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE REGENTS OF -//THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE FOR ANY DAMAGES, -//INCLUDING DIRECT, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL -//DAMAGES, WITH RESPECT TO ANY CLAIM ARISING OUT OF OR IN CONNECTION -//WITH THE USE OF THE SOFTWARE, EVEN IF IT HAS BEEN OR IS HEREAFTER -//ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - -//////////////////////////////////////////////////////////////////// -// -// SPARC ISA description file. -// -//////////////////////////////////////////////////////////////////// - -//Include the C++ include directives -##include "m5/arch/sparc/isa_desc/includes.h" - -//////////////////////////////////////////////////////////////////// -// -// Namespace statement. Everything below this line will be in the -// SparcISAInst namespace. -// - -namespace SparcISA; - -//Include the bitfield definitions -##include "m5/arch/sparc/isa_desc/bitfields.h" - -//Include the operand_types and operand definitions -##include "m5/arch/sparc/isa_desc/operands.h" - -//Include the base class for sparc instructions, and some support code -##include "m5/arch/sparc/isa_desc/base.h" - -//Include the definitions for the instruction formats -##include "m5/arch/sparc/isa_desc/formats.h" - -//Include the decoder definition -##include "m5/arch/sparc/isa_desc/decoder.h" From 879aaa55691285403d47e5891b79399974f6f221 Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Thu, 9 Feb 2006 14:51:37 -0500 Subject: [PATCH 030/180] Change how isa_parser.py generates C++ names for isa_desc operands. arch/isa_parser.py: Get rid of "munged name" for operands in C++ code. That is, "Ra.uq" will now be known in the C++ as "Ra" rather than "Ra_uq". It wasn't legal to use different type extensions for the same operand at the same time anyway, and now it will be easier to refer to explicit operands in template code if necessary. --HG-- extra : convert_revision : 9ff41e0201aeefe761743084ecdb34f4b9c84fdb --- arch/isa_parser.py | 47 ++++++++++++++++++++++------------------------ 1 file changed, 22 insertions(+), 25 deletions(-) diff --git a/arch/isa_parser.py b/arch/isa_parser.py index 8f4c6bce7..bf8b31090 100755 --- a/arch/isa_parser.py +++ b/arch/isa_parser.py @@ -1045,7 +1045,7 @@ class OperandTraits: (size, type, is_signed) = operandSizeMap[op_desc.eff_ext] # Note that initializations in the declarations are solely # to avoid 'uninitialized variable' errors from the compiler. - return type + ' ' + op_desc.munged_name + ' = 0;\n'; + return type + ' ' + op_desc.base_name + ' = 0;\n'; class IntRegOperandTraits(OperandTraits): def isReg(self): @@ -1070,19 +1070,19 @@ class IntRegOperandTraits(OperandTraits): error(0, 'Attempt to read integer register as FP') if (size == self.dflt_size): return '%s = xc->readIntReg(this, %d);\n' % \ - (op_desc.munged_name, op_desc.src_reg_idx) + (op_desc.base_name, op_desc.src_reg_idx) else: return '%s = bits(xc->readIntReg(this, %d), %d, 0);\n' % \ - (op_desc.munged_name, op_desc.src_reg_idx, size-1) + (op_desc.base_name, op_desc.src_reg_idx, size-1) def makeWrite(self, op_desc): (size, type, is_signed) = operandSizeMap[op_desc.eff_ext] if (type == 'float' or type == 'double'): error(0, 'Attempt to write integer register as FP') if (size != self.dflt_size and is_signed): - final_val = 'sext<%d>(%s)' % (size, op_desc.munged_name) + final_val = 'sext<%d>(%s)' % (size, op_desc.base_name) else: - final_val = op_desc.munged_name + final_val = op_desc.base_name wb = ''' { %s final_val = %s; @@ -1123,13 +1123,13 @@ class FloatRegOperandTraits(OperandTraits): (func, op_desc.src_reg_idx) if bit_select: return '%s = bits(%s, %d, 0);\n' % \ - (op_desc.munged_name, base, size-1) + (op_desc.base_name, base, size-1) else: - return '%s = %s;\n' % (op_desc.munged_name, base) + return '%s = %s;\n' % (op_desc.base_name, base) def makeWrite(self, op_desc): (size, type, is_signed) = operandSizeMap[op_desc.eff_ext] - final_val = op_desc.munged_name + final_val = op_desc.base_name if (type == 'float'): func = 'setFloatRegSingle' elif (type == 'double'): @@ -1138,7 +1138,7 @@ class FloatRegOperandTraits(OperandTraits): func = 'setFloatRegInt' type = 'uint%d_t' % self.dflt_size if (size != self.dflt_size and is_signed): - final_val = 'sext<%d>(%s)' % (size, op_desc.munged_name) + final_val = 'sext<%d>(%s)' % (size, op_desc.base_name) wb = ''' { %s final_val = %s; @@ -1171,18 +1171,18 @@ class ControlRegOperandTraits(OperandTraits): error(0, 'Attempt to read control register as FP') base = 'xc->read%s()' % self.reg_spec if size == self.dflt_size: - return '%s = %s;\n' % (op_desc.munged_name, base) + return '%s = %s;\n' % (op_desc.base_name, base) else: return '%s = bits(%s, %d, 0);\n' % \ - (op_desc.munged_name, base, size-1) + (op_desc.base_name, base, size-1) def makeWrite(self, op_desc): (size, type, is_signed) = operandSizeMap[op_desc.eff_ext] if (type == 'float' or type == 'double'): error(0, 'Attempt to write control register as FP') - wb = 'xc->set%s(%s);\n' % (self.reg_spec, op_desc.munged_name) + wb = 'xc->set%s(%s);\n' % (self.reg_spec, op_desc.base_name) wb += 'if (traceData) { traceData->setData(%s); }' % \ - op_desc.munged_name + op_desc.base_name return wb class MemOperandTraits(OperandTraits): @@ -1197,7 +1197,7 @@ class MemOperandTraits(OperandTraits): # Note that initializations in the declarations are solely # to avoid 'uninitialized variable' errors from the compiler. # Declare memory data variable. - c = '%s %s = 0;\n' % (type, op_desc.munged_name) + c = '%s %s = 0;\n' % (type, op_desc.base_name) # Declare var to hold memory access flags. c += 'unsigned %s_flags = memAccessFlags;\n' % op_desc.base_name # If this operand is a dest (i.e., it's a store operation), @@ -1211,16 +1211,16 @@ class MemOperandTraits(OperandTraits): (size, type, is_signed) = operandSizeMap[op_desc.eff_ext] eff_type = 'uint%d_t' % size return 'fault = xc->read(EA, (%s&)%s, %s_flags);\n' \ - % (eff_type, op_desc.munged_name, op_desc.base_name) + % (eff_type, op_desc.base_name, op_desc.base_name) def makeWrite(self, op_desc): (size, type, is_signed) = operandSizeMap[op_desc.eff_ext] eff_type = 'uint%d_t' % size wb = 'fault = xc->write((%s&)%s, EA, %s_flags, &%s_write_result);\n' \ - % (eff_type, op_desc.munged_name, op_desc.base_name, + % (eff_type, op_desc.base_name, op_desc.base_name, op_desc.base_name) wb += 'if (traceData) { traceData->setData(%s); }' % \ - op_desc.munged_name + op_desc.base_name return wb class NPCOperandTraits(OperandTraits): @@ -1228,10 +1228,10 @@ class NPCOperandTraits(OperandTraits): return '' def makeRead(self, op_desc): - return '%s = xc->readPC() + 4;\n' % op_desc.munged_name + return '%s = xc->readPC() + 4;\n' % op_desc.base_name def makeWrite(self, op_desc): - return 'xc->setNextPC(%s);\n' % op_desc.munged_name + return 'xc->setNextPC(%s);\n' % op_desc.base_name exportContextSymbols = ('IntRegOperandTraits', 'FloatRegOperandTraits', @@ -1294,14 +1294,10 @@ class OperandDescriptor: self.traits = operandTraitsMap[base_name] # The 'effective extension' (eff_ext) is either the actual # extension, if one was explicitly provided, or the default. - # The 'munged name' replaces the '.' between the base and - # extension (if any) with a '_' to make a legal C++ variable name. if ext: self.eff_ext = ext - self.munged_name = base_name + '_' + ext else: self.eff_ext = self.traits.dflt_ext - self.munged_name = base_name # Finalize additional fields (primarily code fields). This step # is done separately since some of these fields may depend on the @@ -1444,9 +1440,10 @@ def findOperands(code): return operands # Munge operand names in code string to make legal C++ variable names. -# (Will match munged_name attribute of OperandDescriptor object.) +# This means getting rid of the type extension if any. +# (Will match base_name attribute of OperandDescriptor object.) def substMungedOpNames(code): - return operandsWithExtRE.sub(r'\1_\2', code) + return operandsWithExtRE.sub(r'\1', code) def joinLists(t): return map(string.join, t) From fb90b1dd13fb6c0090bfe2731ca9ccee56479761 Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Thu, 9 Feb 2006 22:27:41 -0500 Subject: [PATCH 031/180] Minor cleanup of include-handling code in isa_parser.py. arch/isa_parser.py: Clean up ##include code a bit. arch/sparc/isa/formats.isa: arch/sparc/isa/main.isa: Fix include paths. --HG-- extra : convert_revision : 0689963c2948e5f1088ecbf2cf6018d29bdaceff --- arch/isa_parser.py | 32 ++++++++++++++++++-------------- arch/sparc/isa/formats.isa | 12 ++++++------ arch/sparc/isa/main.isa | 12 ++++++------ 3 files changed, 30 insertions(+), 26 deletions(-) diff --git a/arch/isa_parser.py b/arch/isa_parser.py index fc6880877..b12329ebb 100755 --- a/arch/isa_parser.py +++ b/arch/isa_parser.py @@ -162,7 +162,7 @@ def t_CPPDIRECTIVE(t): return t def t_NEWFILE(t): - r'^\#\#newfile[ /t]*\"[A-Za-z0-9\\/-_.]*\"' + r'^\#\#newfile\s+"[\w/.-]*"' global fileNameStack fileNameStack.append((t.value[11:-1], t.lineno)) t.lineno = 0 @@ -841,7 +841,7 @@ defaultStack = Stack( None ) # Used to make nested code blocks look pretty. # def indent(s): - return re.sub(r'(?m)^(?!\#)', ' ', s) + return re.sub(r'(?m)^(?!#)', ' ', s) # # Munge a somewhat arbitrarily formatted piece of Python code @@ -870,7 +870,6 @@ def fixPythonIndentation(s): # Error handler. Just call exit. Output formatted to work under # Emacs compile-mode. def error(lineno, string): - global fileNameStack spaces = "" for (filename, line) in fileNameStack[0:-1]: print spaces + "In file included from " + filename @@ -1622,24 +1621,29 @@ def update_if_needed(file, contents): f.close() # This regular expression matches include directives -regExp = re.compile('(?P^[ \t]*##include[ \t]*\"[ \t]*(?P[A-Za-z0-9\\/-_.]*)[ \t]*\"[ \t]*\n)', re.MULTILINE) +includeRE = re.compile(r'^\s*##include\s+"(?P[\w/.-]*)".*$', + re.MULTILINE) def preprocess_isa_desc(isa_desc): # Find any includes and include them - - # Look for an include - m = re.search(regExp, isa_desc) - while m: + pos = 0 + while 1: + m = includeRE.search(isa_desc, pos) + if not m: + break filename = m.group('filename') print 'Including file "%s"' % filename - includeFile = open(filename) - includecontents = includeFile.read() - isa_desc = isa_desc[:m.start('include')] + '##newfile "' + filename + '"\n' + includecontents + '##endfile\n' + isa_desc[m.end('include'):] - # Look for the next include - m = re.search(regExp, isa_desc) + try: + isa_desc = isa_desc[:m.start()] + \ + '##newfile "' + filename + '"\n' + \ + open(filename).read() + \ + '##endfile\n' + \ + isa_desc[m.end():] + except IOError: + error(0, 'Error including file "%s"' % (filename)) + pos = m.start() return isa_desc - # # Read in and parse the ISA description. # diff --git a/arch/sparc/isa/formats.isa b/arch/sparc/isa/formats.isa index a21e1c110..547f8be48 100644 --- a/arch/sparc/isa/formats.isa +++ b/arch/sparc/isa/formats.isa @@ -1,19 +1,19 @@ //Include the basic format //Templates from this format are used later -##include "m5/arch/sparc/isa_desc/formats/basic.isa" +##include "m5/arch/sparc/isa/formats/basic.isa" //Include the integerOp and integerOpCc format -##include "m5/arch/sparc/isa_desc/formats/integerop.isa" +##include "m5/arch/sparc/isa/formats/integerop.isa" //Include the mem format -##include "m5/arch/sparc/isa_desc/formats/mem.isa" +##include "m5/arch/sparc/isa/formats/mem.isa" //Include the trap format -##include "m5/arch/sparc/isa_desc/formats/trap.isa" +##include "m5/arch/sparc/isa/formats/trap.isa" //Include the branch format -##include "m5/arch/sparc/isa_desc/formats/branch.isa" +##include "m5/arch/sparc/isa/formats/branch.isa" //Include the noop format -##include "m5/arch/sparc/isa_desc/formats/noop.isa" +##include "m5/arch/sparc/isa/formats/noop.isa" diff --git a/arch/sparc/isa/main.isa b/arch/sparc/isa/main.isa index 8b6166d34..ab0290d58 100644 --- a/arch/sparc/isa/main.isa +++ b/arch/sparc/isa/main.isa @@ -26,7 +26,7 @@ // (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 "m5/arch/sparc/isa_desc/includes.isa" +##include "m5/arch/sparc/isa/includes.isa" //////////////////////////////////////////////////////////////////// // @@ -37,16 +37,16 @@ namespace SparcISA; //Include the bitfield definitions -##include "m5/arch/sparc/isa_desc/bitfields.isa" +##include "m5/arch/sparc/isa/bitfields.isa" //Include the operand_types and operand definitions -##include "m5/arch/sparc/isa_desc/operands.isa" +##include "m5/arch/sparc/isa/operands.isa" //Include the base class for sparc instructions, and some support code -##include "m5/arch/sparc/isa_desc/base.isa" +##include "m5/arch/sparc/isa/base.isa" //Include the definitions for the instruction formats -##include "m5/arch/sparc/isa_desc/formats.isa" +##include "m5/arch/sparc/isa/formats.isa" //Include the decoder definition -##include "m5/arch/sparc/isa_desc/decoder.isa" +##include "m5/arch/sparc/isa/decoder.isa" From dd473ecd578a1bb21d2b6420f3944065a3539ffa Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Thu, 9 Feb 2006 23:02:38 -0500 Subject: [PATCH 032/180] Split Alpha ISA description into multiple files (thanks to Gabe's include feature!). arch/alpha/isa/main.isa: Split out into multiple .isa files. --HG-- extra : convert_revision : 30d8edf74ea194d4a208febf1e66edc72a7dbd5d --- arch/alpha/isa/branch.isa | 259 ++++ arch/alpha/isa/decoder.isa | 799 +++++++++++++ arch/alpha/isa/fp.isa | 300 +++++ arch/alpha/isa/int.isa | 128 ++ arch/alpha/isa/main.isa | 2326 +----------------------------------- arch/alpha/isa/mem.isa | 441 +++++++ arch/alpha/isa/pal.isa | 260 ++++ arch/alpha/isa/unimp.isa | 165 +++ arch/alpha/isa/unknown.isa | 52 + arch/alpha/isa/util.isa | 112 ++ 10 files changed, 2534 insertions(+), 2308 deletions(-) create mode 100644 arch/alpha/isa/branch.isa create mode 100644 arch/alpha/isa/decoder.isa create mode 100644 arch/alpha/isa/fp.isa create mode 100644 arch/alpha/isa/int.isa create mode 100644 arch/alpha/isa/mem.isa create mode 100644 arch/alpha/isa/pal.isa create mode 100644 arch/alpha/isa/unimp.isa create mode 100644 arch/alpha/isa/unknown.isa create mode 100644 arch/alpha/isa/util.isa diff --git a/arch/alpha/isa/branch.isa b/arch/alpha/isa/branch.isa new file mode 100644 index 000000000..e9c790c53 --- /dev/null +++ b/arch/alpha/isa/branch.isa @@ -0,0 +1,259 @@ +// -*- mode:c++ -*- + +// 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. + +output header {{ + + /** + * Base class for instructions whose disassembly is not purely a + * function of the machine instruction (i.e., it depends on the + * PC). This class overrides the disassemble() method to check + * the PC and symbol table values before re-using a cached + * disassembly string. This is necessary for branches and jumps, + * where the disassembly string includes the target address (which + * may depend on the PC and/or symbol table). + */ + class PCDependentDisassembly : public AlphaStaticInst + { + protected: + /// Cached program counter from last disassembly + mutable Addr cachedPC; + /// Cached symbol table pointer from last disassembly + mutable const SymbolTable *cachedSymtab; + + /// Constructor + PCDependentDisassembly(const char *mnem, MachInst _machInst, + OpClass __opClass) + : AlphaStaticInst(mnem, _machInst, __opClass), + cachedPC(0), cachedSymtab(0) + { + } + + const std::string & + disassemble(Addr pc, const SymbolTable *symtab) const; + }; + + /** + * Base class for branches (PC-relative control transfers), + * conditional or unconditional. + */ + class Branch : public PCDependentDisassembly + { + protected: + /// Displacement to target address (signed). + int32_t disp; + + /// Constructor. + Branch(const char *mnem, MachInst _machInst, OpClass __opClass) + : PCDependentDisassembly(mnem, _machInst, __opClass), + disp(BRDISP << 2) + { + } + + Addr branchTarget(Addr branchPC) const; + + std::string + generateDisassembly(Addr pc, const SymbolTable *symtab) const; + }; + + /** + * Base class for jumps (register-indirect control transfers). In + * the Alpha ISA, these are always unconditional. + */ + class Jump : public PCDependentDisassembly + { + protected: + + /// Displacement to target address (signed). + int32_t disp; + + public: + /// Constructor + Jump(const char *mnem, MachInst _machInst, OpClass __opClass) + : PCDependentDisassembly(mnem, _machInst, __opClass), + disp(BRDISP) + { + } + + Addr branchTarget(ExecContext *xc) const; + + std::string + generateDisassembly(Addr pc, const SymbolTable *symtab) const; + }; +}}; + +output decoder {{ + Addr + Branch::branchTarget(Addr branchPC) const + { + return branchPC + 4 + disp; + } + + Addr + Jump::branchTarget(ExecContext *xc) const + { + Addr NPC = xc->readPC() + 4; + uint64_t Rb = xc->readIntReg(_srcRegIdx[0]); + return (Rb & ~3) | (NPC & 1); + } + + const std::string & + PCDependentDisassembly::disassemble(Addr pc, + const SymbolTable *symtab) const + { + if (!cachedDisassembly || + pc != cachedPC || symtab != cachedSymtab) + { + if (cachedDisassembly) + delete cachedDisassembly; + + cachedDisassembly = + new std::string(generateDisassembly(pc, symtab)); + cachedPC = pc; + cachedSymtab = symtab; + } + + return *cachedDisassembly; + } + + std::string + Branch::generateDisassembly(Addr pc, const SymbolTable *symtab) const + { + std::stringstream ss; + + ccprintf(ss, "%-10s ", mnemonic); + + // There's only one register arg (RA), but it could be + // either a source (the condition for conditional + // branches) or a destination (the link reg for + // unconditional branches) + if (_numSrcRegs > 0) { + printReg(ss, _srcRegIdx[0]); + ss << ","; + } + else if (_numDestRegs > 0) { + printReg(ss, _destRegIdx[0]); + ss << ","; + } + +#ifdef SS_COMPATIBLE_DISASSEMBLY + if (_numSrcRegs == 0 && _numDestRegs == 0) { + printReg(ss, 31); + ss << ","; + } +#endif + + Addr target = pc + 4 + disp; + + std::string str; + if (symtab && symtab->findSymbol(target, str)) + ss << str; + else + ccprintf(ss, "0x%x", target); + + return ss.str(); + } + + std::string + Jump::generateDisassembly(Addr pc, const SymbolTable *symtab) const + { + std::stringstream ss; + + ccprintf(ss, "%-10s ", mnemonic); + +#ifdef SS_COMPATIBLE_DISASSEMBLY + if (_numDestRegs == 0) { + printReg(ss, 31); + ss << ","; + } +#endif + + if (_numDestRegs > 0) { + printReg(ss, _destRegIdx[0]); + ss << ","; + } + + ccprintf(ss, "(r%d)", RB); + + return ss.str(); + } +}}; + +def template JumpOrBranchDecode {{ + return (RA == 31) + ? (StaticInst *)new %(class_name)s(machInst) + : (StaticInst *)new %(class_name)sAndLink(machInst); +}}; + +def format CondBranch(code) {{ + code = 'bool cond;\n' + code + '\nif (cond) NPC = NPC + disp;\n'; + iop = InstObjParams(name, Name, 'Branch', CodeBlock(code), + ('IsDirectControl', 'IsCondControl')) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecode.subst(iop) + exec_output = BasicExecute.subst(iop) +}}; + +let {{ +def UncondCtrlBase(name, Name, base_class, npc_expr, flags): + # Declare basic control transfer w/o link (i.e. link reg is R31) + nolink_code = 'NPC = %s;\n' % npc_expr + nolink_iop = InstObjParams(name, Name, base_class, + CodeBlock(nolink_code), flags) + header_output = BasicDeclare.subst(nolink_iop) + decoder_output = BasicConstructor.subst(nolink_iop) + exec_output = BasicExecute.subst(nolink_iop) + + # Generate declaration of '*AndLink' version, append to decls + link_code = 'Ra = NPC & ~3;\n' + nolink_code + link_iop = InstObjParams(name, Name + 'AndLink', base_class, + CodeBlock(link_code), flags) + header_output += BasicDeclare.subst(link_iop) + decoder_output += BasicConstructor.subst(link_iop) + exec_output += BasicExecute.subst(link_iop) + + # need to use link_iop for the decode template since it is expecting + # the shorter version of class_name (w/o "AndLink") + + return (header_output, decoder_output, + JumpOrBranchDecode.subst(nolink_iop), exec_output) +}}; + +def format UncondBranch(*flags) {{ + flags += ('IsUncondControl', 'IsDirectControl') + (header_output, decoder_output, decode_block, exec_output) = \ + UncondCtrlBase(name, Name, 'Branch', 'NPC + disp', flags) +}}; + +def format Jump(*flags) {{ + flags += ('IsUncondControl', 'IsIndirectControl') + (header_output, decoder_output, decode_block, exec_output) = \ + UncondCtrlBase(name, Name, 'Jump', '(Rb & ~3) | (NPC & 1)', flags) +}}; + + diff --git a/arch/alpha/isa/decoder.isa b/arch/alpha/isa/decoder.isa new file mode 100644 index 000000000..6a35fa229 --- /dev/null +++ b/arch/alpha/isa/decoder.isa @@ -0,0 +1,799 @@ +// -*- mode:c++ -*- + +// 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. + +decode OPCODE default Unknown::unknown() { + + format LoadAddress { + 0x08: lda({{ Ra = Rb + disp; }}); + 0x09: ldah({{ Ra = Rb + (disp << 16); }}); + } + + format LoadOrNop { + 0x0a: ldbu({{ EA = Rb + disp; }}, {{ Ra.uq = Mem.ub; }}); + 0x0c: ldwu({{ EA = Rb + disp; }}, {{ Ra.uq = Mem.uw; }}); + 0x0b: ldq_u({{ EA = (Rb + disp) & ~7; }}, {{ Ra = Mem.uq; }}); + 0x23: ldt({{ EA = Rb + disp; }}, {{ Fa = Mem.df; }}); + 0x2a: ldl_l({{ EA = Rb + disp; }}, {{ Ra.sl = Mem.sl; }}, LOCKED); + 0x2b: ldq_l({{ EA = Rb + disp; }}, {{ Ra.uq = Mem.uq; }}, LOCKED); + 0x20: copy_load({{EA = Ra;}}, + {{fault = xc->copySrcTranslate(EA);}}, + IsMemRef, IsLoad, IsCopy); + } + + format LoadOrPrefetch { + 0x28: ldl({{ EA = Rb + disp; }}, {{ Ra.sl = Mem.sl; }}); + 0x29: ldq({{ EA = Rb + disp; }}, {{ Ra.uq = Mem.uq; }}, EVICT_NEXT); + // IsFloating flag on lds gets the prefetch to disassemble + // using f31 instead of r31... funcitonally it's unnecessary + 0x22: lds({{ EA = Rb + disp; }}, {{ Fa.uq = s_to_t(Mem.ul); }}, + PF_EXCLUSIVE, IsFloating); + } + + format Store { + 0x0e: stb({{ EA = Rb + disp; }}, {{ Mem.ub = Ra<7:0>; }}); + 0x0d: stw({{ EA = Rb + disp; }}, {{ Mem.uw = Ra<15:0>; }}); + 0x2c: stl({{ EA = Rb + disp; }}, {{ Mem.ul = Ra<31:0>; }}); + 0x2d: stq({{ EA = Rb + disp; }}, {{ Mem.uq = Ra.uq; }}); + 0x0f: stq_u({{ EA = (Rb + disp) & ~7; }}, {{ Mem.uq = Ra.uq; }}); + 0x26: sts({{ EA = Rb + disp; }}, {{ Mem.ul = t_to_s(Fa.uq); }}); + 0x27: stt({{ EA = Rb + disp; }}, {{ Mem.df = Fa; }}); + 0x24: copy_store({{EA = Rb;}}, + {{fault = xc->copy(EA);}}, + IsMemRef, IsStore, IsCopy); + } + + format StoreCond { + 0x2e: stl_c({{ EA = Rb + disp; }}, {{ Mem.ul = Ra<31:0>; }}, + {{ + uint64_t tmp = Mem_write_result; + // see stq_c + Ra = (tmp == 0 || tmp == 1) ? tmp : Ra; + }}, LOCKED); + 0x2f: stq_c({{ EA = Rb + disp; }}, {{ Mem.uq = Ra; }}, + {{ + uint64_t tmp = Mem_write_result; + // If the write operation returns 0 or 1, then + // this was a conventional store conditional, + // and the value indicates the success/failure + // of the operation. If another value is + // returned, then this was a Turbolaser + // mailbox access, and we don't update the + // result register at all. + Ra = (tmp == 0 || tmp == 1) ? tmp : Ra; + }}, LOCKED); + } + + format IntegerOperate { + + 0x10: decode INTFUNC { // integer arithmetic operations + + 0x00: addl({{ Rc.sl = Ra.sl + Rb_or_imm.sl; }}); + 0x40: addlv({{ + uint32_t tmp = Ra.sl + Rb_or_imm.sl; + // signed overflow occurs when operands have same sign + // and sign of result does not match. + if (Ra.sl<31:> == Rb_or_imm.sl<31:> && tmp<31:> != Ra.sl<31:>) + fault = Integer_Overflow_Fault; + Rc.sl = tmp; + }}); + 0x02: s4addl({{ Rc.sl = (Ra.sl << 2) + Rb_or_imm.sl; }}); + 0x12: s8addl({{ Rc.sl = (Ra.sl << 3) + Rb_or_imm.sl; }}); + + 0x20: addq({{ Rc = Ra + Rb_or_imm; }}); + 0x60: addqv({{ + uint64_t tmp = Ra + Rb_or_imm; + // signed overflow occurs when operands have same sign + // and sign of result does not match. + if (Ra<63:> == Rb_or_imm<63:> && tmp<63:> != Ra<63:>) + fault = Integer_Overflow_Fault; + Rc = tmp; + }}); + 0x22: s4addq({{ Rc = (Ra << 2) + Rb_or_imm; }}); + 0x32: s8addq({{ Rc = (Ra << 3) + Rb_or_imm; }}); + + 0x09: subl({{ Rc.sl = Ra.sl - Rb_or_imm.sl; }}); + 0x49: sublv({{ + uint32_t tmp = Ra.sl - Rb_or_imm.sl; + // signed overflow detection is same as for add, + // except we need to look at the *complemented* + // sign bit of the subtrahend (Rb), i.e., if the initial + // signs are the *same* then no overflow can occur + if (Ra.sl<31:> != Rb_or_imm.sl<31:> && tmp<31:> != Ra.sl<31:>) + fault = Integer_Overflow_Fault; + Rc.sl = tmp; + }}); + 0x0b: s4subl({{ Rc.sl = (Ra.sl << 2) - Rb_or_imm.sl; }}); + 0x1b: s8subl({{ Rc.sl = (Ra.sl << 3) - Rb_or_imm.sl; }}); + + 0x29: subq({{ Rc = Ra - Rb_or_imm; }}); + 0x69: subqv({{ + uint64_t tmp = Ra - Rb_or_imm; + // signed overflow detection is same as for add, + // except we need to look at the *complemented* + // sign bit of the subtrahend (Rb), i.e., if the initial + // signs are the *same* then no overflow can occur + if (Ra<63:> != Rb_or_imm<63:> && tmp<63:> != Ra<63:>) + fault = Integer_Overflow_Fault; + Rc = tmp; + }}); + 0x2b: s4subq({{ Rc = (Ra << 2) - Rb_or_imm; }}); + 0x3b: s8subq({{ Rc = (Ra << 3) - Rb_or_imm; }}); + + 0x2d: cmpeq({{ Rc = (Ra == Rb_or_imm); }}); + 0x6d: cmple({{ Rc = (Ra.sq <= Rb_or_imm.sq); }}); + 0x4d: cmplt({{ Rc = (Ra.sq < Rb_or_imm.sq); }}); + 0x3d: cmpule({{ Rc = (Ra.uq <= Rb_or_imm.uq); }}); + 0x1d: cmpult({{ Rc = (Ra.uq < Rb_or_imm.uq); }}); + + 0x0f: cmpbge({{ + int hi = 7; + int lo = 0; + uint64_t tmp = 0; + for (int i = 0; i < 8; ++i) { + tmp |= (Ra.uq >= Rb_or_imm.uq) << i; + hi += 8; + lo += 8; + } + Rc = tmp; + }}); + } + + 0x11: decode INTFUNC { // integer logical operations + + 0x00: and({{ Rc = Ra & Rb_or_imm; }}); + 0x08: bic({{ Rc = Ra & ~Rb_or_imm; }}); + 0x20: bis({{ Rc = Ra | Rb_or_imm; }}); + 0x28: ornot({{ Rc = Ra | ~Rb_or_imm; }}); + 0x40: xor({{ Rc = Ra ^ Rb_or_imm; }}); + 0x48: eqv({{ Rc = Ra ^ ~Rb_or_imm; }}); + + // conditional moves + 0x14: cmovlbs({{ Rc = ((Ra & 1) == 1) ? Rb_or_imm : Rc; }}); + 0x16: cmovlbc({{ Rc = ((Ra & 1) == 0) ? Rb_or_imm : Rc; }}); + 0x24: cmoveq({{ Rc = (Ra == 0) ? Rb_or_imm : Rc; }}); + 0x26: cmovne({{ Rc = (Ra != 0) ? Rb_or_imm : Rc; }}); + 0x44: cmovlt({{ Rc = (Ra.sq < 0) ? Rb_or_imm : Rc; }}); + 0x46: cmovge({{ Rc = (Ra.sq >= 0) ? Rb_or_imm : Rc; }}); + 0x64: cmovle({{ Rc = (Ra.sq <= 0) ? Rb_or_imm : Rc; }}); + 0x66: cmovgt({{ Rc = (Ra.sq > 0) ? Rb_or_imm : Rc; }}); + + // For AMASK, RA must be R31. + 0x61: decode RA { + 31: amask({{ Rc = Rb_or_imm & ~ULL(0x17); }}); + } + + // For IMPLVER, RA must be R31 and the B operand + // must be the immediate value 1. + 0x6c: decode RA { + 31: decode IMM { + 1: decode INTIMM { + // return EV5 for FULL_SYSTEM and EV6 otherwise + 1: implver({{ +#if FULL_SYSTEM + Rc = 1; +#else + Rc = 2; +#endif + }}); + } + } + } + +#if FULL_SYSTEM + // The mysterious 11.25... + 0x25: WarnUnimpl::eleven25(); +#endif + } + + 0x12: decode INTFUNC { + 0x39: sll({{ Rc = Ra << Rb_or_imm<5:0>; }}); + 0x34: srl({{ Rc = Ra.uq >> Rb_or_imm<5:0>; }}); + 0x3c: sra({{ Rc = Ra.sq >> Rb_or_imm<5:0>; }}); + + 0x02: mskbl({{ Rc = Ra & ~(mask( 8) << (Rb_or_imm<2:0> * 8)); }}); + 0x12: mskwl({{ Rc = Ra & ~(mask(16) << (Rb_or_imm<2:0> * 8)); }}); + 0x22: mskll({{ Rc = Ra & ~(mask(32) << (Rb_or_imm<2:0> * 8)); }}); + 0x32: mskql({{ Rc = Ra & ~(mask(64) << (Rb_or_imm<2:0> * 8)); }}); + + 0x52: mskwh({{ + int bv = Rb_or_imm<2:0>; + Rc = bv ? (Ra & ~(mask(16) >> (64 - 8 * bv))) : Ra; + }}); + 0x62: msklh({{ + int bv = Rb_or_imm<2:0>; + Rc = bv ? (Ra & ~(mask(32) >> (64 - 8 * bv))) : Ra; + }}); + 0x72: mskqh({{ + int bv = Rb_or_imm<2:0>; + Rc = bv ? (Ra & ~(mask(64) >> (64 - 8 * bv))) : Ra; + }}); + + 0x06: extbl({{ Rc = (Ra.uq >> (Rb_or_imm<2:0> * 8))< 7:0>; }}); + 0x16: extwl({{ Rc = (Ra.uq >> (Rb_or_imm<2:0> * 8))<15:0>; }}); + 0x26: extll({{ Rc = (Ra.uq >> (Rb_or_imm<2:0> * 8))<31:0>; }}); + 0x36: extql({{ Rc = (Ra.uq >> (Rb_or_imm<2:0> * 8)); }}); + + 0x5a: extwh({{ + Rc = (Ra << (64 - (Rb_or_imm<2:0> * 8))<5:0>)<15:0>; }}); + 0x6a: extlh({{ + Rc = (Ra << (64 - (Rb_or_imm<2:0> * 8))<5:0>)<31:0>; }}); + 0x7a: extqh({{ + Rc = (Ra << (64 - (Rb_or_imm<2:0> * 8))<5:0>); }}); + + 0x0b: insbl({{ Rc = Ra< 7:0> << (Rb_or_imm<2:0> * 8); }}); + 0x1b: inswl({{ Rc = Ra<15:0> << (Rb_or_imm<2:0> * 8); }}); + 0x2b: insll({{ Rc = Ra<31:0> << (Rb_or_imm<2:0> * 8); }}); + 0x3b: insql({{ Rc = Ra << (Rb_or_imm<2:0> * 8); }}); + + 0x57: inswh({{ + int bv = Rb_or_imm<2:0>; + Rc = bv ? (Ra.uq<15:0> >> (64 - 8 * bv)) : 0; + }}); + 0x67: inslh({{ + int bv = Rb_or_imm<2:0>; + Rc = bv ? (Ra.uq<31:0> >> (64 - 8 * bv)) : 0; + }}); + 0x77: insqh({{ + int bv = Rb_or_imm<2:0>; + Rc = bv ? (Ra.uq >> (64 - 8 * bv)) : 0; + }}); + + 0x30: zap({{ + uint64_t zapmask = 0; + for (int i = 0; i < 8; ++i) { + if (Rb_or_imm) + zapmask |= (mask(8) << (i * 8)); + } + Rc = Ra & ~zapmask; + }}); + 0x31: zapnot({{ + uint64_t zapmask = 0; + for (int i = 0; i < 8; ++i) { + if (!Rb_or_imm) + zapmask |= (mask(8) << (i * 8)); + } + Rc = Ra & ~zapmask; + }}); + } + + 0x13: decode INTFUNC { // integer multiplies + 0x00: mull({{ Rc.sl = Ra.sl * Rb_or_imm.sl; }}, IntMultOp); + 0x20: mulq({{ Rc = Ra * Rb_or_imm; }}, IntMultOp); + 0x30: umulh({{ + uint64_t hi, lo; + mul128(Ra, Rb_or_imm, hi, lo); + Rc = hi; + }}, IntMultOp); + 0x40: mullv({{ + // 32-bit multiply with trap on overflow + int64_t Rax = Ra.sl; // sign extended version of Ra.sl + int64_t Rbx = Rb_or_imm.sl; + int64_t tmp = Rax * Rbx; + // To avoid overflow, all the upper 32 bits must match + // the sign bit of the lower 32. We code this as + // checking the upper 33 bits for all 0s or all 1s. + uint64_t sign_bits = tmp<63:31>; + if (sign_bits != 0 && sign_bits != mask(33)) + fault = Integer_Overflow_Fault; + Rc.sl = tmp<31:0>; + }}, IntMultOp); + 0x60: mulqv({{ + // 64-bit multiply with trap on overflow + uint64_t hi, lo; + mul128(Ra, Rb_or_imm, hi, lo); + // all the upper 64 bits must match the sign bit of + // the lower 64 + if (!((hi == 0 && lo<63:> == 0) || + (hi == mask(64) && lo<63:> == 1))) + fault = Integer_Overflow_Fault; + Rc = lo; + }}, IntMultOp); + } + + 0x1c: decode INTFUNC { + 0x00: decode RA { 31: sextb({{ Rc.sb = Rb_or_imm< 7:0>; }}); } + 0x01: decode RA { 31: sextw({{ Rc.sw = Rb_or_imm<15:0>; }}); } + 0x32: ctlz({{ + uint64_t count = 0; + uint64_t temp = Rb; + if (temp<63:32>) temp >>= 32; else count += 32; + if (temp<31:16>) temp >>= 16; else count += 16; + if (temp<15:8>) temp >>= 8; else count += 8; + if (temp<7:4>) temp >>= 4; else count += 4; + if (temp<3:2>) temp >>= 2; else count += 2; + if (temp<1:1>) temp >>= 1; else count += 1; + if ((temp<0:0>) != 0x1) count += 1; + Rc = count; + }}, IntAluOp); + + 0x33: cttz({{ + uint64_t count = 0; + uint64_t temp = Rb; + if (!(temp<31:0>)) { temp >>= 32; count += 32; } + if (!(temp<15:0>)) { temp >>= 16; count += 16; } + if (!(temp<7:0>)) { temp >>= 8; count += 8; } + if (!(temp<3:0>)) { temp >>= 4; count += 4; } + if (!(temp<1:0>)) { temp >>= 2; count += 2; } + if (!(temp<0:0> & ULL(0x1))) count += 1; + Rc = count; + }}, IntAluOp); + + format FailUnimpl { + 0x30: ctpop(); + 0x31: perr(); + 0x34: unpkbw(); + 0x35: unpkbl(); + 0x36: pkwb(); + 0x37: pklb(); + 0x38: minsb8(); + 0x39: minsw4(); + 0x3a: minub8(); + 0x3b: minuw4(); + 0x3c: maxub8(); + 0x3d: maxuw4(); + 0x3e: maxsb8(); + 0x3f: maxsw4(); + } + + format BasicOperateWithNopCheck { + 0x70: decode RB { + 31: ftoit({{ Rc = Fa.uq; }}, FloatCvtOp); + } + 0x78: decode RB { + 31: ftois({{ Rc.sl = t_to_s(Fa.uq); }}, + FloatCvtOp); + } + } + } + } + + // Conditional branches. + format CondBranch { + 0x39: beq({{ cond = (Ra == 0); }}); + 0x3d: bne({{ cond = (Ra != 0); }}); + 0x3e: bge({{ cond = (Ra.sq >= 0); }}); + 0x3f: bgt({{ cond = (Ra.sq > 0); }}); + 0x3b: ble({{ cond = (Ra.sq <= 0); }}); + 0x3a: blt({{ cond = (Ra.sq < 0); }}); + 0x38: blbc({{ cond = ((Ra & 1) == 0); }}); + 0x3c: blbs({{ cond = ((Ra & 1) == 1); }}); + + 0x31: fbeq({{ cond = (Fa == 0); }}); + 0x35: fbne({{ cond = (Fa != 0); }}); + 0x36: fbge({{ cond = (Fa >= 0); }}); + 0x37: fbgt({{ cond = (Fa > 0); }}); + 0x33: fble({{ cond = (Fa <= 0); }}); + 0x32: fblt({{ cond = (Fa < 0); }}); + } + + // unconditional branches + format UncondBranch { + 0x30: br(); + 0x34: bsr(IsCall); + } + + // indirect branches + 0x1a: decode JMPFUNC { + format Jump { + 0: jmp(); + 1: jsr(IsCall); + 2: ret(IsReturn); + 3: jsr_coroutine(IsCall, IsReturn); + } + } + + // Square root and integer-to-FP moves + 0x14: decode FP_SHORTFUNC { + // Integer to FP register moves must have RB == 31 + 0x4: decode RB { + 31: decode FP_FULLFUNC { + format BasicOperateWithNopCheck { + 0x004: itofs({{ Fc.uq = s_to_t(Ra.ul); }}, FloatCvtOp); + 0x024: itoft({{ Fc.uq = Ra.uq; }}, FloatCvtOp); + 0x014: FailUnimpl::itoff(); // VAX-format conversion + } + } + } + + // Square root instructions must have FA == 31 + 0xb: decode FA { + 31: decode FP_TYPEFUNC { + format FloatingPointOperate { +#if SS_COMPATIBLE_FP + 0x0b: sqrts({{ + if (Fb < 0.0) + fault = Arithmetic_Fault; + Fc = sqrt(Fb); + }}, FloatSqrtOp); +#else + 0x0b: sqrts({{ + if (Fb.sf < 0.0) + fault = Arithmetic_Fault; + Fc.sf = sqrt(Fb.sf); + }}, FloatSqrtOp); +#endif + 0x2b: sqrtt({{ + if (Fb < 0.0) + fault = Arithmetic_Fault; + Fc = sqrt(Fb); + }}, FloatSqrtOp); + } + } + } + + // VAX-format sqrtf and sqrtg are not implemented + 0xa: FailUnimpl::sqrtfg(); + } + + // IEEE floating point + 0x16: decode FP_SHORTFUNC_TOP2 { + // The top two bits of the short function code break this + // space into four groups: binary ops, compares, reserved, and + // conversions. See Table 4-12 of AHB. There are different + // special cases in these different groups, so we decode on + // these top two bits first just to select a decode strategy. + // Most of these instructions may have various trapping and + // rounding mode flags set; these are decoded in the + // FloatingPointDecode template used by the + // FloatingPointOperate format. + + // add/sub/mul/div: just decode on the short function code + // and source type. All valid trapping and rounding modes apply. + 0: decode FP_TRAPMODE { + // check for valid trapping modes here + 0,1,5,7: decode FP_TYPEFUNC { + format FloatingPointOperate { +#if SS_COMPATIBLE_FP + 0x00: adds({{ Fc = Fa + Fb; }}); + 0x01: subs({{ Fc = Fa - Fb; }}); + 0x02: muls({{ Fc = Fa * Fb; }}, FloatMultOp); + 0x03: divs({{ Fc = Fa / Fb; }}, FloatDivOp); +#else + 0x00: adds({{ Fc.sf = Fa.sf + Fb.sf; }}); + 0x01: subs({{ Fc.sf = Fa.sf - Fb.sf; }}); + 0x02: muls({{ Fc.sf = Fa.sf * Fb.sf; }}, FloatMultOp); + 0x03: divs({{ Fc.sf = Fa.sf / Fb.sf; }}, FloatDivOp); +#endif + + 0x20: addt({{ Fc = Fa + Fb; }}); + 0x21: subt({{ Fc = Fa - Fb; }}); + 0x22: mult({{ Fc = Fa * Fb; }}, FloatMultOp); + 0x23: divt({{ Fc = Fa / Fb; }}, FloatDivOp); + } + } + } + + // Floating-point compare instructions must have the default + // rounding mode, and may use the default trapping mode or + // /SU. Both trapping modes are treated the same by M5; the + // only difference on the real hardware (as far a I can tell) + // is that without /SU you'd get an imprecise trap if you + // tried to compare a NaN with something else (instead of an + // "unordered" result). + 1: decode FP_FULLFUNC { + format BasicOperateWithNopCheck { + 0x0a5, 0x5a5: cmpteq({{ Fc = (Fa == Fb) ? 2.0 : 0.0; }}, + FloatCmpOp); + 0x0a7, 0x5a7: cmptle({{ Fc = (Fa <= Fb) ? 2.0 : 0.0; }}, + FloatCmpOp); + 0x0a6, 0x5a6: cmptlt({{ Fc = (Fa < Fb) ? 2.0 : 0.0; }}, + FloatCmpOp); + 0x0a4, 0x5a4: cmptun({{ // unordered + Fc = (!(Fa < Fb) && !(Fa == Fb) && !(Fa > Fb)) ? 2.0 : 0.0; + }}, FloatCmpOp); + } + } + + // The FP-to-integer and integer-to-FP conversion insts + // require that FA be 31. + 3: decode FA { + 31: decode FP_TYPEFUNC { + format FloatingPointOperate { + 0x2f: decode FP_ROUNDMODE { + format FPFixedRounding { + // "chopped" i.e. round toward zero + 0: cvttq({{ Fc.sq = (int64_t)trunc(Fb); }}, + Chopped); + // round to minus infinity + 1: cvttq({{ Fc.sq = (int64_t)floor(Fb); }}, + MinusInfinity); + } + default: cvttq({{ Fc.sq = (int64_t)nearbyint(Fb); }}); + } + + // The cvtts opcode is overloaded to be cvtst if the trap + // mode is 2 or 6 (which are not valid otherwise) + 0x2c: decode FP_FULLFUNC { + format BasicOperateWithNopCheck { + // trap on denorm version "cvtst/s" is + // simulated same as cvtst + 0x2ac, 0x6ac: cvtst({{ Fc = Fb.sf; }}); + } + default: cvtts({{ Fc.sf = Fb; }}); + } + + // The trapping mode for integer-to-FP conversions + // must be /SUI or nothing; /U and /SU are not + // allowed. The full set of rounding modes are + // supported though. + 0x3c: decode FP_TRAPMODE { + 0,7: cvtqs({{ Fc.sf = Fb.sq; }}); + } + 0x3e: decode FP_TRAPMODE { + 0,7: cvtqt({{ Fc = Fb.sq; }}); + } + } + } + } + } + + // misc FP operate + 0x17: decode FP_FULLFUNC { + format BasicOperateWithNopCheck { + 0x010: cvtlq({{ + Fc.sl = (Fb.uq<63:62> << 30) | Fb.uq<58:29>; + }}); + 0x030: cvtql({{ + Fc.uq = (Fb.uq<31:30> << 62) | (Fb.uq<29:0> << 29); + }}); + + // We treat the precise & imprecise trapping versions of + // cvtql identically. + 0x130, 0x530: cvtqlv({{ + // To avoid overflow, all the upper 32 bits must match + // the sign bit of the lower 32. We code this as + // checking the upper 33 bits for all 0s or all 1s. + uint64_t sign_bits = Fb.uq<63:31>; + if (sign_bits != 0 && sign_bits != mask(33)) + fault = Integer_Overflow_Fault; + Fc.uq = (Fb.uq<31:30> << 62) | (Fb.uq<29:0> << 29); + }}); + + 0x020: cpys({{ // copy sign + Fc.uq = (Fa.uq<63:> << 63) | Fb.uq<62:0>; + }}); + 0x021: cpysn({{ // copy sign negated + Fc.uq = (~Fa.uq<63:> << 63) | Fb.uq<62:0>; + }}); + 0x022: cpyse({{ // copy sign and exponent + Fc.uq = (Fa.uq<63:52> << 52) | Fb.uq<51:0>; + }}); + + 0x02a: fcmoveq({{ Fc = (Fa == 0) ? Fb : Fc; }}); + 0x02b: fcmovne({{ Fc = (Fa != 0) ? Fb : Fc; }}); + 0x02c: fcmovlt({{ Fc = (Fa < 0) ? Fb : Fc; }}); + 0x02d: fcmovge({{ Fc = (Fa >= 0) ? Fb : Fc; }}); + 0x02e: fcmovle({{ Fc = (Fa <= 0) ? Fb : Fc; }}); + 0x02f: fcmovgt({{ Fc = (Fa > 0) ? Fb : Fc; }}); + + 0x024: mt_fpcr({{ FPCR = Fa.uq; }}); + 0x025: mf_fpcr({{ Fa.uq = FPCR; }}); + } + } + + // miscellaneous mem-format ops + 0x18: decode MEMFUNC { + format WarnUnimpl { + 0x8000: fetch(); + 0xa000: fetch_m(); + 0xe800: ecb(); + } + + format MiscPrefetch { + 0xf800: wh64({{ EA = Rb & ~ULL(63); }}, + {{ xc->writeHint(EA, 64, memAccessFlags); }}, + IsMemRef, IsDataPrefetch, IsStore, MemWriteOp, + NO_FAULT); + } + + format BasicOperate { + 0xc000: rpcc({{ +#if FULL_SYSTEM + /* Rb is a fake dependency so here is a fun way to get + * the parser to understand that. + */ + Ra = xc->readIpr(AlphaISA::IPR_CC, fault) + (Rb & 0); + +#else + Ra = curTick; +#endif + }}); + + // All of the barrier instructions below do nothing in + // their execute() methods (hence the empty code blocks). + // All of their functionality is hard-coded in the + // pipeline based on the flags IsSerializing, + // IsMemBarrier, and IsWriteBarrier. In the current + // detailed CPU model, the execute() function only gets + // called at fetch, so there's no way to generate pipeline + // behavior at any other stage. Once we go to an + // exec-in-exec CPU model we should be able to get rid of + // these flags and implement this behavior via the + // execute() methods. + + // trapb is just a barrier on integer traps, where excb is + // a barrier on integer and FP traps. "EXCB is thus a + // superset of TRAPB." (Alpha ARM, Sec 4.11.4) We treat + // them the same though. + 0x0000: trapb({{ }}, IsSerializing, No_OpClass); + 0x0400: excb({{ }}, IsSerializing, No_OpClass); + 0x4000: mb({{ }}, IsMemBarrier, MemReadOp); + 0x4400: wmb({{ }}, IsWriteBarrier, MemWriteOp); + } + +#if FULL_SYSTEM + format BasicOperate { + 0xe000: rc({{ + Ra = xc->readIntrFlag(); + xc->setIntrFlag(0); + }}, IsNonSpeculative); + 0xf000: rs({{ + Ra = xc->readIntrFlag(); + xc->setIntrFlag(1); + }}, IsNonSpeculative); + } +#else + format FailUnimpl { + 0xe000: rc(); + 0xf000: rs(); + } +#endif + } + +#if FULL_SYSTEM + 0x00: CallPal::call_pal({{ + if (!palValid || + (palPriv + && xc->readIpr(AlphaISA::IPR_ICM, fault) != AlphaISA::mode_kernel)) { + // invalid pal function code, or attempt to do privileged + // PAL call in non-kernel mode + fault = Unimplemented_Opcode_Fault; + } + else { + // check to see if simulator wants to do something special + // on this PAL call (including maybe suppress it) + bool dopal = xc->simPalCheck(palFunc); + + if (dopal) { + AlphaISA::swap_palshadow(&xc->xcBase()->regs, true); + xc->setIpr(AlphaISA::IPR_EXC_ADDR, NPC); + NPC = xc->readIpr(AlphaISA::IPR_PAL_BASE, fault) + palOffset; + } + } + }}, IsNonSpeculative); +#else + 0x00: decode PALFUNC { + format EmulatedCallPal { + 0x00: halt ({{ + SimExit(curTick, "halt instruction encountered"); + }}, IsNonSpeculative); + 0x83: callsys({{ + xc->syscall(); + }}, IsNonSpeculative); + // Read uniq reg into ABI return value register (r0) + 0x9e: rduniq({{ R0 = Runiq; }}); + // Write uniq reg with value from ABI arg register (r16) + 0x9f: wruniq({{ Runiq = R16; }}); + } + } +#endif + +#if FULL_SYSTEM + format HwLoadStore { + 0x1b: decode HW_LDST_QUAD { + 0: hw_ld({{ EA = (Rb + disp) & ~3; }}, {{ Ra = Mem.ul; }}, L); + 1: hw_ld({{ EA = (Rb + disp) & ~7; }}, {{ Ra = Mem.uq; }}, Q); + } + + 0x1f: decode HW_LDST_COND { + 0: decode HW_LDST_QUAD { + 0: hw_st({{ EA = (Rb + disp) & ~3; }}, + {{ Mem.ul = Ra<31:0>; }}, L); + 1: hw_st({{ EA = (Rb + disp) & ~7; }}, + {{ Mem.uq = Ra.uq; }}, Q); + } + + 1: FailUnimpl::hw_st_cond(); + } + } + + format HwMoveIPR { + 0x19: hw_mfpr({{ + // this instruction is only valid in PAL mode + if (!xc->inPalMode()) { + fault = Unimplemented_Opcode_Fault; + } + else { + Ra = xc->readIpr(ipr_index, fault); + } + }}); + 0x1d: hw_mtpr({{ + // this instruction is only valid in PAL mode + if (!xc->inPalMode()) { + fault = Unimplemented_Opcode_Fault; + } + else { + xc->setIpr(ipr_index, Ra); + if (traceData) { traceData->setData(Ra); } + } + }}); + } + + format BasicOperate { + 0x1e: hw_rei({{ xc->hwrei(); }}, IsSerializing); + + // M5 special opcodes use the reserved 0x01 opcode space + 0x01: decode M5FUNC { + 0x00: arm({{ + AlphaPseudo::arm(xc->xcBase()); + }}, IsNonSpeculative); + 0x01: quiesce({{ + AlphaPseudo::quiesce(xc->xcBase()); + }}, IsNonSpeculative); + 0x10: ivlb({{ + AlphaPseudo::ivlb(xc->xcBase()); + }}, No_OpClass, IsNonSpeculative); + 0x11: ivle({{ + AlphaPseudo::ivle(xc->xcBase()); + }}, No_OpClass, IsNonSpeculative); + 0x20: m5exit_old({{ + AlphaPseudo::m5exit_old(xc->xcBase()); + }}, No_OpClass, IsNonSpeculative); + 0x21: m5exit({{ + AlphaPseudo::m5exit(xc->xcBase()); + }}, No_OpClass, IsNonSpeculative); + 0x30: initparam({{ Ra = xc->xcBase()->cpu->system->init_param; }}); + 0x40: resetstats({{ + AlphaPseudo::resetstats(xc->xcBase()); + }}, IsNonSpeculative); + 0x41: dumpstats({{ + AlphaPseudo::dumpstats(xc->xcBase()); + }}, IsNonSpeculative); + 0x42: dumpresetstats({{ + AlphaPseudo::dumpresetstats(xc->xcBase()); + }}, IsNonSpeculative); + 0x43: m5checkpoint({{ + AlphaPseudo::m5checkpoint(xc->xcBase()); + }}, IsNonSpeculative); + 0x50: m5readfile({{ + AlphaPseudo::readfile(xc->xcBase()); + }}, IsNonSpeculative); + 0x51: m5break({{ + AlphaPseudo::debugbreak(xc->xcBase()); + }}, IsNonSpeculative); + 0x52: m5switchcpu({{ + AlphaPseudo::switchcpu(xc->xcBase()); + }}, IsNonSpeculative); + 0x53: m5addsymbol({{ + AlphaPseudo::addsymbol(xc->xcBase()); + }}, IsNonSpeculative); + + } + } +#endif +} diff --git a/arch/alpha/isa/fp.isa b/arch/alpha/isa/fp.isa new file mode 100644 index 000000000..0abc814be --- /dev/null +++ b/arch/alpha/isa/fp.isa @@ -0,0 +1,300 @@ +// -*- mode:c++ -*- + +// 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. + +output exec {{ + /// Check "FP enabled" machine status bit. Called when executing any FP + /// instruction in full-system mode. + /// @retval Full-system mode: No_Fault if FP is enabled, Fen_Fault + /// if not. Non-full-system mode: always returns No_Fault. +#if FULL_SYSTEM + inline Fault checkFpEnableFault(%(CPU_exec_context)s *xc) + { + Fault fault = No_Fault; // dummy... this ipr access should not fault + if (!EV5::ICSR_FPE(xc->readIpr(AlphaISA::IPR_ICSR, fault))) { + fault = Fen_Fault; + } + return fault; + } +#else + inline Fault checkFpEnableFault(%(CPU_exec_context)s *xc) + { + return No_Fault; + } +#endif +}}; + +output header {{ + /** + * Base class for general floating-point instructions. Includes + * support for various Alpha rounding and trapping modes. Only FP + * instructions that require this support are derived from this + * class; the rest derive directly from AlphaStaticInst. + */ + class AlphaFP : public AlphaStaticInst + { + public: + /// Alpha FP rounding modes. + enum RoundingMode { + Chopped = 0, ///< round toward zero + Minus_Infinity = 1, ///< round toward minus infinity + Normal = 2, ///< round to nearest (default) + Dynamic = 3, ///< use FPCR setting (in instruction) + Plus_Infinity = 3 ///< round to plus inifinity (in FPCR) + }; + + /// Alpha FP trapping modes. + /// For instructions that produce integer results, the + /// "Underflow Enable" modes really mean "Overflow Enable", and + /// the assembly modifier is V rather than U. + enum TrappingMode { + /// default: nothing enabled + Imprecise = 0, ///< no modifier + /// underflow/overflow traps enabled, inexact disabled + Underflow_Imprecise = 1, ///< /U or /V + Underflow_Precise = 5, ///< /SU or /SV + /// underflow/overflow and inexact traps enabled + Underflow_Inexact_Precise = 7 ///< /SUI or /SVI + }; + + protected: + /// Map Alpha rounding mode to C99 constants from . + static const int alphaToC99RoundingMode[]; + + /// Map enum RoundingMode values to disassembly suffixes. + static const char *roundingModeSuffix[]; + /// Map enum TrappingMode values to FP disassembly suffixes. + static const char *fpTrappingModeSuffix[]; + /// Map enum TrappingMode values to integer disassembly suffixes. + static const char *intTrappingModeSuffix[]; + + /// This instruction's rounding mode. + RoundingMode roundingMode; + /// This instruction's trapping mode. + TrappingMode trappingMode; + + /// Have we warned about this instruction's unsupported + /// rounding mode (if applicable)? + mutable bool warnedOnRounding; + + /// Have we warned about this instruction's unsupported + /// trapping mode (if applicable)? + mutable bool warnedOnTrapping; + + /// Constructor + AlphaFP(const char *mnem, MachInst _machInst, OpClass __opClass) + : AlphaStaticInst(mnem, _machInst, __opClass), + roundingMode((enum RoundingMode)FP_ROUNDMODE), + trappingMode((enum TrappingMode)FP_TRAPMODE), + warnedOnRounding(false), + warnedOnTrapping(false) + { + } + + int getC99RoundingMode(uint64_t fpcr_val) const; + + // This differs from the AlphaStaticInst version only in + // printing suffixes for non-default rounding & trapping modes. + std::string + generateDisassembly(Addr pc, const SymbolTable *symtab) const; + }; + +}}; + + +output decoder {{ + int + AlphaFP::getC99RoundingMode(uint64_t fpcr_val) const + { + if (roundingMode == Dynamic) { + return alphaToC99RoundingMode[bits(fpcr_val, 59, 58)]; + } + else { + return alphaToC99RoundingMode[roundingMode]; + } + } + + std::string + AlphaFP::generateDisassembly(Addr pc, const SymbolTable *symtab) const + { + std::string mnem_str(mnemonic); + +#ifndef SS_COMPATIBLE_DISASSEMBLY + std::string suffix(""); + suffix += ((_destRegIdx[0] >= FP_Base_DepTag) + ? fpTrappingModeSuffix[trappingMode] + : intTrappingModeSuffix[trappingMode]); + suffix += roundingModeSuffix[roundingMode]; + + if (suffix != "") { + mnem_str = csprintf("%s/%s", mnemonic, suffix); + } +#endif + + std::stringstream ss; + ccprintf(ss, "%-10s ", mnem_str.c_str()); + + // just print the first two source regs... if there's + // a third one, it's a read-modify-write dest (Rc), + // e.g. for CMOVxx + if (_numSrcRegs > 0) { + printReg(ss, _srcRegIdx[0]); + } + if (_numSrcRegs > 1) { + ss << ","; + printReg(ss, _srcRegIdx[1]); + } + + // just print the first dest... if there's a second one, + // it's generally implicit + if (_numDestRegs > 0) { + if (_numSrcRegs > 0) + ss << ","; + printReg(ss, _destRegIdx[0]); + } + + return ss.str(); + } + + const int AlphaFP::alphaToC99RoundingMode[] = { + FE_TOWARDZERO, // Chopped + FE_DOWNWARD, // Minus_Infinity + FE_TONEAREST, // Normal + FE_UPWARD // Dynamic in inst, Plus_Infinity in FPCR + }; + + const char *AlphaFP::roundingModeSuffix[] = { "c", "m", "", "d" }; + // mark invalid trapping modes, but don't fail on them, because + // you could decode anything on a misspeculated path + const char *AlphaFP::fpTrappingModeSuffix[] = + { "", "u", "INVTM2", "INVTM3", "INVTM4", "su", "INVTM6", "sui" }; + const char *AlphaFP::intTrappingModeSuffix[] = + { "", "v", "INVTM2", "INVTM3", "INVTM4", "sv", "INVTM6", "svi" }; +}}; + +// FP instruction class execute method template. Handles non-standard +// rounding modes. +def template FloatingPointExecute {{ + Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + if (trappingMode != Imprecise && !warnedOnTrapping) { + warn("%s: non-standard trapping mode not supported", + generateDisassembly(0, NULL)); + warnedOnTrapping = true; + } + + Fault fault = No_Fault; + + %(fp_enable_check)s; + %(op_decl)s; + %(op_rd)s; +#if USE_FENV + if (roundingMode == Normal) { + %(code)s; + } else { + fesetround(getC99RoundingMode(xc->readFpcr())); + %(code)s; + fesetround(FE_TONEAREST); + } +#else + if (roundingMode != Normal && !warnedOnRounding) { + warn("%s: non-standard rounding mode not supported", + generateDisassembly(0, NULL)); + warnedOnRounding = true; + } + %(code)s; +#endif + + if (fault == No_Fault) { + %(op_wb)s; + } + + return fault; + } +}}; + +// FP instruction class execute method template where no dynamic +// rounding mode control is needed. Like BasicExecute, but includes +// check & warning for non-standard trapping mode. +def template FPFixedRoundingExecute {{ + Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + if (trappingMode != Imprecise && !warnedOnTrapping) { + warn("%s: non-standard trapping mode not supported", + generateDisassembly(0, NULL)); + warnedOnTrapping = true; + } + + Fault fault = No_Fault; + + %(fp_enable_check)s; + %(op_decl)s; + %(op_rd)s; + %(code)s; + + if (fault == No_Fault) { + %(op_wb)s; + } + + return fault; + } +}}; + +def template FloatingPointDecode {{ + { + AlphaStaticInst *i = new %(class_name)s(machInst); + if (FC == 31) { + i = makeNop(i); + } + return i; + } +}}; + +// General format for floating-point operate instructions: +// - Checks trapping and rounding mode flags. Trapping modes +// currently unimplemented (will fail). +// - Generates NOP if FC == 31. +def format FloatingPointOperate(code, *opt_args) {{ + iop = InstObjParams(name, Name, 'AlphaFP', CodeBlock(code), opt_args) + decode_block = FloatingPointDecode.subst(iop) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + exec_output = FloatingPointExecute.subst(iop) +}}; + +// Special format for cvttq where rounding mode is pre-decoded +def format FPFixedRounding(code, class_suffix, *opt_args) {{ + Name += class_suffix + iop = InstObjParams(name, Name, 'AlphaFP', CodeBlock(code), opt_args) + decode_block = FloatingPointDecode.subst(iop) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + exec_output = FPFixedRoundingExecute.subst(iop) +}}; + diff --git a/arch/alpha/isa/int.isa b/arch/alpha/isa/int.isa new file mode 100644 index 000000000..049437f8c --- /dev/null +++ b/arch/alpha/isa/int.isa @@ -0,0 +1,128 @@ +// -*- mode:c++ -*- + +// 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. + +output header {{ + /** + * Base class for integer immediate instructions. + */ + class IntegerImm : public AlphaStaticInst + { + protected: + /// Immediate operand value (unsigned 8-bit int). + uint8_t imm; + + /// Constructor + IntegerImm(const char *mnem, MachInst _machInst, OpClass __opClass) + : AlphaStaticInst(mnem, _machInst, __opClass), imm(INTIMM) + { + } + + std::string + generateDisassembly(Addr pc, const SymbolTable *symtab) const; + }; +}}; + +output decoder {{ + std::string + IntegerImm::generateDisassembly(Addr pc, const SymbolTable *symtab) const + { + std::stringstream ss; + + ccprintf(ss, "%-10s ", mnemonic); + + // just print the first source reg... if there's + // a second one, it's a read-modify-write dest (Rc), + // e.g. for CMOVxx + if (_numSrcRegs > 0) { + printReg(ss, _srcRegIdx[0]); + ss << ","; + } + + ss << (int)imm; + + if (_numDestRegs > 0) { + ss << ","; + printReg(ss, _destRegIdx[0]); + } + + return ss.str(); + } +}}; + + +def template RegOrImmDecode {{ + { + AlphaStaticInst *i = + (IMM) ? (AlphaStaticInst *)new %(class_name)sImm(machInst) + : (AlphaStaticInst *)new %(class_name)s(machInst); + if (RC == 31) { + i = makeNop(i); + } + return i; + } +}}; + +// Primary format for integer operate instructions: +// - Generates both reg-reg and reg-imm versions if Rb_or_imm is used. +// - Generates NOP if RC == 31. +def format IntegerOperate(code, *opt_flags) {{ + # If the code block contains 'Rb_or_imm', we define two instructions, + # one using 'Rb' and one using 'imm', and have the decoder select + # the right one. + uses_imm = (code.find('Rb_or_imm') != -1) + if uses_imm: + orig_code = code + # base code is reg version: + # rewrite by substituting 'Rb' for 'Rb_or_imm' + code = re.sub(r'Rb_or_imm', 'Rb', orig_code) + # generate immediate version by substituting 'imm' + # note that imm takes no extenstion, so we extend + # the regexp to replace any extension as well + imm_code = re.sub(r'Rb_or_imm(\.\w+)?', 'imm', orig_code) + + # generate declaration for register version + cblk = CodeBlock(code) + iop = InstObjParams(name, Name, 'AlphaStaticInst', cblk, opt_flags) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + exec_output = BasicExecute.subst(iop) + + if uses_imm: + # append declaration for imm version + imm_cblk = CodeBlock(imm_code) + imm_iop = InstObjParams(name, Name + 'Imm', 'IntegerImm', imm_cblk, + opt_flags) + header_output += BasicDeclare.subst(imm_iop) + decoder_output += BasicConstructor.subst(imm_iop) + exec_output += BasicExecute.subst(imm_iop) + # decode checks IMM bit to pick correct version + decode_block = RegOrImmDecode.subst(iop) + else: + # no imm version: just check for nop + decode_block = OperateNopCheckDecode.subst(iop) +}}; diff --git a/arch/alpha/isa/main.isa b/arch/alpha/isa/main.isa index eb4aad033..fa2f71a29 100644 --- a/arch/alpha/isa/main.isa +++ b/arch/alpha/isa/main.isa @@ -405,2319 +405,29 @@ def format BasicOperateWithNopCheck(code, *opt_args) {{ exec_output = BasicExecute.subst(iop) }}; +// Integer instruction templates, formats, etc. +##include "m5/arch/alpha/isa/int.isa" -//////////////////////////////////////////////////////////////////// -// -// Integer operate instructions -// +// Floating-point instruction templates, formats, etc. +##include "m5/arch/alpha/isa/fp.isa" -output header {{ - /** - * Base class for integer immediate instructions. - */ - class IntegerImm : public AlphaStaticInst - { - protected: - /// Immediate operand value (unsigned 8-bit int). - uint8_t imm; +// Memory instruction templates, formats, etc. +##include "m5/arch/alpha/isa/mem.isa" - /// Constructor - IntegerImm(const char *mnem, MachInst _machInst, OpClass __opClass) - : AlphaStaticInst(mnem, _machInst, __opClass), imm(INTIMM) - { - } +// Branch/jump instruction templates, formats, etc. +##include "m5/arch/alpha/isa/branch.isa" - std::string - generateDisassembly(Addr pc, const SymbolTable *symtab) const; - }; -}}; +// PAL instruction templates, formats, etc. +##include "m5/arch/alpha/isa/pal.isa" -output decoder {{ - std::string - IntegerImm::generateDisassembly(Addr pc, const SymbolTable *symtab) const - { - std::stringstream ss; +// Unimplemented instruction templates, formats, etc. +##include "m5/arch/alpha/isa/unimp.isa" - ccprintf(ss, "%-10s ", mnemonic); +// Unknown instruction templates, formats, etc. +##include "m5/arch/alpha/isa/unknown.isa" - // just print the first source reg... if there's - // a second one, it's a read-modify-write dest (Rc), - // e.g. for CMOVxx - if (_numSrcRegs > 0) { - printReg(ss, _srcRegIdx[0]); - ss << ","; - } +// Execution utility functions +##include "m5/arch/alpha/isa/util.isa" - ss << (int)imm; - - if (_numDestRegs > 0) { - ss << ","; - printReg(ss, _destRegIdx[0]); - } - - return ss.str(); - } -}}; - - -def template RegOrImmDecode {{ - { - AlphaStaticInst *i = - (IMM) ? (AlphaStaticInst *)new %(class_name)sImm(machInst) - : (AlphaStaticInst *)new %(class_name)s(machInst); - if (RC == 31) { - i = makeNop(i); - } - return i; - } -}}; - -// Primary format for integer operate instructions: -// - Generates both reg-reg and reg-imm versions if Rb_or_imm is used. -// - Generates NOP if RC == 31. -def format IntegerOperate(code, *opt_flags) {{ - # If the code block contains 'Rb_or_imm', we define two instructions, - # one using 'Rb' and one using 'imm', and have the decoder select - # the right one. - uses_imm = (code.find('Rb_or_imm') != -1) - if uses_imm: - orig_code = code - # base code is reg version: - # rewrite by substituting 'Rb' for 'Rb_or_imm' - code = re.sub(r'Rb_or_imm', 'Rb', orig_code) - # generate immediate version by substituting 'imm' - # note that imm takes no extenstion, so we extend - # the regexp to replace any extension as well - imm_code = re.sub(r'Rb_or_imm(\.\w+)?', 'imm', orig_code) - - # generate declaration for register version - cblk = CodeBlock(code) - iop = InstObjParams(name, Name, 'AlphaStaticInst', cblk, opt_flags) - header_output = BasicDeclare.subst(iop) - decoder_output = BasicConstructor.subst(iop) - exec_output = BasicExecute.subst(iop) - - if uses_imm: - # append declaration for imm version - imm_cblk = CodeBlock(imm_code) - imm_iop = InstObjParams(name, Name + 'Imm', 'IntegerImm', imm_cblk, - opt_flags) - header_output += BasicDeclare.subst(imm_iop) - decoder_output += BasicConstructor.subst(imm_iop) - exec_output += BasicExecute.subst(imm_iop) - # decode checks IMM bit to pick correct version - decode_block = RegOrImmDecode.subst(iop) - else: - # no imm version: just check for nop - decode_block = OperateNopCheckDecode.subst(iop) -}}; - - -//////////////////////////////////////////////////////////////////// -// -// Floating-point instructions -// -// Note that many FP-type instructions which do not support all the -// various rounding & trapping modes use the simpler format -// BasicOperateWithNopCheck. -// - -output exec {{ - /// Check "FP enabled" machine status bit. Called when executing any FP - /// instruction in full-system mode. - /// @retval Full-system mode: No_Fault if FP is enabled, Fen_Fault - /// if not. Non-full-system mode: always returns No_Fault. -#if FULL_SYSTEM - inline Fault checkFpEnableFault(%(CPU_exec_context)s *xc) - { - Fault fault = No_Fault; // dummy... this ipr access should not fault - if (!EV5::ICSR_FPE(xc->readIpr(AlphaISA::IPR_ICSR, fault))) { - fault = Fen_Fault; - } - return fault; - } -#else - inline Fault checkFpEnableFault(%(CPU_exec_context)s *xc) - { - return No_Fault; - } -#endif -}}; - -output header {{ - /** - * Base class for general floating-point instructions. Includes - * support for various Alpha rounding and trapping modes. Only FP - * instructions that require this support are derived from this - * class; the rest derive directly from AlphaStaticInst. - */ - class AlphaFP : public AlphaStaticInst - { - public: - /// Alpha FP rounding modes. - enum RoundingMode { - Chopped = 0, ///< round toward zero - Minus_Infinity = 1, ///< round toward minus infinity - Normal = 2, ///< round to nearest (default) - Dynamic = 3, ///< use FPCR setting (in instruction) - Plus_Infinity = 3 ///< round to plus inifinity (in FPCR) - }; - - /// Alpha FP trapping modes. - /// For instructions that produce integer results, the - /// "Underflow Enable" modes really mean "Overflow Enable", and - /// the assembly modifier is V rather than U. - enum TrappingMode { - /// default: nothing enabled - Imprecise = 0, ///< no modifier - /// underflow/overflow traps enabled, inexact disabled - Underflow_Imprecise = 1, ///< /U or /V - Underflow_Precise = 5, ///< /SU or /SV - /// underflow/overflow and inexact traps enabled - Underflow_Inexact_Precise = 7 ///< /SUI or /SVI - }; - - protected: - /// Map Alpha rounding mode to C99 constants from . - static const int alphaToC99RoundingMode[]; - - /// Map enum RoundingMode values to disassembly suffixes. - static const char *roundingModeSuffix[]; - /// Map enum TrappingMode values to FP disassembly suffixes. - static const char *fpTrappingModeSuffix[]; - /// Map enum TrappingMode values to integer disassembly suffixes. - static const char *intTrappingModeSuffix[]; - - /// This instruction's rounding mode. - RoundingMode roundingMode; - /// This instruction's trapping mode. - TrappingMode trappingMode; - - /// Have we warned about this instruction's unsupported - /// rounding mode (if applicable)? - mutable bool warnedOnRounding; - - /// Have we warned about this instruction's unsupported - /// trapping mode (if applicable)? - mutable bool warnedOnTrapping; - - /// Constructor - AlphaFP(const char *mnem, MachInst _machInst, OpClass __opClass) - : AlphaStaticInst(mnem, _machInst, __opClass), - roundingMode((enum RoundingMode)FP_ROUNDMODE), - trappingMode((enum TrappingMode)FP_TRAPMODE), - warnedOnRounding(false), - warnedOnTrapping(false) - { - } - - int getC99RoundingMode(uint64_t fpcr_val) const; - - // This differs from the AlphaStaticInst version only in - // printing suffixes for non-default rounding & trapping modes. - std::string - generateDisassembly(Addr pc, const SymbolTable *symtab) const; - }; - -}}; - - -output decoder {{ - int - AlphaFP::getC99RoundingMode(uint64_t fpcr_val) const - { - if (roundingMode == Dynamic) { - return alphaToC99RoundingMode[bits(fpcr_val, 59, 58)]; - } - else { - return alphaToC99RoundingMode[roundingMode]; - } - } - - std::string - AlphaFP::generateDisassembly(Addr pc, const SymbolTable *symtab) const - { - std::string mnem_str(mnemonic); - -#ifndef SS_COMPATIBLE_DISASSEMBLY - std::string suffix(""); - suffix += ((_destRegIdx[0] >= FP_Base_DepTag) - ? fpTrappingModeSuffix[trappingMode] - : intTrappingModeSuffix[trappingMode]); - suffix += roundingModeSuffix[roundingMode]; - - if (suffix != "") { - mnem_str = csprintf("%s/%s", mnemonic, suffix); - } -#endif - - std::stringstream ss; - ccprintf(ss, "%-10s ", mnem_str.c_str()); - - // just print the first two source regs... if there's - // a third one, it's a read-modify-write dest (Rc), - // e.g. for CMOVxx - if (_numSrcRegs > 0) { - printReg(ss, _srcRegIdx[0]); - } - if (_numSrcRegs > 1) { - ss << ","; - printReg(ss, _srcRegIdx[1]); - } - - // just print the first dest... if there's a second one, - // it's generally implicit - if (_numDestRegs > 0) { - if (_numSrcRegs > 0) - ss << ","; - printReg(ss, _destRegIdx[0]); - } - - return ss.str(); - } - - const int AlphaFP::alphaToC99RoundingMode[] = { - FE_TOWARDZERO, // Chopped - FE_DOWNWARD, // Minus_Infinity - FE_TONEAREST, // Normal - FE_UPWARD // Dynamic in inst, Plus_Infinity in FPCR - }; - - const char *AlphaFP::roundingModeSuffix[] = { "c", "m", "", "d" }; - // mark invalid trapping modes, but don't fail on them, because - // you could decode anything on a misspeculated path - const char *AlphaFP::fpTrappingModeSuffix[] = - { "", "u", "INVTM2", "INVTM3", "INVTM4", "su", "INVTM6", "sui" }; - const char *AlphaFP::intTrappingModeSuffix[] = - { "", "v", "INVTM2", "INVTM3", "INVTM4", "sv", "INVTM6", "svi" }; -}}; - -// FP instruction class execute method template. Handles non-standard -// rounding modes. -def template FloatingPointExecute {{ - Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, - Trace::InstRecord *traceData) const - { - if (trappingMode != Imprecise && !warnedOnTrapping) { - warn("%s: non-standard trapping mode not supported", - generateDisassembly(0, NULL)); - warnedOnTrapping = true; - } - - Fault fault = No_Fault; - - %(fp_enable_check)s; - %(op_decl)s; - %(op_rd)s; -#if USE_FENV - if (roundingMode == Normal) { - %(code)s; - } else { - fesetround(getC99RoundingMode(xc->readFpcr())); - %(code)s; - fesetround(FE_TONEAREST); - } -#else - if (roundingMode != Normal && !warnedOnRounding) { - warn("%s: non-standard rounding mode not supported", - generateDisassembly(0, NULL)); - warnedOnRounding = true; - } - %(code)s; -#endif - - if (fault == No_Fault) { - %(op_wb)s; - } - - return fault; - } -}}; - -// FP instruction class execute method template where no dynamic -// rounding mode control is needed. Like BasicExecute, but includes -// check & warning for non-standard trapping mode. -def template FPFixedRoundingExecute {{ - Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, - Trace::InstRecord *traceData) const - { - if (trappingMode != Imprecise && !warnedOnTrapping) { - warn("%s: non-standard trapping mode not supported", - generateDisassembly(0, NULL)); - warnedOnTrapping = true; - } - - Fault fault = No_Fault; - - %(fp_enable_check)s; - %(op_decl)s; - %(op_rd)s; - %(code)s; - - if (fault == No_Fault) { - %(op_wb)s; - } - - return fault; - } -}}; - -def template FloatingPointDecode {{ - { - AlphaStaticInst *i = new %(class_name)s(machInst); - if (FC == 31) { - i = makeNop(i); - } - return i; - } -}}; - -// General format for floating-point operate instructions: -// - Checks trapping and rounding mode flags. Trapping modes -// currently unimplemented (will fail). -// - Generates NOP if FC == 31. -def format FloatingPointOperate(code, *opt_args) {{ - iop = InstObjParams(name, Name, 'AlphaFP', CodeBlock(code), opt_args) - decode_block = FloatingPointDecode.subst(iop) - header_output = BasicDeclare.subst(iop) - decoder_output = BasicConstructor.subst(iop) - exec_output = FloatingPointExecute.subst(iop) -}}; - -// Special format for cvttq where rounding mode is pre-decoded -def format FPFixedRounding(code, class_suffix, *opt_args) {{ - Name += class_suffix - iop = InstObjParams(name, Name, 'AlphaFP', CodeBlock(code), opt_args) - decode_block = FloatingPointDecode.subst(iop) - header_output = BasicDeclare.subst(iop) - decoder_output = BasicConstructor.subst(iop) - exec_output = FPFixedRoundingExecute.subst(iop) -}}; - -//////////////////////////////////////////////////////////////////// -// -// Memory-format instructions: LoadAddress, Load, Store -// - -output header {{ - /** - * Base class for general Alpha memory-format instructions. - */ - class Memory : public AlphaStaticInst - { - protected: - - /// Memory request flags. See mem_req_base.hh. - unsigned memAccessFlags; - /// Pointer to EAComp object. - const StaticInstPtr eaCompPtr; - /// Pointer to MemAcc object. - const StaticInstPtr memAccPtr; - - /// Constructor - Memory(const char *mnem, MachInst _machInst, OpClass __opClass, - StaticInstPtr _eaCompPtr = nullStaticInstPtr, - StaticInstPtr _memAccPtr = nullStaticInstPtr) - : AlphaStaticInst(mnem, _machInst, __opClass), - memAccessFlags(0), eaCompPtr(_eaCompPtr), memAccPtr(_memAccPtr) - { - } - - std::string - generateDisassembly(Addr pc, const SymbolTable *symtab) const; - - public: - - const StaticInstPtr &eaCompInst() const { return eaCompPtr; } - const StaticInstPtr &memAccInst() const { return memAccPtr; } - }; - - /** - * Base class for memory-format instructions using a 32-bit - * displacement (i.e. most of them). - */ - class MemoryDisp32 : public Memory - { - protected: - /// Displacement for EA calculation (signed). - int32_t disp; - - /// Constructor. - MemoryDisp32(const char *mnem, MachInst _machInst, OpClass __opClass, - StaticInstPtr _eaCompPtr = nullStaticInstPtr, - StaticInstPtr _memAccPtr = nullStaticInstPtr) - : Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr), - disp(MEMDISP) - { - } - }; - - - /** - * Base class for a few miscellaneous memory-format insts - * that don't interpret the disp field: wh64, fetch, fetch_m, ecb. - * None of these instructions has a destination register either. - */ - class MemoryNoDisp : public Memory - { - protected: - /// Constructor - MemoryNoDisp(const char *mnem, MachInst _machInst, OpClass __opClass, - StaticInstPtr _eaCompPtr = nullStaticInstPtr, - StaticInstPtr _memAccPtr = nullStaticInstPtr) - : Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr) - { - } - - std::string - generateDisassembly(Addr pc, const SymbolTable *symtab) const; - }; -}}; - - -output decoder {{ - std::string - Memory::generateDisassembly(Addr pc, const SymbolTable *symtab) const - { - return csprintf("%-10s %c%d,%d(r%d)", mnemonic, - flags[IsFloating] ? 'f' : 'r', RA, MEMDISP, RB); - } - - std::string - MemoryNoDisp::generateDisassembly(Addr pc, const SymbolTable *symtab) const - { - return csprintf("%-10s (r%d)", mnemonic, RB); - } -}}; - -def format LoadAddress(code) {{ - iop = InstObjParams(name, Name, 'MemoryDisp32', CodeBlock(code)) - header_output = BasicDeclare.subst(iop) - decoder_output = BasicConstructor.subst(iop) - decode_block = BasicDecode.subst(iop) - exec_output = BasicExecute.subst(iop) -}}; - - -def template LoadStoreDeclare {{ - /** - * Static instruction class for "%(mnemonic)s". - */ - class %(class_name)s : public %(base_class)s - { - protected: - - /** - * "Fake" effective address computation class for "%(mnemonic)s". - */ - class EAComp : public %(base_class)s - { - public: - /// Constructor - EAComp(MachInst machInst); - - %(BasicExecDeclare)s - }; - - /** - * "Fake" memory access instruction class for "%(mnemonic)s". - */ - class MemAcc : public %(base_class)s - { - public: - /// Constructor - MemAcc(MachInst machInst); - - %(BasicExecDeclare)s - }; - - public: - - /// Constructor. - %(class_name)s(MachInst machInst); - - %(BasicExecDeclare)s - }; -}}; - -def template LoadStoreConstructor {{ - /** TODO: change op_class to AddrGenOp or something (requires - * creating new member of OpClass enum in op_class.hh, updating - * config files, etc.). */ - inline %(class_name)s::EAComp::EAComp(MachInst machInst) - : %(base_class)s("%(mnemonic)s (EAComp)", machInst, IntAluOp) - { - %(ea_constructor)s; - } - - inline %(class_name)s::MemAcc::MemAcc(MachInst machInst) - : %(base_class)s("%(mnemonic)s (MemAcc)", machInst, %(op_class)s) - { - %(memacc_constructor)s; - } - - inline %(class_name)s::%(class_name)s(MachInst machInst) - : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, - new EAComp(machInst), new MemAcc(machInst)) - { - %(constructor)s; - } -}}; - - -def template EACompExecute {{ - Fault - %(class_name)s::EAComp::execute(%(CPU_exec_context)s *xc, - Trace::InstRecord *traceData) const - { - Addr EA; - Fault fault = No_Fault; - - %(fp_enable_check)s; - %(op_decl)s; - %(op_rd)s; - %(code)s; - - if (fault == No_Fault) { - %(op_wb)s; - xc->setEA(EA); - } - - return fault; - } -}}; - -def template MemAccExecute {{ - Fault - %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc, - Trace::InstRecord *traceData) const - { - Addr EA; - Fault fault = No_Fault; - - %(fp_enable_check)s; - %(op_decl)s; - %(op_nonmem_rd)s; - EA = xc->getEA(); - - if (fault == No_Fault) { - %(op_mem_rd)s; - %(code)s; - } - - if (fault == No_Fault) { - %(op_mem_wb)s; - } - - if (fault == No_Fault) { - %(postacc_code)s; - } - - if (fault == No_Fault) { - %(op_nonmem_wb)s; - } - - return fault; - } -}}; - - -def template LoadStoreExecute {{ - Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, - Trace::InstRecord *traceData) const - { - Addr EA; - Fault fault = No_Fault; - - %(fp_enable_check)s; - %(op_decl)s; - %(op_nonmem_rd)s; - %(ea_code)s; - - if (fault == No_Fault) { - %(op_mem_rd)s; - %(memacc_code)s; - } - - if (fault == No_Fault) { - %(op_mem_wb)s; - } - - if (fault == No_Fault) { - %(postacc_code)s; - } - - if (fault == No_Fault) { - %(op_nonmem_wb)s; - } - - return fault; - } -}}; - - -def template PrefetchExecute {{ - Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, - Trace::InstRecord *traceData) const - { - Addr EA; - Fault fault = No_Fault; - - %(fp_enable_check)s; - %(op_decl)s; - %(op_nonmem_rd)s; - %(ea_code)s; - - if (fault == No_Fault) { - xc->prefetch(EA, memAccessFlags); - } - - return No_Fault; - } -}}; - -// load instructions use Ra as dest, so check for -// Ra == 31 to detect nops -def template LoadNopCheckDecode {{ - { - AlphaStaticInst *i = new %(class_name)s(machInst); - if (RA == 31) { - i = makeNop(i); - } - return i; - } -}}; - - -// for some load instructions, Ra == 31 indicates a prefetch (not a nop) -def template LoadPrefetchCheckDecode {{ - { - if (RA != 31) { - return new %(class_name)s(machInst); - } - else { - return new %(class_name)sPrefetch(machInst); - } - } -}}; - - -let {{ -def LoadStoreBase(name, Name, ea_code, memacc_code, postacc_code = '', - base_class = 'MemoryDisp32', flags = [], - decode_template = BasicDecode, - exec_template = LoadStoreExecute): - # Segregate flags into instruction flags (handled by InstObjParams) - # and memory access flags (handled here). - - # Would be nice to autogenerate this list, but oh well. - valid_mem_flags = ['LOCKED', 'NO_FAULT', 'EVICT_NEXT', 'PF_EXCLUSIVE'] - mem_flags = [f for f in flags if f in valid_mem_flags] - inst_flags = [f for f in flags if f not in valid_mem_flags] - - # add hook to get effective addresses into execution trace output. - ea_code += '\nif (traceData) { traceData->setAddr(EA); }\n' - - # generate code block objects - ea_cblk = CodeBlock(ea_code) - memacc_cblk = CodeBlock(memacc_code) - postacc_cblk = CodeBlock(postacc_code) - - # Some CPU models execute the memory operation as an atomic unit, - # while others want to separate them into an effective address - # computation and a memory access operation. As a result, we need - # to generate three StaticInst objects. Note that the latter two - # are nested inside the larger "atomic" one. - - # generate InstObjParams for EAComp object - ea_iop = InstObjParams(name, Name, base_class, ea_cblk, inst_flags) - - # generate InstObjParams for MemAcc object - memacc_iop = InstObjParams(name, Name, base_class, memacc_cblk, inst_flags) - # in the split execution model, the MemAcc portion is responsible - # for the post-access code. - memacc_iop.postacc_code = postacc_cblk.code - - # generate InstObjParams for unified execution - cblk = CodeBlock(ea_code + memacc_code + postacc_code) - iop = InstObjParams(name, Name, base_class, cblk, inst_flags) - - iop.ea_constructor = ea_cblk.constructor - iop.ea_code = ea_cblk.code - iop.memacc_constructor = memacc_cblk.constructor - iop.memacc_code = memacc_cblk.code - iop.postacc_code = postacc_cblk.code - - if mem_flags: - s = '\n\tmemAccessFlags = ' + string.join(mem_flags, '|') + ';' - iop.constructor += s - memacc_iop.constructor += s - - # (header_output, decoder_output, decode_block, exec_output) - return (LoadStoreDeclare.subst(iop), LoadStoreConstructor.subst(iop), - decode_template.subst(iop), - EACompExecute.subst(ea_iop) - + MemAccExecute.subst(memacc_iop) - + exec_template.subst(iop)) -}}; - - -def format LoadOrNop(ea_code, memacc_code, *flags) {{ - (header_output, decoder_output, decode_block, exec_output) = \ - LoadStoreBase(name, Name, ea_code, memacc_code, flags = flags, - decode_template = LoadNopCheckDecode) -}}; - - -// Note that the flags passed in apply only to the prefetch version -def format LoadOrPrefetch(ea_code, memacc_code, *pf_flags) {{ - # declare the load instruction object and generate the decode block - (header_output, decoder_output, decode_block, exec_output) = \ - LoadStoreBase(name, Name, ea_code, memacc_code, - decode_template = LoadPrefetchCheckDecode) - - # Declare the prefetch instruction object. - - # convert flags from tuple to list to make them mutable - pf_flags = list(pf_flags) + ['IsMemRef', 'IsLoad', 'IsDataPrefetch', 'MemReadOp', 'NO_FAULT'] - - (pf_header_output, pf_decoder_output, _, pf_exec_output) = \ - LoadStoreBase(name, Name + 'Prefetch', ea_code, '', - flags = pf_flags, exec_template = PrefetchExecute) - - header_output += pf_header_output - decoder_output += pf_decoder_output - exec_output += pf_exec_output -}}; - - -def format Store(ea_code, memacc_code, *flags) {{ - (header_output, decoder_output, decode_block, exec_output) = \ - LoadStoreBase(name, Name, ea_code, memacc_code, flags = flags) -}}; - - -def format StoreCond(ea_code, memacc_code, postacc_code, *flags) {{ - (header_output, decoder_output, decode_block, exec_output) = \ - LoadStoreBase(name, Name, ea_code, memacc_code, postacc_code, - flags = flags) -}}; - - -// Use 'MemoryNoDisp' as base: for wh64, fetch, ecb -def format MiscPrefetch(ea_code, memacc_code, *flags) {{ - (header_output, decoder_output, decode_block, exec_output) = \ - LoadStoreBase(name, Name, ea_code, memacc_code, flags = flags, - base_class = 'MemoryNoDisp') -}}; - - -//////////////////////////////////////////////////////////////////// -// -// Control transfer instructions -// - -output header {{ - - /** - * Base class for instructions whose disassembly is not purely a - * function of the machine instruction (i.e., it depends on the - * PC). This class overrides the disassemble() method to check - * the PC and symbol table values before re-using a cached - * disassembly string. This is necessary for branches and jumps, - * where the disassembly string includes the target address (which - * may depend on the PC and/or symbol table). - */ - class PCDependentDisassembly : public AlphaStaticInst - { - protected: - /// Cached program counter from last disassembly - mutable Addr cachedPC; - /// Cached symbol table pointer from last disassembly - mutable const SymbolTable *cachedSymtab; - - /// Constructor - PCDependentDisassembly(const char *mnem, MachInst _machInst, - OpClass __opClass) - : AlphaStaticInst(mnem, _machInst, __opClass), - cachedPC(0), cachedSymtab(0) - { - } - - const std::string & - disassemble(Addr pc, const SymbolTable *symtab) const; - }; - - /** - * Base class for branches (PC-relative control transfers), - * conditional or unconditional. - */ - class Branch : public PCDependentDisassembly - { - protected: - /// Displacement to target address (signed). - int32_t disp; - - /// Constructor. - Branch(const char *mnem, MachInst _machInst, OpClass __opClass) - : PCDependentDisassembly(mnem, _machInst, __opClass), - disp(BRDISP << 2) - { - } - - Addr branchTarget(Addr branchPC) const; - - std::string - generateDisassembly(Addr pc, const SymbolTable *symtab) const; - }; - - /** - * Base class for jumps (register-indirect control transfers). In - * the Alpha ISA, these are always unconditional. - */ - class Jump : public PCDependentDisassembly - { - protected: - - /// Displacement to target address (signed). - int32_t disp; - - public: - /// Constructor - Jump(const char *mnem, MachInst _machInst, OpClass __opClass) - : PCDependentDisassembly(mnem, _machInst, __opClass), - disp(BRDISP) - { - } - - Addr branchTarget(ExecContext *xc) const; - - std::string - generateDisassembly(Addr pc, const SymbolTable *symtab) const; - }; -}}; - -output decoder {{ - Addr - Branch::branchTarget(Addr branchPC) const - { - return branchPC + 4 + disp; - } - - Addr - Jump::branchTarget(ExecContext *xc) const - { - Addr NPC = xc->readPC() + 4; - uint64_t Rb = xc->readIntReg(_srcRegIdx[0]); - return (Rb & ~3) | (NPC & 1); - } - - const std::string & - PCDependentDisassembly::disassemble(Addr pc, - const SymbolTable *symtab) const - { - if (!cachedDisassembly || - pc != cachedPC || symtab != cachedSymtab) - { - if (cachedDisassembly) - delete cachedDisassembly; - - cachedDisassembly = - new std::string(generateDisassembly(pc, symtab)); - cachedPC = pc; - cachedSymtab = symtab; - } - - return *cachedDisassembly; - } - - std::string - Branch::generateDisassembly(Addr pc, const SymbolTable *symtab) const - { - std::stringstream ss; - - ccprintf(ss, "%-10s ", mnemonic); - - // There's only one register arg (RA), but it could be - // either a source (the condition for conditional - // branches) or a destination (the link reg for - // unconditional branches) - if (_numSrcRegs > 0) { - printReg(ss, _srcRegIdx[0]); - ss << ","; - } - else if (_numDestRegs > 0) { - printReg(ss, _destRegIdx[0]); - ss << ","; - } - -#ifdef SS_COMPATIBLE_DISASSEMBLY - if (_numSrcRegs == 0 && _numDestRegs == 0) { - printReg(ss, 31); - ss << ","; - } -#endif - - Addr target = pc + 4 + disp; - - std::string str; - if (symtab && symtab->findSymbol(target, str)) - ss << str; - else - ccprintf(ss, "0x%x", target); - - return ss.str(); - } - - std::string - Jump::generateDisassembly(Addr pc, const SymbolTable *symtab) const - { - std::stringstream ss; - - ccprintf(ss, "%-10s ", mnemonic); - -#ifdef SS_COMPATIBLE_DISASSEMBLY - if (_numDestRegs == 0) { - printReg(ss, 31); - ss << ","; - } -#endif - - if (_numDestRegs > 0) { - printReg(ss, _destRegIdx[0]); - ss << ","; - } - - ccprintf(ss, "(r%d)", RB); - - return ss.str(); - } -}}; - -def template JumpOrBranchDecode {{ - return (RA == 31) - ? (StaticInst *)new %(class_name)s(machInst) - : (StaticInst *)new %(class_name)sAndLink(machInst); -}}; - -def format CondBranch(code) {{ - code = 'bool cond;\n' + code + '\nif (cond) NPC = NPC + disp;\n'; - iop = InstObjParams(name, Name, 'Branch', CodeBlock(code), - ('IsDirectControl', 'IsCondControl')) - header_output = BasicDeclare.subst(iop) - decoder_output = BasicConstructor.subst(iop) - decode_block = BasicDecode.subst(iop) - exec_output = BasicExecute.subst(iop) -}}; - -let {{ -def UncondCtrlBase(name, Name, base_class, npc_expr, flags): - # Declare basic control transfer w/o link (i.e. link reg is R31) - nolink_code = 'NPC = %s;\n' % npc_expr - nolink_iop = InstObjParams(name, Name, base_class, - CodeBlock(nolink_code), flags) - header_output = BasicDeclare.subst(nolink_iop) - decoder_output = BasicConstructor.subst(nolink_iop) - exec_output = BasicExecute.subst(nolink_iop) - - # Generate declaration of '*AndLink' version, append to decls - link_code = 'Ra = NPC & ~3;\n' + nolink_code - link_iop = InstObjParams(name, Name + 'AndLink', base_class, - CodeBlock(link_code), flags) - header_output += BasicDeclare.subst(link_iop) - decoder_output += BasicConstructor.subst(link_iop) - exec_output += BasicExecute.subst(link_iop) - - # need to use link_iop for the decode template since it is expecting - # the shorter version of class_name (w/o "AndLink") - - return (header_output, decoder_output, - JumpOrBranchDecode.subst(nolink_iop), exec_output) -}}; - -def format UncondBranch(*flags) {{ - flags += ('IsUncondControl', 'IsDirectControl') - (header_output, decoder_output, decode_block, exec_output) = \ - UncondCtrlBase(name, Name, 'Branch', 'NPC + disp', flags) -}}; - -def format Jump(*flags) {{ - flags += ('IsUncondControl', 'IsIndirectControl') - (header_output, decoder_output, decode_block, exec_output) = \ - UncondCtrlBase(name, Name, 'Jump', '(Rb & ~3) | (NPC & 1)', flags) -}}; - - -//////////////////////////////////////////////////////////////////// -// -// PAL calls -// - -output header {{ - /** - * Base class for emulated call_pal calls (used only in - * non-full-system mode). - */ - class EmulatedCallPal : public AlphaStaticInst - { - protected: - - /// Constructor. - EmulatedCallPal(const char *mnem, MachInst _machInst, - OpClass __opClass) - : AlphaStaticInst(mnem, _machInst, __opClass) - { - } - - std::string - generateDisassembly(Addr pc, const SymbolTable *symtab) const; - }; -}}; - -output decoder {{ - std::string - EmulatedCallPal::generateDisassembly(Addr pc, - const SymbolTable *symtab) const - { -#ifdef SS_COMPATIBLE_DISASSEMBLY - return csprintf("%s %s", "call_pal", mnemonic); -#else - return csprintf("%-10s %s", "call_pal", mnemonic); -#endif - } -}}; - -def format EmulatedCallPal(code, *flags) {{ - iop = InstObjParams(name, Name, 'EmulatedCallPal', CodeBlock(code), flags) - header_output = BasicDeclare.subst(iop) - decoder_output = BasicConstructor.subst(iop) - decode_block = BasicDecode.subst(iop) - exec_output = BasicExecute.subst(iop) -}}; - -output header {{ - /** - * Base class for full-system-mode call_pal instructions. - * Probably could turn this into a leaf class and get rid of the - * parser template. - */ - class CallPalBase : public AlphaStaticInst - { - protected: - int palFunc; ///< Function code part of instruction - int palOffset; ///< Target PC, offset from IPR_PAL_BASE - bool palValid; ///< is the function code valid? - bool palPriv; ///< is this call privileged? - - /// Constructor. - CallPalBase(const char *mnem, MachInst _machInst, - OpClass __opClass); - - std::string - generateDisassembly(Addr pc, const SymbolTable *symtab) const; - }; -}}; - -output decoder {{ - inline - CallPalBase::CallPalBase(const char *mnem, MachInst _machInst, - OpClass __opClass) - : AlphaStaticInst(mnem, _machInst, __opClass), - palFunc(PALFUNC) - { - // From the 21164 HRM (paraphrased): - // Bit 7 of the function code (mask 0x80) indicates - // whether the call is privileged (bit 7 == 0) or - // unprivileged (bit 7 == 1). The privileged call table - // starts at 0x2000, the unprivielged call table starts at - // 0x3000. Bits 5-0 (mask 0x3f) are used to calculate the - // offset. - const int palPrivMask = 0x80; - const int palOffsetMask = 0x3f; - - // Pal call is invalid unless all other bits are 0 - palValid = ((machInst & ~(palPrivMask | palOffsetMask)) == 0); - palPriv = ((machInst & palPrivMask) == 0); - int shortPalFunc = (machInst & palOffsetMask); - // Add 1 to base to set pal-mode bit - palOffset = (palPriv ? 0x2001 : 0x3001) + (shortPalFunc << 6); - } - - std::string - CallPalBase::generateDisassembly(Addr pc, const SymbolTable *symtab) const - { - return csprintf("%-10s %#x", "call_pal", palFunc); - } -}}; - -def format CallPal(code, *flags) {{ - iop = InstObjParams(name, Name, 'CallPalBase', CodeBlock(code), flags) - header_output = BasicDeclare.subst(iop) - decoder_output = BasicConstructor.subst(iop) - decode_block = BasicDecode.subst(iop) - exec_output = BasicExecute.subst(iop) -}}; - -//////////////////////////////////////////////////////////////////// -// -// hw_ld, hw_st -// - -output header {{ - /** - * Base class for hw_ld and hw_st. - */ - class HwLoadStore : public Memory - { - protected: - - /// Displacement for EA calculation (signed). - int16_t disp; - - /// Constructor - HwLoadStore(const char *mnem, MachInst _machInst, OpClass __opClass, - StaticInstPtr _eaCompPtr = nullStaticInstPtr, - StaticInstPtr _memAccPtr = nullStaticInstPtr); - - std::string - generateDisassembly(Addr pc, const SymbolTable *symtab) const; - }; -}}; - - -output decoder {{ - inline - HwLoadStore::HwLoadStore(const char *mnem, MachInst _machInst, - OpClass __opClass, - StaticInstPtr _eaCompPtr, - StaticInstPtr _memAccPtr) - : Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr), - disp(HW_LDST_DISP) - { - memAccessFlags = 0; - if (HW_LDST_PHYS) memAccessFlags |= PHYSICAL; - if (HW_LDST_ALT) memAccessFlags |= ALTMODE; - if (HW_LDST_VPTE) memAccessFlags |= VPTE; - if (HW_LDST_LOCK) memAccessFlags |= LOCKED; - } - - std::string - HwLoadStore::generateDisassembly(Addr pc, const SymbolTable *symtab) const - { -#ifdef SS_COMPATIBLE_DISASSEMBLY - return csprintf("%-10s r%d,%d(r%d)", mnemonic, RA, disp, RB); -#else - // HW_LDST_LOCK and HW_LDST_COND are the same bit. - const char *lock_str = - (HW_LDST_LOCK) ? (flags[IsLoad] ? ",LOCK" : ",COND") : ""; - - return csprintf("%-10s r%d,%d(r%d)%s%s%s%s%s", - mnemonic, RA, disp, RB, - HW_LDST_PHYS ? ",PHYS" : "", - HW_LDST_ALT ? ",ALT" : "", - HW_LDST_QUAD ? ",QUAD" : "", - HW_LDST_VPTE ? ",VPTE" : "", - lock_str); -#endif - } -}}; - -def format HwLoadStore(ea_code, memacc_code, class_ext, *flags) {{ - (header_output, decoder_output, decode_block, exec_output) = \ - LoadStoreBase(name, Name + class_ext, ea_code, memacc_code, - flags = flags, base_class = 'HwLoadStore') -}}; - - -def format HwStoreCond(ea_code, memacc_code, postacc_code, class_ext, *flags) {{ - (header_output, decoder_output, decode_block, exec_output) = \ - LoadStoreBase(name, Name + class_ext, ea_code, memacc_code, - postacc_code, flags = flags, base_class = 'HwLoadStore') -}}; - - -output header {{ - /** - * Base class for hw_mfpr and hw_mtpr. - */ - class HwMoveIPR : public AlphaStaticInst - { - protected: - /// Index of internal processor register. - int ipr_index; - - /// Constructor - HwMoveIPR(const char *mnem, MachInst _machInst, OpClass __opClass) - : AlphaStaticInst(mnem, _machInst, __opClass), - ipr_index(HW_IPR_IDX) - { - } - - std::string - generateDisassembly(Addr pc, const SymbolTable *symtab) const; - }; -}}; - -output decoder {{ - std::string - HwMoveIPR::generateDisassembly(Addr pc, const SymbolTable *symtab) const - { - if (_numSrcRegs > 0) { - // must be mtpr - return csprintf("%-10s r%d,IPR(%#x)", - mnemonic, RA, ipr_index); - } - else { - // must be mfpr - return csprintf("%-10s IPR(%#x),r%d", - mnemonic, ipr_index, RA); - } - } -}}; - -def format HwMoveIPR(code) {{ - iop = InstObjParams(name, Name, 'HwMoveIPR', CodeBlock(code), - ['IprAccessOp']) - header_output = BasicDeclare.subst(iop) - decoder_output = BasicConstructor.subst(iop) - decode_block = BasicDecode.subst(iop) - exec_output = BasicExecute.subst(iop) -}}; - - -//////////////////////////////////////////////////////////////////// -// -// Unimplemented instructions -// - -output header {{ - /** - * Static instruction class for unimplemented instructions that - * cause simulator termination. Note that these are recognized - * (legal) instructions that the simulator does not support; the - * 'Unknown' class is used for unrecognized/illegal instructions. - * This is a leaf class. - */ - class FailUnimplemented : public AlphaStaticInst - { - public: - /// Constructor - FailUnimplemented(const char *_mnemonic, MachInst _machInst) - : AlphaStaticInst(_mnemonic, _machInst, No_OpClass) - { - // don't call execute() (which panics) if we're on a - // speculative path - flags[IsNonSpeculative] = true; - } - - %(BasicExecDeclare)s - - std::string - generateDisassembly(Addr pc, const SymbolTable *symtab) const; - }; - - /** - * Base class for unimplemented instructions that cause a warning - * to be printed (but do not terminate simulation). This - * implementation is a little screwy in that it will print a - * warning for each instance of a particular unimplemented machine - * instruction, not just for each unimplemented opcode. Should - * probably make the 'warned' flag a static member of the derived - * class. - */ - class WarnUnimplemented : public AlphaStaticInst - { - private: - /// Have we warned on this instruction yet? - mutable bool warned; - - public: - /// Constructor - WarnUnimplemented(const char *_mnemonic, MachInst _machInst) - : AlphaStaticInst(_mnemonic, _machInst, No_OpClass), warned(false) - { - // don't call execute() (which panics) if we're on a - // speculative path - flags[IsNonSpeculative] = true; - } - - %(BasicExecDeclare)s - - std::string - generateDisassembly(Addr pc, const SymbolTable *symtab) const; - }; -}}; - -output decoder {{ - std::string - FailUnimplemented::generateDisassembly(Addr pc, - const SymbolTable *symtab) const - { - return csprintf("%-10s (unimplemented)", mnemonic); - } - - std::string - WarnUnimplemented::generateDisassembly(Addr pc, - const SymbolTable *symtab) const - { -#ifdef SS_COMPATIBLE_DISASSEMBLY - return csprintf("%-10s", mnemonic); -#else - return csprintf("%-10s (unimplemented)", mnemonic); -#endif - } -}}; - -output exec {{ - Fault - FailUnimplemented::execute(%(CPU_exec_context)s *xc, - Trace::InstRecord *traceData) const - { - panic("attempt to execute unimplemented instruction '%s' " - "(inst 0x%08x, opcode 0x%x)", mnemonic, machInst, OPCODE); - return Unimplemented_Opcode_Fault; - } - - Fault - WarnUnimplemented::execute(%(CPU_exec_context)s *xc, - Trace::InstRecord *traceData) const - { - if (!warned) { - warn("instruction '%s' unimplemented\n", mnemonic); - warned = true; - } - - return No_Fault; - } -}}; - - -def format FailUnimpl() {{ - iop = InstObjParams(name, 'FailUnimplemented') - decode_block = BasicDecodeWithMnemonic.subst(iop) -}}; - -def format WarnUnimpl() {{ - iop = InstObjParams(name, 'WarnUnimplemented') - decode_block = BasicDecodeWithMnemonic.subst(iop) -}}; - -output header {{ - /** - * Static instruction class for unknown (illegal) instructions. - * These cause simulator termination if they are executed in a - * non-speculative mode. This is a leaf class. - */ - class Unknown : public AlphaStaticInst - { - public: - /// Constructor - Unknown(MachInst _machInst) - : AlphaStaticInst("unknown", _machInst, No_OpClass) - { - // don't call execute() (which panics) if we're on a - // speculative path - flags[IsNonSpeculative] = true; - } - - %(BasicExecDeclare)s - - std::string - generateDisassembly(Addr pc, const SymbolTable *symtab) const; - }; -}}; - -//////////////////////////////////////////////////////////////////// -// -// Unknown instructions -// - -output decoder {{ - std::string - Unknown::generateDisassembly(Addr pc, const SymbolTable *symtab) const - { - return csprintf("%-10s (inst 0x%x, opcode 0x%x)", - "unknown", machInst, OPCODE); - } -}}; - -output exec {{ - Fault - Unknown::execute(%(CPU_exec_context)s *xc, - Trace::InstRecord *traceData) const - { - panic("attempt to execute unknown instruction " - "(inst 0x%08x, opcode 0x%x)", machInst, OPCODE); - return Unimplemented_Opcode_Fault; - } -}}; - -def format Unknown() {{ - decode_block = 'return new Unknown(machInst);\n' -}}; - -//////////////////////////////////////////////////////////////////// -// -// Utility functions for execute methods -// - -output exec {{ - - /// Return opa + opb, summing carry into third arg. - inline uint64_t - addc(uint64_t opa, uint64_t opb, int &carry) - { - uint64_t res = opa + opb; - if (res < opa || res < opb) - ++carry; - return res; - } - - /// Multiply two 64-bit values (opa * opb), returning the 128-bit - /// product in res_hi and res_lo. - inline void - mul128(uint64_t opa, uint64_t opb, uint64_t &res_hi, uint64_t &res_lo) - { - // do a 64x64 --> 128 multiply using four 32x32 --> 64 multiplies - uint64_t opa_hi = opa<63:32>; - uint64_t opa_lo = opa<31:0>; - uint64_t opb_hi = opb<63:32>; - uint64_t opb_lo = opb<31:0>; - - res_lo = opa_lo * opb_lo; - - // The middle partial products logically belong in bit - // positions 95 to 32. Thus the lower 32 bits of each product - // sum into the upper 32 bits of the low result, while the - // upper 32 sum into the low 32 bits of the upper result. - uint64_t partial1 = opa_hi * opb_lo; - uint64_t partial2 = opa_lo * opb_hi; - - uint64_t partial1_lo = partial1<31:0> << 32; - uint64_t partial1_hi = partial1<63:32>; - uint64_t partial2_lo = partial2<31:0> << 32; - uint64_t partial2_hi = partial2<63:32>; - - // Add partial1_lo and partial2_lo to res_lo, keeping track - // of any carries out - int carry_out = 0; - res_lo = addc(partial1_lo, res_lo, carry_out); - res_lo = addc(partial2_lo, res_lo, carry_out); - - // Now calculate the high 64 bits... - res_hi = (opa_hi * opb_hi) + partial1_hi + partial2_hi + carry_out; - } - - /// Map 8-bit S-floating exponent to 11-bit T-floating exponent. - /// See Table 2-2 of Alpha AHB. - inline int - map_s(int old_exp) - { - int hibit = old_exp<7:>; - int lobits = old_exp<6:0>; - - if (hibit == 1) { - return (lobits == 0x7f) ? 0x7ff : (0x400 | lobits); - } - else { - return (lobits == 0) ? 0 : (0x380 | lobits); - } - } - - /// Convert a 32-bit S-floating value to the equivalent 64-bit - /// representation to be stored in an FP reg. - inline uint64_t - s_to_t(uint32_t s_val) - { - uint64_t tmp = s_val; - return (tmp<31:> << 63 // sign bit - | (uint64_t)map_s(tmp<30:23>) << 52 // exponent - | tmp<22:0> << 29); // fraction - } - - /// Convert a 64-bit T-floating value to the equivalent 32-bit - /// S-floating representation to be stored in memory. - inline int32_t - t_to_s(uint64_t t_val) - { - return (t_val<63:62> << 30 // sign bit & hi exp bit - | t_val<58:29>); // rest of exp & fraction - } -}}; - -//////////////////////////////////////////////////////////////////// -// -// The actual decoder specification -// - -decode OPCODE default Unknown::unknown() { - - format LoadAddress { - 0x08: lda({{ Ra = Rb + disp; }}); - 0x09: ldah({{ Ra = Rb + (disp << 16); }}); - } - - format LoadOrNop { - 0x0a: ldbu({{ EA = Rb + disp; }}, {{ Ra.uq = Mem.ub; }}); - 0x0c: ldwu({{ EA = Rb + disp; }}, {{ Ra.uq = Mem.uw; }}); - 0x0b: ldq_u({{ EA = (Rb + disp) & ~7; }}, {{ Ra = Mem.uq; }}); - 0x23: ldt({{ EA = Rb + disp; }}, {{ Fa = Mem.df; }}); - 0x2a: ldl_l({{ EA = Rb + disp; }}, {{ Ra.sl = Mem.sl; }}, LOCKED); - 0x2b: ldq_l({{ EA = Rb + disp; }}, {{ Ra.uq = Mem.uq; }}, LOCKED); - 0x20: copy_load({{EA = Ra;}}, - {{fault = xc->copySrcTranslate(EA);}}, - IsMemRef, IsLoad, IsCopy); - } - - format LoadOrPrefetch { - 0x28: ldl({{ EA = Rb + disp; }}, {{ Ra.sl = Mem.sl; }}); - 0x29: ldq({{ EA = Rb + disp; }}, {{ Ra.uq = Mem.uq; }}, EVICT_NEXT); - // IsFloating flag on lds gets the prefetch to disassemble - // using f31 instead of r31... funcitonally it's unnecessary - 0x22: lds({{ EA = Rb + disp; }}, {{ Fa.uq = s_to_t(Mem.ul); }}, - PF_EXCLUSIVE, IsFloating); - } - - format Store { - 0x0e: stb({{ EA = Rb + disp; }}, {{ Mem.ub = Ra<7:0>; }}); - 0x0d: stw({{ EA = Rb + disp; }}, {{ Mem.uw = Ra<15:0>; }}); - 0x2c: stl({{ EA = Rb + disp; }}, {{ Mem.ul = Ra<31:0>; }}); - 0x2d: stq({{ EA = Rb + disp; }}, {{ Mem.uq = Ra.uq; }}); - 0x0f: stq_u({{ EA = (Rb + disp) & ~7; }}, {{ Mem.uq = Ra.uq; }}); - 0x26: sts({{ EA = Rb + disp; }}, {{ Mem.ul = t_to_s(Fa.uq); }}); - 0x27: stt({{ EA = Rb + disp; }}, {{ Mem.df = Fa; }}); - 0x24: copy_store({{EA = Rb;}}, - {{fault = xc->copy(EA);}}, - IsMemRef, IsStore, IsCopy); - } - - format StoreCond { - 0x2e: stl_c({{ EA = Rb + disp; }}, {{ Mem.ul = Ra<31:0>; }}, - {{ - uint64_t tmp = Mem_write_result; - // see stq_c - Ra = (tmp == 0 || tmp == 1) ? tmp : Ra; - }}, LOCKED); - 0x2f: stq_c({{ EA = Rb + disp; }}, {{ Mem.uq = Ra; }}, - {{ - uint64_t tmp = Mem_write_result; - // If the write operation returns 0 or 1, then - // this was a conventional store conditional, - // and the value indicates the success/failure - // of the operation. If another value is - // returned, then this was a Turbolaser - // mailbox access, and we don't update the - // result register at all. - Ra = (tmp == 0 || tmp == 1) ? tmp : Ra; - }}, LOCKED); - } - - format IntegerOperate { - - 0x10: decode INTFUNC { // integer arithmetic operations - - 0x00: addl({{ Rc.sl = Ra.sl + Rb_or_imm.sl; }}); - 0x40: addlv({{ - uint32_t tmp = Ra.sl + Rb_or_imm.sl; - // signed overflow occurs when operands have same sign - // and sign of result does not match. - if (Ra.sl<31:> == Rb_or_imm.sl<31:> && tmp<31:> != Ra.sl<31:>) - fault = Integer_Overflow_Fault; - Rc.sl = tmp; - }}); - 0x02: s4addl({{ Rc.sl = (Ra.sl << 2) + Rb_or_imm.sl; }}); - 0x12: s8addl({{ Rc.sl = (Ra.sl << 3) + Rb_or_imm.sl; }}); - - 0x20: addq({{ Rc = Ra + Rb_or_imm; }}); - 0x60: addqv({{ - uint64_t tmp = Ra + Rb_or_imm; - // signed overflow occurs when operands have same sign - // and sign of result does not match. - if (Ra<63:> == Rb_or_imm<63:> && tmp<63:> != Ra<63:>) - fault = Integer_Overflow_Fault; - Rc = tmp; - }}); - 0x22: s4addq({{ Rc = (Ra << 2) + Rb_or_imm; }}); - 0x32: s8addq({{ Rc = (Ra << 3) + Rb_or_imm; }}); - - 0x09: subl({{ Rc.sl = Ra.sl - Rb_or_imm.sl; }}); - 0x49: sublv({{ - uint32_t tmp = Ra.sl - Rb_or_imm.sl; - // signed overflow detection is same as for add, - // except we need to look at the *complemented* - // sign bit of the subtrahend (Rb), i.e., if the initial - // signs are the *same* then no overflow can occur - if (Ra.sl<31:> != Rb_or_imm.sl<31:> && tmp<31:> != Ra.sl<31:>) - fault = Integer_Overflow_Fault; - Rc.sl = tmp; - }}); - 0x0b: s4subl({{ Rc.sl = (Ra.sl << 2) - Rb_or_imm.sl; }}); - 0x1b: s8subl({{ Rc.sl = (Ra.sl << 3) - Rb_or_imm.sl; }}); - - 0x29: subq({{ Rc = Ra - Rb_or_imm; }}); - 0x69: subqv({{ - uint64_t tmp = Ra - Rb_or_imm; - // signed overflow detection is same as for add, - // except we need to look at the *complemented* - // sign bit of the subtrahend (Rb), i.e., if the initial - // signs are the *same* then no overflow can occur - if (Ra<63:> != Rb_or_imm<63:> && tmp<63:> != Ra<63:>) - fault = Integer_Overflow_Fault; - Rc = tmp; - }}); - 0x2b: s4subq({{ Rc = (Ra << 2) - Rb_or_imm; }}); - 0x3b: s8subq({{ Rc = (Ra << 3) - Rb_or_imm; }}); - - 0x2d: cmpeq({{ Rc = (Ra == Rb_or_imm); }}); - 0x6d: cmple({{ Rc = (Ra.sq <= Rb_or_imm.sq); }}); - 0x4d: cmplt({{ Rc = (Ra.sq < Rb_or_imm.sq); }}); - 0x3d: cmpule({{ Rc = (Ra.uq <= Rb_or_imm.uq); }}); - 0x1d: cmpult({{ Rc = (Ra.uq < Rb_or_imm.uq); }}); - - 0x0f: cmpbge({{ - int hi = 7; - int lo = 0; - uint64_t tmp = 0; - for (int i = 0; i < 8; ++i) { - tmp |= (Ra.uq >= Rb_or_imm.uq) << i; - hi += 8; - lo += 8; - } - Rc = tmp; - }}); - } - - 0x11: decode INTFUNC { // integer logical operations - - 0x00: and({{ Rc = Ra & Rb_or_imm; }}); - 0x08: bic({{ Rc = Ra & ~Rb_or_imm; }}); - 0x20: bis({{ Rc = Ra | Rb_or_imm; }}); - 0x28: ornot({{ Rc = Ra | ~Rb_or_imm; }}); - 0x40: xor({{ Rc = Ra ^ Rb_or_imm; }}); - 0x48: eqv({{ Rc = Ra ^ ~Rb_or_imm; }}); - - // conditional moves - 0x14: cmovlbs({{ Rc = ((Ra & 1) == 1) ? Rb_or_imm : Rc; }}); - 0x16: cmovlbc({{ Rc = ((Ra & 1) == 0) ? Rb_or_imm : Rc; }}); - 0x24: cmoveq({{ Rc = (Ra == 0) ? Rb_or_imm : Rc; }}); - 0x26: cmovne({{ Rc = (Ra != 0) ? Rb_or_imm : Rc; }}); - 0x44: cmovlt({{ Rc = (Ra.sq < 0) ? Rb_or_imm : Rc; }}); - 0x46: cmovge({{ Rc = (Ra.sq >= 0) ? Rb_or_imm : Rc; }}); - 0x64: cmovle({{ Rc = (Ra.sq <= 0) ? Rb_or_imm : Rc; }}); - 0x66: cmovgt({{ Rc = (Ra.sq > 0) ? Rb_or_imm : Rc; }}); - - // For AMASK, RA must be R31. - 0x61: decode RA { - 31: amask({{ Rc = Rb_or_imm & ~ULL(0x17); }}); - } - - // For IMPLVER, RA must be R31 and the B operand - // must be the immediate value 1. - 0x6c: decode RA { - 31: decode IMM { - 1: decode INTIMM { - // return EV5 for FULL_SYSTEM and EV6 otherwise - 1: implver({{ -#if FULL_SYSTEM - Rc = 1; -#else - Rc = 2; -#endif - }}); - } - } - } - -#if FULL_SYSTEM - // The mysterious 11.25... - 0x25: WarnUnimpl::eleven25(); -#endif - } - - 0x12: decode INTFUNC { - 0x39: sll({{ Rc = Ra << Rb_or_imm<5:0>; }}); - 0x34: srl({{ Rc = Ra.uq >> Rb_or_imm<5:0>; }}); - 0x3c: sra({{ Rc = Ra.sq >> Rb_or_imm<5:0>; }}); - - 0x02: mskbl({{ Rc = Ra & ~(mask( 8) << (Rb_or_imm<2:0> * 8)); }}); - 0x12: mskwl({{ Rc = Ra & ~(mask(16) << (Rb_or_imm<2:0> * 8)); }}); - 0x22: mskll({{ Rc = Ra & ~(mask(32) << (Rb_or_imm<2:0> * 8)); }}); - 0x32: mskql({{ Rc = Ra & ~(mask(64) << (Rb_or_imm<2:0> * 8)); }}); - - 0x52: mskwh({{ - int bv = Rb_or_imm<2:0>; - Rc = bv ? (Ra & ~(mask(16) >> (64 - 8 * bv))) : Ra; - }}); - 0x62: msklh({{ - int bv = Rb_or_imm<2:0>; - Rc = bv ? (Ra & ~(mask(32) >> (64 - 8 * bv))) : Ra; - }}); - 0x72: mskqh({{ - int bv = Rb_or_imm<2:0>; - Rc = bv ? (Ra & ~(mask(64) >> (64 - 8 * bv))) : Ra; - }}); - - 0x06: extbl({{ Rc = (Ra.uq >> (Rb_or_imm<2:0> * 8))< 7:0>; }}); - 0x16: extwl({{ Rc = (Ra.uq >> (Rb_or_imm<2:0> * 8))<15:0>; }}); - 0x26: extll({{ Rc = (Ra.uq >> (Rb_or_imm<2:0> * 8))<31:0>; }}); - 0x36: extql({{ Rc = (Ra.uq >> (Rb_or_imm<2:0> * 8)); }}); - - 0x5a: extwh({{ - Rc = (Ra << (64 - (Rb_or_imm<2:0> * 8))<5:0>)<15:0>; }}); - 0x6a: extlh({{ - Rc = (Ra << (64 - (Rb_or_imm<2:0> * 8))<5:0>)<31:0>; }}); - 0x7a: extqh({{ - Rc = (Ra << (64 - (Rb_or_imm<2:0> * 8))<5:0>); }}); - - 0x0b: insbl({{ Rc = Ra< 7:0> << (Rb_or_imm<2:0> * 8); }}); - 0x1b: inswl({{ Rc = Ra<15:0> << (Rb_or_imm<2:0> * 8); }}); - 0x2b: insll({{ Rc = Ra<31:0> << (Rb_or_imm<2:0> * 8); }}); - 0x3b: insql({{ Rc = Ra << (Rb_or_imm<2:0> * 8); }}); - - 0x57: inswh({{ - int bv = Rb_or_imm<2:0>; - Rc = bv ? (Ra.uq<15:0> >> (64 - 8 * bv)) : 0; - }}); - 0x67: inslh({{ - int bv = Rb_or_imm<2:0>; - Rc = bv ? (Ra.uq<31:0> >> (64 - 8 * bv)) : 0; - }}); - 0x77: insqh({{ - int bv = Rb_or_imm<2:0>; - Rc = bv ? (Ra.uq >> (64 - 8 * bv)) : 0; - }}); - - 0x30: zap({{ - uint64_t zapmask = 0; - for (int i = 0; i < 8; ++i) { - if (Rb_or_imm) - zapmask |= (mask(8) << (i * 8)); - } - Rc = Ra & ~zapmask; - }}); - 0x31: zapnot({{ - uint64_t zapmask = 0; - for (int i = 0; i < 8; ++i) { - if (!Rb_or_imm) - zapmask |= (mask(8) << (i * 8)); - } - Rc = Ra & ~zapmask; - }}); - } - - 0x13: decode INTFUNC { // integer multiplies - 0x00: mull({{ Rc.sl = Ra.sl * Rb_or_imm.sl; }}, IntMultOp); - 0x20: mulq({{ Rc = Ra * Rb_or_imm; }}, IntMultOp); - 0x30: umulh({{ - uint64_t hi, lo; - mul128(Ra, Rb_or_imm, hi, lo); - Rc = hi; - }}, IntMultOp); - 0x40: mullv({{ - // 32-bit multiply with trap on overflow - int64_t Rax = Ra.sl; // sign extended version of Ra.sl - int64_t Rbx = Rb_or_imm.sl; - int64_t tmp = Rax * Rbx; - // To avoid overflow, all the upper 32 bits must match - // the sign bit of the lower 32. We code this as - // checking the upper 33 bits for all 0s or all 1s. - uint64_t sign_bits = tmp<63:31>; - if (sign_bits != 0 && sign_bits != mask(33)) - fault = Integer_Overflow_Fault; - Rc.sl = tmp<31:0>; - }}, IntMultOp); - 0x60: mulqv({{ - // 64-bit multiply with trap on overflow - uint64_t hi, lo; - mul128(Ra, Rb_or_imm, hi, lo); - // all the upper 64 bits must match the sign bit of - // the lower 64 - if (!((hi == 0 && lo<63:> == 0) || - (hi == mask(64) && lo<63:> == 1))) - fault = Integer_Overflow_Fault; - Rc = lo; - }}, IntMultOp); - } - - 0x1c: decode INTFUNC { - 0x00: decode RA { 31: sextb({{ Rc.sb = Rb_or_imm< 7:0>; }}); } - 0x01: decode RA { 31: sextw({{ Rc.sw = Rb_or_imm<15:0>; }}); } - 0x32: ctlz({{ - uint64_t count = 0; - uint64_t temp = Rb; - if (temp<63:32>) temp >>= 32; else count += 32; - if (temp<31:16>) temp >>= 16; else count += 16; - if (temp<15:8>) temp >>= 8; else count += 8; - if (temp<7:4>) temp >>= 4; else count += 4; - if (temp<3:2>) temp >>= 2; else count += 2; - if (temp<1:1>) temp >>= 1; else count += 1; - if ((temp<0:0>) != 0x1) count += 1; - Rc = count; - }}, IntAluOp); - - 0x33: cttz({{ - uint64_t count = 0; - uint64_t temp = Rb; - if (!(temp<31:0>)) { temp >>= 32; count += 32; } - if (!(temp<15:0>)) { temp >>= 16; count += 16; } - if (!(temp<7:0>)) { temp >>= 8; count += 8; } - if (!(temp<3:0>)) { temp >>= 4; count += 4; } - if (!(temp<1:0>)) { temp >>= 2; count += 2; } - if (!(temp<0:0> & ULL(0x1))) count += 1; - Rc = count; - }}, IntAluOp); - - format FailUnimpl { - 0x30: ctpop(); - 0x31: perr(); - 0x34: unpkbw(); - 0x35: unpkbl(); - 0x36: pkwb(); - 0x37: pklb(); - 0x38: minsb8(); - 0x39: minsw4(); - 0x3a: minub8(); - 0x3b: minuw4(); - 0x3c: maxub8(); - 0x3d: maxuw4(); - 0x3e: maxsb8(); - 0x3f: maxsw4(); - } - - format BasicOperateWithNopCheck { - 0x70: decode RB { - 31: ftoit({{ Rc = Fa.uq; }}, FloatCvtOp); - } - 0x78: decode RB { - 31: ftois({{ Rc.sl = t_to_s(Fa.uq); }}, - FloatCvtOp); - } - } - } - } - - // Conditional branches. - format CondBranch { - 0x39: beq({{ cond = (Ra == 0); }}); - 0x3d: bne({{ cond = (Ra != 0); }}); - 0x3e: bge({{ cond = (Ra.sq >= 0); }}); - 0x3f: bgt({{ cond = (Ra.sq > 0); }}); - 0x3b: ble({{ cond = (Ra.sq <= 0); }}); - 0x3a: blt({{ cond = (Ra.sq < 0); }}); - 0x38: blbc({{ cond = ((Ra & 1) == 0); }}); - 0x3c: blbs({{ cond = ((Ra & 1) == 1); }}); - - 0x31: fbeq({{ cond = (Fa == 0); }}); - 0x35: fbne({{ cond = (Fa != 0); }}); - 0x36: fbge({{ cond = (Fa >= 0); }}); - 0x37: fbgt({{ cond = (Fa > 0); }}); - 0x33: fble({{ cond = (Fa <= 0); }}); - 0x32: fblt({{ cond = (Fa < 0); }}); - } - - // unconditional branches - format UncondBranch { - 0x30: br(); - 0x34: bsr(IsCall); - } - - // indirect branches - 0x1a: decode JMPFUNC { - format Jump { - 0: jmp(); - 1: jsr(IsCall); - 2: ret(IsReturn); - 3: jsr_coroutine(IsCall, IsReturn); - } - } - - // Square root and integer-to-FP moves - 0x14: decode FP_SHORTFUNC { - // Integer to FP register moves must have RB == 31 - 0x4: decode RB { - 31: decode FP_FULLFUNC { - format BasicOperateWithNopCheck { - 0x004: itofs({{ Fc.uq = s_to_t(Ra.ul); }}, FloatCvtOp); - 0x024: itoft({{ Fc.uq = Ra.uq; }}, FloatCvtOp); - 0x014: FailUnimpl::itoff(); // VAX-format conversion - } - } - } - - // Square root instructions must have FA == 31 - 0xb: decode FA { - 31: decode FP_TYPEFUNC { - format FloatingPointOperate { -#if SS_COMPATIBLE_FP - 0x0b: sqrts({{ - if (Fb < 0.0) - fault = Arithmetic_Fault; - Fc = sqrt(Fb); - }}, FloatSqrtOp); -#else - 0x0b: sqrts({{ - if (Fb.sf < 0.0) - fault = Arithmetic_Fault; - Fc.sf = sqrt(Fb.sf); - }}, FloatSqrtOp); -#endif - 0x2b: sqrtt({{ - if (Fb < 0.0) - fault = Arithmetic_Fault; - Fc = sqrt(Fb); - }}, FloatSqrtOp); - } - } - } - - // VAX-format sqrtf and sqrtg are not implemented - 0xa: FailUnimpl::sqrtfg(); - } - - // IEEE floating point - 0x16: decode FP_SHORTFUNC_TOP2 { - // The top two bits of the short function code break this - // space into four groups: binary ops, compares, reserved, and - // conversions. See Table 4-12 of AHB. There are different - // special cases in these different groups, so we decode on - // these top two bits first just to select a decode strategy. - // Most of these instructions may have various trapping and - // rounding mode flags set; these are decoded in the - // FloatingPointDecode template used by the - // FloatingPointOperate format. - - // add/sub/mul/div: just decode on the short function code - // and source type. All valid trapping and rounding modes apply. - 0: decode FP_TRAPMODE { - // check for valid trapping modes here - 0,1,5,7: decode FP_TYPEFUNC { - format FloatingPointOperate { -#if SS_COMPATIBLE_FP - 0x00: adds({{ Fc = Fa + Fb; }}); - 0x01: subs({{ Fc = Fa - Fb; }}); - 0x02: muls({{ Fc = Fa * Fb; }}, FloatMultOp); - 0x03: divs({{ Fc = Fa / Fb; }}, FloatDivOp); -#else - 0x00: adds({{ Fc.sf = Fa.sf + Fb.sf; }}); - 0x01: subs({{ Fc.sf = Fa.sf - Fb.sf; }}); - 0x02: muls({{ Fc.sf = Fa.sf * Fb.sf; }}, FloatMultOp); - 0x03: divs({{ Fc.sf = Fa.sf / Fb.sf; }}, FloatDivOp); -#endif - - 0x20: addt({{ Fc = Fa + Fb; }}); - 0x21: subt({{ Fc = Fa - Fb; }}); - 0x22: mult({{ Fc = Fa * Fb; }}, FloatMultOp); - 0x23: divt({{ Fc = Fa / Fb; }}, FloatDivOp); - } - } - } - - // Floating-point compare instructions must have the default - // rounding mode, and may use the default trapping mode or - // /SU. Both trapping modes are treated the same by M5; the - // only difference on the real hardware (as far a I can tell) - // is that without /SU you'd get an imprecise trap if you - // tried to compare a NaN with something else (instead of an - // "unordered" result). - 1: decode FP_FULLFUNC { - format BasicOperateWithNopCheck { - 0x0a5, 0x5a5: cmpteq({{ Fc = (Fa == Fb) ? 2.0 : 0.0; }}, - FloatCmpOp); - 0x0a7, 0x5a7: cmptle({{ Fc = (Fa <= Fb) ? 2.0 : 0.0; }}, - FloatCmpOp); - 0x0a6, 0x5a6: cmptlt({{ Fc = (Fa < Fb) ? 2.0 : 0.0; }}, - FloatCmpOp); - 0x0a4, 0x5a4: cmptun({{ // unordered - Fc = (!(Fa < Fb) && !(Fa == Fb) && !(Fa > Fb)) ? 2.0 : 0.0; - }}, FloatCmpOp); - } - } - - // The FP-to-integer and integer-to-FP conversion insts - // require that FA be 31. - 3: decode FA { - 31: decode FP_TYPEFUNC { - format FloatingPointOperate { - 0x2f: decode FP_ROUNDMODE { - format FPFixedRounding { - // "chopped" i.e. round toward zero - 0: cvttq({{ Fc.sq = (int64_t)trunc(Fb); }}, - Chopped); - // round to minus infinity - 1: cvttq({{ Fc.sq = (int64_t)floor(Fb); }}, - MinusInfinity); - } - default: cvttq({{ Fc.sq = (int64_t)nearbyint(Fb); }}); - } - - // The cvtts opcode is overloaded to be cvtst if the trap - // mode is 2 or 6 (which are not valid otherwise) - 0x2c: decode FP_FULLFUNC { - format BasicOperateWithNopCheck { - // trap on denorm version "cvtst/s" is - // simulated same as cvtst - 0x2ac, 0x6ac: cvtst({{ Fc = Fb.sf; }}); - } - default: cvtts({{ Fc.sf = Fb; }}); - } - - // The trapping mode for integer-to-FP conversions - // must be /SUI or nothing; /U and /SU are not - // allowed. The full set of rounding modes are - // supported though. - 0x3c: decode FP_TRAPMODE { - 0,7: cvtqs({{ Fc.sf = Fb.sq; }}); - } - 0x3e: decode FP_TRAPMODE { - 0,7: cvtqt({{ Fc = Fb.sq; }}); - } - } - } - } - } - - // misc FP operate - 0x17: decode FP_FULLFUNC { - format BasicOperateWithNopCheck { - 0x010: cvtlq({{ - Fc.sl = (Fb.uq<63:62> << 30) | Fb.uq<58:29>; - }}); - 0x030: cvtql({{ - Fc.uq = (Fb.uq<31:30> << 62) | (Fb.uq<29:0> << 29); - }}); - - // We treat the precise & imprecise trapping versions of - // cvtql identically. - 0x130, 0x530: cvtqlv({{ - // To avoid overflow, all the upper 32 bits must match - // the sign bit of the lower 32. We code this as - // checking the upper 33 bits for all 0s or all 1s. - uint64_t sign_bits = Fb.uq<63:31>; - if (sign_bits != 0 && sign_bits != mask(33)) - fault = Integer_Overflow_Fault; - Fc.uq = (Fb.uq<31:30> << 62) | (Fb.uq<29:0> << 29); - }}); - - 0x020: cpys({{ // copy sign - Fc.uq = (Fa.uq<63:> << 63) | Fb.uq<62:0>; - }}); - 0x021: cpysn({{ // copy sign negated - Fc.uq = (~Fa.uq<63:> << 63) | Fb.uq<62:0>; - }}); - 0x022: cpyse({{ // copy sign and exponent - Fc.uq = (Fa.uq<63:52> << 52) | Fb.uq<51:0>; - }}); - - 0x02a: fcmoveq({{ Fc = (Fa == 0) ? Fb : Fc; }}); - 0x02b: fcmovne({{ Fc = (Fa != 0) ? Fb : Fc; }}); - 0x02c: fcmovlt({{ Fc = (Fa < 0) ? Fb : Fc; }}); - 0x02d: fcmovge({{ Fc = (Fa >= 0) ? Fb : Fc; }}); - 0x02e: fcmovle({{ Fc = (Fa <= 0) ? Fb : Fc; }}); - 0x02f: fcmovgt({{ Fc = (Fa > 0) ? Fb : Fc; }}); - - 0x024: mt_fpcr({{ FPCR = Fa.uq; }}); - 0x025: mf_fpcr({{ Fa.uq = FPCR; }}); - } - } - - // miscellaneous mem-format ops - 0x18: decode MEMFUNC { - format WarnUnimpl { - 0x8000: fetch(); - 0xa000: fetch_m(); - 0xe800: ecb(); - } - - format MiscPrefetch { - 0xf800: wh64({{ EA = Rb & ~ULL(63); }}, - {{ xc->writeHint(EA, 64, memAccessFlags); }}, - IsMemRef, IsDataPrefetch, IsStore, MemWriteOp, - NO_FAULT); - } - - format BasicOperate { - 0xc000: rpcc({{ -#if FULL_SYSTEM - /* Rb is a fake dependency so here is a fun way to get - * the parser to understand that. - */ - Ra = xc->readIpr(AlphaISA::IPR_CC, fault) + (Rb & 0); - -#else - Ra = curTick; -#endif - }}); - - // All of the barrier instructions below do nothing in - // their execute() methods (hence the empty code blocks). - // All of their functionality is hard-coded in the - // pipeline based on the flags IsSerializing, - // IsMemBarrier, and IsWriteBarrier. In the current - // detailed CPU model, the execute() function only gets - // called at fetch, so there's no way to generate pipeline - // behavior at any other stage. Once we go to an - // exec-in-exec CPU model we should be able to get rid of - // these flags and implement this behavior via the - // execute() methods. - - // trapb is just a barrier on integer traps, where excb is - // a barrier on integer and FP traps. "EXCB is thus a - // superset of TRAPB." (Alpha ARM, Sec 4.11.4) We treat - // them the same though. - 0x0000: trapb({{ }}, IsSerializing, No_OpClass); - 0x0400: excb({{ }}, IsSerializing, No_OpClass); - 0x4000: mb({{ }}, IsMemBarrier, MemReadOp); - 0x4400: wmb({{ }}, IsWriteBarrier, MemWriteOp); - } - -#if FULL_SYSTEM - format BasicOperate { - 0xe000: rc({{ - Ra = xc->readIntrFlag(); - xc->setIntrFlag(0); - }}, IsNonSpeculative); - 0xf000: rs({{ - Ra = xc->readIntrFlag(); - xc->setIntrFlag(1); - }}, IsNonSpeculative); - } -#else - format FailUnimpl { - 0xe000: rc(); - 0xf000: rs(); - } -#endif - } - -#if FULL_SYSTEM - 0x00: CallPal::call_pal({{ - if (!palValid || - (palPriv - && xc->readIpr(AlphaISA::IPR_ICM, fault) != AlphaISA::mode_kernel)) { - // invalid pal function code, or attempt to do privileged - // PAL call in non-kernel mode - fault = Unimplemented_Opcode_Fault; - } - else { - // check to see if simulator wants to do something special - // on this PAL call (including maybe suppress it) - bool dopal = xc->simPalCheck(palFunc); - - if (dopal) { - AlphaISA::swap_palshadow(&xc->xcBase()->regs, true); - xc->setIpr(AlphaISA::IPR_EXC_ADDR, NPC); - NPC = xc->readIpr(AlphaISA::IPR_PAL_BASE, fault) + palOffset; - } - } - }}, IsNonSpeculative); -#else - 0x00: decode PALFUNC { - format EmulatedCallPal { - 0x00: halt ({{ - SimExit(curTick, "halt instruction encountered"); - }}, IsNonSpeculative); - 0x83: callsys({{ - xc->syscall(); - }}, IsNonSpeculative); - // Read uniq reg into ABI return value register (r0) - 0x9e: rduniq({{ R0 = Runiq; }}); - // Write uniq reg with value from ABI arg register (r16) - 0x9f: wruniq({{ Runiq = R16; }}); - } - } -#endif - -#if FULL_SYSTEM - format HwLoadStore { - 0x1b: decode HW_LDST_QUAD { - 0: hw_ld({{ EA = (Rb + disp) & ~3; }}, {{ Ra = Mem.ul; }}, L); - 1: hw_ld({{ EA = (Rb + disp) & ~7; }}, {{ Ra = Mem.uq; }}, Q); - } - - 0x1f: decode HW_LDST_COND { - 0: decode HW_LDST_QUAD { - 0: hw_st({{ EA = (Rb + disp) & ~3; }}, - {{ Mem.ul = Ra<31:0>; }}, L); - 1: hw_st({{ EA = (Rb + disp) & ~7; }}, - {{ Mem.uq = Ra.uq; }}, Q); - } - - 1: FailUnimpl::hw_st_cond(); - } - } - - format HwMoveIPR { - 0x19: hw_mfpr({{ - // this instruction is only valid in PAL mode - if (!xc->inPalMode()) { - fault = Unimplemented_Opcode_Fault; - } - else { - Ra = xc->readIpr(ipr_index, fault); - } - }}); - 0x1d: hw_mtpr({{ - // this instruction is only valid in PAL mode - if (!xc->inPalMode()) { - fault = Unimplemented_Opcode_Fault; - } - else { - xc->setIpr(ipr_index, Ra); - if (traceData) { traceData->setData(Ra); } - } - }}); - } - - format BasicOperate { - 0x1e: hw_rei({{ xc->hwrei(); }}, IsSerializing); - - // M5 special opcodes use the reserved 0x01 opcode space - 0x01: decode M5FUNC { - 0x00: arm({{ - AlphaPseudo::arm(xc->xcBase()); - }}, IsNonSpeculative); - 0x01: quiesce({{ - AlphaPseudo::quiesce(xc->xcBase()); - }}, IsNonSpeculative); - 0x10: ivlb({{ - AlphaPseudo::ivlb(xc->xcBase()); - }}, No_OpClass, IsNonSpeculative); - 0x11: ivle({{ - AlphaPseudo::ivle(xc->xcBase()); - }}, No_OpClass, IsNonSpeculative); - 0x20: m5exit_old({{ - AlphaPseudo::m5exit_old(xc->xcBase()); - }}, No_OpClass, IsNonSpeculative); - 0x21: m5exit({{ - AlphaPseudo::m5exit(xc->xcBase()); - }}, No_OpClass, IsNonSpeculative); - 0x30: initparam({{ Ra = xc->xcBase()->cpu->system->init_param; }}); - 0x40: resetstats({{ - AlphaPseudo::resetstats(xc->xcBase()); - }}, IsNonSpeculative); - 0x41: dumpstats({{ - AlphaPseudo::dumpstats(xc->xcBase()); - }}, IsNonSpeculative); - 0x42: dumpresetstats({{ - AlphaPseudo::dumpresetstats(xc->xcBase()); - }}, IsNonSpeculative); - 0x43: m5checkpoint({{ - AlphaPseudo::m5checkpoint(xc->xcBase()); - }}, IsNonSpeculative); - 0x50: m5readfile({{ - AlphaPseudo::readfile(xc->xcBase()); - }}, IsNonSpeculative); - 0x51: m5break({{ - AlphaPseudo::debugbreak(xc->xcBase()); - }}, IsNonSpeculative); - 0x52: m5switchcpu({{ - AlphaPseudo::switchcpu(xc->xcBase()); - }}, IsNonSpeculative); - 0x53: m5addsymbol({{ - AlphaPseudo::addsymbol(xc->xcBase()); - }}, IsNonSpeculative); - - } - } -#endif -} +// The actual decoder +##include "m5/arch/alpha/isa/decoder.isa" diff --git a/arch/alpha/isa/mem.isa b/arch/alpha/isa/mem.isa new file mode 100644 index 000000000..89296626c --- /dev/null +++ b/arch/alpha/isa/mem.isa @@ -0,0 +1,441 @@ +// -*- mode:c++ -*- + +// 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. + +output header {{ + /** + * Base class for general Alpha memory-format instructions. + */ + class Memory : public AlphaStaticInst + { + protected: + + /// Memory request flags. See mem_req_base.hh. + unsigned memAccessFlags; + /// Pointer to EAComp object. + const StaticInstPtr eaCompPtr; + /// Pointer to MemAcc object. + const StaticInstPtr memAccPtr; + + /// Constructor + Memory(const char *mnem, MachInst _machInst, OpClass __opClass, + StaticInstPtr _eaCompPtr = nullStaticInstPtr, + StaticInstPtr _memAccPtr = nullStaticInstPtr) + : AlphaStaticInst(mnem, _machInst, __opClass), + memAccessFlags(0), eaCompPtr(_eaCompPtr), memAccPtr(_memAccPtr) + { + } + + std::string + generateDisassembly(Addr pc, const SymbolTable *symtab) const; + + public: + + const StaticInstPtr &eaCompInst() const { return eaCompPtr; } + const StaticInstPtr &memAccInst() const { return memAccPtr; } + }; + + /** + * Base class for memory-format instructions using a 32-bit + * displacement (i.e. most of them). + */ + class MemoryDisp32 : public Memory + { + protected: + /// Displacement for EA calculation (signed). + int32_t disp; + + /// Constructor. + MemoryDisp32(const char *mnem, MachInst _machInst, OpClass __opClass, + StaticInstPtr _eaCompPtr = nullStaticInstPtr, + StaticInstPtr _memAccPtr = nullStaticInstPtr) + : Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr), + disp(MEMDISP) + { + } + }; + + + /** + * Base class for a few miscellaneous memory-format insts + * that don't interpret the disp field: wh64, fetch, fetch_m, ecb. + * None of these instructions has a destination register either. + */ + class MemoryNoDisp : public Memory + { + protected: + /// Constructor + MemoryNoDisp(const char *mnem, MachInst _machInst, OpClass __opClass, + StaticInstPtr _eaCompPtr = nullStaticInstPtr, + StaticInstPtr _memAccPtr = nullStaticInstPtr) + : Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr) + { + } + + std::string + generateDisassembly(Addr pc, const SymbolTable *symtab) const; + }; +}}; + + +output decoder {{ + std::string + Memory::generateDisassembly(Addr pc, const SymbolTable *symtab) const + { + return csprintf("%-10s %c%d,%d(r%d)", mnemonic, + flags[IsFloating] ? 'f' : 'r', RA, MEMDISP, RB); + } + + std::string + MemoryNoDisp::generateDisassembly(Addr pc, const SymbolTable *symtab) const + { + return csprintf("%-10s (r%d)", mnemonic, RB); + } +}}; + +def format LoadAddress(code) {{ + iop = InstObjParams(name, Name, 'MemoryDisp32', CodeBlock(code)) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecode.subst(iop) + exec_output = BasicExecute.subst(iop) +}}; + + +def template LoadStoreDeclare {{ + /** + * Static instruction class for "%(mnemonic)s". + */ + class %(class_name)s : public %(base_class)s + { + protected: + + /** + * "Fake" effective address computation class for "%(mnemonic)s". + */ + class EAComp : public %(base_class)s + { + public: + /// Constructor + EAComp(MachInst machInst); + + %(BasicExecDeclare)s + }; + + /** + * "Fake" memory access instruction class for "%(mnemonic)s". + */ + class MemAcc : public %(base_class)s + { + public: + /// Constructor + MemAcc(MachInst machInst); + + %(BasicExecDeclare)s + }; + + public: + + /// Constructor. + %(class_name)s(MachInst machInst); + + %(BasicExecDeclare)s + }; +}}; + +def template LoadStoreConstructor {{ + /** TODO: change op_class to AddrGenOp or something (requires + * creating new member of OpClass enum in op_class.hh, updating + * config files, etc.). */ + inline %(class_name)s::EAComp::EAComp(MachInst machInst) + : %(base_class)s("%(mnemonic)s (EAComp)", machInst, IntAluOp) + { + %(ea_constructor)s; + } + + inline %(class_name)s::MemAcc::MemAcc(MachInst machInst) + : %(base_class)s("%(mnemonic)s (MemAcc)", machInst, %(op_class)s) + { + %(memacc_constructor)s; + } + + inline %(class_name)s::%(class_name)s(MachInst machInst) + : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, + new EAComp(machInst), new MemAcc(machInst)) + { + %(constructor)s; + } +}}; + + +def template EACompExecute {{ + Fault + %(class_name)s::EAComp::execute(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + Addr EA; + Fault fault = No_Fault; + + %(fp_enable_check)s; + %(op_decl)s; + %(op_rd)s; + %(code)s; + + if (fault == No_Fault) { + %(op_wb)s; + xc->setEA(EA); + } + + return fault; + } +}}; + +def template MemAccExecute {{ + Fault + %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + Addr EA; + Fault fault = No_Fault; + + %(fp_enable_check)s; + %(op_decl)s; + %(op_nonmem_rd)s; + EA = xc->getEA(); + + if (fault == No_Fault) { + %(op_mem_rd)s; + %(code)s; + } + + if (fault == No_Fault) { + %(op_mem_wb)s; + } + + if (fault == No_Fault) { + %(postacc_code)s; + } + + if (fault == No_Fault) { + %(op_nonmem_wb)s; + } + + return fault; + } +}}; + + +def template LoadStoreExecute {{ + Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + Addr EA; + Fault fault = No_Fault; + + %(fp_enable_check)s; + %(op_decl)s; + %(op_nonmem_rd)s; + %(ea_code)s; + + if (fault == No_Fault) { + %(op_mem_rd)s; + %(memacc_code)s; + } + + if (fault == No_Fault) { + %(op_mem_wb)s; + } + + if (fault == No_Fault) { + %(postacc_code)s; + } + + if (fault == No_Fault) { + %(op_nonmem_wb)s; + } + + return fault; + } +}}; + + +def template PrefetchExecute {{ + Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + Addr EA; + Fault fault = No_Fault; + + %(fp_enable_check)s; + %(op_decl)s; + %(op_nonmem_rd)s; + %(ea_code)s; + + if (fault == No_Fault) { + xc->prefetch(EA, memAccessFlags); + } + + return No_Fault; + } +}}; + +// load instructions use Ra as dest, so check for +// Ra == 31 to detect nops +def template LoadNopCheckDecode {{ + { + AlphaStaticInst *i = new %(class_name)s(machInst); + if (RA == 31) { + i = makeNop(i); + } + return i; + } +}}; + + +// for some load instructions, Ra == 31 indicates a prefetch (not a nop) +def template LoadPrefetchCheckDecode {{ + { + if (RA != 31) { + return new %(class_name)s(machInst); + } + else { + return new %(class_name)sPrefetch(machInst); + } + } +}}; + + +let {{ +def LoadStoreBase(name, Name, ea_code, memacc_code, postacc_code = '', + base_class = 'MemoryDisp32', flags = [], + decode_template = BasicDecode, + exec_template = LoadStoreExecute): + # Segregate flags into instruction flags (handled by InstObjParams) + # and memory access flags (handled here). + + # Would be nice to autogenerate this list, but oh well. + valid_mem_flags = ['LOCKED', 'NO_FAULT', 'EVICT_NEXT', 'PF_EXCLUSIVE'] + mem_flags = [f for f in flags if f in valid_mem_flags] + inst_flags = [f for f in flags if f not in valid_mem_flags] + + # add hook to get effective addresses into execution trace output. + ea_code += '\nif (traceData) { traceData->setAddr(EA); }\n' + + # generate code block objects + ea_cblk = CodeBlock(ea_code) + memacc_cblk = CodeBlock(memacc_code) + postacc_cblk = CodeBlock(postacc_code) + + # Some CPU models execute the memory operation as an atomic unit, + # while others want to separate them into an effective address + # computation and a memory access operation. As a result, we need + # to generate three StaticInst objects. Note that the latter two + # are nested inside the larger "atomic" one. + + # generate InstObjParams for EAComp object + ea_iop = InstObjParams(name, Name, base_class, ea_cblk, inst_flags) + + # generate InstObjParams for MemAcc object + memacc_iop = InstObjParams(name, Name, base_class, memacc_cblk, inst_flags) + # in the split execution model, the MemAcc portion is responsible + # for the post-access code. + memacc_iop.postacc_code = postacc_cblk.code + + # generate InstObjParams for unified execution + cblk = CodeBlock(ea_code + memacc_code + postacc_code) + iop = InstObjParams(name, Name, base_class, cblk, inst_flags) + + iop.ea_constructor = ea_cblk.constructor + iop.ea_code = ea_cblk.code + iop.memacc_constructor = memacc_cblk.constructor + iop.memacc_code = memacc_cblk.code + iop.postacc_code = postacc_cblk.code + + if mem_flags: + s = '\n\tmemAccessFlags = ' + string.join(mem_flags, '|') + ';' + iop.constructor += s + memacc_iop.constructor += s + + # (header_output, decoder_output, decode_block, exec_output) + return (LoadStoreDeclare.subst(iop), LoadStoreConstructor.subst(iop), + decode_template.subst(iop), + EACompExecute.subst(ea_iop) + + MemAccExecute.subst(memacc_iop) + + exec_template.subst(iop)) +}}; + + +def format LoadOrNop(ea_code, memacc_code, *flags) {{ + (header_output, decoder_output, decode_block, exec_output) = \ + LoadStoreBase(name, Name, ea_code, memacc_code, flags = flags, + decode_template = LoadNopCheckDecode) +}}; + + +// Note that the flags passed in apply only to the prefetch version +def format LoadOrPrefetch(ea_code, memacc_code, *pf_flags) {{ + # declare the load instruction object and generate the decode block + (header_output, decoder_output, decode_block, exec_output) = \ + LoadStoreBase(name, Name, ea_code, memacc_code, + decode_template = LoadPrefetchCheckDecode) + + # Declare the prefetch instruction object. + + # convert flags from tuple to list to make them mutable + pf_flags = list(pf_flags) + ['IsMemRef', 'IsLoad', 'IsDataPrefetch', 'MemReadOp', 'NO_FAULT'] + + (pf_header_output, pf_decoder_output, _, pf_exec_output) = \ + LoadStoreBase(name, Name + 'Prefetch', ea_code, '', + flags = pf_flags, exec_template = PrefetchExecute) + + header_output += pf_header_output + decoder_output += pf_decoder_output + exec_output += pf_exec_output +}}; + + +def format Store(ea_code, memacc_code, *flags) {{ + (header_output, decoder_output, decode_block, exec_output) = \ + LoadStoreBase(name, Name, ea_code, memacc_code, flags = flags) +}}; + + +def format StoreCond(ea_code, memacc_code, postacc_code, *flags) {{ + (header_output, decoder_output, decode_block, exec_output) = \ + LoadStoreBase(name, Name, ea_code, memacc_code, postacc_code, + flags = flags) +}}; + + +// Use 'MemoryNoDisp' as base: for wh64, fetch, ecb +def format MiscPrefetch(ea_code, memacc_code, *flags) {{ + (header_output, decoder_output, decode_block, exec_output) = \ + LoadStoreBase(name, Name, ea_code, memacc_code, flags = flags, + base_class = 'MemoryNoDisp') +}}; + + diff --git a/arch/alpha/isa/pal.isa b/arch/alpha/isa/pal.isa new file mode 100644 index 000000000..9debffa38 --- /dev/null +++ b/arch/alpha/isa/pal.isa @@ -0,0 +1,260 @@ +// -*- mode:c++ -*- + +// 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. + +output header {{ + /** + * Base class for emulated call_pal calls (used only in + * non-full-system mode). + */ + class EmulatedCallPal : public AlphaStaticInst + { + protected: + + /// Constructor. + EmulatedCallPal(const char *mnem, MachInst _machInst, + OpClass __opClass) + : AlphaStaticInst(mnem, _machInst, __opClass) + { + } + + std::string + generateDisassembly(Addr pc, const SymbolTable *symtab) const; + }; +}}; + +output decoder {{ + std::string + EmulatedCallPal::generateDisassembly(Addr pc, + const SymbolTable *symtab) const + { +#ifdef SS_COMPATIBLE_DISASSEMBLY + return csprintf("%s %s", "call_pal", mnemonic); +#else + return csprintf("%-10s %s", "call_pal", mnemonic); +#endif + } +}}; + +def format EmulatedCallPal(code, *flags) {{ + iop = InstObjParams(name, Name, 'EmulatedCallPal', CodeBlock(code), flags) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecode.subst(iop) + exec_output = BasicExecute.subst(iop) +}}; + +output header {{ + /** + * Base class for full-system-mode call_pal instructions. + * Probably could turn this into a leaf class and get rid of the + * parser template. + */ + class CallPalBase : public AlphaStaticInst + { + protected: + int palFunc; ///< Function code part of instruction + int palOffset; ///< Target PC, offset from IPR_PAL_BASE + bool palValid; ///< is the function code valid? + bool palPriv; ///< is this call privileged? + + /// Constructor. + CallPalBase(const char *mnem, MachInst _machInst, + OpClass __opClass); + + std::string + generateDisassembly(Addr pc, const SymbolTable *symtab) const; + }; +}}; + +output decoder {{ + inline + CallPalBase::CallPalBase(const char *mnem, MachInst _machInst, + OpClass __opClass) + : AlphaStaticInst(mnem, _machInst, __opClass), + palFunc(PALFUNC) + { + // From the 21164 HRM (paraphrased): + // Bit 7 of the function code (mask 0x80) indicates + // whether the call is privileged (bit 7 == 0) or + // unprivileged (bit 7 == 1). The privileged call table + // starts at 0x2000, the unprivielged call table starts at + // 0x3000. Bits 5-0 (mask 0x3f) are used to calculate the + // offset. + const int palPrivMask = 0x80; + const int palOffsetMask = 0x3f; + + // Pal call is invalid unless all other bits are 0 + palValid = ((machInst & ~(palPrivMask | palOffsetMask)) == 0); + palPriv = ((machInst & palPrivMask) == 0); + int shortPalFunc = (machInst & palOffsetMask); + // Add 1 to base to set pal-mode bit + palOffset = (palPriv ? 0x2001 : 0x3001) + (shortPalFunc << 6); + } + + std::string + CallPalBase::generateDisassembly(Addr pc, const SymbolTable *symtab) const + { + return csprintf("%-10s %#x", "call_pal", palFunc); + } +}}; + +def format CallPal(code, *flags) {{ + iop = InstObjParams(name, Name, 'CallPalBase', CodeBlock(code), flags) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecode.subst(iop) + exec_output = BasicExecute.subst(iop) +}}; + +//////////////////////////////////////////////////////////////////// +// +// hw_ld, hw_st +// + +output header {{ + /** + * Base class for hw_ld and hw_st. + */ + class HwLoadStore : public Memory + { + protected: + + /// Displacement for EA calculation (signed). + int16_t disp; + + /// Constructor + HwLoadStore(const char *mnem, MachInst _machInst, OpClass __opClass, + StaticInstPtr _eaCompPtr = nullStaticInstPtr, + StaticInstPtr _memAccPtr = nullStaticInstPtr); + + std::string + generateDisassembly(Addr pc, const SymbolTable *symtab) const; + }; +}}; + + +output decoder {{ + inline + HwLoadStore::HwLoadStore(const char *mnem, MachInst _machInst, + OpClass __opClass, + StaticInstPtr _eaCompPtr, + StaticInstPtr _memAccPtr) + : Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr), + disp(HW_LDST_DISP) + { + memAccessFlags = 0; + if (HW_LDST_PHYS) memAccessFlags |= PHYSICAL; + if (HW_LDST_ALT) memAccessFlags |= ALTMODE; + if (HW_LDST_VPTE) memAccessFlags |= VPTE; + if (HW_LDST_LOCK) memAccessFlags |= LOCKED; + } + + std::string + HwLoadStore::generateDisassembly(Addr pc, const SymbolTable *symtab) const + { +#ifdef SS_COMPATIBLE_DISASSEMBLY + return csprintf("%-10s r%d,%d(r%d)", mnemonic, RA, disp, RB); +#else + // HW_LDST_LOCK and HW_LDST_COND are the same bit. + const char *lock_str = + (HW_LDST_LOCK) ? (flags[IsLoad] ? ",LOCK" : ",COND") : ""; + + return csprintf("%-10s r%d,%d(r%d)%s%s%s%s%s", + mnemonic, RA, disp, RB, + HW_LDST_PHYS ? ",PHYS" : "", + HW_LDST_ALT ? ",ALT" : "", + HW_LDST_QUAD ? ",QUAD" : "", + HW_LDST_VPTE ? ",VPTE" : "", + lock_str); +#endif + } +}}; + +def format HwLoadStore(ea_code, memacc_code, class_ext, *flags) {{ + (header_output, decoder_output, decode_block, exec_output) = \ + LoadStoreBase(name, Name + class_ext, ea_code, memacc_code, + flags = flags, base_class = 'HwLoadStore') +}}; + + +def format HwStoreCond(ea_code, memacc_code, postacc_code, class_ext, *flags) {{ + (header_output, decoder_output, decode_block, exec_output) = \ + LoadStoreBase(name, Name + class_ext, ea_code, memacc_code, + postacc_code, flags = flags, base_class = 'HwLoadStore') +}}; + + +output header {{ + /** + * Base class for hw_mfpr and hw_mtpr. + */ + class HwMoveIPR : public AlphaStaticInst + { + protected: + /// Index of internal processor register. + int ipr_index; + + /// Constructor + HwMoveIPR(const char *mnem, MachInst _machInst, OpClass __opClass) + : AlphaStaticInst(mnem, _machInst, __opClass), + ipr_index(HW_IPR_IDX) + { + } + + std::string + generateDisassembly(Addr pc, const SymbolTable *symtab) const; + }; +}}; + +output decoder {{ + std::string + HwMoveIPR::generateDisassembly(Addr pc, const SymbolTable *symtab) const + { + if (_numSrcRegs > 0) { + // must be mtpr + return csprintf("%-10s r%d,IPR(%#x)", + mnemonic, RA, ipr_index); + } + else { + // must be mfpr + return csprintf("%-10s IPR(%#x),r%d", + mnemonic, ipr_index, RA); + } + } +}}; + +def format HwMoveIPR(code) {{ + iop = InstObjParams(name, Name, 'HwMoveIPR', CodeBlock(code), + ['IprAccessOp']) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecode.subst(iop) + exec_output = BasicExecute.subst(iop) +}}; + + diff --git a/arch/alpha/isa/unimp.isa b/arch/alpha/isa/unimp.isa new file mode 100644 index 000000000..767888157 --- /dev/null +++ b/arch/alpha/isa/unimp.isa @@ -0,0 +1,165 @@ +// -*- mode:c++ -*- + +// 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. + +output header {{ + /** + * Static instruction class for unimplemented instructions that + * cause simulator termination. Note that these are recognized + * (legal) instructions that the simulator does not support; the + * 'Unknown' class is used for unrecognized/illegal instructions. + * This is a leaf class. + */ + class FailUnimplemented : public AlphaStaticInst + { + public: + /// Constructor + FailUnimplemented(const char *_mnemonic, MachInst _machInst) + : AlphaStaticInst(_mnemonic, _machInst, No_OpClass) + { + // don't call execute() (which panics) if we're on a + // speculative path + flags[IsNonSpeculative] = true; + } + + %(BasicExecDeclare)s + + std::string + generateDisassembly(Addr pc, const SymbolTable *symtab) const; + }; + + /** + * Base class for unimplemented instructions that cause a warning + * to be printed (but do not terminate simulation). This + * implementation is a little screwy in that it will print a + * warning for each instance of a particular unimplemented machine + * instruction, not just for each unimplemented opcode. Should + * probably make the 'warned' flag a static member of the derived + * class. + */ + class WarnUnimplemented : public AlphaStaticInst + { + private: + /// Have we warned on this instruction yet? + mutable bool warned; + + public: + /// Constructor + WarnUnimplemented(const char *_mnemonic, MachInst _machInst) + : AlphaStaticInst(_mnemonic, _machInst, No_OpClass), warned(false) + { + // don't call execute() (which panics) if we're on a + // speculative path + flags[IsNonSpeculative] = true; + } + + %(BasicExecDeclare)s + + std::string + generateDisassembly(Addr pc, const SymbolTable *symtab) const; + }; +}}; + +output decoder {{ + std::string + FailUnimplemented::generateDisassembly(Addr pc, + const SymbolTable *symtab) const + { + return csprintf("%-10s (unimplemented)", mnemonic); + } + + std::string + WarnUnimplemented::generateDisassembly(Addr pc, + const SymbolTable *symtab) const + { +#ifdef SS_COMPATIBLE_DISASSEMBLY + return csprintf("%-10s", mnemonic); +#else + return csprintf("%-10s (unimplemented)", mnemonic); +#endif + } +}}; + +output exec {{ + Fault + FailUnimplemented::execute(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + panic("attempt to execute unimplemented instruction '%s' " + "(inst 0x%08x, opcode 0x%x)", mnemonic, machInst, OPCODE); + return Unimplemented_Opcode_Fault; + } + + Fault + WarnUnimplemented::execute(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + if (!warned) { + warn("instruction '%s' unimplemented\n", mnemonic); + warned = true; + } + + return No_Fault; + } +}}; + + +def format FailUnimpl() {{ + iop = InstObjParams(name, 'FailUnimplemented') + decode_block = BasicDecodeWithMnemonic.subst(iop) +}}; + +def format WarnUnimpl() {{ + iop = InstObjParams(name, 'WarnUnimplemented') + decode_block = BasicDecodeWithMnemonic.subst(iop) +}}; + +output header {{ + /** + * Static instruction class for unknown (illegal) instructions. + * These cause simulator termination if they are executed in a + * non-speculative mode. This is a leaf class. + */ + class Unknown : public AlphaStaticInst + { + public: + /// Constructor + Unknown(MachInst _machInst) + : AlphaStaticInst("unknown", _machInst, No_OpClass) + { + // don't call execute() (which panics) if we're on a + // speculative path + flags[IsNonSpeculative] = true; + } + + %(BasicExecDeclare)s + + std::string + generateDisassembly(Addr pc, const SymbolTable *symtab) const; + }; +}}; + diff --git a/arch/alpha/isa/unknown.isa b/arch/alpha/isa/unknown.isa new file mode 100644 index 000000000..6eba5b4f9 --- /dev/null +++ b/arch/alpha/isa/unknown.isa @@ -0,0 +1,52 @@ +// -*- mode:c++ -*- + +// 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. + +output decoder {{ + std::string + Unknown::generateDisassembly(Addr pc, const SymbolTable *symtab) const + { + return csprintf("%-10s (inst 0x%x, opcode 0x%x)", + "unknown", machInst, OPCODE); + } +}}; + +output exec {{ + Fault + Unknown::execute(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + panic("attempt to execute unknown instruction " + "(inst 0x%08x, opcode 0x%x)", machInst, OPCODE); + return Unimplemented_Opcode_Fault; + } +}}; + +def format Unknown() {{ + decode_block = 'return new Unknown(machInst);\n' +}}; + diff --git a/arch/alpha/isa/util.isa b/arch/alpha/isa/util.isa new file mode 100644 index 000000000..9fbbf6636 --- /dev/null +++ b/arch/alpha/isa/util.isa @@ -0,0 +1,112 @@ +// -*- mode:c++ -*- + +// 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. + +output exec {{ + + /// Return opa + opb, summing carry into third arg. + inline uint64_t + addc(uint64_t opa, uint64_t opb, int &carry) + { + uint64_t res = opa + opb; + if (res < opa || res < opb) + ++carry; + return res; + } + + /// Multiply two 64-bit values (opa * opb), returning the 128-bit + /// product in res_hi and res_lo. + inline void + mul128(uint64_t opa, uint64_t opb, uint64_t &res_hi, uint64_t &res_lo) + { + // do a 64x64 --> 128 multiply using four 32x32 --> 64 multiplies + uint64_t opa_hi = opa<63:32>; + uint64_t opa_lo = opa<31:0>; + uint64_t opb_hi = opb<63:32>; + uint64_t opb_lo = opb<31:0>; + + res_lo = opa_lo * opb_lo; + + // The middle partial products logically belong in bit + // positions 95 to 32. Thus the lower 32 bits of each product + // sum into the upper 32 bits of the low result, while the + // upper 32 sum into the low 32 bits of the upper result. + uint64_t partial1 = opa_hi * opb_lo; + uint64_t partial2 = opa_lo * opb_hi; + + uint64_t partial1_lo = partial1<31:0> << 32; + uint64_t partial1_hi = partial1<63:32>; + uint64_t partial2_lo = partial2<31:0> << 32; + uint64_t partial2_hi = partial2<63:32>; + + // Add partial1_lo and partial2_lo to res_lo, keeping track + // of any carries out + int carry_out = 0; + res_lo = addc(partial1_lo, res_lo, carry_out); + res_lo = addc(partial2_lo, res_lo, carry_out); + + // Now calculate the high 64 bits... + res_hi = (opa_hi * opb_hi) + partial1_hi + partial2_hi + carry_out; + } + + /// Map 8-bit S-floating exponent to 11-bit T-floating exponent. + /// See Table 2-2 of Alpha AHB. + inline int + map_s(int old_exp) + { + int hibit = old_exp<7:>; + int lobits = old_exp<6:0>; + + if (hibit == 1) { + return (lobits == 0x7f) ? 0x7ff : (0x400 | lobits); + } + else { + return (lobits == 0) ? 0 : (0x380 | lobits); + } + } + + /// Convert a 32-bit S-floating value to the equivalent 64-bit + /// representation to be stored in an FP reg. + inline uint64_t + s_to_t(uint32_t s_val) + { + uint64_t tmp = s_val; + return (tmp<31:> << 63 // sign bit + | (uint64_t)map_s(tmp<30:23>) << 52 // exponent + | tmp<22:0> << 29); // fraction + } + + /// Convert a 64-bit T-floating value to the equivalent 32-bit + /// S-floating representation to be stored in memory. + inline int32_t + t_to_s(uint64_t t_val) + { + return (t_val<63:62> << 30 // sign bit & hi exp bit + | t_val<58:29>); // rest of exp & fraction + } +}}; + From 5cfc5e80802f1b5aa240a289bcf0267b5f829aa4 Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Fri, 10 Feb 2006 03:27:19 -0500 Subject: [PATCH 033/180] The first fully coded version of decoder.isa!!!!! ================================================= -every MIPS32 ISA is represented with some type of code block. -any instruction that doesnt have a code block would be of format WarnUnimpl. Examples of the ones I am waiting on further info to implement are the TLB register insts, memory consistency instructions (ll,sc,etc.) and software debug insts. --HG-- extra : convert_revision : 4a26c72e4fa1f63b8689fe2631a7508daf660969 --- arch/mips/isa/decoder.isa | 321 ++++++++++++++++++++++++-------------- 1 file changed, 204 insertions(+), 117 deletions(-) diff --git a/arch/mips/isa/decoder.isa b/arch/mips/isa/decoder.isa index acd00e70d..d6fd90657 100644 --- a/arch/mips/isa/decoder.isa +++ b/arch/mips/isa/decoder.isa @@ -66,7 +66,7 @@ decode OPCODE_HI default FailUnimpl::unknown() { 0x3: movn({{ if (Rt != 0) Rd = Rs; }}); } - format Trap { + format WarnUnimpl { 0x4: syscall({{ xc->syscall()}},IsNonSpeculative); 0x5: break({{ }}); 0x7: sync({{ }}); @@ -131,12 +131,12 @@ decode OPCODE_HI default FailUnimpl::unknown() { 0x6: decode FUNCTION_LO { format Trap { - 0x0: tge({{ }}); - 0x1: tgeu({{ }}); - 0x2: tlt({{ }}); - 0x3: tltu({{ }}); - 0x4: teq({{ }}); - 0x6: tne({{ }}); + 0x0: tge({{ cond = (Rs.sw >= Rt.sw); }}); + 0x1: tgeu({{ cond = (Rs.uw >= Rt.uw); }}); + 0x2: tlt({{ cond = (Rs.sw < Rt.sw); }}); + 0x3: tltu({{ cond = (Rs.uw >= Rt.uw); }}); + 0x4: teq({{ cond = (Rs.sw == Rt.sw); }}); + 0x6: tne({{ cond = (Rs.sw != Rt.sw); }}); } } } @@ -155,12 +155,12 @@ decode OPCODE_HI default FailUnimpl::unknown() { 0x1: decode REGIMM_LO { format Trap { - 0x0: tgei({{ }}); - 0x1: tgeiu({{ }}); - 0x2: tlti({{ }}); - 0x3: tltiu({{ }}); - 0x4: teqi({{ }}); - 0x6: tnei({{ }}); + 0x0: tgei({{ cond = (Rs.sw >= INTIMM; }}); + 0x1: tgeiu({{ cond = (Rs.uw < INTIMM); }}); + 0x2: tlti({{ cond = (Rs.sw < INTIMM); }}); + 0x3: tltiu({{ cond = (Rs.uw < INTIMM); }}); + 0x4: teqi({{ cond = (Rs.sw == INTIMM); }}); + 0x6: tnei({{ cond = (Rs.sw != INTIMM); }}); } } @@ -176,7 +176,7 @@ decode OPCODE_HI default FailUnimpl::unknown() { } 0x3: decode REGIMM_LO { - format Trap { + format WarnUnimpl { 0x7: synci({{ }}); } } @@ -334,61 +334,69 @@ decode OPCODE_HI default FailUnimpl::unknown() { 0x0: decode RS_HI { 0x0: decode RS_LO { format FloatOp { - 0x0: add_fmt({{ }}); - 0x1: sub_fmt({{ }}); - 0x2: mul_fmt({{ }}); - 0x3: div_fmt({{ }}); - 0x4: sqrt_fmt({{ }}); - 0x5: abs_fmt({{ }}); - 0x6: mov_fmt({{ }}); - 0x7: neg_fmt({{ }}); + 0x0: adds({{ Fd.sf = Fs.sf + Ft.sf;}}); + 0x1: subs({{ Fd.sf = Fs.sf - Ft.sf;}}); + 0x2: muls({{ Fd.sf = Fs.sf * Ft.sf;}}); + 0x3: divs({{ Fd.sf = Fs.sf / Ft.sf;}}); + 0x4: sqrts({{ Fd.sf = sqrt(Fs.sf);}}); + 0x5: abss({{ Fd.sf = abs(Fs.sf);}}); + 0x6: movs({{ Fd.sf = Fs.sf;}}); + 0x7: negs({{ Fd.sf = -1 * Fs.sf;}}); } } 0x1: decode RS_LO { //only legal for 64 bit format Float64Op { - 0x0: round_l({{ }}); - 0x1: trunc_l({{ }}); - 0x2: ceil_l({{ }}); - 0x3: floor_l({{ }}); + 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);}}); } format FloatOp { - 0x4: round_w({{ }}); - 0x5: trunc_w({{ }}); - 0x6: ceil_w({{ }}); - 0x7: floor_w({{ }}); + 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);}}); } } 0x2: decode RS_LO { 0x1: decode MOVCF { format FloatOp { - 0x0: movf_fmt({{ }}); - 0x1: movt_fmt({{ }}); + 0x0: movfs({{ if ( FPConditionCode(CC) == 0 ) Fd = Fs; }}); + 0x1: movts({{ if ( FPConditionCode(CC) == 1 ) Fd = Fs;}}); } } format BasicOp { - 0x2: movz({{ if (Rt == 0) Rd = Rs; }}); - 0x3: movn({{ if (Rt != 0) Rd = Rs; }}); + 0x2: movzs({{ if (Rt == 0) Fd = Fs; }}); + 0x3: movns({{ if (Rt != 0) Fd = Fs; }}); } format Float64Op { - 0x2: recip({{ }}); - 0x3: rsqrt{{ }}); + 0x2: recips({{ Fd = 1 / Fs; }}); + 0x3: rsqrts{{ Fd = 1 / sqrt(Fs); }}); } } 0x4: decode RS_LO { - 0x1: cvt_d({{ }}); - 0x4: cvt_w({{ }}); + 0x1: cvt_d_s({{ int rnd_mode = xc->miscRegs.fcsr; + Fd = convert_and_round(Fs.sf,rnd_mode,FP_DOUBLE,FP_SINGLE); + }}); + + 0x4: cvt_w_s({{ int rnd_mode = xc->miscRegs.fcsr; + Fd = convert_and_round(Fs.sf,rnd_mode,FP_WORD,FP_SINGLE); + }}); //only legal for 64 bit format Float64Op { - 0x5: cvt_l({{ }}); - 0x6: cvt_ps({{ }}); + 0x5: cvt_l_s({{ int rnd_mode = xc->miscRegs.fcsr; + Fd = convert_and_round(Fs.sf,rnd_mode,FP_LONG,FP_SINGLE); + }}); + + 0x6: cvt_ps_s({{ Fd.df = Fs.df<31:0> | Ft.df<31:0>; }}); } } } @@ -397,62 +405,72 @@ decode OPCODE_HI default FailUnimpl::unknown() { 0x1: decode RS_HI { 0x0: decode RS_LO { format FloatOp { - 0x0: add_fmt({{ }}); - 0x1: sub_fmt({{ }}); - 0x2: mul_fmt({{ }}); - 0x3: div_fmt({{ }}); - 0x4: sqrt_fmt({{ }}); - 0x5: abs_fmt({{ }}); - 0x6: mov_fmt({{ }}); - 0x7: neg_fmt({{ }}); + 0x0: addd({{ Fd.df = Fs.df + Ft.df;}}); + 0x1: subd({{ Fd.df = Fs.df - Ft.df;}}); + 0x2: muld({{ Fd.df = Fs.df * Ft.df;}}); + 0x3: divd({{ Fd.df = Fs.df / Ft.df;}}); + 0x4: sqrtd({{ Fd.df = sqrt(Fs.df);}}); + 0x5: absd({{ Fd.df = abs(Fs.df);}}); + 0x6: movd({{ Fd.df = Fs.df;}}); + 0x7: negd({{ Fd.df = -1 * Fs.df;}}); } } 0x1: decode RS_LO { //only legal for 64 bit format FloatOp64 { - 0x0: round_l({{ }}); - 0x1: trunc_l({{ }}); - 0x2: ceil_l({{ }}); - 0x3: floor_l({{ }}); + 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);}}); } format FloatOp { - 0x4: round_w({{ }}); - 0x5: trunc_w({{ }}); - 0x6: ceil_w({{ }}); - 0x7: floor_w({{ }}); + 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); }}); } } 0x2: decode RS_LO { 0x1: decode MOVCF { format FloatOp { - 0x0: movf_fmt({{ }}); - 0x1: movt_fmt({{ }}); + 0x0: movfd({{ if (FPConditionCode(CC) == 0) Fd.df = Fs.df; }}); + 0x1: movtd({{ if (FPConditionCode(CC) == 1) Fd.df = Fs.df; }}); } } format BasicOp { - 0x2: movz({{ if (Rt == 0) Rd = Rs; }}); - 0x3: movn({{ if (Rt != 0) Rd = Rs; }}); + 0x2: movz({{ if (Rt == 0) Fd.df = Fs.df; }}); + 0x3: movn({{ if (Rt != 0) Fd.df = Fs.df; }}); } format FloatOp64 { - 0x5: recip({{ }}); - 0x6: rsqrt{{ }}); + 0x5: recipd({{ Fd.df = 1 / Fs.df}}); + 0x6: rsqrtd{{ Fd.df = 1 / sqrt(Fs.df) }}); } } 0x4: decode RS_LO { format FloatOp { - 0x0: cvt_s({{ }}); - 0x4: cvt_w({{ }}); + 0x0: cvt_s_d({{ + int rnd_mode = xc->miscRegs.fcsr; + Fd = convert_and_round(Fs.df,rnd_mode,FP_SINGLE,FP_DOUBLE); + }}); + + 0x4: cvt_w_d({{ + int rnd_mode = xc->miscRegs.fcsr; + Fd = convert_and_round(Fs.df,rnd_mode,FP_WORD,FP_DOUBLE); + }}); } //only legal for 64 bit format FloatOp64 { - 0x5: cvt_l({{ }}); + 0x5: cvt_l_d({{ + int rnd_mode = xc->miscRegs.fcsr; + Fd = convert_and_round(Fs.df,rnd_mode,FP_LONG,FP_DOUBLE); + }}); } } } @@ -460,8 +478,15 @@ decode OPCODE_HI default FailUnimpl::unknown() { //Table A-16 MIPS32 COP1 Encoding of Function Field When rs=W 0x4: decode FUNCTION { format FloatOp { - 0x10: cvt_s({{ }}); - 0x10: cvt_d({{ }}); + 0x10: cvt_s({{ + int rnd_mode = xc->miscRegs.fcsr; + Fd = convert_and_round(Fs.df,rnd_mode,FP_SINGLE,FP_WORD); + }}); + + 0x10: cvt_d({{ + int rnd_mode = xc->miscRegs.fcsr; + Fd = convert_and_round(Fs.df,rnd_mode,FP_DOUBLE,FP_WORD); + }}); } } @@ -470,8 +495,15 @@ decode OPCODE_HI default FailUnimpl::unknown() { //are enabled." 0x5: decode FUNCTION_HI { format FloatOp { - 0x10: cvt_s({{ }}); - 0x11: cvt_d({{ }}); + 0x10: cvt_s_l({{ + int rnd_mode = xc->miscRegs.fcsr; + Fd = convert_and_round(Fs.df,rnd_mode,FP_SINGLE,FP_LONG); + }}); + + 0x11: cvt_d_l({{ + int rnd_mode = xc->miscRegs.fcsr; + Fd = convert_and_round(Fs.df,rnd_mode,FP_DOUBLE,FP_LONG); + }}); } } @@ -481,36 +513,65 @@ decode OPCODE_HI default FailUnimpl::unknown() { 0x6: decode RS_HI { 0x0: decode RS_LO { format FloatOp64 { - 0x0: add_fmt({{ }}); - 0x1: sub_fmt({{ }}); - 0x2: mul_fmt({{ }}); - 0x5: abs_fmt({{ }}); - 0x6: mov_fmt({{ }}); - 0x7: neg_fmt({{ }}); + 0x0: addps({{ //Must Check for Exception Here... Supposed to Operate on Upper and + //Lower Halves Independently but we take simulator shortcut + Fd.df = Fs.df + Ft.df; + }}); + + 0x1: subps({{ //Must Check for Exception Here... Supposed to Operate on Upper and + //Lower Halves Independently but we take simulator shortcut + Fd.df = Fs.df - Ft.df; + }}); + + 0x2: mulps({{ //Must Check for Exception Here... Supposed to Operate on Upper and + //Lower Halves Independently but we take simulator shortcut + Fd.df = Fs.df * Ft.df; + }}); + + 0x5: absps({{ //Must Check for Exception Here... Supposed to Operate on Upper and + //Lower Halves Independently but we take simulator shortcut + Fd.df = abs(Fs.df); + }}); + + 0x6: movps({{ //Must Check for Exception Here... Supposed to Operate on Upper and + //Lower Halves Independently but we take simulator shortcut + Fd.df = Fs<31:0> | Ft<31:0>; + }}); + + 0x7: negps({{ //Must Check for Exception Here... Supposed to Operate on Upper and + //Lower Halves Independently but we take simulator shortcut + Fd.df = -1 * Fs.df; + }}); } } 0x2: decode RS_LO { 0x1: decode MOVCF { format FloatOp64 { - 0x0: movf_fmt({{ }}); - 0x1: movt_fmt({{ }}); + 0x0: movfps({{ if ( FPConditionCode(CC) == 0) Fd = Fs;}}) + 0x1: movtps({{ if ( FPConditionCode(CC) == 0) Fd = Fs;}}) } } } 0x4: decode RS_LO { - 0x0: FloatOp64::cvt_s_pu({{ }}); + 0x0: FloatOp64::cvt_s_pu({{ + int rnd_mode = xc->miscRegs.fcsr; + Fd = convert_and_round(Fs.df,rnd_mode,FP_DOUBLE,FP_PS_HI); + }}); } 0x5: decode RS_LO { format FloatOp64 { - 0x0: cvt_s_pl({{ }}); - 0x4: pll_s_pl({{ }}); - 0x5: plu_s_pl({{ }}); - 0x6: pul_s_pl({{ }}); - 0x7: puu_s_pl({{ }}); + 0x0: cvt_s_pl({{ + int rnd_mode = xc->miscRegs.fcsr; + Fd = convert_and_round(Fs.df,rnd_mode,FP_SINGLE,FP_PS_LO); + }}); + 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>}}); } } } @@ -532,14 +593,14 @@ decode OPCODE_HI default FailUnimpl::unknown() { 0x1: decode ND { 0x0: decode TF { - format Branch { + format WarnUnimpl { 0x0: bc2f({{ cond = (xc->miscRegs.cop2cc == 0); }}, COP2); 0x1: bc2t({{ cond = (xc->miscRegs.cop2cc == 1); }}, COP2}}); } } 0x1: decode TF { - format Branch { + format WarnUnimpl { 0x0: bc2fl({{ cond = (xc->miscRegs.cop2cc == 0); }}, COP2}}); 0x1: bc2tl({{ cond = (xc->miscRegs.cop2cc == 1); }}, COP2}}); } @@ -554,46 +615,70 @@ decode OPCODE_HI default FailUnimpl::unknown() { 0x3: decode FUNCTION_HI { 0x0: decode FUNCTION_LO { format Memory { - 0x0: lwxc1({{ }}); - 0x1: ldxc1({{ }}); - 0x5: luxc1({{ }}); + 0x0: lwxc1({{ EA = Rs + Rt; }},{{ Ft<31:0> = Mem.uf; }}); + 0x1: ldxc1({{ EA = Rs + Rt; }},{{ Ft<63:0> = Mem.df; }}); + 0x5: luxc1({{ //Need to make EA<2:0> = 0 + EA = Rs + Rt; + }}, + {{ Ft<31:0> = Mem.df; }}); } } 0x1: decode FUNCTION_LO { format Memory { - 0x0: swxc1({{ }}); - 0x1: sdxc1({{ }}); - 0x5: suxc1({{ }}); + 0x0: swxc1({{ EA = Rs + Rt; }},{{ Mem.uf = Ft<31:0>; }}); + 0x1: sdxc1({{ EA = Rs + Rt; }},{{ Mem.uf = Ft<63:0>}}); + 0x5: suxc1({{ //Need to make EA<2:0> = 0 + EA = Rs + Rt; + }}, + {{ Mem.df = Ft<63:0>;}}); 0x7: prefx({{ }}); } } format FloatOp { - 0x3: alnv_ps({{ }}); + 0x3: WarnUnimpl::alnv_ps({{ }}); - 0x4: decode FUNCTION_LO { - 0x0: madd_s({{ }}); - 0x1: madd_d({{ }}); - 0x6: madd_ps({{ }}); - } + format BasicOp { + 0x4: decode FUNCTION_LO { + 0x0: madd_s({{ Fd.sf = (Fs.sf * Fs.sf) + Fr.sf; }}); + 0x1: madd_d({{ Fd.df = (Fs.df * Fs.df) + Fr.df; }}); + 0x6: madd_ps({{ + //Must Check for Exception Here... Supposed to Operate on Upper and + //Lower Halves Independently but we take simulator shortcut + Fd.df = (Fs.df * Fs.df) + Fr.df; + }}); + } - 0x5: decode FUNCTION_LO { - 0x0: msub_s({{ }}); - 0x1: msub_d({{ }}); - 0x6: msub_ps({{ }}); - } + 0x5: decode FUNCTION_LO { + 0x0: msub_s({{ Fd.sf = (Fs.sf * Fs.sf) - Fr.sf; }}); + 0x1: msub_d({{ Fd.df = (Fs.df * Fs.df) - Fr.df; }}); + 0x6: msub_ps({{ + //Must Check for Exception Here... Supposed to Operate on Upper and + //Lower Halves Independently but we take simulator shortcut + Fd.df = (Fs.df * Fs.df) - Fr.df; + }}); + } - 0x6: decode FUNCTION_LO { - 0x0: nmadd_s({{ }}); - 0x1: nmadd_d({{ }}); - 0x6: nmadd_ps({{ }}); - } + 0x6: decode FUNCTION_LO { + 0x0: nmadd_s({{ Fd.sf = (-1 * Fs.sf * Fs.sf) - Fr.sf; }}); + 0x1: nmadd_d({{ Fd.df = (-1 * Fs.df * Fs.df) + Fr.df; }}); + 0x6: nmadd_ps({{ + //Must Check for Exception Here... Supposed to Operate on Upper and + //Lower Halves Independently but we take simulator shortcut + Fd.df = (-1 * Fs.df * Fs.df) + Fr.df; + }}); + } - 0x7: decode FUNCTION_LO { - 0x0: nmsub_s({{ }}); - 0x1: nmsub_d({{ }}); - 0x6: nmsub_ps({{ }}); + 0x7: decode FUNCTION_LO { + 0x0: nmsub_s({{ Fd.sf = (-1 * Fs.sf * Fs.sf) - Fr.sf; }}); + 0x1: nmsub_d({{ Fd.df = (-1 * Fs.df * Fs.df) - Fr.df; }}); + 0x6: nmsub_ps({{ + //Must Check for Exception Here... Supposed to Operate on Upper and + //Lower Halves Independently but we take simulator shortcut + Fd.df = (-1 * Fs.df * Fs.df) + Fr.df; + }}); + } } } } @@ -689,15 +774,17 @@ decode OPCODE_HI default FailUnimpl::unknown() { //Table A-10 MIPS32 BSHFL Encoding of sa Field 0x4: decode SA { + + 0x02: WarnUnimpl::wsbh({{ }}); + format BasicOp { - 0x02: wsbh({{ }}); 0x10: seb({{ Rd.sw = /* sext32(Rt<7>,24) | */ Rt<7:0>}}); 0x18: seh({{ Rd.sw = /* sext32(Rt<15>,16) | */ Rt<15:0>}}); } } 0x6: decode FUNCTION_LO { - 0x7: BasicOp::rdhwr({{ }}); + 0x7: BasicOp::rdhwr({{ Rt = xc->hwRegs[RD];}}); } } }; @@ -726,24 +813,24 @@ decode OPCODE_HI default FailUnimpl::unknown() { }; format WarnUnimpl { - 0x4: reserved({{ }}); - 0x5: reserved({{ }}); 0x7: cache({{ }}); }; }; 0x6: decode OPCODE_LO default FailUnimpl::reserved() { + 0x0: WarnUnimpl::ll({{ }}); + format Memory { - 0x0: ll({{ }}); 0x1: lwc1({{ EA = Rs + disp; }},{{ Ft<31:0> = Mem.uf; }}); 0x5: ldc1({{ EA = Rs + disp; }},{{ Ft<63:0> = Mem.df; }}); }; }; 0x7: decode OPCODE_LO default FailUnimpl::reserved() { + 0x0: WarnUnimpl::sc({{ }}); + format Memory { - 0x0: sc({{ }}); 0x1: swc1({{ EA = Rs + disp; }},{{ Mem.uf = Ft<31:0>; }}); 0x5: sdc1({{ EA = Rs + disp; }},{{ Mem.df = Ft<63:0>; }}); }; From 3923eec0ef46dd1ce7ed2ef0cbc68419a0161796 Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Fri, 10 Feb 2006 09:12:55 -0500 Subject: [PATCH 034/180] Change how memory operands are handled in ISA descriptions. Should enable implementation of split-phase timing loads with new memory model. May create slight timing differences under FullCPU, as I believe we were not handling software prefetches correctly before when the split MemAcc/Exec model was used. I haven't looked into this in any detail though. arch/alpha/isa/decoder.isa: HwLoadStore format split into separate HwLoad and HwStore formats. Copy instructions now fall under MiscPrefetch format. Mem_write_result is now just write_result in store conditionals. arch/alpha/isa/mem.isa: Split MemAccExecute and LoadStoreExecute templates into separate templates for loads and stores; now that memory operands are handled differently from registers, it's impossible to have a single template serve both. Also unified the handling of "regular" prefetches (loads to r31) and "misc" prefetches (e.g., wh64) under the new scheme. It looks like SW prefetches were not handled correctly in FullCPU up til now, since we generated an execute() method for the outer instruction but didn't generate a proper method for MemAcc::execute() (instead getting a default no-op method for that). arch/alpha/isa/pal.isa: Split HwLoadStore into separate HwLoad and HwStore formats to select proper template (see change to mem.isa in this changeset). arch/isa_parser.py: Stop trying to treat memory operands like register operands, since we never used them in a uniform way anyway, and it made it impossible to do split-phase loads as needed for the new CPU model. Now there's no more 'op_mem_rd', 'op_nonmem_rd', etc.: 'op_rd' just does register operands, and the template code is responsible for formulating the call to the memory system. Right now the only thing exported by InstObjParams is a new attribute 'mem_acc_size' which gives the memory access size in bits, though more attributes can be added if needed. Also moved code in findOperands() method to OperandDescriptorList.__init__(), which is where it belongs. --HG-- extra : convert_revision : 6d53d07e0c5e828455834ded4395fa40f9146a34 --- arch/alpha/isa/decoder.isa | 20 ++-- arch/alpha/isa/mem.isa | 160 ++++++++++++++++++++++++-------- arch/alpha/isa/pal.isa | 13 ++- arch/isa_parser.py | 183 ++++++++++++++++++------------------- 4 files changed, 231 insertions(+), 145 deletions(-) diff --git a/arch/alpha/isa/decoder.isa b/arch/alpha/isa/decoder.isa index 6a35fa229..c21465928 100644 --- a/arch/alpha/isa/decoder.isa +++ b/arch/alpha/isa/decoder.isa @@ -40,9 +40,9 @@ decode OPCODE default Unknown::unknown() { 0x23: ldt({{ EA = Rb + disp; }}, {{ Fa = Mem.df; }}); 0x2a: ldl_l({{ EA = Rb + disp; }}, {{ Ra.sl = Mem.sl; }}, LOCKED); 0x2b: ldq_l({{ EA = Rb + disp; }}, {{ Ra.uq = Mem.uq; }}, LOCKED); - 0x20: copy_load({{EA = Ra;}}, - {{fault = xc->copySrcTranslate(EA);}}, - IsMemRef, IsLoad, IsCopy); + 0x20: MiscPrefetch::copy_load({{ EA = Ra; }}, + {{ fault = xc->copySrcTranslate(EA); }}, + IsMemRef, IsLoad, IsCopy); } format LoadOrPrefetch { @@ -62,21 +62,21 @@ decode OPCODE default Unknown::unknown() { 0x0f: stq_u({{ EA = (Rb + disp) & ~7; }}, {{ Mem.uq = Ra.uq; }}); 0x26: sts({{ EA = Rb + disp; }}, {{ Mem.ul = t_to_s(Fa.uq); }}); 0x27: stt({{ EA = Rb + disp; }}, {{ Mem.df = Fa; }}); - 0x24: copy_store({{EA = Rb;}}, - {{fault = xc->copy(EA);}}, - IsMemRef, IsStore, IsCopy); + 0x24: MiscPrefetch::copy_store({{ EA = Rb; }}, + {{ fault = xc->copy(EA); }}, + IsMemRef, IsStore, IsCopy); } format StoreCond { 0x2e: stl_c({{ EA = Rb + disp; }}, {{ Mem.ul = Ra<31:0>; }}, {{ - uint64_t tmp = Mem_write_result; + uint64_t tmp = write_result; // see stq_c Ra = (tmp == 0 || tmp == 1) ? tmp : Ra; }}, LOCKED); 0x2f: stq_c({{ EA = Rb + disp; }}, {{ Mem.uq = Ra; }}, {{ - uint64_t tmp = Mem_write_result; + uint64_t tmp = write_result; // If the write operation returns 0 or 1, then // this was a conventional store conditional, // and the value indicates the success/failure @@ -704,12 +704,14 @@ decode OPCODE default Unknown::unknown() { #endif #if FULL_SYSTEM - format HwLoadStore { + format HwLoad { 0x1b: decode HW_LDST_QUAD { 0: hw_ld({{ EA = (Rb + disp) & ~3; }}, {{ Ra = Mem.ul; }}, L); 1: hw_ld({{ EA = (Rb + disp) & ~7; }}, {{ Ra = Mem.uq; }}, Q); } + } + format HwStore { 0x1f: decode HW_LDST_COND { 0: decode HW_LDST_QUAD { 0: hw_st({{ EA = (Rb + disp) & ~3; }}, diff --git a/arch/alpha/isa/mem.isa b/arch/alpha/isa/mem.isa index 89296626c..0d9d59cee 100644 --- a/arch/alpha/isa/mem.isa +++ b/arch/alpha/isa/mem.isa @@ -214,7 +214,7 @@ def template EACompExecute {{ } }}; -def template MemAccExecute {{ +def template LoadMemAccExecute {{ Fault %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const @@ -224,24 +224,16 @@ def template MemAccExecute {{ %(fp_enable_check)s; %(op_decl)s; - %(op_nonmem_rd)s; + %(op_rd)s; EA = xc->getEA(); if (fault == No_Fault) { - %(op_mem_rd)s; + fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags); %(code)s; } if (fault == No_Fault) { - %(op_mem_wb)s; - } - - if (fault == No_Fault) { - %(postacc_code)s; - } - - if (fault == No_Fault) { - %(op_nonmem_wb)s; + %(op_wb)s; } return fault; @@ -249,7 +241,7 @@ def template MemAccExecute {{ }}; -def template LoadStoreExecute {{ +def template LoadExecute {{ Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const { @@ -258,24 +250,16 @@ def template LoadStoreExecute {{ %(fp_enable_check)s; %(op_decl)s; - %(op_nonmem_rd)s; + %(op_rd)s; %(ea_code)s; if (fault == No_Fault) { - %(op_mem_rd)s; + fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags); %(memacc_code)s; } if (fault == No_Fault) { - %(op_mem_wb)s; - } - - if (fault == No_Fault) { - %(postacc_code)s; - } - - if (fault == No_Fault) { - %(op_nonmem_wb)s; + %(op_wb)s; } return fault; @@ -283,7 +267,100 @@ def template LoadStoreExecute {{ }}; -def template PrefetchExecute {{ +def template StoreMemAccExecute {{ + Fault + %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + Addr EA; + Fault fault = No_Fault; + uint64_t write_result = 0; + + %(fp_enable_check)s; + %(op_decl)s; + %(op_rd)s; + EA = xc->getEA(); + + if (fault == No_Fault) { + %(code)s; + } + + if (fault == No_Fault) { + fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, + memAccessFlags, &write_result); + if (traceData) { traceData->setData(Mem); } + } + + if (fault == No_Fault) { + %(postacc_code)s; + } + + if (fault == No_Fault) { + %(op_wb)s; + } + + return fault; + } +}}; + + +def template StoreExecute {{ + Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + Addr EA; + Fault fault = No_Fault; + uint64_t write_result = 0; + + %(fp_enable_check)s; + %(op_decl)s; + %(op_rd)s; + %(ea_code)s; + + if (fault == No_Fault) { + %(memacc_code)s; + } + + if (fault == No_Fault) { + fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, + memAccessFlags, &write_result); + if (traceData) { traceData->setData(Mem); } + } + + if (fault == No_Fault) { + %(postacc_code)s; + } + + if (fault == No_Fault) { + %(op_wb)s; + } + + return fault; + } +}}; + + +def template MiscMemAccExecute {{ + Fault %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + Addr EA; + Fault fault = No_Fault; + + %(fp_enable_check)s; + %(op_decl)s; + %(op_rd)s; + EA = xc->getEA(); + + if (fault == No_Fault) { + %(code)s; + } + + return No_Fault; + } +}}; + +def template MiscExecute {{ Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const { @@ -292,11 +369,11 @@ def template PrefetchExecute {{ %(fp_enable_check)s; %(op_decl)s; - %(op_nonmem_rd)s; + %(op_rd)s; %(ea_code)s; if (fault == No_Fault) { - xc->prefetch(EA, memAccessFlags); + %(memacc_code)s; } return No_Fault; @@ -332,8 +409,7 @@ def template LoadPrefetchCheckDecode {{ let {{ def LoadStoreBase(name, Name, ea_code, memacc_code, postacc_code = '', base_class = 'MemoryDisp32', flags = [], - decode_template = BasicDecode, - exec_template = LoadStoreExecute): + decode_template = BasicDecode, exec_template_base = ''): # Segregate flags into instruction flags (handled by InstObjParams) # and memory access flags (handled here). @@ -380,19 +456,24 @@ def LoadStoreBase(name, Name, ea_code, memacc_code, postacc_code = '', iop.constructor += s memacc_iop.constructor += s + # select templates + memAccExecTemplate = eval(exec_template_base + 'MemAccExecute') + fullExecTemplate = eval(exec_template_base + 'Execute') + # (header_output, decoder_output, decode_block, exec_output) return (LoadStoreDeclare.subst(iop), LoadStoreConstructor.subst(iop), decode_template.subst(iop), EACompExecute.subst(ea_iop) - + MemAccExecute.subst(memacc_iop) - + exec_template.subst(iop)) + + memAccExecTemplate.subst(memacc_iop) + + fullExecTemplate.subst(iop)) }}; def format LoadOrNop(ea_code, memacc_code, *flags) {{ (header_output, decoder_output, decode_block, exec_output) = \ LoadStoreBase(name, Name, ea_code, memacc_code, flags = flags, - decode_template = LoadNopCheckDecode) + decode_template = LoadNopCheckDecode, + exec_template_base = 'Load') }}; @@ -401,7 +482,8 @@ def format LoadOrPrefetch(ea_code, memacc_code, *pf_flags) {{ # declare the load instruction object and generate the decode block (header_output, decoder_output, decode_block, exec_output) = \ LoadStoreBase(name, Name, ea_code, memacc_code, - decode_template = LoadPrefetchCheckDecode) + decode_template = LoadPrefetchCheckDecode, + exec_template_base = 'Load') # Declare the prefetch instruction object. @@ -409,8 +491,9 @@ def format LoadOrPrefetch(ea_code, memacc_code, *pf_flags) {{ pf_flags = list(pf_flags) + ['IsMemRef', 'IsLoad', 'IsDataPrefetch', 'MemReadOp', 'NO_FAULT'] (pf_header_output, pf_decoder_output, _, pf_exec_output) = \ - LoadStoreBase(name, Name + 'Prefetch', ea_code, '', - flags = pf_flags, exec_template = PrefetchExecute) + LoadStoreBase(name, Name + 'Prefetch', ea_code, + 'xc->prefetch(EA, memAccessFlags);', + flags = pf_flags, exec_template_base = 'Misc') header_output += pf_header_output decoder_output += pf_decoder_output @@ -420,14 +503,15 @@ def format LoadOrPrefetch(ea_code, memacc_code, *pf_flags) {{ def format Store(ea_code, memacc_code, *flags) {{ (header_output, decoder_output, decode_block, exec_output) = \ - LoadStoreBase(name, Name, ea_code, memacc_code, flags = flags) + LoadStoreBase(name, Name, ea_code, memacc_code, flags = flags, + exec_template_base = 'Store') }}; def format StoreCond(ea_code, memacc_code, postacc_code, *flags) {{ (header_output, decoder_output, decode_block, exec_output) = \ LoadStoreBase(name, Name, ea_code, memacc_code, postacc_code, - flags = flags) + flags = flags, exec_template_base = 'Store') }}; @@ -435,7 +519,7 @@ def format StoreCond(ea_code, memacc_code, postacc_code, *flags) {{ def format MiscPrefetch(ea_code, memacc_code, *flags) {{ (header_output, decoder_output, decode_block, exec_output) = \ LoadStoreBase(name, Name, ea_code, memacc_code, flags = flags, - base_class = 'MemoryNoDisp') + base_class = 'MemoryNoDisp', exec_template_base = 'Misc') }}; diff --git a/arch/alpha/isa/pal.isa b/arch/alpha/isa/pal.isa index 9debffa38..552dde2d7 100644 --- a/arch/alpha/isa/pal.isa +++ b/arch/alpha/isa/pal.isa @@ -195,10 +195,19 @@ output decoder {{ } }}; -def format HwLoadStore(ea_code, memacc_code, class_ext, *flags) {{ +def format HwLoad(ea_code, memacc_code, class_ext, *flags) {{ (header_output, decoder_output, decode_block, exec_output) = \ LoadStoreBase(name, Name + class_ext, ea_code, memacc_code, - flags = flags, base_class = 'HwLoadStore') + flags = flags, base_class = 'HwLoadStore', + exec_template_base = 'Load') +}}; + + +def format HwStore(ea_code, memacc_code, class_ext, *flags) {{ + (header_output, decoder_output, decode_block, exec_output) = \ + LoadStoreBase(name, Name + class_ext, ea_code, memacc_code, + flags = flags, base_class = 'HwLoadStore', + exec_template_base = 'Store') }}; diff --git a/arch/isa_parser.py b/arch/isa_parser.py index b12329ebb..fffcc33e5 100755 --- a/arch/isa_parser.py +++ b/arch/isa_parser.py @@ -868,16 +868,21 @@ def fixPythonIndentation(s): return s # Error handler. Just call exit. Output formatted to work under -# Emacs compile-mode. +# Emacs compile-mode. This function should be called when errors due +# to user input are detected (as opposed to parser bugs). def error(lineno, string): spaces = "" for (filename, line) in fileNameStack[0:-1]: print spaces + "In file included from " + filename spaces += " " + # Uncomment the following line to get a Python stack backtrace for + # these errors too. Can be handy when trying to debug the parser. + # traceback.print_exc() sys.exit(spaces + "%s:%d: %s" % (fileNameStack[-1][0], lineno, string)) # Like error(), but include a Python stack backtrace (for processing -# Python exceptions). +# Python exceptions). This function should be called for errors that +# appear to be bugs in the parser itself. def error_bt(lineno, string): traceback.print_exc() print >> sys.stderr, "%s:%d: %s" % (input_filename, lineno, string) @@ -1220,30 +1225,19 @@ class MemOperandTraits(OperandTraits): # to avoid 'uninitialized variable' errors from the compiler. # Declare memory data variable. c = '%s %s = 0;\n' % (type, op_desc.base_name) - # Declare var to hold memory access flags. - c += 'unsigned %s_flags = memAccessFlags;\n' % op_desc.base_name - # If this operand is a dest (i.e., it's a store operation), - # then we need to declare a variable for the write result code - # as well. - if op_desc.is_dest: - c += 'uint64_t %s_write_result = 0;\n' % op_desc.base_name return c def makeRead(self, op_desc): - (size, type, is_signed) = operandSizeMap[op_desc.eff_ext] - eff_type = 'uint%d_t' % size - return 'fault = xc->read(EA, (%s&)%s, %s_flags);\n' \ - % (eff_type, op_desc.base_name, op_desc.base_name) + return '' def makeWrite(self, op_desc): + return '' + + # Return the memory access size *in bits*, suitable for + # forming a type via "uint%d_t". Divide by 8 if you want bytes. + def makeAccSize(self, op_desc): (size, type, is_signed) = operandSizeMap[op_desc.eff_ext] - eff_type = 'uint%d_t' % size - wb = 'fault = xc->write((%s&)%s, EA, %s_flags, &%s_write_result);\n' \ - % (eff_type, op_desc.base_name, op_desc.base_name, - op_desc.base_name) - wb += 'if (traceData) { traceData->setData(%s); }' % \ - op_desc.base_name - return wb + return size class NPCOperandTraits(OperandTraits): def makeConstructor(self, op_desc): @@ -1321,6 +1315,11 @@ class OperandDescriptor: else: self.eff_ext = self.traits.dflt_ext + # note that mem_acc_size is undefined for non-mem operands... + # template must be careful not to use it if it doesn't apply. + if self.traits.isMem(): + self.mem_acc_size = self.traits.makeAccSize(self) + # Finalize additional fields (primarily code fields). This step # is done separately since some of these fields may depend on the # register index enumeration that hasn't been performed yet at the @@ -1340,10 +1339,73 @@ class OperandDescriptor: else: self.op_wb = '' + class OperandDescriptorList: - def __init__(self): + + # Find all the operands in the given code block. Returns an operand + # descriptor list (instance of class OperandDescriptorList). + def __init__(self, code): self.items = [] self.bases = {} + # delete comments so we don't match on reg specifiers inside + code = commentRE.sub('', code) + # search for operands + next_pos = 0 + while 1: + match = operandsRE.search(code, next_pos) + if not match: + # no more matches: we're done + break + op = match.groups() + # regexp groups are operand full name, base, and extension + (op_full, op_base, op_ext) = op + # if the token following the operand is an assignment, this is + # a destination (LHS), else it's a source (RHS) + is_dest = (assignRE.match(code, match.end()) != None) + is_src = not is_dest + # see if we've already seen this one + op_desc = self.find_base(op_base) + if op_desc: + if op_desc.ext != op_ext: + error(0, 'Inconsistent extensions for operand %s' % \ + op_base) + op_desc.is_src = op_desc.is_src or is_src + op_desc.is_dest = op_desc.is_dest or is_dest + else: + # new operand: create new descriptor + op_desc = OperandDescriptor(op_full, op_base, op_ext, + is_src, is_dest) + self.append(op_desc) + # start next search after end of current match + next_pos = match.end() + self.sort() + # enumerate source & dest register operands... used in building + # constructor later + self.numSrcRegs = 0 + self.numDestRegs = 0 + self.numFPDestRegs = 0 + self.numIntDestRegs = 0 + self.memOperand = None + for op_desc in self.items: + if op_desc.traits.isReg(): + if op_desc.is_src: + op_desc.src_reg_idx = self.numSrcRegs + self.numSrcRegs += 1 + if op_desc.is_dest: + op_desc.dest_reg_idx = self.numDestRegs + self.numDestRegs += 1 + if op_desc.traits.isFloatReg(): + self.numFPDestRegs += 1 + elif op_desc.traits.isIntReg(): + self.numIntDestRegs += 1 + elif op_desc.traits.isMem(): + if self.memOperand: + error(0, "Code block has more than one memory operand.") + self.memOperand = op_desc + # now make a final pass to finalize op_desc fields that may depend + # on the register enumeration + for op_desc in self.items: + op_desc.finalize() def __len__(self): return len(self.items) @@ -1398,69 +1460,6 @@ commentRE = re.compile(r'//.*\n') # (used in findOperands()) assignRE = re.compile(r'\s*=(?!=)', re.MULTILINE) -# -# Find all the operands in the given code block. Returns an operand -# descriptor list (instance of class OperandDescriptorList). -# -def findOperands(code): - operands = OperandDescriptorList() - # delete comments so we don't accidentally match on reg specifiers inside - code = commentRE.sub('', code) - # search for operands - next_pos = 0 - while 1: - match = operandsRE.search(code, next_pos) - if not match: - # no more matches: we're done - break - op = match.groups() - # regexp groups are operand full name, base, and extension - (op_full, op_base, op_ext) = op - # if the token following the operand is an assignment, this is - # a destination (LHS), else it's a source (RHS) - is_dest = (assignRE.match(code, match.end()) != None) - is_src = not is_dest - # see if we've already seen this one - op_desc = operands.find_base(op_base) - if op_desc: - if op_desc.ext != op_ext: - error(0, 'Inconsistent extensions for operand %s' % op_base) - op_desc.is_src = op_desc.is_src or is_src - op_desc.is_dest = op_desc.is_dest or is_dest - else: - # new operand: create new descriptor - op_desc = OperandDescriptor(op_full, op_base, op_ext, - is_src, is_dest) - operands.append(op_desc) - # start next search after end of current match - next_pos = match.end() - operands.sort() - # enumerate source & dest register operands... used in building - # constructor later - srcRegs = 0 - destRegs = 0 - operands.numFPDestRegs = 0 - operands.numIntDestRegs = 0 - for op_desc in operands: - if op_desc.traits.isReg(): - if op_desc.is_src: - op_desc.src_reg_idx = srcRegs - srcRegs += 1 - if op_desc.is_dest: - op_desc.dest_reg_idx = destRegs - destRegs += 1 - if op_desc.traits.isFloatReg(): - operands.numFPDestRegs += 1 - elif op_desc.traits.isIntReg(): - operands.numIntDestRegs += 1 - operands.numSrcRegs = srcRegs - operands.numDestRegs = destRegs - # now make a final pass to finalize op_desc fields that may depend - # on the register enumeration - for op_desc in operands: - op_desc.finalize() - return operands - # Munge operand names in code string to make legal C++ variable names. # This means getting rid of the type extension if any. # (Will match base_name attribute of OperandDescriptor object.) @@ -1489,7 +1488,7 @@ def makeFlagConstructor(flag_list): class CodeBlock: def __init__(self, code): self.orig_code = code - self.operands = findOperands(code) + self.operands = OperandDescriptorList(code) self.code = substMungedOpNames(substBitOps(code)) self.constructor = self.operands.concatAttrStrings('constructor') self.constructor += \ @@ -1503,22 +1502,14 @@ class CodeBlock: self.op_decl = self.operands.concatAttrStrings('op_decl') - is_mem = lambda op: op.traits.isMem() - not_mem = lambda op: not op.traits.isMem() - self.op_rd = self.operands.concatAttrStrings('op_rd') self.op_wb = self.operands.concatAttrStrings('op_wb') - self.op_mem_rd = \ - self.operands.concatSomeAttrStrings(is_mem, 'op_rd') - self.op_mem_wb = \ - self.operands.concatSomeAttrStrings(is_mem, 'op_wb') - self.op_nonmem_rd = \ - self.operands.concatSomeAttrStrings(not_mem, 'op_rd') - self.op_nonmem_wb = \ - self.operands.concatSomeAttrStrings(not_mem, 'op_wb') self.flags = self.operands.concatAttrLists('flags') + if self.operands.memOperand: + self.mem_acc_size = self.operands.memOperand.mem_acc_size + # Make a basic guess on the operand class (function unit type). # These are good enough for most cases, and will be overridden # later otherwise. From fb7899aa681001d2af7837eae7bf0e19fd3e1b02 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Fri, 10 Feb 2006 14:21:32 -0500 Subject: [PATCH 035/180] fix problems on darwin/*BSD for syscall emulation mode arch/alpha/alpha_linux_process.cc: arch/alpha/alpha_tru64_process.cc: fixup for bsd hosts. Some headers are included by default which means that more variables need TGT_ prefixes and there isn't a stat call (everything is a stat64 call) so we have to work around that a bit base/intmath.hh: base/socket.cc: this is no longer needed with mac os 10.4 cpu/inst_seq.hh: just use a uint64_t instead of long long cpu/o3/inst_queue_impl.hh: I much cleaner way to get max int sim/syscall_emul.hh: fix stat64 problems on *BSD --HG-- extra : convert_revision : 9eef5f896e083ae1774e818a9765dd83e0305942 --- arch/alpha/alpha_linux_process.cc | 72 +++++++++++++++++++++++-------- arch/alpha/alpha_tru64_process.cc | 28 ++++++------ base/intmath.hh | 16 ------- base/socket.cc | 3 -- cpu/inst_seq.hh | 2 +- cpu/o3/inst_queue_impl.hh | 3 +- sim/syscall_emul.hh | 41 +++++++++++------- 7 files changed, 97 insertions(+), 68 deletions(-) diff --git a/arch/alpha/alpha_linux_process.cc b/arch/alpha/alpha_linux_process.cc index 8f114955f..68d6ca180 100644 --- a/arch/alpha/alpha_linux_process.cc +++ b/arch/alpha/alpha_linux_process.cc @@ -71,6 +71,15 @@ class Linux { typedef uint32_t gid_t; //@} +#if BSD_HOST + typedef struct stat hst_stat; + typedef struct stat hst_stat64; +#else + typedef struct stat hst_stat ; + typedef struct stat64 hst_stat64; +#endif + + //@{ /// open(2) flag values. static const int TGT_O_RDONLY = 00000000; //!< O_RDONLY @@ -139,7 +148,7 @@ class Linux { uint64_t st_mtime_nsec; uint64_t tgt_st_ctime; uint64_t st_ctime_nsec; - int64_t __unused[3]; + int64_t ___unused[3]; }; /// Length of strings in struct utsname (plus 1 for null char). @@ -170,18 +179,18 @@ class Linux { /// Resource enumeration for getrlimit(). enum rlimit_resources { - RLIMIT_CPU = 0, - RLIMIT_FSIZE = 1, - RLIMIT_DATA = 2, - RLIMIT_STACK = 3, - RLIMIT_CORE = 4, - RLIMIT_RSS = 5, - RLIMIT_NOFILE = 6, - RLIMIT_AS = 7, - RLIMIT_VMEM = 7, - RLIMIT_NPROC = 8, - RLIMIT_MEMLOCK = 9, - RLIMIT_LOCKS = 10 + TGT_RLIMIT_CPU = 0, + TGT_RLIMIT_FSIZE = 1, + TGT_RLIMIT_DATA = 2, + TGT_RLIMIT_STACK = 3, + TGT_RLIMIT_CORE = 4, + TGT_RLIMIT_RSS = 5, + TGT_RLIMIT_NOFILE = 6, + TGT_RLIMIT_AS = 7, + TGT_RLIMIT_VMEM = 7, + TGT_RLIMIT_NPROC = 8, + TGT_RLIMIT_MEMLOCK = 9, + TGT_RLIMIT_LOCKS = 10 }; /// Limit struct for getrlimit/setrlimit. @@ -208,9 +217,9 @@ class Linux { //@{ /// For getrusage(). - static const int RUSAGE_SELF = 0; - static const int RUSAGE_CHILDREN = -1; - static const int RUSAGE_BOTH = -2; + static const int TGT_RUSAGE_SELF = 0; + static const int TGT_RUSAGE_CHILDREN = -1; + static const int TGT_RUSAGE_BOTH = -2; //@} /// For getrusage(). @@ -236,8 +245,9 @@ class Linux { /// Helper function to convert a host stat buffer to a target stat /// buffer. Also copies the target buffer out to the simulated /// memory space. Used by stat(), fstat(), and lstat(). +#if !BSD_HOST static void - copyOutStatBuf(FunctionalMemory *mem, Addr addr, struct stat *host) + copyOutStatBuf(FunctionalMemory *mem, Addr addr, hst_stat *host) { TypedBufferArg tgt(addr); @@ -257,10 +267,36 @@ class Linux { tgt.copyOut(mem); } +#else + // Third version for bsd systems which no longer have any support for + // the old stat() call and stat() is actually a stat64() + static void + copyOutStatBuf(FunctionalMemory *mem, Addr addr, hst_stat64 *host) + { + TypedBufferArg tgt(addr); + + tgt->st_dev = host->st_dev; + tgt->st_ino = host->st_ino; + tgt->st_mode = host->st_mode; + tgt->st_nlink = host->st_nlink; + tgt->st_uid = host->st_uid; + tgt->st_gid = host->st_gid; + tgt->st_rdev = host->st_rdev; + tgt->st_size = host->st_size; + tgt->st_atimeX = host->st_atime; + tgt->st_mtimeX = host->st_mtime; + tgt->st_ctimeX = host->st_ctime; + tgt->st_blksize = host->st_blksize; + tgt->st_blocks = host->st_blocks; + + tgt.copyOut(mem); + } +#endif + // Same for stat64 static void - copyOutStat64Buf(FunctionalMemory *mem, Addr addr, struct stat64 *host) + copyOutStat64Buf(FunctionalMemory *mem, Addr addr, hst_stat64 *host) { TypedBufferArg tgt(addr); diff --git a/arch/alpha/alpha_tru64_process.cc b/arch/alpha/alpha_tru64_process.cc index 6d790b173..1a66d7499 100644 --- a/arch/alpha/alpha_tru64_process.cc +++ b/arch/alpha/alpha_tru64_process.cc @@ -28,7 +28,7 @@ #include #include -#if defined(__OpenBSD__) +#if defined(__OpenBSD__) || defined(__APPLE__) || defined(__FreeBSD__) #include #include #else @@ -260,15 +260,15 @@ class Tru64 { /// Resource enumeration for getrlimit(). enum rlimit_resources { - RLIMIT_CPU = 0, - RLIMIT_FSIZE = 1, - RLIMIT_DATA = 2, - RLIMIT_STACK = 3, - RLIMIT_CORE = 4, - RLIMIT_RSS = 5, - RLIMIT_NOFILE = 6, - RLIMIT_AS = 7, - RLIMIT_VMEM = 7 + TGT_RLIMIT_CPU = 0, + TGT_RLIMIT_FSIZE = 1, + TGT_RLIMIT_DATA = 2, + TGT_RLIMIT_STACK = 3, + TGT_RLIMIT_CORE = 4, + TGT_RLIMIT_RSS = 5, + TGT_RLIMIT_NOFILE = 6, + TGT_RLIMIT_AS = 7, + TGT_RLIMIT_VMEM = 7 }; /// Limit struct for getrlimit/setrlimit. @@ -320,9 +320,9 @@ class Tru64 { //@{ /// For getrusage(). - static const int RUSAGE_THREAD = 1; - static const int RUSAGE_SELF = 0; - static const int RUSAGE_CHILDREN = -1; + static const int TGT_RUSAGE_THREAD = 1; + static const int TGT_RUSAGE_SELF = 0; + static const int TGT_RUSAGE_CHILDREN = -1; //@} /// For getrusage(). @@ -568,7 +568,7 @@ class Tru64 { { TypedBufferArg tgt(addr); -#if defined(__OpenBSD__) +#if defined(__OpenBSD__) || defined(__APPLE__) || defined(__FreeBSD__) tgt->f_type = 0; #else tgt->f_type = host->f_type; diff --git a/base/intmath.hh b/base/intmath.hh index c8b9c5ec5..df0687c62 100644 --- a/base/intmath.hh +++ b/base/intmath.hh @@ -145,22 +145,6 @@ floorLog2(long long x) return floorLog2((unsigned long long)x); } -#if defined(__APPLE__) -inline int -floorLog2(size_t x) -{ - assert(x > 0); - assert(sizeof(size_t) == 4 || sizeof(size_t) == 8); - - // It's my hope that this is optimized away? - if (sizeof(size_t) == 4) - return floorLog2((uint32_t)x); - else if (sizeof(size_t) == 8) - return floorLog2((uint64_t)x); - -} -#endif - template inline int ceilLog2(T n) diff --git a/base/socket.cc b/base/socket.cc index f33e79426..45a60e7e3 100644 --- a/base/socket.cc +++ b/base/socket.cc @@ -93,9 +93,6 @@ ListenSocket::listen(int port, bool reuse) return true; } -#if defined(__APPLE__) -typedef int socklen_t; -#endif // Open a connection. Accept will block, so if you don't want it to, // make sure a connection is ready before you call accept. diff --git a/cpu/inst_seq.hh b/cpu/inst_seq.hh index 3239d4d24..8de047af7 100644 --- a/cpu/inst_seq.hh +++ b/cpu/inst_seq.hh @@ -32,7 +32,7 @@ // inst sequence type, used to order instructions in the ready list, // if this rolls over the ready list order temporarily will get messed // up, but execution will continue and complete correctly -typedef unsigned long long InstSeqNum; +typedef uint64_t InstSeqNum; // inst tag type, used to tag an operation instance in the IQ typedef unsigned int InstTag; diff --git a/cpu/o3/inst_queue_impl.hh b/cpu/o3/inst_queue_impl.hh index 2221ba456..048dc7c00 100644 --- a/cpu/o3/inst_queue_impl.hh +++ b/cpu/o3/inst_queue_impl.hh @@ -34,6 +34,7 @@ // but probably is more flexible to actually add in a delay parameter than // just running it backwards. +#include #include #include "sim/root.hh" @@ -42,7 +43,7 @@ // Either compile error or max int due to sign extension. // Hack to avoid compile warnings. -const InstSeqNum MaxInstSeqNum = 0 - 1; +const InstSeqNum MaxInstSeqNum = std::numeric_limits::max(); template InstructionQueue::InstructionQueue(Params ¶ms) diff --git a/sim/syscall_emul.hh b/sim/syscall_emul.hh index 185ada2c5..a10ee297c 100644 --- a/sim/syscall_emul.hh +++ b/sim/syscall_emul.hh @@ -29,6 +29,9 @@ #ifndef __SIM_SYSCALL_EMUL_HH__ #define __SIM_SYSCALL_EMUL_HH__ +#define BSD_HOST (defined(__APPLE__) || defined(__OpenBSD__) || \ + defined(__FreeBSD__)) + /// /// @file syscall_emul.hh /// @@ -441,8 +444,13 @@ fstat64Func(SyscallDesc *desc, int callnum, Process *process, return -EBADF; } - struct stat64 hostBuf; +#ifdef BSD_HOST + struct stat hostBuf; + int result = fstat(process->sim_fd(fd), &hostBuf); +#else + struct stat64 hostBuf; int result = fstat64(process->sim_fd(fd), &hostBuf); +#endif if (result < 0) return errno; @@ -486,8 +494,13 @@ lstat64Func(SyscallDesc *desc, int callnum, Process *process, if (xc->mem->readString(path, xc->getSyscallArg(0)) != No_Fault) return -EFAULT; +#ifdef BSD_HOST + struct stat hostBuf; + int result = lstat(path.c_str(), &hostBuf); +#else struct stat64 hostBuf; int result = lstat64(path.c_str(), &hostBuf); +#endif if (result < 0) return -errno; @@ -517,7 +530,6 @@ fstatFunc(SyscallDesc *desc, int callnum, Process *process, return -errno; OS::copyOutStatBuf(xc->mem, xc->getSyscallArg(1), &hostBuf); - return 0; } @@ -653,22 +665,22 @@ mmapFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) template SyscallReturn getrlimitFunc(SyscallDesc *desc, int callnum, Process *process, - ExecContext *xc) + ExecContext *xc) { unsigned resource = xc->getSyscallArg(0); TypedBufferArg rlp(xc->getSyscallArg(1)); switch (resource) { - case OS::RLIMIT_STACK: - // max stack size in bytes: make up a number (2MB for now) - rlp->rlim_cur = rlp->rlim_max = 8 * 1024 * 1024; - break; + case OS::TGT_RLIMIT_STACK: + // max stack size in bytes: make up a number (2MB for now) + rlp->rlim_cur = rlp->rlim_max = 8 * 1024 * 1024; + break; - default: - std::cerr << "getrlimitFunc: unimplemented resource " << resource - << std::endl; - abort(); - break; + default: + std::cerr << "getrlimitFunc: unimplemented resource " << resource + << std::endl; + abort(); + break; } rlp.copyOut(xc->mem); @@ -679,7 +691,7 @@ getrlimitFunc(SyscallDesc *desc, int callnum, Process *process, template SyscallReturn gettimeofdayFunc(SyscallDesc *desc, int callnum, Process *process, - ExecContext *xc) + ExecContext *xc) { TypedBufferArg tp(xc->getSyscallArg(0)); @@ -719,7 +731,6 @@ utimesFunc(SyscallDesc *desc, int callnum, Process *process, return 0; } - /// Target getrusage() function. template SyscallReturn @@ -729,7 +740,7 @@ getrusageFunc(SyscallDesc *desc, int callnum, Process *process, int who = xc->getSyscallArg(0); // THREAD, SELF, or CHILDREN TypedBufferArg rup(xc->getSyscallArg(1)); - if (who != OS::RUSAGE_SELF) { + if (who != OS::TGT_RUSAGE_SELF) { // don't really handle THREAD or CHILDREN, but just warn and // plow ahead warn("getrusage() only supports RUSAGE_SELF. Parameter %d ignored.", From ac6240896e26dd709dc17298ba093d32860b947f Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Fri, 10 Feb 2006 14:59:37 -0500 Subject: [PATCH 036/180] confused an ifdef with an if --HG-- extra : convert_revision : 5b8e8bdff5813cf8846e66de2652246d77c97e88 --- sim/syscall_emul.hh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sim/syscall_emul.hh b/sim/syscall_emul.hh index a10ee297c..f55709575 100644 --- a/sim/syscall_emul.hh +++ b/sim/syscall_emul.hh @@ -444,7 +444,7 @@ fstat64Func(SyscallDesc *desc, int callnum, Process *process, return -EBADF; } -#ifdef BSD_HOST +#if BSD_HOST struct stat hostBuf; int result = fstat(process->sim_fd(fd), &hostBuf); #else @@ -494,7 +494,7 @@ lstat64Func(SyscallDesc *desc, int callnum, Process *process, if (xc->mem->readString(path, xc->getSyscallArg(0)) != No_Fault) return -EFAULT; -#ifdef BSD_HOST +#if BSD_HOST struct stat hostBuf; int result = lstat(path.c_str(), &hostBuf); #else From 96d6ac441cabdd9b089e2306e926c67891fdf9fa Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Sat, 11 Feb 2006 00:55:36 -0500 Subject: [PATCH 037/180] hello world works on a BE host for a LE guest arch/alpha/alpha_linux_process.cc: Add endian conversions to fstat sim/byteswap.hh: for some reason I don't understand g++ really wanted a long version defined even though int32_t should be the same. --HG-- extra : convert_revision : 5bfe9d3f0b31824fa5a7ae3f51fd0be5ed4d555d --- arch/alpha/alpha_linux_process.cc | 88 +++++++++++++++---------------- sim/byteswap.hh | 19 +++---- 2 files changed, 54 insertions(+), 53 deletions(-) diff --git a/arch/alpha/alpha_linux_process.cc b/arch/alpha/alpha_linux_process.cc index 68d6ca180..f2907433f 100644 --- a/arch/alpha/alpha_linux_process.cc +++ b/arch/alpha/alpha_linux_process.cc @@ -251,19 +251,19 @@ class Linux { { TypedBufferArg tgt(addr); - tgt->st_dev = host->st_dev; - tgt->st_ino = host->st_ino; - tgt->st_mode = host->st_mode; - tgt->st_nlink = host->st_nlink; - tgt->st_uid = host->st_uid; - tgt->st_gid = host->st_gid; - tgt->st_rdev = host->st_rdev; - tgt->st_size = host->st_size; - tgt->st_atimeX = host->st_atime; - tgt->st_mtimeX = host->st_mtime; - tgt->st_ctimeX = host->st_ctime; - tgt->st_blksize = host->st_blksize; - tgt->st_blocks = host->st_blocks; + tgt->st_dev = htog(host->st_dev); + tgt->st_ino = htog(host->st_ino); + tgt->st_mode = htog(host->st_mode); + tgt->st_nlink = htog(host->st_nlink); + tgt->st_uid = htog(host->st_uid); + tgt->st_gid = htog(host->st_gid); + tgt->st_rdev = htog(host->st_rdev); + tgt->st_size = htog(host->st_size); + tgt->st_atimeX = htog(host->st_atime); + tgt->st_mtimeX = htog(host->st_mtime); + tgt->st_ctimeX = htog(host->st_ctime); + tgt->st_blksize = htog(host->st_blksize); + tgt->st_blocks = htog(host->st_blocks); tgt.copyOut(mem); } @@ -275,19 +275,19 @@ class Linux { { TypedBufferArg tgt(addr); - tgt->st_dev = host->st_dev; - tgt->st_ino = host->st_ino; - tgt->st_mode = host->st_mode; - tgt->st_nlink = host->st_nlink; - tgt->st_uid = host->st_uid; - tgt->st_gid = host->st_gid; - tgt->st_rdev = host->st_rdev; - tgt->st_size = host->st_size; - tgt->st_atimeX = host->st_atime; - tgt->st_mtimeX = host->st_mtime; - tgt->st_ctimeX = host->st_ctime; - tgt->st_blksize = host->st_blksize; - tgt->st_blocks = host->st_blocks; + tgt->st_dev = htog(host->st_dev); + tgt->st_ino = htog(host->st_ino); + tgt->st_mode = htog(host->st_mode); + tgt->st_nlink = htog(host->st_nlink); + tgt->st_uid = htog(host->st_uid); + tgt->st_gid = htog(host->st_gid); + tgt->st_rdev = htog(host->st_rdev); + tgt->st_size = htog(host->st_size); + tgt->st_atimeX = htog(host->st_atime); + tgt->st_mtimeX = htog(host->st_mtime); + tgt->st_ctimeX = htog(host->st_ctime); + tgt->st_blksize = htog(host->st_blksize); + tgt->st_blocks = htog(host->st_blocks); tgt.copyOut(mem); } @@ -301,25 +301,25 @@ class Linux { TypedBufferArg tgt(addr); // XXX byteswaps - tgt->st_dev = host->st_dev; + tgt->st_dev = htog(host->st_dev); // XXX What about STAT64_HAS_BROKEN_ST_INO ??? - tgt->st_ino = host->st_ino; - tgt->st_rdev = host->st_rdev; - tgt->st_size = host->st_size; - tgt->st_blocks = host->st_blocks; + tgt->st_ino = htog(host->st_ino); + tgt->st_rdev = htog(host->st_rdev); + tgt->st_size = htog(host->st_size); + tgt->st_blocks = htog(host->st_blocks); - tgt->st_mode = host->st_mode; - tgt->st_uid = host->st_uid; - tgt->st_gid = host->st_gid; - tgt->st_blksize = host->st_blksize; - tgt->st_nlink = host->st_nlink; - tgt->tgt_st_atime = host->st_atime; - tgt->tgt_st_mtime = host->st_mtime; - tgt->tgt_st_ctime = host->st_ctime; -#ifdef STAT_HAVE_NSEC - tgt->st_atime_nsec = host->st_atime_nsec; - tgt->st_mtime_nsec = host->st_mtime_nsec; - tgt->st_ctime_nsec = host->st_ctime_nsec; + tgt->st_mode = htog(host->st_mode); + tgt->st_uid = htog(host->st_uid); + tgt->st_gid = htog(host->st_gid); + tgt->st_blksize = htog(host->st_blksize); + tgt->st_nlink = htog(host->st_nlink); + tgt->tgt_st_atime = htog(host->st_atime); + tgt->tgt_st_mtime = htog(host->st_mtime); + tgt->tgt_st_ctime = htog(host->st_ctime); +#ifdef STAT_HAVE_NSEC || BSD_HOST == 1 + tgt->st_atime_nsec = htog(host->st_atime_nsec); + tgt->st_mtime_nsec = htog(host->st_mtime_nsec); + tgt->st_ctime_nsec = htog(host->st_ctime_nsec); #else tgt->st_atime_nsec = 0; tgt->st_mtime_nsec = 0; @@ -392,7 +392,7 @@ class Linux { // I don't think this exactly matches the HW FPCR fpcr.copyIn(xc->mem); DPRINTFR(SyscallVerbose, "osf_setsysinfo(SSI_IEEE_FP_CONTROL): " - " setting FPCR to 0x%x\n", *(uint64_t*)fpcr); + " setting FPCR to 0x%x\n", gtoh(*(uint64_t*)fpcr)); return 0; } diff --git a/sim/byteswap.hh b/sim/byteswap.hh index 12d63b6b6..6a98a987f 100644 --- a/sim/byteswap.hh +++ b/sim/byteswap.hh @@ -75,15 +75,16 @@ swap_byte16(uint16_t x) //This lets the compiler figure out how to call the swap_byte functions above //for different data types. -static inline uint64_t swap_byte(uint64_t x) {return swap_byte64(x);} \ -static inline int64_t swap_byte(int64_t x) {return swap_byte64((uint64_t)x);} \ -static inline uint32_t swap_byte(uint32_t x) {return swap_byte32(x);} \ -static inline int32_t swap_byte(int32_t x) {return swap_byte32((uint32_t)x);} \ -static inline uint16_t swap_byte(uint16_t x) {return swap_byte32(x);} \ -static inline int16_t swap_byte(int16_t x) {return swap_byte16((uint16_t)x);} \ -static inline uint8_t swap_byte(uint8_t x) {return x;} \ -static inline int8_t swap_byte(int8_t x) {return x;} \ -static inline double swap_byte(double x) {return swap_byte64((uint64_t)x);} \ +static inline uint64_t swap_byte(uint64_t x) {return swap_byte64(x);} +static inline int64_t swap_byte(int64_t x) {return swap_byte64((uint64_t)x);} +static inline uint32_t swap_byte(uint32_t x) {return swap_byte32(x);} +static inline int32_t swap_byte(int32_t x) {return swap_byte32((uint32_t)x);} +static inline int32_t swap_byte(long x) {return swap_byte32((long)x);} +static inline uint16_t swap_byte(uint16_t x) {return swap_byte32(x);} +static inline int16_t swap_byte(int16_t x) {return swap_byte16((uint16_t)x);} +static inline uint8_t swap_byte(uint8_t x) {return x;} +static inline int8_t swap_byte(int8_t x) {return x;} +static inline double swap_byte(double x) {return swap_byte64((uint64_t)x);} static inline float swap_byte(float x) {return swap_byte32((uint32_t)x);} //The conversion functions with fixed endianness on both ends don't need to From 59ba3d463cffb4da29b4b89e78bc5a3d1ccf51f6 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Sat, 11 Feb 2006 11:01:51 -0500 Subject: [PATCH 038/180] fix #if. I wonder why my compiler had no issues. Even though it is clearly wrong arch/alpha/alpha_linux_process.cc: fix #if. I wonder why my compiler had no issues --HG-- extra : convert_revision : 880a0442b28811db5ec548ce940060d4b26ec634 --- arch/alpha/alpha_linux_process.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/alpha/alpha_linux_process.cc b/arch/alpha/alpha_linux_process.cc index f2907433f..113b41472 100644 --- a/arch/alpha/alpha_linux_process.cc +++ b/arch/alpha/alpha_linux_process.cc @@ -316,7 +316,7 @@ class Linux { tgt->tgt_st_atime = htog(host->st_atime); tgt->tgt_st_mtime = htog(host->st_mtime); tgt->tgt_st_ctime = htog(host->st_ctime); -#ifdef STAT_HAVE_NSEC || BSD_HOST == 1 +#if defined(STAT_HAVE_NSEC) || (BSD_HOST == 1) tgt->st_atime_nsec = htog(host->st_atime_nsec); tgt->st_mtime_nsec = htog(host->st_mtime_nsec); tgt->st_ctime_nsec = htog(host->st_ctime_nsec); From 3cc6c59582a0de71a7a7c8696f503388a7447acf Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Sat, 11 Feb 2006 15:11:00 -0500 Subject: [PATCH 039/180] Add keyword parameters and list-valued arguments to instruction format functions in ISA description language. Take advantage of these features to clean up memory instruction definitions in Alpha. arch/alpha/isa/decoder.isa: arch/alpha/isa/mem.isa: arch/alpha/isa/pal.isa: Take advantage of new keyword parameters to disambiguate instruction vs. memory-request flags, and to provide a default EA calculation for memory ops (since 99% of them are the same). arch/isa_parser.py: Add two new features to instruction format functions: - Keyword parameters, a la Python. - List-valued arguments. Also export makeList() function to Python code blocks, as this is handy for dealing with flags. --HG-- extra : convert_revision : 99bbbaa2e765230aa96b6a06ed193793325f9fb0 --- arch/alpha/isa/decoder.isa | 51 +++++------ arch/alpha/isa/mem.isa | 54 ++++++----- arch/alpha/isa/pal.isa | 14 +-- arch/isa_parser.py | 178 ++++++++++++++++++++++++++++--------- 4 files changed, 199 insertions(+), 98 deletions(-) diff --git a/arch/alpha/isa/decoder.isa b/arch/alpha/isa/decoder.isa index c21465928..29124f191 100644 --- a/arch/alpha/isa/decoder.isa +++ b/arch/alpha/isa/decoder.isa @@ -34,47 +34,47 @@ decode OPCODE default Unknown::unknown() { } format LoadOrNop { - 0x0a: ldbu({{ EA = Rb + disp; }}, {{ Ra.uq = Mem.ub; }}); - 0x0c: ldwu({{ EA = Rb + disp; }}, {{ Ra.uq = Mem.uw; }}); - 0x0b: ldq_u({{ EA = (Rb + disp) & ~7; }}, {{ Ra = Mem.uq; }}); - 0x23: ldt({{ EA = Rb + disp; }}, {{ Fa = Mem.df; }}); - 0x2a: ldl_l({{ EA = Rb + disp; }}, {{ Ra.sl = Mem.sl; }}, LOCKED); - 0x2b: ldq_l({{ EA = Rb + disp; }}, {{ Ra.uq = Mem.uq; }}, LOCKED); + 0x0a: ldbu({{ Ra.uq = Mem.ub; }}); + 0x0c: ldwu({{ Ra.uq = Mem.uw; }}); + 0x0b: ldq_u({{ Ra = Mem.uq; }}, ea_code = {{ EA = (Rb + disp) & ~7; }}); + 0x23: ldt({{ Fa = Mem.df; }}); + 0x2a: ldl_l({{ Ra.sl = Mem.sl; }}, mem_flags = LOCKED); + 0x2b: ldq_l({{ Ra.uq = Mem.uq; }}, mem_flags = LOCKED); 0x20: MiscPrefetch::copy_load({{ EA = Ra; }}, {{ fault = xc->copySrcTranslate(EA); }}, - IsMemRef, IsLoad, IsCopy); + inst_flags = [IsMemRef, IsLoad, IsCopy]); } format LoadOrPrefetch { - 0x28: ldl({{ EA = Rb + disp; }}, {{ Ra.sl = Mem.sl; }}); - 0x29: ldq({{ EA = Rb + disp; }}, {{ Ra.uq = Mem.uq; }}, EVICT_NEXT); + 0x28: ldl({{ Ra.sl = Mem.sl; }}); + 0x29: ldq({{ Ra.uq = Mem.uq; }}, pf_flags = EVICT_NEXT); // IsFloating flag on lds gets the prefetch to disassemble // using f31 instead of r31... funcitonally it's unnecessary - 0x22: lds({{ EA = Rb + disp; }}, {{ Fa.uq = s_to_t(Mem.ul); }}, - PF_EXCLUSIVE, IsFloating); + 0x22: lds({{ Fa.uq = s_to_t(Mem.ul); }}, + pf_flags = PF_EXCLUSIVE, inst_flags = IsFloating); } format Store { - 0x0e: stb({{ EA = Rb + disp; }}, {{ Mem.ub = Ra<7:0>; }}); - 0x0d: stw({{ EA = Rb + disp; }}, {{ Mem.uw = Ra<15:0>; }}); - 0x2c: stl({{ EA = Rb + disp; }}, {{ Mem.ul = Ra<31:0>; }}); - 0x2d: stq({{ EA = Rb + disp; }}, {{ Mem.uq = Ra.uq; }}); - 0x0f: stq_u({{ EA = (Rb + disp) & ~7; }}, {{ Mem.uq = Ra.uq; }}); - 0x26: sts({{ EA = Rb + disp; }}, {{ Mem.ul = t_to_s(Fa.uq); }}); - 0x27: stt({{ EA = Rb + disp; }}, {{ Mem.df = Fa; }}); + 0x0e: stb({{ Mem.ub = Ra<7:0>; }}); + 0x0d: stw({{ Mem.uw = Ra<15:0>; }}); + 0x2c: stl({{ Mem.ul = Ra<31:0>; }}); + 0x2d: stq({{ Mem.uq = Ra.uq; }}); + 0x0f: stq_u({{ Mem.uq = Ra.uq; }}, {{ EA = (Rb + disp) & ~7; }}); + 0x26: sts({{ Mem.ul = t_to_s(Fa.uq); }}); + 0x27: stt({{ Mem.df = Fa; }}); 0x24: MiscPrefetch::copy_store({{ EA = Rb; }}, {{ fault = xc->copy(EA); }}, - IsMemRef, IsStore, IsCopy); + inst_flags = [IsMemRef, IsStore, IsCopy]); } format StoreCond { - 0x2e: stl_c({{ EA = Rb + disp; }}, {{ Mem.ul = Ra<31:0>; }}, + 0x2e: stl_c({{ Mem.ul = Ra<31:0>; }}, {{ uint64_t tmp = write_result; // see stq_c Ra = (tmp == 0 || tmp == 1) ? tmp : Ra; - }}, LOCKED); - 0x2f: stq_c({{ EA = Rb + disp; }}, {{ Mem.uq = Ra; }}, + }}, mem_flags = LOCKED); + 0x2f: stq_c({{ Mem.uq = Ra; }}, {{ uint64_t tmp = write_result; // If the write operation returns 0 or 1, then @@ -85,7 +85,7 @@ decode OPCODE default Unknown::unknown() { // mailbox access, and we don't update the // result register at all. Ra = (tmp == 0 || tmp == 1) ? tmp : Ra; - }}, LOCKED); + }}, mem_flags = LOCKED); } format IntegerOperate { @@ -607,8 +607,9 @@ decode OPCODE default Unknown::unknown() { format MiscPrefetch { 0xf800: wh64({{ EA = Rb & ~ULL(63); }}, {{ xc->writeHint(EA, 64, memAccessFlags); }}, - IsMemRef, IsDataPrefetch, IsStore, MemWriteOp, - NO_FAULT); + mem_flags = NO_FAULT, + inst_flags = [IsMemRef, IsDataPrefetch, + IsStore, MemWriteOp]); } format BasicOperate { diff --git a/arch/alpha/isa/mem.isa b/arch/alpha/isa/mem.isa index 0d9d59cee..45afd378c 100644 --- a/arch/alpha/isa/mem.isa +++ b/arch/alpha/isa/mem.isa @@ -407,16 +407,12 @@ def template LoadPrefetchCheckDecode {{ let {{ -def LoadStoreBase(name, Name, ea_code, memacc_code, postacc_code = '', - base_class = 'MemoryDisp32', flags = [], +def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, + postacc_code = '', base_class = 'MemoryDisp32', decode_template = BasicDecode, exec_template_base = ''): - # Segregate flags into instruction flags (handled by InstObjParams) - # and memory access flags (handled here). - - # Would be nice to autogenerate this list, but oh well. - valid_mem_flags = ['LOCKED', 'NO_FAULT', 'EVICT_NEXT', 'PF_EXCLUSIVE'] - mem_flags = [f for f in flags if f in valid_mem_flags] - inst_flags = [f for f in flags if f not in valid_mem_flags] + # Make sure flags are in lists (convert to lists if not). + mem_flags = makeList(mem_flags) + inst_flags = makeList(inst_flags) # add hook to get effective addresses into execution trace output. ea_code += '\nif (traceData) { traceData->setAddr(EA); }\n' @@ -469,31 +465,39 @@ def LoadStoreBase(name, Name, ea_code, memacc_code, postacc_code = '', }}; -def format LoadOrNop(ea_code, memacc_code, *flags) {{ +def format LoadOrNop(memacc_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, flags = flags, + LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, decode_template = LoadNopCheckDecode, exec_template_base = 'Load') }}; // Note that the flags passed in apply only to the prefetch version -def format LoadOrPrefetch(ea_code, memacc_code, *pf_flags) {{ +def format LoadOrPrefetch(memacc_code, ea_code = {{ EA = Rb + disp; }}, + mem_flags = [], pf_flags = [], inst_flags = []) {{ # declare the load instruction object and generate the decode block (header_output, decoder_output, decode_block, exec_output) = \ - LoadStoreBase(name, Name, ea_code, memacc_code, + LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, decode_template = LoadPrefetchCheckDecode, exec_template_base = 'Load') # Declare the prefetch instruction object. - # convert flags from tuple to list to make them mutable - pf_flags = list(pf_flags) + ['IsMemRef', 'IsLoad', 'IsDataPrefetch', 'MemReadOp', 'NO_FAULT'] + # Make sure flag args are lists so we can mess with them. + mem_flags = makeList(mem_flags) + pf_flags = makeList(pf_flags) + inst_flags = makeList(inst_flags) + + pf_mem_flags = mem_flags + pf_flags + ['NO_FAULT'] + pf_inst_flags = inst_flags + ['IsMemRef', 'IsLoad', + 'IsDataPrefetch', 'MemReadOp'] (pf_header_output, pf_decoder_output, _, pf_exec_output) = \ LoadStoreBase(name, Name + 'Prefetch', ea_code, 'xc->prefetch(EA, memAccessFlags);', - flags = pf_flags, exec_template_base = 'Misc') + pf_mem_flags, pf_inst_flags, exec_template_base = 'Misc') header_output += pf_header_output decoder_output += pf_decoder_output @@ -501,24 +505,28 @@ def format LoadOrPrefetch(ea_code, memacc_code, *pf_flags) {{ }}; -def format Store(ea_code, memacc_code, *flags) {{ +def format Store(memacc_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, flags = flags, + LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, exec_template_base = 'Store') }}; -def format StoreCond(ea_code, memacc_code, postacc_code, *flags) {{ +def format StoreCond(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, postacc_code, - flags = flags, exec_template_base = 'Store') + LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, + postacc_code, exec_template_base = 'Store') }}; // Use 'MemoryNoDisp' as base: for wh64, fetch, ecb -def format MiscPrefetch(ea_code, memacc_code, *flags) {{ +def format MiscPrefetch(ea_code, memacc_code, + mem_flags = [], inst_flags = []) {{ (header_output, decoder_output, decode_block, exec_output) = \ - LoadStoreBase(name, Name, ea_code, memacc_code, flags = flags, + LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, base_class = 'MemoryNoDisp', exec_template_base = 'Misc') }}; diff --git a/arch/alpha/isa/pal.isa b/arch/alpha/isa/pal.isa index 552dde2d7..b68a7c19f 100644 --- a/arch/alpha/isa/pal.isa +++ b/arch/alpha/isa/pal.isa @@ -198,23 +198,25 @@ output decoder {{ def format HwLoad(ea_code, memacc_code, class_ext, *flags) {{ (header_output, decoder_output, decode_block, exec_output) = \ LoadStoreBase(name, Name + class_ext, ea_code, memacc_code, - flags = flags, base_class = 'HwLoadStore', - exec_template_base = 'Load') + mem_flags = [], inst_flags = flags, + base_class = 'HwLoadStore', exec_template_base = 'Load') }}; def format HwStore(ea_code, memacc_code, class_ext, *flags) {{ (header_output, decoder_output, decode_block, exec_output) = \ LoadStoreBase(name, Name + class_ext, ea_code, memacc_code, - flags = flags, base_class = 'HwLoadStore', - exec_template_base = 'Store') + mem_flags = [], inst_flags = flags, + base_class = 'HwLoadStore', exec_template_base = 'Store') }}; -def format HwStoreCond(ea_code, memacc_code, postacc_code, class_ext, *flags) {{ +def format HwStoreCond(ea_code, memacc_code, postacc_code, class_ext, + *flags) {{ (header_output, decoder_output, decode_block, exec_output) = \ LoadStoreBase(name, Name + class_ext, ea_code, memacc_code, - postacc_code, flags = flags, base_class = 'HwLoadStore') + postacc_code, mem_flags = [], inst_flags = flags, + base_class = 'HwLoadStore') }}; diff --git a/arch/isa_parser.py b/arch/isa_parser.py index fffcc33e5..e7f7a897c 100755 --- a/arch/isa_parser.py +++ b/arch/isa_parser.py @@ -82,10 +82,9 @@ tokens = reserved + ( # ( ) [ ] { } < > , ; : :: * 'LPAREN', 'RPAREN', -# not used any more... commented out to suppress PLY warning -# 'LBRACKET', 'RBRACKET', + 'LBRACKET', 'RBRACKET', 'LBRACE', 'RBRACE', - 'LESS', 'GREATER', + 'LESS', 'GREATER', 'EQUALS', 'COMMA', 'SEMI', 'COLON', 'DBLCOLON', 'ASTERISK', @@ -104,13 +103,13 @@ tokens = reserved + ( # Regular expressions for token matching t_LPAREN = r'\(' t_RPAREN = r'\)' -# not used any more... commented out to suppress PLY warning -# t_LBRACKET = r'\[' -# t_RBRACKET = r'\]' +t_LBRACKET = r'\[' +t_RBRACKET = r'\]' t_LBRACE = r'\{' t_RBRACE = r'\}' t_LESS = r'\<' t_GREATER = r'\>' +t_EQUALS = r'=' t_COMMA = r',' t_SEMI = r';' t_COLON = r':' @@ -387,32 +386,66 @@ def p_def_format(t): t[0] = GenCode() # The formal parameter list for an instruction format is a possibly -# empty list of comma-separated parameters. +# empty list of comma-separated parameters. Positional (standard, +# non-keyword) parameters must come first, followed by keyword +# parameters, followed by a '*foo' parameter that gets excess +# positional arguments (as in Python). Each of these three parameter +# categories is optional. +# +# Note that we do not support the '**foo' parameter for collecting +# otherwise undefined keyword args. Otherwise the parameter list is +# (I believe) identical to what is supported in Python. +# +# The param list generates a tuple, where the first element is a list of +# the positional params and the second element is a dict containing the +# keyword params. def p_param_list_0(t): - 'param_list : empty' - t[0] = [ ] + 'param_list : positional_param_list COMMA nonpositional_param_list' + t[0] = t[1] + t[3] def p_param_list_1(t): - 'param_list : param' + '''param_list : positional_param_list + | nonpositional_param_list''' + t[0] = t[1] + +def p_positional_param_list_0(t): + 'positional_param_list : empty' + t[0] = [] + +def p_positional_param_list_1(t): + 'positional_param_list : ID' t[0] = [t[1]] -def p_param_list_2(t): - 'param_list : param_list COMMA param' - t[0] = t[1] - t[0].append(t[3]) +def p_positional_param_list_2(t): + 'positional_param_list : positional_param_list COMMA ID' + t[0] = t[1] + [t[3]] -# Each formal parameter is either an identifier or an identifier -# preceded by an asterisk. As in Python, the latter (if present) gets -# a tuple containing all the excess positional arguments, allowing -# varargs functions. -def p_param_0(t): - 'param : ID' +def p_nonpositional_param_list_0(t): + 'nonpositional_param_list : keyword_param_list COMMA excess_args_param' + t[0] = t[1] + t[3] + +def p_nonpositional_param_list_1(t): + '''nonpositional_param_list : keyword_param_list + | excess_args_param''' t[0] = t[1] -def p_param_1(t): - 'param : ASTERISK ID' - # just concatenate them: '*ID' - t[0] = t[1] + t[2] +def p_keyword_param_list_0(t): + 'keyword_param_list : keyword_param' + t[0] = [t[1]] + +def p_keyword_param_list_1(t): + 'keyword_param_list : keyword_param_list COMMA keyword_param' + t[0] = t[1] + [t[3]] + +def p_keyword_param(t): + 'keyword_param : ID EQUALS expr' + t[0] = t[1] + ' = ' + t[3].__repr__() + +def p_excess_args_param(t): + 'excess_args_param : ASTERISK ID' + # Just concatenate them: '*ID'. Wrap in list to be consistent + # with positional_param_list and keyword_param_list. + t[0] = [t[1] + t[2]] # End of format definition-related rules. ############## @@ -577,26 +610,79 @@ def p_inst_1(t): codeObj.prepend_all(comment) t[0] = codeObj +# The arg list generates a tuple, where the first element is a list of +# the positional args and the second element is a dict containing the +# keyword args. def p_arg_list_0(t): - 'arg_list : empty' - t[0] = [ ] + 'arg_list : positional_arg_list COMMA keyword_arg_list' + t[0] = ( t[1], t[3] ) def p_arg_list_1(t): - 'arg_list : arg' - t[0] = [t[1]] + 'arg_list : positional_arg_list' + t[0] = ( t[1], {} ) def p_arg_list_2(t): - 'arg_list : arg_list COMMA arg' - t[0] = t[1] - t[0].append(t[3]) + 'arg_list : keyword_arg_list' + t[0] = ( [], t[1] ) -def p_arg(t): - '''arg : ID - | INTLIT - | STRLIT - | CODELIT''' +def p_positional_arg_list_0(t): + 'positional_arg_list : empty' + t[0] = [] + +def p_positional_arg_list_1(t): + 'positional_arg_list : expr' + t[0] = [t[1]] + +def p_positional_arg_list_2(t): + 'positional_arg_list : positional_arg_list COMMA expr' + t[0] = t[1] + [t[3]] + +def p_keyword_arg_list_0(t): + 'keyword_arg_list : keyword_arg' t[0] = t[1] +def p_keyword_arg_list_1(t): + 'keyword_arg_list : keyword_arg_list COMMA keyword_arg' + t[0] = t[1] + t[0].update(t[3]) + +def p_keyword_arg(t): + 'keyword_arg : ID EQUALS expr' + t[0] = { t[1] : t[3] } + +# +# Basic expressions. These constitute the argument values of +# "function calls" (i.e. instruction definitions in the decode block) +# and default values for formal parameters of format functions. +# +# Right now, these are either strings, integers, or (recursively) +# lists of exprs (using Python square-bracket list syntax). Note that +# bare identifiers are trated as string constants here (since there +# isn't really a variable namespace to refer to). +# +def p_expr_0(t): + '''expr : ID + | INTLIT + | STRLIT + | CODELIT''' + t[0] = t[1] + +def p_expr_1(t): + '''expr : LBRACKET list_expr RBRACKET''' + t[0] = t[2] + +def p_list_expr_0(t): + 'list_expr : expr' + t[0] = [t[1]] + +def p_list_expr_1(t): + 'list_expr : list_expr COMMA expr' + t[0] = t[1] + [t[3]] + +def p_list_expr_2(t): + 'list_expr : empty' + t[0] = [] + # # Empty production... use in other rules for readability. # @@ -779,7 +865,7 @@ class Format: context.update(exportContext) context.update({ 'name': name, 'Name': string.capitalize(name) }) try: - vars = self.func(self.user_code, context, *args) + vars = self.func(self.user_code, context, *args[0], **args[1]) except Exception, exc: error(lineno, 'error defining "%s": %s.' % (name, exc)) for k in vars.keys(): @@ -974,14 +1060,18 @@ class Template: # ##################################################################### -# Force the argument to be a list -def makeList(list_or_item): - if not list_or_item: +# Force the argument to be a list. Useful for flags, where a caller +# can specify a singleton flag or a list of flags. Also usful for +# converting tuples to lists so they can be modified. +def makeList(arg): + if isinstance(arg, list): + return arg + elif isinstance(arg, tuple): + return list(arg) + elif not arg: return [] - elif type(list_or_item) == ListType: - return list_or_item else: - return [ list_or_item ] + return [ arg ] # generate operandSizeMap based on provided operandTypeMap: # basically generate equiv. C++ type and make is_signed flag @@ -1253,7 +1343,7 @@ class NPCOperandTraits(OperandTraits): exportContextSymbols = ('IntRegOperandTraits', 'FloatRegOperandTraits', 'ControlRegOperandTraits', 'MemOperandTraits', 'NPCOperandTraits', 'InstObjParams', 'CodeBlock', - 're', 'string') + 'makeList', 're', 'string') exportContext = {} From 8f2e096275386cbd6744c4bd65190dba1c5b89b4 Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Sat, 11 Feb 2006 21:26:49 -0500 Subject: [PATCH 040/180] Minor cleanup of operand type and traits code in isa_parser.py. arch/isa_parser.py: Minor cleanup of operand type and traits code: - build operand size map right away when types are defined instead of waiting to do it lazily - check that operand types have been defined before operands - don't use 'type' as a variable name - use isinstance() instead of checking for types directly --HG-- extra : convert_revision : 099c1ee8d490f9c38316749bf87209388c55c971 --- arch/isa_parser.py | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/arch/isa_parser.py b/arch/isa_parser.py index e7f7a897c..0e33b4ff7 100755 --- a/arch/isa_parser.py +++ b/arch/isa_parser.py @@ -326,12 +326,16 @@ def p_def_operand_types(t): except Exception, exc: error(t.lineno(1), 'error: %s in def operand_types block "%s".' % (exc, t[3])) + buildOperandSizeMap() t[0] = GenCode() # contributes nothing to the output C++ file # Define the mapping from operand names to operand classes and other # traits. Stored in operandTraitsMap. def p_def_operands(t): 'def_operands : DEF OPERANDS CODELIT SEMI' + if not globals().has_key('operandSizeMap'): + error(t.lineno(1), + 'error: operand types must be defined before operands') s = 'global operandTraitsMap; operandTraitsMap = {' + t[3] + '}' try: exec s @@ -1081,20 +1085,20 @@ def buildOperandSizeMap(): for ext in operandTypeMap.keys(): (desc, size) = operandTypeMap[ext] if desc == 'signed int': - type = 'int%d_t' % size + ctype = 'int%d_t' % size is_signed = 1 elif desc == 'unsigned int': - type = 'uint%d_t' % size + ctype = 'uint%d_t' % size is_signed = 0 elif desc == 'float': is_signed = 1 # shouldn't really matter if size == 32: - type = 'float' + ctype = 'float' elif size == 64: - type = 'double' - if type == '': + ctype = 'double' + if ctype == '': error(0, 'Unrecognized type description "%s" in operandTypeMap') - operandSizeMap[ext] = (size, type, is_signed) + operandSizeMap[ext] = (size, ctype, is_signed) # # Base class for operand traits. An instance of this class (or actually @@ -1103,10 +1107,6 @@ def buildOperandSizeMap(): # class OperandTraits: def __init__(self, dflt_ext, reg_spec, flags, sort_pri): - # Force construction of operandSizeMap from operandTypeMap - # if it hasn't happened yet - if not globals().has_key('operandSizeMap'): - buildOperandSizeMap() self.dflt_ext = dflt_ext (self.dflt_size, self.dflt_type, self.dflt_is_signed) = \ operandSizeMap[dflt_ext] @@ -1119,13 +1119,13 @@ class OperandTraits: if not flags: # no flags specified (e.g., 'None') self.flags = ( [], [], [] ) - elif type(flags) == StringType: + elif isinstance(flags, str): # a single flag: assumed to be unconditional self.flags = ( [ flags ], [], [] ) - elif type(flags) == ListType: + elif isinstance(flags, list): # a list of flags: also assumed to be unconditional self.flags = ( flags, [], [] ) - elif type(flags) == TupleType: + elif isinstance(flags, tuple): # it's a tuple: it should be a triple, # but each item could be a single string or a list (uncond_flags, src_flags, dest_flags) = flags From 79613686f0f6a8725e88e935a7c9ff4ede4cfc2b Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Sun, 12 Feb 2006 00:31:19 -0500 Subject: [PATCH 041/180] Polishing of isa_parser.py internal operand handling, resulting in minor change to syntax of 'def operands' in ISA descriptions. arch/alpha/isa/main.isa: arch/mips/isa/operands.isa: arch/sparc/isa/operands.isa: Change 'def operands' statement to work with new isa_parser changes. arch/isa_parser.py: Merge OperandTraits and OperandDescriptor objects into a unified hierarchy of Operand objects. Required a change in the syntax of the 'def operands' statement in the ISA description. --HG-- extra : convert_revision : cb43f1607311497ead88ba13953d410ab5bc6a37 --- arch/alpha/isa/main.isa | 25 +- arch/isa_parser.py | 635 ++++++++++++++++++------------------ arch/mips/isa/operands.isa | 29 +- arch/sparc/isa/operands.isa | 25 +- 4 files changed, 354 insertions(+), 360 deletions(-) diff --git a/arch/alpha/isa/main.isa b/arch/alpha/isa/main.isa index fa2f71a29..c082df8c8 100644 --- a/arch/alpha/isa/main.isa +++ b/arch/alpha/isa/main.isa @@ -148,20 +148,19 @@ def operands {{ # Int regs default to unsigned, but code should not count on this. # For clarity, descriptions that depend on unsigned behavior should # explicitly specify '.uq'. - 'Ra': IntRegOperandTraits('uq', 'RA', 'IsInteger', 1), - 'Rb': IntRegOperandTraits('uq', 'RB', 'IsInteger', 2), - 'Rc': IntRegOperandTraits('uq', 'RC', 'IsInteger', 3), - 'Fa': FloatRegOperandTraits('df', 'FA', 'IsFloating', 1), - 'Fb': FloatRegOperandTraits('df', 'FB', 'IsFloating', 2), - 'Fc': FloatRegOperandTraits('df', 'FC', 'IsFloating', 3), - 'Mem': MemOperandTraits('uq', None, - ('IsMemRef', 'IsLoad', 'IsStore'), 4), - 'NPC': NPCOperandTraits('uq', None, ( None, None, 'IsControl' ), 4), - 'Runiq': ControlRegOperandTraits('uq', 'Uniq', None, 1), - 'FPCR': ControlRegOperandTraits('uq', 'Fpcr', None, 1), + 'Ra': ('IntReg', 'uq', 'RA', 'IsInteger', 1), + 'Rb': ('IntReg', 'uq', 'RB', 'IsInteger', 2), + 'Rc': ('IntReg', 'uq', 'RC', 'IsInteger', 3), + 'Fa': ('FloatReg', 'df', 'FA', 'IsFloating', 1), + 'Fb': ('FloatReg', 'df', 'FB', 'IsFloating', 2), + 'Fc': ('FloatReg', 'df', 'FC', 'IsFloating', 3), + 'Mem': ('Mem', 'uq', None, ('IsMemRef', 'IsLoad', 'IsStore'), 4), + 'NPC': ('NPC', 'uq', None, ( None, None, 'IsControl' ), 4), + 'Runiq': ('ControlReg', 'uq', 'Uniq', None, 1), + 'FPCR': (' ControlReg', 'uq', 'Fpcr', None, 1), # The next two are hacks for non-full-system call-pal emulation - 'R0': IntRegOperandTraits('uq', '0', None, 1), - 'R16': IntRegOperandTraits('uq', '16', None, 1) + 'R0': ('IntReg', 'uq', '0', None, 1), + 'R16': ('IntReg', 'uq', '16', None, 1) }}; //////////////////////////////////////////////////////////////////// diff --git a/arch/isa_parser.py b/arch/isa_parser.py index 0e33b4ff7..030bb5a7c 100755 --- a/arch/isa_parser.py +++ b/arch/isa_parser.py @@ -320,29 +320,27 @@ def p_global_let(t): # widths (stored in operandTypeMap). def p_def_operand_types(t): 'def_operand_types : DEF OPERAND_TYPES CODELIT SEMI' - s = 'global operandTypeMap; operandTypeMap = {' + t[3] + '}' try: - exec s + userDict = eval('{' + t[3] + '}') except Exception, exc: error(t.lineno(1), 'error: %s in def operand_types block "%s".' % (exc, t[3])) - buildOperandSizeMap() + buildOperandTypeMap(userDict, t.lineno(1)) t[0] = GenCode() # contributes nothing to the output C++ file # Define the mapping from operand names to operand classes and other -# traits. Stored in operandTraitsMap. +# traits. Stored in operandNameMap. def p_def_operands(t): 'def_operands : DEF OPERANDS CODELIT SEMI' - if not globals().has_key('operandSizeMap'): + if not globals().has_key('operandTypeMap'): error(t.lineno(1), 'error: operand types must be defined before operands') - s = 'global operandTraitsMap; operandTraitsMap = {' + t[3] + '}' try: - exec s + userDict = eval('{' + t[3] + '}') except Exception, exc: error(t.lineno(1), 'error: %s in def operands block "%s".' % (exc, t[3])) - defineDerivedOperandVars() + buildOperandNameMap(userDict, t.lineno(1)) t[0] = GenCode() # contributes nothing to the output C++ file # A bitfield definition looks like: @@ -847,6 +845,19 @@ class GenCode: # a defineInst() method that generates the code for an instruction # definition. +exportContextSymbols = ('InstObjParams', 'CodeBlock', + 'makeList', 're', 'string') + +exportContext = {} + +def updateExportContext(): + exportContext.update(exportDict(*exportContextSymbols)) + exportContext.update(templateMap) + +def exportDict(*symNames): + return dict([(s, eval(s)) for s in symNames]) + + class Format: def __init__(self, id, params, code): # constructor: just save away arguments @@ -1077,13 +1088,12 @@ def makeList(arg): else: return [ arg ] -# generate operandSizeMap based on provided operandTypeMap: -# basically generate equiv. C++ type and make is_signed flag -def buildOperandSizeMap(): - global operandSizeMap - operandSizeMap = {} - for ext in operandTypeMap.keys(): - (desc, size) = operandTypeMap[ext] +# Generate operandTypeMap from the user's 'def operand_types' +# statement. +def buildOperandTypeMap(userDict, lineno): + global operandTypeMap + operandTypeMap = {} + for (ext, (desc, size)) in userDict.iteritems(): if desc == 'signed int': ctype = 'int%d_t' % size is_signed = 1 @@ -1097,20 +1107,262 @@ def buildOperandSizeMap(): elif size == 64: ctype = 'double' if ctype == '': - error(0, 'Unrecognized type description "%s" in operandTypeMap') - operandSizeMap[ext] = (size, ctype, is_signed) + error(0, 'Unrecognized type description "%s" in userDict') + operandTypeMap[ext] = (size, ctype, is_signed) # -# Base class for operand traits. An instance of this class (or actually -# a class derived from this one) encapsulates the traits of a particular -# operand type (e.g., "32-bit integer register"). # -class OperandTraits: - def __init__(self, dflt_ext, reg_spec, flags, sort_pri): - self.dflt_ext = dflt_ext - (self.dflt_size, self.dflt_type, self.dflt_is_signed) = \ - operandSizeMap[dflt_ext] - self.reg_spec = reg_spec +# +# Base class for operand descriptors. An instance of this class (or +# actually a class derived from this one) represents a specific +# operand for a code block (e.g, "Rc.sq" as a dest). Intermediate +# derived classes encapsulates the traits of a particular operand type +# (e.g., "32-bit integer register"). +# +class Operand(object): + def __init__(self, full_name, ext, is_src, is_dest): + self.full_name = full_name + self.ext = ext + self.is_src = is_src + self.is_dest = is_dest + # The 'effective extension' (eff_ext) is either the actual + # extension, if one was explicitly provided, or the default. + if ext: + self.eff_ext = ext + else: + self.eff_ext = self.dflt_ext + + (self.size, self.ctype, self.is_signed) = operandTypeMap[self.eff_ext] + + # note that mem_acc_size is undefined for non-mem operands... + # template must be careful not to use it if it doesn't apply. + if self.isMem(): + self.mem_acc_size = self.makeAccSize() + + # Finalize additional fields (primarily code fields). This step + # is done separately since some of these fields may depend on the + # register index enumeration that hasn't been performed yet at the + # time of __init__(). + def finalize(self): + self.flags = self.getFlags() + self.constructor = self.makeConstructor() + self.op_decl = self.makeDecl() + + if self.is_src: + self.op_rd = self.makeRead() + else: + self.op_rd = '' + + if self.is_dest: + self.op_wb = self.makeWrite() + else: + self.op_wb = '' + + def isMem(self): + return 0 + + def isReg(self): + return 0 + + def isFloatReg(self): + return 0 + + def isIntReg(self): + return 0 + + def isControlReg(self): + return 0 + + def getFlags(self): + # note the empty slice '[:]' gives us a copy of self.flags[0] + # instead of a reference to it + my_flags = self.flags[0][:] + if self.is_src: + my_flags += self.flags[1] + if self.is_dest: + my_flags += self.flags[2] + return my_flags + + def makeDecl(self): + # Note that initializations in the declarations are solely + # to avoid 'uninitialized variable' errors from the compiler. + return self.ctype + ' ' + self.base_name + ' = 0;\n'; + +class IntRegOperand(Operand): + def isReg(self): + return 1 + + def isIntReg(self): + return 1 + + def makeConstructor(self): + c = '' + if self.is_src: + c += '\n\t_srcRegIdx[%d] = %s;' % \ + (self.src_reg_idx, self.reg_spec) + if self.is_dest: + c += '\n\t_destRegIdx[%d] = %s;' % \ + (self.dest_reg_idx, self.reg_spec) + return c + + def makeRead(self): + if (self.ctype == 'float' or self.ctype == 'double'): + error(0, 'Attempt to read integer register as FP') + if (self.size == self.dflt_size): + return '%s = xc->readIntReg(this, %d);\n' % \ + (self.base_name, self.src_reg_idx) + else: + return '%s = bits(xc->readIntReg(this, %d), %d, 0);\n' % \ + (self.base_name, self.src_reg_idx, self.size-1) + + def makeWrite(self): + if (self.ctype == 'float' or self.ctype == 'double'): + error(0, 'Attempt to write integer register as FP') + if (self.size != self.dflt_size and self.is_signed): + final_val = 'sext<%d>(%s)' % (self.size, self.base_name) + else: + final_val = self.base_name + wb = ''' + { + %s final_val = %s; + xc->setIntReg(this, %d, final_val);\n + if (traceData) { traceData->setData(final_val); } + }''' % (self.dflt_ctype, final_val, self.dest_reg_idx) + return wb + +class FloatRegOperand(Operand): + def isReg(self): + return 1 + + def isFloatReg(self): + return 1 + + def makeConstructor(self): + c = '' + if self.is_src: + c += '\n\t_srcRegIdx[%d] = %s + FP_Base_DepTag;' % \ + (self.src_reg_idx, self.reg_spec) + if self.is_dest: + c += '\n\t_destRegIdx[%d] = %s + FP_Base_DepTag;' % \ + (self.dest_reg_idx, self.reg_spec) + return c + + def makeRead(self): + bit_select = 0 + if (self.ctype == 'float'): + func = 'readFloatRegSingle' + elif (self.ctype == 'double'): + func = 'readFloatRegDouble' + else: + func = 'readFloatRegInt' + if (self.size != self.dflt_size): + bit_select = 1 + base = 'xc->%s(this, %d)' % \ + (func, self.src_reg_idx) + if bit_select: + return '%s = bits(%s, %d, 0);\n' % \ + (self.base_name, base, self.size-1) + else: + return '%s = %s;\n' % (self.base_name, base) + + def makeWrite(self): + final_val = self.base_name + final_ctype = self.ctype + if (self.ctype == 'float'): + func = 'setFloatRegSingle' + elif (self.ctype == 'double'): + func = 'setFloatRegDouble' + else: + func = 'setFloatRegInt' + final_ctype = 'uint%d_t' % self.dflt_size + if (self.size != self.dflt_size and self.is_signed): + final_val = 'sext<%d>(%s)' % (self.size, self.base_name) + wb = ''' + { + %s final_val = %s; + xc->%s(this, %d, final_val);\n + if (traceData) { traceData->setData(final_val); } + }''' % (final_ctype, final_val, func, self.dest_reg_idx) + return wb + +class ControlRegOperand(Operand): + def isReg(self): + return 1 + + def isControlReg(self): + return 1 + + def makeConstructor(self): + c = '' + if self.is_src: + c += '\n\t_srcRegIdx[%d] = %s_DepTag;' % \ + (self.src_reg_idx, self.reg_spec) + if self.is_dest: + c += '\n\t_destRegIdx[%d] = %s_DepTag;' % \ + (self.dest_reg_idx, self.reg_spec) + return c + + def makeRead(self): + bit_select = 0 + if (self.ctype == 'float' or self.ctype == 'double'): + error(0, 'Attempt to read control register as FP') + base = 'xc->read%s()' % self.reg_spec + if self.size == self.dflt_size: + return '%s = %s;\n' % (self.base_name, base) + else: + return '%s = bits(%s, %d, 0);\n' % \ + (self.base_name, base, self.size-1) + + def makeWrite(self): + if (self.ctype == 'float' or self.ctype == 'double'): + error(0, 'Attempt to write control register as FP') + wb = 'xc->set%s(%s);\n' % (self.reg_spec, self.base_name) + wb += 'if (traceData) { traceData->setData(%s); }' % \ + self.base_name + return wb + +class MemOperand(Operand): + def isMem(self): + return 1 + + def makeConstructor(self): + return '' + + def makeDecl(self): + # Note that initializations in the declarations are solely + # to avoid 'uninitialized variable' errors from the compiler. + # Declare memory data variable. + c = '%s %s = 0;\n' % (self.ctype, self.base_name) + return c + + def makeRead(self): + return '' + + def makeWrite(self): + return '' + + # Return the memory access size *in bits*, suitable for + # forming a type via "uint%d_t". Divide by 8 if you want bytes. + def makeAccSize(self): + return self.size + +class NPCOperand(Operand): + def makeConstructor(self): + return '' + + def makeRead(self): + return '%s = xc->readPC() + 4;\n' % self.base_name + + def makeWrite(self): + return 'xc->setNextPC(%s);\n' % self.base_name + + +def buildOperandNameMap(userDict, lineno): + global operandNameMap + operandNameMap = {} + for (op_name, val) in userDict.iteritems(): + (base_cls_name, dflt_ext, reg_spec, flags, sort_pri) = val + (dflt_size, dflt_ctype, dflt_is_signed) = operandTypeMap[dflt_ext] # Canonical flag structure is a triple of lists, where each list # indicates the set of flags implied by this operand always, when # used as a source, and when used as a dest, respectively. @@ -1118,253 +1370,42 @@ class OperandTraits: # obvious shortcuts; we convert these to canonical form here. if not flags: # no flags specified (e.g., 'None') - self.flags = ( [], [], [] ) + flags = ( [], [], [] ) elif isinstance(flags, str): # a single flag: assumed to be unconditional - self.flags = ( [ flags ], [], [] ) + flags = ( [ flags ], [], [] ) elif isinstance(flags, list): # a list of flags: also assumed to be unconditional - self.flags = ( flags, [], [] ) + flags = ( flags, [], [] ) elif isinstance(flags, tuple): # it's a tuple: it should be a triple, # but each item could be a single string or a list (uncond_flags, src_flags, dest_flags) = flags - self.flags = (makeList(uncond_flags), - makeList(src_flags), makeList(dest_flags)) - self.sort_pri = sort_pri + flags = (makeList(uncond_flags), + makeList(src_flags), makeList(dest_flags)) + # Accumulate attributes of new operand class in tmp_dict + tmp_dict = {} + for attr in ('dflt_ext', 'reg_spec', 'flags', 'sort_pri', + 'dflt_size', 'dflt_ctype', 'dflt_is_signed'): + tmp_dict[attr] = eval(attr) + tmp_dict['base_name'] = op_name + # New class name will be e.g. "IntReg_Ra" + cls_name = base_cls_name + '_' + op_name + # Evaluate string arg to get class object. Note that the + # actual base class for "IntReg" is "IntRegOperand", i.e. we + # have to append "Operand". + try: + base_cls = eval(base_cls_name + 'Operand') + except NameError: + error(lineno, + 'error: unknown operand base class "%s"' % base_cls_name) + # The following statement creates a new class called + # as a subclass of with the attributes + # in tmp_dict, just as if we evaluated a class declaration. + operandNameMap[op_name] = type(cls_name, (base_cls,), tmp_dict) - def isMem(self): - return 0 - - def isReg(self): - return 0 - - def isFloatReg(self): - return 0 - - def isIntReg(self): - return 0 - - def isControlReg(self): - return 0 - - def getFlags(self, op_desc): - # note the empty slice '[:]' gives us a copy of self.flags[0] - # instead of a reference to it - my_flags = self.flags[0][:] - if op_desc.is_src: - my_flags += self.flags[1] - if op_desc.is_dest: - my_flags += self.flags[2] - return my_flags - - def makeDecl(self, op_desc): - (size, type, is_signed) = operandSizeMap[op_desc.eff_ext] - # Note that initializations in the declarations are solely - # to avoid 'uninitialized variable' errors from the compiler. - return type + ' ' + op_desc.base_name + ' = 0;\n'; - -class IntRegOperandTraits(OperandTraits): - def isReg(self): - return 1 - - def isIntReg(self): - return 1 - - def makeConstructor(self, op_desc): - c = '' - if op_desc.is_src: - c += '\n\t_srcRegIdx[%d] = %s;' % \ - (op_desc.src_reg_idx, self.reg_spec) - if op_desc.is_dest: - c += '\n\t_destRegIdx[%d] = %s;' % \ - (op_desc.dest_reg_idx, self.reg_spec) - return c - - def makeRead(self, op_desc): - (size, type, is_signed) = operandSizeMap[op_desc.eff_ext] - if (type == 'float' or type == 'double'): - error(0, 'Attempt to read integer register as FP') - if (size == self.dflt_size): - return '%s = xc->readIntReg(this, %d);\n' % \ - (op_desc.base_name, op_desc.src_reg_idx) - else: - return '%s = bits(xc->readIntReg(this, %d), %d, 0);\n' % \ - (op_desc.base_name, op_desc.src_reg_idx, size-1) - - def makeWrite(self, op_desc): - (size, type, is_signed) = operandSizeMap[op_desc.eff_ext] - if (type == 'float' or type == 'double'): - error(0, 'Attempt to write integer register as FP') - if (size != self.dflt_size and is_signed): - final_val = 'sext<%d>(%s)' % (size, op_desc.base_name) - else: - final_val = op_desc.base_name - wb = ''' - { - %s final_val = %s; - xc->setIntReg(this, %d, final_val);\n - if (traceData) { traceData->setData(final_val); } - }''' % (self.dflt_type, final_val, op_desc.dest_reg_idx) - return wb - -class FloatRegOperandTraits(OperandTraits): - def isReg(self): - return 1 - - def isFloatReg(self): - return 1 - - def makeConstructor(self, op_desc): - c = '' - if op_desc.is_src: - c += '\n\t_srcRegIdx[%d] = %s + FP_Base_DepTag;' % \ - (op_desc.src_reg_idx, self.reg_spec) - if op_desc.is_dest: - c += '\n\t_destRegIdx[%d] = %s + FP_Base_DepTag;' % \ - (op_desc.dest_reg_idx, self.reg_spec) - return c - - def makeRead(self, op_desc): - (size, type, is_signed) = operandSizeMap[op_desc.eff_ext] - bit_select = 0 - if (type == 'float'): - func = 'readFloatRegSingle' - elif (type == 'double'): - func = 'readFloatRegDouble' - else: - func = 'readFloatRegInt' - if (size != self.dflt_size): - bit_select = 1 - base = 'xc->%s(this, %d)' % \ - (func, op_desc.src_reg_idx) - if bit_select: - return '%s = bits(%s, %d, 0);\n' % \ - (op_desc.base_name, base, size-1) - else: - return '%s = %s;\n' % (op_desc.base_name, base) - - def makeWrite(self, op_desc): - (size, type, is_signed) = operandSizeMap[op_desc.eff_ext] - final_val = op_desc.base_name - if (type == 'float'): - func = 'setFloatRegSingle' - elif (type == 'double'): - func = 'setFloatRegDouble' - else: - func = 'setFloatRegInt' - type = 'uint%d_t' % self.dflt_size - if (size != self.dflt_size and is_signed): - final_val = 'sext<%d>(%s)' % (size, op_desc.base_name) - wb = ''' - { - %s final_val = %s; - xc->%s(this, %d, final_val);\n - if (traceData) { traceData->setData(final_val); } - }''' % (type, final_val, func, op_desc.dest_reg_idx) - return wb - -class ControlRegOperandTraits(OperandTraits): - def isReg(self): - return 1 - - def isControlReg(self): - return 1 - - def makeConstructor(self, op_desc): - c = '' - if op_desc.is_src: - c += '\n\t_srcRegIdx[%d] = %s_DepTag;' % \ - (op_desc.src_reg_idx, self.reg_spec) - if op_desc.is_dest: - c += '\n\t_destRegIdx[%d] = %s_DepTag;' % \ - (op_desc.dest_reg_idx, self.reg_spec) - return c - - def makeRead(self, op_desc): - (size, type, is_signed) = operandSizeMap[op_desc.eff_ext] - bit_select = 0 - if (type == 'float' or type == 'double'): - error(0, 'Attempt to read control register as FP') - base = 'xc->read%s()' % self.reg_spec - if size == self.dflt_size: - return '%s = %s;\n' % (op_desc.base_name, base) - else: - return '%s = bits(%s, %d, 0);\n' % \ - (op_desc.base_name, base, size-1) - - def makeWrite(self, op_desc): - (size, type, is_signed) = operandSizeMap[op_desc.eff_ext] - if (type == 'float' or type == 'double'): - error(0, 'Attempt to write control register as FP') - wb = 'xc->set%s(%s);\n' % (self.reg_spec, op_desc.base_name) - wb += 'if (traceData) { traceData->setData(%s); }' % \ - op_desc.base_name - return wb - -class MemOperandTraits(OperandTraits): - def isMem(self): - return 1 - - def makeConstructor(self, op_desc): - return '' - - def makeDecl(self, op_desc): - (size, type, is_signed) = operandSizeMap[op_desc.eff_ext] - # Note that initializations in the declarations are solely - # to avoid 'uninitialized variable' errors from the compiler. - # Declare memory data variable. - c = '%s %s = 0;\n' % (type, op_desc.base_name) - return c - - def makeRead(self, op_desc): - return '' - - def makeWrite(self, op_desc): - return '' - - # Return the memory access size *in bits*, suitable for - # forming a type via "uint%d_t". Divide by 8 if you want bytes. - def makeAccSize(self, op_desc): - (size, type, is_signed) = operandSizeMap[op_desc.eff_ext] - return size - -class NPCOperandTraits(OperandTraits): - def makeConstructor(self, op_desc): - return '' - - def makeRead(self, op_desc): - return '%s = xc->readPC() + 4;\n' % op_desc.base_name - - def makeWrite(self, op_desc): - return 'xc->setNextPC(%s);\n' % op_desc.base_name - - -exportContextSymbols = ('IntRegOperandTraits', 'FloatRegOperandTraits', - 'ControlRegOperandTraits', 'MemOperandTraits', - 'NPCOperandTraits', 'InstObjParams', 'CodeBlock', - 'makeList', 're', 'string') - -exportContext = {} - -def updateExportContext(): - exportContext.update(exportDict(*exportContextSymbols)) - exportContext.update(templateMap) - - -def exportDict(*symNames): - return dict([(s, eval(s)) for s in symNames]) - - -# -# Define operand variables that get derived from the basic declaration -# of ISA-specific operands in operandTraitsMap. This function must be -# called by the ISA description file explicitly after defining -# operandTraitsMap (in a 'let' block). -# -def defineDerivedOperandVars(): - global operands - operands = operandTraitsMap.keys() + # Define operand variables. + operands = userDict.keys() operandsREString = (r''' (? Date: Sun, 12 Feb 2006 12:14:14 -0500 Subject: [PATCH 042/180] vptr.hh: Rename: arch/alpha/vptr.hh -> sim/vptr.hh --HG-- rename : arch/alpha/vptr.hh => sim/vptr.hh extra : convert_revision : 345745efec49f6169d1d9f61fd590240a995373b --- {arch/alpha => sim}/vptr.hh | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {arch/alpha => sim}/vptr.hh (100%) diff --git a/arch/alpha/vptr.hh b/sim/vptr.hh similarity index 100% rename from arch/alpha/vptr.hh rename to sim/vptr.hh From 2c5e03550adcd1348cc1d6f3c00af77cbf99c5ce Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 12 Feb 2006 12:40:58 -0500 Subject: [PATCH 043/180] Removed isa_traits.hh from targetarch, moved vptr.hh from arch/alpha to sim, fixed an include to have the new location, and removed an ambiguating function declaration in byteswap.hh. SConscript: Moved isa_fullsys_traits.hh out of targetarch, since the only place it's included, and the only place the comments in the file say it should be included, is in the alpha isa_traits.hh targetarch/isa_traits.hh is now included through arch/isa_traits.hh vptr.hh was removed from targetarch, and moved to sim arch/alpha/pseudo_inst.cc: Moved vptr.hh from targetarch to sim base/loader/object_file.hh: base/loader/symtab.hh: cpu/base.hh: dev/ide_disk.cc: Changed the include of isa_traits.hh from targetarch to arch cpu/static_inst.hh: dev/platform.hh: dev/simple_disk.hh: kern/tru64/dump_mbuf.cc: kern/tru64/mbuf.hh: kern/tru64/tru64_events.cc: kern/tru64/tru64_system.cc: kern/tru64/tru64_system.hh: sim/process.hh: sim/syscall_emul.hh: Changed the include of isa_traits.hh from targetarch to arch. kern/linux/linux_threadinfo.hh: Changed the include of vptr.hh from targetarch to sim. sim/byteswap.hh: Removed the line declaring swap_byte(long), since it ambiguates with swap_byte(int32_t) sim/vptr.hh: Fixed the assert in the equals operator. Changed the AlphaISA namespace reference to TheISA. Changed arch/alpha/vtophys.hh to targetarch/vtophys.hh, since this file is now for all architectures. Added an include of arch/isa_traits.hh so that TheISA would be defined. --HG-- extra : convert_revision : e3c6ac17ed0277cfeba1d35cd63eba66eba5996f --- SConscript | 6 +++--- arch/alpha/pseudo_inst.cc | 2 +- base/loader/object_file.hh | 2 +- base/loader/symtab.hh | 2 +- cpu/base.hh | 2 +- cpu/static_inst.hh | 2 +- dev/ide_disk.cc | 2 +- dev/platform.hh | 2 +- dev/simple_disk.hh | 2 +- kern/linux/linux_threadinfo.hh | 2 +- kern/tru64/dump_mbuf.cc | 2 +- kern/tru64/mbuf.hh | 2 +- kern/tru64/tru64_events.cc | 2 +- kern/tru64/tru64_system.cc | 2 +- kern/tru64/tru64_system.hh | 2 +- sim/byteswap.hh | 1 - sim/process.hh | 2 +- sim/syscall_emul.hh | 2 +- sim/vptr.hh | 10 ++++++---- 19 files changed, 25 insertions(+), 24 deletions(-) diff --git a/SConscript b/SConscript index 589b2a17c..0206141fc 100644 --- a/SConscript +++ b/SConscript @@ -347,16 +347,16 @@ targetarch_files = Split(''' ecoff_machdep.h ev5.hh faults.hh - isa_fullsys_traits.hh - isa_traits.hh pseudo_inst.hh stacktrace.hh - vptr.hh vtophys.hh ''') +# isa_traits.hh # osfpal.hh # byte_swap.hh # alpha_common_syscall_emul.hh +# vptr.hh +# isa_fullsys_traits.hh # Set up bridging headers to the architecture specific versions for f in targetarch_files: diff --git a/arch/alpha/pseudo_inst.cc b/arch/alpha/pseudo_inst.cc index e105b3cc8..d6f622ba2 100644 --- a/arch/alpha/pseudo_inst.cc +++ b/arch/alpha/pseudo_inst.cc @@ -46,7 +46,7 @@ #include "sim/stats.hh" #include "sim/system.hh" #include "sim/debug.hh" -#include "targetarch/vptr.hh" +#include "sim/vptr.hh" using namespace std; diff --git a/base/loader/object_file.hh b/base/loader/object_file.hh index 26d3ef3b0..3c8659e18 100644 --- a/base/loader/object_file.hh +++ b/base/loader/object_file.hh @@ -29,7 +29,7 @@ #ifndef __OBJECT_FILE_HH__ #define __OBJECT_FILE_HH__ -#include "targetarch/isa_traits.hh" // for Addr +#include "arch/isa_traits.hh" // for Addr class FunctionalMemory; class SymbolTable; diff --git a/base/loader/symtab.hh b/base/loader/symtab.hh index 324fd8b45..ebcda1345 100644 --- a/base/loader/symtab.hh +++ b/base/loader/symtab.hh @@ -32,7 +32,7 @@ #include #include -#include "targetarch/isa_traits.hh" // for Addr +#include "arch/isa_traits.hh" // for Addr class Checkpoint; class SymbolTable diff --git a/cpu/base.hh b/cpu/base.hh index 4a44ab804..2bd1210d8 100644 --- a/cpu/base.hh +++ b/cpu/base.hh @@ -36,7 +36,7 @@ #include "cpu/sampler/sampler.hh" #include "sim/eventq.hh" #include "sim/sim_object.hh" -#include "targetarch/isa_traits.hh" +#include "arch/isa_traits.hh" #if FULL_SYSTEM class System; diff --git a/cpu/static_inst.hh b/cpu/static_inst.hh index 85cfb5ae7..24997eadc 100644 --- a/cpu/static_inst.hh +++ b/cpu/static_inst.hh @@ -36,7 +36,7 @@ #include "base/refcnt.hh" #include "encumbered/cpu/full/op_class.hh" #include "sim/host.hh" -#include "targetarch/isa_traits.hh" +#include "arch/isa_traits.hh" // forward declarations struct AlphaSimpleImpl; diff --git a/dev/ide_disk.cc b/dev/ide_disk.cc index ea8f151c0..9d8bb8825 100644 --- a/dev/ide_disk.cc +++ b/dev/ide_disk.cc @@ -50,7 +50,7 @@ #include "sim/builder.hh" #include "sim/sim_object.hh" #include "sim/root.hh" -#include "targetarch/isa_traits.hh" +#include "arch/isa_traits.hh" using namespace std; diff --git a/dev/platform.hh b/dev/platform.hh index ee9c72617..1ee645454 100644 --- a/dev/platform.hh +++ b/dev/platform.hh @@ -35,7 +35,7 @@ #define __DEV_PLATFORM_HH__ #include "sim/sim_object.hh" -#include "targetarch/isa_traits.hh" +#include "arch/isa_traits.hh" class PciConfigAll; class IntrControl; diff --git a/dev/simple_disk.hh b/dev/simple_disk.hh index 006155168..6560e15c2 100644 --- a/dev/simple_disk.hh +++ b/dev/simple_disk.hh @@ -34,7 +34,7 @@ #define __DEV_SIMPLE_DISK_HH__ #include "sim/sim_object.hh" -#include "targetarch/isa_traits.hh" +#include "arch/isa_traits.hh" class DiskImage; class PhysicalMemory; diff --git a/kern/linux/linux_threadinfo.hh b/kern/linux/linux_threadinfo.hh index 0c60b9f5c..9bab1dc49 100644 --- a/kern/linux/linux_threadinfo.hh +++ b/kern/linux/linux_threadinfo.hh @@ -31,7 +31,7 @@ #include "kern/linux/thread_info.hh" #include "kern/linux/sched.hh" -#include "targetarch/vptr.hh" +#include "sim/vptr.hh" namespace Linux { diff --git a/kern/tru64/dump_mbuf.cc b/kern/tru64/dump_mbuf.cc index 215930923..85cb4de96 100644 --- a/kern/tru64/dump_mbuf.cc +++ b/kern/tru64/dump_mbuf.cc @@ -35,7 +35,7 @@ #include "kern/tru64/mbuf.hh" #include "sim/host.hh" #include "targetarch/arguments.hh" -#include "targetarch/isa_traits.hh" +#include "arch/isa_traits.hh" #include "targetarch/vtophys.hh" namespace tru64 { diff --git a/kern/tru64/mbuf.hh b/kern/tru64/mbuf.hh index f89074653..93424858f 100644 --- a/kern/tru64/mbuf.hh +++ b/kern/tru64/mbuf.hh @@ -30,7 +30,7 @@ #define __MBUF_HH__ #include "sim/host.hh" -#include "targetarch/isa_traits.hh" +#include "arch/isa_traits.hh" namespace tru64 { diff --git a/kern/tru64/tru64_events.cc b/kern/tru64/tru64_events.cc index 2079922b7..d769aab0f 100644 --- a/kern/tru64/tru64_events.cc +++ b/kern/tru64/tru64_events.cc @@ -34,7 +34,7 @@ #include "kern/tru64/printf.hh" #include "mem/functional/memory_control.hh" #include "targetarch/arguments.hh" -#include "targetarch/isa_traits.hh" +#include "arch/isa_traits.hh" //void SkipFuncEvent::process(ExecContext *xc); diff --git a/kern/tru64/tru64_system.cc b/kern/tru64/tru64_system.cc index f65293474..ebcdc1553 100644 --- a/kern/tru64/tru64_system.cc +++ b/kern/tru64/tru64_system.cc @@ -36,7 +36,7 @@ #include "mem/functional/memory_control.hh" #include "mem/functional/physical.hh" #include "sim/builder.hh" -#include "targetarch/isa_traits.hh" +#include "arch/isa_traits.hh" #include "targetarch/vtophys.hh" using namespace std; diff --git a/kern/tru64/tru64_system.hh b/kern/tru64/tru64_system.hh index a9077e112..d4eb5a59a 100644 --- a/kern/tru64/tru64_system.hh +++ b/kern/tru64/tru64_system.hh @@ -30,7 +30,7 @@ #define __KERN_TRU64_TRU64_SYSTEM_HH__ #include "sim/system.hh" -#include "targetarch/isa_traits.hh" +#include "arch/isa_traits.hh" class ExecContext; diff --git a/sim/byteswap.hh b/sim/byteswap.hh index 6a98a987f..c8e3694fe 100644 --- a/sim/byteswap.hh +++ b/sim/byteswap.hh @@ -79,7 +79,6 @@ static inline uint64_t swap_byte(uint64_t x) {return swap_byte64(x);} static inline int64_t swap_byte(int64_t x) {return swap_byte64((uint64_t)x);} static inline uint32_t swap_byte(uint32_t x) {return swap_byte32(x);} static inline int32_t swap_byte(int32_t x) {return swap_byte32((uint32_t)x);} -static inline int32_t swap_byte(long x) {return swap_byte32((long)x);} static inline uint16_t swap_byte(uint16_t x) {return swap_byte32(x);} static inline int16_t swap_byte(int16_t x) {return swap_byte16((uint16_t)x);} static inline uint8_t swap_byte(uint8_t x) {return x;} diff --git a/sim/process.hh b/sim/process.hh index 2116ef632..43fafd9d7 100644 --- a/sim/process.hh +++ b/sim/process.hh @@ -40,7 +40,7 @@ #include -#include "targetarch/isa_traits.hh" +#include "arch/isa_traits.hh" #include "sim/sim_object.hh" #include "sim/stats.hh" #include "base/statistics.hh" diff --git a/sim/syscall_emul.hh b/sim/syscall_emul.hh index f55709575..4e247ed55 100644 --- a/sim/syscall_emul.hh +++ b/sim/syscall_emul.hh @@ -47,7 +47,7 @@ #include "base/intmath.hh" // for RoundUp #include "mem/functional/functional.hh" -#include "targetarch/isa_traits.hh" // for Addr +#include "arch/isa_traits.hh" // for Addr #include "base/trace.hh" #include "cpu/exec_context.hh" diff --git a/sim/vptr.hh b/sim/vptr.hh index d1bda4061..7ec43602d 100644 --- a/sim/vptr.hh +++ b/sim/vptr.hh @@ -29,7 +29,8 @@ #ifndef __ARCH_ALPHA_VPTR_HH__ #define __ARCH_ALPHA_VPTR_HH__ -#include "arch/alpha/vtophys.hh" +#include "targetarch/vtophys.hh" +#include "arch/isa_traits.hh" class ExecContext; @@ -69,15 +70,16 @@ class VPtr const VPtr &operator+=(int offset) { ptr += offset; - assert((ptr & (AlphaISA::PageBytes - 1)) + sizeof(T) - < AlphaISA::PageBytes); + assert((ptr & (TheISA::PageBytes - 1)) + sizeof(T) + < TheISA::PageBytes); return *this; } const VPtr &operator=(Addr p) { - assert((p & (AlphaISA::PageBytes)) + sizeof(T) < AlphaISA::PageBytes); + assert((p & (TheISA::PageBytes - 1)) + sizeof(T) + < TheISA::PageBytes); ptr = p; return *this; From 19e5efed03dd7e0ff003ea804b285ee490adf061 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 12 Feb 2006 17:38:10 -0500 Subject: [PATCH 044/180] Pseudo instructions are now passed whatever instructions they need by the decoder, rather than extracting them explicitly. This lets most of the pseudo instruction code to be shared across architectures. SConscript: Moved pseudo_inst.hh from targetarch to full system sources arch/alpha/SConscript: Moved pseudo_inst.cc out of the alpha specific sources arch/alpha/isa/decoder.isa: The decoder now pulls out the arguments for the pseudo instructions based on the alpha ABI arch/alpha/isa/main.isa: Registers 16, 17 and 18 are used to get parameters for the pseudo instructions and can be referred to explicitly sim/pseudo_inst.cc: Changed some include paths to reflect that pseudo_inst.hh is now outside of the alpha directory. Also, instead of extracting their parameters directly, they're passed in as regular function arguments. sim/pseudo_inst.hh: Changed the function prototypes to include the functions parameters, now that they aren't extracted from the execution context. --HG-- rename : arch/alpha/pseudo_inst.cc => sim/pseudo_inst.cc rename : arch/alpha/pseudo_inst.hh => sim/pseudo_inst.hh extra : convert_revision : 76ce768cf1d8a838aa7b64878a7ab4c4215ac999 --- SConscript | 3 ++- arch/alpha/SConscript | 1 - arch/alpha/isa/decoder.isa | 14 +++++------ arch/alpha/isa/main.isa | 4 ++- {arch/alpha => sim}/pseudo_inst.cc | 40 ++++++++++-------------------- {arch/alpha => sim}/pseudo_inst.hh | 19 ++++++++------ 6 files changed, 37 insertions(+), 44 deletions(-) rename {arch/alpha => sim}/pseudo_inst.cc (84%) rename {arch/alpha => sim}/pseudo_inst.hh (77%) diff --git a/SConscript b/SConscript index 0206141fc..fc2e6ae0b 100644 --- a/SConscript +++ b/SConscript @@ -292,6 +292,7 @@ full_system_sources = Split(''' mem/functional/physical.cc sim/system.cc + sim/pseudo_inst.cc ''') # These are now included by the architecture specific SConscript @@ -347,10 +348,10 @@ targetarch_files = Split(''' ecoff_machdep.h ev5.hh faults.hh - pseudo_inst.hh stacktrace.hh vtophys.hh ''') +# pseudo_inst.hh # isa_traits.hh # osfpal.hh # byte_swap.hh diff --git a/arch/alpha/SConscript b/arch/alpha/SConscript index 2c98125bc..8bf408c06 100644 --- a/arch/alpha/SConscript +++ b/arch/alpha/SConscript @@ -244,7 +244,6 @@ arch_full_system_sources = Split(''' arch/alpha/arguments.cc arch/alpha/ev5.cc arch/alpha/osfpal.cc - arch/alpha/pseudo_inst.cc arch/alpha/stacktrace.cc arch/alpha/vtophys.cc ''') diff --git a/arch/alpha/isa/decoder.isa b/arch/alpha/isa/decoder.isa index 29124f191..aff8571e9 100644 --- a/arch/alpha/isa/decoder.isa +++ b/arch/alpha/isa/decoder.isa @@ -768,23 +768,23 @@ decode OPCODE default Unknown::unknown() { AlphaPseudo::m5exit_old(xc->xcBase()); }}, No_OpClass, IsNonSpeculative); 0x21: m5exit({{ - AlphaPseudo::m5exit(xc->xcBase()); + AlphaPseudo::m5exit(xc->xcBase(), R16); }}, No_OpClass, IsNonSpeculative); 0x30: initparam({{ Ra = xc->xcBase()->cpu->system->init_param; }}); 0x40: resetstats({{ - AlphaPseudo::resetstats(xc->xcBase()); + AlphaPseudo::resetstats(xc->xcBase(), R16, R17); }}, IsNonSpeculative); 0x41: dumpstats({{ - AlphaPseudo::dumpstats(xc->xcBase()); + AlphaPseudo::dumpstats(xc->xcBase(), R16, R17); }}, IsNonSpeculative); 0x42: dumpresetstats({{ - AlphaPseudo::dumpresetstats(xc->xcBase()); + AlphaPseudo::dumpresetstats(xc->xcBase(), R16, R17); }}, IsNonSpeculative); 0x43: m5checkpoint({{ - AlphaPseudo::m5checkpoint(xc->xcBase()); + AlphaPseudo::m5checkpoint(xc->xcBase(), R16, R17); }}, IsNonSpeculative); 0x50: m5readfile({{ - AlphaPseudo::readfile(xc->xcBase()); + R0 = AlphaPseudo::readfile(xc->xcBase(), R16, R17, R18); }}, IsNonSpeculative); 0x51: m5break({{ AlphaPseudo::debugbreak(xc->xcBase()); @@ -793,7 +793,7 @@ decode OPCODE default Unknown::unknown() { AlphaPseudo::switchcpu(xc->xcBase()); }}, IsNonSpeculative); 0x53: m5addsymbol({{ - AlphaPseudo::addsymbol(xc->xcBase()); + AlphaPseudo::addsymbol(xc->xcBase(), R16, R17); }}, IsNonSpeculative); } diff --git a/arch/alpha/isa/main.isa b/arch/alpha/isa/main.isa index c082df8c8..a2860f17b 100644 --- a/arch/alpha/isa/main.isa +++ b/arch/alpha/isa/main.isa @@ -160,7 +160,9 @@ def operands {{ 'FPCR': (' ControlReg', 'uq', 'Fpcr', None, 1), # The next two are hacks for non-full-system call-pal emulation 'R0': ('IntReg', 'uq', '0', None, 1), - 'R16': ('IntReg', 'uq', '16', None, 1) + 'R16': ('IntReg', 'uq', '16', None, 1), + 'R17': ('IntReg', 'uq', '17', None, 1), + 'R18': ('IntReg', 'uq', '18', None, 1) }}; //////////////////////////////////////////////////////////////////// diff --git a/arch/alpha/pseudo_inst.cc b/sim/pseudo_inst.cc similarity index 84% rename from arch/alpha/pseudo_inst.cc rename to sim/pseudo_inst.cc index d6f622ba2..11ab55f53 100644 --- a/arch/alpha/pseudo_inst.cc +++ b/sim/pseudo_inst.cc @@ -33,8 +33,8 @@ #include -#include "arch/alpha/pseudo_inst.hh" -#include "arch/alpha/vtophys.hh" +#include "sim/pseudo_inst.hh" +#include "targetarch/vtophys.hh" #include "cpu/base.hh" #include "cpu/sampler/sampler.hh" #include "cpu/exec_context.hh" @@ -94,21 +94,18 @@ namespace AlphaPseudo } void - m5exit(ExecContext *xc) + m5exit(ExecContext *xc, Tick delay) { - Tick delay = xc->regs.intRegFile[16]; Tick when = curTick + delay * Clock::Int::ns; SimExit(when, "m5_exit instruction encountered"); } void - resetstats(ExecContext *xc) + resetstats(ExecContext *xc, Tick delay, Tick period) { if (!doStatisticsInsts) return; - Tick delay = xc->regs.intRegFile[16]; - Tick period = xc->regs.intRegFile[17]; Tick when = curTick + delay * Clock::Int::ns; Tick repeat = period * Clock::Int::ns; @@ -118,13 +115,11 @@ namespace AlphaPseudo } void - dumpstats(ExecContext *xc) + dumpstats(ExecContext *xc, Tick delay, Tick period) { if (!doStatisticsInsts) return; - Tick delay = xc->regs.intRegFile[16]; - Tick period = xc->regs.intRegFile[17]; Tick when = curTick + delay * Clock::Int::ns; Tick repeat = period * Clock::Int::ns; @@ -134,11 +129,10 @@ namespace AlphaPseudo } void - addsymbol(ExecContext *xc) + addsymbol(ExecContext *xc, Addr addr, Addr symbolAddr) { - Addr addr = xc->regs.intRegFile[16]; char symb[100]; - CopyString(xc, symb, xc->regs.intRegFile[17], 100); + CopyString(xc, symb, symbolAddr, 100); std::string symbol(symb); DPRINTF(Loader, "Loaded symbol: %s @ %#llx\n", symbol, addr); @@ -147,13 +141,11 @@ namespace AlphaPseudo } void - dumpresetstats(ExecContext *xc) + dumpresetstats(ExecContext *xc, Tick delay, Tick period) { if (!doStatisticsInsts) return; - Tick delay = xc->regs.intRegFile[16]; - Tick period = xc->regs.intRegFile[17]; Tick when = curTick + delay * Clock::Int::ns; Tick repeat = period * Clock::Int::ns; @@ -163,13 +155,11 @@ namespace AlphaPseudo } void - m5checkpoint(ExecContext *xc) + m5checkpoint(ExecContext *xc, Tick delay, Tick period) { if (!doCheckpointInsts) return; - Tick delay = xc->regs.intRegFile[16]; - Tick period = xc->regs.intRegFile[17]; Tick when = curTick + delay * Clock::Int::ns; Tick repeat = period * Clock::Int::ns; @@ -177,18 +167,14 @@ namespace AlphaPseudo Checkpoint::setup(when, repeat); } - void - readfile(ExecContext *xc) + uint64_t + readfile(ExecContext *xc, Addr vaddr, uint64_t len, uint64_t offset) { const string &file = xc->cpu->system->params->readfile; if (file.empty()) { - xc->regs.intRegFile[0] = ULL(0); - return; + return ULL(0); } - Addr vaddr = xc->regs.intRegFile[16]; - uint64_t len = xc->regs.intRegFile[17]; - uint64_t offset = xc->regs.intRegFile[18]; uint64_t result = 0; int fd = ::open(file.c_str(), O_RDONLY, 0); @@ -213,7 +199,7 @@ namespace AlphaPseudo close(fd); CopyIn(xc, vaddr, buf, result); delete [] buf; - xc->regs.intRegFile[0] = result; + return result; } class Context : public ParamContext diff --git a/arch/alpha/pseudo_inst.hh b/sim/pseudo_inst.hh similarity index 77% rename from arch/alpha/pseudo_inst.hh rename to sim/pseudo_inst.hh index 0e7462a56..3857f2050 100644 --- a/arch/alpha/pseudo_inst.hh +++ b/sim/pseudo_inst.hh @@ -28,6 +28,11 @@ class ExecContext; +//We need the "Tick" data type from here +#include "sim/host.hh" +//We need the "Addr" data type from here +#include "arch/isa_traits.hh" + namespace AlphaPseudo { /** @@ -41,14 +46,14 @@ namespace AlphaPseudo void quiesce(ExecContext *xc); void ivlb(ExecContext *xc); void ivle(ExecContext *xc); - void m5exit(ExecContext *xc); + void m5exit(ExecContext *xc, Tick delay); void m5exit_old(ExecContext *xc); - void resetstats(ExecContext *xc); - void dumpstats(ExecContext *xc); - void dumpresetstats(ExecContext *xc); - void m5checkpoint(ExecContext *xc); - void readfile(ExecContext *xc); + void resetstats(ExecContext *xc, Tick delay, Tick period); + void dumpstats(ExecContext *xc, Tick delay, Tick period); + void dumpresetstats(ExecContext *xc, Tick delay, Tick period); + void m5checkpoint(ExecContext *xc, Tick delay, Tick period); + uint64_t readfile(ExecContext *xc, Addr vaddr, uint64_t len, uint64_t offset); void debugbreak(ExecContext *xc); void switchcpu(ExecContext *xc); - void addsymbol(ExecContext *xc); + void addsymbol(ExecContext *xc, Addr addr, Addr symbolAddr); } From d7ac2b56c2fdc4a8a5f96ee725f11f37c4432f14 Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Tue, 14 Feb 2006 02:03:14 -0500 Subject: [PATCH 045/180] make MIPS MT instructions decodable ... arch/mips/isa/bitfields.isa: extra bitfield for decoding --HG-- extra : convert_revision : 27f0afc3ee6ce00a94f44b2b1ac160ec26030866 --- arch/mips/isa/bitfields.isa | 1 + arch/mips/isa/decoder.isa | 82 +++++++++++++++++++++++++++++++------ 2 files changed, 70 insertions(+), 13 deletions(-) diff --git a/arch/mips/isa/bitfields.isa b/arch/mips/isa/bitfields.isa index 94a8a6467..bead9c151 100644 --- a/arch/mips/isa/bitfields.isa +++ b/arch/mips/isa/bitfields.isa @@ -15,6 +15,7 @@ def bitfield RT_HI <20:19>; def bitfield RT_LO <18:16>; def bitfield RS <25:21>; +def bitfield RS_MSB <25:25>; def bitfield RS_HI <25:24>; def bitfield RS_LO <23:21>; diff --git a/arch/mips/isa/decoder.isa b/arch/mips/isa/decoder.isa index d6fd90657..2ec7da805 100644 --- a/arch/mips/isa/decoder.isa +++ b/arch/mips/isa/decoder.isa @@ -229,7 +229,7 @@ decode OPCODE_HI default FailUnimpl::unknown() { Rt = xc->miscRegs.cop0[reg_num]; }}); - 0xC: mtc0({{ + 0x4: mtc0({{ //The contents of the coprocessor 0 register specified by the //combination of rd and sel are loaded into general register //rt. Note that not all coprocessor 0 registers support the @@ -243,6 +243,25 @@ decode OPCODE_HI default FailUnimpl::unknown() { xc->miscRegs.cop0[reg_num] = Rt; }}); + 0x8: mftr({{ + //The contents of the coprocessor 0 register specified by the + //combination of rd and sel are loaded into general register + //rt. Note that not all coprocessor 0 registers support the + //sel field. In those instances, the sel field must be zero. + + //MT Code Needed Here + }}); + + 0xC: mttr({{ + //The contents of the coprocessor 0 register specified by the + //combination of rd and sel are loaded into general register + //rt. Note that not all coprocessor 0 registers support the + //sel field. In those instances, the sel field must be zero. + + //MT Code Needed Here + }}); + + 0xA: rdpgpr({{ //Accessing Previous Shadow Set Register Number uint64_t prev = xc->miscRegs.cop0[SRSCtl][PSS]; @@ -252,23 +271,52 @@ decode OPCODE_HI default FailUnimpl::unknown() { }}); } - 0xB: decode SC { - format BasicOp { - 0x0: di({{ - //Accessing Coprocessor 0 "Status" Register - Rt.sw = xc->miscRegs.cop0[12]; - xc->miscRegs.cop0[12][INTERRUPT_ENABLE] = 0; + 0xB: decode RD { + + 0x0: decode SC { + format BasicOp { + 0x0: dvpe({{ + Rt.sw = xc->miscRegs.cop0.MVPControl; + xc->miscRegs.cop0.MVPControl[EVP] = 0; }}); - 0x1: ei({{ - //Accessing Coprocessor 0 "Status" Register - Rt.sw = xc->miscRegs.cop0[12]; - xc->miscRegs.cop0[12][INTERRUPT_ENABLE] = 1; + 0x1: evpe({{ + Rt.sw = xc->miscRegs.cop0.MVPControl; + xc->miscRegs.cop0.MVPControl[EVP] = 1; }}); + } + } + + 0x1: decode SC { + format BasicOp { + 0x0: dmt({{ + Rt.sw = xc->miscRegs.cop0.VPEControl; + xc->miscRegs.cop0.VPEControl[THREAD_ENABLE] = 0; + }}); + + 0x1: emt({{ + Rt.sw = xc->miscRegs.cop0.VPEControl; + xc->miscRegs.cop0.VPEControl[THREAD_ENABLE] = 1; + }}); + } + } + + 0xC: decode SC { + format BasicOp { + 0x0: di({{ + Rt.sw = xc->miscRegs.cop0.Status; + xc->miscRegs.cop0.Status[INTERRUPT_ENABLE] = 0; + }}); + + 0x1: ei({{ + Rt.sw = xc->miscRegs.cop0.Status; + xc->miscRegs.cop0.Status[INTERRUPT_ENABLE] = 1; + }}); + } + } } - } - 0xE: BasicOp::wrpgpr({{ + 0xE: BasicOp::wrpgpr({{ //Accessing Previous Shadow Set Register Number uint64_t prev = xc->miscRegs.cop0[SRSCtl][PSS]; uint64_t reg_num = Rd.uw; @@ -772,6 +820,14 @@ decode OPCODE_HI default FailUnimpl::unknown() { } } + 0x1: decode FUNCTION_LO { + format WarnUnimpl { + 0x0: fork({{ }}); + 0x1: yield({{ }}); + } + } + + //Table A-10 MIPS32 BSHFL Encoding of sa Field 0x4: decode SA { From 085b73fe445f75504ca042135495dfede1d55d45 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 14 Feb 2006 03:57:42 -0500 Subject: [PATCH 046/180] Fixed a path in the alpha isa description. --HG-- extra : convert_revision : 2a73ef7703ffe5c5232619698a16c8b4ee265a21 --- arch/alpha/isa/main.isa | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/alpha/isa/main.isa b/arch/alpha/isa/main.isa index a2860f17b..ef4d83ce2 100644 --- a/arch/alpha/isa/main.isa +++ b/arch/alpha/isa/main.isa @@ -50,7 +50,7 @@ output exec {{ #include #if FULL_SYSTEM -#include "arch/alpha/pseudo_inst.hh" +#include "sim/pseudo_inst.hh" #endif #include "base/fenv.hh" #include "config/ss_compatible_fp.hh" From 7826fcd09dfb265adae82f99d09944fe67f0fb5a Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 14 Feb 2006 20:13:08 -0500 Subject: [PATCH 047/180] New files to fix building the SPARC_SE and MIPS_SE isa_parser.py generated files. --HG-- extra : convert_revision : 94a9543376f8b4709a4aef54c5ac0d6f582a9dad --- arch/mips/SConscript | 81 ++++++++++++++++++++++++++++ arch/sparc/SConscript | 82 +++++++++++++++++++++++++++++ build/build_options/default/MIPS_SE | 2 + 3 files changed, 165 insertions(+) create mode 100644 arch/mips/SConscript create mode 100644 arch/sparc/SConscript create mode 100644 build/build_options/default/MIPS_SE diff --git a/arch/mips/SConscript b/arch/mips/SConscript new file mode 100644 index 000000000..bd67c98e9 --- /dev/null +++ b/arch/mips/SConscript @@ -0,0 +1,81 @@ +# -*- mode:python -*- + +# Copyright (c) 2004-2005 The Regents of The University of Michigan +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import os +import sys +from os.path import isdir + +# Import build environment variable from SConstruct. +Import('env') + +################################################### +# +# Define needed sources. +# +################################################### + +# Base sources used by all configurations. +arch_base_sources = Split(''' + arch/mips/decoder.cc + arch/mips/alpha_o3_exec.cc + arch/mips/fast_cpu_exec.cc + arch/mips/simple_cpu_exec.cc + arch/mips/full_cpu_exec.cc + arch/mips/faults.cc + arch/mips/isa_traits.cc + ''') + +# Full-system sources +arch_full_system_sources = Split(''' + arch/mips/alpha_memory.cc + arch/mips/arguments.cc + arch/mips/ev5.cc + arch/mips/osfpal.cc + arch/mips/stacktrace.cc + arch/mips/vtophys.cc + ''') + +# Syscall emulation (non-full-system) sources +arch_syscall_emulation_sources = Split(''' + arch/mips/alpha_common_syscall_emul.cc + arch/mips/alpha_linux_process.cc + arch/mips/alpha_tru64_process.cc + ''') + +# Set up complete list of sources based on configuration. +sources = arch_base_sources + +if env['FULL_SYSTEM']: + sources += arch_full_system_sources +else: + sources += arch_syscall_emulation_sources + +for opt in env.ExportOptions: + env.ConfigFile(opt) + +Return('sources') diff --git a/arch/sparc/SConscript b/arch/sparc/SConscript new file mode 100644 index 000000000..d8a3749a1 --- /dev/null +++ b/arch/sparc/SConscript @@ -0,0 +1,82 @@ +# -*- mode:python -*- + +# Copyright (c) 2004-2005 The Regents of The University of Michigan +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import os +import sys +from os.path import isdir + +# Import build environment variable from SConstruct. +Import('env') + +################################################### +# +# Define needed sources. +# +################################################### + +# Base sources used by all configurations. +arch_base_sources = Split(''' + arch/sparc/decoder.cc + arch/sparc/alpha_o3_exec.cc + arch/sparc/fast_cpu_exec.cc + arch/sparc/simple_cpu_exec.cc + arch/sparc/full_cpu_exec.cc + arch/sparc/faults.cc + arch/sparc/isa_traits.cc + ''') + +# Full-system sources +arch_full_system_sources = Split(''' + arch/sparc/alpha_memory.cc + arch/sparc/arguments.cc + arch/sparc/ev5.cc + arch/sparc/osfpal.cc + arch/sparc/stacktrace.cc + arch/sparc/vtophys.cc + ''') + +# Syscall emulation (non-full-system) sources +arch_syscall_emulation_sources = Split(''' + arch/sparc/alpha_common_syscall_emul.cc + arch/sparc/alpha_linux_process.cc + arch/sparc/alpha_tru64_process.cc + ''') + +sources = arch_base_sources + +if env['FULL_SYSTEM']: + sources += arch_full_system_sources + if env['ALPHA_TLASER']: + sources += arch_turbolaser_sources +else: + sources += arch_syscall_emulation_sources + +for opt in env.ExportOptions: + env.ConfigFile(opt) + +Return('sources') diff --git a/build/build_options/default/MIPS_SE b/build/build_options/default/MIPS_SE new file mode 100644 index 000000000..e74e2f69c --- /dev/null +++ b/build/build_options/default/MIPS_SE @@ -0,0 +1,2 @@ +TARGET_ISA = 'mips' +FULL_SYSTEM = 0 From 5830200d78afa4d50f672b67fc7db80c78e3a2ad Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Tue, 14 Feb 2006 21:26:01 -0500 Subject: [PATCH 048/180] trying to get ISA to parse correctly ... arch/mips/isa/formats/unimp.isa: holds unimplemented formats arch/mips/isa/formats/unknown.isa: holds unknown formats --HG-- extra : convert_revision : 0f3a8ea7e3a1592322cce54527d6989152e57975 --- arch/mips/isa/decoder.isa | 13 +- arch/mips/isa/formats.isa | 21 ++- arch/mips/isa/formats/basic.isa | 2 +- arch/mips/isa/formats/branch.isa | 273 +++++++++++++++++++++++++----- arch/mips/isa/formats/int.isa | 4 +- arch/mips/isa/formats/unimp.isa | 165 ++++++++++++++++++ arch/mips/isa/formats/unknown.isa | 52 ++++++ arch/mips/isa/main.isa | 12 +- 8 files changed, 480 insertions(+), 62 deletions(-) create mode 100644 arch/mips/isa/formats/unimp.isa create mode 100644 arch/mips/isa/formats/unknown.isa diff --git a/arch/mips/isa/decoder.isa b/arch/mips/isa/decoder.isa index 2ec7da805..7e7dfe1d1 100644 --- a/arch/mips/isa/decoder.isa +++ b/arch/mips/isa/decoder.isa @@ -9,7 +9,7 @@ // //@todo: Distinguish "unknown/future" use insts from "reserved" // ones -decode OPCODE_HI default FailUnimpl::unknown() { +decode OPCODE_HI default Unknown::unknown() { // Derived From ... Table A-2 MIPS32 ISA Manual 0x0: decode OPCODE_LO default FailUnimpl::reserved(){ @@ -66,10 +66,11 @@ decode OPCODE_HI default FailUnimpl::unknown() { 0x3: movn({{ if (Rt != 0) Rd = Rs; }}); } + format WarnUnimpl { - 0x4: syscall({{ xc->syscall()}},IsNonSpeculative); - 0x5: break({{ }}); - 0x7: sync({{ }}); + 0x4: syscall();//{{ xc->syscall()}},IsNonSpeculative + 0x5: break(); + 0x7: sync(); } } @@ -80,14 +81,14 @@ decode OPCODE_HI default FailUnimpl::unknown() { 0x2: mflo({{ Rd = xc->miscRegs.lo; }}); 0x3: mtlo({{ xc->miscRegs.lo = Rs; }}); } - }; + } 0x3: decode FUNCTION_LO { format IntOp { 0x0: mult({{ INT64 temp1 = Rs.sw * Rt.sw; xc->miscRegs.hi->temp1<63:32>; - xc->miscRegs.lo->temp1<31:0> + xc->miscRegs.lo->temp1<31:0>; }}); 0x1: multu({{ diff --git a/arch/mips/isa/formats.isa b/arch/mips/isa/formats.isa index 404314c7a..20ef49d82 100644 --- a/arch/mips/isa/formats.isa +++ b/arch/mips/isa/formats.isa @@ -1,22 +1,29 @@ //Include the basic format //Templates from this format are used later -##include "m5/arch/mips/isa_desc/formats/basic.format" +##include "m5/arch/mips/isa/formats/basic.isa" //Include the integerOp and integerOpCc format -##include "m5/arch/mips/isa_desc/formats/integerop.format" +##include "m5/arch/mips/isa/formats/int.isa" //Include the floatOp format -##include "m5/arch/mips/isa_desc/formats/floatop.format" +##include "m5/arch/mips/isa/formats/fp.isa" //Include the mem format -##include "m5/arch/mips/isa_desc/formats/mem.format" +##include "m5/arch/mips/isa/formats/mem.isa" //Include the trap format -##include "m5/arch/mips/isa_desc/formats/trap.format" +##include "m5/arch/mips/isa/formats/trap.isa" //Include the branch format -##include "m5/arch/mips/isa_desc/formats/branch.format" +##include "m5/arch/mips/isa/formats/branch.isa" //Include the noop format -##include "m5/arch/mips/isa_desc/formats/noop.format" +##include "m5/arch/mips/isa/formats/noop.isa" + + +//Include the noop format +##include "m5/arch/mips/isa/formats/unimp.isa" + +//Include the noop format +##include "m5/arch/mips/isa/formats/unknown.isa" diff --git a/arch/mips/isa/formats/basic.isa b/arch/mips/isa/formats/basic.isa index 8fba9845a..fc97c6ffa 100644 --- a/arch/mips/isa/formats/basic.isa +++ b/arch/mips/isa/formats/basic.isa @@ -56,7 +56,7 @@ def template BasicDecodeWithMnemonic {{ }}; // The most basic instruction format... used only for a few misc. insts -def format BasicOperate(code, *flags) {{ +def format BasicOp(code, *flags) {{ iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags) header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) diff --git a/arch/mips/isa/formats/branch.isa b/arch/mips/isa/formats/branch.isa index a565eb71b..e9c790c53 100644 --- a/arch/mips/isa/formats/branch.isa +++ b/arch/mips/isa/formats/branch.isa @@ -1,57 +1,212 @@ -//////////////////////////////////////////////////////////////////// +// -*- mode:c++ -*- + +// Copyright (c) 2003-2005 The Regents of The University of Michigan +// All rights reserved. // -// Branch instructions +// 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. output header {{ - /** - * Base class for integer operations. - */ - class Branch : public MipsStaticInst + + /** + * Base class for instructions whose disassembly is not purely a + * function of the machine instruction (i.e., it depends on the + * PC). This class overrides the disassemble() method to check + * the PC and symbol table values before re-using a cached + * disassembly string. This is necessary for branches and jumps, + * where the disassembly string includes the target address (which + * may depend on the PC and/or symbol table). + */ + class PCDependentDisassembly : public AlphaStaticInst + { + protected: + /// Cached program counter from last disassembly + mutable Addr cachedPC; + /// Cached symbol table pointer from last disassembly + mutable const SymbolTable *cachedSymtab; + + /// Constructor + PCDependentDisassembly(const char *mnem, MachInst _machInst, + OpClass __opClass) + : AlphaStaticInst(mnem, _machInst, __opClass), + cachedPC(0), cachedSymtab(0) { - protected: + } - /// Constructor - Branch(const char *mnem, MachInst _machInst, OpClass __opClass) : MipsStaticInst(mnem, _machInst, __opClass) - { - } + const std::string & + disassemble(Addr pc, const SymbolTable *symtab) const; + }; - std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; - }; + /** + * Base class for branches (PC-relative control transfers), + * conditional or unconditional. + */ + class Branch : public PCDependentDisassembly + { + protected: + /// Displacement to target address (signed). + int32_t disp; + + /// Constructor. + Branch(const char *mnem, MachInst _machInst, OpClass __opClass) + : PCDependentDisassembly(mnem, _machInst, __opClass), + disp(BRDISP << 2) + { + } + + Addr branchTarget(Addr branchPC) const; + + std::string + generateDisassembly(Addr pc, const SymbolTable *symtab) const; + }; + + /** + * Base class for jumps (register-indirect control transfers). In + * the Alpha ISA, these are always unconditional. + */ + class Jump : public PCDependentDisassembly + { + protected: + + /// Displacement to target address (signed). + int32_t disp; + + public: + /// Constructor + Jump(const char *mnem, MachInst _machInst, OpClass __opClass) + : PCDependentDisassembly(mnem, _machInst, __opClass), + disp(BRDISP) + { + } + + Addr branchTarget(ExecContext *xc) const; + + std::string + generateDisassembly(Addr pc, const SymbolTable *symtab) const; + }; }}; output decoder {{ - std::string Branch::generateDisassembly(Addr pc, const SymbolTable *symtab) const + Addr + Branch::branchTarget(Addr branchPC) const + { + return branchPC + 4 + disp; + } + + Addr + Jump::branchTarget(ExecContext *xc) const + { + Addr NPC = xc->readPC() + 4; + uint64_t Rb = xc->readIntReg(_srcRegIdx[0]); + return (Rb & ~3) | (NPC & 1); + } + + const std::string & + PCDependentDisassembly::disassemble(Addr pc, + const SymbolTable *symtab) const + { + if (!cachedDisassembly || + pc != cachedPC || symtab != cachedSymtab) { - return "Disassembly of integer instruction\n"; + if (cachedDisassembly) + delete cachedDisassembly; + + cachedDisassembly = + new std::string(generateDisassembly(pc, symtab)); + cachedPC = pc; + cachedSymtab = symtab; } + + return *cachedDisassembly; + } + + std::string + Branch::generateDisassembly(Addr pc, const SymbolTable *symtab) const + { + std::stringstream ss; + + ccprintf(ss, "%-10s ", mnemonic); + + // There's only one register arg (RA), but it could be + // either a source (the condition for conditional + // branches) or a destination (the link reg for + // unconditional branches) + if (_numSrcRegs > 0) { + printReg(ss, _srcRegIdx[0]); + ss << ","; + } + else if (_numDestRegs > 0) { + printReg(ss, _destRegIdx[0]); + ss << ","; + } + +#ifdef SS_COMPATIBLE_DISASSEMBLY + if (_numSrcRegs == 0 && _numDestRegs == 0) { + printReg(ss, 31); + ss << ","; + } +#endif + + Addr target = pc + 4 + disp; + + std::string str; + if (symtab && symtab->findSymbol(target, str)) + ss << str; + else + ccprintf(ss, "0x%x", target); + + return ss.str(); + } + + std::string + Jump::generateDisassembly(Addr pc, const SymbolTable *symtab) const + { + std::stringstream ss; + + ccprintf(ss, "%-10s ", mnemonic); + +#ifdef SS_COMPATIBLE_DISASSEMBLY + if (_numDestRegs == 0) { + printReg(ss, 31); + ss << ","; + } +#endif + + if (_numDestRegs > 0) { + printReg(ss, _destRegIdx[0]); + ss << ","; + } + + ccprintf(ss, "(r%d)", RB); + + return ss.str(); + } }}; -def template BranchExecute {{ - Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const - { - //Attempt to execute the instruction - try - { - checkPriv; - - %(op_decl)s; - %(op_rd)s; - %(code)s; - } - //If we have an exception for some reason, - //deal with it - catch(MipsException except) - { - //Deal with exception - return No_Fault; - } - - //Write the resulting state to the execution context - %(op_wb)s; - - return No_Fault; - } +def template JumpOrBranchDecode {{ + return (RA == 31) + ? (StaticInst *)new %(class_name)s(machInst) + : (StaticInst *)new %(class_name)sAndLink(machInst); }}; def format CondBranch(code) {{ @@ -64,3 +219,41 @@ def format CondBranch(code) {{ exec_output = BasicExecute.subst(iop) }}; +let {{ +def UncondCtrlBase(name, Name, base_class, npc_expr, flags): + # Declare basic control transfer w/o link (i.e. link reg is R31) + nolink_code = 'NPC = %s;\n' % npc_expr + nolink_iop = InstObjParams(name, Name, base_class, + CodeBlock(nolink_code), flags) + header_output = BasicDeclare.subst(nolink_iop) + decoder_output = BasicConstructor.subst(nolink_iop) + exec_output = BasicExecute.subst(nolink_iop) + + # Generate declaration of '*AndLink' version, append to decls + link_code = 'Ra = NPC & ~3;\n' + nolink_code + link_iop = InstObjParams(name, Name + 'AndLink', base_class, + CodeBlock(link_code), flags) + header_output += BasicDeclare.subst(link_iop) + decoder_output += BasicConstructor.subst(link_iop) + exec_output += BasicExecute.subst(link_iop) + + # need to use link_iop for the decode template since it is expecting + # the shorter version of class_name (w/o "AndLink") + + return (header_output, decoder_output, + JumpOrBranchDecode.subst(nolink_iop), exec_output) +}}; + +def format UncondBranch(*flags) {{ + flags += ('IsUncondControl', 'IsDirectControl') + (header_output, decoder_output, decode_block, exec_output) = \ + UncondCtrlBase(name, Name, 'Branch', 'NPC + disp', flags) +}}; + +def format Jump(*flags) {{ + flags += ('IsUncondControl', 'IsIndirectControl') + (header_output, decoder_output, decode_block, exec_output) = \ + UncondCtrlBase(name, Name, 'Jump', '(Rb & ~3) | (NPC & 1)', flags) +}}; + + diff --git a/arch/mips/isa/formats/int.isa b/arch/mips/isa/formats/int.isa index 5b8df54e9..521f3a130 100644 --- a/arch/mips/isa/formats/int.isa +++ b/arch/mips/isa/formats/int.isa @@ -53,9 +53,9 @@ def format IntOp(code, *opt_flags) {{ orig_code = code cblk = CodeBlock(code) - //Figure out if we are creating a IntImmOp or a IntOp + # Figure out if we are creating a IntImmOp or a IntOp strlen = len(name) - if ( name[strlen-1] = 'i' or ( name[strlen-2:] = 'iu')) + if name[strlen-1] == 'i' or name[strlen-2:] == 'iu': iop = InstObjParams(name, Name, 'IntOp', cblk, opt_flags) else: iop = InstObjParams(name, Name, 'IntImmOp', cblk, opt_flags) diff --git a/arch/mips/isa/formats/unimp.isa b/arch/mips/isa/formats/unimp.isa new file mode 100644 index 000000000..767888157 --- /dev/null +++ b/arch/mips/isa/formats/unimp.isa @@ -0,0 +1,165 @@ +// -*- mode:c++ -*- + +// 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. + +output header {{ + /** + * Static instruction class for unimplemented instructions that + * cause simulator termination. Note that these are recognized + * (legal) instructions that the simulator does not support; the + * 'Unknown' class is used for unrecognized/illegal instructions. + * This is a leaf class. + */ + class FailUnimplemented : public AlphaStaticInst + { + public: + /// Constructor + FailUnimplemented(const char *_mnemonic, MachInst _machInst) + : AlphaStaticInst(_mnemonic, _machInst, No_OpClass) + { + // don't call execute() (which panics) if we're on a + // speculative path + flags[IsNonSpeculative] = true; + } + + %(BasicExecDeclare)s + + std::string + generateDisassembly(Addr pc, const SymbolTable *symtab) const; + }; + + /** + * Base class for unimplemented instructions that cause a warning + * to be printed (but do not terminate simulation). This + * implementation is a little screwy in that it will print a + * warning for each instance of a particular unimplemented machine + * instruction, not just for each unimplemented opcode. Should + * probably make the 'warned' flag a static member of the derived + * class. + */ + class WarnUnimplemented : public AlphaStaticInst + { + private: + /// Have we warned on this instruction yet? + mutable bool warned; + + public: + /// Constructor + WarnUnimplemented(const char *_mnemonic, MachInst _machInst) + : AlphaStaticInst(_mnemonic, _machInst, No_OpClass), warned(false) + { + // don't call execute() (which panics) if we're on a + // speculative path + flags[IsNonSpeculative] = true; + } + + %(BasicExecDeclare)s + + std::string + generateDisassembly(Addr pc, const SymbolTable *symtab) const; + }; +}}; + +output decoder {{ + std::string + FailUnimplemented::generateDisassembly(Addr pc, + const SymbolTable *symtab) const + { + return csprintf("%-10s (unimplemented)", mnemonic); + } + + std::string + WarnUnimplemented::generateDisassembly(Addr pc, + const SymbolTable *symtab) const + { +#ifdef SS_COMPATIBLE_DISASSEMBLY + return csprintf("%-10s", mnemonic); +#else + return csprintf("%-10s (unimplemented)", mnemonic); +#endif + } +}}; + +output exec {{ + Fault + FailUnimplemented::execute(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + panic("attempt to execute unimplemented instruction '%s' " + "(inst 0x%08x, opcode 0x%x)", mnemonic, machInst, OPCODE); + return Unimplemented_Opcode_Fault; + } + + Fault + WarnUnimplemented::execute(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + if (!warned) { + warn("instruction '%s' unimplemented\n", mnemonic); + warned = true; + } + + return No_Fault; + } +}}; + + +def format FailUnimpl() {{ + iop = InstObjParams(name, 'FailUnimplemented') + decode_block = BasicDecodeWithMnemonic.subst(iop) +}}; + +def format WarnUnimpl() {{ + iop = InstObjParams(name, 'WarnUnimplemented') + decode_block = BasicDecodeWithMnemonic.subst(iop) +}}; + +output header {{ + /** + * Static instruction class for unknown (illegal) instructions. + * These cause simulator termination if they are executed in a + * non-speculative mode. This is a leaf class. + */ + class Unknown : public AlphaStaticInst + { + public: + /// Constructor + Unknown(MachInst _machInst) + : AlphaStaticInst("unknown", _machInst, No_OpClass) + { + // don't call execute() (which panics) if we're on a + // speculative path + flags[IsNonSpeculative] = true; + } + + %(BasicExecDeclare)s + + std::string + generateDisassembly(Addr pc, const SymbolTable *symtab) const; + }; +}}; + diff --git a/arch/mips/isa/formats/unknown.isa b/arch/mips/isa/formats/unknown.isa new file mode 100644 index 000000000..6eba5b4f9 --- /dev/null +++ b/arch/mips/isa/formats/unknown.isa @@ -0,0 +1,52 @@ +// -*- mode:c++ -*- + +// 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. + +output decoder {{ + std::string + Unknown::generateDisassembly(Addr pc, const SymbolTable *symtab) const + { + return csprintf("%-10s (inst 0x%x, opcode 0x%x)", + "unknown", machInst, OPCODE); + } +}}; + +output exec {{ + Fault + Unknown::execute(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + panic("attempt to execute unknown instruction " + "(inst 0x%08x, opcode 0x%x)", machInst, OPCODE); + return Unimplemented_Opcode_Fault; + } +}}; + +def format Unknown() {{ + decode_block = 'return new Unknown(machInst);\n' +}}; + diff --git a/arch/mips/isa/main.isa b/arch/mips/isa/main.isa index a8c71872b..411e398b4 100644 --- a/arch/mips/isa/main.isa +++ b/arch/mips/isa/main.isa @@ -26,7 +26,7 @@ // (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 "m5/arch/sparc/isa_desc/includes.h" +##include "m5/arch/mips/isa/includes.isa" //////////////////////////////////////////////////////////////////// // @@ -37,16 +37,16 @@ namespace MipsISA; //Include the bitfield definitions -##include "m5/arch/mips/isa_desc/bitfields.h" +##include "m5/arch/mips/isa/bitfields.isa" //Include the operand_types and operand definitions -##include "m5/arch/mips/isa_desc/operands.h" +##include "m5/arch/mips/isa/operands.isa" //Include the base class for mips instructions, and some support code -##include "m5/arch/mips/isa_desc/base.h" +##include "m5/arch/mips/isa/base.isa" //Include the definitions for the instruction formats -##include "m5/arch/mips/isa_desc/formats.h" +##include "m5/arch/mips/isa/formats.isa" //Include the decoder definition -##include "m5/arch/mips/isa_desc/decoder.h" +##include "m5/arch/mips/isa/decoder.isa" From 23bbec6a3445b4382f8c6ff8ea49fd818f960330 Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Tue, 14 Feb 2006 22:43:14 -0500 Subject: [PATCH 049/180] another big step to a parsable ISA ... no errors after I used a symbolic link for arch/alpha/main.isa to test my files ... arch/mips/isa/operands.isa: use sd and ud instead of sdw and udw --HG-- extra : convert_revision : d66f3fd2c4a4d70e6015f0f1643c400cdfe73055 --- arch/mips/isa/decoder.isa | 166 +++++++++++++++++---------------- arch/mips/isa/formats/fp.isa | 27 +++++- arch/mips/isa/formats/mem.isa | 2 +- arch/mips/isa/formats/noop.isa | 87 +++++++++++++++++ arch/mips/isa/operands.isa | 6 +- 5 files changed, 200 insertions(+), 88 deletions(-) diff --git a/arch/mips/isa/decoder.isa b/arch/mips/isa/decoder.isa index 7e7dfe1d1..6bb5bf4d8 100644 --- a/arch/mips/isa/decoder.isa +++ b/arch/mips/isa/decoder.isa @@ -108,7 +108,7 @@ decode OPCODE_HI default Unknown::unknown() { xc->miscRegs.lo = Rs.uw / Rt.uw; }}); } - }; + } 0x4: decode FUNCTION_LO { format IntOp { @@ -128,7 +128,7 @@ decode OPCODE_HI default Unknown::unknown() { 0x2: slt({{ Rd.sw = ( Rs.sw < Rt.sw ) ? 1 : 0}}); 0x3: sltu({{ Rd.uw = ( Rs.uw < Rt.uw ) ? 1 : 0}}); } - }; + } 0x6: decode FUNCTION_LO { format Trap { @@ -144,13 +144,13 @@ decode OPCODE_HI default Unknown::unknown() { 0x1: decode REGIMM_HI { 0x0: decode REGIMM_LO { - format Branch { - 0x0: bltz({{ cond = (Rs.sq < 0); }}); - 0x1: bgez({{ cond = (Rs.sq >= 0); }}); + format CondBranch { + 0x0: bltz({{ cond = (Rs.sw < 0); }}); + 0x1: bgez({{ cond = (Rs.sw >= 0); }}); //MIPS obsolete instructions - 0x2: bltzl({{ cond = (Rs.sq < 0); }}); - 0x3: bgezl({{ cond = (Rs.sq >= 0); }}); + 0x2: bltzl({{ cond = (Rs.sw < 0); }}); + 0x3: bgezl({{ cond = (Rs.sw >= 0); }}); } } @@ -166,19 +166,19 @@ decode OPCODE_HI default Unknown::unknown() { } 0x2: decode REGIMM_LO { - format Branch { - 0x0: bltzal({{ cond = (Rs.sq < 0); }}); - 0x1: bgezal({{ cond = (Rs.sq >= 0); }}); + format CondBranch { + 0x0: bltzal({{ cond = (Rs.sw < 0); }}); + 0x1: bgezal({{ cond = (Rs.sw >= 0); }}); //MIPS obsolete instructions - 0x2: bltzall({{ cond = (Rs.sq < 0); }}); - 0x3: bgezall({{ cond = (Rs.sq >= 0); }}); + 0x2: bltzall({{ cond = (Rs.sw < 0); }}); + 0x3: bgezall({{ cond = (Rs.sw >= 0); }}); } } 0x3: decode REGIMM_LO { format WarnUnimpl { - 0x7: synci({{ }}); + 0x7: synci(); } } } @@ -188,13 +188,13 @@ decode OPCODE_HI default Unknown::unknown() { 0x3: jal(IsCall); } - format Branch { - 0x4: beq({{ cond = (Rs.sq == 0); }}); - 0x5: bne({{ cond = (Rs.sq != 0); }}); - 0x6: blez({{ cond = (Rs.sq <= 0); }}); - 0x7: bgtz({{ cond = (Rs.sq > 0); }}); + format CondBranch { + 0x4: beq({{ cond = (Rs.sw == 0); }}); + 0x5: bne({{ cond = (Rs.sw != 0); }}); + 0x6: blez({{ cond = (Rs.sw <= 0); }}); + 0x7: bgtz({{ cond = (Rs.sw > 0); }}); } - }; + } 0x1: decode OPCODE_LO default FailUnimpl::reserved(){ format IntOp { @@ -206,8 +206,8 @@ decode OPCODE_HI default Unknown::unknown() { 0x5: ori({{ Rt.sw = Rs.sw | INTIMM;}}); 0x6: xori({{ Rt.sw = Rs.sw ^ INTIMM;}}); 0x7: lui({{ Rt = INTIMM << 16}}); - }; - }; + } + } 0x2: decode OPCODE_LO default FailUnimpl::reserved(){ @@ -336,9 +336,9 @@ decode OPCODE_HI default Unknown::unknown() { } format WarnUnimpl { - 0x18: eret({{ }}); - 0x1F: deret({{ }}); - 0x20: wait({{ }}); + 0x18: eret(); + 0x1F: deret(); + 0x20: wait(); } } } @@ -360,14 +360,14 @@ decode OPCODE_HI default Unknown::unknown() { 0x1: decode ND { 0x0: decode TF { - format Branch { + format CondBranch { 0x0: bc1f({{ cond = (xc->miscRegs.fpcr == 0); }}); 0x1: bc1t({{ cond = (xc->miscRegs.fpcr == 1); }}); } } 0x1: decode TF { - format Branch { + format CondBranch { 0x0: bc1fl({{ cond = (xc->miscRegs.fpcr == 0); }}); 0x1: bc1tl({{ cond = (xc->miscRegs.fpcr == 1); }}); } @@ -395,7 +395,7 @@ decode OPCODE_HI default Unknown::unknown() { } 0x1: decode RS_LO { - //only legal for 64 bit + //only legal for 64 bit-FP 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);}}); @@ -426,18 +426,21 @@ decode OPCODE_HI default Unknown::unknown() { format Float64Op { 0x2: recips({{ Fd = 1 / Fs; }}); - 0x3: rsqrts{{ Fd = 1 / sqrt(Fs); }}); + 0x3: rsqrts({{ Fd = 1 / sqrt(Fs.ud);}}); } } 0x4: decode RS_LO { - 0x1: cvt_d_s({{ int rnd_mode = xc->miscRegs.fcsr; + + format FloatOp { + 0x1: cvt_d_s({{ int rnd_mode = xc->miscRegs.fcsr; Fd = convert_and_round(Fs.sf,rnd_mode,FP_DOUBLE,FP_SINGLE); }}); - 0x4: cvt_w_s({{ int rnd_mode = xc->miscRegs.fcsr; + 0x4: cvt_w_s({{ int rnd_mode = xc->miscRegs.fcsr; Fd = convert_and_round(Fs.sf,rnd_mode,FP_WORD,FP_SINGLE); }}); + } //only legal for 64 bit format Float64Op { @@ -467,7 +470,7 @@ decode OPCODE_HI default Unknown::unknown() { 0x1: decode RS_LO { //only legal for 64 bit - format FloatOp64 { + 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);}}); @@ -495,9 +498,9 @@ decode OPCODE_HI default Unknown::unknown() { 0x3: movn({{ if (Rt != 0) Fd.df = Fs.df; }}); } - format FloatOp64 { + format Float64Op { 0x5: recipd({{ Fd.df = 1 / Fs.df}}); - 0x6: rsqrtd{{ Fd.df = 1 / sqrt(Fs.df) }}); + 0x6: rsqrtd({{ Fd.df = 1 / sqrt(Fs.df) }}); } } @@ -515,7 +518,7 @@ decode OPCODE_HI default Unknown::unknown() { } //only legal for 64 bit - format FloatOp64 { + format Float64Op { 0x5: cvt_l_d({{ int rnd_mode = xc->miscRegs.fcsr; Fd = convert_and_round(Fs.df,rnd_mode,FP_LONG,FP_DOUBLE); @@ -561,7 +564,7 @@ decode OPCODE_HI default Unknown::unknown() { //are enabled. " 0x6: decode RS_HI { 0x0: decode RS_LO { - format FloatOp64 { + format Float64Op { 0x0: addps({{ //Must Check for Exception Here... Supposed to Operate on Upper and //Lower Halves Independently but we take simulator shortcut Fd.df = Fs.df + Ft.df; @@ -596,23 +599,23 @@ decode OPCODE_HI default Unknown::unknown() { 0x2: decode RS_LO { 0x1: decode MOVCF { - format FloatOp64 { - 0x0: movfps({{ if ( FPConditionCode(CC) == 0) Fd = Fs;}}) - 0x1: movtps({{ if ( FPConditionCode(CC) == 0) Fd = Fs;}}) + format Float64Op { + 0x0: movfps({{ if ( FPConditionCode(CC) == 0) Fd = Fs;}}); + 0x1: movtps({{ if ( FPConditionCode(CC) == 0) Fd = Fs;}}); } } } 0x4: decode RS_LO { - 0x0: FloatOp64::cvt_s_pu({{ + 0x0: Float64Op::cvt_s_pu({{ int rnd_mode = xc->miscRegs.fcsr; Fd = convert_and_round(Fs.df,rnd_mode,FP_DOUBLE,FP_PS_HI); }}); } 0x5: decode RS_LO { - format FloatOp64 { + format Float64Op { 0x0: cvt_s_pl({{ int rnd_mode = xc->miscRegs.fcsr; Fd = convert_and_round(Fs.df,rnd_mode,FP_SINGLE,FP_PS_LO); @@ -631,27 +634,27 @@ decode OPCODE_HI default Unknown::unknown() { 0x0: decode RS_HI { 0x0: decode RS_LO { format WarnUnimpl { - 0x0: mfc2({{ }}); - 0x2: cfc2({{ }}); - 0x3: mfhc2({{ }}); - 0x4: mtc2({{ }}); - 0x6: ctc2({{ }}); - 0x7: mftc2({{ }}); + 0x0: mfc2(); + 0x2: cfc2(); + 0x3: mfhc2(); + 0x4: mtc2(); + 0x6: ctc2(); + 0x7: mftc2(); } } 0x1: decode ND { 0x0: decode TF { format WarnUnimpl { - 0x0: bc2f({{ cond = (xc->miscRegs.cop2cc == 0); }}, COP2); - 0x1: bc2t({{ cond = (xc->miscRegs.cop2cc == 1); }}, COP2}}); + 0x0: bc2f(); + 0x1: bc2t(); } } 0x1: decode TF { format WarnUnimpl { - 0x0: bc2fl({{ cond = (xc->miscRegs.cop2cc == 0); }}, COP2}}); - 0x1: bc2tl({{ cond = (xc->miscRegs.cop2cc == 1); }}, COP2}}); + 0x0: bc2fl(); + 0x1: bc2tl(); } } } @@ -681,12 +684,13 @@ decode OPCODE_HI default Unknown::unknown() { EA = Rs + Rt; }}, {{ Mem.df = Ft<63:0>;}}); - 0x7: prefx({{ }}); } + + 0x7: WarnUnimpl::prefx(); } format FloatOp { - 0x3: WarnUnimpl::alnv_ps({{ }}); + 0x3: WarnUnimpl::alnv_ps(); format BasicOp { 0x4: decode FUNCTION_LO { @@ -733,13 +737,13 @@ decode OPCODE_HI default Unknown::unknown() { } //MIPS obsolete instructions - format Branch { - 0x4: beql({{ cond = (Rs.sq == 0); }}); - 0x5: bnel({{ cond = (Rs.sq != 0); }}); - 0x6: blezl({{ cond = (Rs.sq <= 0); }}); - 0x7: bgtzl({{ cond = (Rs.sq > 0); }}); + format CondBranch { + 0x4: beql({{ cond = (Rs.sw == 0); }}); + 0x5: bnel({{ cond = (Rs.sw != 0); }}); + 0x6: blezl({{ cond = (Rs.sw <= 0); }}); + 0x7: bgtzl({{ cond = (Rs.sw > 0); }}); } - }; + } 0x3: decode OPCODE_LO default FailUnimpl::reserved() { @@ -807,7 +811,7 @@ decode OPCODE_HI default Unknown::unknown() { } 0x7: decode FUNCTION_LO { - 0x7: WarnUnimpl::sdbbp({{ }}); + 0x7: WarnUnimpl::sdbbp(); } } @@ -816,15 +820,15 @@ decode OPCODE_HI default Unknown::unknown() { 0x0: decode FUNCTION_LO { format WarnUnimpl { - 0x1: ext({{ }}); - 0x4: ins({{ }}); + 0x1: ext(); + 0x4: ins(); } } 0x1: decode FUNCTION_LO { format WarnUnimpl { - 0x0: fork({{ }}); - 0x1: yield({{ }}); + 0x0: fork(); + 0x1: yield(); } } @@ -832,7 +836,7 @@ decode OPCODE_HI default Unknown::unknown() { //Table A-10 MIPS32 BSHFL Encoding of sa Field 0x4: decode SA { - 0x02: WarnUnimpl::wsbh({{ }}); + 0x02: WarnUnimpl::wsbh(); format BasicOp { 0x10: seb({{ Rd.sw = /* sext32(Rt<7>,24) | */ Rt<7:0>}}); @@ -844,53 +848,53 @@ decode OPCODE_HI default Unknown::unknown() { 0x7: BasicOp::rdhwr({{ Rt = xc->hwRegs[RD];}}); } } - }; + } 0x4: decode OPCODE_LO default FailUnimpl::reserved() { format Memory { 0x0: lb({{ EA = Rs + disp; }}, {{ Rb.sw = Mem.sb; }}); 0x1: lh({{ EA = Rs + disp; }}, {{ Rb.sw = Mem.sh; }}); - 0x2: lwl({{ EA = Rs + disp; }}, {{ Rb.sw = Mem.sw; }}, WordAlign); + 0x2: lwl({{ EA = Rs + disp; }}, {{ Rb.sw = Mem.sw; }});//, WordAlign); 0x3: lw({{ EA = Rs + disp; }}, {{ Rb.uq = Mem.sb; }}); 0x4: lbu({{ EA = Rs + disp; }}, {{ Rb.uw = Mem.ub; }}); 0x5: lhu({{ EA = Rs + disp; }}, {{ Rb.uw = Mem.uh; }}); - 0x6: lwr({{ EA = Rs + disp; }}, {{ Rb.uw = Mem.uw; }}, WordAlign); - }; + 0x6: lwr({{ EA = Rs + disp; }}, {{ Rb.uw = Mem.uw; }});//, WordAlign); + } - 0x7: FailUnimpl::reserved({{ }}); - }; + 0x7: FailUnimpl::reserved(); + } 0x5: decode OPCODE_LO default FailUnimpl::reserved() { format Memory { 0x0: sb({{ EA = Rs + disp; }}, {{ Mem.ub = Rt<7:0>; }}); 0x1: sh({{ EA = Rs + disp; }},{{ Mem.uh = Rt<15:0>; }}); - 0x2: swl({{ EA = Rs + disp; }},{{ Mem.ub = Rt<31:0>; }},WordAlign); + 0x2: swl({{ EA = Rs + disp; }},{{ Mem.ub = Rt<31:0>; }});//,WordAlign); 0x3: sw({{ EA = Rs + disp; }},{{ Mem.ub = Rt<31:0>; }}); - 0x6: swr({{ EA = Rs + disp; }},{{ Mem.ub = Rt<31:0>; }},WordAlign); - }; + 0x6: swr({{ EA = Rs + disp; }},{{ Mem.ub = Rt<31:0>; }});//,WordAlign); + } format WarnUnimpl { - 0x7: cache({{ }}); - }; + 0x7: cache(); + } - }; + } 0x6: decode OPCODE_LO default FailUnimpl::reserved() { - 0x0: WarnUnimpl::ll({{ }}); + 0x0: WarnUnimpl::ll(); format Memory { 0x1: lwc1({{ EA = Rs + disp; }},{{ Ft<31:0> = Mem.uf; }}); 0x5: ldc1({{ EA = Rs + disp; }},{{ Ft<63:0> = Mem.df; }}); - }; - }; + } + } 0x7: decode OPCODE_LO default FailUnimpl::reserved() { - 0x0: WarnUnimpl::sc({{ }}); + 0x0: WarnUnimpl::sc(); format Memory { 0x1: swc1({{ EA = Rs + disp; }},{{ Mem.uf = Ft<31:0>; }}); 0x5: sdc1({{ EA = Rs + disp; }},{{ Mem.df = Ft<63:0>; }}); - }; + } } } diff --git a/arch/mips/isa/formats/fp.isa b/arch/mips/isa/formats/fp.isa index 707109fc2..23fcbaa67 100644 --- a/arch/mips/isa/formats/fp.isa +++ b/arch/mips/isa/formats/fp.isa @@ -27,7 +27,7 @@ output decoder {{ } }}; -def template FPExecute {{ +def template FloatingPointExecute {{ Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const { //These are set to constants when the execute method @@ -70,7 +70,7 @@ def template FPExecute {{ }}; // Primary format for integer operate instructions: -def format FPOp(code, *opt_flags) {{ +def format FloatOp(code, *opt_flags) {{ orig_code = code cblk = CodeBlock(code) checkPriv = (code.find('checkPriv') != -1) @@ -86,12 +86,33 @@ def format FPOp(code, *opt_flags) {{ header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) decode_block = BasicDecodeWithMnemonic.subst(iop) - exec_output = IntegerExecute.subst(iop) + exec_output = FloatingPointExecute.subst(iop) +}}; + +// Primary format for integer operate instructions: +def format Float64Op(code, *opt_flags) {{ + orig_code = code + cblk = CodeBlock(code) + checkPriv = (code.find('checkPriv') != -1) + code.replace('checkPriv', '') + if checkPriv: + code.replace('checkPriv;', 'if(!xc->regs.miscRegFile.pstateFields.priv) throw privileged_opcode;') + else: + code.replace('checkPriv;', '') + for (marker, value) in (('ivValue', '0'), ('icValue', '0'), + ('xvValue', '0'), ('xcValue', '0')): + code.replace(marker, value) + iop = InstObjParams(name, Name, 'MipsStaticInst', cblk, opt_flags) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecodeWithMnemonic.subst(iop) + exec_output = FloatingPointExecute.subst(iop) }}; // Primary format for integer operate instructions: def format FPOpCc(code, icValue, ivValue, xcValue, xvValue, *opt_flags) {{ orig_code = code + cblk = CodeBlock(code) checkPriv = (code.find('checkPriv') != -1) code.replace('checkPriv', '') diff --git a/arch/mips/isa/formats/mem.isa b/arch/mips/isa/formats/mem.isa index 5ed5237c5..e3028eb7c 100644 --- a/arch/mips/isa/formats/mem.isa +++ b/arch/mips/isa/formats/mem.isa @@ -55,7 +55,7 @@ def template MemExecute {{ }}; // Primary format for integer operate instructions: -def format Mem(code, *opt_flags) {{ +def format Memory(code, ea_code = {{ EA = Rb + disp; }},*opt_flags) {{ orig_code = code cblk = CodeBlock(code) iop = InstObjParams(name, Name, 'MipsStaticInst', cblk, opt_flags) diff --git a/arch/mips/isa/formats/noop.isa b/arch/mips/isa/formats/noop.isa index b1ece654d..6d45ba9b6 100644 --- a/arch/mips/isa/formats/noop.isa +++ b/arch/mips/isa/formats/noop.isa @@ -45,3 +45,90 @@ def format Noop(code, *opt_flags) {{ decode_block = BasicDecodeWithMnemonic.subst(iop) exec_output = NoopExecute.subst(iop) }}; + +//////////////////////////////////////////////////////////////////// +// +// Nop +// + +output header {{ + /** + * Static instruction class for no-ops. This is a leaf class. + */ + class Nop : public AlphaStaticInst + { + /// Disassembly of original instruction. + const std::string originalDisassembly; + + public: + /// Constructor + Nop(const std::string _originalDisassembly, MachInst _machInst) + : AlphaStaticInst("nop", _machInst, No_OpClass), + originalDisassembly(_originalDisassembly) + { + flags[IsNop] = true; + } + + ~Nop() { } + + std::string + generateDisassembly(Addr pc, const SymbolTable *symtab) const; + + %(BasicExecDeclare)s + }; +}}; + +output decoder {{ + std::string Nop::generateDisassembly(Addr pc, + const SymbolTable *symtab) const + { +#ifdef SS_COMPATIBLE_DISASSEMBLY + return originalDisassembly; +#else + return csprintf("%-10s (%s)", "nop", originalDisassembly); +#endif + } + + /// Helper function for decoding nops. Substitute Nop object + /// for original inst passed in as arg (and delete latter). + inline + AlphaStaticInst * + makeNop(AlphaStaticInst *inst) + { + AlphaStaticInst *nop = new Nop(inst->disassemble(0), inst->machInst); + delete inst; + return nop; + } +}}; + +output exec {{ + Fault + Nop::execute(%(CPU_exec_context)s *, Trace::InstRecord *) const + { + return No_Fault; + } +}}; + +// integer & FP operate instructions use Rc as dest, so check for +// Rc == 31 to detect nops +def template OperateNopCheckDecode {{ + { + AlphaStaticInst *i = new %(class_name)s(machInst); + if (RC == 31) { + i = makeNop(i); + } + return i; + } +}}; + + +// Like BasicOperate format, but generates NOP if RC/FC == 31 +def format BasicOperateWithNopCheck(code, *opt_args) {{ + iop = InstObjParams(name, Name, 'AlphaStaticInst', CodeBlock(code), + opt_args) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = OperateNopCheckDecode.subst(iop) + exec_output = BasicExecute.subst(iop) +}}; + diff --git a/arch/mips/isa/operands.isa b/arch/mips/isa/operands.isa index c8e08a436..cf6f10e0b 100644 --- a/arch/mips/isa/operands.isa +++ b/arch/mips/isa/operands.isa @@ -5,8 +5,8 @@ def operand_types {{ 'uhw' : ('unsigned int', 16), 'sw' : ('signed int', 32), 'uw' : ('unsigned int', 32), - 'sdw' : ('signed int', 64), - 'udw' : ('unsigned int', 64), + 'sd' : ('signed int', 64), + 'ud' : ('unsigned int', 64), 'sf' : ('float', 32), 'df' : ('float', 64), 'qf' : ('float', 128) @@ -24,7 +24,7 @@ def operands {{ 'Fs': ('FloatReg', 'sf', 'FS', 'IsFloating', 2), 'Ft': ('FloatReg', 'sf', 'FT', 'IsFloating', 3), - 'Mem': ('Mem', 'udw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 4) + 'Mem': ('Mem', 'ud', None, ('IsMemRef', 'IsLoad', 'IsStore'), 4) #'NPC': ('NPC', 'uq', None, ( None, None, 'IsControl' ), 4), #'Runiq': ('ControlReg', 'uq', 'Uniq', None, 1), From 18a0fa3e0c19e1afaf1dedb3d5a3b14a2c3aa3c7 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Wed, 15 Feb 2006 01:23:13 -0500 Subject: [PATCH 050/180] endian fixes and compiles on mac os x arch/alpha/alpha_linux_process.cc: add endian conversions for fstat functions arch/alpha/alpha_tru64_process.cc: add endian conversions for various functions sim/byteswap.hh: for some reason gcc on macos really wants long and unsigned long Why int32_t and uint32_t isn't sufficient I don't know. sim/process.cc: sim/syscall_emul.hh: endian fixes --HG-- extra : convert_revision : ce625d5660b70867c43c74fbed856149c0d8cd36 --- arch/alpha/alpha_linux_process.cc | 44 ++++--- arch/alpha/alpha_tru64_process.cc | 207 +++++++++++++++--------------- sim/byteswap.hh | 6 +- sim/process.cc | 5 +- sim/syscall_emul.hh | 19 ++- 5 files changed, 157 insertions(+), 124 deletions(-) diff --git a/arch/alpha/alpha_linux_process.cc b/arch/alpha/alpha_linux_process.cc index 113b41472..fb5e32e63 100644 --- a/arch/alpha/alpha_linux_process.cc +++ b/arch/alpha/alpha_linux_process.cc @@ -296,27 +296,38 @@ class Linux { // Same for stat64 static void - copyOutStat64Buf(FunctionalMemory *mem, Addr addr, hst_stat64 *host) + copyOutStat64Buf(FunctionalMemory *mem, int fd, Addr addr, hst_stat64 *host) { TypedBufferArg tgt(addr); - // XXX byteswaps - tgt->st_dev = htog(host->st_dev); + // fd == 1 checks are because libc does some checks + // that the stdout is interactive vs. a file + // this makes it work on non-linux systems + if (fd == 1) + tgt->st_dev = htog((uint64_t)0xA); + else + tgt->st_dev = htog((uint64_t)host->st_dev); // XXX What about STAT64_HAS_BROKEN_ST_INO ??? - tgt->st_ino = htog(host->st_ino); - tgt->st_rdev = htog(host->st_rdev); - tgt->st_size = htog(host->st_size); - tgt->st_blocks = htog(host->st_blocks); + tgt->st_ino = htog((uint64_t)host->st_ino); + if (fd == 1) + tgt->st_rdev = htog((uint64_t)0x880d); + else + tgt->st_rdev = htog((uint64_t)host->st_rdev); + tgt->st_size = htog((int64_t)host->st_size); + tgt->st_blocks = htog((uint64_t)host->st_blocks); - tgt->st_mode = htog(host->st_mode); - tgt->st_uid = htog(host->st_uid); - tgt->st_gid = htog(host->st_gid); - tgt->st_blksize = htog(host->st_blksize); - tgt->st_nlink = htog(host->st_nlink); - tgt->tgt_st_atime = htog(host->st_atime); - tgt->tgt_st_mtime = htog(host->st_mtime); - tgt->tgt_st_ctime = htog(host->st_ctime); -#if defined(STAT_HAVE_NSEC) || (BSD_HOST == 1) + if (fd == 1) + tgt->st_mode = htog((uint32_t)0x2190); + else + tgt->st_mode = htog((uint32_t)host->st_mode); + tgt->st_uid = htog((uint32_t)host->st_uid); + tgt->st_gid = htog((uint32_t)host->st_gid); + tgt->st_blksize = htog((uint32_t)host->st_blksize); + tgt->st_nlink = htog((uint32_t)host->st_nlink); + tgt->tgt_st_atime = htog((uint64_t)host->st_atime); + tgt->tgt_st_mtime = htog((uint64_t)host->st_mtime); + tgt->tgt_st_ctime = htog((uint64_t)host->st_ctime); +#if defined(STAT_HAVE_NSEC) tgt->st_atime_nsec = htog(host->st_atime_nsec); tgt->st_mtime_nsec = htog(host->st_mtime_nsec); tgt->st_ctime_nsec = htog(host->st_ctime_nsec); @@ -325,6 +336,7 @@ class Linux { tgt->st_mtime_nsec = 0; tgt->st_ctime_nsec = 0; #endif + tgt.copyOut(mem); } diff --git a/arch/alpha/alpha_tru64_process.cc b/arch/alpha/alpha_tru64_process.cc index 1a66d7499..5c24adad9 100644 --- a/arch/alpha/alpha_tru64_process.cc +++ b/arch/alpha/alpha_tru64_process.cc @@ -542,19 +542,19 @@ class Tru64 { { TypedBufferArg tgt(addr); - tgt->st_dev = host->st_dev; - tgt->st_ino = host->st_ino; - tgt->st_mode = host->st_mode; - tgt->st_nlink = host->st_nlink; - tgt->st_uid = host->st_uid; - tgt->st_gid = host->st_gid; - tgt->st_rdev = host->st_rdev; - tgt->st_size = host->st_size; - tgt->st_atimeX = host->st_atime; - tgt->st_mtimeX = host->st_mtime; - tgt->st_ctimeX = host->st_ctime; - tgt->st_blksize = host->st_blksize; - tgt->st_blocks = host->st_blocks; + tgt->st_dev = htog(host->st_dev); + tgt->st_ino = htog(host->st_ino); + tgt->st_mode = htog(host->st_mode); + tgt->st_nlink = htog(host->st_nlink); + tgt->st_uid = htog(host->st_uid); + tgt->st_gid = htog(host->st_gid); + tgt->st_rdev = htog(host->st_rdev); + tgt->st_size = htog(host->st_size); + tgt->st_atimeX = htog(host->st_atime); + tgt->st_mtimeX = htog(host->st_mtime); + tgt->st_ctimeX = htog(host->st_ctime); + tgt->st_blksize = htog(host->st_blksize); + tgt->st_blocks = htog(host->st_blocks); tgt.copyOut(mem); } @@ -571,14 +571,16 @@ class Tru64 { #if defined(__OpenBSD__) || defined(__APPLE__) || defined(__FreeBSD__) tgt->f_type = 0; #else - tgt->f_type = host->f_type; + tgt->f_type = htog(host->f_type); #endif - tgt->f_bsize = host->f_bsize; - tgt->f_blocks = host->f_blocks; - tgt->f_bfree = host->f_bfree; - tgt->f_bavail = host->f_bavail; - tgt->f_files = host->f_files; - tgt->f_ffree = host->f_ffree; + tgt->f_bsize = htog(host->f_bsize); + tgt->f_blocks = htog(host->f_blocks); + tgt->f_bfree = htog(host->f_bfree); + tgt->f_bavail = htog(host->f_bavail); + tgt->f_files = htog(host->f_files); + tgt->f_ffree = htog(host->f_ffree); + + // Is this as string normally? memcpy(&tgt->f_fsid, &host->f_fsid, sizeof(host->f_fsid)); tgt.copyOut(mem); @@ -623,19 +625,19 @@ class Tru64 { { TypedBufferArg tgt(addr); - tgt->st_dev = host->st_dev; - tgt->st_ino = host->st_ino; - tgt->st_mode = host->st_mode; - tgt->st_nlink = host->st_nlink; - tgt->st_uid = host->st_uid; - tgt->st_gid = host->st_gid; - tgt->st_rdev = host->st_rdev; - tgt->st_size = host->st_size; - tgt->st_atimeX = host->st_atime; - tgt->st_mtimeX = host->st_mtime; - tgt->st_ctimeX = host->st_ctime; - tgt->st_blksize = host->st_blksize; - tgt->st_blocks = host->st_blocks; + tgt->st_dev = htog(host->st_dev); + tgt->st_ino = htog(host->st_ino); + tgt->st_mode = htog(host->st_mode); + tgt->st_nlink = htog(host->st_nlink); + tgt->st_uid = htog(host->st_uid); + tgt->st_gid = htog(host->st_gid); + tgt->st_rdev = htog(host->st_rdev); + tgt->st_size = htog(host->st_size); + tgt->st_atimeX = htog(host->st_atime); + tgt->st_mtimeX = htog(host->st_mtime); + tgt->st_ctimeX = htog(host->st_ctime); + tgt->st_blksize = htog(host->st_blksize); + tgt->st_blocks = htog(host->st_blocks); tgt.copyOut(mem); } @@ -674,21 +676,21 @@ class Tru64 { case Tru64::GSI_MAX_CPU: { TypedBufferArg max_cpu(xc->getSyscallArg(1)); - *max_cpu = process->numCpus(); + *max_cpu = htog((uint32_t)process->numCpus()); max_cpu.copyOut(xc->mem); return 1; } case Tru64::GSI_CPUS_IN_BOX: { TypedBufferArg cpus_in_box(xc->getSyscallArg(1)); - *cpus_in_box = process->numCpus(); + *cpus_in_box = htog((uint32_t)process->numCpus()); cpus_in_box.copyOut(xc->mem); return 1; } case Tru64::GSI_PHYSMEM: { TypedBufferArg physmem(xc->getSyscallArg(1)); - *physmem = 1024 * 1024; // physical memory in KB + *physmem = htog((uint64_t)1024 * 1024); // physical memory in KB physmem.copyOut(xc->mem); return 1; } @@ -696,15 +698,15 @@ class Tru64 { case Tru64::GSI_CPU_INFO: { TypedBufferArg infop(xc->getSyscallArg(1)); - infop->current_cpu = 0; - infop->cpus_in_box = process->numCpus(); - infop->cpu_type = 57; - infop->ncpus = process->numCpus(); - int cpumask = (1 << process->numCpus()) - 1; - infop->cpus_present = infop->cpus_running = cpumask; - infop->cpu_binding = 0; - infop->cpu_ex_binding = 0; - infop->mhz = 667; + infop->current_cpu = htog(0); + infop->cpus_in_box = htog(process->numCpus()); + infop->cpu_type = htog(57); + infop->ncpus = htog(process->numCpus()); + uint64_t cpumask = (1 << process->numCpus()) - 1; + infop->cpus_present = infop->cpus_running = htog(cpumask); + infop->cpu_binding = htog(0); + infop->cpu_ex_binding = htog(0); + infop->mhz = htog(667); infop.copyOut(xc->mem); return 1; @@ -712,7 +714,7 @@ class Tru64 { case Tru64::GSI_PROC_TYPE: { TypedBufferArg proc_type(xc->getSyscallArg(1)); - *proc_type = 11; + *proc_type = htog((uint64_t)11); proc_type.copyOut(xc->mem); return 1; } @@ -728,7 +730,7 @@ class Tru64 { case Tru64::GSI_CLK_TCK: { TypedBufferArg clk_hz(xc->getSyscallArg(1)); - *clk_hz = 1024; + *clk_hz = htog((uint64_t)1024); clk_hz.copyOut(xc->mem); return 1; } @@ -824,7 +826,7 @@ class Tru64 { // just pass basep through uninterpreted. TypedBufferArg basep(tgt_basep); basep.copyIn(xc->mem); - long host_basep = (off_t)*basep; + long host_basep = (off_t)htog((int64_t)*basep); int host_result = getdirentries(fd, host_buf, tgt_nbytes, &host_basep); // check for error @@ -858,7 +860,7 @@ class Tru64 { delete [] host_buf; - *basep = host_basep; + *basep = htog((int64_t)host_basep); basep.copyOut(xc->mem); return tgt_buf_ptr - tgt_buf; @@ -879,14 +881,14 @@ class Tru64 { // Note that we'll advance PC <- NPC before the end of the cycle, // so we need to restore the desired PC into NPC. // The current regs->pc will get clobbered. - regs->npc = sc->sc_pc; + regs->npc = htog(sc->sc_pc); for (int i = 0; i < 31; ++i) { - regs->intRegFile[i] = sc->sc_regs[i]; - regs->floatRegFile.q[i] = sc->sc_fpregs[i]; + regs->intRegFile[i] = htog(sc->sc_regs[i]); + regs->floatRegFile.q[i] = htog(sc->sc_fpregs[i]); } - regs->miscRegs.fpcr = sc->sc_fpcr; + regs->miscRegs.fpcr = htog(sc->sc_fpcr); return 0; } @@ -909,15 +911,15 @@ class Tru64 { TypedBufferArg elp(xc->getSyscallArg(2)); const int clk_hz = one_million; - elp->si_user = curTick / (Clock::Frequency / clk_hz); - elp->si_nice = 0; - elp->si_sys = 0; - elp->si_idle = 0; - elp->wait = 0; - elp->si_hz = clk_hz; - elp->si_phz = clk_hz; - elp->si_boottime = seconds_since_epoch; // seconds since epoch? - elp->si_max_procs = process->numCpus(); + elp->si_user = htog(curTick / (Clock::Frequency / clk_hz)); + elp->si_nice = htog(0); + elp->si_sys = htog(0); + elp->si_idle = htog(0); + elp->wait = htog(0); + elp->si_hz = htog(clk_hz); + elp->si_phz = htog(clk_hz); + elp->si_boottime = htog(seconds_since_epoch); // seconds since epoch? + elp->si_max_procs = htog(process->numCpus()); elp.copyOut(xc->mem); return 0; } @@ -952,9 +954,10 @@ class Tru64 { // if the user chose an address, just let them have it. Otherwise // pick one for them. - if (argp->address == 0) { - argp->address = process->next_thread_stack_base; - int stack_size = (argp->rsize + argp->ysize + argp->gsize); + if (htog(argp->address) == 0) { + argp->address = htog(process->next_thread_stack_base); + int stack_size = (htog(argp->rsize) + htog(argp->ysize) + + htog(argp->gsize)); process->next_thread_stack_base -= stack_size; argp.copyOut(xc->mem); } @@ -978,14 +981,14 @@ class Tru64 { attrp.copyIn(xc->mem); - if (attrp->nxm_version != NXM_LIB_VERSION) { + if (gtoh(attrp->nxm_version) != NXM_LIB_VERSION) { cerr << "nxm_task_init: thread library version mismatch! " << "got " << attrp->nxm_version << ", expected " << NXM_LIB_VERSION << endl; abort(); } - if (attrp->flags != Tru64::NXM_TASK_INIT_VP) { + if (gtoh(attrp->flags) != Tru64::NXM_TASK_INIT_VP) { cerr << "nxm_task_init: bad flag value " << attrp->flags << " (expected " << Tru64::NXM_TASK_INIT_VP << ")" << endl; abort(); @@ -1012,10 +1015,10 @@ class Tru64 { // now initialize a config_info struct and copy it out to user space TypedBufferArg config(config_addr); - config->nxm_nslots_per_rad = process->numCpus(); - config->nxm_nrads = 1; // only one RAD in our system! - config->nxm_slot_state = slot_state_addr; - config->nxm_rad[0] = rad_state_addr; + config->nxm_nslots_per_rad = htog(process->numCpus()); + config->nxm_nrads = htog(1); // only one RAD in our system! + config->nxm_slot_state = htog(slot_state_addr); + config->nxm_rad[0] = htog(rad_state_addr); config.copyOut(xc->mem); @@ -1024,6 +1027,8 @@ class Tru64 { slot_state_size); for (int i = 0; i < process->numCpus(); ++i) { // CPU 0 is bound to the calling process; all others are available + // XXX this code should have an endian conversion, but I don't think + // it works anyway slot_state[i] = (i == 0) ? Tru64::NXM_SLOT_BOUND : Tru64::NXM_SLOT_AVAIL; } @@ -1041,24 +1046,24 @@ class Tru64 { rad_state->nxm_uniq_offset = attrp->nxm_uniq_offset; for (int i = 0; i < process->numCpus(); ++i) { Tru64::nxm_sched_state *ssp = &rad_state->nxm_ss[i]; - ssp->nxm_u.sigmask = 0; - ssp->nxm_u.sig = 0; - ssp->nxm_u.flags = 0; - ssp->nxm_u.cancel_state = 0; + ssp->nxm_u.sigmask = htog(0); + ssp->nxm_u.sig = htog(0); + ssp->nxm_u.flags = htog(0); + ssp->nxm_u.cancel_state = htog(0); ssp->nxm_u.nxm_ssig = 0; - ssp->nxm_bits = 0; + ssp->nxm_bits = htog(0); ssp->nxm_quantum = attrp->nxm_quantum; ssp->nxm_set_quantum = attrp->nxm_quantum; - ssp->nxm_sysevent = 0; + ssp->nxm_sysevent = htog(0); if (i == 0) { uint64_t uniq = xc->regs.miscRegs.uniq; - ssp->nxm_u.pth_id = uniq + attrp->nxm_uniq_offset; - ssp->nxm_u.nxm_active = uniq | 1; + ssp->nxm_u.pth_id = htog(uniq + gtoh(attrp->nxm_uniq_offset)); + ssp->nxm_u.nxm_active = htog(uniq | 1); } else { - ssp->nxm_u.pth_id = 0; - ssp->nxm_u.nxm_active = 0; + ssp->nxm_u.pth_id = htog(0); + ssp->nxm_u.nxm_active = htog(0); } } @@ -1067,7 +1072,7 @@ class Tru64 { // // copy pointer to shared config area out to user // - *configptr_ptr = config_addr; + *configptr_ptr = htog(config_addr); configptr_ptr.copyOut(xc->mem); // Register this as a valid address range with the process @@ -1084,13 +1089,13 @@ class Tru64 { { memset(&ec->regs, 0, sizeof(ec->regs)); - ec->regs.intRegFile[ArgumentReg0] = attrp->registers.a0; - ec->regs.intRegFile[27/*t12*/] = attrp->registers.pc; - ec->regs.intRegFile[StackPointerReg] = attrp->registers.sp; + ec->regs.intRegFile[ArgumentReg0] = gtoh(attrp->registers.a0); + ec->regs.intRegFile[27/*t12*/] = gtoh(attrp->registers.pc); + ec->regs.intRegFile[StackPointerReg] = gtoh(attrp->registers.sp); ec->regs.miscRegs.uniq = uniq_val; - ec->regs.pc = attrp->registers.pc; - ec->regs.npc = attrp->registers.pc + sizeof(MachInst); + ec->regs.pc = gtoh(attrp->registers.pc); + ec->regs.npc = gtoh(attrp->registers.pc) + sizeof(MachInst); ec->activate(); } @@ -1107,7 +1112,7 @@ class Tru64 { // get attribute args attrp.copyIn(xc->mem); - if (attrp->version != NXM_LIB_VERSION) { + if (gtoh(attrp->version) != NXM_LIB_VERSION) { cerr << "nxm_thread_create: thread library version mismatch! " << "got " << attrp->version << ", expected " << NXM_LIB_VERSION << endl; @@ -1132,28 +1137,28 @@ class Tru64 { rad_state_size); rad_state.copyIn(xc->mem); - uint64_t uniq_val = attrp->pthid - rad_state->nxm_uniq_offset; + uint64_t uniq_val = gtoh(attrp->pthid) - gtoh(rad_state->nxm_uniq_offset); - if (attrp->type == Tru64::NXM_TYPE_MANAGER) { + if (gtoh(attrp->type) == Tru64::NXM_TYPE_MANAGER) { // DEC pthreads seems to always create one of these (in // addition to N application threads), but we don't use it, // so don't bother creating it. // This is supposed to be a port number. Make something up. - *kidp = 99; + *kidp = htog(99); kidp.copyOut(xc->mem); return 0; - } else if (attrp->type == Tru64::NXM_TYPE_VP) { + } else if (gtoh(attrp->type) == Tru64::NXM_TYPE_VP) { // A real "virtual processor" kernel thread. Need to fork // this thread on another CPU. Tru64::nxm_sched_state *ssp = &rad_state->nxm_ss[thread_index]; - if (ssp->nxm_u.nxm_active != 0) + if (gtoh(ssp->nxm_u.nxm_active) != 0) return (int) Tru64::KERN_NOT_RECEIVER; ssp->nxm_u.pth_id = attrp->pthid; - ssp->nxm_u.nxm_active = uniq_val | 1; + ssp->nxm_u.nxm_active = htog(uniq_val | 1); rad_state.copyOut(xc->mem); @@ -1173,6 +1178,8 @@ class Tru64 { fatal(""); } + // XXX This should have an endian conversion but I think this code + // doesn't work anyway slot_state[thread_index] = Tru64::NXM_SLOT_BOUND; slot_state.copyOut(xc->mem); @@ -1188,7 +1195,7 @@ class Tru64 { // This is supposed to be a port number, but we'll try // and get away with just sticking the thread index // here. - *kidp = thread_index; + *kidp = htog(thread_index); kidp.copyOut(xc->mem); return 0; @@ -1320,9 +1327,9 @@ class Tru64 { lockp.copyIn(xc->mem); - if (*lockp == 0) { + if (gtoh(*lockp) == 0) { // lock is free: grab it - *lockp = 1; + *lockp = htog(1); lockp.copyOut(xc->mem); } else { // lock is busy: disable until free @@ -1375,9 +1382,9 @@ class Tru64 { lockp.copyIn(xc->mem); - if (*lockp == 0) { + if (gtoh(*lockp) == 0) { // lock is free: grab it - *lockp = 1; + *lockp = htog(1); lockp.copyOut(xc->mem); return 0; } else { @@ -1434,7 +1441,7 @@ class Tru64 { // user is supposed to acquire lock before entering lockp.copyIn(xc->mem); - assert(*lockp != 0); + assert(gtoh(*lockp) != 0); m5_unlock_mutex(lock_addr, process, xc); diff --git a/sim/byteswap.hh b/sim/byteswap.hh index 6a98a987f..c5d8801ab 100644 --- a/sim/byteswap.hh +++ b/sim/byteswap.hh @@ -79,7 +79,11 @@ static inline uint64_t swap_byte(uint64_t x) {return swap_byte64(x);} static inline int64_t swap_byte(int64_t x) {return swap_byte64((uint64_t)x);} static inline uint32_t swap_byte(uint32_t x) {return swap_byte32(x);} static inline int32_t swap_byte(int32_t x) {return swap_byte32((uint32_t)x);} -static inline int32_t swap_byte(long x) {return swap_byte32((long)x);} +#if defined(__APPLE__) +static inline long swap_byte(long x) {return swap_byte32((long)x);} +static inline unsigned long swap_byte(unsigned long x) + { return swap_byte32((unsigned long)x);} +#endif static inline uint16_t swap_byte(uint16_t x) {return swap_byte32(x);} static inline int16_t swap_byte(int16_t x) {return swap_byte16((uint16_t)x);} static inline uint8_t swap_byte(uint8_t x) {return x;} diff --git a/sim/process.cc b/sim/process.cc index 395e2eb0a..59d122b48 100644 --- a/sim/process.cc +++ b/sim/process.cc @@ -251,8 +251,10 @@ static void copyStringArray(vector &strings, Addr array_ptr, Addr data_ptr, FunctionalMemory *memory) { + Addr data_ptr_swap; for (int i = 0; i < strings.size(); ++i) { - memory->access(Write, array_ptr, &data_ptr, sizeof(Addr)); + data_ptr_swap = htog(data_ptr); + memory->access(Write, array_ptr, &data_ptr_swap, sizeof(Addr)); memory->writeString(data_ptr, strings[i].c_str()); array_ptr += sizeof(Addr); data_ptr += strings[i].size() + 1; @@ -334,6 +336,7 @@ LiveProcess::LiveProcess(const string &nm, ObjectFile *objFile, // write contents to stack uint64_t argc = argv.size(); + argc = htog(argc); memory->access(Write, stack_min, &argc, sizeof(uint64_t)); copyStringArray(argv, argv_array_base, arg_data_base, memory); diff --git a/sim/syscall_emul.hh b/sim/syscall_emul.hh index f55709575..8f5402413 100644 --- a/sim/syscall_emul.hh +++ b/sim/syscall_emul.hh @@ -455,7 +455,7 @@ fstat64Func(SyscallDesc *desc, int callnum, Process *process, if (result < 0) return errno; - OS::copyOutStat64Buf(xc->mem, xc->getSyscallArg(1), &hostBuf); + OS::copyOutStat64Buf(xc->mem, fd, xc->getSyscallArg(1), &hostBuf); return 0; } @@ -505,7 +505,7 @@ lstat64Func(SyscallDesc *desc, int callnum, Process *process, if (result < 0) return -errno; - OS::copyOutStat64Buf(xc->mem, xc->getSyscallArg(1), &hostBuf); + OS::copyOutStat64Buf(xc->mem, -1, xc->getSyscallArg(1), &hostBuf); return 0; } @@ -600,9 +600,9 @@ writevFunc(SyscallDesc *desc, int callnum, Process *process, typename OS::tgt_iovec tiov; xc->mem->access(Read, tiov_base + i*sizeof(typename OS::tgt_iovec), &tiov, sizeof(typename OS::tgt_iovec)); - hiov[i].iov_len = tiov.iov_len; + hiov[i].iov_len = gtoh(tiov.iov_len); hiov[i].iov_base = new char [hiov[i].iov_len]; - xc->mem->access(Read, tiov.iov_base, + xc->mem->access(Read, gtoh(tiov.iov_base), hiov[i].iov_base, hiov[i].iov_len); } @@ -674,6 +674,8 @@ getrlimitFunc(SyscallDesc *desc, int callnum, Process *process, case OS::TGT_RLIMIT_STACK: // max stack size in bytes: make up a number (2MB for now) rlp->rlim_cur = rlp->rlim_max = 8 * 1024 * 1024; + rlp->rlim_cur = htog(rlp->rlim_cur); + rlp->rlim_max = htog(rlp->rlim_max); break; default: @@ -697,6 +699,8 @@ gettimeofdayFunc(SyscallDesc *desc, int callnum, Process *process, getElapsedTime(tp->tv_sec, tp->tv_usec); tp->tv_sec += seconds_since_epoch; + tp->tv_sec = htog(tp->tv_sec); + tp->tv_usec = htog(tp->tv_usec); tp.copyOut(xc->mem); @@ -721,8 +725,8 @@ utimesFunc(SyscallDesc *desc, int callnum, Process *process, struct timeval hostTimeval[2]; for (int i = 0; i < 2; ++i) { - hostTimeval[i].tv_sec = (*tp)[i].tv_sec; - hostTimeval[i].tv_usec = (*tp)[i].tv_usec; + hostTimeval[i].tv_sec = gtoh((*tp)[i].tv_sec); + hostTimeval[i].tv_usec = gtoh((*tp)[i].tv_usec); } int result = utimes(path.c_str(), hostTimeval); @@ -748,6 +752,9 @@ getrusageFunc(SyscallDesc *desc, int callnum, Process *process, } getElapsedTime(rup->ru_utime.tv_sec, rup->ru_utime.tv_usec); + rup->ru_utime.tv_sec = htog(rup->ru_utime.tv_sec); + rup->ru_utime.tv_usec = htog(rup->ru_utime.tv_usec); + rup->ru_stime.tv_sec = 0; rup->ru_stime.tv_usec = 0; rup->ru_maxrss = 0; From 2d04f186748c70b3d8afecd39b94436c33848d93 Mon Sep 17 00:00:00 2001 From: Kevin Lim Date: Wed, 15 Feb 2006 13:05:21 -0500 Subject: [PATCH 051/180] Gives separate methods for initiating and completing a memory access, which will be helpful for the merged memory model. arch/alpha/isa/mem.isa: Include methods that allow a memory operation to be split between the part that initiates the access, and the part that completes the access. In these functions the Mem variable is explicitly declared; in the default execute functions, the Mem variable is still handled through %(op_decl)s. arch/isa_parser.py: Include recording the type of the memory access variable so that it can be used if it needs to be explicitly declared in a template. Have memory operands consider themselves neither a source nor a destination to avoid including themselves on the op_src_decl list or the op_dest_decl list. Record op_src_decl and op_dest_decl lists to allow for declaring only source or destination operands. This is needed for the split memory access methods. --HG-- extra : convert_revision : f674f7a2f747ae40ba8c3a0933b0337c87ee0b6c --- arch/alpha/isa/mem.isa | 153 ++++++++++++++++++++++++++++++++++++++++- arch/isa_parser.py | 18 +++++ 2 files changed, 170 insertions(+), 1 deletion(-) diff --git a/arch/alpha/isa/mem.isa b/arch/alpha/isa/mem.isa index 45afd378c..1889daefc 100644 --- a/arch/alpha/isa/mem.isa +++ b/arch/alpha/isa/mem.isa @@ -164,9 +164,24 @@ def template LoadStoreDeclare {{ %(class_name)s(MachInst machInst); %(BasicExecDeclare)s + + %(InitiateAccDeclare)s + + %(CompleteAccDeclare)s }; }}; + +def template InitiateAccDeclare {{ + Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const; +}}; + + +def template CompleteAccDeclare {{ + Fault completeAcc(uint8_t *, %(CPU_exec_context)s *, Trace::InstRecord *) const; +}}; + + def template LoadStoreConstructor {{ /** TODO: change op_class to AddrGenOp or something (requires * creating new member of OpClass enum in op_class.hh, updating @@ -267,6 +282,54 @@ def template LoadExecute {{ }}; +def template LoadInitiateAcc {{ + Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + Addr EA; + Fault fault = No_Fault; + %(mem_acc_type)s Mem = 0; + + %(fp_enable_check)s; + %(op_src_decl)s; + %(op_rd)s; + %(ea_code)s; + + if (fault == No_Fault) { + fault = xc->read(EA, (uint%(mem_acc_size)d_t &)Mem, memAccessFlags); + } + + return fault; + } +}}; + + +def template LoadCompleteAcc {{ + Fault %(class_name)s::completeAcc(uint8_t *data, + %(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + Fault fault = No_Fault; + %(mem_acc_type)s Mem = 0; + + %(fp_enable_check)s; + %(op_dest_decl)s; + + memcpy(&Mem, data, sizeof(Mem)); + + if (fault == No_Fault) { + %(memacc_code)s; + } + + if (fault == No_Fault) { + %(op_wb)s; + } + + return fault; + } +}}; + + def template StoreMemAccExecute {{ Fault %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc, @@ -339,6 +402,60 @@ def template StoreExecute {{ } }}; +def template StoreInitiateAcc {{ + Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + Addr EA; + Fault fault = No_Fault; + uint64_t write_result = 0; + %(mem_acc_type)s Mem = 0; + + %(fp_enable_check)s; + %(op_src_decl)s; + %(op_rd)s; + %(ea_code)s; + + if (fault == No_Fault) { + %(memacc_code)s; + } + + if (fault == No_Fault) { + fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, + memAccessFlags, &write_result); + if (traceData) { traceData->setData(Mem); } + } + + return fault; + } +}}; + + +def template StoreCompleteAcc {{ + Fault %(class_name)s::completeAcc(uint8_t *data, + %(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + Fault fault = No_Fault; + uint64_t write_result = 0; + + %(fp_enable_check)s; + %(op_dest_decl)s; + + memcpy(&write_result, data, sizeof(write_result)); + + if (fault == No_Fault) { + %(postacc_code)s; + } + + if (fault == No_Fault) { + %(op_wb)s; + } + + return fault; + } +}}; + def template MiscMemAccExecute {{ Fault %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc, @@ -380,6 +497,36 @@ def template MiscExecute {{ } }}; +def template MiscInitiateAcc {{ + Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + Addr EA; + Fault fault = No_Fault; + + %(fp_enable_check)s; + %(op_decl)s; + %(op_rd)s; + %(ea_code)s; + + if (fault == No_Fault) { + %(memacc_code)s; + } + + return No_Fault; + } +}}; + + +def template MiscCompleteAcc {{ + Fault %(class_name)s::completeAcc(uint8_t *data, + %(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + return No_Fault; + } +}}; + // load instructions use Ra as dest, so check for // Ra == 31 to detect nops def template LoadNopCheckDecode {{ @@ -455,13 +602,17 @@ def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, # select templates memAccExecTemplate = eval(exec_template_base + 'MemAccExecute') fullExecTemplate = eval(exec_template_base + 'Execute') + initiateAccTemplate = eval(exec_template_base + 'InitiateAcc') + completeAccTemplate = eval(exec_template_base + 'CompleteAcc') # (header_output, decoder_output, decode_block, exec_output) return (LoadStoreDeclare.subst(iop), LoadStoreConstructor.subst(iop), decode_template.subst(iop), EACompExecute.subst(ea_iop) + memAccExecTemplate.subst(memacc_iop) - + fullExecTemplate.subst(iop)) + + fullExecTemplate.subst(iop) + + initiateAccTemplate.subst(iop) + + completeAccTemplate.subst(iop)) }}; diff --git a/arch/isa_parser.py b/arch/isa_parser.py index 030bb5a7c..96d3e8438 100755 --- a/arch/isa_parser.py +++ b/arch/isa_parser.py @@ -1138,6 +1138,7 @@ class Operand(object): # template must be careful not to use it if it doesn't apply. if self.isMem(): self.mem_acc_size = self.makeAccSize() + self.mem_acc_type = self.ctype # Finalize additional fields (primarily code fields). This step # is done separately since some of these fields may depend on the @@ -1148,15 +1149,23 @@ class Operand(object): self.constructor = self.makeConstructor() self.op_decl = self.makeDecl() + if self.isMem(): + self.is_src = '' + self.is_dest = '' + if self.is_src: self.op_rd = self.makeRead() + self.op_src_decl = self.makeDecl() else: self.op_rd = '' + self.op_src_decl = '' if self.is_dest: self.op_wb = self.makeWrite() + self.op_dest_decl = self.makeDecl() else: self.op_wb = '' + self.op_dest_decl = '' def isMem(self): return 0 @@ -1589,6 +1598,14 @@ class CodeBlock: self.op_decl = self.operands.concatAttrStrings('op_decl') + is_src = lambda op: op.is_src + is_dest = lambda op: op.is_dest + + self.op_src_decl = \ + self.operands.concatSomeAttrStrings(is_src, 'op_src_decl') + self.op_dest_decl = \ + self.operands.concatSomeAttrStrings(is_dest, 'op_dest_decl') + self.op_rd = self.operands.concatAttrStrings('op_rd') self.op_wb = self.operands.concatAttrStrings('op_wb') @@ -1596,6 +1613,7 @@ class CodeBlock: if self.operands.memOperand: self.mem_acc_size = self.operands.memOperand.mem_acc_size + self.mem_acc_type = self.operands.memOperand.mem_acc_type # Make a basic guess on the operand class (function unit type). # These are good enough for most cases, and will be overridden From a0cdf213ab534838d9757a59639c371e9d2c9809 Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Wed, 15 Feb 2006 14:08:54 -0500 Subject: [PATCH 052/180] ... arch/mips/isa/base.isa: restore base.isa --HG-- extra : convert_revision : a551caae28f505b22bceae3297fc00b0fb6a0e23 --- arch/mips/isa/base.isa | 82 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 arch/mips/isa/base.isa diff --git a/arch/mips/isa/base.isa b/arch/mips/isa/base.isa new file mode 100644 index 000000000..b504f1906 --- /dev/null +++ b/arch/mips/isa/base.isa @@ -0,0 +1,82 @@ +//////////////////////////////////////////////////////////////////// +// +// Base class for sparc instructions, and some support functions +// + +output header {{ + /** + * Base class for all SPARC static instructions. + */ + class SparcStaticInst : public StaticInst + { + protected: + + // Constructor. + SparcStaticInst(const char *mnem, MachInst _machInst, OpClass __opClass) + : StaticInst(mnem, _machInst, __opClass) + { + } + + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; + }; + + bool passesCondition(struct {uint8_t c:1; uint8_t v:1; uint8_t z:1; uint8_t n:1} codes, uint8_t condition); +}}; + +output decoder {{ + + std::string SparcStaticInst::generateDisassembly(Addr pc, const SymbolTable *symtab) const + { + std::stringstream ss; + + ccprintf(ss, "%-10s ", mnemonic); + + // just print the first two source regs... if there's + // a third one, it's a read-modify-write dest (Rc), + // e.g. for CMOVxx + if(_numSrcRegs > 0) + { + printReg(ss, _srcRegIdx[0]); + } + if(_numSrcRegs > 1) + { + ss << ","; + printReg(ss, _srcRegIdx[1]); + } + + // just print the first dest... if there's a second one, + // it's generally implicit + if(_numDestRegs > 0) + { + if(_numSrcRegs > 0) + ss << ","; + printReg(ss, _destRegIdx[0]); + } + + return ss.str(); + } + + bool passesCondition(struct {uint8_t c:1; uint8_t v:1; uint8_t z:1; uint8_t n:1} codes, uint8_t condition) + { + switch(condition) + { + case 0b1000: return true; + case 0b0000: return false; + case 0b1001: return !codes.z; + case 0b0001: return codes.z; + case 0b1010: return !(codes.z | (codes.n ^ codes.v)); + case 0b0010: return codes.z | (codes.n ^ codes.v); + case 0b1011: return !(codes.n ^ codes.v); + case 0b0011: return (codes.n ^ codes.v); + case 0b1100: return !(codes.c | codes.z); + case 0b0100: return (codes.c | codes.z); + case 0b1101: return !codes.c; + case 0b0101: return codes.c; + case 0b1110: return !codes.n; + case 0b0110: return codes.n; + case 0b1111: return !codes.v; + case 0b0111: return codes.v; + } + } +}}; + From 10c79efe556697ebbed74c82214b5505b405da5b Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Thu, 16 Feb 2006 01:22:51 -0500 Subject: [PATCH 053/180] Changed the fault enum into a class, and fixed everything up to work with it. Next, the faults need to be pulled out of all the other code so that they are only used to communicate between the CPU and the ISA. SConscript: The new faults.cc file in sim allocates the system wide faults. When these faults are generated through a function interface in the ISA, this file may go away. arch/alpha/alpha_memory.cc: Changed Fault to Fault * and took the underscores out of fault names. arch/alpha/alpha_memory.hh: Changed Fault to Fault *. Also, added an include for the alpha faults. arch/alpha/ev5.cc: Changed the fault_addr array into a fault_addr function. Once all of the faults can be expected to have the same type, fault_addr can go away completely and the info it provided will come from the fault itself. Also, Fault was changed to Fault *, and underscores were taken out of fault names. arch/alpha/isa/decoder.isa: Changed Fault to Fault * and took the underscores out fault names. arch/alpha/isa/fp.isa: Changed Fault to Fault *, and took the underscores out of fault names. arch/alpha/isa/main.isa: Changed Fault to Fault *, removed underscores from fault names, and made an include of the alpha faults show up in all the generated files. arch/alpha/isa/mem.isa: Changed Fault to Fault * and removed underscores from fault names. arch/alpha/isa/unimp.isa: arch/alpha/isa/unknown.isa: cpu/exec_context.hh: cpu/ozone/cpu.hh: cpu/simple/cpu.cc: dev/alpha_console.cc: dev/ide_ctrl.cc: dev/isa_fake.cc: dev/pciconfigall.cc: dev/pcidev.cc: dev/pcidev.hh: dev/tsunami_cchip.cc: dev/tsunami_io.cc: dev/tsunami_pchip.cc: Changed Fault to Fault *, and removed underscores from fault names. arch/alpha/isa_traits.hh: Changed the include of arch/alpha/faults.hh to sim/faults.hh, since the alpha faults weren't needed. cpu/base_dyn_inst.cc: Changed Fault to Fault *, and removed underscores from fault names. This file probably shouldn't use the Unimplemented Opcode fault. cpu/base_dyn_inst.hh: Changed Fault to Fault * and took the underscores out of the fault names. cpu/exec_context.cc: cpu/o3/alpha_dyn_inst.hh: cpu/o3/alpha_dyn_inst_impl.hh: cpu/o3/fetch.hh: dev/alpha_console.hh: dev/baddev.hh: dev/ide_ctrl.hh: dev/isa_fake.hh: dev/ns_gige.hh: dev/pciconfigall.hh: dev/sinic.hh: dev/tsunami_cchip.hh: dev/tsunami_io.hh: dev/tsunami_pchip.hh: dev/uart.hh: dev/uart8250.hh: Changed Fault to Fault *. cpu/o3/alpha_cpu.hh: Changed Fault to Fault *, removed underscores from fault names. cpu/o3/alpha_cpu_impl.hh: Changed Fault to Fault *, removed underscores from fault names, and changed the fault_addr array to the fault_addr function. Once all faults are from the ISA, this function will probably go away. cpu/o3/commit_impl.hh: cpu/o3/fetch_impl.hh: dev/baddev.cc: Changed Fault to Fault *, and removed underscores from the fault names. cpu/o3/regfile.hh: Added an include for the alpha specific faults which will hopefully go away once the ipr stuff is moved, changed Fault to Fault *, and removed the underscores from fault names. cpu/simple/cpu.hh: Changed Fault to Fault * dev/ns_gige.cc: Changed Fault to Fault *, and removdd underscores from fault names. dev/sinic.cc: Changed Fault to Fault *, and removed the underscores from fault names. dev/uart8250.cc: Chanted Fault to Fault *, and removed underscores from fault names. kern/kernel_stats.cc: Removed underscores from fault names, and from NumFaults. kern/kernel_stats.hh: Changed the predeclaration of Fault from an enum to a class, and changd the "fault" function to work with the classes instead of the enum. Once there are no system wide faults anymore, this code will simplify back to something like it was originally. sim/faults.cc: This allocates the system wide faults. sim/faults.hh: This declares the system wide faults. sim/syscall_emul.cc: sim/syscall_emul.hh: Removed the underscores from fault names. --HG-- rename : arch/alpha/faults.cc => sim/faults.cc rename : arch/alpha/faults.hh => sim/faults.hh extra : convert_revision : 253d39258237333ae8ec4d8047367cb3ea68569d --- SConscript | 1 + arch/alpha/alpha_memory.cc | 38 +++++------ arch/alpha/alpha_memory.hh | 5 +- arch/alpha/ev5.cc | 81 ++++++++++------------- arch/alpha/faults.cc | 64 ++++++++++-------- arch/alpha/faults.hh | 120 +++++++++++++++++++++++++++------- arch/alpha/isa/decoder.isa | 26 ++++---- arch/alpha/isa/fp.isa | 26 ++++---- arch/alpha/isa/main.isa | 13 ++-- arch/alpha/isa/mem.isa | 62 +++++++++--------- arch/alpha/isa/unimp.isa | 8 +-- arch/alpha/isa/unknown.isa | 4 +- arch/alpha/isa_traits.hh | 3 +- cpu/base_dyn_inst.cc | 32 ++++----- cpu/base_dyn_inst.hh | 24 +++---- cpu/exec_context.cc | 2 +- cpu/exec_context.hh | 36 +++++----- cpu/o3/alpha_cpu.hh | 38 +++++------ cpu/o3/alpha_cpu_impl.hh | 26 ++++---- cpu/o3/alpha_dyn_inst.hh | 14 ++-- cpu/o3/alpha_dyn_inst_impl.hh | 8 +-- cpu/o3/commit_impl.hh | 4 +- cpu/o3/fetch.hh | 2 +- cpu/o3/fetch_impl.hh | 14 ++-- cpu/o3/regfile.hh | 19 +++--- cpu/ozone/cpu.hh | 54 +++++++-------- cpu/simple/cpu.cc | 78 +++++++++++----------- cpu/simple/cpu.hh | 16 ++--- dev/alpha_console.cc | 14 ++-- dev/alpha_console.hh | 4 +- dev/baddev.cc | 8 +-- dev/baddev.hh | 4 +- dev/ide_ctrl.cc | 14 ++-- dev/ide_ctrl.hh | 4 +- dev/isa_fake.cc | 16 ++--- dev/isa_fake.hh | 4 +- dev/ns_gige.cc | 14 ++-- dev/ns_gige.hh | 4 +- dev/pciconfigall.cc | 18 ++--- dev/pciconfigall.hh | 4 +- dev/pcidev.cc | 32 ++++----- dev/pcidev.hh | 40 ++++++------ dev/sinic.cc | 28 ++++---- dev/sinic.hh | 10 +-- dev/tsunami_cchip.cc | 68 +++++++++---------- dev/tsunami_cchip.hh | 4 +- dev/tsunami_io.cc | 70 ++++++++++---------- dev/tsunami_io.hh | 4 +- dev/tsunami_pchip.cc | 70 ++++++++++---------- dev/tsunami_pchip.hh | 4 +- dev/uart.hh | 4 +- dev/uart8250.cc | 8 +-- dev/uart8250.hh | 4 +- kern/kernel_stats.cc | 6 +- kern/kernel_stats.hh | 11 +++- sim/faults.cc | 36 ++++++++++ sim/faults.hh | 65 ++++++++++++++++++ sim/syscall_emul.cc | 10 +-- sim/syscall_emul.hh | 14 ++-- 59 files changed, 798 insertions(+), 616 deletions(-) create mode 100644 sim/faults.cc create mode 100644 sim/faults.hh diff --git a/SConscript b/SConscript index fc2e6ae0b..360f91b3a 100644 --- a/SConscript +++ b/SConscript @@ -209,6 +209,7 @@ base_sources = Split(''' sim/configfile.cc sim/debug.cc sim/eventq.cc + sim/faults.cc sim/main.cc sim/param.cc sim/profile.cc diff --git a/arch/alpha/alpha_memory.cc b/arch/alpha/alpha_memory.cc index 8dda4d9c4..615ce92a4 100644 --- a/arch/alpha/alpha_memory.cc +++ b/arch/alpha/alpha_memory.cc @@ -303,7 +303,7 @@ AlphaITB::fault(Addr pc, ExecContext *xc) const } -Fault +Fault * AlphaITB::translate(MemReqPtr &req) const { InternalProcReg *ipr = req->xc->regs.ipr; @@ -312,7 +312,7 @@ AlphaITB::translate(MemReqPtr &req) const // strip off PAL PC marker (lsb is 1) req->paddr = (req->vaddr & ~3) & PAddrImplMask; hits++; - return No_Fault; + return NoFault; } if (req->flags & PHYSICAL) { @@ -322,7 +322,7 @@ AlphaITB::translate(MemReqPtr &req) const if (!validVirtualAddress(req->vaddr)) { fault(req->vaddr, req->xc); acv++; - return ITB_Acv_Fault; + return ItbAcvFault; } @@ -339,7 +339,7 @@ AlphaITB::translate(MemReqPtr &req) const AlphaISA::mode_kernel) { fault(req->vaddr, req->xc); acv++; - return ITB_Acv_Fault; + return ItbAcvFault; } req->paddr = req->vaddr & PAddrImplMask; @@ -360,7 +360,7 @@ AlphaITB::translate(MemReqPtr &req) const if (!pte) { fault(req->vaddr, req->xc); misses++; - return ITB_Fault_Fault; + return ItbPageFault; } req->paddr = (pte->ppn << AlphaISA::PageShift) + @@ -371,7 +371,7 @@ AlphaITB::translate(MemReqPtr &req) const // instruction access fault fault(req->vaddr, req->xc); acv++; - return ITB_Acv_Fault; + return ItbAcvFault; } hits++; @@ -380,11 +380,11 @@ AlphaITB::translate(MemReqPtr &req) const // check that the physical address is ok (catch bad physical addresses) if (req->paddr & ~PAddrImplMask) - return Machine_Check_Fault; + return MachineCheckFault; checkCacheability(req); - return No_Fault; + return NoFault; } /////////////////////////////////////////////////////////////////////// @@ -493,7 +493,7 @@ AlphaDTB::fault(MemReqPtr &req, uint64_t flags) const } } -Fault +Fault * AlphaDTB::translate(MemReqPtr &req, bool write) const { RegFile *regs = &req->xc->regs; @@ -511,7 +511,7 @@ AlphaDTB::translate(MemReqPtr &req, bool write) const fault(req, write ? MM_STAT_WR_MASK : 0); DPRINTF(TLB, "Alignment Fault on %#x, size = %d", req->vaddr, req->size); - return Alignment_Fault; + return AlignmentFault; } if (pc & 0x1) { @@ -530,7 +530,7 @@ AlphaDTB::translate(MemReqPtr &req, bool write) const MM_STAT_ACV_MASK); if (write) { write_acv++; } else { read_acv++; } - return DTB_Fault_Fault; + return DtbPageFault; } // Check for "superpage" mapping @@ -547,7 +547,7 @@ AlphaDTB::translate(MemReqPtr &req, bool write) const fault(req, ((write ? MM_STAT_WR_MASK : 0) | MM_STAT_ACV_MASK)); if (write) { write_acv++; } else { read_acv++; } - return DTB_Acv_Fault; + return DtbAcvFault; } req->paddr = req->vaddr & PAddrImplMask; @@ -575,7 +575,7 @@ AlphaDTB::translate(MemReqPtr &req, bool write) const fault(req, (write ? MM_STAT_WR_MASK : 0) | MM_STAT_DTB_MISS_MASK); if (write) { write_misses++; } else { read_misses++; } - return (req->flags & VPTE) ? Pdtb_Miss_Fault : Ndtb_Miss_Fault; + return (req->flags & VPTE) ? (Fault *)PDtbMissFault : (Fault *)NDtbMissFault; } req->paddr = (pte->ppn << AlphaISA::PageShift) + @@ -588,25 +588,25 @@ AlphaDTB::translate(MemReqPtr &req, bool write) const MM_STAT_ACV_MASK | (pte->fonw ? MM_STAT_FONW_MASK : 0)); write_acv++; - return DTB_Fault_Fault; + return DtbPageFault; } if (pte->fonw) { fault(req, MM_STAT_WR_MASK | MM_STAT_FONW_MASK); write_acv++; - return DTB_Fault_Fault; + return DtbPageFault; } } else { if (!(pte->xre & MODE2MASK(mode))) { fault(req, MM_STAT_ACV_MASK | (pte->fonr ? MM_STAT_FONR_MASK : 0)); read_acv++; - return DTB_Acv_Fault; + return DtbAcvFault; } if (pte->fonr) { fault(req, MM_STAT_FONR_MASK); read_acv++; - return DTB_Fault_Fault; + return DtbPageFault; } } } @@ -619,11 +619,11 @@ AlphaDTB::translate(MemReqPtr &req, bool write) const // check that the physical address is ok (catch bad physical addresses) if (req->paddr & ~PAddrImplMask) - return Machine_Check_Fault; + return MachineCheckFault; checkCacheability(req); - return No_Fault; + return NoFault; } AlphaISA::PTE & diff --git a/arch/alpha/alpha_memory.hh b/arch/alpha/alpha_memory.hh index 788923434..849063f59 100644 --- a/arch/alpha/alpha_memory.hh +++ b/arch/alpha/alpha_memory.hh @@ -32,6 +32,7 @@ #include #include "arch/alpha/isa_traits.hh" +#include "arch/alpha/faults.hh" #include "base/statistics.hh" #include "mem/mem_req.hh" #include "sim/sim_object.hh" @@ -93,7 +94,7 @@ class AlphaITB : public AlphaTLB AlphaITB(const std::string &name, int size); virtual void regStats(); - Fault translate(MemReqPtr &req) const; + Fault * translate(MemReqPtr &req) const; }; class AlphaDTB : public AlphaTLB @@ -119,7 +120,7 @@ class AlphaDTB : public AlphaTLB AlphaDTB(const std::string &name, int size); virtual void regStats(); - Fault translate(MemReqPtr &req, bool write) const; + Fault * translate(MemReqPtr &req, bool write) const; }; #endif // __ALPHA_MEMORY_HH__ diff --git a/arch/alpha/ev5.cc b/arch/alpha/ev5.cc index 125affd03..9d14be4d5 100644 --- a/arch/alpha/ev5.cc +++ b/arch/alpha/ev5.cc @@ -76,7 +76,7 @@ AlphaISA::initCPU(RegFile *regs) // CPU comes up with PAL regs enabled swap_palshadow(regs, true); - regs->pc = regs->ipr[IPR_PAL_BASE] + fault_addr[Reset_Fault]; + regs->pc = regs->ipr[IPR_PAL_BASE] + fault_addr(ResetFault); regs->npc = regs->pc + sizeof(MachInst); } @@ -84,25 +84,16 @@ AlphaISA::initCPU(RegFile *regs) // // alpha exceptions - value equals trap address, update with MD_FAULT_TYPE // -Addr -AlphaISA::fault_addr[Num_Faults] = { - 0x0000, /* No_Fault */ - 0x0001, /* Reset_Fault */ - 0x0401, /* Machine_Check_Fault */ - 0x0501, /* Arithmetic_Fault */ - 0x0101, /* Interrupt_Fault */ - 0x0201, /* Ndtb_Miss_Fault */ - 0x0281, /* Pdtb_Miss_Fault */ - 0x0301, /* Alignment_Fault */ - 0x0381, /* DTB_Fault_Fault */ - 0x0381, /* DTB_Acv_Fault */ - 0x0181, /* ITB_Miss_Fault */ - 0x0181, /* ITB_Fault_Fault */ - 0x0081, /* ITB_Acv_Fault */ - 0x0481, /* Unimplemented_Opcode_Fault */ - 0x0581, /* Fen_Fault */ - 0x2001, /* Pal_Fault */ - 0x0501, /* Integer_Overflow_Fault: maps to Arithmetic_Fault */ +const Addr +AlphaISA::fault_addr(Fault * fault) +{ + //Check for the system wide faults + if(fault == NoFault) return 0x0000; + else if(fault == MachineCheckFault) return 0x0401; + else if(fault == AlignmentFault) return 0x0301; + else if(fault == FakeMemFault) return 0x0000; + //Deal with the alpha specific faults + return ((AlphaFault*)fault)->vect; }; const int AlphaISA::reg_redir[AlphaISA::NumIntRegs] = { @@ -168,7 +159,7 @@ AlphaISA::processInterrupts(CPU *cpu) if (ipl && ipl > ipr[IPR_IPLR]) { ipr[IPR_ISR] = summary; ipr[IPR_INTID] = ipl; - cpu->trap(Interrupt_Fault); + cpu->trap(InterruptFault); DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n", ipr[IPR_IPLR], ipl, summary); } @@ -187,25 +178,25 @@ AlphaISA::zeroRegisters(CPU *cpu) } void -ExecContext::ev5_trap(Fault fault) +ExecContext::ev5_trap(Fault * fault) { - DPRINTF(Fault, "Fault %s at PC: %#x\n", FaultName(fault), regs.pc); - cpu->recordEvent(csprintf("Fault %s", FaultName(fault))); + DPRINTF(Fault, "Fault %s at PC: %#x\n", fault ? fault->name : "none", regs.pc); + cpu->recordEvent(csprintf("Fault %s", fault ? fault->name : "none")); assert(!misspeculating()); kernelStats->fault(fault); - if (fault == Arithmetic_Fault) + if (fault == ArithmeticFault) panic("Arithmetic traps are unimplemented!"); AlphaISA::InternalProcReg *ipr = regs.ipr; // exception restart address - if (fault != Interrupt_Fault || !inPalMode()) + if (fault != InterruptFault || !inPalMode()) ipr[AlphaISA::IPR_EXC_ADDR] = regs.pc; - if (fault == Pal_Fault || fault == Arithmetic_Fault /* || - fault == Interrupt_Fault && !inPalMode() */) { + if (fault == PalFault || fault == ArithmeticFault /* || + fault == InterruptFault && !inPalMode() */) { // traps... skip faulting instruction ipr[AlphaISA::IPR_EXC_ADDR] += 4; } @@ -213,22 +204,22 @@ ExecContext::ev5_trap(Fault fault) if (!inPalMode()) AlphaISA::swap_palshadow(®s, true); - regs.pc = ipr[AlphaISA::IPR_PAL_BASE] + AlphaISA::fault_addr[fault]; + regs.pc = ipr[AlphaISA::IPR_PAL_BASE] + AlphaISA::fault_addr(fault); regs.npc = regs.pc + sizeof(MachInst); } void -AlphaISA::intr_post(RegFile *regs, Fault fault, Addr pc) +AlphaISA::intr_post(RegFile *regs, Fault * fault, Addr pc) { InternalProcReg *ipr = regs->ipr; - bool use_pc = (fault == No_Fault); + bool use_pc = (fault == NoFault); - if (fault == Arithmetic_Fault) + if (fault == ArithmeticFault) panic("arithmetic faults NYI..."); // compute exception restart address - if (use_pc || fault == Pal_Fault || fault == Arithmetic_Fault) { + if (use_pc || fault == PalFault || fault == ArithmeticFault) { // traps... skip faulting instruction ipr[IPR_EXC_ADDR] = regs->pc + 4; } else { @@ -238,20 +229,20 @@ AlphaISA::intr_post(RegFile *regs, Fault fault, Addr pc) // jump to expection address (PAL PC bit set here as well...) if (!use_pc) - regs->npc = ipr[IPR_PAL_BASE] + fault_addr[fault]; + regs->npc = ipr[IPR_PAL_BASE] + fault_addr(fault); else regs->npc = ipr[IPR_PAL_BASE] + pc; // that's it! (orders of magnitude less painful than x86) } -Fault +Fault * ExecContext::hwrei() { uint64_t *ipr = regs.ipr; if (!inPalMode()) - return Unimplemented_Opcode_Fault; + return UnimplementedOpcodeFault; setNextPC(ipr[AlphaISA::IPR_EXC_ADDR]); @@ -265,11 +256,11 @@ ExecContext::hwrei() } // FIXME: XXX check for interrupts? XXX - return No_Fault; + return NoFault; } uint64_t -ExecContext::readIpr(int idx, Fault &fault) +ExecContext::readIpr(int idx, Fault * &fault) { uint64_t *ipr = regs.ipr; uint64_t retval = 0; // return value, default 0 @@ -363,12 +354,12 @@ ExecContext::readIpr(int idx, Fault &fault) case AlphaISA::IPR_DTB_IAP: case AlphaISA::IPR_ITB_IA: case AlphaISA::IPR_ITB_IAP: - fault = Unimplemented_Opcode_Fault; + fault = UnimplementedOpcodeFault; break; default: // invalid IPR - fault = Unimplemented_Opcode_Fault; + fault = UnimplementedOpcodeFault; break; } @@ -380,14 +371,14 @@ ExecContext::readIpr(int idx, Fault &fault) int break_ipl = -1; #endif -Fault +Fault * ExecContext::setIpr(int idx, uint64_t val) { uint64_t *ipr = regs.ipr; uint64_t old; if (misspeculating()) - return No_Fault; + return NoFault; switch (idx) { case AlphaISA::IPR_PALtemp0: @@ -533,7 +524,7 @@ ExecContext::setIpr(int idx, uint64_t val) case AlphaISA::IPR_ITB_PTE_TEMP: case AlphaISA::IPR_DTB_PTE_TEMP: // read-only registers - return Unimplemented_Opcode_Fault; + return UnimplementedOpcodeFault; case AlphaISA::IPR_HWINT_CLR: case AlphaISA::IPR_SL_XMIT: @@ -635,11 +626,11 @@ ExecContext::setIpr(int idx, uint64_t val) default: // invalid IPR - return Unimplemented_Opcode_Fault; + return UnimplementedOpcodeFault; } // no error... - return No_Fault; + return NoFault; } /** diff --git a/arch/alpha/faults.cc b/arch/alpha/faults.cc index 3aecf029d..2dc3d9cbb 100644 --- a/arch/alpha/faults.cc +++ b/arch/alpha/faults.cc @@ -28,34 +28,40 @@ #include "arch/alpha/faults.hh" -namespace { - const char * - fault_name[Num_Faults] = { - "none", - "reset", - "mchk", - "arith", - "interrupt", - "dtb_miss_single", - "dtb_miss_double", - "unalign", - "dfault", - "dfault", - "itbmiss", - "itbmiss", - "iaccvio", - "opdec", - "fen", - "pal", - }; -} +ResetFaultType * ResetFault = new ResetFaultType("reset", 1, 0x0001); +ArithmeticFaultType * ArithmeticFault = new ArithmeticFaultType("arith", 3, 0x0501); +InterruptFaultType * InterruptFault = new InterruptFaultType("interrupt", 4, 0x0101); +NDtbMissFaultType * NDtbMissFault = new NDtbMissFaultType("dtb_miss_single", 5, 0x0201); +PDtbMissFaultType * PDtbMissFault = new PDtbMissFaultType("dtb_miss_double", 6, 0x0281); +DtbPageFaultType * DtbPageFault = new DtbPageFaultType("dfault", 8, 0x0381); +DtbAcvFaultType * DtbAcvFault = new DtbAcvFaultType("dfault", 9, 0x0381); +ItbMissFaultType * ItbMissFault = new ItbMissFaultType("itbmiss", 10, 0x0181); +ItbPageFaultType * ItbPageFault = new ItbPageFaultType("itbmiss", 11, 0x0181); +ItbAcvFaultType * ItbAcvFault = new ItbAcvFaultType("iaccvio", 12, 0x0081); +UnimplementedOpcodeFaultType * UnimplementedOpcodeFault = new UnimplementedOpcodeFaultType("opdec", 13, 0x0481); +FloatEnableFaultType * FloatEnableFault = new FloatEnableFaultType("fen", 14, 0x0581); +PalFaultType * PalFault = new PalFaultType("pal", 15, 0x2001); +IntegerOverflowFaultType * IntegerOverflowFault = new IntegerOverflowFaultType("intover", 16, 0x0501); -const char * -FaultName(int index) -{ - if (index < 0 || index >= Num_Faults) - return 0; - - return fault_name[index]; -} +Fault ** ListOfFaults[] = { + (Fault **)&NoFault, + (Fault **)&ResetFault, + (Fault **)&MachineCheckFault, + (Fault **)&ArithmeticFault, + (Fault **)&InterruptFault, + (Fault **)&NDtbMissFault, + (Fault **)&PDtbMissFault, + (Fault **)&AlignmentFault, + (Fault **)&DtbPageFault, + (Fault **)&DtbAcvFault, + (Fault **)&ItbMissFault, + (Fault **)&ItbPageFault, + (Fault **)&ItbAcvFault, + (Fault **)&UnimplementedOpcodeFault, + (Fault **)&FloatEnableFault, + (Fault **)&PalFault, + (Fault **)&IntegerOverflowFault, + (Fault **)&FakeMemFault + }; +int NumFaults = sizeof(ListOfFaults) / sizeof(Fault **); diff --git a/arch/alpha/faults.hh b/arch/alpha/faults.hh index bbac7cbf2..2bb929a1e 100644 --- a/arch/alpha/faults.hh +++ b/arch/alpha/faults.hh @@ -26,32 +26,104 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef __FAULTS_HH__ -#define __FAULTS_HH__ +#ifndef __ALPHA_FAULTS_HH__ +#define __ALPHA_FAULTS_HH__ -enum Fault { - No_Fault, - Reset_Fault, // processor reset - Machine_Check_Fault, // machine check (also internal S/W fault) - Arithmetic_Fault, // FP exception - Interrupt_Fault, // external interrupt - Ndtb_Miss_Fault, // DTB miss - Pdtb_Miss_Fault, // nested DTB miss - Alignment_Fault, // unaligned access - DTB_Fault_Fault, // DTB page fault - DTB_Acv_Fault, // DTB access violation - ITB_Miss_Fault, // ITB miss - ITB_Fault_Fault, // ITB page fault - ITB_Acv_Fault, // ITB access violation - Unimplemented_Opcode_Fault, // invalid/unimplemented instruction - Fen_Fault, // FP not-enabled fault - Pal_Fault, // call_pal S/W interrupt - Integer_Overflow_Fault, - Fake_Mem_Fault, - Num_Faults // number of faults +#include "sim/faults.hh" +#include "arch/isa_traits.hh" //For the Addr type + +class AlphaFault : public Fault +{ +public: + AlphaFault(char * newName, int newId, Addr newVect) : Fault(newName, newId), vect(newVect) {;} + TheISA::Addr vect; }; -const char * -FaultName(int index); +extern class ResetFaultType : public AlphaFault +{ +public: + ResetFaultType(char * newName, int newId, Addr newVect) : AlphaFault(newName, newId, newVect) {;} +} * ResetFault; + +extern class ArithmeticFaultType : public AlphaFault +{ +public: + ArithmeticFaultType(char * newName, int newId, Addr newVect) : AlphaFault(newName, newId, newVect) {;} +} * ArithmeticFault; + +extern class InterruptFaultType : public AlphaFault +{ +public: + InterruptFaultType(char * newName, int newId, Addr newVect) : AlphaFault(newName, newId, newVect) {;} +} * InterruptFault; + +extern class NDtbMissFaultType : public AlphaFault +{ +public: + NDtbMissFaultType(char * newName, int newId, Addr newVect) : AlphaFault(newName, newId, newVect) {;} +} * NDtbMissFault; + +extern class PDtbMissFaultType : public AlphaFault +{ +public: + PDtbMissFaultType(char * newName, int newId, Addr newVect) : AlphaFault(newName, newId, newVect) {;} +} * PDtbMissFault; + +extern class DtbPageFaultType : public AlphaFault +{ +public: + DtbPageFaultType(char * newName, int newId, Addr newVect) : AlphaFault(newName, newId, newVect) {;} +} * DtbPageFault; + +extern class DtbAcvFaultType : public AlphaFault +{ +public: + DtbAcvFaultType(char * newName, int newId, Addr newVect) : AlphaFault(newName, newId, newVect) {;} +} * DtbAcvFault; + +extern class ItbMissFaultType : public AlphaFault +{ +public: + ItbMissFaultType(char * newName, int newId, Addr newVect) : AlphaFault(newName, newId, newVect) {;} +} * ItbMissFault; + +extern class ItbPageFaultType : public AlphaFault +{ +public: + ItbPageFaultType(char * newName, int newId, Addr newVect) : AlphaFault(newName, newId, newVect) {;} +} * ItbPageFault; + +extern class ItbAcvFaultType : public AlphaFault +{ +public: + ItbAcvFaultType(char * newName, int newId, Addr newVect) : AlphaFault(newName, newId, newVect) {;} +} * ItbAcvFault; + +extern class UnimplementedOpcodeFaultType : public AlphaFault +{ +public: + UnimplementedOpcodeFaultType(char * newName, int newId, Addr newVect) : AlphaFault(newName, newId, newVect) {;} +} * UnimplementedOpcodeFault; + +extern class FloatEnableFaultType : public AlphaFault +{ +public: + FloatEnableFaultType(char * newName, int newId, Addr newVect) : AlphaFault(newName, newId, newVect) {;} +} * FloatEnableFault; + +extern class PalFaultType : public AlphaFault +{ +public: + PalFaultType(char * newName, int newId, Addr newVect) : AlphaFault(newName, newId, newVect) {;} +} * PalFault; + +extern class IntegerOverflowFaultType : public AlphaFault +{ +public: + IntegerOverflowFaultType(char * newName, int newId, Addr newVect) : AlphaFault(newName, newId, newVect) {;} +} * IntegerOverflowFault; + +extern Fault ** ListOfFaults[]; +extern int NumFaults; #endif // __FAULTS_HH__ diff --git a/arch/alpha/isa/decoder.isa b/arch/alpha/isa/decoder.isa index aff8571e9..37b15416b 100644 --- a/arch/alpha/isa/decoder.isa +++ b/arch/alpha/isa/decoder.isa @@ -98,7 +98,7 @@ decode OPCODE default Unknown::unknown() { // signed overflow occurs when operands have same sign // and sign of result does not match. if (Ra.sl<31:> == Rb_or_imm.sl<31:> && tmp<31:> != Ra.sl<31:>) - fault = Integer_Overflow_Fault; + fault = IntegerOverflowFault; Rc.sl = tmp; }}); 0x02: s4addl({{ Rc.sl = (Ra.sl << 2) + Rb_or_imm.sl; }}); @@ -110,7 +110,7 @@ decode OPCODE default Unknown::unknown() { // signed overflow occurs when operands have same sign // and sign of result does not match. if (Ra<63:> == Rb_or_imm<63:> && tmp<63:> != Ra<63:>) - fault = Integer_Overflow_Fault; + fault = IntegerOverflowFault; Rc = tmp; }}); 0x22: s4addq({{ Rc = (Ra << 2) + Rb_or_imm; }}); @@ -124,7 +124,7 @@ decode OPCODE default Unknown::unknown() { // sign bit of the subtrahend (Rb), i.e., if the initial // signs are the *same* then no overflow can occur if (Ra.sl<31:> != Rb_or_imm.sl<31:> && tmp<31:> != Ra.sl<31:>) - fault = Integer_Overflow_Fault; + fault = IntegerOverflowFault; Rc.sl = tmp; }}); 0x0b: s4subl({{ Rc.sl = (Ra.sl << 2) - Rb_or_imm.sl; }}); @@ -138,7 +138,7 @@ decode OPCODE default Unknown::unknown() { // sign bit of the subtrahend (Rb), i.e., if the initial // signs are the *same* then no overflow can occur if (Ra<63:> != Rb_or_imm<63:> && tmp<63:> != Ra<63:>) - fault = Integer_Overflow_Fault; + fault = IntegerOverflowFault; Rc = tmp; }}); 0x2b: s4subq({{ Rc = (Ra << 2) - Rb_or_imm; }}); @@ -299,7 +299,7 @@ decode OPCODE default Unknown::unknown() { // checking the upper 33 bits for all 0s or all 1s. uint64_t sign_bits = tmp<63:31>; if (sign_bits != 0 && sign_bits != mask(33)) - fault = Integer_Overflow_Fault; + fault = IntegerOverflowFault; Rc.sl = tmp<31:0>; }}, IntMultOp); 0x60: mulqv({{ @@ -310,7 +310,7 @@ decode OPCODE default Unknown::unknown() { // the lower 64 if (!((hi == 0 && lo<63:> == 0) || (hi == mask(64) && lo<63:> == 1))) - fault = Integer_Overflow_Fault; + fault = IntegerOverflowFault; Rc = lo; }}, IntMultOp); } @@ -427,19 +427,19 @@ decode OPCODE default Unknown::unknown() { #if SS_COMPATIBLE_FP 0x0b: sqrts({{ if (Fb < 0.0) - fault = Arithmetic_Fault; + fault = ArithmeticFault; Fc = sqrt(Fb); }}, FloatSqrtOp); #else 0x0b: sqrts({{ if (Fb.sf < 0.0) - fault = Arithmetic_Fault; + fault = ArithmeticFault; Fc.sf = sqrt(Fb.sf); }}, FloatSqrtOp); #endif 0x2b: sqrtt({{ if (Fb < 0.0) - fault = Arithmetic_Fault; + fault = ArithmeticFault; Fc = sqrt(Fb); }}, FloatSqrtOp); } @@ -570,7 +570,7 @@ decode OPCODE default Unknown::unknown() { // checking the upper 33 bits for all 0s or all 1s. uint64_t sign_bits = Fb.uq<63:31>; if (sign_bits != 0 && sign_bits != mask(33)) - fault = Integer_Overflow_Fault; + fault = IntegerOverflowFault; Fc.uq = (Fb.uq<31:30> << 62) | (Fb.uq<29:0> << 29); }}); @@ -673,7 +673,7 @@ decode OPCODE default Unknown::unknown() { && xc->readIpr(AlphaISA::IPR_ICM, fault) != AlphaISA::mode_kernel)) { // invalid pal function code, or attempt to do privileged // PAL call in non-kernel mode - fault = Unimplemented_Opcode_Fault; + fault = UnimplementedOpcodeFault; } else { // check to see if simulator wants to do something special @@ -729,7 +729,7 @@ decode OPCODE default Unknown::unknown() { 0x19: hw_mfpr({{ // this instruction is only valid in PAL mode if (!xc->inPalMode()) { - fault = Unimplemented_Opcode_Fault; + fault = UnimplementedOpcodeFault; } else { Ra = xc->readIpr(ipr_index, fault); @@ -738,7 +738,7 @@ decode OPCODE default Unknown::unknown() { 0x1d: hw_mtpr({{ // this instruction is only valid in PAL mode if (!xc->inPalMode()) { - fault = Unimplemented_Opcode_Fault; + fault = UnimplementedOpcodeFault; } else { xc->setIpr(ipr_index, Ra); diff --git a/arch/alpha/isa/fp.isa b/arch/alpha/isa/fp.isa index 0abc814be..c718c5524 100644 --- a/arch/alpha/isa/fp.isa +++ b/arch/alpha/isa/fp.isa @@ -29,21 +29,21 @@ output exec {{ /// Check "FP enabled" machine status bit. Called when executing any FP /// instruction in full-system mode. - /// @retval Full-system mode: No_Fault if FP is enabled, Fen_Fault - /// if not. Non-full-system mode: always returns No_Fault. + /// @retval Full-system mode: NoFault if FP is enabled, FenFault + /// if not. Non-full-system mode: always returns NoFault. #if FULL_SYSTEM - inline Fault checkFpEnableFault(%(CPU_exec_context)s *xc) + inline Fault * checkFpEnableFault(%(CPU_exec_context)s *xc) { - Fault fault = No_Fault; // dummy... this ipr access should not fault + Fault * fault = NoFault; // dummy... this ipr access should not fault if (!EV5::ICSR_FPE(xc->readIpr(AlphaISA::IPR_ICSR, fault))) { - fault = Fen_Fault; + fault = FloatEnableFault; } return fault; } #else - inline Fault checkFpEnableFault(%(CPU_exec_context)s *xc) + inline Fault * checkFpEnableFault(%(CPU_exec_context)s *xc) { - return No_Fault; + return NoFault; } #endif }}; @@ -199,7 +199,7 @@ output decoder {{ // FP instruction class execute method template. Handles non-standard // rounding modes. def template FloatingPointExecute {{ - Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, + Fault * %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const { if (trappingMode != Imprecise && !warnedOnTrapping) { @@ -208,7 +208,7 @@ def template FloatingPointExecute {{ warnedOnTrapping = true; } - Fault fault = No_Fault; + Fault * fault = NoFault; %(fp_enable_check)s; %(op_decl)s; @@ -230,7 +230,7 @@ def template FloatingPointExecute {{ %(code)s; #endif - if (fault == No_Fault) { + if (fault == NoFault) { %(op_wb)s; } @@ -242,7 +242,7 @@ def template FloatingPointExecute {{ // rounding mode control is needed. Like BasicExecute, but includes // check & warning for non-standard trapping mode. def template FPFixedRoundingExecute {{ - Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, + Fault * %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const { if (trappingMode != Imprecise && !warnedOnTrapping) { @@ -251,14 +251,14 @@ def template FPFixedRoundingExecute {{ warnedOnTrapping = true; } - Fault fault = No_Fault; + Fault * fault = NoFault; %(fp_enable_check)s; %(op_decl)s; %(op_rd)s; %(code)s; - if (fault == No_Fault) { + if (fault == NoFault) { %(op_wb)s; } diff --git a/arch/alpha/isa/main.isa b/arch/alpha/isa/main.isa index a2860f17b..baf2f2658 100644 --- a/arch/alpha/isa/main.isa +++ b/arch/alpha/isa/main.isa @@ -33,6 +33,7 @@ output header {{ #include "config/ss_compatible_fp.hh" #include "cpu/static_inst.hh" +#include "arch/alpha/faults.hh" #include "mem/mem_req.hh" // some constructors use MemReq flags }}; @@ -253,7 +254,7 @@ output decoder {{ // Declarations for execute() methods. def template BasicExecDeclare {{ - Fault execute(%(CPU_exec_context)s *, Trace::InstRecord *) const; + Fault * execute(%(CPU_exec_context)s *, Trace::InstRecord *) const; }}; // Basic instruction class declaration template. @@ -282,17 +283,17 @@ def template BasicConstructor {{ // Basic instruction class execute method template. def template BasicExecute {{ - Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, + Fault * %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const { - Fault fault = No_Fault; + Fault * fault = NoFault; %(fp_enable_check)s; %(op_decl)s; %(op_rd)s; %(code)s; - if (fault == No_Fault) { + if (fault == NoFault) { %(op_wb)s; } @@ -377,10 +378,10 @@ output decoder {{ }}; output exec {{ - Fault + Fault * Nop::execute(%(CPU_exec_context)s *, Trace::InstRecord *) const { - return No_Fault; + return NoFault; } }}; diff --git a/arch/alpha/isa/mem.isa b/arch/alpha/isa/mem.isa index 45afd378c..1f6907181 100644 --- a/arch/alpha/isa/mem.isa +++ b/arch/alpha/isa/mem.isa @@ -193,19 +193,19 @@ def template LoadStoreConstructor {{ def template EACompExecute {{ - Fault + Fault * %(class_name)s::EAComp::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const { Addr EA; - Fault fault = No_Fault; + Fault * fault = NoFault; %(fp_enable_check)s; %(op_decl)s; %(op_rd)s; %(code)s; - if (fault == No_Fault) { + if (fault == NoFault) { %(op_wb)s; xc->setEA(EA); } @@ -215,24 +215,24 @@ def template EACompExecute {{ }}; def template LoadMemAccExecute {{ - Fault + Fault * %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const { Addr EA; - Fault fault = No_Fault; + Fault * fault = NoFault; %(fp_enable_check)s; %(op_decl)s; %(op_rd)s; EA = xc->getEA(); - if (fault == No_Fault) { + if (fault == NoFault) { fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags); %(code)s; } - if (fault == No_Fault) { + if (fault == NoFault) { %(op_wb)s; } @@ -242,23 +242,23 @@ def template LoadMemAccExecute {{ def template LoadExecute {{ - Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, + Fault * %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const { Addr EA; - Fault fault = No_Fault; + Fault * fault = NoFault; %(fp_enable_check)s; %(op_decl)s; %(op_rd)s; %(ea_code)s; - if (fault == No_Fault) { + if (fault == NoFault) { fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags); %(memacc_code)s; } - if (fault == No_Fault) { + if (fault == NoFault) { %(op_wb)s; } @@ -268,12 +268,12 @@ def template LoadExecute {{ def template StoreMemAccExecute {{ - Fault + Fault * %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const { Addr EA; - Fault fault = No_Fault; + Fault * fault = NoFault; uint64_t write_result = 0; %(fp_enable_check)s; @@ -281,21 +281,21 @@ def template StoreMemAccExecute {{ %(op_rd)s; EA = xc->getEA(); - if (fault == No_Fault) { + if (fault == NoFault) { %(code)s; } - if (fault == No_Fault) { + if (fault == NoFault) { fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, memAccessFlags, &write_result); if (traceData) { traceData->setData(Mem); } } - if (fault == No_Fault) { + if (fault == NoFault) { %(postacc_code)s; } - if (fault == No_Fault) { + if (fault == NoFault) { %(op_wb)s; } @@ -305,11 +305,11 @@ def template StoreMemAccExecute {{ def template StoreExecute {{ - Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, + Fault * %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const { Addr EA; - Fault fault = No_Fault; + Fault * fault = NoFault; uint64_t write_result = 0; %(fp_enable_check)s; @@ -317,21 +317,21 @@ def template StoreExecute {{ %(op_rd)s; %(ea_code)s; - if (fault == No_Fault) { + if (fault == NoFault) { %(memacc_code)s; } - if (fault == No_Fault) { + if (fault == NoFault) { fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, memAccessFlags, &write_result); if (traceData) { traceData->setData(Mem); } } - if (fault == No_Fault) { + if (fault == NoFault) { %(postacc_code)s; } - if (fault == No_Fault) { + if (fault == NoFault) { %(op_wb)s; } @@ -341,42 +341,42 @@ def template StoreExecute {{ def template MiscMemAccExecute {{ - Fault %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc, + Fault * %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const { Addr EA; - Fault fault = No_Fault; + Fault * fault = NoFault; %(fp_enable_check)s; %(op_decl)s; %(op_rd)s; EA = xc->getEA(); - if (fault == No_Fault) { + if (fault == NoFault) { %(code)s; } - return No_Fault; + return NoFault; } }}; def template MiscExecute {{ - Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, + Fault * %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const { Addr EA; - Fault fault = No_Fault; + Fault * fault = NoFault; %(fp_enable_check)s; %(op_decl)s; %(op_rd)s; %(ea_code)s; - if (fault == No_Fault) { + if (fault == NoFault) { %(memacc_code)s; } - return No_Fault; + return NoFault; } }}; diff --git a/arch/alpha/isa/unimp.isa b/arch/alpha/isa/unimp.isa index 767888157..ce8197708 100644 --- a/arch/alpha/isa/unimp.isa +++ b/arch/alpha/isa/unimp.isa @@ -105,16 +105,16 @@ output decoder {{ }}; output exec {{ - Fault + Fault * FailUnimplemented::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const { panic("attempt to execute unimplemented instruction '%s' " "(inst 0x%08x, opcode 0x%x)", mnemonic, machInst, OPCODE); - return Unimplemented_Opcode_Fault; + return UnimplementedOpcodeFault; } - Fault + Fault * WarnUnimplemented::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const { @@ -123,7 +123,7 @@ output exec {{ warned = true; } - return No_Fault; + return NoFault; } }}; diff --git a/arch/alpha/isa/unknown.isa b/arch/alpha/isa/unknown.isa index 6eba5b4f9..e7f8bc8db 100644 --- a/arch/alpha/isa/unknown.isa +++ b/arch/alpha/isa/unknown.isa @@ -36,13 +36,13 @@ output decoder {{ }}; output exec {{ - Fault + Fault * Unknown::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const { panic("attempt to execute unknown instruction " "(inst 0x%08x, opcode 0x%x)", machInst, OPCODE); - return Unimplemented_Opcode_Fault; + return UnimplementedOpcodeFault; } }}; diff --git a/arch/alpha/isa_traits.hh b/arch/alpha/isa_traits.hh index a17cde49b..a6e34acbb 100644 --- a/arch/alpha/isa_traits.hh +++ b/arch/alpha/isa_traits.hh @@ -32,10 +32,11 @@ namespace LittleEndianGuest {} using namespace LittleEndianGuest; -#include "arch/alpha/faults.hh" +//#include "arch/alpha/faults.hh" #include "base/misc.hh" #include "config/full_system.hh" #include "sim/host.hh" +#include "sim/faults.hh" class FastCPU; class FullCPU; diff --git a/cpu/base_dyn_inst.cc b/cpu/base_dyn_inst.cc index d921bd148..59a12f2d0 100644 --- a/cpu/base_dyn_inst.cc +++ b/cpu/base_dyn_inst.cc @@ -113,7 +113,7 @@ BaseDynInst::initVars() asid = 0; // Initialize the fault to be unimplemented opcode. - fault = Unimplemented_Opcode_Fault; + fault = UnimplementedOpcodeFault; ++instcount; @@ -142,12 +142,12 @@ BaseDynInst::prefetch(Addr addr, unsigned flags) req->asid = asid; // Prefetches never cause faults. - fault = No_Fault; + fault = NoFault; // note this is a local, not BaseDynInst::fault - Fault trans_fault = xc->translateDataReadReq(req); + Fault * trans_fault = xc->translateDataReadReq(req); - if (trans_fault == No_Fault && !(req->flags & UNCACHEABLE)) { + if (trans_fault == NoFault && !(req->flags & UNCACHEABLE)) { // It's a valid address to cacheable space. Record key MemReq // parameters so we can generate another one just like it for // the timing access without calling translate() again (which @@ -188,7 +188,7 @@ BaseDynInst::writeHint(Addr addr, int size, unsigned flags) fault = xc->translateDataWriteReq(req); - if (fault == No_Fault && !(req->flags & UNCACHEABLE)) { + if (fault == NoFault && !(req->flags & UNCACHEABLE)) { // Record key MemReq parameters so we can generate another one // just like it for the timing access without calling translate() // again (which might mess up the TLB). @@ -208,16 +208,16 @@ BaseDynInst::writeHint(Addr addr, int size, unsigned flags) * @todo Need to find a way to get the cache block size here. */ template -Fault +Fault * BaseDynInst::copySrcTranslate(Addr src) { MemReqPtr req = new MemReq(src, xc, 64); req->asid = asid; // translate to physical address - Fault fault = xc->translateDataReadReq(req); + Fault * fault = xc->translateDataReadReq(req); - if (fault == No_Fault) { + if (fault == NoFault) { xc->copySrcAddr = src; xc->copySrcPhysAddr = req->paddr; } else { @@ -231,7 +231,7 @@ BaseDynInst::copySrcTranslate(Addr src) * @todo Need to find a way to get the cache block size here. */ template -Fault +Fault * BaseDynInst::copy(Addr dest) { uint8_t data[64]; @@ -241,9 +241,9 @@ BaseDynInst::copy(Addr dest) req->asid = asid; // translate to physical address - Fault fault = xc->translateDataWriteReq(req); + Fault * fault = xc->translateDataWriteReq(req); - if (fault == No_Fault) { + if (fault == NoFault) { Addr dest_addr = req->paddr; // Need to read straight from memory since we have more than 8 bytes. req->paddr = xc->copySrcPhysAddr; @@ -277,10 +277,10 @@ BaseDynInst::dump(std::string &outstring) #if 0 template -Fault +Fault * BaseDynInst::mem_access(mem_cmd cmd, Addr addr, void *p, int nbytes) { - Fault fault; + Fault * fault; // check alignments, even speculative this test should always pass if ((nbytes & nbytes - 1) != 0 || (addr & nbytes - 1) != 0) { @@ -292,7 +292,7 @@ BaseDynInst::mem_access(mem_cmd cmd, Addr addr, void *p, int nbytes) #if 0 panic("unaligned access. Cycle = %n", curTick); #endif - return No_Fault; + return NoFault; } MemReqPtr req = new MemReq(addr, thread, nbytes); @@ -303,7 +303,7 @@ BaseDynInst::mem_access(mem_cmd cmd, Addr addr, void *p, int nbytes) case Write: fault = spec_mem->write(req, (uint8_t *)p); - if (fault != No_Fault) + if (fault != NoFault) break; specMemWrite = true; @@ -325,7 +325,7 @@ BaseDynInst::mem_access(mem_cmd cmd, Addr addr, void *p, int nbytes) break; default: - fault = Machine_Check_Fault; + fault = MachineCheckFault; break; } diff --git a/cpu/base_dyn_inst.hh b/cpu/base_dyn_inst.hh index d29257a52..2c91db99c 100644 --- a/cpu/base_dyn_inst.hh +++ b/cpu/base_dyn_inst.hh @@ -89,16 +89,16 @@ class BaseDynInst : public FastAlloc, public RefCounted Trace::InstRecord *traceData; template - Fault read(Addr addr, T &data, unsigned flags); + Fault * read(Addr addr, T &data, unsigned flags); template - Fault write(T data, Addr addr, unsigned flags, + Fault * write(T data, Addr addr, unsigned flags, uint64_t *res); void prefetch(Addr addr, unsigned flags); void writeHint(Addr addr, int size, unsigned flags); - Fault copySrcTranslate(Addr src); - Fault copy(Addr dest); + Fault * copySrcTranslate(Addr src); + Fault * copy(Addr dest); /** @todo: Consider making this private. */ public: @@ -154,7 +154,7 @@ class BaseDynInst : public FastAlloc, public RefCounted ExecContext *xc; /** The kind of fault this instruction has generated. */ - Fault fault; + Fault * fault; /** The effective virtual address (lds & stores only). */ Addr effAddr; @@ -225,7 +225,7 @@ class BaseDynInst : public FastAlloc, public RefCounted public: void - trace_mem(Fault fault, // last fault + trace_mem(Fault * fault, // last fault MemCmd cmd, // last command Addr addr, // virtual address of access void *p, // memory accessed @@ -238,7 +238,7 @@ class BaseDynInst : public FastAlloc, public RefCounted void dump(std::string &outstring); /** Returns the fault type. */ - Fault getFault() { return fault; } + Fault * getFault() { return fault; } /** Checks whether or not this instruction has had its branch target * calculated yet. For now it is not utilized and is hacked to be @@ -447,7 +447,7 @@ class BaseDynInst : public FastAlloc, public RefCounted template template -inline Fault +inline Fault * BaseDynInst::read(Addr addr, T &data, unsigned flags) { MemReqPtr req = new MemReq(addr, xc, sizeof(T), flags); @@ -472,7 +472,7 @@ BaseDynInst::read(Addr addr, T &data, unsigned flags) req->paddr = req->vaddr; #endif - if (fault == No_Fault) { + if (fault == NoFault) { fault = cpu->read(req, data, lqIdx); } else { // Return a fixed value to keep simulation deterministic even @@ -490,7 +490,7 @@ BaseDynInst::read(Addr addr, T &data, unsigned flags) template template -inline Fault +inline Fault * BaseDynInst::write(T data, Addr addr, unsigned flags, uint64_t *res) { if (traceData) { @@ -520,14 +520,14 @@ BaseDynInst::write(T data, Addr addr, unsigned flags, uint64_t *res) req->paddr = req->vaddr; #endif - if (fault == No_Fault) { + if (fault == NoFault) { fault = cpu->write(req, data, sqIdx); } if (res) { // always return some result to keep misspeculated paths // (which will ignore faults) deterministic - *res = (fault == No_Fault) ? req->result : 0; + *res = (fault == NoFault) ? req->result : 0; } return fault; diff --git a/cpu/exec_context.cc b/cpu/exec_context.cc index 9bed3ba47..e7facbebb 100644 --- a/cpu/exec_context.cc +++ b/cpu/exec_context.cc @@ -221,7 +221,7 @@ ExecContext::regStats(const string &name) } void -ExecContext::trap(Fault fault) +ExecContext::trap(Fault * fault) { //TheISA::trap(fault); //One possible way to do it... diff --git a/cpu/exec_context.hh b/cpu/exec_context.hh index 846be831a..7e195af23 100644 --- a/cpu/exec_context.hh +++ b/cpu/exec_context.hh @@ -206,17 +206,17 @@ class ExecContext int getInstAsid() { return regs.instAsid(); } int getDataAsid() { return regs.dataAsid(); } - Fault translateInstReq(MemReqPtr &req) + Fault * translateInstReq(MemReqPtr &req) { return itb->translate(req); } - Fault translateDataReadReq(MemReqPtr &req) + Fault * translateDataReadReq(MemReqPtr &req) { return dtb->translate(req, false); } - Fault translateDataWriteReq(MemReqPtr &req) + Fault * translateDataWriteReq(MemReqPtr &req) { return dtb->translate(req, true); } @@ -231,7 +231,7 @@ class ExecContext int getInstAsid() { return asid; } int getDataAsid() { return asid; } - Fault dummyTranslation(MemReqPtr &req) + Fault * dummyTranslation(MemReqPtr &req) { #if 0 assert((req->vaddr >> 48 & 0xffff) == 0); @@ -240,17 +240,17 @@ class ExecContext // put the asid in the upper 16 bits of the paddr req->paddr = req->vaddr & ~((Addr)0xffff << sizeof(Addr) * 8 - 16); req->paddr = req->paddr | (Addr)req->asid << sizeof(Addr) * 8 - 16; - return No_Fault; + return NoFault; } - Fault translateInstReq(MemReqPtr &req) + Fault * translateInstReq(MemReqPtr &req) { return dummyTranslation(req); } - Fault translateDataReadReq(MemReqPtr &req) + Fault * translateDataReadReq(MemReqPtr &req) { return dummyTranslation(req); } - Fault translateDataWriteReq(MemReqPtr &req) + Fault * translateDataWriteReq(MemReqPtr &req) { return dummyTranslation(req); } @@ -258,7 +258,7 @@ class ExecContext #endif template - Fault read(MemReqPtr &req, T &data) + Fault * read(MemReqPtr &req, T &data) { #if FULL_SYSTEM && defined(TARGET_ALPHA) if (req->flags & LOCKED) { @@ -268,14 +268,14 @@ class ExecContext } #endif - Fault error; + Fault * error; error = mem->read(req, data); data = LittleEndianGuest::gtoh(data); return error; } template - Fault write(MemReqPtr &req, T &data) + Fault * write(MemReqPtr &req, T &data) { #if FULL_SYSTEM && defined(TARGET_ALPHA) @@ -301,7 +301,7 @@ class ExecContext << "on cpu " << req->xc->cpu_id << std::endl; } - return No_Fault; + return NoFault; } else req->xc->storeCondFailures = 0; } @@ -333,7 +333,7 @@ class ExecContext inst = new_inst; } - Fault instRead(MemReqPtr &req) + Fault * instRead(MemReqPtr &req) { return mem->read(req, inst); } @@ -412,13 +412,13 @@ class ExecContext } #if FULL_SYSTEM - uint64_t readIpr(int idx, Fault &fault); - Fault setIpr(int idx, uint64_t val); + uint64_t readIpr(int idx, Fault * &fault); + Fault * setIpr(int idx, uint64_t val); int readIntrFlag() { return regs.intrflag; } void setIntrFlag(int val) { regs.intrflag = val; } - Fault hwrei(); + Fault * hwrei(); bool inPalMode() { return AlphaISA::PcPAL(regs.pc); } - void ev5_trap(Fault fault); + void ev5_trap(Fault * fault); bool simPalCheck(int palFunc); #endif @@ -428,7 +428,7 @@ class ExecContext * @todo How to do this properly so it's dependent upon ISA only? */ - void trap(Fault fault); + void trap(Fault * fault); #if !FULL_SYSTEM IntReg getSyscallArg(int i) diff --git a/cpu/o3/alpha_cpu.hh b/cpu/o3/alpha_cpu.hh index 1e1a72af0..606f9fa0a 100644 --- a/cpu/o3/alpha_cpu.hh +++ b/cpu/o3/alpha_cpu.hh @@ -62,23 +62,23 @@ class AlphaFullCPU : public FullO3CPU // void clear_interrupt(int int_num, int index); // void clear_interrupts(); - Fault translateInstReq(MemReqPtr &req) + Fault * translateInstReq(MemReqPtr &req) { return itb->translate(req); } - Fault translateDataReadReq(MemReqPtr &req) + Fault * translateDataReadReq(MemReqPtr &req) { return dtb->translate(req, false); } - Fault translateDataWriteReq(MemReqPtr &req) + Fault * translateDataWriteReq(MemReqPtr &req) { return dtb->translate(req, true); } #else - Fault dummyTranslation(MemReqPtr &req) + Fault * dummyTranslation(MemReqPtr &req) { #if 0 assert((req->vaddr >> 48 & 0xffff) == 0); @@ -87,20 +87,20 @@ class AlphaFullCPU : public FullO3CPU // put the asid in the upper 16 bits of the paddr req->paddr = req->vaddr & ~((Addr)0xffff << sizeof(Addr) * 8 - 16); req->paddr = req->paddr | (Addr)req->asid << sizeof(Addr) * 8 - 16; - return No_Fault; + return NoFault; } - Fault translateInstReq(MemReqPtr &req) + Fault * translateInstReq(MemReqPtr &req) { return dummyTranslation(req); } - Fault translateDataReadReq(MemReqPtr &req) + Fault * translateDataReadReq(MemReqPtr &req) { return dummyTranslation(req); } - Fault translateDataWriteReq(MemReqPtr &req) + Fault * translateDataWriteReq(MemReqPtr &req) { return dummyTranslation(req); } @@ -135,16 +135,16 @@ class AlphaFullCPU : public FullO3CPU // look like. #if FULL_SYSTEM uint64_t *getIpr(); - uint64_t readIpr(int idx, Fault &fault); - Fault setIpr(int idx, uint64_t val); + uint64_t readIpr(int idx, Fault * &fault); + Fault * setIpr(int idx, uint64_t val); int readIntrFlag(); void setIntrFlag(int val); - Fault hwrei(); + Fault * hwrei(); bool inPalMode() { return AlphaISA::PcPAL(this->regFile.readPC()); } bool inPalMode(uint64_t PC) { return AlphaISA::PcPAL(PC); } - void trap(Fault fault); + void trap(Fault * fault); bool simPalCheck(int palFunc); void processInterrupts(); @@ -197,7 +197,7 @@ class AlphaFullCPU : public FullO3CPU bool palShadowEnabled; // Not sure this is used anywhere. - void intr_post(RegFile *regs, Fault fault, Addr pc); + void intr_post(RegFile *regs, Fault * fault, Addr pc); // Actually used within exec files. Implement properly. void swapPALShadow(bool use_shadow); // Called by CPU constructor. Can implement as I please. @@ -210,7 +210,7 @@ class AlphaFullCPU : public FullO3CPU template - Fault read(MemReqPtr &req, T &data) + Fault * read(MemReqPtr &req, T &data) { #if FULL_SYSTEM && defined(TARGET_ALPHA) if (req->flags & LOCKED) { @@ -220,20 +220,20 @@ class AlphaFullCPU : public FullO3CPU } #endif - Fault error; + Fault * error; error = this->mem->read(req, data); data = gtoh(data); return error; } template - Fault read(MemReqPtr &req, T &data, int load_idx) + Fault * read(MemReqPtr &req, T &data, int load_idx) { return this->iew.ldstQueue.read(req, data, load_idx); } template - Fault write(MemReqPtr &req, T &data) + Fault * write(MemReqPtr &req, T &data) { #if FULL_SYSTEM && defined(TARGET_ALPHA) @@ -259,7 +259,7 @@ class AlphaFullCPU : public FullO3CPU << "on cpu " << this->cpu_id << std::endl; } - return No_Fault; + return NoFault; } else req->xc->storeCondFailures = 0; } @@ -283,7 +283,7 @@ class AlphaFullCPU : public FullO3CPU } template - Fault write(MemReqPtr &req, T &data, int store_idx) + Fault * write(MemReqPtr &req, T &data, int store_idx) { return this->iew.ldstQueue.write(req, data, store_idx); } diff --git a/cpu/o3/alpha_cpu_impl.hh b/cpu/o3/alpha_cpu_impl.hh index 3b16975a9..408676331 100644 --- a/cpu/o3/alpha_cpu_impl.hh +++ b/cpu/o3/alpha_cpu_impl.hh @@ -246,13 +246,13 @@ AlphaFullCPU::getIpr() template uint64_t -AlphaFullCPU::readIpr(int idx, Fault &fault) +AlphaFullCPU::readIpr(int idx, Fault * &fault) { return this->regFile.readIpr(idx, fault); } template -Fault +Fault * AlphaFullCPU::setIpr(int idx, uint64_t val) { return this->regFile.setIpr(idx, val); @@ -274,13 +274,13 @@ AlphaFullCPU::setIntrFlag(int val) // Can force commit stage to squash and stuff. template -Fault +Fault * AlphaFullCPU::hwrei() { uint64_t *ipr = getIpr(); if (!inPalMode()) - return Unimplemented_Opcode_Fault; + return UnimplementedOpcodeFault; setNextPC(ipr[AlphaISA::IPR_EXC_ADDR]); @@ -292,7 +292,7 @@ AlphaFullCPU::hwrei() this->checkInterrupts = true; // FIXME: XXX check for interrupts? XXX - return No_Fault; + return NoFault; } template @@ -323,28 +323,28 @@ AlphaFullCPU::simPalCheck(int palFunc) // stage. template void -AlphaFullCPU::trap(Fault fault) +AlphaFullCPU::trap(Fault * fault) { // Keep in mind that a trap may be initiated by fetch if there's a TLB // miss uint64_t PC = this->commit.readCommitPC(); - DPRINTF(Fault, "Fault %s\n", FaultName(fault)); - this->recordEvent(csprintf("Fault %s", FaultName(fault))); + DPRINTF(Fault, "Fault %s\n", fault ? fault->name : "name"); + this->recordEvent(csprintf("Fault %s", fault ? fault->name : "name")); // kernelStats.fault(fault); - if (fault == Arithmetic_Fault) + if (fault == ArithmeticFault) panic("Arithmetic traps are unimplemented!"); typename AlphaISA::InternalProcReg *ipr = getIpr(); // exception restart address - Get the commit PC - if (fault != Interrupt_Fault || !inPalMode(PC)) + if (fault != InterruptFault || !inPalMode(PC)) ipr[AlphaISA::IPR_EXC_ADDR] = PC; - if (fault == Pal_Fault || fault == Arithmetic_Fault /* || - fault == Interrupt_Fault && !PC_PAL(regs.pc) */) { + if (fault == PalFault || fault == ArithmeticFault /* || + fault == InterruptFault && !PC_PAL(regs.pc) */) { // traps... skip faulting instruction ipr[AlphaISA::IPR_EXC_ADDR] += 4; } @@ -353,7 +353,7 @@ AlphaFullCPU::trap(Fault fault) swapPALShadow(true); this->regFile.setPC( ipr[AlphaISA::IPR_PAL_BASE] + - AlphaISA::fault_addr[fault] ); + AlphaISA::fault_addr(fault) ); this->regFile.setNextPC(PC + sizeof(MachInst)); } diff --git a/cpu/o3/alpha_dyn_inst.hh b/cpu/o3/alpha_dyn_inst.hh index bb90bf21a..77dcbaf74 100644 --- a/cpu/o3/alpha_dyn_inst.hh +++ b/cpu/o3/alpha_dyn_inst.hh @@ -74,7 +74,7 @@ class AlphaDynInst : public BaseDynInst AlphaDynInst(StaticInstPtr &_staticInst); /** Executes the instruction.*/ - Fault execute() + Fault * execute() { return this->fault = this->staticInst->execute(this, this->traceData); } @@ -87,13 +87,13 @@ class AlphaDynInst : public BaseDynInst void setFpcr(uint64_t val); #if FULL_SYSTEM - uint64_t readIpr(int idx, Fault &fault); - Fault setIpr(int idx, uint64_t val); - Fault hwrei(); + uint64_t readIpr(int idx, Fault * &fault); + Fault * setIpr(int idx, uint64_t val); + Fault * hwrei(); int readIntrFlag(); void setIntrFlag(int val); bool inPalMode(); - void trap(Fault fault); + void trap(Fault * fault); bool simPalCheck(int palFunc); #else void syscall(); @@ -220,12 +220,12 @@ class AlphaDynInst : public BaseDynInst } public: - Fault calcEA() + Fault * calcEA() { return this->staticInst->eaCompInst()->execute(this, this->traceData); } - Fault memAccess() + Fault * memAccess() { return this->staticInst->memAccInst()->execute(this, this->traceData); } diff --git a/cpu/o3/alpha_dyn_inst_impl.hh b/cpu/o3/alpha_dyn_inst_impl.hh index d1ebb812d..b20af48cd 100644 --- a/cpu/o3/alpha_dyn_inst_impl.hh +++ b/cpu/o3/alpha_dyn_inst_impl.hh @@ -98,20 +98,20 @@ AlphaDynInst::setFpcr(uint64_t val) #if FULL_SYSTEM template uint64_t -AlphaDynInst::readIpr(int idx, Fault &fault) +AlphaDynInst::readIpr(int idx, Fault * &fault) { return this->cpu->readIpr(idx, fault); } template -Fault +Fault * AlphaDynInst::setIpr(int idx, uint64_t val) { return this->cpu->setIpr(idx, val); } template -Fault +Fault * AlphaDynInst::hwrei() { return this->cpu->hwrei(); @@ -140,7 +140,7 @@ AlphaDynInst::inPalMode() template void -AlphaDynInst::trap(Fault fault) +AlphaDynInst::trap(Fault * fault) { this->cpu->trap(fault); } diff --git a/cpu/o3/commit_impl.hh b/cpu/o3/commit_impl.hh index dc0986772..540f16b78 100644 --- a/cpu/o3/commit_impl.hh +++ b/cpu/o3/commit_impl.hh @@ -393,9 +393,9 @@ SimpleCommit::commitHead(DynInstPtr &head_inst, unsigned inst_num) } // Check if the instruction caused a fault. If so, trap. - Fault inst_fault = head_inst->getFault(); + Fault * inst_fault = head_inst->getFault(); - if (inst_fault != No_Fault && inst_fault != Fake_Mem_Fault) { + if (inst_fault != NoFault && inst_fault != FakeMemFault) { if (!head_inst->isNop()) { #if FULL_SYSTEM cpu->trap(inst_fault); diff --git a/cpu/o3/fetch.hh b/cpu/o3/fetch.hh index 24e445f0b..5443d274e 100644 --- a/cpu/o3/fetch.hh +++ b/cpu/o3/fetch.hh @@ -123,7 +123,7 @@ class SimpleFetch * @param fetch_PC The PC address that is being fetched from. * @return Any fault that occured. */ - Fault fetchCacheLine(Addr fetch_PC); + Fault * fetchCacheLine(Addr fetch_PC); inline void doSquash(const Addr &new_PC); diff --git a/cpu/o3/fetch_impl.hh b/cpu/o3/fetch_impl.hh index cd1ed1351..e8d333ed4 100644 --- a/cpu/o3/fetch_impl.hh +++ b/cpu/o3/fetch_impl.hh @@ -221,7 +221,7 @@ SimpleFetch::lookupAndUpdateNextPC(DynInstPtr &inst, Addr &next_PC) } template -Fault +Fault * SimpleFetch::fetchCacheLine(Addr fetch_PC) { // Check if the instruction exists within the cache. @@ -236,7 +236,7 @@ SimpleFetch::fetchCacheLine(Addr fetch_PC) unsigned flags = 0; #endif // FULL_SYSTEM - Fault fault = No_Fault; + Fault * fault = NoFault; // Align the fetch PC so it's at the start of a cache block. fetch_PC = icacheBlockAlignPC(fetch_PC); @@ -258,7 +258,7 @@ SimpleFetch::fetchCacheLine(Addr fetch_PC) // If translation was successful, attempt to read the first // instruction. - if (fault == No_Fault) { + if (fault == NoFault) { DPRINTF(Fetch, "Fetch: Doing instruction read.\n"); fault = cpu->mem->read(memReq, cacheData); // This read may change when the mem interface changes. @@ -268,7 +268,7 @@ SimpleFetch::fetchCacheLine(Addr fetch_PC) // Now do the timing access to see whether or not the instruction // exists within the cache. - if (icacheInterface && fault == No_Fault) { + if (icacheInterface && fault == NoFault) { DPRINTF(Fetch, "Fetch: Doing timing memory access.\n"); memReq->completionEvent = NULL; @@ -468,7 +468,7 @@ SimpleFetch::fetch() Addr fetch_PC = cpu->readPC(); // Fault code for memory access. - Fault fault = No_Fault; + Fault * fault = NoFault; // If returning from the delay of a cache miss, then update the status // to running, otherwise do the cache access. Possibly move this up @@ -506,7 +506,7 @@ SimpleFetch::fetch() unsigned offset = fetch_PC & cacheBlkMask; unsigned fetched; - if (fault == No_Fault) { + if (fault == NoFault) { // If the read of the first instruction was successful, then grab the // instructions from the rest of the cache line and put them into the // queue heading to decode. @@ -582,7 +582,7 @@ SimpleFetch::fetch() // Or might want to leave setting the PC to the main CPU, with fetch // only changing the nextPC (will require correct determination of // next PC). - if (fault == No_Fault) { + if (fault == NoFault) { DPRINTF(Fetch, "Fetch: Setting PC to %08p.\n", next_PC); cpu->setPC(next_PC); cpu->setNextPC(next_PC + instSize); diff --git a/cpu/o3/regfile.hh b/cpu/o3/regfile.hh index 4d47b8f9c..5aafd5495 100644 --- a/cpu/o3/regfile.hh +++ b/cpu/o3/regfile.hh @@ -32,6 +32,7 @@ // @todo: Destructor #include "arch/alpha/isa_traits.hh" +#include "arch/alpha/faults.hh" #include "base/trace.hh" #include "config/full_system.hh" #include "cpu/o3/comm.hh" @@ -211,8 +212,8 @@ class PhysRegFile } #if FULL_SYSTEM - uint64_t readIpr(int idx, Fault &fault); - Fault setIpr(int idx, uint64_t val); + uint64_t readIpr(int idx, Fault * &fault); + Fault * setIpr(int idx, uint64_t val); InternalProcReg *getIpr() { return ipr; } int readIntrFlag() { return intrflag; } void setIntrFlag(int val) { intrflag = val; } @@ -275,7 +276,7 @@ PhysRegFile::PhysRegFile(unsigned _numPhysicalIntRegs, //the DynInst level. template uint64_t -PhysRegFile::readIpr(int idx, Fault &fault) +PhysRegFile::readIpr(int idx, Fault * &fault) { uint64_t retval = 0; // return value, default 0 @@ -368,12 +369,12 @@ PhysRegFile::readIpr(int idx, Fault &fault) case ISA::IPR_DTB_IAP: case ISA::IPR_ITB_IA: case ISA::IPR_ITB_IAP: - fault = Unimplemented_Opcode_Fault; + fault = UnimplementedOpcodeFault; break; default: // invalid IPR - fault = Unimplemented_Opcode_Fault; + fault = UnimplementedOpcodeFault; break; } @@ -383,7 +384,7 @@ PhysRegFile::readIpr(int idx, Fault &fault) extern int break_ipl; template -Fault +Fault * PhysRegFile::setIpr(int idx, uint64_t val) { uint64_t old; @@ -521,7 +522,7 @@ PhysRegFile::setIpr(int idx, uint64_t val) case ISA::IPR_ITB_PTE_TEMP: case ISA::IPR_DTB_PTE_TEMP: // read-only registers - return Unimplemented_Opcode_Fault; + return UnimplementedOpcodeFault; case ISA::IPR_HWINT_CLR: case ISA::IPR_SL_XMIT: @@ -623,11 +624,11 @@ PhysRegFile::setIpr(int idx, uint64_t val) default: // invalid IPR - return Unimplemented_Opcode_Fault; + return UnimplementedOpcodeFault; } // no error... - return No_Fault; + return NoFault; } #endif // #if FULL_SYSTEM diff --git a/cpu/ozone/cpu.hh b/cpu/ozone/cpu.hh index 5af77862a..21fe05b6a 100644 --- a/cpu/ozone/cpu.hh +++ b/cpu/ozone/cpu.hh @@ -286,17 +286,17 @@ class OoOCPU : public BaseCPU int getInstAsid() { return xc->regs.instAsid(); } int getDataAsid() { return xc->regs.dataAsid(); } - Fault translateInstReq(MemReqPtr &req) + Fault * translateInstReq(MemReqPtr &req) { return itb->translate(req); } - Fault translateDataReadReq(MemReqPtr &req) + Fault * translateDataReadReq(MemReqPtr &req) { return dtb->translate(req, false); } - Fault translateDataWriteReq(MemReqPtr &req) + Fault * translateDataWriteReq(MemReqPtr &req) { return dtb->translate(req, true); } @@ -311,7 +311,7 @@ class OoOCPU : public BaseCPU int getInstAsid() { return xc->asid; } int getDataAsid() { return xc->asid; } - Fault dummyTranslation(MemReqPtr &req) + Fault * dummyTranslation(MemReqPtr &req) { #if 0 assert((req->vaddr >> 48 & 0xffff) == 0); @@ -320,17 +320,17 @@ class OoOCPU : public BaseCPU // put the asid in the upper 16 bits of the paddr req->paddr = req->vaddr & ~((Addr)0xffff << sizeof(Addr) * 8 - 16); req->paddr = req->paddr | (Addr)req->asid << sizeof(Addr) * 8 - 16; - return No_Fault; + return NoFault; } - Fault translateInstReq(MemReqPtr &req) + Fault * translateInstReq(MemReqPtr &req) { return dummyTranslation(req); } - Fault translateDataReadReq(MemReqPtr &req) + Fault * translateDataReadReq(MemReqPtr &req) { return dummyTranslation(req); } - Fault translateDataWriteReq(MemReqPtr &req) + Fault * translateDataWriteReq(MemReqPtr &req) { return dummyTranslation(req); } @@ -338,10 +338,10 @@ class OoOCPU : public BaseCPU #endif template - Fault read(Addr addr, T &data, unsigned flags, DynInstPtr inst); + Fault * read(Addr addr, T &data, unsigned flags, DynInstPtr inst); template - Fault write(T data, Addr addr, unsigned flags, + Fault * write(T data, Addr addr, unsigned flags, uint64_t *res, DynInstPtr inst); void prefetch(Addr addr, unsigned flags) @@ -354,9 +354,9 @@ class OoOCPU : public BaseCPU // need to do this... } - Fault copySrcTranslate(Addr src); + Fault * copySrcTranslate(Addr src); - Fault copy(Addr dest); + Fault * copy(Addr dest); private: bool executeInst(DynInstPtr &inst); @@ -369,7 +369,7 @@ class OoOCPU : public BaseCPU bool getOneInst(); - Fault fetchCacheLine(); + Fault * fetchCacheLine(); InstSeqNum getAndIncrementInstSeq(); @@ -512,13 +512,13 @@ class OoOCPU : public BaseCPU void setFpcr(uint64_t val) { xc->setFpcr(val); } #if FULL_SYSTEM - uint64_t readIpr(int idx, Fault &fault) { return xc->readIpr(idx, fault); } - Fault setIpr(int idx, uint64_t val) { return xc->setIpr(idx, val); } - Fault hwrei() { return xc->hwrei(); } + uint64_t readIpr(int idx, Fault * &fault) { return xc->readIpr(idx, fault); } + Fault * setIpr(int idx, uint64_t val) { return xc->setIpr(idx, val); } + Fault * hwrei() { return xc->hwrei(); } int readIntrFlag() { return xc->readIntrFlag(); } void setIntrFlag(int val) { xc->setIntrFlag(val); } bool inPalMode() { return xc->inPalMode(); } - void ev5_trap(Fault fault) { xc->ev5_trap(fault); } + void ev5_trap(Fault * fault) { xc->ev5_trap(fault); } bool simPalCheck(int palFunc) { return xc->simPalCheck(palFunc); } #else void syscall() { xc->syscall(); } @@ -531,7 +531,7 @@ class OoOCPU : public BaseCPU // precise architected memory state accessor macros template template -Fault +Fault * OoOCPU::read(Addr addr, T &data, unsigned flags, DynInstPtr inst) { MemReqPtr readReq = new MemReq(); @@ -542,21 +542,21 @@ OoOCPU::read(Addr addr, T &data, unsigned flags, DynInstPtr inst) readReq->reset(addr, sizeof(T), flags); // translate to physical address - This might be an ISA impl call - Fault fault = translateDataReadReq(readReq); + Fault * fault = translateDataReadReq(readReq); // do functional access - if (fault == No_Fault) + if (fault == NoFault) fault = xc->mem->read(readReq, data); #if 0 if (traceData) { traceData->setAddr(addr); - if (fault == No_Fault) + if (fault == NoFault) traceData->setData(data); } #endif // if we have a cache, do cache access too - if (fault == No_Fault && dcacheInterface) { + if (fault == NoFault && dcacheInterface) { readReq->cmd = Read; readReq->completionEvent = NULL; readReq->time = curTick; @@ -576,7 +576,7 @@ OoOCPU::read(Addr addr, T &data, unsigned flags, DynInstPtr inst) template template -Fault +Fault * OoOCPU::write(T data, Addr addr, unsigned flags, uint64_t *res, DynInstPtr inst) { @@ -595,13 +595,13 @@ OoOCPU::write(T data, Addr addr, unsigned flags, writeReq->reset(addr, sizeof(T), flags); // translate to physical address - Fault fault = translateDataWriteReq(writeReq); + Fault * fault = translateDataWriteReq(writeReq); // do functional access - if (fault == No_Fault) + if (fault == NoFault) fault = xc->write(writeReq, data); - if (fault == No_Fault && dcacheInterface) { + if (fault == NoFault && dcacheInterface) { writeReq->cmd = Write; memcpy(writeReq->data,(uint8_t *)&data,writeReq->size); writeReq->completionEvent = NULL; @@ -614,7 +614,7 @@ OoOCPU::write(T data, Addr addr, unsigned flags, } } - if (res && (fault == No_Fault)) + if (res && (fault == NoFault)) *res = writeReq->result; if (!dcacheInterface && (writeReq->flags & UNCACHEABLE)) diff --git a/cpu/simple/cpu.cc b/cpu/simple/cpu.cc index 70217f0bb..6aff94abd 100644 --- a/cpu/simple/cpu.cc +++ b/cpu/simple/cpu.cc @@ -312,7 +312,7 @@ change_thread_state(int thread_number, int activate, int priority) { } -Fault +Fault * SimpleCPU::copySrcTranslate(Addr src) { static bool no_warn = true; @@ -332,11 +332,11 @@ SimpleCPU::copySrcTranslate(Addr src) memReq->reset(src & ~(blk_size - 1), blk_size); // translate to physical address - Fault fault = xc->translateDataReadReq(memReq); + Fault * fault = xc->translateDataReadReq(memReq); - assert(fault != Alignment_Fault); + assert(fault != AlignmentFault); - if (fault == No_Fault) { + if (fault == NoFault) { xc->copySrcAddr = src; xc->copySrcPhysAddr = memReq->paddr + offset; } else { @@ -346,7 +346,7 @@ SimpleCPU::copySrcTranslate(Addr src) return fault; } -Fault +Fault * SimpleCPU::copy(Addr dest) { static bool no_warn = true; @@ -367,11 +367,11 @@ SimpleCPU::copy(Addr dest) memReq->reset(dest & ~(blk_size -1), blk_size); // translate to physical address - Fault fault = xc->translateDataWriteReq(memReq); + Fault * fault = xc->translateDataWriteReq(memReq); - assert(fault != Alignment_Fault); + assert(fault != AlignmentFault); - if (fault == No_Fault) { + if (fault == NoFault) { Addr dest_addr = memReq->paddr + offset; // Need to read straight from memory since we have more than 8 bytes. memReq->paddr = xc->copySrcPhysAddr; @@ -394,11 +394,11 @@ SimpleCPU::copy(Addr dest) // precise architected memory state accessor macros template -Fault +Fault * SimpleCPU::read(Addr addr, T &data, unsigned flags) { if (status() == DcacheMissStall || status() == DcacheMissSwitch) { - Fault fault = xc->read(memReq,data); + Fault * fault = xc->read(memReq,data); if (traceData) { traceData->setAddr(addr); @@ -409,10 +409,10 @@ SimpleCPU::read(Addr addr, T &data, unsigned flags) memReq->reset(addr, sizeof(T), flags); // translate to physical address - Fault fault = xc->translateDataReadReq(memReq); + Fault * fault = xc->translateDataReadReq(memReq); // if we have a cache, do cache access too - if (fault == No_Fault && dcacheInterface) { + if (fault == NoFault && dcacheInterface) { memReq->cmd = Read; memReq->completionEvent = NULL; memReq->time = curTick; @@ -432,7 +432,7 @@ SimpleCPU::read(Addr addr, T &data, unsigned flags) fault = xc->read(memReq, data); } - } else if(fault == No_Fault) { + } else if(fault == NoFault) { // do functional access fault = xc->read(memReq, data); @@ -447,32 +447,32 @@ SimpleCPU::read(Addr addr, T &data, unsigned flags) #ifndef DOXYGEN_SHOULD_SKIP_THIS template -Fault +Fault * SimpleCPU::read(Addr addr, uint64_t &data, unsigned flags); template -Fault +Fault * SimpleCPU::read(Addr addr, uint32_t &data, unsigned flags); template -Fault +Fault * SimpleCPU::read(Addr addr, uint16_t &data, unsigned flags); template -Fault +Fault * SimpleCPU::read(Addr addr, uint8_t &data, unsigned flags); #endif //DOXYGEN_SHOULD_SKIP_THIS template<> -Fault +Fault * SimpleCPU::read(Addr addr, double &data, unsigned flags) { return read(addr, *(uint64_t*)&data, flags); } template<> -Fault +Fault * SimpleCPU::read(Addr addr, float &data, unsigned flags) { return read(addr, *(uint32_t*)&data, flags); @@ -480,7 +480,7 @@ SimpleCPU::read(Addr addr, float &data, unsigned flags) template<> -Fault +Fault * SimpleCPU::read(Addr addr, int32_t &data, unsigned flags) { return read(addr, (uint32_t&)data, flags); @@ -488,19 +488,19 @@ SimpleCPU::read(Addr addr, int32_t &data, unsigned flags) template -Fault +Fault * SimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res) { memReq->reset(addr, sizeof(T), flags); // translate to physical address - Fault fault = xc->translateDataWriteReq(memReq); + Fault * fault = xc->translateDataWriteReq(memReq); // do functional access - if (fault == No_Fault) + if (fault == NoFault) fault = xc->write(memReq, data); - if (fault == No_Fault && dcacheInterface) { + if (fault == NoFault && dcacheInterface) { memReq->cmd = Write; memcpy(memReq->data,(uint8_t *)&data,memReq->size); memReq->completionEvent = NULL; @@ -519,7 +519,7 @@ SimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res) } } - if (res && (fault == No_Fault)) + if (res && (fault == NoFault)) *res = memReq->result; if (!dcacheInterface && (memReq->flags & UNCACHEABLE)) @@ -531,32 +531,32 @@ SimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res) #ifndef DOXYGEN_SHOULD_SKIP_THIS template -Fault +Fault * SimpleCPU::write(uint64_t data, Addr addr, unsigned flags, uint64_t *res); template -Fault +Fault * SimpleCPU::write(uint32_t data, Addr addr, unsigned flags, uint64_t *res); template -Fault +Fault * SimpleCPU::write(uint16_t data, Addr addr, unsigned flags, uint64_t *res); template -Fault +Fault * SimpleCPU::write(uint8_t data, Addr addr, unsigned flags, uint64_t *res); #endif //DOXYGEN_SHOULD_SKIP_THIS template<> -Fault +Fault * SimpleCPU::write(double data, Addr addr, unsigned flags, uint64_t *res) { return write(*(uint64_t*)&data, addr, flags, res); } template<> -Fault +Fault * SimpleCPU::write(float data, Addr addr, unsigned flags, uint64_t *res) { return write(*(uint32_t*)&data, addr, flags, res); @@ -564,7 +564,7 @@ SimpleCPU::write(float data, Addr addr, unsigned flags, uint64_t *res) template<> -Fault +Fault * SimpleCPU::write(int32_t data, Addr addr, unsigned flags, uint64_t *res) { return write((uint32_t)data, addr, flags, res); @@ -638,7 +638,7 @@ SimpleCPU::tick() traceData = NULL; - Fault fault = No_Fault; + Fault * fault = NoFault; #if FULL_SYSTEM if (checkInterrupts && check_interrupts() && !xc->inPalMode() && @@ -675,7 +675,7 @@ SimpleCPU::tick() if (ipl && ipl > xc->regs.ipr[TheISA::IPR_IPLR]) { ipr[TheISA::IPR_ISR] = summary; ipr[TheISA::IPR_INTID] = ipl; - xc->ev5_trap(Interrupt_Fault); + xc->ev5_trap(InterruptFault); DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n", ipr[TheISA::IPR_IPLR], ipl, summary); @@ -713,10 +713,10 @@ SimpleCPU::tick() fault = xc->translateInstReq(memReq); - if (fault == No_Fault) + if (fault == NoFault) fault = xc->mem->read(memReq, inst); - if (icacheInterface && fault == No_Fault) { + if (icacheInterface && fault == NoFault) { memReq->completionEvent = NULL; memReq->time = curTick; @@ -738,7 +738,7 @@ SimpleCPU::tick() // If we've got a valid instruction (i.e., no fault on instruction // fetch), then execute it. - if (fault == No_Fault) { + if (fault == NoFault) { // keep an instruction count numInst++; @@ -795,9 +795,9 @@ SimpleCPU::tick() traceFunctions(xc->regs.pc); - } // if (fault == No_Fault) + } // if (fault == NoFault) - if (fault != No_Fault) { + if (fault != NoFault) { #if FULL_SYSTEM xc->ev5_trap(fault); #else // !FULL_SYSTEM diff --git a/cpu/simple/cpu.hh b/cpu/simple/cpu.hh index 0f7251237..e7a447117 100644 --- a/cpu/simple/cpu.hh +++ b/cpu/simple/cpu.hh @@ -234,10 +234,10 @@ class SimpleCPU : public BaseCPU virtual void unserialize(Checkpoint *cp, const std::string §ion); template - Fault read(Addr addr, T &data, unsigned flags); + Fault * read(Addr addr, T &data, unsigned flags); template - Fault write(T data, Addr addr, unsigned flags, uint64_t *res); + Fault * write(T data, Addr addr, unsigned flags, uint64_t *res); // These functions are only used in CPU models that split // effective address computation from the actual memory access. @@ -254,9 +254,9 @@ class SimpleCPU : public BaseCPU // need to do this... } - Fault copySrcTranslate(Addr src); + Fault * copySrcTranslate(Addr src); - Fault copy(Addr dest); + Fault * copy(Addr dest); // The register accessor methods provide the index of the // instruction's operand (e.g., 0 or 1), not the architectural @@ -325,13 +325,13 @@ class SimpleCPU : public BaseCPU void setFpcr(uint64_t val) { xc->setFpcr(val); } #if FULL_SYSTEM - uint64_t readIpr(int idx, Fault &fault) { return xc->readIpr(idx, fault); } - Fault setIpr(int idx, uint64_t val) { return xc->setIpr(idx, val); } - Fault hwrei() { return xc->hwrei(); } + uint64_t readIpr(int idx, Fault * &fault) { return xc->readIpr(idx, fault); } + Fault * setIpr(int idx, uint64_t val) { return xc->setIpr(idx, val); } + Fault * hwrei() { return xc->hwrei(); } int readIntrFlag() { return xc->readIntrFlag(); } void setIntrFlag(int val) { xc->setIntrFlag(val); } bool inPalMode() { return xc->inPalMode(); } - void ev5_trap(Fault fault) { xc->ev5_trap(fault); } + void ev5_trap(Fault * fault) { xc->ev5_trap(fault); } bool simPalCheck(int palFunc) { return xc->simPalCheck(palFunc); } #else void syscall() { xc->syscall(); } diff --git a/dev/alpha_console.cc b/dev/alpha_console.cc index 61b444628..38fbbdef0 100644 --- a/dev/alpha_console.cc +++ b/dev/alpha_console.cc @@ -99,7 +99,7 @@ AlphaConsole::startup() alphaAccess->intrClockFrequency = platform->intrFrequency(); } -Fault +Fault * AlphaConsole::read(MemReqPtr &req, uint8_t *data) { memset(data, 0, req->size); @@ -183,13 +183,13 @@ AlphaConsole::read(MemReqPtr &req, uint8_t *data) } break; default: - return Machine_Check_Fault; + return MachineCheckFault; } - return No_Fault; + return NoFault; } -Fault +Fault * AlphaConsole::write(MemReqPtr &req, const uint8_t *data) { uint64_t val; @@ -203,7 +203,7 @@ AlphaConsole::write(MemReqPtr &req, const uint8_t *data) val = *(uint64_t *)data; break; default: - return Machine_Check_Fault; + return MachineCheckFault; } Addr daddr = req->paddr - (addr & EV5::PAddrImplMask); @@ -256,10 +256,10 @@ AlphaConsole::write(MemReqPtr &req, const uint8_t *data) break; default: - return Machine_Check_Fault; + return MachineCheckFault; } - return No_Fault; + return NoFault; } Tick diff --git a/dev/alpha_console.hh b/dev/alpha_console.hh index 74ad795f0..75f0a3a67 100644 --- a/dev/alpha_console.hh +++ b/dev/alpha_console.hh @@ -110,8 +110,8 @@ class AlphaConsole : public PioDevice /** * memory mapped reads and writes */ - virtual Fault read(MemReqPtr &req, uint8_t *data); - virtual Fault write(MemReqPtr &req, const uint8_t *data); + virtual Fault * read(MemReqPtr &req, uint8_t *data); + virtual Fault * write(MemReqPtr &req, const uint8_t *data); /** * standard serialization routines for checkpointing diff --git a/dev/baddev.cc b/dev/baddev.cc index 52c538707..b6ca919e4 100644 --- a/dev/baddev.cc +++ b/dev/baddev.cc @@ -61,19 +61,19 @@ BadDevice::BadDevice(const string &name, Addr a, MemoryController *mmu, } -Fault +Fault * BadDevice::read(MemReqPtr &req, uint8_t *data) { panic("Device %s not imlpmented\n", devname); - return No_Fault; + return NoFault; } -Fault +Fault * BadDevice::write(MemReqPtr &req, const uint8_t *data) { panic("Device %s not imlpmented\n", devname); - return No_Fault; + return NoFault; } Tick diff --git a/dev/baddev.hh b/dev/baddev.hh index c2a204c05..b7b67e31a 100644 --- a/dev/baddev.hh +++ b/dev/baddev.hh @@ -71,7 +71,7 @@ class BadDevice : public PioDevice * @param data A pointer to write the read data to. * @return The fault condition of the access. */ - virtual Fault read(MemReqPtr &req, uint8_t *data); + virtual Fault * read(MemReqPtr &req, uint8_t *data); /** * On a write event we just panic aand hopefully print a @@ -80,7 +80,7 @@ class BadDevice : public PioDevice * @param data The data to write. * @return The fault condition of the access. */ - virtual Fault write(MemReqPtr &req, const uint8_t *data); + virtual Fault * write(MemReqPtr &req, const uint8_t *data); /** * Return how long this access will take. diff --git a/dev/ide_ctrl.cc b/dev/ide_ctrl.cc index 1279efc82..a5cb0dfd8 100644 --- a/dev/ide_ctrl.cc +++ b/dev/ide_ctrl.cc @@ -390,7 +390,7 @@ IdeController::writeConfig(int offset, int size, const uint8_t *data) } } -Fault +Fault * IdeController::read(MemReqPtr &req, uint8_t *data) { Addr offset; @@ -401,7 +401,7 @@ IdeController::read(MemReqPtr &req, uint8_t *data) parseAddr(req->paddr, offset, channel, reg_type); if (!io_enabled) - return No_Fault; + return NoFault; switch (reg_type) { case BMI_BLOCK: @@ -457,10 +457,10 @@ IdeController::read(MemReqPtr &req, uint8_t *data) DPRINTF(IdeCtrl, "read from offset: %#x size: %#x data: %#x\n", offset, req->size, *(uint32_t*)data); - return No_Fault; + return NoFault; } -Fault +Fault * IdeController::write(MemReqPtr &req, const uint8_t *data) { Addr offset; @@ -472,12 +472,12 @@ IdeController::write(MemReqPtr &req, const uint8_t *data) parseAddr(req->paddr, offset, channel, reg_type); if (!io_enabled) - return No_Fault; + return NoFault; switch (reg_type) { case BMI_BLOCK: if (!bm_enabled) - return No_Fault; + return NoFault; switch (offset) { // Bus master IDE command register @@ -627,7 +627,7 @@ IdeController::write(MemReqPtr &req, const uint8_t *data) DPRINTF(IdeCtrl, "write to offset: %#x size: %#x data: %#x\n", offset, req->size, *(uint32_t*)data); - return No_Fault; + return NoFault; } //// diff --git a/dev/ide_ctrl.hh b/dev/ide_ctrl.hh index 0fbaf9207..72523f57c 100644 --- a/dev/ide_ctrl.hh +++ b/dev/ide_ctrl.hh @@ -213,7 +213,7 @@ class IdeController : public PciDev * @param data Return the field read. * @return The fault condition of the access. */ - virtual Fault read(MemReqPtr &req, uint8_t *data); + virtual Fault * read(MemReqPtr &req, uint8_t *data); /** * Write to the mmapped I/O control registers. @@ -221,7 +221,7 @@ class IdeController : public PciDev * @param data The data to write. * @return The fault condition of the access. */ - virtual Fault write(MemReqPtr &req, const uint8_t *data); + virtual Fault * write(MemReqPtr &req, const uint8_t *data); /** * Serialize this object to the given output stream. diff --git a/dev/isa_fake.cc b/dev/isa_fake.cc index e2802eaa9..93c9eedbf 100644 --- a/dev/isa_fake.cc +++ b/dev/isa_fake.cc @@ -59,7 +59,7 @@ IsaFake::IsaFake(const string &name, Addr a, MemoryController *mmu, } } -Fault +Fault * IsaFake::read(MemReqPtr &req, uint8_t *data) { DPRINTF(Tsunami, "read va=%#x size=%d\n", @@ -73,26 +73,26 @@ IsaFake::read(MemReqPtr &req, uint8_t *data) case sizeof(uint64_t): *(uint64_t*)data = 0xFFFFFFFFFFFFFFFFULL; - return No_Fault; + return NoFault; case sizeof(uint32_t): *(uint32_t*)data = 0xFFFFFFFF; - return No_Fault; + return NoFault; case sizeof(uint16_t): *(uint16_t*)data = 0xFFFF; - return No_Fault; + return NoFault; case sizeof(uint8_t): *(uint8_t*)data = 0xFF; - return No_Fault; + return NoFault; default: panic("invalid access size(?) for PCI configspace!\n"); } DPRINTFN("Isa FakeSMC ERROR: read daddr=%#x size=%d\n", daddr, req->size); - return No_Fault; + return NoFault; } -Fault +Fault * IsaFake::write(MemReqPtr &req, const uint8_t *data) { DPRINTF(Tsunami, "write - va=%#x size=%d \n", @@ -100,7 +100,7 @@ IsaFake::write(MemReqPtr &req, const uint8_t *data) //:Addr daddr = (req->paddr & addr_mask) >> 6; - return No_Fault; + return NoFault; } Tick diff --git a/dev/isa_fake.hh b/dev/isa_fake.hh index 290b24b54..60ca5f90a 100644 --- a/dev/isa_fake.hh +++ b/dev/isa_fake.hh @@ -65,14 +65,14 @@ class IsaFake : public PioDevice * @param req The memory request. * @param data Where to put the data. */ - virtual Fault read(MemReqPtr &req, uint8_t *data); + virtual Fault * read(MemReqPtr &req, uint8_t *data); /** * All writes are simply ignored. * @param req The memory request. * @param data the data to not write. */ - virtual Fault write(MemReqPtr &req, const uint8_t *data); + virtual Fault * write(MemReqPtr &req, const uint8_t *data); /** * Return how long this access will take. diff --git a/dev/ns_gige.cc b/dev/ns_gige.cc index 9010850ab..c28615438 100644 --- a/dev/ns_gige.cc +++ b/dev/ns_gige.cc @@ -558,7 +558,7 @@ NSGigE::writeConfig(int offset, int size, const uint8_t* data) * This reads the device registers, which are detailed in the NS83820 * spec sheet */ -Fault +Fault * NSGigE::read(MemReqPtr &req, uint8_t *data) { assert(ioEnable); @@ -575,14 +575,14 @@ NSGigE::read(MemReqPtr &req, uint8_t *data) panic("Accessing reserved register"); } else if (daddr > RESERVED && daddr <= 0x3FC) { readConfig(daddr & 0xff, req->size, data); - return No_Fault; + return NoFault; } else if (daddr >= MIB_START && daddr <= MIB_END) { // don't implement all the MIB's. hopefully the kernel // doesn't actually DEPEND upon their values // MIB are just hardware stats keepers uint32_t ® = *(uint32_t *) data; reg = 0; - return No_Fault; + return NoFault; } else if (daddr > 0x3FC) panic("Something is messed up!\n"); @@ -784,10 +784,10 @@ NSGigE::read(MemReqPtr &req, uint8_t *data) daddr, req->size); } - return No_Fault; + return NoFault; } -Fault +Fault * NSGigE::write(MemReqPtr &req, const uint8_t *data) { assert(ioEnable); @@ -800,7 +800,7 @@ NSGigE::write(MemReqPtr &req, const uint8_t *data) panic("Accessing reserved register"); } else if (daddr > RESERVED && daddr <= 0x3FC) { writeConfig(daddr & 0xff, req->size, data); - return No_Fault; + return NoFault; } else if (daddr > 0x3FC) panic("Something is messed up!\n"); @@ -1203,7 +1203,7 @@ NSGigE::write(MemReqPtr &req, const uint8_t *data) panic("Invalid Request Size"); } - return No_Fault; + return NoFault; } void diff --git a/dev/ns_gige.hh b/dev/ns_gige.hh index ade7e32e6..b65626b7b 100644 --- a/dev/ns_gige.hh +++ b/dev/ns_gige.hh @@ -408,8 +408,8 @@ class NSGigE : public PciDev virtual void writeConfig(int offset, int size, const uint8_t *data); virtual void readConfig(int offset, int size, uint8_t *data); - virtual Fault read(MemReqPtr &req, uint8_t *data); - virtual Fault write(MemReqPtr &req, const uint8_t *data); + virtual Fault * read(MemReqPtr &req, uint8_t *data); + virtual Fault * write(MemReqPtr &req, const uint8_t *data); bool cpuIntrPending() const; void cpuIntrAck() { cpuIntrClear(); } diff --git a/dev/pciconfigall.cc b/dev/pciconfigall.cc index 396e130af..1175172c4 100644 --- a/dev/pciconfigall.cc +++ b/dev/pciconfigall.cc @@ -95,7 +95,7 @@ PciConfigAll::startup() } -Fault +Fault * PciConfigAll::read(MemReqPtr &req, uint8_t *data) { @@ -112,16 +112,16 @@ PciConfigAll::read(MemReqPtr &req, uint8_t *data) switch (req->size) { // case sizeof(uint64_t): // *(uint64_t*)data = 0xFFFFFFFFFFFFFFFF; - // return No_Fault; + // return NoFault; case sizeof(uint32_t): *(uint32_t*)data = 0xFFFFFFFF; - return No_Fault; + return NoFault; case sizeof(uint16_t): *(uint16_t*)data = 0xFFFF; - return No_Fault; + return NoFault; case sizeof(uint8_t): *(uint8_t*)data = 0xFF; - return No_Fault; + return NoFault; default: panic("invalid access size(?) for PCI configspace!\n"); } @@ -131,7 +131,7 @@ PciConfigAll::read(MemReqPtr &req, uint8_t *data) case sizeof(uint16_t): case sizeof(uint8_t): devices[device][func]->readConfig(reg, req->size, data); - return No_Fault; + return NoFault; default: panic("invalid access size(?) for PCI configspace!\n"); } @@ -140,10 +140,10 @@ PciConfigAll::read(MemReqPtr &req, uint8_t *data) DPRINTFN("PCI Configspace ERROR: read daddr=%#x size=%d\n", daddr, req->size); - return No_Fault; + return NoFault; } -Fault +Fault * PciConfigAll::write(MemReqPtr &req, const uint8_t *data) { Addr daddr = (req->paddr - (addr & EV5::PAddrImplMask)); @@ -164,7 +164,7 @@ PciConfigAll::write(MemReqPtr &req, const uint8_t *data) devices[device][func]->writeConfig(reg, req->size, data); - return No_Fault; + return NoFault; } void diff --git a/dev/pciconfigall.hh b/dev/pciconfigall.hh index c6a0241d8..6df033286 100644 --- a/dev/pciconfigall.hh +++ b/dev/pciconfigall.hh @@ -103,7 +103,7 @@ class PciConfigAll : public PioDevice * @param data Return the field read. * @return The fault condition of the access. */ - virtual Fault read(MemReqPtr &req, uint8_t *data); + virtual Fault * read(MemReqPtr &req, uint8_t *data); /** * Write to PCI config spcae. If the device does not exit the simulator @@ -114,7 +114,7 @@ class PciConfigAll : public PioDevice * @return The fault condition of the access. */ - virtual Fault write(MemReqPtr &req, const uint8_t *data); + virtual Fault * write(MemReqPtr &req, const uint8_t *data); /** * Start up function to check if more than one person is using an interrupt line diff --git a/dev/pcidev.cc b/dev/pcidev.cc index 1d9ea137d..c469e716a 100644 --- a/dev/pcidev.cc +++ b/dev/pcidev.cc @@ -70,59 +70,59 @@ PciDev::PciDev(Params *p) p->configSpace->registerDevice(p->deviceNum, p->functionNum, this); } -Fault +Fault * PciDev::read(MemReqPtr &req, uint8_t *data) -{ return No_Fault; } +{ return NoFault; } -Fault +Fault * PciDev::write(MemReqPtr &req, const uint8_t *data) -{ return No_Fault; } +{ return NoFault; } -Fault +Fault * PciDev::readBar0(MemReqPtr &req, Addr daddr, uint8_t *data) { panic("not implemented"); } -Fault +Fault * PciDev::readBar1(MemReqPtr &req, Addr daddr, uint8_t *data) { panic("not implemented"); } -Fault +Fault * PciDev::readBar2(MemReqPtr &req, Addr daddr, uint8_t *data) { panic("not implemented"); } -Fault +Fault * PciDev::readBar3(MemReqPtr &req, Addr daddr, uint8_t *data) { panic("not implemented"); } -Fault +Fault * PciDev::readBar4(MemReqPtr &req, Addr daddr, uint8_t *data) { panic("not implemented"); } -Fault +Fault * PciDev::readBar5(MemReqPtr &req, Addr daddr, uint8_t *data) { panic("not implemented"); } -Fault +Fault * PciDev::writeBar0(MemReqPtr &req, Addr daddr, const uint8_t *data) { panic("not implemented"); } -Fault +Fault * PciDev::writeBar1(MemReqPtr &req, Addr daddr, const uint8_t *data) { panic("not implemented"); } -Fault +Fault * PciDev::writeBar2(MemReqPtr &req, Addr daddr, const uint8_t *data) { panic("not implemented"); } -Fault +Fault * PciDev::writeBar3(MemReqPtr &req, Addr daddr, const uint8_t *data) { panic("not implemented"); } -Fault +Fault * PciDev::writeBar4(MemReqPtr &req, Addr daddr, const uint8_t *data) { panic("not implemented"); } -Fault +Fault * PciDev::writeBar5(MemReqPtr &req, Addr daddr, const uint8_t *data) { panic("not implemented"); } diff --git a/dev/pcidev.hh b/dev/pcidev.hh index efc805b3f..c8d9685c1 100644 --- a/dev/pcidev.hh +++ b/dev/pcidev.hh @@ -189,37 +189,37 @@ class PciDev : public DmaDevice */ PciDev(Params *params); - virtual Fault read(MemReqPtr &req, uint8_t *data); - virtual Fault write(MemReqPtr &req, const uint8_t *data); + virtual Fault * read(MemReqPtr &req, uint8_t *data); + virtual Fault * write(MemReqPtr &req, const uint8_t *data); public: /** * Implement the read/write as BAR accesses */ - Fault readBar(MemReqPtr &req, uint8_t *data); - Fault writeBar(MemReqPtr &req, const uint8_t *data); + Fault * readBar(MemReqPtr &req, uint8_t *data); + Fault * writeBar(MemReqPtr &req, const uint8_t *data); public: /** * Read from a specific BAR */ - virtual Fault readBar0(MemReqPtr &req, Addr daddr, uint8_t *data); - virtual Fault readBar1(MemReqPtr &req, Addr daddr, uint8_t *data); - virtual Fault readBar2(MemReqPtr &req, Addr daddr, uint8_t *data); - virtual Fault readBar3(MemReqPtr &req, Addr daddr, uint8_t *data); - virtual Fault readBar4(MemReqPtr &req, Addr daddr, uint8_t *data); - virtual Fault readBar5(MemReqPtr &req, Addr daddr, uint8_t *data); + virtual Fault * readBar0(MemReqPtr &req, Addr daddr, uint8_t *data); + virtual Fault * readBar1(MemReqPtr &req, Addr daddr, uint8_t *data); + virtual Fault * readBar2(MemReqPtr &req, Addr daddr, uint8_t *data); + virtual Fault * readBar3(MemReqPtr &req, Addr daddr, uint8_t *data); + virtual Fault * readBar4(MemReqPtr &req, Addr daddr, uint8_t *data); + virtual Fault * readBar5(MemReqPtr &req, Addr daddr, uint8_t *data); public: /** * Write to a specific BAR */ - virtual Fault writeBar0(MemReqPtr &req, Addr daddr, const uint8_t *data); - virtual Fault writeBar1(MemReqPtr &req, Addr daddr, const uint8_t *data); - virtual Fault writeBar2(MemReqPtr &req, Addr daddr, const uint8_t *data); - virtual Fault writeBar3(MemReqPtr &req, Addr daddr, const uint8_t *data); - virtual Fault writeBar4(MemReqPtr &req, Addr daddr, const uint8_t *data); - virtual Fault writeBar5(MemReqPtr &req, Addr daddr, const uint8_t *data); + virtual Fault * writeBar0(MemReqPtr &req, Addr daddr, const uint8_t *data); + virtual Fault * writeBar1(MemReqPtr &req, Addr daddr, const uint8_t *data); + virtual Fault * writeBar2(MemReqPtr &req, Addr daddr, const uint8_t *data); + virtual Fault * writeBar3(MemReqPtr &req, Addr daddr, const uint8_t *data); + virtual Fault * writeBar4(MemReqPtr &req, Addr daddr, const uint8_t *data); + virtual Fault * writeBar5(MemReqPtr &req, Addr daddr, const uint8_t *data); public: /** @@ -257,7 +257,7 @@ class PciDev : public DmaDevice virtual void unserialize(Checkpoint *cp, const std::string §ion); }; -inline Fault +inline Fault * PciDev::readBar(MemReqPtr &req, uint8_t *data) { if (isBAR(req->paddr, 0)) @@ -272,10 +272,10 @@ PciDev::readBar(MemReqPtr &req, uint8_t *data) return readBar4(req, req->paddr - BARAddrs[4], data); if (isBAR(req->paddr, 5)) return readBar5(req, req->paddr - BARAddrs[5], data); - return Machine_Check_Fault; + return MachineCheckFault; } -inline Fault +inline Fault * PciDev::writeBar(MemReqPtr &req, const uint8_t *data) { if (isBAR(req->paddr, 0)) @@ -290,7 +290,7 @@ PciDev::writeBar(MemReqPtr &req, const uint8_t *data) return writeBar4(req, req->paddr - BARAddrs[4], data); if (isBAR(req->paddr, 5)) return writeBar5(req, req->paddr - BARAddrs[5], data); - return Machine_Check_Fault; + return MachineCheckFault; } #endif // __DEV_PCIDEV_HH__ diff --git a/dev/sinic.cc b/dev/sinic.cc index 69239df32..e79f80678 100644 --- a/dev/sinic.cc +++ b/dev/sinic.cc @@ -361,23 +361,23 @@ Device::prepareWrite(int cpu, int index) /** * I/O read of device register */ -Fault +Fault * Device::read(MemReqPtr &req, uint8_t *data) { assert(config.command & PCI_CMD_MSE); - Fault fault = readBar(req, data); + Fault * fault = readBar(req, data); - if (fault == Machine_Check_Fault) { + if (fault == MachineCheckFault) { panic("address does not map to a BAR pa=%#x va=%#x size=%d", req->paddr, req->vaddr, req->size); - return Machine_Check_Fault; + return MachineCheckFault; } return fault; } -Fault +Fault * Device::readBar0(MemReqPtr &req, Addr daddr, uint8_t *data) { int cpu = (req->xc->regs.ipr[TheISA::IPR_PALtemp16] >> 8) & 0xff; @@ -421,13 +421,13 @@ Device::readBar0(MemReqPtr &req, Addr daddr, uint8_t *data) if (raddr == Regs::IntrStatus) devIntrClear(); - return No_Fault; + return NoFault; } /** * IPR read of device register */ -Fault +Fault * Device::iprRead(Addr daddr, int cpu, uint64_t &result) { if (!regValid(daddr)) @@ -451,29 +451,29 @@ Device::iprRead(Addr daddr, int cpu, uint64_t &result) DPRINTF(EthernetPIO, "IPR read %s: cpu=%s da=%#x val=%#x\n", info.name, cpu, result); - return No_Fault; + return NoFault; } /** * I/O write of device register */ -Fault +Fault * Device::write(MemReqPtr &req, const uint8_t *data) { assert(config.command & PCI_CMD_MSE); - Fault fault = writeBar(req, data); + Fault * fault = writeBar(req, data); - if (fault == Machine_Check_Fault) { + if (fault == MachineCheckFault) { panic("address does not map to a BAR pa=%#x va=%#x size=%d", req->paddr, req->vaddr, req->size); - return Machine_Check_Fault; + return MachineCheckFault; } return fault; } -Fault +Fault * Device::writeBar0(MemReqPtr &req, Addr daddr, const uint8_t *data) { int cpu = (req->xc->regs.ipr[TheISA::IPR_PALtemp16] >> 8) & 0xff; @@ -508,7 +508,7 @@ Device::writeBar0(MemReqPtr &req, Addr daddr, const uint8_t *data) if (!pioDelayWrite || !info.delay_write) regWrite(daddr, cpu, data); - return No_Fault; + return NoFault; } void diff --git a/dev/sinic.hh b/dev/sinic.hh index af2f109a4..7935a7cdc 100644 --- a/dev/sinic.hh +++ b/dev/sinic.hh @@ -271,15 +271,15 @@ class Device : public Base * Memory Interface */ public: - virtual Fault read(MemReqPtr &req, uint8_t *data); - virtual Fault write(MemReqPtr &req, const uint8_t *data); + virtual Fault * read(MemReqPtr &req, uint8_t *data); + virtual Fault * write(MemReqPtr &req, const uint8_t *data); void prepareIO(int cpu, int index); void prepareRead(int cpu, int index); void prepareWrite(int cpu, int index); - Fault iprRead(Addr daddr, int cpu, uint64_t &result); - Fault readBar0(MemReqPtr &req, Addr daddr, uint8_t *data); - Fault writeBar0(MemReqPtr &req, Addr daddr, const uint8_t *data); + Fault * iprRead(Addr daddr, int cpu, uint64_t &result); + Fault * readBar0(MemReqPtr &req, Addr daddr, uint8_t *data); + Fault * writeBar0(MemReqPtr &req, Addr daddr, const uint8_t *data); void regWrite(Addr daddr, int cpu, const uint8_t *data); Tick cacheAccess(MemReqPtr &req); diff --git a/dev/tsunami_cchip.cc b/dev/tsunami_cchip.cc index 2287a2a3d..4cda9ec36 100644 --- a/dev/tsunami_cchip.cc +++ b/dev/tsunami_cchip.cc @@ -76,7 +76,7 @@ TsunamiCChip::TsunamiCChip(const string &name, Tsunami *t, Addr a, tsunami->cchip = this; } -Fault +Fault * TsunamiCChip::read(MemReqPtr &req, uint8_t *data) { DPRINTF(Tsunami, "read va=%#x size=%d\n", req->vaddr, req->size); @@ -92,81 +92,81 @@ TsunamiCChip::read(MemReqPtr &req, uint8_t *data) if (daddr & TSDEV_CC_BDIMS) { *(uint64_t*)data = dim[(daddr >> 4) & 0x3F]; - return No_Fault; + return NoFault; } if (daddr & TSDEV_CC_BDIRS) { *(uint64_t*)data = dir[(daddr >> 4) & 0x3F]; - return No_Fault; + return NoFault; } switch(regnum) { case TSDEV_CC_CSR: *(uint64_t*)data = 0x0; - return No_Fault; + return NoFault; case TSDEV_CC_MTR: panic("TSDEV_CC_MTR not implemeted\n"); - return No_Fault; + return NoFault; case TSDEV_CC_MISC: *(uint64_t*)data = (ipint << 8) & 0xF | (itint << 4) & 0xF | (xc->cpu_id & 0x3); - return No_Fault; + return NoFault; case TSDEV_CC_AAR0: case TSDEV_CC_AAR1: case TSDEV_CC_AAR2: case TSDEV_CC_AAR3: *(uint64_t*)data = 0; - return No_Fault; + return NoFault; case TSDEV_CC_DIM0: *(uint64_t*)data = dim[0]; - return No_Fault; + return NoFault; case TSDEV_CC_DIM1: *(uint64_t*)data = dim[1]; - return No_Fault; + return NoFault; case TSDEV_CC_DIM2: *(uint64_t*)data = dim[2]; - return No_Fault; + return NoFault; case TSDEV_CC_DIM3: *(uint64_t*)data = dim[3]; - return No_Fault; + return NoFault; case TSDEV_CC_DIR0: *(uint64_t*)data = dir[0]; - return No_Fault; + return NoFault; case TSDEV_CC_DIR1: *(uint64_t*)data = dir[1]; - return No_Fault; + return NoFault; case TSDEV_CC_DIR2: *(uint64_t*)data = dir[2]; - return No_Fault; + return NoFault; case TSDEV_CC_DIR3: *(uint64_t*)data = dir[3]; - return No_Fault; + return NoFault; case TSDEV_CC_DRIR: *(uint64_t*)data = drir; - return No_Fault; + return NoFault; case TSDEV_CC_PRBEN: panic("TSDEV_CC_PRBEN not implemented\n"); - return No_Fault; + return NoFault; case TSDEV_CC_IIC0: case TSDEV_CC_IIC1: case TSDEV_CC_IIC2: case TSDEV_CC_IIC3: panic("TSDEV_CC_IICx not implemented\n"); - return No_Fault; + return NoFault; case TSDEV_CC_MPR0: case TSDEV_CC_MPR1: case TSDEV_CC_MPR2: case TSDEV_CC_MPR3: panic("TSDEV_CC_MPRx not implemented\n"); - return No_Fault; + return NoFault; case TSDEV_CC_IPIR: *(uint64_t*)data = ipint; - return No_Fault; + return NoFault; case TSDEV_CC_ITIR: *(uint64_t*)data = itint; - return No_Fault; + return NoFault; default: panic("default in cchip read reached, accessing 0x%x\n"); } // uint64_t @@ -179,7 +179,7 @@ TsunamiCChip::read(MemReqPtr &req, uint8_t *data) *(uint32_t*)data = drir; } else panic("invalid access size(?) for tsunami register!\n"); - return No_Fault; + return NoFault; case sizeof(uint16_t): case sizeof(uint8_t): default: @@ -187,10 +187,10 @@ TsunamiCChip::read(MemReqPtr &req, uint8_t *data) } DPRINTFN("Tsunami CChip ERROR: read regnum=%#x size=%d\n", regnum, req->size); - return No_Fault; + return NoFault; } -Fault +Fault * TsunamiCChip::write(MemReqPtr &req, const uint8_t *data) { DPRINTF(Tsunami, "write - va=%#x value=%#x size=%d \n", @@ -243,16 +243,16 @@ TsunamiCChip::write(MemReqPtr &req, const uint8_t *data) } } - return No_Fault; + return NoFault; } switch(regnum) { case TSDEV_CC_CSR: panic("TSDEV_CC_CSR write\n"); - return No_Fault; + return NoFault; case TSDEV_CC_MTR: panic("TSDEV_CC_MTR write not implemented\n"); - return No_Fault; + return NoFault; case TSDEV_CC_MISC: uint64_t ipreq; ipreq = (*(uint64_t*)data >> 12) & 0xF; @@ -285,13 +285,13 @@ TsunamiCChip::write(MemReqPtr &req, const uint8_t *data) if(!supportedWrite) panic("TSDEV_CC_MISC write not implemented\n"); - return No_Fault; + return NoFault; case TSDEV_CC_AAR0: case TSDEV_CC_AAR1: case TSDEV_CC_AAR2: case TSDEV_CC_AAR3: panic("TSDEV_CC_AARx write not implemeted\n"); - return No_Fault; + return NoFault; case TSDEV_CC_DIM0: case TSDEV_CC_DIM1: case TSDEV_CC_DIM2: @@ -341,7 +341,7 @@ TsunamiCChip::write(MemReqPtr &req, const uint8_t *data) } } - return No_Fault; + return NoFault; case TSDEV_CC_DIR0: case TSDEV_CC_DIR1: case TSDEV_CC_DIR2: @@ -363,13 +363,13 @@ TsunamiCChip::write(MemReqPtr &req, const uint8_t *data) panic("TSDEV_CC_MPRx write not implemented\n"); case TSDEV_CC_IPIR: clearIPI(*(uint64_t*)data); - return No_Fault; + return NoFault; case TSDEV_CC_ITIR: clearITI(*(uint64_t*)data); - return No_Fault; + return NoFault; case TSDEV_CC_IPIQ: reqIPI(*(uint64_t*)data); - return No_Fault; + return NoFault; default: panic("default in cchip read reached, accessing 0x%x\n"); } @@ -384,7 +384,7 @@ TsunamiCChip::write(MemReqPtr &req, const uint8_t *data) DPRINTFN("Tsunami ERROR: write daddr=%#x size=%d\n", daddr, req->size); - return No_Fault; + return NoFault; } void diff --git a/dev/tsunami_cchip.hh b/dev/tsunami_cchip.hh index d88ad375f..dadbdb0e3 100644 --- a/dev/tsunami_cchip.hh +++ b/dev/tsunami_cchip.hh @@ -105,7 +105,7 @@ class TsunamiCChip : public PioDevice * @param data A pointer to write the read data to. * @return The fault condition of the access. */ - virtual Fault read(MemReqPtr &req, uint8_t *data); + virtual Fault * read(MemReqPtr &req, uint8_t *data); /** @@ -114,7 +114,7 @@ class TsunamiCChip : public PioDevice * @param data The data to write. * @return The fault condition of the access. */ - virtual Fault write(MemReqPtr &req, const uint8_t *data); + virtual Fault * write(MemReqPtr &req, const uint8_t *data); /** * post an RTC interrupt to the CPU diff --git a/dev/tsunami_io.cc b/dev/tsunami_io.cc index 724a5bfb9..0d0d27570 100644 --- a/dev/tsunami_io.cc +++ b/dev/tsunami_io.cc @@ -444,7 +444,7 @@ TsunamiIO::frequency() const return Clock::Frequency / clockInterval; } -Fault +Fault * TsunamiIO::read(MemReqPtr &req, uint8_t *data) { DPRINTF(Tsunami, "io read va=%#x size=%d IOPorrt=%#x\n", @@ -459,38 +459,38 @@ TsunamiIO::read(MemReqPtr &req, uint8_t *data) // PIC1 mask read case TSDEV_PIC1_MASK: *(uint8_t*)data = ~mask1; - return No_Fault; + return NoFault; case TSDEV_PIC2_MASK: *(uint8_t*)data = ~mask2; - return No_Fault; + return NoFault; case TSDEV_PIC1_ISR: // !!! If this is modified 64bit case needs to be too // Pal code has to do a 64 bit physical read because there is // no load physical byte instruction *(uint8_t*)data = picr; - return No_Fault; + return NoFault; case TSDEV_PIC2_ISR: // PIC2 not implemnted... just return 0 *(uint8_t*)data = 0x00; - return No_Fault; + return NoFault; case TSDEV_TMR0_DATA: pitimer.counter0.read(data); - return No_Fault; + return NoFault; case TSDEV_TMR1_DATA: pitimer.counter1.read(data); - return No_Fault; + return NoFault; case TSDEV_TMR2_DATA: pitimer.counter2.read(data); - return No_Fault; + return NoFault; case TSDEV_RTC_DATA: rtc.readData(data); - return No_Fault; + return NoFault; case TSDEV_CTRL_PORTB: if (pitimer.counter2.outputHigh()) *data = PORTB_SPKR_HIGH; else *data = 0x00; - return No_Fault; + return NoFault; default: panic("I/O Read - va%#x size %d\n", req->vaddr, req->size); } @@ -506,7 +506,7 @@ TsunamiIO::read(MemReqPtr &req, uint8_t *data) // Pal code has to do a 64 bit physical read because there is // no load physical byte instruction *(uint64_t*)data = (uint64_t)picr; - return No_Fault; + return NoFault; default: panic("I/O Read - invalid size - va %#x size %d\n", req->vaddr, req->size); @@ -518,10 +518,10 @@ TsunamiIO::read(MemReqPtr &req, uint8_t *data) } panic("I/O Read - va%#x size %d\n", req->vaddr, req->size); - return No_Fault; + return NoFault; } -Fault +Fault * TsunamiIO::write(MemReqPtr &req, const uint8_t *data) { @@ -550,63 +550,63 @@ TsunamiIO::write(MemReqPtr &req, const uint8_t *data) tsunami->cchip->clearDRIR(55); DPRINTF(Tsunami, "clearing pic interrupt\n"); } - return No_Fault; + return NoFault; case TSDEV_PIC2_MASK: mask2 = *(uint8_t*)data; //PIC2 Not implemented to interrupt - return No_Fault; + return NoFault; case TSDEV_PIC1_ACK: // clear the interrupt on the PIC picr &= ~(1 << (*(uint8_t*)data & 0xF)); if (!(picr & mask1)) tsunami->cchip->clearDRIR(55); - return No_Fault; + return NoFault; case TSDEV_DMA1_CMND: - return No_Fault; + return NoFault; case TSDEV_DMA2_CMND: - return No_Fault; + return NoFault; case TSDEV_DMA1_MMASK: - return No_Fault; + return NoFault; case TSDEV_DMA2_MMASK: - return No_Fault; + return NoFault; case TSDEV_PIC2_ACK: - return No_Fault; + return NoFault; case TSDEV_DMA1_RESET: - return No_Fault; + return NoFault; case TSDEV_DMA2_RESET: - return No_Fault; + return NoFault; case TSDEV_DMA1_MODE: mode1 = *(uint8_t*)data; - return No_Fault; + return NoFault; case TSDEV_DMA2_MODE: mode2 = *(uint8_t*)data; - return No_Fault; + return NoFault; case TSDEV_DMA1_MASK: case TSDEV_DMA2_MASK: - return No_Fault; + return NoFault; case TSDEV_TMR0_DATA: pitimer.counter0.write(data); - return No_Fault; + return NoFault; case TSDEV_TMR1_DATA: pitimer.counter1.write(data); - return No_Fault; + return NoFault; case TSDEV_TMR2_DATA: pitimer.counter2.write(data); - return No_Fault; + return NoFault; case TSDEV_TMR_CTRL: pitimer.writeControl(data); - return No_Fault; + return NoFault; case TSDEV_RTC_ADDR: rtc.writeAddr(data); - return No_Fault; + return NoFault; case TSDEV_KBD: - return No_Fault; + return NoFault; case TSDEV_RTC_DATA: rtc.writeData(data); - return No_Fault; + return NoFault; case TSDEV_CTRL_PORTB: // System Control Port B not implemented - return No_Fault; + return NoFault; default: panic("I/O Write - va%#x size %d data %#x\n", req->vaddr, req->size, (int)*data); } @@ -619,7 +619,7 @@ TsunamiIO::write(MemReqPtr &req, const uint8_t *data) } - return No_Fault; + return NoFault; } void diff --git a/dev/tsunami_io.hh b/dev/tsunami_io.hh index b024ecd14..3b26ebfaa 100644 --- a/dev/tsunami_io.hh +++ b/dev/tsunami_io.hh @@ -330,7 +330,7 @@ class TsunamiIO : public PioDevice * @param data A pointer to write the read data to. * @return The fault condition of the access. */ - virtual Fault read(MemReqPtr &req, uint8_t *data); + virtual Fault * read(MemReqPtr &req, uint8_t *data); /** * Process a write to one of the devices we emulate. @@ -338,7 +338,7 @@ class TsunamiIO : public PioDevice * @param data The data to write. * @return The fault condition of the access. */ - virtual Fault write(MemReqPtr &req, const uint8_t *data); + virtual Fault * write(MemReqPtr &req, const uint8_t *data); /** * Post an PIC interrupt to the CPU via the CChip diff --git a/dev/tsunami_pchip.cc b/dev/tsunami_pchip.cc index e61137170..a4c04a79f 100644 --- a/dev/tsunami_pchip.cc +++ b/dev/tsunami_pchip.cc @@ -76,7 +76,7 @@ TsunamiPChip::TsunamiPChip(const string &name, Tsunami *t, Addr a, tsunami->pchip = this; } -Fault +Fault * TsunamiPChip::read(MemReqPtr &req, uint8_t *data) { DPRINTF(Tsunami, "read va=%#x size=%d\n", @@ -90,60 +90,60 @@ TsunamiPChip::read(MemReqPtr &req, uint8_t *data) switch(daddr) { case TSDEV_PC_WSBA0: *(uint64_t*)data = wsba[0]; - return No_Fault; + return NoFault; case TSDEV_PC_WSBA1: *(uint64_t*)data = wsba[1]; - return No_Fault; + return NoFault; case TSDEV_PC_WSBA2: *(uint64_t*)data = wsba[2]; - return No_Fault; + return NoFault; case TSDEV_PC_WSBA3: *(uint64_t*)data = wsba[3]; - return No_Fault; + return NoFault; case TSDEV_PC_WSM0: *(uint64_t*)data = wsm[0]; - return No_Fault; + return NoFault; case TSDEV_PC_WSM1: *(uint64_t*)data = wsm[1]; - return No_Fault; + return NoFault; case TSDEV_PC_WSM2: *(uint64_t*)data = wsm[2]; - return No_Fault; + return NoFault; case TSDEV_PC_WSM3: *(uint64_t*)data = wsm[3]; - return No_Fault; + return NoFault; case TSDEV_PC_TBA0: *(uint64_t*)data = tba[0]; - return No_Fault; + return NoFault; case TSDEV_PC_TBA1: *(uint64_t*)data = tba[1]; - return No_Fault; + return NoFault; case TSDEV_PC_TBA2: *(uint64_t*)data = tba[2]; - return No_Fault; + return NoFault; case TSDEV_PC_TBA3: *(uint64_t*)data = tba[3]; - return No_Fault; + return NoFault; case TSDEV_PC_PCTL: *(uint64_t*)data = pctl; - return No_Fault; + return NoFault; case TSDEV_PC_PLAT: panic("PC_PLAT not implemented\n"); case TSDEV_PC_RES: panic("PC_RES not implemented\n"); case TSDEV_PC_PERROR: *(uint64_t*)data = 0x00; - return No_Fault; + return NoFault; case TSDEV_PC_PERRMASK: *(uint64_t*)data = 0x00; - return No_Fault; + return NoFault; case TSDEV_PC_PERRSET: panic("PC_PERRSET not implemented\n"); case TSDEV_PC_TLBIV: panic("PC_TLBIV not implemented\n"); case TSDEV_PC_TLBIA: *(uint64_t*)data = 0x00; // shouldn't be readable, but linux - return No_Fault; + return NoFault; case TSDEV_PC_PMONCTL: panic("PC_PMONCTL not implemented\n"); case TSDEV_PC_PMONCNT: @@ -162,10 +162,10 @@ TsunamiPChip::read(MemReqPtr &req, uint8_t *data) } DPRINTFN("Tsunami PChip ERROR: read daddr=%#x size=%d\n", daddr, req->size); - return No_Fault; + return NoFault; } -Fault +Fault * TsunamiPChip::write(MemReqPtr &req, const uint8_t *data) { DPRINTF(Tsunami, "write - va=%#x size=%d \n", @@ -179,49 +179,49 @@ TsunamiPChip::write(MemReqPtr &req, const uint8_t *data) switch(daddr) { case TSDEV_PC_WSBA0: wsba[0] = *(uint64_t*)data; - return No_Fault; + return NoFault; case TSDEV_PC_WSBA1: wsba[1] = *(uint64_t*)data; - return No_Fault; + return NoFault; case TSDEV_PC_WSBA2: wsba[2] = *(uint64_t*)data; - return No_Fault; + return NoFault; case TSDEV_PC_WSBA3: wsba[3] = *(uint64_t*)data; - return No_Fault; + return NoFault; case TSDEV_PC_WSM0: wsm[0] = *(uint64_t*)data; - return No_Fault; + return NoFault; case TSDEV_PC_WSM1: wsm[1] = *(uint64_t*)data; - return No_Fault; + return NoFault; case TSDEV_PC_WSM2: wsm[2] = *(uint64_t*)data; - return No_Fault; + return NoFault; case TSDEV_PC_WSM3: wsm[3] = *(uint64_t*)data; - return No_Fault; + return NoFault; case TSDEV_PC_TBA0: tba[0] = *(uint64_t*)data; - return No_Fault; + return NoFault; case TSDEV_PC_TBA1: tba[1] = *(uint64_t*)data; - return No_Fault; + return NoFault; case TSDEV_PC_TBA2: tba[2] = *(uint64_t*)data; - return No_Fault; + return NoFault; case TSDEV_PC_TBA3: tba[3] = *(uint64_t*)data; - return No_Fault; + return NoFault; case TSDEV_PC_PCTL: pctl = *(uint64_t*)data; - return No_Fault; + return NoFault; case TSDEV_PC_PLAT: panic("PC_PLAT not implemented\n"); case TSDEV_PC_RES: panic("PC_RES not implemented\n"); case TSDEV_PC_PERROR: - return No_Fault; + return NoFault; case TSDEV_PC_PERRMASK: panic("PC_PERRMASK not implemented\n"); case TSDEV_PC_PERRSET: @@ -229,7 +229,7 @@ TsunamiPChip::write(MemReqPtr &req, const uint8_t *data) case TSDEV_PC_TLBIV: panic("PC_TLBIV not implemented\n"); case TSDEV_PC_TLBIA: - return No_Fault; // value ignored, supposted to invalidate SG TLB + return NoFault; // value ignored, supposted to invalidate SG TLB case TSDEV_PC_PMONCTL: panic("PC_PMONCTL not implemented\n"); case TSDEV_PC_PMONCNT: @@ -249,7 +249,7 @@ TsunamiPChip::write(MemReqPtr &req, const uint8_t *data) DPRINTFN("Tsunami ERROR: write daddr=%#x size=%d\n", daddr, req->size); - return No_Fault; + return NoFault; } #define DMA_ADDR_MASK ULL(0x3ffffffff) diff --git a/dev/tsunami_pchip.hh b/dev/tsunami_pchip.hh index c1d95431b..ff888bea1 100644 --- a/dev/tsunami_pchip.hh +++ b/dev/tsunami_pchip.hh @@ -99,7 +99,7 @@ class TsunamiPChip : public PioDevice * @param data A pointer to write the read data to. * @return The fault condition of the access. */ - virtual Fault read(MemReqPtr &req, uint8_t *data); + virtual Fault * read(MemReqPtr &req, uint8_t *data); /** * Process a write to the PChip. @@ -107,7 +107,7 @@ class TsunamiPChip : public PioDevice * @param data The data to write. * @return The fault condition of the access. */ - virtual Fault write(MemReqPtr &req, const uint8_t *data); + virtual Fault * write(MemReqPtr &req, const uint8_t *data); /** * Serialize this object to the given output stream. diff --git a/dev/uart.hh b/dev/uart.hh index 145b9ca9e..96c22025c 100644 --- a/dev/uart.hh +++ b/dev/uart.hh @@ -57,8 +57,8 @@ class Uart : public PioDevice Addr a, Addr s, HierParams *hier, Bus *bus, Tick pio_latency, Platform *p); - virtual Fault read(MemReqPtr &req, uint8_t *data) = 0; - virtual Fault write(MemReqPtr &req, const uint8_t *data) = 0; + virtual Fault * read(MemReqPtr &req, uint8_t *data) = 0; + virtual Fault * write(MemReqPtr &req, const uint8_t *data) = 0; /** diff --git a/dev/uart8250.cc b/dev/uart8250.cc index 71f429069..a2e782189 100644 --- a/dev/uart8250.cc +++ b/dev/uart8250.cc @@ -111,7 +111,7 @@ Uart8250::Uart8250(const string &name, SimConsole *c, MemoryController *mmu, } -Fault +Fault * Uart8250::read(MemReqPtr &req, uint8_t *data) { Addr daddr = req->paddr - (addr & EV5::PAddrImplMask); @@ -183,11 +183,11 @@ Uart8250::read(MemReqPtr &req, uint8_t *data) break; } - return No_Fault; + return NoFault; } -Fault +Fault * Uart8250::write(MemReqPtr &req, const uint8_t *data) { Addr daddr = req->paddr - (addr & EV5::PAddrImplMask); @@ -255,7 +255,7 @@ Uart8250::write(MemReqPtr &req, const uint8_t *data) panic("Tried to access a UART port that doesn't exist\n"); break; } - return No_Fault; + return NoFault; } void diff --git a/dev/uart8250.hh b/dev/uart8250.hh index 88abf8e24..a0e2d344a 100644 --- a/dev/uart8250.hh +++ b/dev/uart8250.hh @@ -82,8 +82,8 @@ class Uart8250 : public Uart Addr a, Addr s, HierParams *hier, Bus *pio_bus, Tick pio_latency, Platform *p); - virtual Fault read(MemReqPtr &req, uint8_t *data); - virtual Fault write(MemReqPtr &req, const uint8_t *data); + virtual Fault * read(MemReqPtr &req, uint8_t *data); + virtual Fault * write(MemReqPtr &req, const uint8_t *data); /** diff --git a/kern/kernel_stats.cc b/kern/kernel_stats.cc index 3a7d12443..50bbaee00 100644 --- a/kern/kernel_stats.cc +++ b/kern/kernel_stats.cc @@ -137,14 +137,14 @@ Statistics::regStats(const string &_name) } _faults - .init(Num_Faults) + .init(NumFaults) .name(name() + ".faults") .desc("number of faults") .flags(total | pdf | nozero | nonan) ; - for (int i = 1; i < Num_Faults; ++i) { - const char *str = FaultName(i); + for (int i = 1; i < NumFaults; ++i) { + const char *str = (*ListOfFaults[i])->name; if (str) _faults.subname(i, str); } diff --git a/kern/kernel_stats.hh b/kern/kernel_stats.hh index 62dd84a28..98cc044ac 100644 --- a/kern/kernel_stats.hh +++ b/kern/kernel_stats.hh @@ -41,7 +41,7 @@ class ExecContext; class FnEvent; // What does kernel stats expect is included? class System; -enum Fault; +class Fault; namespace Kernel { @@ -176,7 +176,14 @@ class Statistics : public Serializable void ivlb() { _ivlb++; } void ivle() { _ivle++; } void hwrei() { _hwrei++; } - void fault(Fault fault) { _faults[fault]++; } + void fault(Fault * fault) + { + if(fault == NoFault) _faults[0]++; + else if(fault == MachineCheckFault) _faults[2]++; + else if(fault == AlignmentFault) _faults[7]++; + else if(fault == FakeMemFault) _faults[17]++; + else _faults[fault->id]++; + }// FIXME: When there are no generic system fault objects, this will go back to _faults[fault]++; } void swpipl(int ipl); void mode(cpu_mode newmode); void context(Addr oldpcbb, Addr newpcbb); diff --git a/sim/faults.cc b/sim/faults.cc new file mode 100644 index 000000000..640f439c4 --- /dev/null +++ b/sim/faults.cc @@ -0,0 +1,36 @@ +/* + * 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 "sim/faults.hh" + +NoFaultType * NoFault = new NoFaultType("none"); +MachineCheckFaultType * MachineCheckFault = new MachineCheckFaultType("mchk"); +AlignmentFaultType * AlignmentFault = new AlignmentFaultType("unalign"); +//This needs to not exist +FakeMemFaultType * FakeMemFault = new FakeMemFaultType("fakemem"); + diff --git a/sim/faults.hh b/sim/faults.hh new file mode 100644 index 000000000..bc2c35c64 --- /dev/null +++ b/sim/faults.hh @@ -0,0 +1,65 @@ +/* + * 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 __FAULTS_HH__ +#define __FAULTS_HH__ + +class Fault +{ +public: + Fault(char * newName, int newId = 0) : name(newName), id(newId) {;} + const char * name; + int id; +}; + +extern class NoFaultType : public Fault +{ +public: + NoFaultType(char * newName) : Fault(newName) {;} +} * NoFault; + +extern class MachineCheckFaultType : public Fault +{ +public: + MachineCheckFaultType(char * newName) : Fault(newName) {;} +} * MachineCheckFault; + +extern class AlignmentFaultType : public Fault +{ +public: + AlignmentFaultType(char * newName) : Fault(newName) {;} +} * AlignmentFault; + +extern class FakeMemFaultType : public Fault +{ +public: + FakeMemFaultType(char * newName) : Fault(newName) {;} +} * FakeMemFault; + + +#endif // __FAULTS_HH__ diff --git a/sim/syscall_emul.cc b/sim/syscall_emul.cc index 4b6388a41..0fac43fc5 100644 --- a/sim/syscall_emul.cc +++ b/sim/syscall_emul.cc @@ -191,7 +191,7 @@ unlinkFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) { string path; - if (xc->mem->readString(path, xc->getSyscallArg(0)) != No_Fault) + if (xc->mem->readString(path, xc->getSyscallArg(0)) != NoFault) return (TheISA::IntReg)-EFAULT; int result = unlink(path.c_str()); @@ -203,12 +203,12 @@ renameFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) { string old_name; - if (xc->mem->readString(old_name, xc->getSyscallArg(0)) != No_Fault) + if (xc->mem->readString(old_name, xc->getSyscallArg(0)) != NoFault) return -EFAULT; string new_name; - if (xc->mem->readString(new_name, xc->getSyscallArg(1)) != No_Fault) + if (xc->mem->readString(new_name, xc->getSyscallArg(1)) != NoFault) return -EFAULT; int64_t result = rename(old_name.c_str(), new_name.c_str()); @@ -220,7 +220,7 @@ truncateFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) { string path; - if (xc->mem->readString(path, xc->getSyscallArg(0)) != No_Fault) + if (xc->mem->readString(path, xc->getSyscallArg(0)) != NoFault) return -EFAULT; off_t length = xc->getSyscallArg(1); @@ -248,7 +248,7 @@ chownFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) { string path; - if (xc->mem->readString(path, xc->getSyscallArg(0)) != No_Fault) + if (xc->mem->readString(path, xc->getSyscallArg(0)) != NoFault) return -EFAULT; /* XXX endianess */ diff --git a/sim/syscall_emul.hh b/sim/syscall_emul.hh index 4e247ed55..488797b67 100644 --- a/sim/syscall_emul.hh +++ b/sim/syscall_emul.hh @@ -317,7 +317,7 @@ openFunc(SyscallDesc *desc, int callnum, Process *process, { std::string path; - if (xc->mem->readString(path, xc->getSyscallArg(0)) != No_Fault) + if (xc->mem->readString(path, xc->getSyscallArg(0)) != NoFault) return -EFAULT; if (path == "/dev/sysdev0") { @@ -364,7 +364,7 @@ chmodFunc(SyscallDesc *desc, int callnum, Process *process, { std::string path; - if (xc->mem->readString(path, xc->getSyscallArg(0)) != No_Fault) + if (xc->mem->readString(path, xc->getSyscallArg(0)) != NoFault) return -EFAULT; uint32_t mode = xc->getSyscallArg(1); @@ -417,7 +417,7 @@ statFunc(SyscallDesc *desc, int callnum, Process *process, { std::string path; - if (xc->mem->readString(path, xc->getSyscallArg(0)) != No_Fault) + if (xc->mem->readString(path, xc->getSyscallArg(0)) != NoFault) return -EFAULT; struct stat hostBuf; @@ -469,7 +469,7 @@ lstatFunc(SyscallDesc *desc, int callnum, Process *process, { std::string path; - if (xc->mem->readString(path, xc->getSyscallArg(0)) != No_Fault) + if (xc->mem->readString(path, xc->getSyscallArg(0)) != NoFault) return -EFAULT; struct stat hostBuf; @@ -491,7 +491,7 @@ lstat64Func(SyscallDesc *desc, int callnum, Process *process, { std::string path; - if (xc->mem->readString(path, xc->getSyscallArg(0)) != No_Fault) + if (xc->mem->readString(path, xc->getSyscallArg(0)) != NoFault) return -EFAULT; #if BSD_HOST @@ -542,7 +542,7 @@ statfsFunc(SyscallDesc *desc, int callnum, Process *process, { std::string path; - if (xc->mem->readString(path, xc->getSyscallArg(0)) != No_Fault) + if (xc->mem->readString(path, xc->getSyscallArg(0)) != NoFault) return -EFAULT; struct statfs hostBuf; @@ -712,7 +712,7 @@ utimesFunc(SyscallDesc *desc, int callnum, Process *process, { std::string path; - if (xc->mem->readString(path, xc->getSyscallArg(0)) != No_Fault) + if (xc->mem->readString(path, xc->getSyscallArg(0)) != NoFault) return -EFAULT; TypedBufferArg tp(xc->getSyscallArg(1)); From 00f451cc02373a22023f1e32ba3823a1d07adb42 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Thu, 16 Feb 2006 02:08:13 -0500 Subject: [PATCH 054/180] Some changes which weren't needed before doing a bk pull were needed afterwards, for some reason. arch/alpha/ev5.cc: Took out the unnecessary check for a null Fault pointer. arch/alpha/isa/mem.isa: Changed Fault to Fault *, and removed underscores from fault names. --HG-- extra : convert_revision : 367a58a375f911185ddcc5fc826034af96427461 --- arch/alpha/ev5.cc | 4 ++-- arch/alpha/isa/mem.isa | 46 +++++++++++++++++++++--------------------- 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/arch/alpha/ev5.cc b/arch/alpha/ev5.cc index 9d14be4d5..a48609729 100644 --- a/arch/alpha/ev5.cc +++ b/arch/alpha/ev5.cc @@ -180,8 +180,8 @@ AlphaISA::zeroRegisters(CPU *cpu) void ExecContext::ev5_trap(Fault * fault) { - DPRINTF(Fault, "Fault %s at PC: %#x\n", fault ? fault->name : "none", regs.pc); - cpu->recordEvent(csprintf("Fault %s", fault ? fault->name : "none")); + DPRINTF(Fault, "Fault %s at PC: %#x\n", fault->name, regs.pc); + cpu->recordEvent(csprintf("Fault %s", fault->name)); assert(!misspeculating()); kernelStats->fault(fault); diff --git a/arch/alpha/isa/mem.isa b/arch/alpha/isa/mem.isa index 19785e3a8..0b79bc376 100644 --- a/arch/alpha/isa/mem.isa +++ b/arch/alpha/isa/mem.isa @@ -173,12 +173,12 @@ def template LoadStoreDeclare {{ def template InitiateAccDeclare {{ - Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const; + Fault * initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const; }}; def template CompleteAccDeclare {{ - Fault completeAcc(uint8_t *, %(CPU_exec_context)s *, Trace::InstRecord *) const; + Fault * completeAcc(uint8_t *, %(CPU_exec_context)s *, Trace::InstRecord *) const; }}; @@ -283,11 +283,11 @@ def template LoadExecute {{ def template LoadInitiateAcc {{ - Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, + Fault * %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const { Addr EA; - Fault fault = No_Fault; + Fault * fault = NoFault; %(mem_acc_type)s Mem = 0; %(fp_enable_check)s; @@ -295,7 +295,7 @@ def template LoadInitiateAcc {{ %(op_rd)s; %(ea_code)s; - if (fault == No_Fault) { + if (fault == NoFault) { fault = xc->read(EA, (uint%(mem_acc_size)d_t &)Mem, memAccessFlags); } @@ -305,11 +305,11 @@ def template LoadInitiateAcc {{ def template LoadCompleteAcc {{ - Fault %(class_name)s::completeAcc(uint8_t *data, + Fault * %(class_name)s::completeAcc(uint8_t *data, %(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const { - Fault fault = No_Fault; + Fault * fault = NoFault; %(mem_acc_type)s Mem = 0; %(fp_enable_check)s; @@ -317,11 +317,11 @@ def template LoadCompleteAcc {{ memcpy(&Mem, data, sizeof(Mem)); - if (fault == No_Fault) { + if (fault == NoFault) { %(memacc_code)s; } - if (fault == No_Fault) { + if (fault == NoFault) { %(op_wb)s; } @@ -403,11 +403,11 @@ def template StoreExecute {{ }}; def template StoreInitiateAcc {{ - Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, + Fault * %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const { Addr EA; - Fault fault = No_Fault; + Fault * fault = NoFault; uint64_t write_result = 0; %(mem_acc_type)s Mem = 0; @@ -416,11 +416,11 @@ def template StoreInitiateAcc {{ %(op_rd)s; %(ea_code)s; - if (fault == No_Fault) { + if (fault == NoFault) { %(memacc_code)s; } - if (fault == No_Fault) { + if (fault == NoFault) { fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, memAccessFlags, &write_result); if (traceData) { traceData->setData(Mem); } @@ -432,11 +432,11 @@ def template StoreInitiateAcc {{ def template StoreCompleteAcc {{ - Fault %(class_name)s::completeAcc(uint8_t *data, + Fault * %(class_name)s::completeAcc(uint8_t *data, %(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const { - Fault fault = No_Fault; + Fault * fault = NoFault; uint64_t write_result = 0; %(fp_enable_check)s; @@ -444,11 +444,11 @@ def template StoreCompleteAcc {{ memcpy(&write_result, data, sizeof(write_result)); - if (fault == No_Fault) { + if (fault == NoFault) { %(postacc_code)s; } - if (fault == No_Fault) { + if (fault == NoFault) { %(op_wb)s; } @@ -498,32 +498,32 @@ def template MiscExecute {{ }}; def template MiscInitiateAcc {{ - Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, + Fault * %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const { Addr EA; - Fault fault = No_Fault; + Fault * fault = NoFault; %(fp_enable_check)s; %(op_decl)s; %(op_rd)s; %(ea_code)s; - if (fault == No_Fault) { + if (fault == NoFault) { %(memacc_code)s; } - return No_Fault; + return NoFault; } }}; def template MiscCompleteAcc {{ - Fault %(class_name)s::completeAcc(uint8_t *data, + Fault * %(class_name)s::completeAcc(uint8_t *data, %(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const { - return No_Fault; + return NoFault; } }}; From 7c9ea671aff141bc0a3e7acc892794e7e8181cf3 Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Thu, 16 Feb 2006 02:39:46 -0500 Subject: [PATCH 055/180] file name changes ... minor ISA changes arch/mips/isa/base.isa: restoring base.isa file ... arch/mips/isa/formats/basic.isa: add c++ emacs header arch/mips/isa/formats/branch.isa: added branch likely format arch/mips/isa/formats/int.isa: small change to python code --HG-- extra : convert_revision : defd592abb1a724f5f88b19c197b858420e92d17 --- arch/mips/isa/base.isa | 35 +++-------- arch/mips/isa/formats/basic.isa | 1 + arch/mips/isa/formats/branch.isa | 104 ++++++++++++++----------------- arch/mips/isa/formats/int.isa | 29 +++++++-- 4 files changed, 79 insertions(+), 90 deletions(-) diff --git a/arch/mips/isa/base.isa b/arch/mips/isa/base.isa index b504f1906..99fa302c0 100644 --- a/arch/mips/isa/base.isa +++ b/arch/mips/isa/base.isa @@ -1,18 +1,21 @@ +// -*- mode:c++ -*- + //////////////////////////////////////////////////////////////////// // -// Base class for sparc instructions, and some support functions +// Base class for MIPS instructions, and some support functions // +//Outputs to decoder.hh output header {{ /** * Base class for all SPARC static instructions. */ - class SparcStaticInst : public StaticInst + class MipsStaticInst : public StaticInst { protected: // Constructor. - SparcStaticInst(const char *mnem, MachInst _machInst, OpClass __opClass) + MipsStaticInst(const char *mnem, MachInst _machInst, OpClass __opClass) : StaticInst(mnem, _machInst, __opClass) { } @@ -20,12 +23,12 @@ output header {{ std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; }; - bool passesCondition(struct {uint8_t c:1; uint8_t v:1; uint8_t z:1; uint8_t n:1} codes, uint8_t condition); }}; +//Ouputs to decoder.cc output decoder {{ - std::string SparcStaticInst::generateDisassembly(Addr pc, const SymbolTable *symtab) const + std::string MipsStaticInst::generateDisassembly(Addr pc, const SymbolTable *symtab) const { std::stringstream ss; @@ -56,27 +59,5 @@ output decoder {{ return ss.str(); } - bool passesCondition(struct {uint8_t c:1; uint8_t v:1; uint8_t z:1; uint8_t n:1} codes, uint8_t condition) - { - switch(condition) - { - case 0b1000: return true; - case 0b0000: return false; - case 0b1001: return !codes.z; - case 0b0001: return codes.z; - case 0b1010: return !(codes.z | (codes.n ^ codes.v)); - case 0b0010: return codes.z | (codes.n ^ codes.v); - case 0b1011: return !(codes.n ^ codes.v); - case 0b0011: return (codes.n ^ codes.v); - case 0b1100: return !(codes.c | codes.z); - case 0b0100: return (codes.c | codes.z); - case 0b1101: return !codes.c; - case 0b0101: return codes.c; - case 0b1110: return !codes.n; - case 0b0110: return codes.n; - case 0b1111: return !codes.v; - case 0b0111: return codes.v; - } - } }}; diff --git a/arch/mips/isa/formats/basic.isa b/arch/mips/isa/formats/basic.isa index fc97c6ffa..24c397685 100644 --- a/arch/mips/isa/formats/basic.isa +++ b/arch/mips/isa/formats/basic.isa @@ -1,3 +1,4 @@ +// -*- mode:c++ -*- // Declarations for execute() methods. def template BasicExecDeclare {{ diff --git a/arch/mips/isa/formats/branch.isa b/arch/mips/isa/formats/branch.isa index e9c790c53..45980349d 100644 --- a/arch/mips/isa/formats/branch.isa +++ b/arch/mips/isa/formats/branch.isa @@ -1,30 +1,9 @@ -// -*- mode:c++ -*- +e// -*- mode:c++ -*- -// 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. +// Control transfer instructions // -// 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. output header {{ @@ -37,18 +16,19 @@ output header {{ * where the disassembly string includes the target address (which * may depend on the PC and/or symbol table). */ - class PCDependentDisassembly : public AlphaStaticInst + class PCDependentDisassembly : public MipsStaticInst { protected: /// Cached program counter from last disassembly mutable Addr cachedPC; + /// Cached symbol table pointer from last disassembly mutable const SymbolTable *cachedSymtab; /// Constructor PCDependentDisassembly(const char *mnem, MachInst _machInst, OpClass __opClass) - : AlphaStaticInst(mnem, _machInst, __opClass), + : MipsStaticInst(mnem, _machInst, __opClass), cachedPC(0), cachedSymtab(0) { } @@ -64,13 +44,36 @@ output header {{ class Branch : public PCDependentDisassembly { protected: - /// Displacement to target address (signed). - int32_t disp; + /// target address (signed) Displacement . + int32_t targetOffset; /// Constructor. Branch(const char *mnem, MachInst _machInst, OpClass __opClass) : PCDependentDisassembly(mnem, _machInst, __opClass), - disp(BRDISP << 2) + targetOffset(OFFSET << 2) + { + } + + Addr branchTarget(Addr branchPC) const; + + std::string + generateDisassembly(Addr pc, const SymbolTable *symtab) const; + }; + + /** + * Base class for branches (PC-relative control transfers), + * conditional or unconditional. + */ + class BranchLikely : public PCDependentDisassembly + { + protected: + /// target address (signed) Displacement . + int32_t targetOffset; + + /// Constructor. + Branch(const char *mnem, MachInst _machInst, OpClass __opClass) + : PCDependentDisassembly(mnem, _machInst, __opClass), + targetOffset(OFFSET << 2) { } @@ -82,7 +85,7 @@ output header {{ /** * Base class for jumps (register-indirect control transfers). In - * the Alpha ISA, these are always unconditional. + * the Mips ISA, these are always unconditional. */ class Jump : public PCDependentDisassembly { @@ -95,7 +98,7 @@ output header {{ /// Constructor Jump(const char *mnem, MachInst _machInst, OpClass __opClass) : PCDependentDisassembly(mnem, _machInst, __opClass), - disp(BRDISP) + disp(OFFSET) { } @@ -204,12 +207,12 @@ output decoder {{ }}; def template JumpOrBranchDecode {{ - return (RA == 31) - ? (StaticInst *)new %(class_name)s(machInst) - : (StaticInst *)new %(class_name)sAndLink(machInst); + return (RD == 0) + ? (StaticInst *)new %(class_name)s(machInst) + : (StaticInst *)new %(class_name)sAndLink(machInst); }}; -def format CondBranch(code) {{ +def format Branch(code) {{ code = 'bool cond;\n' + code + '\nif (cond) NPC = NPC + disp;\n'; iop = InstObjParams(name, Name, 'Branch', CodeBlock(code), ('IsDirectControl', 'IsCondControl')) @@ -219,31 +222,18 @@ def format CondBranch(code) {{ exec_output = BasicExecute.subst(iop) }}; -let {{ -def UncondCtrlBase(name, Name, base_class, npc_expr, flags): - # Declare basic control transfer w/o link (i.e. link reg is R31) - nolink_code = 'NPC = %s;\n' % npc_expr - nolink_iop = InstObjParams(name, Name, base_class, - CodeBlock(nolink_code), flags) - header_output = BasicDeclare.subst(nolink_iop) - decoder_output = BasicConstructor.subst(nolink_iop) - exec_output = BasicExecute.subst(nolink_iop) - # Generate declaration of '*AndLink' version, append to decls - link_code = 'Ra = NPC & ~3;\n' + nolink_code - link_iop = InstObjParams(name, Name + 'AndLink', base_class, - CodeBlock(link_code), flags) - header_output += BasicDeclare.subst(link_iop) - decoder_output += BasicConstructor.subst(link_iop) - exec_output += BasicExecute.subst(link_iop) - - # need to use link_iop for the decode template since it is expecting - # the shorter version of class_name (w/o "AndLink") - - return (header_output, decoder_output, - JumpOrBranchDecode.subst(nolink_iop), exec_output) +def format BranchLikely(code) {{ + code = 'bool cond;\n' + code + '\nif (cond) NPC = NPC + disp;\n'; + iop = InstObjParams(name, Name, 'Branch', CodeBlock(code), + ('IsDirectControl', 'IsCondControl')) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecode.subst(iop) + exec_output = BasicExecute.subst(iop) }}; + def format UncondBranch(*flags) {{ flags += ('IsUncondControl', 'IsDirectControl') (header_output, decoder_output, decode_block, exec_output) = \ diff --git a/arch/mips/isa/formats/int.isa b/arch/mips/isa/formats/int.isa index 521f3a130..982992b41 100644 --- a/arch/mips/isa/formats/int.isa +++ b/arch/mips/isa/formats/int.isa @@ -1,8 +1,11 @@ +// -*- mode:c++ -*- + //////////////////////////////////////////////////////////////////// // // Integer operate instructions // +//Outputs to decoder.hh output header {{ /** * Base class for integer operations. @@ -12,7 +15,7 @@ output header {{ protected: /// Constructor - IntegerOp(const char *mnem, MachInst _machInst, OpClass __opClass) : + IntOp(const char *mnem, MachInst _machInst, OpClass __opClass) : MipsStaticInst(mnem, _machInst, __opClass) { } @@ -26,7 +29,7 @@ output header {{ uint16_t imm; /// Constructor - IntegerOp(const char *mnem, MachInst _machInst, OpClass __opClass) : + IntImmOp(const char *mnem, MachInst _machInst, OpClass __opClass) : MipsStaticInst(mnem, _machInst, __opClass),imm(INTIMM) { } @@ -36,6 +39,7 @@ output header {{ }}; +//Outputs to decoder.cc output decoder {{ std::string IntOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const { @@ -48,17 +52,30 @@ output decoder {{ } }}; -// Primary format for integer operate instructions: + +// integer & FP operate instructions use Rd as dest, so check for +// Rd == 0 to detect nops +def template OperateNopCheckDecode {{ + { + MipsStaticInst *i = new %(class_name)s(machInst); + if (RD == 0) { + i = makeNop(i); + } + return i; + } +}}; + +//Used by decoder.isa def format IntOp(code, *opt_flags) {{ orig_code = code cblk = CodeBlock(code) # Figure out if we are creating a IntImmOp or a IntOp + # by looking at the instruction name + iop = InstObjParams(name, Name, 'IntOp', cblk, opt_flags) strlen = len(name) if name[strlen-1] == 'i' or name[strlen-2:] == 'iu': - iop = InstObjParams(name, Name, 'IntOp', cblk, opt_flags) - else: - iop = InstObjParams(name, Name, 'IntImmOp', cblk, opt_flags) + iop = InstObjParams(name, Name, 'IntImmOp', cblk, opt_flags) header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) From 7446238118bf15ce7844759ef216b138bb2b13d3 Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Thu, 16 Feb 2006 02:51:04 -0500 Subject: [PATCH 056/180] Get ISA parser to at least include all the ISA correctly ... crashes with "None" error arch/mips/isa/decoder.isa: CondBranch format split up into Branch & BranchLikely formats arch/mips/isa/formats.isa: include util.isa arch/mips/isa/formats/branch.isa: erroneous 'e' at top of code arch/mips/isa/formats/util.isa: util.isa --HG-- extra : convert_revision : 4fc44a05e2838749e66cd70f210e8a718b34cbf3 --- arch/mips/isa/decoder.isa | 19 +++++++++++++------ arch/mips/isa/formats.isa | 4 +++- arch/mips/isa/formats/branch.isa | 2 +- arch/mips/isa/formats/util.isa | 26 ++++++++++++++++++++++++++ 4 files changed, 43 insertions(+), 8 deletions(-) create mode 100644 arch/mips/isa/formats/util.isa diff --git a/arch/mips/isa/decoder.isa b/arch/mips/isa/decoder.isa index 6bb5bf4d8..62b0c1b7e 100644 --- a/arch/mips/isa/decoder.isa +++ b/arch/mips/isa/decoder.isa @@ -1,3 +1,5 @@ +// -*- mode:c++ -*- + //////////////////////////////////////////////////////////////////// // // The actual MIPS32 ISA decoder @@ -144,10 +146,13 @@ decode OPCODE_HI default Unknown::unknown() { 0x1: decode REGIMM_HI { 0x0: decode REGIMM_LO { - format CondBranch { + format Branch { 0x0: bltz({{ cond = (Rs.sw < 0); }}); 0x1: bgez({{ cond = (Rs.sw >= 0); }}); + } + + format BranchLikely { //MIPS obsolete instructions 0x2: bltzl({{ cond = (Rs.sw < 0); }}); 0x3: bgezl({{ cond = (Rs.sw >= 0); }}); @@ -166,10 +171,12 @@ decode OPCODE_HI default Unknown::unknown() { } 0x2: decode REGIMM_LO { - format CondBranch { + format Branch { 0x0: bltzal({{ cond = (Rs.sw < 0); }}); 0x1: bgezal({{ cond = (Rs.sw >= 0); }}); + } + format BranchLikely { //MIPS obsolete instructions 0x2: bltzall({{ cond = (Rs.sw < 0); }}); 0x3: bgezall({{ cond = (Rs.sw >= 0); }}); @@ -188,7 +195,7 @@ decode OPCODE_HI default Unknown::unknown() { 0x3: jal(IsCall); } - format CondBranch { + format Branch { 0x4: beq({{ cond = (Rs.sw == 0); }}); 0x5: bne({{ cond = (Rs.sw != 0); }}); 0x6: blez({{ cond = (Rs.sw <= 0); }}); @@ -360,14 +367,14 @@ decode OPCODE_HI default Unknown::unknown() { 0x1: decode ND { 0x0: decode TF { - format CondBranch { + format Branch { 0x0: bc1f({{ cond = (xc->miscRegs.fpcr == 0); }}); 0x1: bc1t({{ cond = (xc->miscRegs.fpcr == 1); }}); } } 0x1: decode TF { - format CondBranch { + format BranchLikely { 0x0: bc1fl({{ cond = (xc->miscRegs.fpcr == 0); }}); 0x1: bc1tl({{ cond = (xc->miscRegs.fpcr == 1); }}); } @@ -737,7 +744,7 @@ decode OPCODE_HI default Unknown::unknown() { } //MIPS obsolete instructions - format CondBranch { + format BranchLikely { 0x4: beql({{ cond = (Rs.sw == 0); }}); 0x5: bnel({{ cond = (Rs.sw != 0); }}); 0x6: blezl({{ cond = (Rs.sw <= 0); }}); diff --git a/arch/mips/isa/formats.isa b/arch/mips/isa/formats.isa index 20ef49d82..61ac185d3 100644 --- a/arch/mips/isa/formats.isa +++ b/arch/mips/isa/formats.isa @@ -1,5 +1,7 @@ -//Include the basic format //Templates from this format are used later +##include "m5/arch/mips/isa/formats/util.isa" + +//Include the basic format ##include "m5/arch/mips/isa/formats/basic.isa" //Include the integerOp and integerOpCc format diff --git a/arch/mips/isa/formats/branch.isa b/arch/mips/isa/formats/branch.isa index 45980349d..c7c97c2c8 100644 --- a/arch/mips/isa/formats/branch.isa +++ b/arch/mips/isa/formats/branch.isa @@ -1,4 +1,4 @@ -e// -*- mode:c++ -*- +// -*- mode:c++ -*- //////////////////////////////////////////////////////////////////// // diff --git a/arch/mips/isa/formats/util.isa b/arch/mips/isa/formats/util.isa new file mode 100644 index 000000000..c6dae6783 --- /dev/null +++ b/arch/mips/isa/formats/util.isa @@ -0,0 +1,26 @@ +// -*- mode:c++ -*- + +let {{ +def UncondCtrlBase(name, Name, base_class, npc_expr, flags): + # Declare basic control transfer w/o link (i.e. link reg is R31) + nolink_code = 'NPC = %s;\n' % npc_expr + nolink_iop = InstObjParams(name, Name, base_class, + CodeBlock(nolink_code), flags) + header_output = BasicDeclare.subst(nolink_iop) + decoder_output = BasicConstructor.subst(nolink_iop) + exec_output = BasicExecute.subst(nolink_iop) + + # Generate declaration of '*AndLink' version, append to decls + link_code = 'Ra = NPC & ~3;\n' + nolink_code + link_iop = InstObjParams(name, Name + 'AndLink', base_class, + CodeBlock(link_code), flags) + header_output += BasicDeclare.subst(link_iop) + decoder_output += BasicConstructor.subst(link_iop) + exec_output += BasicExecute.subst(link_iop) + + # need to use link_iop for the decode template since it is expecting + # the shorter version of class_name (w/o "AndLink") + + return (header_output, decoder_output, + JumpOrBranchDecode.subst(nolink_iop), exec_output) +}}; From 485568efa972db7fc27f34708d9bc3a2f19871de Mon Sep 17 00:00:00 2001 From: Kevin Lim Date: Thu, 16 Feb 2006 11:55:28 -0500 Subject: [PATCH 057/180] Fixes to handle generating the initiateAcc and completeAcc functions a little more cleanly. arch/alpha/isa/mem.isa: Avoid explicitly declaring the Mem variable. Instead break up the code blocks used to generate the initiate and complete functions. The templates reflect which operands need to be declared for each function (src, dest, or both). Loads use both the EA code and mem acc code for the initiate, and memacc code and postacc code for the complete. Stores use both the EA code and mem acc code for the initiate, and only post acc code for the complete. arch/isa_parser.py: Remove hack for mem ops. --HG-- extra : convert_revision : a367797a2cb698762bfc27be1da00bcbe9367150 --- arch/alpha/isa/mem.isa | 51 +++++++++++++++++++++++++++++------------- arch/isa_parser.py | 4 ---- 2 files changed, 35 insertions(+), 20 deletions(-) diff --git a/arch/alpha/isa/mem.isa b/arch/alpha/isa/mem.isa index 1889daefc..37d0dcf14 100644 --- a/arch/alpha/isa/mem.isa +++ b/arch/alpha/isa/mem.isa @@ -288,7 +288,6 @@ def template LoadInitiateAcc {{ { Addr EA; Fault fault = No_Fault; - %(mem_acc_type)s Mem = 0; %(fp_enable_check)s; %(op_src_decl)s; @@ -310,9 +309,9 @@ def template LoadCompleteAcc {{ Trace::InstRecord *traceData) const { Fault fault = No_Fault; - %(mem_acc_type)s Mem = 0; %(fp_enable_check)s; + %(op_src_decl)s; %(op_dest_decl)s; memcpy(&Mem, data, sizeof(Mem)); @@ -409,10 +408,10 @@ def template StoreInitiateAcc {{ Addr EA; Fault fault = No_Fault; uint64_t write_result = 0; - %(mem_acc_type)s Mem = 0; %(fp_enable_check)s; %(op_src_decl)s; + %(op_dest_decl)s; %(op_rd)s; %(ea_code)s; @@ -501,17 +500,7 @@ def template MiscInitiateAcc {{ Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const { - Addr EA; - Fault fault = No_Fault; - - %(fp_enable_check)s; - %(op_decl)s; - %(op_rd)s; - %(ea_code)s; - - if (fault == No_Fault) { - %(memacc_code)s; - } + panic("Misc instruction does not support split access method!"); return No_Fault; } @@ -523,6 +512,8 @@ def template MiscCompleteAcc {{ %(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const { + panic("Misc instruction does not support split access method!"); + return No_Fault; } }}; @@ -584,6 +575,34 @@ def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, # for the post-access code. memacc_iop.postacc_code = postacc_cblk.code + # generate InstObjParams for InitiateAcc, CompleteAcc object + # The code used depends on the template being used + if (exec_template_base == 'Load'): + initiateacc_cblk = CodeBlock(ea_code + memacc_code) + completeacc_cblk = CodeBlock(memacc_code + postacc_code) + elif (exec_template_base == 'Store'): + initiateacc_cblk = CodeBlock(ea_code + memacc_code) + completeacc_cblk = CodeBlock(postacc_code) + else: + initiateacc_cblk = '' + completeacc_cblk = '' + + initiateacc_iop = InstObjParams(name, Name, base_class, initiateacc_cblk, + inst_flags) + + completeacc_iop = InstObjParams(name, Name, base_class, completeacc_cblk, + inst_flags) + + if (exec_template_base == 'Load'): + initiateacc_iop.ea_code = ea_cblk.code + initiateacc_iop.memacc_code = memacc_cblk.code + completeacc_iop.memacc_code = memacc_cblk.code + completeacc_iop.postacc_code = postacc_cblk.code + elif (exec_template_base == 'Store'): + initiateacc_iop.ea_code = ea_cblk.code + initiateacc_iop.memacc_code = memacc_cblk.code + completeacc_iop.postacc_code = postacc_cblk.code + # generate InstObjParams for unified execution cblk = CodeBlock(ea_code + memacc_code + postacc_code) iop = InstObjParams(name, Name, base_class, cblk, inst_flags) @@ -611,8 +630,8 @@ def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, EACompExecute.subst(ea_iop) + memAccExecTemplate.subst(memacc_iop) + fullExecTemplate.subst(iop) - + initiateAccTemplate.subst(iop) - + completeAccTemplate.subst(iop)) + + initiateAccTemplate.subst(initiateacc_iop) + + completeAccTemplate.subst(completeacc_iop)) }}; diff --git a/arch/isa_parser.py b/arch/isa_parser.py index 96d3e8438..bcef77ddf 100755 --- a/arch/isa_parser.py +++ b/arch/isa_parser.py @@ -1149,10 +1149,6 @@ class Operand(object): self.constructor = self.makeConstructor() self.op_decl = self.makeDecl() - if self.isMem(): - self.is_src = '' - self.is_dest = '' - if self.is_src: self.op_rd = self.makeRead() self.op_src_decl = self.makeDecl() From d6a330ebb949b6cd63195d44e5a4304e2fd3378e Mon Sep 17 00:00:00 2001 From: Kevin Lim Date: Thu, 16 Feb 2006 14:55:15 -0500 Subject: [PATCH 058/180] Remove fake fault. Switch fault pointers to const pointers to prevent them from accidentally being changed. Fix some coding style. arch/alpha/ev5.cc: cpu/o3/commit_impl.hh: kern/kernel_stats.hh: Remove fake fault. arch/alpha/faults.cc: Remove fake fault, fix to have normal m5 line length limit, and change pointers to be const pointers so that the default faults aren't changed accidentally. arch/alpha/faults.hh: Fix to have normal m5 line length limit, change pointers to const pointers. sim/faults.cc: sim/faults.hh: Remove fake fault, change pointers to const pointers. --HG-- extra : convert_revision : 01d4600e0d4bdc1d177b32edebc78f86a1bbfe2e --- arch/alpha/ev5.cc | 1 - arch/alpha/faults.cc | 43 +++++++++------ arch/alpha/faults.hh | 121 ++++++++++++++++++++++++++---------------- cpu/o3/commit_impl.hh | 2 +- kern/kernel_stats.hh | 1 - sim/faults.cc | 10 ++-- sim/faults.hh | 12 ++--- 7 files changed, 113 insertions(+), 77 deletions(-) diff --git a/arch/alpha/ev5.cc b/arch/alpha/ev5.cc index a48609729..72f48bfb2 100644 --- a/arch/alpha/ev5.cc +++ b/arch/alpha/ev5.cc @@ -91,7 +91,6 @@ AlphaISA::fault_addr(Fault * fault) if(fault == NoFault) return 0x0000; else if(fault == MachineCheckFault) return 0x0401; else if(fault == AlignmentFault) return 0x0301; - else if(fault == FakeMemFault) return 0x0000; //Deal with the alpha specific faults return ((AlphaFault*)fault)->vect; }; diff --git a/arch/alpha/faults.cc b/arch/alpha/faults.cc index 2dc3d9cbb..e05b3fe59 100644 --- a/arch/alpha/faults.cc +++ b/arch/alpha/faults.cc @@ -28,20 +28,34 @@ #include "arch/alpha/faults.hh" -ResetFaultType * ResetFault = new ResetFaultType("reset", 1, 0x0001); -ArithmeticFaultType * ArithmeticFault = new ArithmeticFaultType("arith", 3, 0x0501); -InterruptFaultType * InterruptFault = new InterruptFaultType("interrupt", 4, 0x0101); -NDtbMissFaultType * NDtbMissFault = new NDtbMissFaultType("dtb_miss_single", 5, 0x0201); -PDtbMissFaultType * PDtbMissFault = new PDtbMissFaultType("dtb_miss_double", 6, 0x0281); -DtbPageFaultType * DtbPageFault = new DtbPageFaultType("dfault", 8, 0x0381); -DtbAcvFaultType * DtbAcvFault = new DtbAcvFaultType("dfault", 9, 0x0381); -ItbMissFaultType * ItbMissFault = new ItbMissFaultType("itbmiss", 10, 0x0181); -ItbPageFaultType * ItbPageFault = new ItbPageFaultType("itbmiss", 11, 0x0181); -ItbAcvFaultType * ItbAcvFault = new ItbAcvFaultType("iaccvio", 12, 0x0081); -UnimplementedOpcodeFaultType * UnimplementedOpcodeFault = new UnimplementedOpcodeFaultType("opdec", 13, 0x0481); -FloatEnableFaultType * FloatEnableFault = new FloatEnableFaultType("fen", 14, 0x0581); -PalFaultType * PalFault = new PalFaultType("pal", 15, 0x2001); -IntegerOverflowFaultType * IntegerOverflowFault = new IntegerOverflowFaultType("intover", 16, 0x0501); +ResetFaultType * const ResetFault = + new ResetFaultType("reset", 1, 0x0001); +ArithmeticFaultType * const ArithmeticFault = + new ArithmeticFaultType("arith", 3, 0x0501); +InterruptFaultType * const InterruptFault = + new InterruptFaultType("interrupt", 4, 0x0101); +NDtbMissFaultType * const NDtbMissFault = + new NDtbMissFaultType("dtb_miss_single", 5, 0x0201); +PDtbMissFaultType * const PDtbMissFault = + new PDtbMissFaultType("dtb_miss_double", 6, 0x0281); +DtbPageFaultType * const DtbPageFault = + new DtbPageFaultType("dfault", 8, 0x0381); +DtbAcvFaultType * const DtbAcvFault = + new DtbAcvFaultType("dfault", 9, 0x0381); +ItbMissFaultType * const ItbMissFault = + new ItbMissFaultType("itbmiss", 10, 0x0181); +ItbPageFaultType * const ItbPageFault = + new ItbPageFaultType("itbmiss", 11, 0x0181); +ItbAcvFaultType * const ItbAcvFault = + new ItbAcvFaultType("iaccvio", 12, 0x0081); +UnimplementedOpcodeFaultType * const UnimplementedOpcodeFault = + new UnimplementedOpcodeFaultType("opdec", 13, 0x0481); +FloatEnableFaultType * const FloatEnableFault = + new FloatEnableFaultType("fen", 14, 0x0581); +PalFaultType * const PalFault = + new PalFaultType("pal", 15, 0x2001); +IntegerOverflowFaultType * const IntegerOverflowFault = + new IntegerOverflowFaultType("intover", 16, 0x0501); Fault ** ListOfFaults[] = { (Fault **)&NoFault, @@ -61,7 +75,6 @@ Fault ** ListOfFaults[] = { (Fault **)&FloatEnableFault, (Fault **)&PalFault, (Fault **)&IntegerOverflowFault, - (Fault **)&FakeMemFault }; int NumFaults = sizeof(ListOfFaults) / sizeof(Fault **); diff --git a/arch/alpha/faults.hh b/arch/alpha/faults.hh index 2bb929a1e..06605861a 100644 --- a/arch/alpha/faults.hh +++ b/arch/alpha/faults.hh @@ -34,94 +34,125 @@ class AlphaFault : public Fault { -public: - AlphaFault(char * newName, int newId, Addr newVect) : Fault(newName, newId), vect(newVect) {;} - TheISA::Addr vect; + public: + AlphaFault(char * newName, int newId, Addr newVect) + : Fault(newName, newId), vect(newVect) + {;} + + TheISA::Addr vect; }; extern class ResetFaultType : public AlphaFault { -public: - ResetFaultType(char * newName, int newId, Addr newVect) : AlphaFault(newName, newId, newVect) {;} -} * ResetFault; + public: + ResetFaultType(char * newName, int newId, Addr newVect) + : AlphaFault(newName, newId, newVect) + {;} +} * const ResetFault; extern class ArithmeticFaultType : public AlphaFault { -public: - ArithmeticFaultType(char * newName, int newId, Addr newVect) : AlphaFault(newName, newId, newVect) {;} -} * ArithmeticFault; + public: + ArithmeticFaultType(char * newName, int newId, Addr newVect) + : AlphaFault(newName, newId, newVect) + {;} +} * const ArithmeticFault; extern class InterruptFaultType : public AlphaFault { -public: - InterruptFaultType(char * newName, int newId, Addr newVect) : AlphaFault(newName, newId, newVect) {;} -} * InterruptFault; + public: + InterruptFaultType(char * newName, int newId, Addr newVect) + : AlphaFault(newName, newId, newVect) + {;} +} * const InterruptFault; extern class NDtbMissFaultType : public AlphaFault { -public: - NDtbMissFaultType(char * newName, int newId, Addr newVect) : AlphaFault(newName, newId, newVect) {;} -} * NDtbMissFault; + public: + NDtbMissFaultType(char * newName, int newId, Addr newVect) + : AlphaFault(newName, newId, newVect) + {;} +} * const NDtbMissFault; extern class PDtbMissFaultType : public AlphaFault { -public: - PDtbMissFaultType(char * newName, int newId, Addr newVect) : AlphaFault(newName, newId, newVect) {;} -} * PDtbMissFault; + public: + PDtbMissFaultType(char * newName, int newId, Addr newVect) + : AlphaFault(newName, newId, newVect) + {;} +} * const PDtbMissFault; extern class DtbPageFaultType : public AlphaFault { -public: - DtbPageFaultType(char * newName, int newId, Addr newVect) : AlphaFault(newName, newId, newVect) {;} -} * DtbPageFault; + public: + DtbPageFaultType(char * newName, int newId, Addr newVect) + : AlphaFault(newName, newId, newVect) + {;} +} * const DtbPageFault; extern class DtbAcvFaultType : public AlphaFault { -public: - DtbAcvFaultType(char * newName, int newId, Addr newVect) : AlphaFault(newName, newId, newVect) {;} -} * DtbAcvFault; + public: + DtbAcvFaultType(char * newName, int newId, Addr newVect) + : AlphaFault(newName, newId, newVect) + {;} +} * const DtbAcvFault; extern class ItbMissFaultType : public AlphaFault { -public: - ItbMissFaultType(char * newName, int newId, Addr newVect) : AlphaFault(newName, newId, newVect) {;} -} * ItbMissFault; + public: + ItbMissFaultType(char * newName, int newId, Addr newVect) + : AlphaFault(newName, newId, newVect) + {;} +} * const ItbMissFault; extern class ItbPageFaultType : public AlphaFault { -public: - ItbPageFaultType(char * newName, int newId, Addr newVect) : AlphaFault(newName, newId, newVect) {;} -} * ItbPageFault; + public: + ItbPageFaultType(char * newName, int newId, Addr newVect) + : AlphaFault(newName, newId, newVect) + {;} +} * const ItbPageFault; extern class ItbAcvFaultType : public AlphaFault { -public: - ItbAcvFaultType(char * newName, int newId, Addr newVect) : AlphaFault(newName, newId, newVect) {;} -} * ItbAcvFault; + public: + ItbAcvFaultType(char * newName, int newId, Addr newVect) + : AlphaFault(newName, newId, newVect) + {;} +} * const ItbAcvFault; extern class UnimplementedOpcodeFaultType : public AlphaFault { -public: - UnimplementedOpcodeFaultType(char * newName, int newId, Addr newVect) : AlphaFault(newName, newId, newVect) {;} -} * UnimplementedOpcodeFault; + public: + UnimplementedOpcodeFaultType(char * newName, int newId, Addr newVect) + : AlphaFault(newName, newId, newVect) + {;} +} * const UnimplementedOpcodeFault; extern class FloatEnableFaultType : public AlphaFault { -public: - FloatEnableFaultType(char * newName, int newId, Addr newVect) : AlphaFault(newName, newId, newVect) {;} -} * FloatEnableFault; + public: + FloatEnableFaultType(char * newName, int newId, Addr newVect) + : AlphaFault(newName, newId, newVect) + {;} +} * const FloatEnableFault; extern class PalFaultType : public AlphaFault { -public: - PalFaultType(char * newName, int newId, Addr newVect) : AlphaFault(newName, newId, newVect) {;} -} * PalFault; + public: + PalFaultType(char * newName, int newId, Addr newVect) + : AlphaFault(newName, newId, newVect) + {;} +} * const PalFault; extern class IntegerOverflowFaultType : public AlphaFault { -public: - IntegerOverflowFaultType(char * newName, int newId, Addr newVect) : AlphaFault(newName, newId, newVect) {;} -} * IntegerOverflowFault; + public: + IntegerOverflowFaultType(char * newName, int newId, Addr newVect) + : AlphaFault(newName, newId, newVect) + {;} +} * const IntegerOverflowFault; extern Fault ** ListOfFaults[]; extern int NumFaults; diff --git a/cpu/o3/commit_impl.hh b/cpu/o3/commit_impl.hh index 540f16b78..47b4dfd00 100644 --- a/cpu/o3/commit_impl.hh +++ b/cpu/o3/commit_impl.hh @@ -395,7 +395,7 @@ SimpleCommit::commitHead(DynInstPtr &head_inst, unsigned inst_num) // Check if the instruction caused a fault. If so, trap. Fault * inst_fault = head_inst->getFault(); - if (inst_fault != NoFault && inst_fault != FakeMemFault) { + if (inst_fault != NoFault) { if (!head_inst->isNop()) { #if FULL_SYSTEM cpu->trap(inst_fault); diff --git a/kern/kernel_stats.hh b/kern/kernel_stats.hh index 98cc044ac..a36c73fb4 100644 --- a/kern/kernel_stats.hh +++ b/kern/kernel_stats.hh @@ -181,7 +181,6 @@ class Statistics : public Serializable if(fault == NoFault) _faults[0]++; else if(fault == MachineCheckFault) _faults[2]++; else if(fault == AlignmentFault) _faults[7]++; - else if(fault == FakeMemFault) _faults[17]++; else _faults[fault->id]++; }// FIXME: When there are no generic system fault objects, this will go back to _faults[fault]++; } void swpipl(int ipl); diff --git a/sim/faults.cc b/sim/faults.cc index 640f439c4..58a631263 100644 --- a/sim/faults.cc +++ b/sim/faults.cc @@ -28,9 +28,9 @@ #include "sim/faults.hh" -NoFaultType * NoFault = new NoFaultType("none"); -MachineCheckFaultType * MachineCheckFault = new MachineCheckFaultType("mchk"); -AlignmentFaultType * AlignmentFault = new AlignmentFaultType("unalign"); -//This needs to not exist -FakeMemFaultType * FakeMemFault = new FakeMemFaultType("fakemem"); +NoFaultType * const NoFault = new NoFaultType("none"); +MachineCheckFaultType * const MachineCheckFault = + new MachineCheckFaultType("mchk"); +AlignmentFaultType * const AlignmentFault = + new AlignmentFaultType("unalign"); diff --git a/sim/faults.hh b/sim/faults.hh index bc2c35c64..d9c742b90 100644 --- a/sim/faults.hh +++ b/sim/faults.hh @@ -41,25 +41,19 @@ extern class NoFaultType : public Fault { public: NoFaultType(char * newName) : Fault(newName) {;} -} * NoFault; +} * const NoFault; extern class MachineCheckFaultType : public Fault { public: MachineCheckFaultType(char * newName) : Fault(newName) {;} -} * MachineCheckFault; +} * const MachineCheckFault; extern class AlignmentFaultType : public Fault { public: AlignmentFaultType(char * newName) : Fault(newName) {;} -} * AlignmentFault; - -extern class FakeMemFaultType : public Fault -{ -public: - FakeMemFaultType(char * newName) : Fault(newName) {;} -} * FakeMemFault; +} * const AlignmentFault; #endif // __FAULTS_HH__ From dd11b2c4ffc9121faa7e6976bd211dbb595e9af0 Mon Sep 17 00:00:00 2001 From: Kevin Lim Date: Fri, 17 Feb 2006 15:07:48 -0500 Subject: [PATCH 059/180] Get rid of deque (poor memory allocation), switch them over to lists. Beware that using size() on a list is a O(n) operation. dev/ns_gige.hh: Remove typedefs that (I assume) were copied over from etherdev.hh. They were unused in the ns_gige code. --HG-- extra : convert_revision : 577954ec26b899bd6329ce6a4aaa1d9b0ba4f34c --- dev/ns_gige.hh | 3 --- 1 file changed, 3 deletions(-) diff --git a/dev/ns_gige.hh b/dev/ns_gige.hh index b65626b7b..181837c8d 100644 --- a/dev/ns_gige.hh +++ b/dev/ns_gige.hh @@ -170,9 +170,6 @@ class NSGigE : public PciDev static const Addr size = sizeof(dp_regs); protected: - typedef std::deque pktbuf_t; - typedef pktbuf_t::iterator pktiter_t; - /** device register file */ dp_regs regs; dp_rom rom; From 6bf71f96f3ae17e49eca8b77bf1f99b2883f93f6 Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Sat, 18 Feb 2006 03:12:04 -0500 Subject: [PATCH 060/180] MIPS generates ISA code through scons '.../decoder.cc'!!! Now, must create g++ compilable code ... arch/mips/isa/decoder.isa: missing a '}' ... edited a few instruction decodings ... arch/mips/isa/formats.isa: rearranged #include arch/mips/isa/formats/branch.isa: add Branch Likely and Unconditional format arch/mips/isa/formats/int.isa: move OperateNopCheckDecode template to another file ... arch/mips/isa/formats/noop.isa: change Alpha to Mips in noop.isa --HG-- extra : convert_revision : 4bf955fa6dffbbc99fb95fee7878f691e3df5424 --- arch/mips/isa/decoder.isa | 1105 +++++++++++++++--------------- arch/mips/isa/formats.isa | 14 +- arch/mips/isa/formats/branch.isa | 43 +- arch/mips/isa/formats/int.isa | 12 - arch/mips/isa/formats/noop.isa | 62 +- 5 files changed, 594 insertions(+), 642 deletions(-) diff --git a/arch/mips/isa/decoder.isa b/arch/mips/isa/decoder.isa index 62b0c1b7e..997badb25 100644 --- a/arch/mips/isa/decoder.isa +++ b/arch/mips/isa/decoder.isa @@ -14,185 +14,191 @@ decode OPCODE_HI default Unknown::unknown() { // Derived From ... Table A-2 MIPS32 ISA Manual - 0x0: decode OPCODE_LO default FailUnimpl::reserved(){ + 0x0: decode OPCODE_LO { 0x0: decode FUNCTION_HI { 0x0: decode FUNCTION_LO { - 0x1: decode MOVCI { - format BasicOp { - 0: movf({{ if( xc->miscRegs.fpcr == 0) Rd = Rs}}); - 1: movt({{ if( xc->miscRegs.fpcr == 1) Rd = Rs}}); + 0x1: decode MOVCI { + format BasicOp { + 0: movf({{ if( xc->miscRegs.fpcr == 0) Rd = Rs}}); + 1: movt({{ if( xc->miscRegs.fpcr == 1) Rd = Rs}}); + } } - } - format BasicOp { + format BasicOp { - //Table A-3 Note: "1. Specific encodings of the rt, rd, and sa fields - //are used to distinguish among the SLL, NOP, SSNOP and EHB functions." + //Table A-3 Note: "1. Specific encodings of the rt, rd, and sa fields + //are used to distinguish among the SLL, NOP, SSNOP and EHB functions." - 0x0: sll({{ Rd = Rt.uw << SA; }}); + 0x0: sll({{ Rd = Rt.uw << SA; }}); - 0x2: decode SRL { - 0: srl({{ Rd = Rt.uw >> SA; }}); + 0x2: decode SRL { + 0: srl({{ Rd = Rt.uw >> SA; }}); - //Hardcoded assuming 32-bit ISA, probably need parameter here - 1: rotr({{ Rd = (Rt.uw << (32 - SA)) | (Rt.uw >> SA);}}); - } + //Hardcoded assuming 32-bit ISA, probably need parameter here + 1: rotr({{ Rd = (Rt.uw << (32 - SA)) | (Rt.uw >> SA);}}); + } - 0x3: sra({{ Rd = Rt.sw >> SA; }}); + 0x3: sra({{ Rd = Rt.sw >> SA; }}); - 0x4: sllv({{ Rd = Rt.uw << Rs<4:0>; }}); + 0x4: sllv({{ Rd = Rt.uw << Rs<4:0>; }}); - 0x6: decode SRLV { - 0: srlv({{ Rd = Rt.uw >> Rs<4:0>; }}); + 0x6: decode SRLV { + 0: srlv({{ Rd = Rt.uw >> Rs<4:0>; }}); - //Hardcoded assuming 32-bit ISA, probably need parameter here - 1: rotrv({{ Rd = (Rt.uw << (32 - Rs<4:0>)) | (Rt.uw >> Rs<4:0>);}}); - } + //Hardcoded assuming 32-bit ISA, probably need parameter here + 1: rotrv({{ Rd = (Rt.uw << (32 - Rs<4:0>)) | (Rt.uw >> Rs<4:0>);}}); + } - 0x7: srav({{ Rd = Rt.sw >> Rs<4:0>; }}); - } + 0x7: srav({{ Rd = Rt.sw >> Rs<4:0>; }}); + } } 0x1: decode FUNCTION_LO { - //Table A-3 Note: "Specific encodings of the hint field are used - //to distinguish JR from JR.HB and JALR from JALR.HB" - format Jump { - 0x0: jr(IsReturn); - 0x1: jalr(IsCall,IsReturn); - } + //Table A-3 Note: "Specific encodings of the hint field are used + //to distinguish JR from JR.HB and JALR from JALR.HB" + format Unconditional { + 0x0: decode HINT { + 0:jr({{ }},IsReturn,IsLink); + 1:jr_hb({{ }},IsReturn,IsLink); + } - format BasicOp { - 0x2: movz({{ if (Rt == 0) Rd = Rs; }}); - 0x3: movn({{ if (Rt != 0) Rd = Rs; }}); - } + 0x1: decode HINT { + 0: jalr({{ }},'IsCall','IsReturn','IsLink'); + 1: jalr_hb({{ }},IsCall,IsReturn,IsLink); + } + } + + format BasicOp { + 0x2: movz({{ if (Rt == 0) Rd = Rs; }}); + 0x3: movn({{ if (Rt != 0) Rd = Rs; }}); + } - format WarnUnimpl { - 0x4: syscall();//{{ xc->syscall()}},IsNonSpeculative - 0x5: break(); - 0x7: sync(); - } + format WarnUnimpl { + 0x4: syscall();//{{ xc->syscall()}},IsNonSpeculative + 0x5: break(); + 0x7: sync(); + } } 0x2: decode FUNCTION_LO { - format BasicOp { - 0x0: mfhi({{ Rd = xc->miscRegs.hi; }}); - 0x1: mthi({{ xc->miscRegs.hi = Rs; }}); - 0x2: mflo({{ Rd = xc->miscRegs.lo; }}); - 0x3: mtlo({{ xc->miscRegs.lo = Rs; }}); - } + format BasicOp { + 0x0: mfhi({{ Rd = xc->miscRegs.hi; }}); + 0x1: mthi({{ xc->miscRegs.hi = Rs; }}); + 0x2: mflo({{ Rd = xc->miscRegs.lo; }}); + 0x3: mtlo({{ xc->miscRegs.lo = Rs; }}); + } } 0x3: decode FUNCTION_LO { - format IntOp { - 0x0: mult({{ + format IntOp { + 0x0: mult({{ INT64 temp1 = Rs.sw * Rt.sw; xc->miscRegs.hi->temp1<63:32>; xc->miscRegs.lo->temp1<31:0>; - }}); + }}); - 0x1: multu({{ + 0x1: multu({{ INT64 temp1 = Rs.uw * Rt.uw; xc->miscRegs.hi->temp1<63:32>; xc->miscRegs.lo->temp1<31:0> - Rd.sw = Rs.uw * Rt.uw; - }}); + Rd.sw = Rs.uw * Rt.uw; + }}); - 0x2: div({{ + 0x2: div({{ xc->miscRegs.hi = Rs.sw % Rt.sw; xc->miscRegs.lo = Rs.sw / Rt.sw; - }}); + }}); - 0x3: divu({{ + 0x3: divu({{ xc->miscRegs.hi = Rs.uw % Rt.uw; xc->miscRegs.lo = Rs.uw / Rt.uw; - }}); - } + }}); + } } 0x4: decode FUNCTION_LO { - format IntOp { - 0x0: add({{ Rd.sw = Rs.sw + Rt.sw;}}); - 0x1: addu({{ Rd.uw = Rs.uw + Rt.uw;}}); - 0x2: sub({{ Rd.sw = Rs.sw - Rt.sw;}}); - 0x3: subu({{ Rd.uw = Rs.uw - Rt.uw;}}); - 0x4: and({{ Rd.sw = Rs.uw & Rt.uw;}}); - 0x5: or({{ Rd.sw = Rs.uw | Rt.uw;}}); - 0x6: xor({{ Rd.sw = Rs.uw ^ Rt.uw;}}); - 0x7: nor({{ Rd.sw = ~(Rs.uw | Rt.uw);}}); - } + format IntOp { + 0x0: add({{ Rd.sw = Rs.sw + Rt.sw;}}); + 0x1: addu({{ Rd.uw = Rs.uw + Rt.uw;}}); + 0x2: sub({{ Rd.sw = Rs.sw - Rt.sw;}}); + 0x3: subu({{ Rd.uw = Rs.uw - Rt.uw;}}); + 0x4: and({{ Rd.sw = Rs.uw & Rt.uw;}}); + 0x5: or({{ Rd.sw = Rs.uw | Rt.uw;}}); + 0x6: xor({{ Rd.sw = Rs.uw ^ Rt.uw;}}); + 0x7: nor({{ Rd.sw = ~(Rs.uw | Rt.uw);}}); + } } 0x5: decode FUNCTION_LO { - format IntOp{ - 0x2: slt({{ Rd.sw = ( Rs.sw < Rt.sw ) ? 1 : 0}}); - 0x3: sltu({{ Rd.uw = ( Rs.uw < Rt.uw ) ? 1 : 0}}); - } + format IntOp{ + 0x2: slt({{ Rd.sw = ( Rs.sw < Rt.sw ) ? 1 : 0}}); + 0x3: sltu({{ Rd.uw = ( Rs.uw < Rt.uw ) ? 1 : 0}}); + } } 0x6: decode FUNCTION_LO { - format Trap { - 0x0: tge({{ cond = (Rs.sw >= Rt.sw); }}); - 0x1: tgeu({{ cond = (Rs.uw >= Rt.uw); }}); - 0x2: tlt({{ cond = (Rs.sw < Rt.sw); }}); - 0x3: tltu({{ cond = (Rs.uw >= Rt.uw); }}); - 0x4: teq({{ cond = (Rs.sw == Rt.sw); }}); - 0x6: tne({{ cond = (Rs.sw != Rt.sw); }}); - } + format Trap { + 0x0: tge({{ cond = (Rs.sw >= Rt.sw); }}); + 0x1: tgeu({{ cond = (Rs.uw >= Rt.uw); }}); + 0x2: tlt({{ cond = (Rs.sw < Rt.sw); }}); + 0x3: tltu({{ cond = (Rs.uw >= Rt.uw); }}); + 0x4: teq({{ cond = (Rs.sw == Rt.sw); }}); + 0x6: tne({{ cond = (Rs.sw != Rt.sw); }}); + } } } 0x1: decode REGIMM_HI { 0x0: decode REGIMM_LO { - format Branch { - 0x0: bltz({{ cond = (Rs.sw < 0); }}); - 0x1: bgez({{ cond = (Rs.sw >= 0); }}); + format Branch { + 0x0: bltz({{ cond = (Rs.sw < 0); }}); + 0x1: bgez({{ cond = (Rs.sw >= 0); }}); + } - } - - format BranchLikely { - //MIPS obsolete instructions - 0x2: bltzl({{ cond = (Rs.sw < 0); }}); - 0x3: bgezl({{ cond = (Rs.sw >= 0); }}); - } + format BranchLikely { + //MIPS obsolete instructions + 0x2: bltzl({{ cond = (Rs.sw < 0); }}); + 0x3: bgezl({{ cond = (Rs.sw >= 0); }}); + } } 0x1: decode REGIMM_LO { - format Trap { - 0x0: tgei({{ cond = (Rs.sw >= INTIMM; }}); - 0x1: tgeiu({{ cond = (Rs.uw < INTIMM); }}); - 0x2: tlti({{ cond = (Rs.sw < INTIMM); }}); - 0x3: tltiu({{ cond = (Rs.uw < INTIMM); }}); - 0x4: teqi({{ cond = (Rs.sw == INTIMM); }}); - 0x6: tnei({{ cond = (Rs.sw != INTIMM); }}); - } + format Trap { + 0x0: tgei( {{ cond = (Rs.sw >= INTIMM); }}); + 0x1: tgeiu({{ cond = (Rs.uw < INTIMM); }}); + 0x2: tlti( {{ cond = (Rs.sw < INTIMM); }}); + 0x3: tltiu({{ cond = (Rs.uw < INTIMM); }}); + 0x4: teqi( {{ cond = (Rs.sw == INTIMM);}}); + 0x6: tnei( {{ cond = (Rs.sw != INTIMM);}}); + } } 0x2: decode REGIMM_LO { - format Branch { - 0x0: bltzal({{ cond = (Rs.sw < 0); }}); - 0x1: bgezal({{ cond = (Rs.sw >= 0); }}); - } + format Branch { + 0x0: bltzal({{ cond = (Rs.sw < 0); }}, IsLink); + 0x1: bgezal({{ cond = (Rs.sw >= 0); }}, IsLink); + } - format BranchLikely { - //MIPS obsolete instructions - 0x2: bltzall({{ cond = (Rs.sw < 0); }}); - 0x3: bgezall({{ cond = (Rs.sw >= 0); }}); - } + format BranchLikely { + //Will be removed in future MIPS releases + 0x2: bltzall({{ cond = (Rs.sw < 0); }}, IsLink); + 0x3: bgezall({{ cond = (Rs.sw >= 0); }}, IsLink); + } } 0x3: decode REGIMM_LO { - format WarnUnimpl { - 0x7: synci(); - } + format WarnUnimpl { + 0x7: synci(); + } } } - format Jump { - 0x2: j(); - 0x3: jal(IsCall); + format Unconditional { + 0x2: j({{ }}); + 0x3: jal({{ }},IsCall,IsLink); } format Branch { @@ -203,7 +209,7 @@ decode OPCODE_HI default Unknown::unknown() { } } - 0x1: decode OPCODE_LO default FailUnimpl::reserved(){ + 0x1: decode OPCODE_LO { format IntOp { 0x0: addi({{ Rt.sw = Rs.sw + INTIMM; }}); 0x1: addiu({{ Rt.uw = Rs.uw + INTIMM;}}); @@ -216,539 +222,534 @@ decode OPCODE_HI default Unknown::unknown() { } } - 0x2: decode OPCODE_LO default FailUnimpl::reserved(){ + 0x2: decode OPCODE_LO { - //Table A-11 MIPS32 COP0 Encoding of rs Field - 0x0: decode RS_MSB { - 0x0: decode RS { - - format BasicOp { - 0x0: mfc0({{ + //Table A-11 MIPS32 COP0 Encoding of rs Field + 0x0: decode RS_MSB { + 0x0: decode RS { + format BasicOp { + 0x0: mfc0({{ //The contents of the coprocessor 0 register specified by the //combination of rd and sel are loaded into general register //rt. Note that not all coprocessor 0 registers support the //sel field. In those instances, the sel field must be zero. if (SEL > 0) - panic("Can't Handle Cop0 with register select yet\n"); + panic("Can't Handle Cop0 with register select yet\n"); uint64_t reg_num = Rd.uw; Rt = xc->miscRegs.cop0[reg_num]; - }}); + }}); - 0x4: mtc0({{ + 0x4: mtc0({{ //The contents of the coprocessor 0 register specified by the //combination of rd and sel are loaded into general register //rt. Note that not all coprocessor 0 registers support the //sel field. In those instances, the sel field must be zero. if (SEL > 0) - panic("Can't Handle Cop0 with register select yet\n"); + panic("Can't Handle Cop0 with register select yet\n"); uint64_t reg_num = Rd.uw; xc->miscRegs.cop0[reg_num] = Rt; - }}); + }}); - 0x8: mftr({{ + 0x8: mftr({{ //The contents of the coprocessor 0 register specified by the //combination of rd and sel are loaded into general register //rt. Note that not all coprocessor 0 registers support the //sel field. In those instances, the sel field must be zero. //MT Code Needed Here - }}); + }}); - 0xC: mttr({{ + 0xC: mttr({{ //The contents of the coprocessor 0 register specified by the //combination of rd and sel are loaded into general register //rt. Note that not all coprocessor 0 registers support the //sel field. In those instances, the sel field must be zero. //MT Code Needed Here - }}); + }}); - 0xA: rdpgpr({{ + 0xA: rdpgpr({{ //Accessing Previous Shadow Set Register Number uint64_t prev = xc->miscRegs.cop0[SRSCtl][PSS]; uint64_t reg_num = Rt.uw; Rd = xc->shadowIntRegFile[prev][reg_num]; - }}); - } + }}); - 0xB: decode RD { + 0xB: decode RD { - 0x0: decode SC { - format BasicOp { - 0x0: dvpe({{ - Rt.sw = xc->miscRegs.cop0.MVPControl; - xc->miscRegs.cop0.MVPControl[EVP] = 0; - }}); + 0x0: decode SC { + 0x0: dvpe({{ + Rt.sw = xc->miscRegs.cop0.MVPControl; + xc->miscRegs.cop0.MVPControl[EVP] = 0; + }}); - 0x1: evpe({{ - Rt.sw = xc->miscRegs.cop0.MVPControl; - xc->miscRegs.cop0.MVPControl[EVP] = 1; - }}); - } - } + 0x1: evpe({{ + Rt.sw = xc->miscRegs.cop0.MVPControl; + xc->miscRegs.cop0.MVPControl[EVP] = 1; + }}); + } - 0x1: decode SC { - format BasicOp { - 0x0: dmt({{ - Rt.sw = xc->miscRegs.cop0.VPEControl; - xc->miscRegs.cop0.VPEControl[THREAD_ENABLE] = 0; - }}); + 0x1: decode SC { + 0x0: dmt({{ + Rt.sw = xc->miscRegs.cop0.VPEControl; + xc->miscRegs.cop0.VPEControl[THREAD_ENABLE] = 0; + }}); - 0x1: emt({{ - Rt.sw = xc->miscRegs.cop0.VPEControl; - xc->miscRegs.cop0.VPEControl[THREAD_ENABLE] = 1; - }}); - } - } + 0x1: emt({{ + Rt.sw = xc->miscRegs.cop0.VPEControl; + xc->miscRegs.cop0.VPEControl[THREAD_ENABLE] = 1; + }}); + } - 0xC: decode SC { - format BasicOp { - 0x0: di({{ - Rt.sw = xc->miscRegs.cop0.Status; - xc->miscRegs.cop0.Status[INTERRUPT_ENABLE] = 0; - }}); + 0xC: decode SC { + 0x0: di({{ + Rt.sw = xc->miscRegs.cop0.Status; + xc->miscRegs.cop0.Status[INTERRUPT_ENABLE] = 0; + }}); - 0x1: ei({{ - Rt.sw = xc->miscRegs.cop0.Status; - xc->miscRegs.cop0.Status[INTERRUPT_ENABLE] = 1; - }}); - } - } - } + 0x1: ei({{ + Rt.sw = xc->miscRegs.cop0.Status; + xc->miscRegs.cop0.Status[INTERRUPT_ENABLE] = 1; + }}); + } + } - 0xE: BasicOp::wrpgpr({{ + 0xE: wrpgpr({{ //Accessing Previous Shadow Set Register Number uint64_t prev = xc->miscRegs.cop0[SRSCtl][PSS]; uint64_t reg_num = Rd.uw; xc->shadowIntRegFile[prev][reg_num] = Rt; - }}); - } - - //Table A-12 MIPS32 COP0 Encoding of Function Field When rs=CO - 0x1: decode FUNCTION { - format Trap { - 0x01: tlbr({{ }}); - 0x02: tlbwi({{ }}); - 0x06: tlbwr({{ }}); - 0x08: tlbp({{ }}); - } - - format WarnUnimpl { - 0x18: eret(); - 0x1F: deret(); - 0x20: wait(); - } - } - } - - //Table A-13 MIPS32 COP1 Encoding of rs Field - 0x1: decode RS_MSB { - - 0x0: decode RS_HI { - 0x0: decode RS_LO { - format FloatOp { - 0x0: mfc1({{ Rt = Fs<31:0>; }}); - 0x2: cfc1({{ Rt = xc->miscRegs.fpcr[Fs];}}); - 0x3: mfhc1({{ Rt = Fs<63:32>;}}); - 0x4: mtc1({{ Fs<31:0> = Rt}}); - 0x6: ctc1({{ xc->miscRegs.fpcr[Fs] = Rt;}}); - 0x7: mftc1({{ Fs<63:32> = Rt}}); - } - } - - 0x1: decode ND { - 0x0: decode TF { - format Branch { - 0x0: bc1f({{ cond = (xc->miscRegs.fpcr == 0); }}); - 0x1: bc1t({{ cond = (xc->miscRegs.fpcr == 1); }}); - } + }}); + } } - 0x1: decode TF { - format BranchLikely { - 0x0: bc1fl({{ cond = (xc->miscRegs.fpcr == 0); }}); - 0x1: bc1tl({{ cond = (xc->miscRegs.fpcr == 1); }}); - } + //Table A-12 MIPS32 COP0 Encoding of Function Field When rs=CO + 0x1: decode FUNCTION { + format Trap { + 0x01: tlbr({{ }}); + 0x02: tlbwi({{ }}); + 0x06: tlbwr({{ }}); + 0x08: tlbp({{ }}); + } + + format WarnUnimpl { + 0x18: eret(); + 0x1F: deret(); + 0x20: wait(); + } } - } } - 0x1: decode RS_HI { - 0x2: decode RS_LO { + //Table A-13 MIPS32 COP1 Encoding of rs Field + 0x1: decode RS_MSB { - //Table A-14 MIPS32 COP1 Encoding of Function Field When rs=S - //(( single-word )) 0x0: decode RS_HI { - 0x0: decode RS_LO { - format FloatOp { - 0x0: adds({{ Fd.sf = Fs.sf + Ft.sf;}}); - 0x1: subs({{ Fd.sf = Fs.sf - Ft.sf;}}); - 0x2: muls({{ Fd.sf = Fs.sf * Ft.sf;}}); - 0x3: divs({{ Fd.sf = Fs.sf / Ft.sf;}}); - 0x4: sqrts({{ Fd.sf = sqrt(Fs.sf);}}); - 0x5: abss({{ Fd.sf = abs(Fs.sf);}}); - 0x6: movs({{ Fd.sf = Fs.sf;}}); - 0x7: negs({{ Fd.sf = -1 * Fs.sf;}}); - } - } - - 0x1: decode RS_LO { - //only legal for 64 bit-FP - 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: decode RS_LO { + format FloatOp { + 0x0: mfc1({{ Rt = Fs<31:0>; }}); + 0x2: cfc1({{ Rt = xc->miscRegs.fpcr[Fs];}}); + 0x3: mfhc1({{ Rt = Fs<63:32>;}}); + 0x4: mtc1({{ Fs<31:0> = Rt}}); + 0x6: ctc1({{ xc->miscRegs.fpcr[Fs] = Rt;}}); + 0x7: mftc1({{ Fs<63:32> = Rt}}); + } } - 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);}}); + 0x1: decode ND { + 0x0: decode TF { + format Branch { + 0x0: bc1f({{ cond = (xc->miscRegs.fpcr == 0); }}); + 0x1: bc1t({{ cond = (xc->miscRegs.fpcr == 1); }}); + } + } + + 0x1: decode TF { + format BranchLikely { + 0x0: bc1fl({{ cond = (xc->miscRegs.fpcr == 0); }}); + 0x1: bc1tl({{ cond = (xc->miscRegs.fpcr == 1); }}); + } + } } - } - - 0x2: decode RS_LO { - 0x1: decode MOVCF { - format FloatOp { - 0x0: movfs({{ if ( FPConditionCode(CC) == 0 ) Fd = Fs; }}); - 0x1: movts({{ if ( FPConditionCode(CC) == 1 ) Fd = Fs;}}); - } - } - - format BasicOp { - 0x2: movzs({{ if (Rt == 0) Fd = Fs; }}); - 0x3: movns({{ if (Rt != 0) Fd = Fs; }}); - } - - format Float64Op { - 0x2: recips({{ Fd = 1 / Fs; }}); - 0x3: rsqrts({{ Fd = 1 / sqrt(Fs.ud);}}); - } - } - - 0x4: decode RS_LO { - - format FloatOp { - 0x1: cvt_d_s({{ int rnd_mode = xc->miscRegs.fcsr; - Fd = convert_and_round(Fs.sf,rnd_mode,FP_DOUBLE,FP_SINGLE); - }}); - - 0x4: cvt_w_s({{ int rnd_mode = xc->miscRegs.fcsr; - Fd = convert_and_round(Fs.sf,rnd_mode,FP_WORD,FP_SINGLE); - }}); - } - - //only legal for 64 bit - format Float64Op { - 0x5: cvt_l_s({{ int rnd_mode = xc->miscRegs.fcsr; - Fd = convert_and_round(Fs.sf,rnd_mode,FP_LONG,FP_SINGLE); - }}); - - 0x6: cvt_ps_s({{ Fd.df = Fs.df<31:0> | Ft.df<31:0>; }}); - } - } } - //Table A-15 MIPS32 COP1 Encoding of Function Field When rs=D 0x1: decode RS_HI { - 0x0: decode RS_LO { - format FloatOp { - 0x0: addd({{ Fd.df = Fs.df + Ft.df;}}); - 0x1: subd({{ Fd.df = Fs.df - Ft.df;}}); - 0x2: muld({{ Fd.df = Fs.df * Ft.df;}}); - 0x3: divd({{ Fd.df = Fs.df / Ft.df;}}); - 0x4: sqrtd({{ Fd.df = sqrt(Fs.df);}}); - 0x5: absd({{ Fd.df = abs(Fs.df);}}); - 0x6: movd({{ Fd.df = Fs.df;}}); - 0x7: negd({{ Fd.df = -1 * Fs.df;}}); - } - } + 0x2: decode RS_LO { - 0x1: decode RS_LO { - //only legal for 64 bit - 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);}}); - } + //Table A-14 MIPS32 COP1 Encoding of Function Field When rs=S + //(( single-word )) + 0x0: decode RS_HI { + 0x0: decode RS_LO { + format FloatOp { + 0x0: adds({{ Fd.sf = Fs.sf + Ft.sf;}}); + 0x1: subs({{ Fd.sf = Fs.sf - Ft.sf;}}); + 0x2: muls({{ Fd.sf = Fs.sf * Ft.sf;}}); + 0x3: divs({{ Fd.sf = Fs.sf / Ft.sf;}}); + 0x4: sqrts({{ Fd.sf = sqrt(Fs.sf);}}); + 0x5: abss({{ Fd.sf = abs(Fs.sf);}}); + 0x6: movs({{ Fd.sf = Fs.sf;}}); + 0x7: negs({{ Fd.sf = -1 * Fs.sf;}}); + } + } - 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); }}); - } - } + 0x1: decode RS_LO { + //only legal for 64 bit-FP + 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);}}); + } - 0x2: decode RS_LO { - 0x1: decode MOVCF { - format FloatOp { - 0x0: movfd({{ if (FPConditionCode(CC) == 0) Fd.df = Fs.df; }}); - 0x1: movtd({{ if (FPConditionCode(CC) == 1) Fd.df = Fs.df; }}); - } - } + 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);}}); + } + } - format BasicOp { - 0x2: movz({{ if (Rt == 0) Fd.df = Fs.df; }}); - 0x3: movn({{ if (Rt != 0) Fd.df = Fs.df; }}); - } + 0x2: decode RS_LO { + 0x1: decode MOVCF { + format FloatOp { + 0x0: movfs({{ if ( FPConditionCode(CC) == 0 ) Fd = Fs; }}); + 0x1: movts({{ if ( FPConditionCode(CC) == 1 ) Fd = Fs;}}); + } + } - format Float64Op { - 0x5: recipd({{ Fd.df = 1 / Fs.df}}); - 0x6: rsqrtd({{ Fd.df = 1 / sqrt(Fs.df) }}); - } - } + format BasicOp { + 0x2: movzs({{ if (Rt == 0) Fd = Fs; }}); + 0x3: movns({{ if (Rt != 0) Fd = Fs; }}); + } - 0x4: decode RS_LO { - format FloatOp { - 0x0: cvt_s_d({{ - int rnd_mode = xc->miscRegs.fcsr; - Fd = convert_and_round(Fs.df,rnd_mode,FP_SINGLE,FP_DOUBLE); - }}); + format Float64Op { + 0x2: recips({{ Fd = 1 / Fs; }}); + 0x3: rsqrts({{ Fd = 1 / sqrt(Fs.ud);}}); + } + } - 0x4: cvt_w_d({{ - int rnd_mode = xc->miscRegs.fcsr; - Fd = convert_and_round(Fs.df,rnd_mode,FP_WORD,FP_DOUBLE); - }}); - } + 0x4: decode RS_LO { - //only legal for 64 bit - format Float64Op { - 0x5: cvt_l_d({{ - int rnd_mode = xc->miscRegs.fcsr; - Fd = convert_and_round(Fs.df,rnd_mode,FP_LONG,FP_DOUBLE); - }}); - } - } - } + format FloatOp { + 0x1: cvt_d_s({{ int rnd_mode = xc->miscRegs.fcsr; + Fd = convert_and_round(Fs.sf,rnd_mode,FP_DOUBLE,FP_SINGLE); + }}); - //Table A-16 MIPS32 COP1 Encoding of Function Field When rs=W - 0x4: decode FUNCTION { - format FloatOp { - 0x10: cvt_s({{ + 0x4: cvt_w_s({{ int rnd_mode = xc->miscRegs.fcsr; + Fd = convert_and_round(Fs.sf,rnd_mode,FP_WORD,FP_SINGLE); + }}); + } + + //only legal for 64 bit + format Float64Op { + 0x5: cvt_l_s({{ int rnd_mode = xc->miscRegs.fcsr; + Fd = convert_and_round(Fs.sf,rnd_mode,FP_LONG,FP_SINGLE); + }}); + + 0x6: cvt_ps_s({{ Fd.df = Fs.df<31:0> | Ft.df<31:0>; }}); + } + } + } + + //Table A-15 MIPS32 COP1 Encoding of Function Field When rs=D + 0x1: decode RS_HI { + 0x0: decode RS_LO { + format FloatOp { + 0x0: addd({{ Fd.df = Fs.df + Ft.df;}}); + 0x1: subd({{ Fd.df = Fs.df - Ft.df;}}); + 0x2: muld({{ Fd.df = Fs.df * Ft.df;}}); + 0x3: divd({{ Fd.df = Fs.df / Ft.df;}}); + 0x4: sqrtd({{ Fd.df = sqrt(Fs.df);}}); + 0x5: absd({{ Fd.df = abs(Fs.df);}}); + 0x6: movd({{ Fd.df = Fs.df;}}); + 0x7: negd({{ Fd.df = -1 * Fs.df;}}); + } + } + + 0x1: decode RS_LO { + //only legal for 64 bit + 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);}}); + } + + 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); }}); + } + } + + 0x2: decode RS_LO { + 0x1: decode MOVCF { + format FloatOp { + 0x0: movfd({{ if (FPConditionCode(CC) == 0) Fd.df = Fs.df; }}); + 0x1: movtd({{ if (FPConditionCode(CC) == 1) Fd.df = Fs.df; }}); + } + } + + format BasicOp { + 0x2: movz({{ if (Rt == 0) Fd.df = Fs.df; }}); + 0x3: movn({{ if (Rt != 0) Fd.df = Fs.df; }}); + } + + format Float64Op { + 0x5: recipd({{ Fd.df = 1 / Fs.df}}); + 0x6: rsqrtd({{ Fd.df = 1 / sqrt(Fs.df) }}); + } + } + + 0x4: decode RS_LO { + format FloatOp { + 0x0: cvt_s_d({{ + int rnd_mode = xc->miscRegs.fcsr; + Fd = convert_and_round(Fs.df,rnd_mode,FP_SINGLE,FP_DOUBLE); + }}); + + 0x4: cvt_w_d({{ + int rnd_mode = xc->miscRegs.fcsr; + Fd = convert_and_round(Fs.df,rnd_mode,FP_WORD,FP_DOUBLE); + }}); + } + + //only legal for 64 bit + format Float64Op { + 0x5: cvt_l_d({{ + int rnd_mode = xc->miscRegs.fcsr; + Fd = convert_and_round(Fs.df,rnd_mode,FP_LONG,FP_DOUBLE); + }}); + } + } + } + + //Table A-16 MIPS32 COP1 Encoding of Function Field When rs=W + 0x4: decode FUNCTION { + format FloatOp { + 0x10: cvt_s({{ int rnd_mode = xc->miscRegs.fcsr; Fd = convert_and_round(Fs.df,rnd_mode,FP_SINGLE,FP_WORD); }}); - 0x10: cvt_d({{ + 0x10: cvt_d({{ int rnd_mode = xc->miscRegs.fcsr; Fd = convert_and_round(Fs.df,rnd_mode,FP_DOUBLE,FP_WORD); }}); - } - } + } + } - //Table A-16 MIPS32 COP1 Encoding of Function Field When rs=L1 - //Note: "1. Format type L is legal only if 64-bit floating point operations - //are enabled." - 0x5: decode FUNCTION_HI { - format FloatOp { - 0x10: cvt_s_l({{ + //Table A-16 MIPS32 COP1 Encoding of Function Field When rs=L1 + //Note: "1. Format type L is legal only if 64-bit floating point operations + //are enabled." + 0x5: decode FUNCTION_HI { + format FloatOp { + 0x10: cvt_s_l({{ int rnd_mode = xc->miscRegs.fcsr; Fd = convert_and_round(Fs.df,rnd_mode,FP_SINGLE,FP_LONG); }}); - 0x11: cvt_d_l({{ + 0x11: cvt_d_l({{ int rnd_mode = xc->miscRegs.fcsr; Fd = convert_and_round(Fs.df,rnd_mode,FP_DOUBLE,FP_LONG); }}); - } - } + } + } - //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 { - format Float64Op { - 0x0: addps({{ //Must Check for Exception Here... Supposed to Operate on Upper and - //Lower Halves Independently but we take simulator shortcut - Fd.df = Fs.df + Ft.df; - }}); + //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 { + format Float64Op { + 0x0: addps({{ //Must Check for Exception Here... Supposed to Operate on Upper and + //Lower Halves Independently but we take simulator shortcut + Fd.df = Fs.df + Ft.df; + }}); - 0x1: subps({{ //Must Check for Exception Here... Supposed to Operate on Upper and - //Lower Halves Independently but we take simulator shortcut - Fd.df = Fs.df - Ft.df; - }}); + 0x1: subps({{ //Must Check for Exception Here... Supposed to Operate on Upper and + //Lower Halves Independently but we take simulator shortcut + Fd.df = Fs.df - Ft.df; + }}); - 0x2: mulps({{ //Must Check for Exception Here... Supposed to Operate on Upper and - //Lower Halves Independently but we take simulator shortcut - Fd.df = Fs.df * Ft.df; - }}); + 0x2: mulps({{ //Must Check for Exception Here... Supposed to Operate on Upper and + //Lower Halves Independently but we take simulator shortcut + Fd.df = Fs.df * Ft.df; + }}); - 0x5: absps({{ //Must Check for Exception Here... Supposed to Operate on Upper and - //Lower Halves Independently but we take simulator shortcut - Fd.df = abs(Fs.df); - }}); + 0x5: absps({{ //Must Check for Exception Here... Supposed to Operate on Upper and + //Lower Halves Independently but we take simulator shortcut + Fd.df = abs(Fs.df); + }}); - 0x6: movps({{ //Must Check for Exception Here... Supposed to Operate on Upper and - //Lower Halves Independently but we take simulator shortcut - Fd.df = Fs<31:0> | Ft<31:0>; - }}); + 0x6: movps({{ //Must Check for Exception Here... Supposed to Operate on Upper and + //Lower Halves Independently but we take simulator shortcut + Fd.df = Fs<31:0> | Ft<31:0>; + }}); - 0x7: negps({{ //Must Check for Exception Here... Supposed to Operate on Upper and - //Lower Halves Independently but we take simulator shortcut - Fd.df = -1 * Fs.df; - }}); - } - } + 0x7: negps({{ //Must Check for Exception Here... Supposed to Operate on Upper and + //Lower Halves Independently but we take simulator shortcut + Fd.df = -1 * Fs.df; + }}); + } + } - 0x2: decode RS_LO { - 0x1: decode MOVCF { - format Float64Op { - 0x0: movfps({{ if ( FPConditionCode(CC) == 0) Fd = Fs;}}); - 0x1: movtps({{ if ( FPConditionCode(CC) == 0) Fd = Fs;}}); - } - } + 0x2: decode RS_LO { + 0x1: decode MOVCF { + format Float64Op { + 0x0: movfps({{ if ( FPConditionCode(CC) == 0) Fd = Fs;}}); + 0x1: movtps({{ if ( FPConditionCode(CC) == 0) Fd = Fs;}}); + } + } - } + } - 0x4: decode RS_LO { - 0x0: Float64Op::cvt_s_pu({{ + 0x4: decode RS_LO { + 0x0: Float64Op::cvt_s_pu({{ int rnd_mode = xc->miscRegs.fcsr; Fd = convert_and_round(Fs.df,rnd_mode,FP_DOUBLE,FP_PS_HI); - }}); - } + }}); + } - 0x5: decode RS_LO { - format Float64Op { - 0x0: cvt_s_pl({{ - int rnd_mode = xc->miscRegs.fcsr; - Fd = convert_and_round(Fs.df,rnd_mode,FP_SINGLE,FP_PS_LO); - }}); - 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>}}); + 0x5: decode RS_LO { + format Float64Op { + 0x0: cvt_s_pl({{ + int rnd_mode = xc->miscRegs.fcsr; + Fd = convert_and_round(Fs.df,rnd_mode,FP_SINGLE,FP_PS_LO); + }}); + 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>}}); + } + } + } } - } } - } - - //Table A-19 MIPS32 COP2 Encoding of rs Field - 0x2: decode RS_MSB { - 0x0: decode RS_HI { - 0x0: decode RS_LO { - format WarnUnimpl { - 0x0: mfc2(); - 0x2: cfc2(); - 0x3: mfhc2(); - 0x4: mtc2(); - 0x6: ctc2(); - 0x7: mftc2(); - } - } - - 0x1: decode ND { - 0x0: decode TF { - format WarnUnimpl { - 0x0: bc2f(); - 0x1: bc2t(); - } - } - - 0x1: decode TF { - format WarnUnimpl { - 0x0: bc2fl(); - 0x1: bc2tl(); - } - } - } - } - } - - //Table A-20 MIPS64 COP1X Encoding of Function Field 1 - //Note: "COP1X instructions are legal only if 64-bit floating point - //operations are enabled." - 0x3: decode FUNCTION_HI { - 0x0: decode FUNCTION_LO { - format Memory { - 0x0: lwxc1({{ EA = Rs + Rt; }},{{ Ft<31:0> = Mem.uf; }}); - 0x1: ldxc1({{ EA = Rs + Rt; }},{{ Ft<63:0> = Mem.df; }}); - 0x5: luxc1({{ //Need to make EA<2:0> = 0 - EA = Rs + Rt; - }}, - {{ Ft<31:0> = Mem.df; }}); - } } - 0x1: decode FUNCTION_LO { + //Table A-19 MIPS32 COP2 Encoding of rs Field + 0x2: decode RS_MSB { + 0x0: decode RS_HI { + 0x0: decode RS_LO { + format WarnUnimpl { + 0x0: mfc2(); + 0x2: cfc2(); + 0x3: mfhc2(); + 0x4: mtc2(); + 0x6: ctc2(); + 0x7: mftc2(); + } + } + + 0x1: decode ND { + 0x0: decode TF { + format WarnUnimpl { + 0x0: bc2f(); + 0x1: bc2t(); + } + } + + 0x1: decode TF { + format WarnUnimpl { + 0x0: bc2fl(); + 0x1: bc2tl(); + } + } + } + } + } + + //Table A-20 MIPS64 COP1X Encoding of Function Field 1 + //Note: "COP1X instructions are legal only if 64-bit floating point + //operations are enabled." + 0x3: decode FUNCTION_HI { + 0x0: decode FUNCTION_LO { format Memory { - 0x0: swxc1({{ EA = Rs + Rt; }},{{ Mem.uf = Ft<31:0>; }}); - 0x1: sdxc1({{ EA = Rs + Rt; }},{{ Mem.uf = Ft<63:0>}}); - 0x5: suxc1({{ //Need to make EA<2:0> = 0 - EA = Rs + Rt; - }}, - {{ Mem.df = Ft<63:0>;}}); + 0x0: lwxc1({{ EA = Rs + Rt; }},{{ Ft<31:0> = Mem.uf; }}); + 0x1: ldxc1({{ EA = Rs + Rt; }},{{ Ft<63:0> = Mem.df; }}); + 0x5: luxc1({{ //Need to make EA<2:0> = 0 + EA = Rs + Rt; + }}, + {{ Ft<31:0> = Mem.df; }}); + } + } + + 0x1: decode FUNCTION_LO { + format Memory { + 0x0: swxc1({{ EA = Rs + Rt; }},{{ Mem.uf = Ft<31:0>; }}); + 0x1: sdxc1({{ EA = Rs + Rt; }},{{ Mem.uf = Ft<63:0>}}); + 0x5: suxc1({{ //Need to make EA<2:0> = 0 + EA = Rs + Rt; + }}, + {{ Mem.df = Ft<63:0>;}}); } 0x7: WarnUnimpl::prefx(); - } + } - format FloatOp { + format FloatOp { 0x3: WarnUnimpl::alnv_ps(); format BasicOp { - 0x4: decode FUNCTION_LO { - 0x0: madd_s({{ Fd.sf = (Fs.sf * Fs.sf) + Fr.sf; }}); - 0x1: madd_d({{ Fd.df = (Fs.df * Fs.df) + Fr.df; }}); - 0x6: madd_ps({{ - //Must Check for Exception Here... Supposed to Operate on Upper and - //Lower Halves Independently but we take simulator shortcut - Fd.df = (Fs.df * Fs.df) + Fr.df; - }}); - } + 0x4: decode FUNCTION_LO { + 0x0: madd_s({{ Fd.sf = (Fs.sf * Fs.sf) + Fr.sf; }}); + 0x1: madd_d({{ Fd.df = (Fs.df * Fs.df) + Fr.df; }}); + 0x6: madd_ps({{ + //Must Check for Exception Here... Supposed to Operate on Upper and + //Lower Halves Independently but we take simulator shortcut + Fd.df = (Fs.df * Fs.df) + Fr.df; + }}); + } - 0x5: decode FUNCTION_LO { - 0x0: msub_s({{ Fd.sf = (Fs.sf * Fs.sf) - Fr.sf; }}); - 0x1: msub_d({{ Fd.df = (Fs.df * Fs.df) - Fr.df; }}); - 0x6: msub_ps({{ - //Must Check for Exception Here... Supposed to Operate on Upper and - //Lower Halves Independently but we take simulator shortcut - Fd.df = (Fs.df * Fs.df) - Fr.df; - }}); - } + 0x5: decode FUNCTION_LO { + 0x0: msub_s({{ Fd.sf = (Fs.sf * Fs.sf) - Fr.sf; }}); + 0x1: msub_d({{ Fd.df = (Fs.df * Fs.df) - Fr.df; }}); + 0x6: msub_ps({{ + //Must Check for Exception Here... Supposed to Operate on Upper and + //Lower Halves Independently but we take simulator shortcut + Fd.df = (Fs.df * Fs.df) - Fr.df; + }}); + } - 0x6: decode FUNCTION_LO { - 0x0: nmadd_s({{ Fd.sf = (-1 * Fs.sf * Fs.sf) - Fr.sf; }}); - 0x1: nmadd_d({{ Fd.df = (-1 * Fs.df * Fs.df) + Fr.df; }}); - 0x6: nmadd_ps({{ - //Must Check for Exception Here... Supposed to Operate on Upper and - //Lower Halves Independently but we take simulator shortcut - Fd.df = (-1 * Fs.df * Fs.df) + Fr.df; - }}); - } + 0x6: decode FUNCTION_LO { + 0x0: nmadd_s({{ Fd.sf = (-1 * Fs.sf * Fs.sf) - Fr.sf; }}); + 0x1: nmadd_d({{ Fd.df = (-1 * Fs.df * Fs.df) + Fr.df; }}); + 0x6: nmadd_ps({{ + //Must Check for Exception Here... Supposed to Operate on Upper and + //Lower Halves Independently but we take simulator shortcut + Fd.df = (-1 * Fs.df * Fs.df) + Fr.df; + }}); + } - 0x7: decode FUNCTION_LO { - 0x0: nmsub_s({{ Fd.sf = (-1 * Fs.sf * Fs.sf) - Fr.sf; }}); - 0x1: nmsub_d({{ Fd.df = (-1 * Fs.df * Fs.df) - Fr.df; }}); - 0x6: nmsub_ps({{ - //Must Check for Exception Here... Supposed to Operate on Upper and - //Lower Halves Independently but we take simulator shortcut - Fd.df = (-1 * Fs.df * Fs.df) + Fr.df; - }}); - } + 0x7: decode FUNCTION_LO { + 0x0: nmsub_s({{ Fd.sf = (-1 * Fs.sf * Fs.sf) - Fr.sf; }}); + 0x1: nmsub_d({{ Fd.df = (-1 * Fs.df * Fs.df) - Fr.df; }}); + 0x6: nmsub_ps({{ + //Must Check for Exception Here... Supposed to Operate on Upper and + //Lower Halves Independently but we take simulator shortcut + Fd.df = (-1 * Fs.df * Fs.df) + Fr.df; + }}); + } } + } } - } - //MIPS obsolete instructions + //MIPS obsolete instructions format BranchLikely { - 0x4: beql({{ cond = (Rs.sw == 0); }}); - 0x5: bnel({{ cond = (Rs.sw != 0); }}); - 0x6: blezl({{ cond = (Rs.sw <= 0); }}); - 0x7: bgtzl({{ cond = (Rs.sw > 0); }}); + 0x4: beql({{ cond = (Rs.sw == 0); }}); + 0x5: bnel({{ cond = (Rs.sw != 0); }}); + 0x6: blezl({{ cond = (Rs.sw <= 0); }}); + 0x7: bgtzl({{ cond = (Rs.sw > 0); }}); } } @@ -759,89 +760,89 @@ decode OPCODE_HI default Unknown::unknown() { 0x0: decode FUNCTION_LO { format IntOp { - 0x0: madd({{ + 0x0: madd({{ INT64 temp1 = Hi.sw << 32 | Lo.sw >> 32; temp1 = temp1 + (Rs.sw * Rt.sw); xc->miscRegs.hi->temp1<63:32>; xc->miscRegs.lo->temp1<31:0> - }}); + }}); - 0x1: maddu({{ + 0x1: maddu({{ INT64 temp1 = Hi.uw << 32 | Lo.uw >> 32; temp1 = temp1 + (Rs.uw * Rt.uw); xc->miscRegs.hi->temp1<63:32>; xc->miscRegs.lo->temp1<31:0> - }}); + }}); - 0x2: mul({{ Rd.sw = Rs.sw * Rt.sw; }}); + 0x2: mul({{ Rd.sw = Rs.sw * Rt.sw; }}); - 0x4: msub({{ + 0x4: msub({{ INT64 temp1 = Hi.sw << 32 | Lo.sw >> 32; temp1 = temp1 - (Rs.sw * Rt.sw); xc->miscRegs.hi->temp1<63:32>; xc->miscRegs.lo->temp1<31:0> - }}); + }}); - 0x5: msubu({{ + 0x5: msubu({{ INT64 temp1 = Hi.uw << 32 | Lo.uw >> 32; temp1 = temp1 - (Rs.uw * Rt.uw); xc->miscRegs.hi->temp1<63:32>; xc->miscRegs.lo->temp1<31:0> - }}); + }}); } } 0x4: decode FUNCTION_LO { - format BasicOp { - 0x0: clz({{ + format BasicOp { + 0x0: clz({{ int cnt = 0; int idx = 0; while ( Rs.uw!= 1) { - cnt++; - idx--; + cnt++; + idx--; } Rd.uw = cnt; - }}); + }}); - 0x1: clo({{ + 0x1: clo({{ int cnt = 0; int idx = 0; while ( Rs.uw!= 0) { - cnt++; - idx--; + cnt++; + idx--; } Rd.uw = cnt; - }}); - } + }}); + } } 0x7: decode FUNCTION_LO { - 0x7: WarnUnimpl::sdbbp(); + 0x7: WarnUnimpl::sdbbp(); } } //Table A-6 MIPS32 SPECIAL3 Encoding of Function Field for Release 2 of the Architecture 0x7: decode FUNCTION_HI { - 0x0: decode FUNCTION_LO { + 0x0: decode FUNCTION_LO { format WarnUnimpl { 0x1: ext(); 0x4: ins(); } - } + } - 0x1: decode FUNCTION_LO { + 0x1: decode FUNCTION_LO { format WarnUnimpl { 0x0: fork(); 0x1: yield(); } - } + } - //Table A-10 MIPS32 BSHFL Encoding of sa Field - 0x4: decode SA { + //Table A-10 MIPS32 BSHFL Encoding of sa Field + 0x4: decode SA { 0x02: WarnUnimpl::wsbh(); @@ -849,11 +850,11 @@ decode OPCODE_HI default Unknown::unknown() { 0x10: seb({{ Rd.sw = /* sext32(Rt<7>,24) | */ Rt<7:0>}}); 0x18: seh({{ Rd.sw = /* sext32(Rt<15>,16) | */ Rt<15:0>}}); } - } + } - 0x6: decode FUNCTION_LO { - 0x7: BasicOp::rdhwr({{ Rt = xc->hwRegs[RD];}}); - } + 0x6: decode FUNCTION_LO { + 0x7: BasicOp::rdhwr({{ Rt = xc->hwRegs[RD];}}); + } } } @@ -887,7 +888,7 @@ decode OPCODE_HI default Unknown::unknown() { } 0x6: decode OPCODE_LO default FailUnimpl::reserved() { - 0x0: WarnUnimpl::ll(); + 0x0: WarnUnimpl::ll(); format Memory { 0x1: lwc1({{ EA = Rs + disp; }},{{ Ft<31:0> = Mem.uf; }}); diff --git a/arch/mips/isa/formats.isa b/arch/mips/isa/formats.isa index 61ac185d3..c244013df 100644 --- a/arch/mips/isa/formats.isa +++ b/arch/mips/isa/formats.isa @@ -1,9 +1,15 @@ -//Templates from this format are used later -##include "m5/arch/mips/isa/formats/util.isa" +// -*- mode:c++ -*- +//Templates from this format are used later //Include the basic format ##include "m5/arch/mips/isa/formats/basic.isa" +//Include the basic format +##include "m5/arch/mips/isa/formats/noop.isa" + +//Include utility formats/functions +##include "m5/arch/mips/isa/formats/util.isa" + //Include the integerOp and integerOpCc format ##include "m5/arch/mips/isa/formats/int.isa" @@ -19,10 +25,6 @@ //Include the branch format ##include "m5/arch/mips/isa/formats/branch.isa" -//Include the noop format -##include "m5/arch/mips/isa/formats/noop.isa" - - //Include the noop format ##include "m5/arch/mips/isa/formats/unimp.isa" diff --git a/arch/mips/isa/formats/branch.isa b/arch/mips/isa/formats/branch.isa index c7c97c2c8..75e7830d0 100644 --- a/arch/mips/isa/formats/branch.isa +++ b/arch/mips/isa/formats/branch.isa @@ -61,8 +61,7 @@ output header {{ }; /** - * Base class for branches (PC-relative control transfers), - * conditional or unconditional. + * Base class for branch likely branches (PC-relative control transfers), */ class BranchLikely : public PCDependentDisassembly { @@ -206,14 +205,21 @@ output decoder {{ } }}; + def template JumpOrBranchDecode {{ return (RD == 0) ? (StaticInst *)new %(class_name)s(machInst) : (StaticInst *)new %(class_name)sAndLink(machInst); }}; -def format Branch(code) {{ - code = 'bool cond;\n' + code + '\nif (cond) NPC = NPC + disp;\n'; +def format Branch(code,*flags) {{ + code = 'bool cond;\n' + code + '\n' + + if flags == 'IsLink': + code += 'R31 = NPC + 8\n' + + code += '\nif (cond) NPC = NPC + disp;\n'; + iop = InstObjParams(name, Name, 'Branch', CodeBlock(code), ('IsDirectControl', 'IsCondControl')) header_output = BasicDeclare.subst(iop) @@ -222,11 +228,23 @@ def format Branch(code) {{ exec_output = BasicExecute.subst(iop) }}; - -def format BranchLikely(code) {{ +def format BranchLikely(code,*flags) {{ code = 'bool cond;\n' + code + '\nif (cond) NPC = NPC + disp;\n'; + + if flags == 'IsLink': + code += 'R31 = NPC + 8\n' + iop = InstObjParams(name, Name, 'Branch', CodeBlock(code), - ('IsDirectControl', 'IsCondControl')) + ('IsDirectControl', 'IsCondControl','IsCondDelaySlot')) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecode.subst(iop) + exec_output = BasicExecute.subst(iop) +}}; + +def format Unconditional(code,*flags) {{ + iop = InstObjParams(name, Name, 'Jump', CodeBlock(code), + ('IsIndirectControl', 'IsUncondControl')) header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) decode_block = BasicDecode.subst(iop) @@ -234,16 +252,5 @@ def format BranchLikely(code) {{ }}; -def format UncondBranch(*flags) {{ - flags += ('IsUncondControl', 'IsDirectControl') - (header_output, decoder_output, decode_block, exec_output) = \ - UncondCtrlBase(name, Name, 'Branch', 'NPC + disp', flags) -}}; - -def format Jump(*flags) {{ - flags += ('IsUncondControl', 'IsIndirectControl') - (header_output, decoder_output, decode_block, exec_output) = \ - UncondCtrlBase(name, Name, 'Jump', '(Rb & ~3) | (NPC & 1)', flags) -}}; diff --git a/arch/mips/isa/formats/int.isa b/arch/mips/isa/formats/int.isa index 982992b41..cf06741a1 100644 --- a/arch/mips/isa/formats/int.isa +++ b/arch/mips/isa/formats/int.isa @@ -53,18 +53,6 @@ output decoder {{ }}; -// integer & FP operate instructions use Rd as dest, so check for -// Rd == 0 to detect nops -def template OperateNopCheckDecode {{ - { - MipsStaticInst *i = new %(class_name)s(machInst); - if (RD == 0) { - i = makeNop(i); - } - return i; - } -}}; - //Used by decoder.isa def format IntOp(code, *opt_flags) {{ orig_code = code diff --git a/arch/mips/isa/formats/noop.isa b/arch/mips/isa/formats/noop.isa index 6d45ba9b6..d366461e2 100644 --- a/arch/mips/isa/formats/noop.isa +++ b/arch/mips/isa/formats/noop.isa @@ -1,50 +1,4 @@ -//////////////////////////////////////////////////////////////////// -// -// Noop instruction -// - -output header {{ - /** - * Base class for integer operations. - */ - class Noop : public MipsStaticInst - { - protected: - - /// Constructor - Noop(const char *mnem, MachInst _machInst, OpClass __opClass) : MipsStaticInst(mnem, _machInst, __opClass) - { - } - - std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; - }; -}}; - -output decoder {{ - std::string Noop::generateDisassembly(Addr pc, const SymbolTable *symtab) const - { - return "Disassembly of integer instruction\n"; - } -}}; - -def template NoopExecute {{ - Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const - { - //Nothing to see here, move along - return No_Fault; - } -}}; - -// Primary format for integer operate instructions: -def format Noop(code, *opt_flags) {{ - orig_code = code - cblk = CodeBlock(code) - iop = InstObjParams(name, Name, 'MipsStaticInst', cblk, opt_flags) - header_output = BasicDeclare.subst(iop) - decoder_output = BasicConstructor.subst(iop) - decode_block = BasicDecodeWithMnemonic.subst(iop) - exec_output = NoopExecute.subst(iop) -}}; +// -*- mode:c++ -*- //////////////////////////////////////////////////////////////////// // @@ -55,7 +9,7 @@ output header {{ /** * Static instruction class for no-ops. This is a leaf class. */ - class Nop : public AlphaStaticInst + class Nop : public MipsStaticInst { /// Disassembly of original instruction. const std::string originalDisassembly; @@ -63,7 +17,7 @@ output header {{ public: /// Constructor Nop(const std::string _originalDisassembly, MachInst _machInst) - : AlphaStaticInst("nop", _machInst, No_OpClass), + : MipsStaticInst("nop", _machInst, No_OpClass), originalDisassembly(_originalDisassembly) { flags[IsNop] = true; @@ -92,10 +46,10 @@ output decoder {{ /// Helper function for decoding nops. Substitute Nop object /// for original inst passed in as arg (and delete latter). inline - AlphaStaticInst * - makeNop(AlphaStaticInst *inst) + MipsStaticInst * + makeNop(MipsStaticInst *inst) { - AlphaStaticInst *nop = new Nop(inst->disassemble(0), inst->machInst); + MipsStaticInst *nop = new Nop(inst->disassemble(0), inst->machInst); delete inst; return nop; } @@ -113,7 +67,7 @@ output exec {{ // Rc == 31 to detect nops def template OperateNopCheckDecode {{ { - AlphaStaticInst *i = new %(class_name)s(machInst); + MipsStaticInst *i = new %(class_name)s(machInst); if (RC == 31) { i = makeNop(i); } @@ -124,7 +78,7 @@ def template OperateNopCheckDecode {{ // Like BasicOperate format, but generates NOP if RC/FC == 31 def format BasicOperateWithNopCheck(code, *opt_args) {{ - iop = InstObjParams(name, Name, 'AlphaStaticInst', CodeBlock(code), + iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), opt_args) header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) From 159e3345314b921f05f808ace06d62adf79f095a Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Sat, 18 Feb 2006 04:17:11 -0500 Subject: [PATCH 061/180] use string name to figure out if we have a "AndLink" instruction arch/mips/isa/operands.isa: uq -> uw --HG-- extra : convert_revision : eeac6dba813de8174d080a5fa9b5a396b345113a --- arch/mips/isa/formats/branch.isa | 12 +++++++----- arch/mips/isa/operands.isa | 4 ++-- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/arch/mips/isa/formats/branch.isa b/arch/mips/isa/formats/branch.isa index 75e7830d0..c003cb63d 100644 --- a/arch/mips/isa/formats/branch.isa +++ b/arch/mips/isa/formats/branch.isa @@ -213,10 +213,11 @@ def template JumpOrBranchDecode {{ }}; def format Branch(code,*flags) {{ - code = 'bool cond;\n' + code + '\n' + code = 'bool cond;\n\t' + code + '\n' - if flags == 'IsLink': - code += 'R31 = NPC + 8\n' + strlen = len(name) + if name[strlen-2:] == 'al': + code += 'R31 = NPC + 8;\n' code += '\nif (cond) NPC = NPC + disp;\n'; @@ -231,8 +232,9 @@ def format Branch(code,*flags) {{ def format BranchLikely(code,*flags) {{ code = 'bool cond;\n' + code + '\nif (cond) NPC = NPC + disp;\n'; - if flags == 'IsLink': - code += 'R31 = NPC + 8\n' + strlen = len(name) + if name[strlen-3:] == 'all': + code += 'R31 = NPC + 8;\n' iop = InstObjParams(name, Name, 'Branch', CodeBlock(code), ('IsDirectControl', 'IsCondControl','IsCondDelaySlot')) diff --git a/arch/mips/isa/operands.isa b/arch/mips/isa/operands.isa index cf6f10e0b..19d21ac8d 100644 --- a/arch/mips/isa/operands.isa +++ b/arch/mips/isa/operands.isa @@ -26,10 +26,10 @@ def operands {{ 'Mem': ('Mem', 'ud', None, ('IsMemRef', 'IsLoad', 'IsStore'), 4) - #'NPC': ('NPC', 'uq', None, ( None, None, 'IsControl' ), 4), + #'NPC': ('NPC', 'uw', None, ( None, None, 'IsControl' ), 4), #'Runiq': ('ControlReg', 'uq', 'Uniq', None, 1), #'FPCR': ('ControlReg', 'uq', 'Fpcr', None, 1), # The next two are hacks for non-full-system call-pal emulation #'R0': ('IntReg', 'uq', '0', None, 1), - #'R16': ('IntReg', 'uq', '16', None, 1) + #'R31': ('IntReg', 'uw', '31', None, 1) }}; From bd175809286e8da64176da977aeb27fc6ff6d272 Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Sat, 18 Feb 2006 14:38:23 -0500 Subject: [PATCH 062/180] changes from mergedmem arch/mips/isa/formats/branch.isa: add branch_likely member functions cpu/base.hh: cpu/exec_context.hh: cpu/static_inst.hh: change from mergedmem --HG-- extra : convert_revision : d6ad6943e2ef09eac91a466fc5c9bd8e66bf319a --- arch/mips/isa/formats/branch.isa | 57 +++++++++++++++++++++++++++----- cpu/base.hh | 4 ++- cpu/exec_context.hh | 40 +++++++++++----------- cpu/static_inst.hh | 10 ++++-- 4 files changed, 81 insertions(+), 30 deletions(-) diff --git a/arch/mips/isa/formats/branch.isa b/arch/mips/isa/formats/branch.isa index c003cb63d..d9dd433e3 100644 --- a/arch/mips/isa/formats/branch.isa +++ b/arch/mips/isa/formats/branch.isa @@ -115,6 +115,12 @@ output decoder {{ return branchPC + 4 + disp; } + Addr + BranchLikely::branchTarget(Addr branchPC) const + { + return branchPC + 4 + disp; + } + Addr Jump::branchTarget(ExecContext *xc) const { @@ -162,6 +168,44 @@ output decoder {{ ss << ","; } +#ifdef SS_COMPATIBLE_DISASSEMBLY + if (_numSrcRegs == 0 && _numDestRegs == 0) { + printReg(ss, 31); + ss << ","; + } +#endif + + Addr target = pc + 4 + disp; + + std::string str; + if (symtab && symtab->findSymbol(target, str)) + ss << str; + else + ccprintf(ss, "0x%x", target); + + return ss.str(); + } + + std::string + BranchLikely::generateDisassembly(Addr pc, const SymbolTable *symtab) const + { + std::stringstream ss; + + ccprintf(ss, "%-10s ", mnemonic); + + // There's only one register arg (RA), but it could be + // either a source (the condition for conditional + // branches) or a destination (the link reg for + // unconditional branches) + if (_numSrcRegs > 0) { + printReg(ss, _srcRegIdx[0]); + ss << ","; + } + else if (_numDestRegs > 0) { + printReg(ss, _destRegIdx[0]); + ss << ","; + } + #ifdef SS_COMPATIBLE_DISASSEMBLY if (_numSrcRegs == 0 && _numDestRegs == 0) { printReg(ss, 31); @@ -205,16 +249,10 @@ output decoder {{ } }}; - -def template JumpOrBranchDecode {{ - return (RD == 0) - ? (StaticInst *)new %(class_name)s(machInst) - : (StaticInst *)new %(class_name)sAndLink(machInst); -}}; - def format Branch(code,*flags) {{ code = 'bool cond;\n\t' + code + '\n' + #Add Link Code if Link instruction strlen = len(name) if name[strlen-2:] == 'al': code += 'R31 = NPC + 8;\n' @@ -230,12 +268,15 @@ def format Branch(code,*flags) {{ }}; def format BranchLikely(code,*flags) {{ - code = 'bool cond;\n' + code + '\nif (cond) NPC = NPC + disp;\n'; + code = 'bool cond;\n\t\t\t' + code + #Add Link Code if Link instruction strlen = len(name) if name[strlen-3:] == 'all': code += 'R31 = NPC + 8;\n' + code = '\t\t\tif (cond) NPC = NPC + disp;\n'; + iop = InstObjParams(name, Name, 'Branch', CodeBlock(code), ('IsDirectControl', 'IsCondControl','IsCondDelaySlot')) header_output = BasicDeclare.subst(iop) diff --git a/cpu/base.hh b/cpu/base.hh index 2bd1210d8..09a73ab16 100644 --- a/cpu/base.hh +++ b/cpu/base.hh @@ -36,7 +36,7 @@ #include "cpu/sampler/sampler.hh" #include "sim/eventq.hh" #include "sim/sim_object.hh" -#include "arch/isa_traits.hh" +#include "targetarch/isa_traits.hh" #if FULL_SYSTEM class System; @@ -140,6 +140,8 @@ class BaseCPU : public SimObject virtual void startup(); virtual void regStats(); + virtual void activateWhenReady(int tid) {}; + void registerExecContexts(); /// Prepare for another CPU to take over execution. When it is diff --git a/cpu/exec_context.hh b/cpu/exec_context.hh index 7e195af23..845f9264b 100644 --- a/cpu/exec_context.hh +++ b/cpu/exec_context.hh @@ -80,7 +80,7 @@ class ExecContext Active, /// Temporarily inactive. Entered while waiting for - /// synchronization, etc. + /// initialization,synchronization, etc. Suspended, /// Permanently shut down. Entered when target executes @@ -95,6 +95,8 @@ class ExecContext public: Status status() const { return _status; } + void setStatus(Status newStatus) { _status = newStatus; } + /// Set the status to Active. Optional delay indicates number of /// cycles to wait before beginning execution. void activate(int delay = 1); @@ -206,17 +208,17 @@ class ExecContext int getInstAsid() { return regs.instAsid(); } int getDataAsid() { return regs.dataAsid(); } - Fault * translateInstReq(MemReqPtr &req) + Fault translateInstReq(MemReqPtr &req) { return itb->translate(req); } - Fault * translateDataReadReq(MemReqPtr &req) + Fault translateDataReadReq(MemReqPtr &req) { return dtb->translate(req, false); } - Fault * translateDataWriteReq(MemReqPtr &req) + Fault translateDataWriteReq(MemReqPtr &req) { return dtb->translate(req, true); } @@ -231,7 +233,7 @@ class ExecContext int getInstAsid() { return asid; } int getDataAsid() { return asid; } - Fault * dummyTranslation(MemReqPtr &req) + Fault dummyTranslation(MemReqPtr &req) { #if 0 assert((req->vaddr >> 48 & 0xffff) == 0); @@ -240,17 +242,17 @@ class ExecContext // put the asid in the upper 16 bits of the paddr req->paddr = req->vaddr & ~((Addr)0xffff << sizeof(Addr) * 8 - 16); req->paddr = req->paddr | (Addr)req->asid << sizeof(Addr) * 8 - 16; - return NoFault; + return No_Fault; } - Fault * translateInstReq(MemReqPtr &req) + Fault translateInstReq(MemReqPtr &req) { return dummyTranslation(req); } - Fault * translateDataReadReq(MemReqPtr &req) + Fault translateDataReadReq(MemReqPtr &req) { return dummyTranslation(req); } - Fault * translateDataWriteReq(MemReqPtr &req) + Fault translateDataWriteReq(MemReqPtr &req) { return dummyTranslation(req); } @@ -258,7 +260,7 @@ class ExecContext #endif template - Fault * read(MemReqPtr &req, T &data) + Fault read(MemReqPtr &req, T &data) { #if FULL_SYSTEM && defined(TARGET_ALPHA) if (req->flags & LOCKED) { @@ -268,14 +270,14 @@ class ExecContext } #endif - Fault * error; + Fault error; error = mem->read(req, data); data = LittleEndianGuest::gtoh(data); return error; } template - Fault * write(MemReqPtr &req, T &data) + Fault write(MemReqPtr &req, T &data) { #if FULL_SYSTEM && defined(TARGET_ALPHA) @@ -301,7 +303,7 @@ class ExecContext << "on cpu " << req->xc->cpu_id << std::endl; } - return NoFault; + return No_Fault; } else req->xc->storeCondFailures = 0; } @@ -333,7 +335,7 @@ class ExecContext inst = new_inst; } - Fault * instRead(MemReqPtr &req) + Fault instRead(MemReqPtr &req) { return mem->read(req, inst); } @@ -412,13 +414,13 @@ class ExecContext } #if FULL_SYSTEM - uint64_t readIpr(int idx, Fault * &fault); - Fault * setIpr(int idx, uint64_t val); + uint64_t readIpr(int idx, Fault &fault); + Fault setIpr(int idx, uint64_t val); int readIntrFlag() { return regs.intrflag; } void setIntrFlag(int val) { regs.intrflag = val; } - Fault * hwrei(); + Fault hwrei(); bool inPalMode() { return AlphaISA::PcPAL(regs.pc); } - void ev5_trap(Fault * fault); + void ev5_trap(Fault fault); bool simPalCheck(int palFunc); #endif @@ -428,7 +430,7 @@ class ExecContext * @todo How to do this properly so it's dependent upon ISA only? */ - void trap(Fault * fault); + void trap(Fault fault); #if !FULL_SYSTEM IntReg getSyscallArg(int i) diff --git a/cpu/static_inst.hh b/cpu/static_inst.hh index 24997eadc..c574173c2 100644 --- a/cpu/static_inst.hh +++ b/cpu/static_inst.hh @@ -36,7 +36,7 @@ #include "base/refcnt.hh" #include "encumbered/cpu/full/op_class.hh" #include "sim/host.hh" -#include "arch/isa_traits.hh" +#include "targetarch/isa_traits.hh" // forward declarations struct AlphaSimpleImpl; @@ -113,6 +113,8 @@ class StaticInstBase : public RefCounted IsSerializing, ///< Serializes pipeline: won't execute until all /// older instructions have committed. + IsSerializeBefore, + IsSerializeAfter, IsMemBarrier, ///< Is a memory barrier IsWriteBarrier, ///< Is a write barrier @@ -196,7 +198,11 @@ class StaticInstBase : public RefCounted bool isUncondCtrl() const { return flags[IsUncondControl]; } bool isThreadSync() const { return flags[IsThreadSync]; } - bool isSerializing() const { return flags[IsSerializing]; } + bool isSerializing() const { return flags[IsSerializing] || + flags[IsSerializeBefore] || + flags[IsSerializeAfter]; } + bool isSerializeBefore() const { return flags[IsSerializeBefore]; } + bool isSerializeAfter() const { return flags[IsSerializeAfter]; } bool isMemBarrier() const { return flags[IsMemBarrier]; } bool isWriteBarrier() const { return flags[IsWriteBarrier]; } bool isNonSpeculative() const { return flags[IsNonSpeculative]; } From ef14fd4ad31e5da21ed309770e384d82e0a47b10 Mon Sep 17 00:00:00 2001 From: Lisa Hsu Date: Sat, 18 Feb 2006 17:24:23 -0500 Subject: [PATCH 063/180] Now you can have sublabels for every bar using the self.xsubticklabels parameter. --HG-- extra : convert_revision : a6bdf3a972e81c84947b7d6ae76f828494a125c8 --- util/stats/barchart.py | 56 ++++++++++++++++++++++++++++++++---------- 1 file changed, 43 insertions(+), 13 deletions(-) diff --git a/util/stats/barchart.py b/util/stats/barchart.py index 19cccb58a..99f9b8f35 100644 --- a/util/stats/barchart.py +++ b/util/stats/barchart.py @@ -1,4 +1,4 @@ -# Copyright (c) 2005 The Regents of The University of Michigan +# Copyright (c) 2005-2006 The Regents of The University of Michigan # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -76,12 +76,14 @@ class BarChart(ChartOptions): # bars. if dim == 2: self.chartdata = transpose([data], axes=(2,0,1)) + print shape(self.chartdata) # If the input data is a 3d matrix, then it describes an array # of groups of bars with each bar being an array of stacked # values. if dim == 3: self.chartdata = transpose(data, axes=(1,2,0)) + print shape(self.chartdata) def get_data(self): return self.inputdata @@ -120,14 +122,15 @@ class BarChart(ChartOptions): if self.chartdata is None: raise AttributeError, "Data not set for bar chart!" - self.figure = pylab.figure(figsize=self.chart_size) - self.axes = self.figure.add_axes(self.figure_size) + need_subticks = True dim = len(shape(self.inputdata)) cshape = shape(self.chartdata) + print cshape if dim == 1: colors = self.gen_colors(cshape[2]) colors = [ [ colors ] * cshape[1] ] * cshape[0] + need_subticks = False if dim == 2: colors = self.gen_colors(cshape[0]) @@ -139,6 +142,27 @@ class BarChart(ChartOptions): colors = array(colors) + self.figure = pylab.figure(figsize=self.chart_size) + + outer_axes = None + inner_axes = None + if need_subticks: + self.metaaxes = self.figure.add_axes(self.figure_size) + self.metaaxes.set_yticklabels([]) + self.metaaxes.set_yticks([]) + size = [0] * 4 + size[0] = self.figure_size[0] + size[1] = self.figure_size[1] + .075 + size[2] = self.figure_size[2] + size[3] = self.figure_size[3] - .075 + self.axes = self.figure.add_axes(size) + outer_axes = self.metaaxes + inner_axes = self.axes + else: + self.axes = self.figure.add_axes(self.figure_size) + outer_axes = self.axes + inner_axes = self.axes + bars_in_group = len(self.chartdata) if bars_in_group < 5: width = 1.0 / ( bars_in_group + 1) @@ -156,29 +180,34 @@ class BarChart(ChartOptions): ind = arange(len(bardata)) + i * width + center bar = self.axes.bar(ind, bardata, width, bottom=bottom, color=colors[i][j]) + if dim != 1: + self.metaaxes.bar(ind, [0] * len(bardata), width) stack.append(bar) bottom += bardata bars.append(stack) if self.xlabel is not None: - self.axes.set_xlabel(self.xlabel) + outer_axes.set_xlabel(self.xlabel) if self.ylabel is not None: - self.axes.set_ylabel(self.ylabel) + inner_axes.set_ylabel(self.ylabel) if self.yticks is not None: ymin, ymax = self.axes.get_ylim() nticks = float(len(self.yticks)) ticks = arange(nticks) / (nticks - 1) * (ymax - ymin) + ymin - self.axes.set_yticks(ticks) - self.axes.set_yticklabels(self.yticks) + inner_axes.set_yticks(ticks) + inner_axes.set_yticklabels(self.yticks) elif self.ylim is not None: - self.axes.set_ylim(self.ylim) + self.inner_axes.set_ylim(self.ylim) if self.xticks is not None: - self.axes.set_xticks(arange(cshape[2]) + .5) - self.axes.set_xticklabels(self.xticks) - + outer_axes.set_xticks(arange(cshape[2]) + .5) + outer_axes.set_xticklabels(self.xticks) + if self.xsubticks is not None: + inner_axes.set_xticks(arange((cshape[0] + 1)*cshape[2])*width + 2*center) + self.xsubticks.append('') + inner_axes.set_xticklabels(self.xsubticks * cshape[0], fontsize=8) if self.legend is not None: if dim == 1: lbars = bars[0][0] @@ -220,7 +249,6 @@ class BarChart(ChartOptions): f.close() - if __name__ == '__main__': from random import randrange import random, sys @@ -252,6 +280,8 @@ if __name__ == '__main__': chart1.legend = [ 'x%d' % x for x in xrange(myshape[-1]) ] chart1.xticks = [ 'xtick%d' % x for x in xrange(myshape[0]) ] chart1.title = 'this is the title' + chart1.figure_size = [0.1, 0.2, 0.7, 0.85 ] + chart1.xsubticks = [ '%d' % x for x in xrange(myshape[1]) ] chart1.graph() chart1.savefig('/tmp/test1.png') chart1.savefig('/tmp/test1.ps') @@ -266,4 +296,4 @@ if __name__ == '__main__': chart2.savefig('/tmp/test2.png') chart2.savefig('/tmp/test2.ps') - #pylab.show() + pylab.myshow() From 71bf22165acb4a330a98e183f96188daf49d078f Mon Sep 17 00:00:00 2001 From: Lisa Hsu Date: Sat, 18 Feb 2006 17:29:43 -0500 Subject: [PATCH 064/180] more changes for subtick labels. util/stats/barchart.py: oop forgot this for 1D graph cases. util/stats/chart.py: need to add default param to chart. --HG-- extra : convert_revision : f4e6c6c614d584e7928ed905e97608716455ab6c --- util/stats/barchart.py | 3 ++- util/stats/chart.py | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/util/stats/barchart.py b/util/stats/barchart.py index 99f9b8f35..ddb31be46 100644 --- a/util/stats/barchart.py +++ b/util/stats/barchart.py @@ -281,7 +281,8 @@ if __name__ == '__main__': chart1.xticks = [ 'xtick%d' % x for x in xrange(myshape[0]) ] chart1.title = 'this is the title' chart1.figure_size = [0.1, 0.2, 0.7, 0.85 ] - chart1.xsubticks = [ '%d' % x for x in xrange(myshape[1]) ] + if len(myshape) > 1: + chart1.xsubticks = [ '%d' % x for x in xrange(myshape[1]) ] chart1.graph() chart1.savefig('/tmp/test1.png') chart1.savefig('/tmp/test1.ps') diff --git a/util/stats/chart.py b/util/stats/chart.py index 1e301cb58..095620172 100644 --- a/util/stats/chart.py +++ b/util/stats/chart.py @@ -1,4 +1,4 @@ -# Copyright (c) 2005 The Regents of The University of Michigan +# Copyright (c) 2005-2006 The Regents of The University of Michigan # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -38,6 +38,7 @@ class ChartOptions(object): 'xlabel' : None, 'ylabel' : None, 'xticks' : None, + 'xsubticks' : None, 'yticks' : None, 'ylim' : None, } From 6cf0ba84953b0c18fcd702197f3aec9cf8a33f2d Mon Sep 17 00:00:00 2001 From: Lisa Hsu Date: Sat, 18 Feb 2006 18:39:19 -0500 Subject: [PATCH 065/180] remove print statements --HG-- extra : convert_revision : abd635034424eeb9685aea777440a02887ce81a6 --- util/stats/barchart.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/util/stats/barchart.py b/util/stats/barchart.py index ddb31be46..29d16db17 100644 --- a/util/stats/barchart.py +++ b/util/stats/barchart.py @@ -76,14 +76,12 @@ class BarChart(ChartOptions): # bars. if dim == 2: self.chartdata = transpose([data], axes=(2,0,1)) - print shape(self.chartdata) # If the input data is a 3d matrix, then it describes an array # of groups of bars with each bar being an array of stacked # values. if dim == 3: self.chartdata = transpose(data, axes=(1,2,0)) - print shape(self.chartdata) def get_data(self): return self.inputdata @@ -207,7 +205,7 @@ class BarChart(ChartOptions): if self.xsubticks is not None: inner_axes.set_xticks(arange((cshape[0] + 1)*cshape[2])*width + 2*center) self.xsubticks.append('') - inner_axes.set_xticklabels(self.xsubticks * cshape[0], fontsize=8) + inner_axes.set_xticklabels(self.xsubticks * cshape[2], fontsize=8) if self.legend is not None: if dim == 1: lbars = bars[0][0] From a611b8100379e28728c1084801413954c973e734 Mon Sep 17 00:00:00 2001 From: Lisa Hsu Date: Sat, 18 Feb 2006 20:10:42 -0500 Subject: [PATCH 066/180] few changes for nate: 1) cosmetic - removing visibility of meta axes except for the tick labels. 2) unless subticklabels defined, don't do meta axes. (instead of assuming if you have 3D graph, do meta axes) --HG-- extra : convert_revision : 396011ffaa51ea4066b34257f6fd5b3faac9d242 --- util/stats/barchart.py | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/util/stats/barchart.py b/util/stats/barchart.py index 29d16db17..3f202d9bf 100644 --- a/util/stats/barchart.py +++ b/util/stats/barchart.py @@ -31,6 +31,7 @@ import matplotlib, pylab from matplotlib.font_manager import FontProperties from matplotlib.numerix import array, arange, reshape, shape, transpose, zeros from matplotlib.numerix import Float +from matplotlib.ticker import NullLocator matplotlib.interactive(False) @@ -120,15 +121,11 @@ class BarChart(ChartOptions): if self.chartdata is None: raise AttributeError, "Data not set for bar chart!" - need_subticks = True - dim = len(shape(self.inputdata)) cshape = shape(self.chartdata) - print cshape if dim == 1: colors = self.gen_colors(cshape[2]) colors = [ [ colors ] * cshape[1] ] * cshape[0] - need_subticks = False if dim == 2: colors = self.gen_colors(cshape[0]) @@ -144,15 +141,19 @@ class BarChart(ChartOptions): outer_axes = None inner_axes = None - if need_subticks: - self.metaaxes = self.figure.add_axes(self.figure_size) + if self.xsubticks is not None: + color = self.figure.get_facecolor() + self.metaaxes = self.figure.add_axes(self.figure_size, axisbg=color, frameon=False) + for tick in self.metaaxes.xaxis.majorTicks: + tick.tick1On = False + tick.tick2On = False self.metaaxes.set_yticklabels([]) self.metaaxes.set_yticks([]) size = [0] * 4 size[0] = self.figure_size[0] - size[1] = self.figure_size[1] + .075 + size[1] = self.figure_size[1] + .05 size[2] = self.figure_size[2] - size[3] = self.figure_size[3] - .075 + size[3] = self.figure_size[3] - .05 self.axes = self.figure.add_axes(size) outer_axes = self.metaaxes inner_axes = self.axes @@ -202,10 +203,12 @@ class BarChart(ChartOptions): if self.xticks is not None: outer_axes.set_xticks(arange(cshape[2]) + .5) outer_axes.set_xticklabels(self.xticks) + if self.xsubticks is not None: inner_axes.set_xticks(arange((cshape[0] + 1)*cshape[2])*width + 2*center) self.xsubticks.append('') inner_axes.set_xticklabels(self.xsubticks * cshape[2], fontsize=8) + if self.legend is not None: if dim == 1: lbars = bars[0][0] @@ -279,7 +282,7 @@ if __name__ == '__main__': chart1.xticks = [ 'xtick%d' % x for x in xrange(myshape[0]) ] chart1.title = 'this is the title' chart1.figure_size = [0.1, 0.2, 0.7, 0.85 ] - if len(myshape) > 1: + if len(myshape) > 2: chart1.xsubticks = [ '%d' % x for x in xrange(myshape[1]) ] chart1.graph() chart1.savefig('/tmp/test1.png') From db40f256164028e1ccf10c4232160537f15a0943 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sat, 18 Feb 2006 20:58:08 -0500 Subject: [PATCH 067/180] Changed the isa from a class to a namespace, untemplated StaticInst and StaticInstPtr, converted things to using TheISA, cleaned up some header file paths, and improved the system which pulls header files from the appropriate architecture. --HG-- extra : convert_revision : 5087333fbaf442efb4b55e70376244629fff507d --- arch/isa_specific.hh | 76 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 arch/isa_specific.hh diff --git a/arch/isa_specific.hh b/arch/isa_specific.hh new file mode 100644 index 000000000..e11e6c292 --- /dev/null +++ b/arch/isa_specific.hh @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2003-2005 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __ARCH_ISA_SPECIFIC_HH__ +#define __ARCH_ISA_SPECIFIC_HH__ + +//This file provides a mechanism for other source code to bring in +//files from the ISA being compiled with + +//These are constants so you can selective compile code based on the isa +//To use them, do something like +// +//#if THE_ISA == YOUR_FAVORITE_ISA +// conditional_code +//#endif +// +//Note that this is how this file sets up the other isa "hooks" + +//These macros have numerical values because otherwise the preprocessor +//would treat them as 0 in comparisons. +#define ALPHA_ISA 21064 +#define SPARC_ISA 42 +#define MIPS_ISA 1337 + +//These tell the preprocessor where to find the files of a particular +//ISA, and set the "TheISA" macro for use elsewhere. +#if THE_ISA == ALPHA_ISA + #define ISA_PATH arch/alpha/ + #define TheISA AlphaISA +#elif THE_ISA == SPARC_ISA + #define ISA_PATH arch/sparc/ + #define TheISA SparcISA +#elif THE_ISA == MIPS_ISA + #define ISA_PATH arch/mips/ + #define TheISA MipsISA +#else + #error "THE_ISA not set" +#endif +//The following is some preprocessor voodoo to allow redirectable includes +//The end result is the ISA_INCLUDE() macro which is used inside stub +//include files in arch and which redirect to the isa in use. +#define STRINGIFY(token) #token +#define EXPAND(token) token +#define STICK_TOGETHER(firstpart, secondpart) \ + EXPAND(firstpart)EXPAND(secondpart) +#define EXPAND_AND_STRINGIFY(pathAndFile) \ + STRINGIFY(pathAndFile) +#define ISA_INCLUDE(filename) \ + EXPAND_AND_STRINGIFY(STICK_TOGETHER(ISA_PATH, filename)) + +#endif From a48c24b61eedf580645ff0294b225d1e69a9444b Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Sat, 18 Feb 2006 23:17:45 -0500 Subject: [PATCH 068/180] Support NNPC and branch instructions ... Outputs to decoder.cc correctly Edits to the CPU model may still need to be made to handle branch likely insts... arch/isa_parser.py: add a NNPC operand ... arch/mips/isa/base.isa: change SPARC to MIPS arch/mips/isa/decoder.isa: typo < to >= arch/mips/isa/formats/basic.isa: spacing arch/mips/isa/formats/branch.isa: add code for branch instructions (still need adjustments for the branch likely) arch/mips/isa/operands.isa: support for NNPC and R31 arch/mips/isa_traits.hh: NNPC Addr variable --HG-- extra : convert_revision : df03d2a71c36dbc00270c2e3d7882b4f09ed97ad --- arch/isa_parser.py | 10 ++++++++++ arch/mips/isa/base.isa | 2 +- arch/mips/isa/decoder.isa | 2 +- arch/mips/isa/formats/basic.isa | 2 +- arch/mips/isa/formats/branch.isa | 24 ++++++++++++++++-------- arch/mips/isa/operands.isa | 7 ++++--- arch/mips/isa_traits.hh | 2 ++ 7 files changed, 35 insertions(+), 14 deletions(-) diff --git a/arch/isa_parser.py b/arch/isa_parser.py index 96d3e8438..606432e60 100755 --- a/arch/isa_parser.py +++ b/arch/isa_parser.py @@ -1355,6 +1355,7 @@ class MemOperand(Operand): def makeAccSize(self): return self.size + class NPCOperand(Operand): def makeConstructor(self): return '' @@ -1365,6 +1366,15 @@ class NPCOperand(Operand): def makeWrite(self): return 'xc->setNextPC(%s);\n' % self.base_name +class NNPCOperand(Operand): + def makeConstructor(self): + return '' + + def makeRead(self): + return '%s = xc->readPC() + 8;\n' % self.base_name + + def makeWrite(self): + return 'xc->setNextNPC(%s);\n' % self.base_name def buildOperandNameMap(userDict, lineno): global operandNameMap diff --git a/arch/mips/isa/base.isa b/arch/mips/isa/base.isa index 99fa302c0..db37cf49c 100644 --- a/arch/mips/isa/base.isa +++ b/arch/mips/isa/base.isa @@ -16,7 +16,7 @@ output header {{ // Constructor. MipsStaticInst(const char *mnem, MachInst _machInst, OpClass __opClass) - : StaticInst(mnem, _machInst, __opClass) + : StaticInst(mnem, _machInst, __opClass) { } diff --git a/arch/mips/isa/decoder.isa b/arch/mips/isa/decoder.isa index 997badb25..f46024f15 100644 --- a/arch/mips/isa/decoder.isa +++ b/arch/mips/isa/decoder.isa @@ -168,7 +168,7 @@ decode OPCODE_HI default Unknown::unknown() { 0x1: decode REGIMM_LO { format Trap { 0x0: tgei( {{ cond = (Rs.sw >= INTIMM); }}); - 0x1: tgeiu({{ cond = (Rs.uw < INTIMM); }}); + 0x1: tgeiu({{ cond = (Rs.uw >= INTIMM); }}); 0x2: tlti( {{ cond = (Rs.sw < INTIMM); }}); 0x3: tltiu({{ cond = (Rs.uw < INTIMM); }}); 0x4: teqi( {{ cond = (Rs.sw == INTIMM);}}); diff --git a/arch/mips/isa/formats/basic.isa b/arch/mips/isa/formats/basic.isa index 24c397685..3b62aa5c3 100644 --- a/arch/mips/isa/formats/basic.isa +++ b/arch/mips/isa/formats/basic.isa @@ -40,7 +40,7 @@ def template BasicExecute {{ if(fault == No_Fault) { - %(op_wb)s; + %(op_wb)s; } return fault; } diff --git a/arch/mips/isa/formats/branch.isa b/arch/mips/isa/formats/branch.isa index d9dd433e3..1f7a6f330 100644 --- a/arch/mips/isa/formats/branch.isa +++ b/arch/mips/isa/formats/branch.isa @@ -45,12 +45,12 @@ output header {{ { protected: /// target address (signed) Displacement . - int32_t targetOffset; + int32_t disp; /// Constructor. Branch(const char *mnem, MachInst _machInst, OpClass __opClass) : PCDependentDisassembly(mnem, _machInst, __opClass), - targetOffset(OFFSET << 2) + disp(OFFSET << 2) { } @@ -67,12 +67,12 @@ output header {{ { protected: /// target address (signed) Displacement . - int32_t targetOffset; + int32_t disp; /// Constructor. Branch(const char *mnem, MachInst _machInst, OpClass __opClass) : PCDependentDisassembly(mnem, _machInst, __opClass), - targetOffset(OFFSET << 2) + disp(OFFSET << 2) { } @@ -255,9 +255,12 @@ def format Branch(code,*flags) {{ #Add Link Code if Link instruction strlen = len(name) if name[strlen-2:] == 'al': - code += 'R31 = NPC + 8;\n' + code += 'R31 = NPC + 4;\n' - code += '\nif (cond) NPC = NPC + disp;\n'; + # condition code + code += 'if (cond) {' + code += ' NPC = NPC + disp;\n' + code += ' NNPC = NNPC + disp;\n } \n' iop = InstObjParams(name, Name, 'Branch', CodeBlock(code), ('IsDirectControl', 'IsCondControl')) @@ -267,15 +270,20 @@ def format Branch(code,*flags) {{ exec_output = BasicExecute.subst(iop) }}; + def format BranchLikely(code,*flags) {{ code = 'bool cond;\n\t\t\t' + code #Add Link Code if Link instruction strlen = len(name) if name[strlen-3:] == 'all': - code += 'R31 = NPC + 8;\n' + code += 'R31 = NPC + 4;\n' + + #condition code + code += 'if (cond) {' + code += ' NPC = NPC + disp;\n' + code += ' NNPC = NNPC + disp;\n } \n' - code = '\t\t\tif (cond) NPC = NPC + disp;\n'; iop = InstObjParams(name, Name, 'Branch', CodeBlock(code), ('IsDirectControl', 'IsCondControl','IsCondDelaySlot')) diff --git a/arch/mips/isa/operands.isa b/arch/mips/isa/operands.isa index 19d21ac8d..77035f04c 100644 --- a/arch/mips/isa/operands.isa +++ b/arch/mips/isa/operands.isa @@ -16,6 +16,7 @@ def operands {{ 'Rd': ('IntReg', 'uw', 'RD', 'IsInteger', 1), 'Rs': ('IntReg', 'uw', 'RS', 'IsInteger', 2), 'Rt': ('IntReg', 'uw', 'RT', 'IsInteger', 3), + 'R31': ('IntReg', 'uw','R31','IsInteger', 4), 'IntImm': ('IntReg', 'uw', 'INTIMM', 'IsInteger', 3), 'Sa': ('IntReg', 'uw', 'SA', 'IsInteger', 4), @@ -24,12 +25,12 @@ def operands {{ 'Fs': ('FloatReg', 'sf', 'FS', 'IsFloating', 2), 'Ft': ('FloatReg', 'sf', 'FT', 'IsFloating', 3), - 'Mem': ('Mem', 'ud', None, ('IsMemRef', 'IsLoad', 'IsStore'), 4) + 'Mem': ('Mem', 'ud', None, ('IsMemRef', 'IsLoad', 'IsStore'), 4), - #'NPC': ('NPC', 'uw', None, ( None, None, 'IsControl' ), 4), + 'NPC': ('NPC', 'uw', None, ( None, None, 'IsControl' ), 4), + 'NNPC': ('NNPC', 'uw', None, ( None, None, 'IsControl' ), 4) #'Runiq': ('ControlReg', 'uq', 'Uniq', None, 1), #'FPCR': ('ControlReg', 'uq', 'Fpcr', None, 1), # The next two are hacks for non-full-system call-pal emulation #'R0': ('IntReg', 'uq', '0', None, 1), - #'R31': ('IntReg', 'uw', '31', None, 1) }}; diff --git a/arch/mips/isa_traits.hh b/arch/mips/isa_traits.hh index 55e9c0dcb..e171737a3 100644 --- a/arch/mips/isa_traits.hh +++ b/arch/mips/isa_traits.hh @@ -430,6 +430,8 @@ class MipsISA Addr pc; // Program Counter Addr npc; // Next Program Counter + Addr nnpc; // Next next program Counter + void serialize(std::ostream &os); void unserialize(Checkpoint *cp, const std::string §ion); From 53d2c9398e8c1631ae3fd5469b187b006d317f88 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Sat, 18 Feb 2006 23:44:22 -0500 Subject: [PATCH 069/180] Move Linux/Tru64 architecture independent code into kern/* leaving dependent code making way for solaris linux syscall emu. SConscript: Add two new files for syscall emulation Add getDesc() function arch/alpha/alpha_linux_process.cc: arch/alpha/alpha_tru64_process.cc: move architecture independent code into kern/linux/linux.(hh|cc) arch/alpha/alpha_linux_process.hh: arch/alpha/alpha_tru64_process.hh: Add getDesc function kern/linux/linux.hh: move generi linux syscall emulation code into kern/linux kern/tru64/tru64.hh: move generi tru64 syscall emulation code into kern/tru64 sim/process.cc: sim/process.hh: Push the function determination and calling stuff down to LiveProcess and out of the Linux/Tru64 classes respectively sim/syscall_emul.cc: sim/syscall_emul.hh: fnctl implementation was identical in tru64 and linux so moved to generic --HG-- extra : convert_revision : 103293dbe6fe2f7892de4929d17dc085def77026 --- SConscript | 2 + arch/alpha/alpha_linux_process.cc | 576 ++-------- arch/alpha/alpha_linux_process.hh | 11 +- arch/alpha/alpha_tru64_process.cc | 1657 +++-------------------------- arch/alpha/alpha_tru64_process.hh | 12 +- kern/linux/linux.hh | 307 ++++++ kern/tru64/tru64.hh | 1291 +++++++++++++++++++++- sim/process.cc | 15 + sim/process.hh | 6 + sim/syscall_emul.cc | 46 + sim/syscall_emul.hh | 4 + 11 files changed, 1898 insertions(+), 2029 deletions(-) diff --git a/SConscript b/SConscript index fc2e6ae0b..1daf68ead 100644 --- a/SConscript +++ b/SConscript @@ -330,6 +330,8 @@ syscall_emulation_sources = Split(''' encumbered/eio/eio.cc encumbered/eio/exolex.cc encumbered/eio/libexo.cc + kern/linux/linux.cc + kern/tru64/tru64.cc sim/process.cc sim/syscall_emul.cc ''') diff --git a/arch/alpha/alpha_linux_process.cc b/arch/alpha/alpha_linux_process.cc index fb5e32e63..6d50756f2 100644 --- a/arch/alpha/alpha_linux_process.cc +++ b/arch/alpha/alpha_linux_process.cc @@ -26,506 +26,96 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include -#include -#include // for host open() flags -#include // for memset() -#include -#include -#include - -#include "cpu/base.hh" -#include "cpu/exec_context.hh" -#include "mem/functional/functional.hh" -#include "sim/fake_syscall.hh" -#include "sim/host.hh" -#include "sim/process.hh" -#include "sim/sim_events.hh" - -#include "arch/alpha/isa_traits.hh" #include "arch/alpha/alpha_common_syscall_emul.hh" -#include "sim/syscall_emul.hh" -#include "sim/root.hh" // for curTick & ticksPerSecond - #include "arch/alpha/alpha_linux_process.hh" +#include "arch/alpha/isa_traits.hh" #include "base/trace.hh" +#include "cpu/exec_context.hh" +#include "kern/linux/linux.hh" +#include "mem/functional/functional.hh" + +#include "sim/process.hh" +#include "sim/syscall_emul.hh" using namespace std; -/// -/// This class encapsulates the types, structures, constants, -/// functions, and syscall-number mappings specific to the Alpha Linux -/// syscall interface. -/// -class Linux { +/// Target uname() handler. +static SyscallReturn +unameFunc(SyscallDesc *desc, int callnum, Process *process, + ExecContext *xc) +{ + TypedBufferArg name(xc->getSyscallArg(0)); - public: + strcpy(name->sysname, "Linux"); + strcpy(name->nodename, "m5.eecs.umich.edu"); + strcpy(name->release, "2.4.20"); + strcpy(name->version, "#1 Mon Aug 18 11:32:15 EDT 2003"); + strcpy(name->machine, "alpha"); - //@{ - /// Basic Linux types. - typedef uint64_t size_t; - typedef uint64_t off_t; - typedef int64_t time_t; - typedef uint32_t uid_t; - typedef uint32_t gid_t; - //@} + name.copyOut(xc->mem); + return 0; +} -#if BSD_HOST - typedef struct stat hst_stat; - typedef struct stat hst_stat64; -#else - typedef struct stat hst_stat ; - typedef struct stat64 hst_stat64; -#endif +/// Target osf_getsysyinfo() handler. Even though this call is +/// borrowed from Tru64, the subcases that get used appear to be +/// different in practice from those used by Tru64 processes. +static SyscallReturn +osf_getsysinfoFunc(SyscallDesc *desc, int callnum, Process *process, + ExecContext *xc) +{ + unsigned op = xc->getSyscallArg(0); + // unsigned nbytes = xc->getSyscallArg(2); + switch (op) { - //@{ - /// open(2) flag values. - static const int TGT_O_RDONLY = 00000000; //!< O_RDONLY - static const int TGT_O_WRONLY = 00000001; //!< O_WRONLY - static const int TGT_O_RDWR = 00000002; //!< O_RDWR - static const int TGT_O_NONBLOCK = 00000004; //!< O_NONBLOCK - static const int TGT_O_APPEND = 00000010; //!< O_APPEND - static const int TGT_O_CREAT = 00001000; //!< O_CREAT - static const int TGT_O_TRUNC = 00002000; //!< O_TRUNC - static const int TGT_O_EXCL = 00004000; //!< O_EXCL - static const int TGT_O_NOCTTY = 00010000; //!< O_NOCTTY - static const int TGT_O_SYNC = 00040000; //!< O_SYNC - static const int TGT_O_DRD = 00100000; //!< O_DRD - static const int TGT_O_DIRECTIO = 00200000; //!< O_DIRECTIO - static const int TGT_O_CACHE = 00400000; //!< O_CACHE - static const int TGT_O_DSYNC = 02000000; //!< O_DSYNC - static const int TGT_O_RSYNC = 04000000; //!< O_RSYNC - //@} + case 45: { // GSI_IEEE_FP_CONTROL + TypedBufferArg fpcr(xc->getSyscallArg(1)); + // I don't think this exactly matches the HW FPCR + *fpcr = 0; + fpcr.copyOut(xc->mem); + return 0; + } - /// This table maps the target open() flags to the corresponding - /// host open() flags. - static OpenFlagTransTable openFlagTable[]; - - /// Number of entries in openFlagTable[]. - static const int NUM_OPEN_FLAGS; - - /// Stat buffer. Note that we can't call it 'stat' since that - /// gets #defined to something else on some systems. - struct tgt_stat { - uint32_t st_dev; //!< device - uint32_t st_ino; //!< inode - uint32_t st_mode; //!< mode - uint32_t st_nlink; //!< link count - uint32_t st_uid; //!< owner's user ID - uint32_t st_gid; //!< owner's group ID - uint32_t st_rdev; //!< device number - int32_t _pad1; //!< for alignment - int64_t st_size; //!< file size in bytes - uint64_t st_atimeX; //!< time of last access - uint64_t st_mtimeX; //!< time of last modification - uint64_t st_ctimeX; //!< time of last status change - uint32_t st_blksize; //!< optimal I/O block size - int32_t st_blocks; //!< number of blocks allocated - uint32_t st_flags; //!< flags - uint32_t st_gen; //!< unknown - }; - - // same for stat64 - struct tgt_stat64 { - uint64_t st_dev; - uint64_t st_ino; - uint64_t st_rdev; - int64_t st_size; - uint64_t st_blocks; - - uint32_t st_mode; - uint32_t st_uid; - uint32_t st_gid; - uint32_t st_blksize; - uint32_t st_nlink; - uint32_t __pad0; - - uint64_t tgt_st_atime; - uint64_t st_atime_nsec; - uint64_t tgt_st_mtime; - uint64_t st_mtime_nsec; - uint64_t tgt_st_ctime; - uint64_t st_ctime_nsec; - int64_t ___unused[3]; - }; - - /// Length of strings in struct utsname (plus 1 for null char). - static const int _SYS_NMLN = 65; - - /// Interface struct for uname(). - struct utsname { - char sysname[_SYS_NMLN]; //!< System name. - char nodename[_SYS_NMLN]; //!< Node name. - char release[_SYS_NMLN]; //!< OS release. - char version[_SYS_NMLN]; //!< OS version. - char machine[_SYS_NMLN]; //!< Machine type. - }; - - - //@{ - /// ioctl() command codes. - static const unsigned TIOCGETP = 0x40067408; - static const unsigned TIOCSETP = 0x80067409; - static const unsigned TIOCSETN = 0x8006740a; - static const unsigned TIOCSETC = 0x80067411; - static const unsigned TIOCGETC = 0x40067412; - static const unsigned FIONREAD = 0x4004667f; - static const unsigned TIOCISATTY = 0x2000745e; - static const unsigned TIOCGETS = 0x402c7413; - static const unsigned TIOCGETA = 0x40127417; - //@} - - /// Resource enumeration for getrlimit(). - enum rlimit_resources { - TGT_RLIMIT_CPU = 0, - TGT_RLIMIT_FSIZE = 1, - TGT_RLIMIT_DATA = 2, - TGT_RLIMIT_STACK = 3, - TGT_RLIMIT_CORE = 4, - TGT_RLIMIT_RSS = 5, - TGT_RLIMIT_NOFILE = 6, - TGT_RLIMIT_AS = 7, - TGT_RLIMIT_VMEM = 7, - TGT_RLIMIT_NPROC = 8, - TGT_RLIMIT_MEMLOCK = 9, - TGT_RLIMIT_LOCKS = 10 - }; - - /// Limit struct for getrlimit/setrlimit. - struct rlimit { - uint64_t rlim_cur; //!< soft limit - uint64_t rlim_max; //!< hard limit - }; - - - /// For mmap(). - static const unsigned TGT_MAP_ANONYMOUS = 0x10; - - /// For gettimeofday(). - struct timeval { - int64_t tv_sec; //!< seconds - int64_t tv_usec; //!< microseconds - }; - - // For writev/readv - struct tgt_iovec { - uint64_t iov_base; // void * - uint64_t iov_len; - }; - - //@{ - /// For getrusage(). - static const int TGT_RUSAGE_SELF = 0; - static const int TGT_RUSAGE_CHILDREN = -1; - static const int TGT_RUSAGE_BOTH = -2; - //@} - - /// For getrusage(). - struct rusage { - struct timeval ru_utime; //!< user time used - struct timeval ru_stime; //!< system time used - int64_t ru_maxrss; //!< max rss - int64_t ru_ixrss; //!< integral shared memory size - int64_t ru_idrss; //!< integral unshared data " - int64_t ru_isrss; //!< integral unshared stack " - int64_t ru_minflt; //!< page reclaims - total vmfaults - int64_t ru_majflt; //!< page faults - int64_t ru_nswap; //!< swaps - int64_t ru_inblock; //!< block input operations - int64_t ru_oublock; //!< block output operations - int64_t ru_msgsnd; //!< messages sent - int64_t ru_msgrcv; //!< messages received - int64_t ru_nsignals; //!< signals received - int64_t ru_nvcsw; //!< voluntary context switches - int64_t ru_nivcsw; //!< involuntary " - }; - - /// Helper function to convert a host stat buffer to a target stat - /// buffer. Also copies the target buffer out to the simulated - /// memory space. Used by stat(), fstat(), and lstat(). -#if !BSD_HOST - static void - copyOutStatBuf(FunctionalMemory *mem, Addr addr, hst_stat *host) - { - TypedBufferArg tgt(addr); - - tgt->st_dev = htog(host->st_dev); - tgt->st_ino = htog(host->st_ino); - tgt->st_mode = htog(host->st_mode); - tgt->st_nlink = htog(host->st_nlink); - tgt->st_uid = htog(host->st_uid); - tgt->st_gid = htog(host->st_gid); - tgt->st_rdev = htog(host->st_rdev); - tgt->st_size = htog(host->st_size); - tgt->st_atimeX = htog(host->st_atime); - tgt->st_mtimeX = htog(host->st_mtime); - tgt->st_ctimeX = htog(host->st_ctime); - tgt->st_blksize = htog(host->st_blksize); - tgt->st_blocks = htog(host->st_blocks); - - tgt.copyOut(mem); - } -#else - // Third version for bsd systems which no longer have any support for - // the old stat() call and stat() is actually a stat64() - static void - copyOutStatBuf(FunctionalMemory *mem, Addr addr, hst_stat64 *host) - { - TypedBufferArg tgt(addr); - - tgt->st_dev = htog(host->st_dev); - tgt->st_ino = htog(host->st_ino); - tgt->st_mode = htog(host->st_mode); - tgt->st_nlink = htog(host->st_nlink); - tgt->st_uid = htog(host->st_uid); - tgt->st_gid = htog(host->st_gid); - tgt->st_rdev = htog(host->st_rdev); - tgt->st_size = htog(host->st_size); - tgt->st_atimeX = htog(host->st_atime); - tgt->st_mtimeX = htog(host->st_mtime); - tgt->st_ctimeX = htog(host->st_ctime); - tgt->st_blksize = htog(host->st_blksize); - tgt->st_blocks = htog(host->st_blocks); - - tgt.copyOut(mem); - } -#endif - - - // Same for stat64 - static void - copyOutStat64Buf(FunctionalMemory *mem, int fd, Addr addr, hst_stat64 *host) - { - TypedBufferArg tgt(addr); - - // fd == 1 checks are because libc does some checks - // that the stdout is interactive vs. a file - // this makes it work on non-linux systems - if (fd == 1) - tgt->st_dev = htog((uint64_t)0xA); - else - tgt->st_dev = htog((uint64_t)host->st_dev); - // XXX What about STAT64_HAS_BROKEN_ST_INO ??? - tgt->st_ino = htog((uint64_t)host->st_ino); - if (fd == 1) - tgt->st_rdev = htog((uint64_t)0x880d); - else - tgt->st_rdev = htog((uint64_t)host->st_rdev); - tgt->st_size = htog((int64_t)host->st_size); - tgt->st_blocks = htog((uint64_t)host->st_blocks); - - if (fd == 1) - tgt->st_mode = htog((uint32_t)0x2190); - else - tgt->st_mode = htog((uint32_t)host->st_mode); - tgt->st_uid = htog((uint32_t)host->st_uid); - tgt->st_gid = htog((uint32_t)host->st_gid); - tgt->st_blksize = htog((uint32_t)host->st_blksize); - tgt->st_nlink = htog((uint32_t)host->st_nlink); - tgt->tgt_st_atime = htog((uint64_t)host->st_atime); - tgt->tgt_st_mtime = htog((uint64_t)host->st_mtime); - tgt->tgt_st_ctime = htog((uint64_t)host->st_ctime); -#if defined(STAT_HAVE_NSEC) - tgt->st_atime_nsec = htog(host->st_atime_nsec); - tgt->st_mtime_nsec = htog(host->st_mtime_nsec); - tgt->st_ctime_nsec = htog(host->st_ctime_nsec); -#else - tgt->st_atime_nsec = 0; - tgt->st_mtime_nsec = 0; - tgt->st_ctime_nsec = 0; -#endif - - tgt.copyOut(mem); + default: + cerr << "osf_getsysinfo: unknown op " << op << endl; + abort(); + break; } - /// The target system's hostname. - static const char *hostname; + return 1; +} - /// Target uname() handler. - static SyscallReturn - unameFunc(SyscallDesc *desc, int callnum, Process *process, - ExecContext *xc) - { - TypedBufferArg name(xc->getSyscallArg(0)); +/// Target osf_setsysinfo() handler. +static SyscallReturn +osf_setsysinfoFunc(SyscallDesc *desc, int callnum, Process *process, + ExecContext *xc) +{ + unsigned op = xc->getSyscallArg(0); + // unsigned nbytes = xc->getSyscallArg(2); - strcpy(name->sysname, "Linux"); - strcpy(name->nodename, hostname); - strcpy(name->release, "2.4.20"); - strcpy(name->version, "#1 Mon Aug 18 11:32:15 EDT 2003"); - strcpy(name->machine, "alpha"); + switch (op) { - name.copyOut(xc->mem); - return 0; + case 14: { // SSI_IEEE_FP_CONTROL + TypedBufferArg fpcr(xc->getSyscallArg(1)); + // I don't think this exactly matches the HW FPCR + fpcr.copyIn(xc->mem); + DPRINTFR(SyscallVerbose, "osf_setsysinfo(SSI_IEEE_FP_CONTROL): " + " setting FPCR to 0x%x\n", gtoh(*(uint64_t*)fpcr)); + return 0; + } + + default: + cerr << "osf_setsysinfo: unknown op " << op << endl; + abort(); + break; } - /// Target osf_getsysyinfo() handler. Even though this call is - /// borrowed from Tru64, the subcases that get used appear to be - /// different in practice from those used by Tru64 processes. - static SyscallReturn - osf_getsysinfoFunc(SyscallDesc *desc, int callnum, Process *process, - ExecContext *xc) - { - unsigned op = xc->getSyscallArg(0); - // unsigned nbytes = xc->getSyscallArg(2); - - switch (op) { - - case 45: { // GSI_IEEE_FP_CONTROL - TypedBufferArg fpcr(xc->getSyscallArg(1)); - // I don't think this exactly matches the HW FPCR - *fpcr = 0; - fpcr.copyOut(xc->mem); - return 0; - } - - default: - cerr << "osf_getsysinfo: unknown op " << op << endl; - abort(); - break; - } - - return 1; - } - - /// Target osf_setsysinfo() handler. - static SyscallReturn - osf_setsysinfoFunc(SyscallDesc *desc, int callnum, Process *process, - ExecContext *xc) - { - unsigned op = xc->getSyscallArg(0); - // unsigned nbytes = xc->getSyscallArg(2); - - switch (op) { - - case 14: { // SSI_IEEE_FP_CONTROL - TypedBufferArg fpcr(xc->getSyscallArg(1)); - // I don't think this exactly matches the HW FPCR - fpcr.copyIn(xc->mem); - DPRINTFR(SyscallVerbose, "osf_setsysinfo(SSI_IEEE_FP_CONTROL): " - " setting FPCR to 0x%x\n", gtoh(*(uint64_t*)fpcr)); - return 0; - } - - default: - cerr << "osf_setsysinfo: unknown op " << op << endl; - abort(); - break; - } - - return 1; - } - - /// Target fnctl() handler. - static SyscallReturn - fcntlFunc(SyscallDesc *desc, int callnum, Process *process, - ExecContext *xc) - { - int fd = xc->getSyscallArg(0); - - if (fd < 0 || process->sim_fd(fd) < 0) - return -EBADF; - - int cmd = xc->getSyscallArg(1); - switch (cmd) { - case 0: // F_DUPFD - // if we really wanted to support this, we'd need to do it - // in the target fd space. - warn("fcntl(%d, F_DUPFD) not supported, error returned\n", fd); - return -EMFILE; - - case 1: // F_GETFD (get close-on-exec flag) - case 2: // F_SETFD (set close-on-exec flag) - return 0; - - case 3: // F_GETFL (get file flags) - case 4: // F_SETFL (set file flags) - // not sure if this is totally valid, but we'll pass it through - // to the underlying OS - warn("fcntl(%d, %d) passed through to host\n", fd, cmd); - return fcntl(process->sim_fd(fd), cmd); - // return 0; - - case 7: // F_GETLK (get lock) - case 8: // F_SETLK (set lock) - case 9: // F_SETLKW (set lock and wait) - // don't mess with file locking... just act like it's OK - warn("File lock call (fcntl(%d, %d)) ignored.\n", fd, cmd); - return 0; - - default: - warn("Unknown fcntl command %d\n", cmd); - return 0; - } - } - - /// Array of syscall descriptors, indexed by call number. - static SyscallDesc syscallDescs[]; - - /// Number of syscalls in syscallDescs[]. - static const int Num_Syscall_Descs; - - /// Max supported syscall number. - static const int Max_Syscall_Desc; - - /// Do the specified syscall. Just looks the call number up in - /// the table and invokes the appropriate handler. - static void - doSyscall(int callnum, Process *process, ExecContext *xc) - { - if (callnum < 0 || callnum > Max_Syscall_Desc) { - fatal("Syscall %d out of range", callnum); - } - - SyscallDesc *desc = &syscallDescs[callnum]; - - desc->doSyscall(callnum, process, xc); - } -}; // class Linux + return 1; +} -// open(2) flags translation table -OpenFlagTransTable Linux::openFlagTable[] = { -#ifdef _MSC_VER - { Linux::TGT_O_RDONLY, _O_RDONLY }, - { Linux::TGT_O_WRONLY, _O_WRONLY }, - { Linux::TGT_O_RDWR, _O_RDWR }, - { Linux::TGT_O_APPEND, _O_APPEND }, - { Linux::TGT_O_CREAT, _O_CREAT }, - { Linux::TGT_O_TRUNC, _O_TRUNC }, - { Linux::TGT_O_EXCL, _O_EXCL }, -#ifdef _O_NONBLOCK - { Linux::TGT_O_NONBLOCK, _O_NONBLOCK }, -#endif -#ifdef _O_NOCTTY - { Linux::TGT_O_NOCTTY, _O_NOCTTY }, -#endif -#ifdef _O_SYNC - { Linux::TGT_O_SYNC, _O_SYNC }, -#endif -#else /* !_MSC_VER */ - { Linux::TGT_O_RDONLY, O_RDONLY }, - { Linux::TGT_O_WRONLY, O_WRONLY }, - { Linux::TGT_O_RDWR, O_RDWR }, - { Linux::TGT_O_APPEND, O_APPEND }, - { Linux::TGT_O_CREAT, O_CREAT }, - { Linux::TGT_O_TRUNC, O_TRUNC }, - { Linux::TGT_O_EXCL, O_EXCL }, - { Linux::TGT_O_NONBLOCK, O_NONBLOCK }, - { Linux::TGT_O_NOCTTY, O_NOCTTY }, -#ifdef O_SYNC - { Linux::TGT_O_SYNC, O_SYNC }, -#endif -#endif /* _MSC_VER */ -}; - -const int Linux::NUM_OPEN_FLAGS = - (sizeof(Linux::openFlagTable)/sizeof(Linux::openFlagTable[0])); - -const char *Linux::hostname = "m5.eecs.umich.edu"; - -SyscallDesc Linux::syscallDescs[] = { +SyscallDesc AlphaLinuxProcess::syscallDescs[] = { /* 0 */ SyscallDesc("osf_syscall", unimplementedFunc), /* 1 */ SyscallDesc("exit", exitFunc), /* 2 */ SyscallDesc("fork", unimplementedFunc), @@ -973,23 +563,6 @@ SyscallDesc Linux::syscallDescs[] = { /* 441 */ SyscallDesc("keyctl", unimplementedFunc) }; -const int Linux::Num_Syscall_Descs = - sizeof(Linux::syscallDescs) / sizeof(SyscallDesc); - -const int Linux::Max_Syscall_Desc = Linux::Num_Syscall_Descs - 1; - - -void -AlphaLinuxProcess::syscall(ExecContext *xc) -{ - num_syscalls++; - - int64_t callnum = xc->regs.intRegFile[ReturnValueReg]; - - Linux::doSyscall(callnum, this, xc); -} - - AlphaLinuxProcess::AlphaLinuxProcess(const std::string &name, ObjectFile *objFile, int stdin_fd, @@ -997,7 +570,18 @@ AlphaLinuxProcess::AlphaLinuxProcess(const std::string &name, int stderr_fd, std::vector &argv, std::vector &envp) - : LiveProcess(name, objFile, stdin_fd, stdout_fd, stderr_fd, argv, envp) + : LiveProcess(name, objFile, stdin_fd, stdout_fd, stderr_fd, argv, envp), + Num_Syscall_Descs(sizeof(syscallDescs) / sizeof(SyscallDesc)) { init_regs->intRegFile[0] = 0; } + + + +SyscallDesc* +AlphaLinuxProcess::getDesc(int callnum) +{ + if (callnum < 0 || callnum > Num_Syscall_Descs) + return NULL; + return &syscallDescs[callnum]; +} diff --git a/arch/alpha/alpha_linux_process.hh b/arch/alpha/alpha_linux_process.hh index b4fe8e8f8..7de1b1ac1 100644 --- a/arch/alpha/alpha_linux_process.hh +++ b/arch/alpha/alpha_linux_process.hh @@ -43,8 +43,15 @@ class AlphaLinuxProcess : public LiveProcess std::vector &argv, std::vector &envp); - /// Syscall emulation function. - virtual void syscall(ExecContext *xc); + virtual SyscallDesc* getDesc(int callnum); + + /// The target system's hostname. + static const char *hostname; + + /// Array of syscall descriptors, indexed by call number. + static SyscallDesc syscallDescs[]; + + const int Num_Syscall_Descs; }; diff --git a/arch/alpha/alpha_tru64_process.cc b/arch/alpha/alpha_tru64_process.cc index 5c24adad9..90f01637d 100644 --- a/arch/alpha/alpha_tru64_process.cc +++ b/arch/alpha/alpha_tru64_process.cc @@ -26,1532 +26,138 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include -#include -#if defined(__OpenBSD__) || defined(__APPLE__) || defined(__FreeBSD__) -#include -#include -#else -#include -#endif - -#include -#include -#include // for host open() flags -#include // for memset() -#include - #include "arch/alpha/isa_traits.hh" #include "arch/alpha/alpha_common_syscall_emul.hh" #include "arch/alpha/alpha_tru64_process.hh" -#include "base/trace.hh" -#include "cpu/base.hh" #include "cpu/exec_context.hh" +#include "kern/tru64/tru64.hh" #include "mem/functional/functional.hh" #include "sim/fake_syscall.hh" -#include "sim/host.hh" #include "sim/process.hh" -#include "sim/root.hh" #include "sim/syscall_emul.hh" using namespace std; -typedef struct stat global_stat; -typedef struct statfs global_statfs; -typedef struct dirent global_dirent; +/// Target uname() handler. +static SyscallReturn +unameFunc(SyscallDesc *desc, int callnum, Process *process, + ExecContext *xc) +{ + TypedBufferArg name(xc->getSyscallArg(0)); -/// -/// This class encapsulates the types, structures, constants, -/// functions, and syscall-number mappings specific to the Alpha Tru64 -/// syscall interface. -/// -class Tru64 { + strcpy(name->sysname, "OSF1"); + strcpy(name->nodename, "m5.eecs.umich.edu"); + strcpy(name->release, "V5.1"); + strcpy(name->version, "732"); + strcpy(name->machine, "alpha"); - public: + name.copyOut(xc->mem); + return 0; +} - //@{ - /// Basic Tru64 types. - typedef uint64_t size_t; - typedef uint64_t off_t; - typedef uint16_t nlink_t; - typedef int32_t dev_t; - typedef uint32_t uid_t; - typedef uint32_t gid_t; - typedef uint32_t time_t; - typedef uint32_t mode_t; - typedef uint32_t ino_t; - typedef struct { int val[2]; } quad; - typedef quad fsid_t; - //@} +/// Target getsysyinfo() handler. +static SyscallReturn +getsysinfoFunc(SyscallDesc *desc, int callnum, Process *process, + ExecContext *xc) +{ + unsigned op = xc->getSyscallArg(0); + unsigned nbytes = xc->getSyscallArg(2); - //@{ - /// open(2) flag values. - static const int TGT_O_RDONLY = 00000000; - static const int TGT_O_WRONLY = 00000001; - static const int TGT_O_RDWR = 00000002; - static const int TGT_O_NONBLOCK = 00000004; - static const int TGT_O_APPEND = 00000010; - static const int TGT_O_CREAT = 00001000; - static const int TGT_O_TRUNC = 00002000; - static const int TGT_O_EXCL = 00004000; - static const int TGT_O_NOCTTY = 00010000; - static const int TGT_O_SYNC = 00040000; - static const int TGT_O_DRD = 00100000; - static const int TGT_O_DIRECTIO = 00200000; - static const int TGT_O_CACHE = 00400000; - static const int TGT_O_DSYNC = 02000000; - static const int TGT_O_RSYNC = 04000000; - //@} + switch (op) { - /// This table maps the target open() flags to the corresponding - /// host open() flags. - static OpenFlagTransTable openFlagTable[]; + case Tru64::GSI_MAX_CPU: { + TypedBufferArg max_cpu(xc->getSyscallArg(1)); + *max_cpu = htog((uint32_t)process->numCpus()); + max_cpu.copyOut(xc->mem); + return 1; + } - /// Number of entries in openFlagTable[]. - static const int NUM_OPEN_FLAGS; + case Tru64::GSI_CPUS_IN_BOX: { + TypedBufferArg cpus_in_box(xc->getSyscallArg(1)); + *cpus_in_box = htog((uint32_t)process->numCpus()); + cpus_in_box.copyOut(xc->mem); + return 1; + } - /// Stat buffer. Note that Tru64 v5.0+ use a new "F64" stat - /// structure, and a new set of syscall numbers for stat calls. - /// On some hosts (notably Linux) define st_atime, st_mtime, and - /// st_ctime as macros, so we append an X to get around this. - struct F64_stat { - dev_t st_dev; //!< st_dev - int32_t st_retired1; //!< st_retired1 - mode_t st_mode; //!< st_mode - nlink_t st_nlink; //!< st_nlink - uint16_t st_nlink_reserved; //!< st_nlink_reserved - uid_t st_uid; //!< st_uid - gid_t st_gid; //!< st_gid - dev_t st_rdev; //!< st_rdev - dev_t st_ldev; //!< st_ldev - off_t st_size; //!< st_size - time_t st_retired2; //!< st_retired2 - int32_t st_uatime; //!< st_uatime - time_t st_retired3; //!< st_retired3 - int32_t st_umtime; //!< st_umtime - time_t st_retired4; //!< st_retired4 - int32_t st_uctime; //!< st_uctime - int32_t st_retired5; //!< st_retired5 - int32_t st_retired6; //!< st_retired6 - uint32_t st_flags; //!< st_flags - uint32_t st_gen; //!< st_gen - uint64_t st_spare[4]; //!< st_spare[4] - ino_t st_ino; //!< st_ino - int32_t st_ino_reserved; //!< st_ino_reserved - time_t st_atimeX; //!< st_atime - int32_t st_atime_reserved; //!< st_atime_reserved - time_t st_mtimeX; //!< st_mtime - int32_t st_mtime_reserved; //!< st_mtime_reserved - time_t st_ctimeX; //!< st_ctime - int32_t st_ctime_reserved; //!< st_ctime_reserved - uint64_t st_blksize; //!< st_blksize - uint64_t st_blocks; //!< st_blocks - }; + case Tru64::GSI_PHYSMEM: { + TypedBufferArg physmem(xc->getSyscallArg(1)); + *physmem = htog((uint64_t)1024 * 1024); // physical memory in KB + physmem.copyOut(xc->mem); + return 1; + } + case Tru64::GSI_CPU_INFO: { + TypedBufferArg infop(xc->getSyscallArg(1)); - /// Old Tru64 v4.x stat struct. - /// Tru64 maintains backwards compatibility with v4.x by - /// implementing another set of stat functions using the old - /// structure definition and binding them to the old syscall - /// numbers. - struct pre_F64_stat { - dev_t st_dev; - ino_t st_ino; - mode_t st_mode; - nlink_t st_nlink; - uid_t st_uid; - gid_t st_gid; - dev_t st_rdev; - off_t st_size; - time_t st_atimeX; - int32_t st_uatime; - time_t st_mtimeX; - int32_t st_umtime; - time_t st_ctimeX; - int32_t st_uctime; - uint32_t st_blksize; - int32_t st_blocks; - uint32_t st_flags; - uint32_t st_gen; - }; + infop->current_cpu = htog(0); + infop->cpus_in_box = htog(process->numCpus()); + infop->cpu_type = htog(57); + infop->ncpus = htog(process->numCpus()); + uint64_t cpumask = (1 << process->numCpus()) - 1; + infop->cpus_present = infop->cpus_running = htog(cpumask); + infop->cpu_binding = htog(0); + infop->cpu_ex_binding = htog(0); + infop->mhz = htog(667); - /// For statfs(). - struct F64_statfs { - int16_t f_type; - int16_t f_flags; - int32_t f_retired1; - int32_t f_retired2; - int32_t f_retired3; - int32_t f_retired4; - int32_t f_retired5; - int32_t f_retired6; - int32_t f_retired7; - fsid_t f_fsid; - int32_t f_spare[9]; - char f_retired8[90]; - char f_retired9[90]; - uint64_t dummy[10]; // was union mount_info mount_info; - uint64_t f_flags2; - int64_t f_spare2[14]; - int64_t f_fsize; - int64_t f_bsize; - int64_t f_blocks; - int64_t f_bfree; - int64_t f_bavail; - int64_t f_files; - int64_t f_ffree; - char f_mntonname[1024]; - char f_mntfromname[1024]; - }; + infop.copyOut(xc->mem); + return 1; + } - /// For old Tru64 v4.x statfs() - struct pre_F64_statfs { - int16_t f_type; - int16_t f_flags; - int32_t f_fsize; - int32_t f_bsize; - int32_t f_blocks; - int32_t f_bfree; - int32_t f_bavail; - int32_t f_files; - int32_t f_ffree; - fsid_t f_fsid; - int32_t f_spare[9]; - char f_mntonname[90]; - char f_mntfromname[90]; - uint64_t dummy[10]; // was union mount_info mount_info; - }; + case Tru64::GSI_PROC_TYPE: { + TypedBufferArg proc_type(xc->getSyscallArg(1)); + *proc_type = htog((uint64_t)11); + proc_type.copyOut(xc->mem); + return 1; + } - /// For getdirentries(). - struct dirent - { - ino_t d_ino; //!< file number of entry - uint16_t d_reclen; //!< length of this record - uint16_t d_namlen; //!< length of string in d_name - char d_name[256]; //!< dummy name length - }; + case Tru64::GSI_PLATFORM_NAME: { + BufferArg bufArg(xc->getSyscallArg(1), nbytes); + strncpy((char *)bufArg.bufferPtr(), + "COMPAQ Professional Workstation XP1000", + nbytes); + bufArg.copyOut(xc->mem); + return 1; + } + case Tru64::GSI_CLK_TCK: { + TypedBufferArg clk_hz(xc->getSyscallArg(1)); + *clk_hz = htog((uint64_t)1024); + clk_hz.copyOut(xc->mem); + return 1; + } - /// Length of strings in struct utsname (plus 1 for null char). - static const int _SYS_NMLN = 32; - - /// Interface struct for uname(). - struct utsname { - char sysname[_SYS_NMLN]; //!< System name. - char nodename[_SYS_NMLN]; //!< Node name. - char release[_SYS_NMLN]; //!< OS release. - char version[_SYS_NMLN]; //!< OS version. - char machine[_SYS_NMLN]; //!< Machine type. - }; - - //@{ - /// ioctl() command codes. - static const unsigned TIOCGETP = 0x40067408; - static const unsigned TIOCSETP = 0x80067409; - static const unsigned TIOCSETN = 0x8006740a; - static const unsigned TIOCSETC = 0x80067411; - static const unsigned TIOCGETC = 0x40067412; - static const unsigned FIONREAD = 0x4004667f; - static const unsigned TIOCISATTY = 0x2000745e; - // TIOCGETS not defined in tru64, so I made up a number - static const unsigned TIOCGETS = 0x40000000; - static const unsigned TIOCGETA = 0x402c7413; - //@} - - /// Resource enumeration for getrlimit(). - enum rlimit_resources { - TGT_RLIMIT_CPU = 0, - TGT_RLIMIT_FSIZE = 1, - TGT_RLIMIT_DATA = 2, - TGT_RLIMIT_STACK = 3, - TGT_RLIMIT_CORE = 4, - TGT_RLIMIT_RSS = 5, - TGT_RLIMIT_NOFILE = 6, - TGT_RLIMIT_AS = 7, - TGT_RLIMIT_VMEM = 7 - }; - - /// Limit struct for getrlimit/setrlimit. - struct rlimit { - uint64_t rlim_cur; //!< soft limit - uint64_t rlim_max; //!< hard limit - }; - - - /// For mmap(). - static const unsigned TGT_MAP_ANONYMOUS = 0x10; - - - //@{ - /// For getsysinfo(). - static const unsigned GSI_PLATFORM_NAME = 103; //!< platform name as string - static const unsigned GSI_CPU_INFO = 59; //!< CPU information - static const unsigned GSI_PROC_TYPE = 60; //!< get proc_type - static const unsigned GSI_MAX_CPU = 30; //!< max # cpu's on this machine - static const unsigned GSI_CPUS_IN_BOX = 55; //!< number of CPUs in system - static const unsigned GSI_PHYSMEM = 19; //!< Physical memory in KB - static const unsigned GSI_CLK_TCK = 42; //!< clock freq in Hz - //@} - - /// For getsysinfo() GSI_CPU_INFO option. - struct cpu_info { - uint32_t current_cpu; //!< current_cpu - uint32_t cpus_in_box; //!< cpus_in_box - uint32_t cpu_type; //!< cpu_type - uint32_t ncpus; //!< ncpus - uint64_t cpus_present; //!< cpus_present - uint64_t cpus_running; //!< cpus_running - uint64_t cpu_binding; //!< cpu_binding - uint64_t cpu_ex_binding; //!< cpu_ex_binding - uint32_t mhz; //!< mhz - uint32_t unused[3]; //!< future expansion - }; - - //@{ - /// For setsysinfo(). - static const unsigned SSI_IEEE_FP_CONTROL = 14; //!< ieee_set_fp_control() - //@} - - /// For gettimeofday. - struct timeval { - uint32_t tv_sec; //!< seconds - uint32_t tv_usec; //!< microseconds - }; - - //@{ - /// For getrusage(). - static const int TGT_RUSAGE_THREAD = 1; - static const int TGT_RUSAGE_SELF = 0; - static const int TGT_RUSAGE_CHILDREN = -1; - //@} - - /// For getrusage(). - struct rusage { - struct timeval ru_utime; //!< user time used - struct timeval ru_stime; //!< system time used - uint64_t ru_maxrss; //!< ru_maxrss - uint64_t ru_ixrss; //!< integral shared memory size - uint64_t ru_idrss; //!< integral unshared data " - uint64_t ru_isrss; //!< integral unshared stack " - uint64_t ru_minflt; //!< page reclaims - total vmfaults - uint64_t ru_majflt; //!< page faults - uint64_t ru_nswap; //!< swaps - uint64_t ru_inblock; //!< block input operations - uint64_t ru_oublock; //!< block output operations - uint64_t ru_msgsnd; //!< messages sent - uint64_t ru_msgrcv; //!< messages received - uint64_t ru_nsignals; //!< signals received - uint64_t ru_nvcsw; //!< voluntary context switches - uint64_t ru_nivcsw; //!< involuntary " - }; - - /// For sigreturn(). - struct sigcontext { - int64_t sc_onstack; //!< sigstack state to restore - int64_t sc_mask; //!< signal mask to restore - int64_t sc_pc; //!< pc at time of signal - int64_t sc_ps; //!< psl to retore - int64_t sc_regs[32]; //!< processor regs 0 to 31 - int64_t sc_ownedfp; //!< fp has been used - int64_t sc_fpregs[32]; //!< fp regs 0 to 31 - uint64_t sc_fpcr; //!< floating point control reg - uint64_t sc_fp_control; //!< software fpcr - int64_t sc_reserved1; //!< reserved for kernel - uint32_t sc_kreserved1; //!< reserved for kernel - uint32_t sc_kreserved2; //!< reserved for kernel - size_t sc_ssize; //!< stack size - caddr_t sc_sbase; //!< stack start - uint64_t sc_traparg_a0; //!< a0 argument to trap on exc - uint64_t sc_traparg_a1; //!< a1 argument to trap on exc - uint64_t sc_traparg_a2; //!< a2 argument to trap on exc - uint64_t sc_fp_trap_pc; //!< imprecise pc - uint64_t sc_fp_trigger_sum; //!< Exception summary at trigg - uint64_t sc_fp_trigger_inst; //!< Instruction at trigger pc - }; - - - /// For table(). - static const int TBL_SYSINFO = 12; - - /// For table(). - struct tbl_sysinfo { - uint64_t si_user; //!< User time - uint64_t si_nice; //!< Nice time - uint64_t si_sys; //!< System time - uint64_t si_idle; //!< Idle time - uint64_t si_hz; //!< hz - uint64_t si_phz; //!< phz - uint64_t si_boottime; //!< Boot time in seconds - uint64_t wait; //!< Wait time - uint32_t si_max_procs; //!< rpb->rpb_numprocs - uint32_t pad; //!< padding - }; - - - /// For stack_create. - struct vm_stack { - // was void * - Addr address; //!< address hint - size_t rsize; //!< red zone size - size_t ysize; //!< yellow zone size - size_t gsize; //!< green zone size - size_t swap; //!< amount of swap to reserve - size_t incr; //!< growth increment - uint64_t align; //!< address alignment - uint64_t flags; //!< MAP_FIXED etc. - // was struct memalloc_attr * - Addr attr; //!< allocation policy - uint64_t reserved; //!< reserved - }; - - /// Return values for nxm calls. - enum { - KERN_NOT_RECEIVER = 7, - KERN_NOT_IN_SET = 12 - }; - - /// For nxm_task_init. - static const int NXM_TASK_INIT_VP = 2; //!< initial thread is VP - - /// Task attribute structure. - struct nxm_task_attr { - int64_t nxm_callback; //!< nxm_callback - unsigned int nxm_version; //!< nxm_version - unsigned short nxm_uniq_offset; //!< nxm_uniq_offset - unsigned short flags; //!< flags - int nxm_quantum; //!< nxm_quantum - int pad1; //!< pad1 - int64_t pad2; //!< pad2 - }; - - /// Signal set. - typedef uint64_t sigset_t; - - /// Thread state shared between user & kernel. - struct ushared_state { - sigset_t sigmask; //!< thread signal mask - sigset_t sig; //!< thread pending mask - // struct nxm_pth_state * - Addr pth_id; //!< out-of-line state - int flags; //!< shared flags -#define US_SIGSTACK 0x1 // thread called sigaltstack -#define US_ONSTACK 0x2 // thread is running on altstack -#define US_PROFILE 0x4 // thread called profil -#define US_SYSCALL 0x8 // thread in syscall -#define US_TRAP 0x10 // thread has trapped -#define US_YELLOW 0x20 // thread has mellowed yellow -#define US_YZONE 0x40 // thread has zoned out -#define US_FP_OWNED 0x80 // thread used floating point - - int cancel_state; //!< thread's cancelation state -#define US_CANCEL 0x1 // cancel pending -#define US_NOCANCEL 0X2 // synch cancel disabled -#define US_SYS_NOCANCEL 0x4 // syscall cancel disabled -#define US_ASYNC_NOCANCEL 0x8 // asynch cancel disabled -#define US_CANCEL_BITS (US_NOCANCEL|US_SYS_NOCANCEL|US_ASYNC_NOCANCEL) -#define US_CANCEL_MASK (US_CANCEL|US_NOCANCEL|US_SYS_NOCANCEL| \ - US_ASYNC_NOCANCEL) - - // These are semi-shared. They are always visible to - // the kernel but are never context-switched by the library. - - int nxm_ssig; //!< scheduler's synchronous signals - int reserved1; //!< reserved1 - int64_t nxm_active; //!< scheduler active - int64_t reserved2; //!< reserved2 - }; - - struct nxm_sched_state { - struct ushared_state nxm_u; //!< state own by user thread - unsigned int nxm_bits; //!< scheduler state / slot - int nxm_quantum; //!< quantum count-down value - int nxm_set_quantum; //!< quantum reset value - int nxm_sysevent; //!< syscall state - // struct nxm_upcall * - Addr nxm_uc_ret; //!< stack ptr of null thread - // void * - Addr nxm_tid; //!< scheduler's thread id - int64_t nxm_va; //!< page fault address - // struct nxm_pth_state * - Addr nxm_pthid; //!< id of null thread - uint64_t nxm_bound_pcs_count; //!< bound PCS thread count - int64_t pad[2]; //!< pad - }; - - /// nxm_shared. - struct nxm_shared { - int64_t nxm_callback; //!< address of upcall routine - unsigned int nxm_version; //!< version number - unsigned short nxm_uniq_offset; //!< correction factor for TEB - unsigned short pad1; //!< pad1 - int64_t space[2]; //!< future growth - struct nxm_sched_state nxm_ss[1]; //!< array of shared areas - }; - - /// nxm_slot_state_t. - enum nxm_slot_state_t { - NXM_SLOT_AVAIL, - NXM_SLOT_BOUND, - NXM_SLOT_UNBOUND, - NXM_SLOT_EMPTY - }; - - /// nxm_config_info - struct nxm_config_info { - int nxm_nslots_per_rad; //!< max number of VP slots per RAD - int nxm_nrads; //!< max number of RADs - // nxm_slot_state_t * - Addr nxm_slot_state; //!< per-VP slot state - // struct nxm_shared * - Addr nxm_rad[1]; //!< per-RAD shared areas - }; - - /// For nxm_thread_create. - enum nxm_thread_type { - NXM_TYPE_SCS = 0, - NXM_TYPE_VP = 1, - NXM_TYPE_MANAGER = 2 - }; - - /// Thread attributes. - struct nxm_thread_attr { - int version; //!< version - int type; //!< type - int cancel_flags; //!< cancel_flags - int priority; //!< priority - int policy; //!< policy - int signal_type; //!< signal_type - // void * - Addr pthid; //!< pthid - sigset_t sigmask; //!< sigmask - /// Initial register values. - struct { - uint64_t pc; //!< pc - uint64_t sp; //!< sp - uint64_t a0; //!< a0 - } registers; - uint64_t pad2[2]; //!< pad2 - }; - - /// Helper function to convert a host stat buffer to a target stat - /// buffer. Also copies the target buffer out to the simulated - /// memory space. Used by stat(), fstat(), and lstat(). - template - static void - copyOutStatBuf(FunctionalMemory *mem, Addr addr, global_stat *host) - { - TypedBufferArg tgt(addr); - - tgt->st_dev = htog(host->st_dev); - tgt->st_ino = htog(host->st_ino); - tgt->st_mode = htog(host->st_mode); - tgt->st_nlink = htog(host->st_nlink); - tgt->st_uid = htog(host->st_uid); - tgt->st_gid = htog(host->st_gid); - tgt->st_rdev = htog(host->st_rdev); - tgt->st_size = htog(host->st_size); - tgt->st_atimeX = htog(host->st_atime); - tgt->st_mtimeX = htog(host->st_mtime); - tgt->st_ctimeX = htog(host->st_ctime); - tgt->st_blksize = htog(host->st_blksize); - tgt->st_blocks = htog(host->st_blocks); - - tgt.copyOut(mem); + default: + warn("getsysinfo: unknown op %d\n", op); + break; } - /// Helper function to convert a host statfs buffer to a target statfs - /// buffer. Also copies the target buffer out to the simulated - /// memory space. Used by statfs() and fstatfs(). - template - static void - copyOutStatfsBuf(FunctionalMemory *mem, Addr addr, global_statfs *host) - { - TypedBufferArg tgt(addr); + return 0; +} -#if defined(__OpenBSD__) || defined(__APPLE__) || defined(__FreeBSD__) - tgt->f_type = 0; -#else - tgt->f_type = htog(host->f_type); -#endif - tgt->f_bsize = htog(host->f_bsize); - tgt->f_blocks = htog(host->f_blocks); - tgt->f_bfree = htog(host->f_bfree); - tgt->f_bavail = htog(host->f_bavail); - tgt->f_files = htog(host->f_files); - tgt->f_ffree = htog(host->f_ffree); +/// Target setsysyinfo() handler. +static SyscallReturn +setsysinfoFunc(SyscallDesc *desc, int callnum, Process *process, + ExecContext *xc) +{ + unsigned op = xc->getSyscallArg(0); - // Is this as string normally? - memcpy(&tgt->f_fsid, &host->f_fsid, sizeof(host->f_fsid)); + switch (op) { + case Tru64::SSI_IEEE_FP_CONTROL: + warn("setsysinfo: ignoring ieee_set_fp_control() arg 0x%x\n", + xc->getSyscallArg(1)); + break; - tgt.copyOut(mem); + default: + warn("setsysinfo: unknown op %d\n", op); + break; } - class F64 { - public: - static void copyOutStatBuf(FunctionalMemory *mem, Addr addr, - global_stat *host) - { - Tru64::copyOutStatBuf(mem, addr, host); - } + return 0; +} - static void copyOutStatfsBuf(FunctionalMemory *mem, Addr addr, - global_statfs *host) - { - Tru64::copyOutStatfsBuf(mem, addr, host); - } - }; - class PreF64 { - public: - static void copyOutStatBuf(FunctionalMemory *mem, Addr addr, - global_stat *host) - { - Tru64::copyOutStatBuf(mem, addr, host); - } - - static void copyOutStatfsBuf(FunctionalMemory *mem, Addr addr, - global_statfs *host) - { - Tru64::copyOutStatfsBuf(mem, addr, host); - } - }; - - /// Helper function to convert a host stat buffer to an old pre-F64 - /// (4.x) target stat buffer. Also copies the target buffer out to - /// the simulated memory space. Used by pre_F64_stat(), - /// pre_F64_fstat(), and pre_F64_lstat(). - static void - copyOutPreF64StatBuf(FunctionalMemory *mem, Addr addr, struct stat *host) - { - TypedBufferArg tgt(addr); - - tgt->st_dev = htog(host->st_dev); - tgt->st_ino = htog(host->st_ino); - tgt->st_mode = htog(host->st_mode); - tgt->st_nlink = htog(host->st_nlink); - tgt->st_uid = htog(host->st_uid); - tgt->st_gid = htog(host->st_gid); - tgt->st_rdev = htog(host->st_rdev); - tgt->st_size = htog(host->st_size); - tgt->st_atimeX = htog(host->st_atime); - tgt->st_mtimeX = htog(host->st_mtime); - tgt->st_ctimeX = htog(host->st_ctime); - tgt->st_blksize = htog(host->st_blksize); - tgt->st_blocks = htog(host->st_blocks); - - tgt.copyOut(mem); - } - - - /// The target system's hostname. - static const char *hostname; - - /// Target uname() handler. - static SyscallReturn - unameFunc(SyscallDesc *desc, int callnum, Process *process, - ExecContext *xc) - { - TypedBufferArg name(xc->getSyscallArg(0)); - - strcpy(name->sysname, "OSF1"); - strcpy(name->nodename, hostname); - strcpy(name->release, "V5.1"); - strcpy(name->version, "732"); - strcpy(name->machine, "alpha"); - - name.copyOut(xc->mem); - return 0; - } - - - /// Target getsysyinfo() handler. - static SyscallReturn - getsysinfoFunc(SyscallDesc *desc, int callnum, Process *process, - ExecContext *xc) - { - unsigned op = xc->getSyscallArg(0); - unsigned nbytes = xc->getSyscallArg(2); - - switch (op) { - - case Tru64::GSI_MAX_CPU: { - TypedBufferArg max_cpu(xc->getSyscallArg(1)); - *max_cpu = htog((uint32_t)process->numCpus()); - max_cpu.copyOut(xc->mem); - return 1; - } - - case Tru64::GSI_CPUS_IN_BOX: { - TypedBufferArg cpus_in_box(xc->getSyscallArg(1)); - *cpus_in_box = htog((uint32_t)process->numCpus()); - cpus_in_box.copyOut(xc->mem); - return 1; - } - - case Tru64::GSI_PHYSMEM: { - TypedBufferArg physmem(xc->getSyscallArg(1)); - *physmem = htog((uint64_t)1024 * 1024); // physical memory in KB - physmem.copyOut(xc->mem); - return 1; - } - - case Tru64::GSI_CPU_INFO: { - TypedBufferArg infop(xc->getSyscallArg(1)); - - infop->current_cpu = htog(0); - infop->cpus_in_box = htog(process->numCpus()); - infop->cpu_type = htog(57); - infop->ncpus = htog(process->numCpus()); - uint64_t cpumask = (1 << process->numCpus()) - 1; - infop->cpus_present = infop->cpus_running = htog(cpumask); - infop->cpu_binding = htog(0); - infop->cpu_ex_binding = htog(0); - infop->mhz = htog(667); - - infop.copyOut(xc->mem); - return 1; - } - - case Tru64::GSI_PROC_TYPE: { - TypedBufferArg proc_type(xc->getSyscallArg(1)); - *proc_type = htog((uint64_t)11); - proc_type.copyOut(xc->mem); - return 1; - } - - case Tru64::GSI_PLATFORM_NAME: { - BufferArg bufArg(xc->getSyscallArg(1), nbytes); - strncpy((char *)bufArg.bufferPtr(), - "COMPAQ Professional Workstation XP1000", - nbytes); - bufArg.copyOut(xc->mem); - return 1; - } - - case Tru64::GSI_CLK_TCK: { - TypedBufferArg clk_hz(xc->getSyscallArg(1)); - *clk_hz = htog((uint64_t)1024); - clk_hz.copyOut(xc->mem); - return 1; - } - - default: - warn("getsysinfo: unknown op %d\n", op); - break; - } - - return 0; - } - - /// Target setsysyinfo() handler. - static SyscallReturn - setsysinfoFunc(SyscallDesc *desc, int callnum, Process *process, - ExecContext *xc) - { - unsigned op = xc->getSyscallArg(0); - - switch (op) { - case SSI_IEEE_FP_CONTROL: - warn("setsysinfo: ignoring ieee_set_fp_control() arg 0x%x\n", - xc->getSyscallArg(1)); - break; - - default: - warn("setsysinfo: unknown op %d\n", op); - break; - } - - return 0; - } - - /// Target fnctl() handler. - static SyscallReturn - fcntlFunc(SyscallDesc *desc, int callnum, Process *process, - ExecContext *xc) - { - int fd = xc->getSyscallArg(0); - - if (fd < 0 || process->sim_fd(fd) < 0) - return -EBADF; - - int cmd = xc->getSyscallArg(1); - switch (cmd) { - case 0: // F_DUPFD - // if we really wanted to support this, we'd need to do it - // in the target fd space. - warn("fcntl(%d, F_DUPFD) not supported, error returned\n", fd); - return -EMFILE; - - case 1: // F_GETFD (get close-on-exec flag) - case 2: // F_SETFD (set close-on-exec flag) - return 0; - - case 3: // F_GETFL (get file flags) - case 4: // F_SETFL (set file flags) - // not sure if this is totally valid, but we'll pass it through - // to the underlying OS - warn("fcntl(%d, %d) passed through to host\n", fd, cmd); - return fcntl(process->sim_fd(fd), cmd); - // return 0; - - case 7: // F_GETLK (get lock) - case 8: // F_SETLK (set lock) - case 9: // F_SETLKW (set lock and wait) - // don't mess with file locking... just act like it's OK - warn("File lock call (fcntl(%d, %d)) ignored.\n", fd, cmd); - return 0; - - default: - warn("Unknown fcntl command %d\n", cmd); - return 0; - } - } - - - /// Target getdirentries() handler. - static SyscallReturn - getdirentriesFunc(SyscallDesc *desc, int callnum, Process *process, - ExecContext *xc) - { -#ifdef __CYGWIN__ - panic("getdirent not implemented on cygwin!"); -#else - int fd = process->sim_fd(xc->getSyscallArg(0)); - Addr tgt_buf = xc->getSyscallArg(1); - int tgt_nbytes = xc->getSyscallArg(2); - Addr tgt_basep = xc->getSyscallArg(3); - - char * const host_buf = new char[tgt_nbytes]; - - // just pass basep through uninterpreted. - TypedBufferArg basep(tgt_basep); - basep.copyIn(xc->mem); - long host_basep = (off_t)htog((int64_t)*basep); - int host_result = getdirentries(fd, host_buf, tgt_nbytes, &host_basep); - - // check for error - if (host_result < 0) { - delete [] host_buf; - return -errno; - } - - // no error: copy results back to target space - Addr tgt_buf_ptr = tgt_buf; - char *host_buf_ptr = host_buf; - char *host_buf_end = host_buf + host_result; - while (host_buf_ptr < host_buf_end) { - global_dirent *host_dp = (global_dirent *)host_buf_ptr; - int namelen = strlen(host_dp->d_name); - - // Actual size includes padded string rounded up for alignment. - // Subtract 256 for dummy char array in Tru64::dirent definition. - // Add 1 to namelen for terminating null char. - int tgt_bufsize = sizeof(Tru64::dirent) - 256 + roundUp(namelen+1, 8); - TypedBufferArg tgt_dp(tgt_buf_ptr, tgt_bufsize); - tgt_dp->d_ino = host_dp->d_ino; - tgt_dp->d_reclen = tgt_bufsize; - tgt_dp->d_namlen = namelen; - strcpy(tgt_dp->d_name, host_dp->d_name); - tgt_dp.copyOut(xc->mem); - - tgt_buf_ptr += tgt_bufsize; - host_buf_ptr += host_dp->d_reclen; - } - - delete [] host_buf; - - *basep = htog((int64_t)host_basep); - basep.copyOut(xc->mem); - - return tgt_buf_ptr - tgt_buf; -#endif - } - - /// Target sigreturn() handler. - static SyscallReturn - sigreturnFunc(SyscallDesc *desc, int callnum, Process *process, - ExecContext *xc) - { - RegFile *regs = &xc->regs; - TypedBufferArg sc(xc->getSyscallArg(0)); - - sc.copyIn(xc->mem); - - // Restore state from sigcontext structure. - // Note that we'll advance PC <- NPC before the end of the cycle, - // so we need to restore the desired PC into NPC. - // The current regs->pc will get clobbered. - regs->npc = htog(sc->sc_pc); - - for (int i = 0; i < 31; ++i) { - regs->intRegFile[i] = htog(sc->sc_regs[i]); - regs->floatRegFile.q[i] = htog(sc->sc_fpregs[i]); - } - - regs->miscRegs.fpcr = htog(sc->sc_fpcr); - - return 0; - } - - /// Target table() handler. - static SyscallReturn - tableFunc(SyscallDesc *desc, int callnum, Process *process, - ExecContext *xc) - { - int id = xc->getSyscallArg(0); // table ID - int index = xc->getSyscallArg(1); // index into table - // arg 2 is buffer pointer; type depends on table ID - int nel = xc->getSyscallArg(3); // number of elements - int lel = xc->getSyscallArg(4); // expected element size - - switch (id) { - case Tru64::TBL_SYSINFO: { - if (index != 0 || nel != 1 || lel != sizeof(Tru64::tbl_sysinfo)) - return -EINVAL; - TypedBufferArg elp(xc->getSyscallArg(2)); - - const int clk_hz = one_million; - elp->si_user = htog(curTick / (Clock::Frequency / clk_hz)); - elp->si_nice = htog(0); - elp->si_sys = htog(0); - elp->si_idle = htog(0); - elp->wait = htog(0); - elp->si_hz = htog(clk_hz); - elp->si_phz = htog(clk_hz); - elp->si_boottime = htog(seconds_since_epoch); // seconds since epoch? - elp->si_max_procs = htog(process->numCpus()); - elp.copyOut(xc->mem); - return 0; - } - - default: - cerr << "table(): id " << id << " unknown." << endl; - return -EINVAL; - } - } - - /// Array of syscall descriptors, indexed by call number. - static SyscallDesc syscallDescs[]; - - /// Number of syscalls in syscallDescs[]. - static const int Num_Syscall_Descs; - - /// Max supported syscall number. - static const int Max_Syscall_Desc; - - // - // Mach syscalls -- identified by negated syscall numbers - // - - /// Create a stack region for a thread. - static SyscallReturn - stack_createFunc(SyscallDesc *desc, int callnum, Process *process, - ExecContext *xc) - { - TypedBufferArg argp(xc->getSyscallArg(0)); - - argp.copyIn(xc->mem); - - // if the user chose an address, just let them have it. Otherwise - // pick one for them. - if (htog(argp->address) == 0) { - argp->address = htog(process->next_thread_stack_base); - int stack_size = (htog(argp->rsize) + htog(argp->ysize) + - htog(argp->gsize)); - process->next_thread_stack_base -= stack_size; - argp.copyOut(xc->mem); - } - - return 0; - } - - /// NXM library version stamp. - static - const int NXM_LIB_VERSION = 301003; - - /// This call sets up the interface between the user and kernel - /// schedulers by creating a shared-memory region. The shared memory - /// region has several structs, some global, some per-RAD, some per-VP. - static SyscallReturn - nxm_task_initFunc(SyscallDesc *desc, int callnum, Process *process, - ExecContext *xc) - { - TypedBufferArg attrp(xc->getSyscallArg(0)); - TypedBufferArg configptr_ptr(xc->getSyscallArg(1)); - - attrp.copyIn(xc->mem); - - if (gtoh(attrp->nxm_version) != NXM_LIB_VERSION) { - cerr << "nxm_task_init: thread library version mismatch! " - << "got " << attrp->nxm_version - << ", expected " << NXM_LIB_VERSION << endl; - abort(); - } - - if (gtoh(attrp->flags) != Tru64::NXM_TASK_INIT_VP) { - cerr << "nxm_task_init: bad flag value " << attrp->flags - << " (expected " << Tru64::NXM_TASK_INIT_VP << ")" << endl; - abort(); - } - - const Addr base_addr = 0x12000; // was 0x3f0000000LL; - Addr cur_addr = base_addr; // next addresses to use - // first comes the config_info struct - Addr config_addr = cur_addr; - cur_addr += sizeof(Tru64::nxm_config_info); - // next comes the per-cpu state vector - Addr slot_state_addr = cur_addr; - int slot_state_size = - process->numCpus() * sizeof(Tru64::nxm_slot_state_t); - cur_addr += slot_state_size; - // now the per-RAD state struct (we only support one RAD) - cur_addr = 0x14000; // bump up addr for alignment - Addr rad_state_addr = cur_addr; - int rad_state_size = - (sizeof(Tru64::nxm_shared) - + (process->numCpus()-1) * sizeof(Tru64::nxm_sched_state)); - cur_addr += rad_state_size; - - // now initialize a config_info struct and copy it out to user space - TypedBufferArg config(config_addr); - - config->nxm_nslots_per_rad = htog(process->numCpus()); - config->nxm_nrads = htog(1); // only one RAD in our system! - config->nxm_slot_state = htog(slot_state_addr); - config->nxm_rad[0] = htog(rad_state_addr); - - config.copyOut(xc->mem); - - // initialize the slot_state array and copy it out - TypedBufferArg slot_state(slot_state_addr, - slot_state_size); - for (int i = 0; i < process->numCpus(); ++i) { - // CPU 0 is bound to the calling process; all others are available - // XXX this code should have an endian conversion, but I don't think - // it works anyway - slot_state[i] = - (i == 0) ? Tru64::NXM_SLOT_BOUND : Tru64::NXM_SLOT_AVAIL; - } - - slot_state.copyOut(xc->mem); - - // same for the per-RAD "shared" struct. Note that we need to - // allocate extra bytes for the per-VP array which is embedded at - // the end. - TypedBufferArg rad_state(rad_state_addr, - rad_state_size); - - rad_state->nxm_callback = attrp->nxm_callback; - rad_state->nxm_version = attrp->nxm_version; - rad_state->nxm_uniq_offset = attrp->nxm_uniq_offset; - for (int i = 0; i < process->numCpus(); ++i) { - Tru64::nxm_sched_state *ssp = &rad_state->nxm_ss[i]; - ssp->nxm_u.sigmask = htog(0); - ssp->nxm_u.sig = htog(0); - ssp->nxm_u.flags = htog(0); - ssp->nxm_u.cancel_state = htog(0); - ssp->nxm_u.nxm_ssig = 0; - ssp->nxm_bits = htog(0); - ssp->nxm_quantum = attrp->nxm_quantum; - ssp->nxm_set_quantum = attrp->nxm_quantum; - ssp->nxm_sysevent = htog(0); - - if (i == 0) { - uint64_t uniq = xc->regs.miscRegs.uniq; - ssp->nxm_u.pth_id = htog(uniq + gtoh(attrp->nxm_uniq_offset)); - ssp->nxm_u.nxm_active = htog(uniq | 1); - } - else { - ssp->nxm_u.pth_id = htog(0); - ssp->nxm_u.nxm_active = htog(0); - } - } - - rad_state.copyOut(xc->mem); - - // - // copy pointer to shared config area out to user - // - *configptr_ptr = htog(config_addr); - configptr_ptr.copyOut(xc->mem); - - // Register this as a valid address range with the process - process->nxm_start = base_addr; - process->nxm_end = cur_addr; - - return 0; - } - - /// Initialize execution context. - static void - init_exec_context(ExecContext *ec, - Tru64::nxm_thread_attr *attrp, uint64_t uniq_val) - { - memset(&ec->regs, 0, sizeof(ec->regs)); - - ec->regs.intRegFile[ArgumentReg0] = gtoh(attrp->registers.a0); - ec->regs.intRegFile[27/*t12*/] = gtoh(attrp->registers.pc); - ec->regs.intRegFile[StackPointerReg] = gtoh(attrp->registers.sp); - ec->regs.miscRegs.uniq = uniq_val; - - ec->regs.pc = gtoh(attrp->registers.pc); - ec->regs.npc = gtoh(attrp->registers.pc) + sizeof(MachInst); - - ec->activate(); - } - - /// Create thread. - static SyscallReturn - nxm_thread_createFunc(SyscallDesc *desc, int callnum, Process *process, - ExecContext *xc) - { - TypedBufferArg attrp(xc->getSyscallArg(0)); - TypedBufferArg kidp(xc->getSyscallArg(1)); - int thread_index = xc->getSyscallArg(2); - - // get attribute args - attrp.copyIn(xc->mem); - - if (gtoh(attrp->version) != NXM_LIB_VERSION) { - cerr << "nxm_thread_create: thread library version mismatch! " - << "got " << attrp->version - << ", expected " << NXM_LIB_VERSION << endl; - abort(); - } - - if (thread_index < 0 | thread_index > process->numCpus()) { - cerr << "nxm_thread_create: bad thread index " << thread_index - << endl; - abort(); - } - - // On a real machine, the per-RAD shared structure is in - // shared memory, so both the user and kernel can get at it. - // We don't have that luxury, so we just copy it in and then - // back out again. - int rad_state_size = - (sizeof(Tru64::nxm_shared) + - (process->numCpus()-1) * sizeof(Tru64::nxm_sched_state)); - - TypedBufferArg rad_state(0x14000, - rad_state_size); - rad_state.copyIn(xc->mem); - - uint64_t uniq_val = gtoh(attrp->pthid) - gtoh(rad_state->nxm_uniq_offset); - - if (gtoh(attrp->type) == Tru64::NXM_TYPE_MANAGER) { - // DEC pthreads seems to always create one of these (in - // addition to N application threads), but we don't use it, - // so don't bother creating it. - - // This is supposed to be a port number. Make something up. - *kidp = htog(99); - kidp.copyOut(xc->mem); - - return 0; - } else if (gtoh(attrp->type) == Tru64::NXM_TYPE_VP) { - // A real "virtual processor" kernel thread. Need to fork - // this thread on another CPU. - Tru64::nxm_sched_state *ssp = &rad_state->nxm_ss[thread_index]; - - if (gtoh(ssp->nxm_u.nxm_active) != 0) - return (int) Tru64::KERN_NOT_RECEIVER; - - ssp->nxm_u.pth_id = attrp->pthid; - ssp->nxm_u.nxm_active = htog(uniq_val | 1); - - rad_state.copyOut(xc->mem); - - Addr slot_state_addr = 0x12000 + sizeof(Tru64::nxm_config_info); - int slot_state_size = - process->numCpus() * sizeof(Tru64::nxm_slot_state_t); - - TypedBufferArg - slot_state(slot_state_addr, - slot_state_size); - - slot_state.copyIn(xc->mem); - - if (slot_state[thread_index] != Tru64::NXM_SLOT_AVAIL) { - cerr << "nxm_thread_createFunc: requested VP slot " - << thread_index << " not available!" << endl; - fatal(""); - } - - // XXX This should have an endian conversion but I think this code - // doesn't work anyway - slot_state[thread_index] = Tru64::NXM_SLOT_BOUND; - - slot_state.copyOut(xc->mem); - - // Find a free simulator execution context. - for (int i = 0; i < process->numCpus(); ++i) { - ExecContext *xc = process->execContexts[i]; - - if (xc->status() == ExecContext::Unallocated) { - // inactive context... grab it - init_exec_context(xc, attrp, uniq_val); - - // This is supposed to be a port number, but we'll try - // and get away with just sticking the thread index - // here. - *kidp = htog(thread_index); - kidp.copyOut(xc->mem); - - return 0; - } - } - - // fell out of loop... no available inactive context - cerr << "nxm_thread_create: no idle contexts available." << endl; - abort(); - } else { - cerr << "nxm_thread_create: can't handle thread type " - << attrp->type << endl; - abort(); - } - - return 0; - } - - /// Thread idle call (like yield()). - static SyscallReturn - nxm_idleFunc(SyscallDesc *desc, int callnum, Process *process, - ExecContext *xc) - { - return 0; - } - - /// Block thread. - static SyscallReturn - nxm_thread_blockFunc(SyscallDesc *desc, int callnum, Process *process, - ExecContext *xc) - { - uint64_t tid = xc->getSyscallArg(0); - uint64_t secs = xc->getSyscallArg(1); - uint64_t flags = xc->getSyscallArg(2); - uint64_t action = xc->getSyscallArg(3); - uint64_t usecs = xc->getSyscallArg(4); - - cout << xc->cpu->name() << ": nxm_thread_block " << tid << " " << secs - << " " << flags << " " << action << " " << usecs << endl; - - return 0; - } - - /// block. - static SyscallReturn - nxm_blockFunc(SyscallDesc *desc, int callnum, Process *process, - ExecContext *xc) - { - Addr uaddr = xc->getSyscallArg(0); - uint64_t val = xc->getSyscallArg(1); - uint64_t secs = xc->getSyscallArg(2); - uint64_t usecs = xc->getSyscallArg(3); - uint64_t flags = xc->getSyscallArg(4); - - BaseCPU *cpu = xc->cpu; - - cout << cpu->name() << ": nxm_block " - << hex << uaddr << dec << " " << val - << " " << secs << " " << usecs - << " " << flags << endl; - - return 0; - } - - /// Unblock thread. - static SyscallReturn - nxm_unblockFunc(SyscallDesc *desc, int callnum, Process *process, - ExecContext *xc) - { - Addr uaddr = xc->getSyscallArg(0); - - cout << xc->cpu->name() << ": nxm_unblock " - << hex << uaddr << dec << endl; - - return 0; - } - - /// Switch thread priority. - static SyscallReturn - swtch_priFunc(SyscallDesc *desc, int callnum, Process *process, - ExecContext *xc) - { - // Attempts to switch to another runnable thread (if there is - // one). Returns false if there are no other threads to run - // (i.e., the thread can reasonably spin-wait) or true if there - // are other threads. - // - // Since we assume at most one "kernel" thread per CPU, it's - // always safe to return false here. - return 0; //false; - } - - - /// Activate exec context waiting on a channel. Just activate one - /// by default. - static int - activate_waiting_context(Addr uaddr, Process *process, - bool activate_all = false) - { - int num_activated = 0; - - list::iterator i = process->waitList.begin(); - list::iterator end = process->waitList.end(); - - while (i != end && (num_activated == 0 || activate_all)) { - if (i->waitChan == uaddr) { - // found waiting process: make it active - ExecContext *newCtx = i->waitingContext; - assert(newCtx->status() == ExecContext::Suspended); - newCtx->activate(); - - // get rid of this record - i = process->waitList.erase(i); - - ++num_activated; - } else { - ++i; - } - } - - return num_activated; - } - - /// M5 hacked-up lock acquire. - static void - m5_lock_mutex(Addr uaddr, Process *process, ExecContext *xc) - { - TypedBufferArg lockp(uaddr); - - lockp.copyIn(xc->mem); - - if (gtoh(*lockp) == 0) { - // lock is free: grab it - *lockp = htog(1); - lockp.copyOut(xc->mem); - } else { - // lock is busy: disable until free - process->waitList.push_back(Process::WaitRec(uaddr, xc)); - xc->suspend(); - } - } - - /// M5 unlock call. - static void - m5_unlock_mutex(Addr uaddr, Process *process, ExecContext *xc) - { - TypedBufferArg lockp(uaddr); - - lockp.copyIn(xc->mem); - assert(*lockp != 0); - - // Check for a process waiting on the lock. - int num_waiting = activate_waiting_context(uaddr, process); - - // clear lock field if no waiting context is taking over the lock - if (num_waiting == 0) { - *lockp = 0; - lockp.copyOut(xc->mem); - } - } - - /// Lock acquire syscall handler. - static SyscallReturn - m5_mutex_lockFunc(SyscallDesc *desc, int callnum, Process *process, - ExecContext *xc) - { - Addr uaddr = xc->getSyscallArg(0); - - m5_lock_mutex(uaddr, process, xc); - - // Return 0 since we will always return to the user with the lock - // acquired. We will just keep the context inactive until that is - // true. - return 0; - } - - /// Try lock (non-blocking). - static SyscallReturn - m5_mutex_trylockFunc(SyscallDesc *desc, int callnum, Process *process, - ExecContext *xc) - { - Addr uaddr = xc->getSyscallArg(0); - TypedBufferArg lockp(uaddr); - - lockp.copyIn(xc->mem); - - if (gtoh(*lockp) == 0) { - // lock is free: grab it - *lockp = htog(1); - lockp.copyOut(xc->mem); - return 0; - } else { - return 1; - } - } - - /// Unlock syscall handler. - static SyscallReturn - m5_mutex_unlockFunc(SyscallDesc *desc, int callnum, Process *process, - ExecContext *xc) - { - Addr uaddr = xc->getSyscallArg(0); - - m5_unlock_mutex(uaddr, process, xc); - - return 0; - } - - /// Signal ocndition. - static SyscallReturn - m5_cond_signalFunc(SyscallDesc *desc, int callnum, Process *process, - ExecContext *xc) - { - Addr cond_addr = xc->getSyscallArg(0); - - // Wake up one process waiting on the condition variable. - activate_waiting_context(cond_addr, process); - - return 0; - } - - /// Wake up all processes waiting on the condition variable. - static SyscallReturn - m5_cond_broadcastFunc(SyscallDesc *desc, int callnum, Process *process, - ExecContext *xc) - { - Addr cond_addr = xc->getSyscallArg(0); - - activate_waiting_context(cond_addr, process, true); - - return 0; - } - - /// Wait on a condition. - static SyscallReturn - m5_cond_waitFunc(SyscallDesc *desc, int callnum, Process *process, - ExecContext *xc) - { - Addr cond_addr = xc->getSyscallArg(0); - Addr lock_addr = xc->getSyscallArg(1); - TypedBufferArg condp(cond_addr); - TypedBufferArg lockp(lock_addr); - - // user is supposed to acquire lock before entering - lockp.copyIn(xc->mem); - assert(gtoh(*lockp) != 0); - - m5_unlock_mutex(lock_addr, process, xc); - - process->waitList.push_back(Process::WaitRec(cond_addr, xc)); - xc->suspend(); - - return 0; - } - - /// Thread exit. - static SyscallReturn - m5_thread_exitFunc(SyscallDesc *desc, int callnum, Process *process, - ExecContext *xc) - { - assert(xc->status() == ExecContext::Active); - xc->deallocate(); - - return 0; - } - - /// Array of syscall descriptors for Mach syscalls, indexed by - /// (negated) call number. - static SyscallDesc machSyscallDescs[]; - - /// Number of syscalls in machSyscallDescs[]. - static const int Num_Mach_Syscall_Descs; - - /// Max supported Mach syscall number. - static const int Max_Mach_Syscall_Desc; - - /// Since negated values are used to identify Mach syscalls, the - /// minimum (signed) valid syscall number is the negated max Mach - /// syscall number. - static const int Min_Syscall_Desc; - - /// Do the specified syscall. Just looks the call number up in - /// the table and invokes the appropriate handler. - static void - doSyscall(int callnum, Process *process, ExecContext *xc) - { - if (callnum < Min_Syscall_Desc || callnum > Max_Syscall_Desc) { - fatal("Syscall %d out of range\n", callnum); - } - - SyscallDesc *desc = - (callnum < 0) ? - &machSyscallDescs[-callnum] : &syscallDescs[callnum]; - - desc->doSyscall(callnum, process, xc); - } - - /// Indirect syscall invocation (call #0). - static SyscallReturn - indirectSyscallFunc(SyscallDesc *desc, int callnum, Process *process, - ExecContext *xc) - { - int new_callnum = xc->getSyscallArg(0); - - for (int i = 0; i < 5; ++i) - xc->setSyscallArg(i, xc->getSyscallArg(i+1)); - - doSyscall(new_callnum, process, xc); - - return 0; - } - -}; // class Tru64 - - -// open(2) flags translation table -OpenFlagTransTable Tru64::openFlagTable[] = { -#ifdef _MSC_VER - { Tru64::TGT_O_RDONLY, _O_RDONLY }, - { Tru64::TGT_O_WRONLY, _O_WRONLY }, - { Tru64::TGT_O_RDWR, _O_RDWR }, - { Tru64::TGT_O_APPEND, _O_APPEND }, - { Tru64::TGT_O_CREAT, _O_CREAT }, - { Tru64::TGT_O_TRUNC, _O_TRUNC }, - { Tru64::TGT_O_EXCL, _O_EXCL }, -#ifdef _O_NONBLOCK - { Tru64::TGT_O_NONBLOCK, _O_NONBLOCK }, -#endif -#ifdef _O_NOCTTY - { Tru64::TGT_O_NOCTTY, _O_NOCTTY }, -#endif -#ifdef _O_SYNC - { Tru64::TGT_O_SYNC, _O_SYNC }, -#endif -#else /* !_MSC_VER */ - { Tru64::TGT_O_RDONLY, O_RDONLY }, - { Tru64::TGT_O_WRONLY, O_WRONLY }, - { Tru64::TGT_O_RDWR, O_RDWR }, - { Tru64::TGT_O_APPEND, O_APPEND }, - { Tru64::TGT_O_CREAT, O_CREAT }, - { Tru64::TGT_O_TRUNC, O_TRUNC }, - { Tru64::TGT_O_EXCL, O_EXCL }, - { Tru64::TGT_O_NONBLOCK, O_NONBLOCK }, - { Tru64::TGT_O_NOCTTY, O_NOCTTY }, -#ifdef O_SYNC - { Tru64::TGT_O_SYNC, O_SYNC }, -#endif -#endif /* _MSC_VER */ -}; - -const int Tru64::NUM_OPEN_FLAGS = (sizeof(Tru64::openFlagTable)/sizeof(Tru64::openFlagTable[0])); - -const char *Tru64::hostname = "m5.eecs.umich.edu"; - -SyscallDesc Tru64::syscallDescs[] = { - /* 0 */ SyscallDesc("syscall (#0)", indirectSyscallFunc, +SyscallDesc AlphaTru64Process::syscallDescs[] = { + /* 0 */ SyscallDesc("syscall (#0)", Tru64::indirectSyscallFunc, SyscallDesc::SuppressReturnValue), /* 1 */ SyscallDesc("exit", exitFunc), /* 2 */ SyscallDesc("fork", unimplementedFunc), @@ -1637,7 +243,7 @@ SyscallDesc Tru64::syscallDescs[] = { /* 82 */ SyscallDesc("setpgrp", unimplementedFunc), /* 83 */ SyscallDesc("setitimer", unimplementedFunc), /* 84 */ SyscallDesc("old_wait", unimplementedFunc), - /* 85 */ SyscallDesc("table", tableFunc), + /* 85 */ SyscallDesc("table", Tru64::tableFunc), /* 86 */ SyscallDesc("getitimer", unimplementedFunc), /* 87 */ SyscallDesc("gethostname", gethostnameFunc), /* 88 */ SyscallDesc("sethostname", unimplementedFunc), @@ -1655,7 +261,7 @@ SyscallDesc Tru64::syscallDescs[] = { /* 100 */ SyscallDesc("getpriority", unimplementedFunc), /* 101 */ SyscallDesc("old_send", unimplementedFunc), /* 102 */ SyscallDesc("old_recv", unimplementedFunc), - /* 103 */ SyscallDesc("sigreturn", sigreturnFunc, + /* 103 */ SyscallDesc("sigreturn", Tru64::sigreturnFunc, SyscallDesc::SuppressReturnValue), /* 104 */ SyscallDesc("bind", unimplementedFunc), /* 105 */ SyscallDesc("setsockopt", unimplementedFunc), @@ -1712,7 +318,7 @@ SyscallDesc Tru64::syscallDescs[] = { /* 156 */ SyscallDesc("sigaction", ignoreFunc), /* 157 */ SyscallDesc("sigwaitprim", unimplementedFunc), /* 158 */ SyscallDesc("nfssvc", unimplementedFunc), - /* 159 */ SyscallDesc("getdirentries", getdirentriesFunc), + /* 159 */ SyscallDesc("getdirentries", Tru64::getdirentriesFunc), /* 160 */ SyscallDesc("pre_F64_statfs", statfsFunc), /* 161 */ SyscallDesc("pre_F64_fstatfs", fstatfsFunc), /* 162 */ SyscallDesc("unknown #162", unimplementedFunc), @@ -1822,20 +428,17 @@ SyscallDesc Tru64::syscallDescs[] = { /* 266 */ SyscallDesc("sendfile", unimplementedFunc), }; -const int Tru64::Num_Syscall_Descs = - sizeof(Tru64::syscallDescs) / sizeof(SyscallDesc); -const int Tru64::Max_Syscall_Desc = Tru64::Num_Syscall_Descs - 1; -SyscallDesc Tru64::machSyscallDescs[] = { +SyscallDesc AlphaTru64Process::machSyscallDescs[] = { /* 0 */ SyscallDesc("kern_invalid", unimplementedFunc), - /* 1 */ SyscallDesc("m5_mutex_lock", m5_mutex_lockFunc), - /* 2 */ SyscallDesc("m5_mutex_trylock", m5_mutex_trylockFunc), - /* 3 */ SyscallDesc("m5_mutex_unlock", m5_mutex_unlockFunc), - /* 4 */ SyscallDesc("m5_cond_signal", m5_cond_signalFunc), - /* 5 */ SyscallDesc("m5_cond_broadcast", m5_cond_broadcastFunc), - /* 6 */ SyscallDesc("m5_cond_wait", m5_cond_waitFunc), - /* 7 */ SyscallDesc("m5_thread_exit", m5_thread_exitFunc), + /* 1 */ SyscallDesc("m5_mutex_lock", Tru64::m5_mutex_lockFunc), + /* 2 */ SyscallDesc("m5_mutex_trylock", Tru64::m5_mutex_trylockFunc), + /* 3 */ SyscallDesc("m5_mutex_unlock", Tru64::m5_mutex_unlockFunc), + /* 4 */ SyscallDesc("m5_cond_signal", Tru64::m5_cond_signalFunc), + /* 5 */ SyscallDesc("m5_cond_broadcast", Tru64::m5_cond_broadcastFunc), + /* 6 */ SyscallDesc("m5_cond_wait", Tru64::m5_cond_waitFunc), + /* 7 */ SyscallDesc("m5_thread_exit", Tru64::m5_thread_exitFunc), /* 8 */ SyscallDesc("kern_invalid", unimplementedFunc), /* 9 */ SyscallDesc("kern_invalid", unimplementedFunc), /* 10 */ SyscallDesc("task_self", unimplementedFunc), @@ -1852,22 +455,22 @@ SyscallDesc Tru64::machSyscallDescs[] = { /* 21 */ SyscallDesc("msg_receive_trap", unimplementedFunc), /* 22 */ SyscallDesc("msg_rpc_trap", unimplementedFunc), /* 23 */ SyscallDesc("kern_invalid", unimplementedFunc), - /* 24 */ SyscallDesc("nxm_block", nxm_blockFunc), - /* 25 */ SyscallDesc("nxm_unblock", nxm_unblockFunc), + /* 24 */ SyscallDesc("nxm_block", Tru64::nxm_blockFunc), + /* 25 */ SyscallDesc("nxm_unblock", Tru64::nxm_unblockFunc), /* 26 */ SyscallDesc("kern_invalid", unimplementedFunc), /* 27 */ SyscallDesc("kern_invalid", unimplementedFunc), /* 28 */ SyscallDesc("kern_invalid", unimplementedFunc), /* 29 */ SyscallDesc("nxm_thread_destroy", unimplementedFunc), /* 30 */ SyscallDesc("lw_wire", unimplementedFunc), /* 31 */ SyscallDesc("lw_unwire", unimplementedFunc), - /* 32 */ SyscallDesc("nxm_thread_create", nxm_thread_createFunc), - /* 33 */ SyscallDesc("nxm_task_init", nxm_task_initFunc), + /* 32 */ SyscallDesc("nxm_thread_create", Tru64::nxm_thread_createFunc), + /* 33 */ SyscallDesc("nxm_task_init", Tru64::nxm_task_initFunc), /* 34 */ SyscallDesc("kern_invalid", unimplementedFunc), - /* 35 */ SyscallDesc("nxm_idle", nxm_idleFunc), + /* 35 */ SyscallDesc("nxm_idle", Tru64::nxm_idleFunc), /* 36 */ SyscallDesc("nxm_wakeup_idle", unimplementedFunc), /* 37 */ SyscallDesc("nxm_set_pthid", unimplementedFunc), /* 38 */ SyscallDesc("nxm_thread_kill", unimplementedFunc), - /* 39 */ SyscallDesc("nxm_thread_block", nxm_thread_blockFunc), + /* 39 */ SyscallDesc("nxm_thread_block", Tru64::nxm_thread_blockFunc), /* 40 */ SyscallDesc("nxm_thread_wakeup", unimplementedFunc), /* 41 */ SyscallDesc("init_process", unimplementedFunc), /* 42 */ SyscallDesc("nxm_get_binding", unimplementedFunc), @@ -1875,7 +478,7 @@ SyscallDesc Tru64::machSyscallDescs[] = { /* 44 */ SyscallDesc("nxm_resched", unimplementedFunc), /* 45 */ SyscallDesc("nxm_set_cancel", unimplementedFunc), /* 46 */ SyscallDesc("nxm_set_binding", unimplementedFunc), - /* 47 */ SyscallDesc("stack_create", stack_createFunc), + /* 47 */ SyscallDesc("stack_create", Tru64::stack_createFunc), /* 48 */ SyscallDesc("nxm_get_state", unimplementedFunc), /* 49 */ SyscallDesc("nxm_thread_suspend", unimplementedFunc), /* 50 */ SyscallDesc("nxm_thread_resume", unimplementedFunc), @@ -1887,7 +490,7 @@ SyscallDesc Tru64::machSyscallDescs[] = { /* 56 */ SyscallDesc("host_priv_self", unimplementedFunc), /* 57 */ SyscallDesc("kern_invalid", unimplementedFunc), /* 58 */ SyscallDesc("kern_invalid", unimplementedFunc), - /* 59 */ SyscallDesc("swtch_pri", swtch_priFunc), + /* 59 */ SyscallDesc("swtch_pri", Tru64::swtch_priFunc), /* 60 */ SyscallDesc("swtch", unimplementedFunc), /* 61 */ SyscallDesc("thread_switch", unimplementedFunc), /* 62 */ SyscallDesc("semop_fast", unimplementedFunc), @@ -1895,7 +498,7 @@ SyscallDesc Tru64::machSyscallDescs[] = { /* 64 */ SyscallDesc("nxm_pshared_block", unimplementedFunc), /* 65 */ SyscallDesc("nxm_pshared_unblock", unimplementedFunc), /* 66 */ SyscallDesc("nxm_pshared_destroy", unimplementedFunc), - /* 67 */ SyscallDesc("nxm_swtch_pri", swtch_priFunc), + /* 67 */ SyscallDesc("nxm_swtch_pri", Tru64::swtch_priFunc), /* 68 */ SyscallDesc("lw_syscall", unimplementedFunc), /* 69 */ SyscallDesc("kern_invalid", unimplementedFunc), /* 70 */ SyscallDesc("mach_sctimes_0", unimplementedFunc), @@ -1913,20 +516,16 @@ SyscallDesc Tru64::machSyscallDescs[] = { /* 82 */ SyscallDesc("mach_sctimes_port_alloc_dealloc", unimplementedFunc) }; -const int Tru64::Num_Mach_Syscall_Descs = - sizeof(Tru64::machSyscallDescs) / sizeof(SyscallDesc); -const int Tru64::Max_Mach_Syscall_Desc = Tru64::Num_Mach_Syscall_Descs - 1; -const int Tru64::Min_Syscall_Desc = -Tru64::Max_Mach_Syscall_Desc; - - -void -AlphaTru64Process::syscall(ExecContext *xc) +SyscallDesc* +AlphaTru64Process::getDesc(int callnum) { - num_syscalls++; + if (callnum < Num_Mach_Syscall_Descs || callnum > Num_Syscall_Descs) + return NULL; - int64_t callnum = xc->regs.intRegFile[ReturnValueReg]; - - Tru64::doSyscall(callnum, this, xc); + if (callnum < 0) + return &machSyscallDescs[-callnum]; + else + return &syscallDescs[callnum]; } @@ -1937,6 +536,8 @@ AlphaTru64Process::AlphaTru64Process(const std::string &name, int stderr_fd, std::vector &argv, std::vector &envp) - : LiveProcess(name, objFile, stdin_fd, stdout_fd, stderr_fd, argv, envp) + : LiveProcess(name, objFile, stdin_fd, stdout_fd, stderr_fd, argv, envp), + Num_Syscall_Descs(sizeof(syscallDescs) / sizeof(SyscallDesc)), + Num_Mach_Syscall_Descs(sizeof(machSyscallDescs) / sizeof(SyscallDesc)) { } diff --git a/arch/alpha/alpha_tru64_process.hh b/arch/alpha/alpha_tru64_process.hh index 49979806c..051760702 100644 --- a/arch/alpha/alpha_tru64_process.hh +++ b/arch/alpha/alpha_tru64_process.hh @@ -42,8 +42,16 @@ class AlphaTru64Process : public LiveProcess std::vector &argv, std::vector &envp); - /// Syscall emulation function. - virtual void syscall(ExecContext *xc); + /// Array of syscall descriptors, indexed by call number. + static SyscallDesc syscallDescs[]; + + /// Array of mach syscall descriptors, indexed by call number. + static SyscallDesc machSyscallDescs[]; + + const int Num_Syscall_Descs; + const int Num_Mach_Syscall_Descs; + + virtual SyscallDesc* getDesc(int callnum); }; diff --git a/kern/linux/linux.hh b/kern/linux/linux.hh index b083b5a31..0dbccf546 100644 --- a/kern/linux/linux.hh +++ b/kern/linux/linux.hh @@ -28,7 +28,314 @@ #ifndef __LINUX_HH__ #define __LINUX_HH__ +#include "config/full_system.hh" + +#if FULL_SYSTEM class Linux {}; +#else //!FULL_SYSTEM + +#include +#include +#include // for host open() flags +#include // for memset() +#include +#include +#include + +#include "sim/syscall_emul.hh" + +/// +/// This class encapsulates the types, structures, constants, +/// functions, and syscall-number mappings specific to the Alpha Linux +/// syscall interface. +/// +class Linux { + + public: + + //@{ + /// Basic Linux types. + typedef uint64_t size_t; + typedef uint64_t off_t; + typedef int64_t time_t; + typedef uint32_t uid_t; + typedef uint32_t gid_t; + //@} + +#if BSD_HOST + typedef struct stat hst_stat; + typedef struct stat hst_stat64; +#else + typedef struct stat hst_stat ; + typedef struct stat64 hst_stat64; +#endif + + + //@{ + /// open(2) flag values. + static const int TGT_O_RDONLY = 00000000; //!< O_RDONLY + static const int TGT_O_WRONLY = 00000001; //!< O_WRONLY + static const int TGT_O_RDWR = 00000002; //!< O_RDWR + static const int TGT_O_NONBLOCK = 00000004; //!< O_NONBLOCK + static const int TGT_O_APPEND = 00000010; //!< O_APPEND + static const int TGT_O_CREAT = 00001000; //!< O_CREAT + static const int TGT_O_TRUNC = 00002000; //!< O_TRUNC + static const int TGT_O_EXCL = 00004000; //!< O_EXCL + static const int TGT_O_NOCTTY = 00010000; //!< O_NOCTTY + static const int TGT_O_SYNC = 00040000; //!< O_SYNC + static const int TGT_O_DRD = 00100000; //!< O_DRD + static const int TGT_O_DIRECTIO = 00200000; //!< O_DIRECTIO + static const int TGT_O_CACHE = 00400000; //!< O_CACHE + static const int TGT_O_DSYNC = 02000000; //!< O_DSYNC + static const int TGT_O_RSYNC = 04000000; //!< O_RSYNC + //@} + + /// This table maps the target open() flags to the corresponding + /// host open() flags. + static OpenFlagTransTable openFlagTable[]; + + /// Number of entries in openFlagTable[]. + static const int NUM_OPEN_FLAGS; + + /// Stat buffer. Note that we can't call it 'stat' since that + /// gets #defined to something else on some systems. + struct tgt_stat { + uint32_t st_dev; //!< device + uint32_t st_ino; //!< inode + uint32_t st_mode; //!< mode + uint32_t st_nlink; //!< link count + uint32_t st_uid; //!< owner's user ID + uint32_t st_gid; //!< owner's group ID + uint32_t st_rdev; //!< device number + int32_t _pad1; //!< for alignment + int64_t st_size; //!< file size in bytes + uint64_t st_atimeX; //!< time of last access + uint64_t st_mtimeX; //!< time of last modification + uint64_t st_ctimeX; //!< time of last status change + uint32_t st_blksize; //!< optimal I/O block size + int32_t st_blocks; //!< number of blocks allocated + uint32_t st_flags; //!< flags + uint32_t st_gen; //!< unknown + }; + + // same for stat64 + struct tgt_stat64 { + uint64_t st_dev; + uint64_t st_ino; + uint64_t st_rdev; + int64_t st_size; + uint64_t st_blocks; + + uint32_t st_mode; + uint32_t st_uid; + uint32_t st_gid; + uint32_t st_blksize; + uint32_t st_nlink; + uint32_t __pad0; + + uint64_t tgt_st_atime; + uint64_t st_atime_nsec; + uint64_t tgt_st_mtime; + uint64_t st_mtime_nsec; + uint64_t tgt_st_ctime; + uint64_t st_ctime_nsec; + int64_t ___unused[3]; + }; + + /// Length of strings in struct utsname (plus 1 for null char). + static const int _SYS_NMLN = 65; + + /// Interface struct for uname(). + struct utsname { + char sysname[_SYS_NMLN]; //!< System name. + char nodename[_SYS_NMLN]; //!< Node name. + char release[_SYS_NMLN]; //!< OS release. + char version[_SYS_NMLN]; //!< OS version. + char machine[_SYS_NMLN]; //!< Machine type. + }; + + + //@{ + /// ioctl() command codes. + static const unsigned TIOCGETP = 0x40067408; + static const unsigned TIOCSETP = 0x80067409; + static const unsigned TIOCSETN = 0x8006740a; + static const unsigned TIOCSETC = 0x80067411; + static const unsigned TIOCGETC = 0x40067412; + static const unsigned FIONREAD = 0x4004667f; + static const unsigned TIOCISATTY = 0x2000745e; + static const unsigned TIOCGETS = 0x402c7413; + static const unsigned TIOCGETA = 0x40127417; + //@} + + /// Resource enumeration for getrlimit(). + enum rlimit_resources { + TGT_RLIMIT_CPU = 0, + TGT_RLIMIT_FSIZE = 1, + TGT_RLIMIT_DATA = 2, + TGT_RLIMIT_STACK = 3, + TGT_RLIMIT_CORE = 4, + TGT_RLIMIT_RSS = 5, + TGT_RLIMIT_NOFILE = 6, + TGT_RLIMIT_AS = 7, + TGT_RLIMIT_VMEM = 7, + TGT_RLIMIT_NPROC = 8, + TGT_RLIMIT_MEMLOCK = 9, + TGT_RLIMIT_LOCKS = 10 + }; + + /// Limit struct for getrlimit/setrlimit. + struct rlimit { + uint64_t rlim_cur; //!< soft limit + uint64_t rlim_max; //!< hard limit + }; + + + /// For mmap(). + static const unsigned TGT_MAP_ANONYMOUS = 0x10; + + /// For gettimeofday(). + struct timeval { + int64_t tv_sec; //!< seconds + int64_t tv_usec; //!< microseconds + }; + + // For writev/readv + struct tgt_iovec { + uint64_t iov_base; // void * + uint64_t iov_len; + }; + + //@{ + /// For getrusage(). + static const int TGT_RUSAGE_SELF = 0; + static const int TGT_RUSAGE_CHILDREN = -1; + static const int TGT_RUSAGE_BOTH = -2; + //@} + + /// For getrusage(). + struct rusage { + struct timeval ru_utime; //!< user time used + struct timeval ru_stime; //!< system time used + int64_t ru_maxrss; //!< max rss + int64_t ru_ixrss; //!< integral shared memory size + int64_t ru_idrss; //!< integral unshared data " + int64_t ru_isrss; //!< integral unshared stack " + int64_t ru_minflt; //!< page reclaims - total vmfaults + int64_t ru_majflt; //!< page faults + int64_t ru_nswap; //!< swaps + int64_t ru_inblock; //!< block input operations + int64_t ru_oublock; //!< block output operations + int64_t ru_msgsnd; //!< messages sent + int64_t ru_msgrcv; //!< messages received + int64_t ru_nsignals; //!< signals received + int64_t ru_nvcsw; //!< voluntary context switches + int64_t ru_nivcsw; //!< involuntary " + }; + + /// Helper function to convert a host stat buffer to a target stat + /// buffer. Also copies the target buffer out to the simulated + /// memory space. Used by stat(), fstat(), and lstat(). +#if !BSD_HOST + static void + copyOutStatBuf(FunctionalMemory *mem, Addr addr, hst_stat *host) + { + TypedBufferArg tgt(addr); + + tgt->st_dev = htog(host->st_dev); + tgt->st_ino = htog(host->st_ino); + tgt->st_mode = htog(host->st_mode); + tgt->st_nlink = htog(host->st_nlink); + tgt->st_uid = htog(host->st_uid); + tgt->st_gid = htog(host->st_gid); + tgt->st_rdev = htog(host->st_rdev); + tgt->st_size = htog(host->st_size); + tgt->st_atimeX = htog(host->st_atime); + tgt->st_mtimeX = htog(host->st_mtime); + tgt->st_ctimeX = htog(host->st_ctime); + tgt->st_blksize = htog(host->st_blksize); + tgt->st_blocks = htog(host->st_blocks); + + tgt.copyOut(mem); + } +#else + // Third version for bsd systems which no longer have any support for + // the old stat() call and stat() is actually a stat64() + static void + copyOutStatBuf(FunctionalMemory *mem, Addr addr, hst_stat64 *host) + { + TypedBufferArg tgt(addr); + + tgt->st_dev = htog(host->st_dev); + tgt->st_ino = htog(host->st_ino); + tgt->st_mode = htog(host->st_mode); + tgt->st_nlink = htog(host->st_nlink); + tgt->st_uid = htog(host->st_uid); + tgt->st_gid = htog(host->st_gid); + tgt->st_rdev = htog(host->st_rdev); + tgt->st_size = htog(host->st_size); + tgt->st_atimeX = htog(host->st_atime); + tgt->st_mtimeX = htog(host->st_mtime); + tgt->st_ctimeX = htog(host->st_ctime); + tgt->st_blksize = htog(host->st_blksize); + tgt->st_blocks = htog(host->st_blocks); + + tgt.copyOut(mem); + } +#endif + + + // Same for stat64 + static void + copyOutStat64Buf(FunctionalMemory *mem, int fd, Addr addr, hst_stat64 *host) + { + TypedBufferArg tgt(addr); + + // fd == 1 checks are because libc does some checks + // that the stdout is interactive vs. a file + // this makes it work on non-linux systems + if (fd == 1) + tgt->st_dev = htog((uint64_t)0xA); + else + tgt->st_dev = htog((uint64_t)host->st_dev); + // XXX What about STAT64_HAS_BROKEN_ST_INO ??? + tgt->st_ino = htog((uint64_t)host->st_ino); + if (fd == 1) + tgt->st_rdev = htog((uint64_t)0x880d); + else + tgt->st_rdev = htog((uint64_t)host->st_rdev); + tgt->st_size = htog((int64_t)host->st_size); + tgt->st_blocks = htog((uint64_t)host->st_blocks); + + if (fd == 1) + tgt->st_mode = htog((uint32_t)0x2190); + else + tgt->st_mode = htog((uint32_t)host->st_mode); + tgt->st_uid = htog((uint32_t)host->st_uid); + tgt->st_gid = htog((uint32_t)host->st_gid); + tgt->st_blksize = htog((uint32_t)host->st_blksize); + tgt->st_nlink = htog((uint32_t)host->st_nlink); + tgt->tgt_st_atime = htog((uint64_t)host->st_atime); + tgt->tgt_st_mtime = htog((uint64_t)host->st_mtime); + tgt->tgt_st_ctime = htog((uint64_t)host->st_ctime); +#if defined(STAT_HAVE_NSEC) + tgt->st_atime_nsec = htog(host->st_atime_nsec); + tgt->st_mtime_nsec = htog(host->st_mtime_nsec); + tgt->st_ctime_nsec = htog(host->st_ctime_nsec); +#else + tgt->st_atime_nsec = 0; + tgt->st_mtime_nsec = 0; + tgt->st_ctime_nsec = 0; +#endif + + tgt.copyOut(mem); + } + +}; // class Linux + + +#endif // FULL_SYSTEM + #endif // __LINUX_HH__ diff --git a/kern/tru64/tru64.hh b/kern/tru64/tru64.hh index 07c0d21a7..f3dabb0f8 100644 --- a/kern/tru64/tru64.hh +++ b/kern/tru64/tru64.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2005 The Regents of The University of Michigan + * Copyright (c) 2001-2005 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -28,7 +28,1296 @@ #ifndef __TRU64_HH__ #define __TRU64_HH__ +#include "config/full_system.hh" + +#if FULL_SYSTEM class Tru64 {}; +#else //!FULL_SYSTEM + +#include +#include +#if defined(__OpenBSD__) || defined(__APPLE__) || defined(__FreeBSD__) +#include +#include +#else +#include +#endif + +#include +#include +#include +#include // for memset() +#include + +#include "cpu/base.hh" +#include "sim/root.hh" +#include "sim/syscall_emul.hh" + +using namespace std; + +typedef struct stat global_stat; +typedef struct statfs global_statfs; +typedef struct dirent global_dirent; + +/// +/// This class encapsulates the types, structures, constants, +/// functions, and syscall-number mappings specific to the Alpha Tru64 +/// syscall interface. +/// +class Tru64 { + + public: + + //@{ + /// Basic Tru64 types. + typedef uint64_t size_t; + typedef uint64_t off_t; + typedef uint16_t nlink_t; + typedef int32_t dev_t; + typedef uint32_t uid_t; + typedef uint32_t gid_t; + typedef uint32_t time_t; + typedef uint32_t mode_t; + typedef uint32_t ino_t; + typedef struct { int val[2]; } quad; + typedef quad fsid_t; + //@} + + //@{ + /// open(2) flag values. + static const int TGT_O_RDONLY = 00000000; + static const int TGT_O_WRONLY = 00000001; + static const int TGT_O_RDWR = 00000002; + static const int TGT_O_NONBLOCK = 00000004; + static const int TGT_O_APPEND = 00000010; + static const int TGT_O_CREAT = 00001000; + static const int TGT_O_TRUNC = 00002000; + static const int TGT_O_EXCL = 00004000; + static const int TGT_O_NOCTTY = 00010000; + static const int TGT_O_SYNC = 00040000; + static const int TGT_O_DRD = 00100000; + static const int TGT_O_DIRECTIO = 00200000; + static const int TGT_O_CACHE = 00400000; + static const int TGT_O_DSYNC = 02000000; + static const int TGT_O_RSYNC = 04000000; + //@} + + /// This table maps the target open() flags to the corresponding + /// host open() flags. + static OpenFlagTransTable openFlagTable[]; + + /// Number of entries in openFlagTable[]. + static const int NUM_OPEN_FLAGS; + + /// Stat buffer. Note that Tru64 v5.0+ use a new "F64" stat + /// structure, and a new set of syscall numbers for stat calls. + /// On some hosts (notably Linux) define st_atime, st_mtime, and + /// st_ctime as macros, so we append an X to get around this. + struct F64_stat { + dev_t st_dev; //!< st_dev + int32_t st_retired1; //!< st_retired1 + mode_t st_mode; //!< st_mode + nlink_t st_nlink; //!< st_nlink + uint16_t st_nlink_reserved; //!< st_nlink_reserved + uid_t st_uid; //!< st_uid + gid_t st_gid; //!< st_gid + dev_t st_rdev; //!< st_rdev + dev_t st_ldev; //!< st_ldev + off_t st_size; //!< st_size + time_t st_retired2; //!< st_retired2 + int32_t st_uatime; //!< st_uatime + time_t st_retired3; //!< st_retired3 + int32_t st_umtime; //!< st_umtime + time_t st_retired4; //!< st_retired4 + int32_t st_uctime; //!< st_uctime + int32_t st_retired5; //!< st_retired5 + int32_t st_retired6; //!< st_retired6 + uint32_t st_flags; //!< st_flags + uint32_t st_gen; //!< st_gen + uint64_t st_spare[4]; //!< st_spare[4] + ino_t st_ino; //!< st_ino + int32_t st_ino_reserved; //!< st_ino_reserved + time_t st_atimeX; //!< st_atime + int32_t st_atime_reserved; //!< st_atime_reserved + time_t st_mtimeX; //!< st_mtime + int32_t st_mtime_reserved; //!< st_mtime_reserved + time_t st_ctimeX; //!< st_ctime + int32_t st_ctime_reserved; //!< st_ctime_reserved + uint64_t st_blksize; //!< st_blksize + uint64_t st_blocks; //!< st_blocks + }; + + + /// Old Tru64 v4.x stat struct. + /// Tru64 maintains backwards compatibility with v4.x by + /// implementing another set of stat functions using the old + /// structure definition and binding them to the old syscall + /// numbers. + struct pre_F64_stat { + dev_t st_dev; + ino_t st_ino; + mode_t st_mode; + nlink_t st_nlink; + uid_t st_uid; + gid_t st_gid; + dev_t st_rdev; + off_t st_size; + time_t st_atimeX; + int32_t st_uatime; + time_t st_mtimeX; + int32_t st_umtime; + time_t st_ctimeX; + int32_t st_uctime; + uint32_t st_blksize; + int32_t st_blocks; + uint32_t st_flags; + uint32_t st_gen; + }; + + /// For statfs(). + struct F64_statfs { + int16_t f_type; + int16_t f_flags; + int32_t f_retired1; + int32_t f_retired2; + int32_t f_retired3; + int32_t f_retired4; + int32_t f_retired5; + int32_t f_retired6; + int32_t f_retired7; + fsid_t f_fsid; + int32_t f_spare[9]; + char f_retired8[90]; + char f_retired9[90]; + uint64_t dummy[10]; // was union mount_info mount_info; + uint64_t f_flags2; + int64_t f_spare2[14]; + int64_t f_fsize; + int64_t f_bsize; + int64_t f_blocks; + int64_t f_bfree; + int64_t f_bavail; + int64_t f_files; + int64_t f_ffree; + char f_mntonname[1024]; + char f_mntfromname[1024]; + }; + + /// For old Tru64 v4.x statfs() + struct pre_F64_statfs { + int16_t f_type; + int16_t f_flags; + int32_t f_fsize; + int32_t f_bsize; + int32_t f_blocks; + int32_t f_bfree; + int32_t f_bavail; + int32_t f_files; + int32_t f_ffree; + fsid_t f_fsid; + int32_t f_spare[9]; + char f_mntonname[90]; + char f_mntfromname[90]; + uint64_t dummy[10]; // was union mount_info mount_info; + }; + + /// For getdirentries(). + struct dirent + { + ino_t d_ino; //!< file number of entry + uint16_t d_reclen; //!< length of this record + uint16_t d_namlen; //!< length of string in d_name + char d_name[256]; //!< dummy name length + }; + + + /// Length of strings in struct utsname (plus 1 for null char). + static const int _SYS_NMLN = 32; + + /// Interface struct for uname(). + struct utsname { + char sysname[_SYS_NMLN]; //!< System name. + char nodename[_SYS_NMLN]; //!< Node name. + char release[_SYS_NMLN]; //!< OS release. + char version[_SYS_NMLN]; //!< OS version. + char machine[_SYS_NMLN]; //!< Machine type. + }; + + //@{ + /// ioctl() command codes. + static const unsigned TIOCGETP = 0x40067408; + static const unsigned TIOCSETP = 0x80067409; + static const unsigned TIOCSETN = 0x8006740a; + static const unsigned TIOCSETC = 0x80067411; + static const unsigned TIOCGETC = 0x40067412; + static const unsigned FIONREAD = 0x4004667f; + static const unsigned TIOCISATTY = 0x2000745e; + // TIOCGETS not defined in tru64, so I made up a number + static const unsigned TIOCGETS = 0x40000000; + static const unsigned TIOCGETA = 0x402c7413; + //@} + + /// Resource enumeration for getrlimit(). + enum rlimit_resources { + TGT_RLIMIT_CPU = 0, + TGT_RLIMIT_FSIZE = 1, + TGT_RLIMIT_DATA = 2, + TGT_RLIMIT_STACK = 3, + TGT_RLIMIT_CORE = 4, + TGT_RLIMIT_RSS = 5, + TGT_RLIMIT_NOFILE = 6, + TGT_RLIMIT_AS = 7, + TGT_RLIMIT_VMEM = 7 + }; + + /// Limit struct for getrlimit/setrlimit. + struct rlimit { + uint64_t rlim_cur; //!< soft limit + uint64_t rlim_max; //!< hard limit + }; + + + /// For mmap(). + static const unsigned TGT_MAP_ANONYMOUS = 0x10; + + + //@{ + /// For getsysinfo(). + static const unsigned GSI_PLATFORM_NAME = 103; //!< platform name as string + static const unsigned GSI_CPU_INFO = 59; //!< CPU information + static const unsigned GSI_PROC_TYPE = 60; //!< get proc_type + static const unsigned GSI_MAX_CPU = 30; //!< max # cpu's on this machine + static const unsigned GSI_CPUS_IN_BOX = 55; //!< number of CPUs in system + static const unsigned GSI_PHYSMEM = 19; //!< Physical memory in KB + static const unsigned GSI_CLK_TCK = 42; //!< clock freq in Hz + //@} + + /// For getsysinfo() GSI_CPU_INFO option. + struct cpu_info { + uint32_t current_cpu; //!< current_cpu + uint32_t cpus_in_box; //!< cpus_in_box + uint32_t cpu_type; //!< cpu_type + uint32_t ncpus; //!< ncpus + uint64_t cpus_present; //!< cpus_present + uint64_t cpus_running; //!< cpus_running + uint64_t cpu_binding; //!< cpu_binding + uint64_t cpu_ex_binding; //!< cpu_ex_binding + uint32_t mhz; //!< mhz + uint32_t unused[3]; //!< future expansion + }; + + //@{ + /// For setsysinfo(). + static const unsigned SSI_IEEE_FP_CONTROL = 14; //!< ieee_set_fp_control() + //@} + + /// For gettimeofday. + struct timeval { + uint32_t tv_sec; //!< seconds + uint32_t tv_usec; //!< microseconds + }; + + //@{ + /// For getrusage(). + static const int TGT_RUSAGE_THREAD = 1; + static const int TGT_RUSAGE_SELF = 0; + static const int TGT_RUSAGE_CHILDREN = -1; + //@} + + /// For getrusage(). + struct rusage { + struct timeval ru_utime; //!< user time used + struct timeval ru_stime; //!< system time used + uint64_t ru_maxrss; //!< ru_maxrss + uint64_t ru_ixrss; //!< integral shared memory size + uint64_t ru_idrss; //!< integral unshared data " + uint64_t ru_isrss; //!< integral unshared stack " + uint64_t ru_minflt; //!< page reclaims - total vmfaults + uint64_t ru_majflt; //!< page faults + uint64_t ru_nswap; //!< swaps + uint64_t ru_inblock; //!< block input operations + uint64_t ru_oublock; //!< block output operations + uint64_t ru_msgsnd; //!< messages sent + uint64_t ru_msgrcv; //!< messages received + uint64_t ru_nsignals; //!< signals received + uint64_t ru_nvcsw; //!< voluntary context switches + uint64_t ru_nivcsw; //!< involuntary " + }; + + /// For sigreturn(). + struct sigcontext { + int64_t sc_onstack; //!< sigstack state to restore + int64_t sc_mask; //!< signal mask to restore + int64_t sc_pc; //!< pc at time of signal + int64_t sc_ps; //!< psl to retore + int64_t sc_regs[32]; //!< processor regs 0 to 31 + int64_t sc_ownedfp; //!< fp has been used + int64_t sc_fpregs[32]; //!< fp regs 0 to 31 + uint64_t sc_fpcr; //!< floating point control reg + uint64_t sc_fp_control; //!< software fpcr + int64_t sc_reserved1; //!< reserved for kernel + uint32_t sc_kreserved1; //!< reserved for kernel + uint32_t sc_kreserved2; //!< reserved for kernel + size_t sc_ssize; //!< stack size + caddr_t sc_sbase; //!< stack start + uint64_t sc_traparg_a0; //!< a0 argument to trap on exc + uint64_t sc_traparg_a1; //!< a1 argument to trap on exc + uint64_t sc_traparg_a2; //!< a2 argument to trap on exc + uint64_t sc_fp_trap_pc; //!< imprecise pc + uint64_t sc_fp_trigger_sum; //!< Exception summary at trigg + uint64_t sc_fp_trigger_inst; //!< Instruction at trigger pc + }; + + + /// For table(). + static const int TBL_SYSINFO = 12; + + /// For table(). + struct tbl_sysinfo { + uint64_t si_user; //!< User time + uint64_t si_nice; //!< Nice time + uint64_t si_sys; //!< System time + uint64_t si_idle; //!< Idle time + uint64_t si_hz; //!< hz + uint64_t si_phz; //!< phz + uint64_t si_boottime; //!< Boot time in seconds + uint64_t wait; //!< Wait time + uint32_t si_max_procs; //!< rpb->rpb_numprocs + uint32_t pad; //!< padding + }; + + + /// For stack_create. + struct vm_stack { + // was void * + Addr address; //!< address hint + size_t rsize; //!< red zone size + size_t ysize; //!< yellow zone size + size_t gsize; //!< green zone size + size_t swap; //!< amount of swap to reserve + size_t incr; //!< growth increment + uint64_t align; //!< address alignment + uint64_t flags; //!< MAP_FIXED etc. + // was struct memalloc_attr * + Addr attr; //!< allocation policy + uint64_t reserved; //!< reserved + }; + + /// Return values for nxm calls. + enum { + KERN_NOT_RECEIVER = 7, + KERN_NOT_IN_SET = 12 + }; + + /// For nxm_task_init. + static const int NXM_TASK_INIT_VP = 2; //!< initial thread is VP + + /// Task attribute structure. + struct nxm_task_attr { + int64_t nxm_callback; //!< nxm_callback + unsigned int nxm_version; //!< nxm_version + unsigned short nxm_uniq_offset; //!< nxm_uniq_offset + unsigned short flags; //!< flags + int nxm_quantum; //!< nxm_quantum + int pad1; //!< pad1 + int64_t pad2; //!< pad2 + }; + + /// Signal set. + typedef uint64_t sigset_t; + + /// Thread state shared between user & kernel. + struct ushared_state { + sigset_t sigmask; //!< thread signal mask + sigset_t sig; //!< thread pending mask + // struct nxm_pth_state * + Addr pth_id; //!< out-of-line state + int flags; //!< shared flags +#define US_SIGSTACK 0x1 // thread called sigaltstack +#define US_ONSTACK 0x2 // thread is running on altstack +#define US_PROFILE 0x4 // thread called profil +#define US_SYSCALL 0x8 // thread in syscall +#define US_TRAP 0x10 // thread has trapped +#define US_YELLOW 0x20 // thread has mellowed yellow +#define US_YZONE 0x40 // thread has zoned out +#define US_FP_OWNED 0x80 // thread used floating point + + int cancel_state; //!< thread's cancelation state +#define US_CANCEL 0x1 // cancel pending +#define US_NOCANCEL 0X2 // synch cancel disabled +#define US_SYS_NOCANCEL 0x4 // syscall cancel disabled +#define US_ASYNC_NOCANCEL 0x8 // asynch cancel disabled +#define US_CANCEL_BITS (US_NOCANCEL|US_SYS_NOCANCEL|US_ASYNC_NOCANCEL) +#define US_CANCEL_MASK (US_CANCEL|US_NOCANCEL|US_SYS_NOCANCEL| \ + US_ASYNC_NOCANCEL) + + // These are semi-shared. They are always visible to + // the kernel but are never context-switched by the library. + + int nxm_ssig; //!< scheduler's synchronous signals + int reserved1; //!< reserved1 + int64_t nxm_active; //!< scheduler active + int64_t reserved2; //!< reserved2 + }; + + struct nxm_sched_state { + struct ushared_state nxm_u; //!< state own by user thread + unsigned int nxm_bits; //!< scheduler state / slot + int nxm_quantum; //!< quantum count-down value + int nxm_set_quantum; //!< quantum reset value + int nxm_sysevent; //!< syscall state + // struct nxm_upcall * + Addr nxm_uc_ret; //!< stack ptr of null thread + // void * + Addr nxm_tid; //!< scheduler's thread id + int64_t nxm_va; //!< page fault address + // struct nxm_pth_state * + Addr nxm_pthid; //!< id of null thread + uint64_t nxm_bound_pcs_count; //!< bound PCS thread count + int64_t pad[2]; //!< pad + }; + + /// nxm_shared. + struct nxm_shared { + int64_t nxm_callback; //!< address of upcall routine + unsigned int nxm_version; //!< version number + unsigned short nxm_uniq_offset; //!< correction factor for TEB + unsigned short pad1; //!< pad1 + int64_t space[2]; //!< future growth + struct nxm_sched_state nxm_ss[1]; //!< array of shared areas + }; + + /// nxm_slot_state_t. + enum nxm_slot_state_t { + NXM_SLOT_AVAIL, + NXM_SLOT_BOUND, + NXM_SLOT_UNBOUND, + NXM_SLOT_EMPTY + }; + + /// nxm_config_info + struct nxm_config_info { + int nxm_nslots_per_rad; //!< max number of VP slots per RAD + int nxm_nrads; //!< max number of RADs + // nxm_slot_state_t * + Addr nxm_slot_state; //!< per-VP slot state + // struct nxm_shared * + Addr nxm_rad[1]; //!< per-RAD shared areas + }; + + /// For nxm_thread_create. + enum nxm_thread_type { + NXM_TYPE_SCS = 0, + NXM_TYPE_VP = 1, + NXM_TYPE_MANAGER = 2 + }; + + /// Thread attributes. + struct nxm_thread_attr { + int version; //!< version + int type; //!< type + int cancel_flags; //!< cancel_flags + int priority; //!< priority + int policy; //!< policy + int signal_type; //!< signal_type + // void * + Addr pthid; //!< pthid + sigset_t sigmask; //!< sigmask + /// Initial register values. + struct { + uint64_t pc; //!< pc + uint64_t sp; //!< sp + uint64_t a0; //!< a0 + } registers; + uint64_t pad2[2]; //!< pad2 + }; + + /// Helper function to convert a host stat buffer to a target stat + /// buffer. Also copies the target buffer out to the simulated + /// memory space. Used by stat(), fstat(), and lstat(). + template + static void + copyOutStatBuf(FunctionalMemory *mem, Addr addr, global_stat *host) + { + TypedBufferArg tgt(addr); + + tgt->st_dev = htog(host->st_dev); + tgt->st_ino = htog(host->st_ino); + tgt->st_mode = htog(host->st_mode); + tgt->st_nlink = htog(host->st_nlink); + tgt->st_uid = htog(host->st_uid); + tgt->st_gid = htog(host->st_gid); + tgt->st_rdev = htog(host->st_rdev); + tgt->st_size = htog(host->st_size); + tgt->st_atimeX = htog(host->st_atime); + tgt->st_mtimeX = htog(host->st_mtime); + tgt->st_ctimeX = htog(host->st_ctime); + tgt->st_blksize = htog(host->st_blksize); + tgt->st_blocks = htog(host->st_blocks); + + tgt.copyOut(mem); + } + + /// Helper function to convert a host statfs buffer to a target statfs + /// buffer. Also copies the target buffer out to the simulated + /// memory space. Used by statfs() and fstatfs(). + template + static void + copyOutStatfsBuf(FunctionalMemory *mem, Addr addr, global_statfs *host) + { + TypedBufferArg tgt(addr); + +#if defined(__OpenBSD__) || defined(__APPLE__) || defined(__FreeBSD__) + tgt->f_type = 0; +#else + tgt->f_type = htog(host->f_type); +#endif + tgt->f_bsize = htog(host->f_bsize); + tgt->f_blocks = htog(host->f_blocks); + tgt->f_bfree = htog(host->f_bfree); + tgt->f_bavail = htog(host->f_bavail); + tgt->f_files = htog(host->f_files); + tgt->f_ffree = htog(host->f_ffree); + + // Is this as string normally? + memcpy(&tgt->f_fsid, &host->f_fsid, sizeof(host->f_fsid)); + + tgt.copyOut(mem); + } + + class F64 { + public: + static void copyOutStatBuf(FunctionalMemory *mem, Addr addr, + global_stat *host) + { + Tru64::copyOutStatBuf(mem, addr, host); + } + + static void copyOutStatfsBuf(FunctionalMemory *mem, Addr addr, + global_statfs *host) + { + Tru64::copyOutStatfsBuf(mem, addr, host); + } + }; + + class PreF64 { + public: + static void copyOutStatBuf(FunctionalMemory *mem, Addr addr, + global_stat *host) + { + Tru64::copyOutStatBuf(mem, addr, host); + } + + static void copyOutStatfsBuf(FunctionalMemory *mem, Addr addr, + global_statfs *host) + { + Tru64::copyOutStatfsBuf(mem, addr, host); + } + }; + + /// Helper function to convert a host stat buffer to an old pre-F64 + /// (4.x) target stat buffer. Also copies the target buffer out to + /// the simulated memory space. Used by pre_F64_stat(), + /// pre_F64_fstat(), and pre_F64_lstat(). + static void + copyOutPreF64StatBuf(FunctionalMemory *mem, Addr addr, struct stat *host) + { + TypedBufferArg tgt(addr); + + tgt->st_dev = htog(host->st_dev); + tgt->st_ino = htog(host->st_ino); + tgt->st_mode = htog(host->st_mode); + tgt->st_nlink = htog(host->st_nlink); + tgt->st_uid = htog(host->st_uid); + tgt->st_gid = htog(host->st_gid); + tgt->st_rdev = htog(host->st_rdev); + tgt->st_size = htog(host->st_size); + tgt->st_atimeX = htog(host->st_atime); + tgt->st_mtimeX = htog(host->st_mtime); + tgt->st_ctimeX = htog(host->st_ctime); + tgt->st_blksize = htog(host->st_blksize); + tgt->st_blocks = htog(host->st_blocks); + + tgt.copyOut(mem); + } + + + /// The target system's hostname. + static const char *hostname; + + + /// Target getdirentries() handler. + static SyscallReturn + getdirentriesFunc(SyscallDesc *desc, int callnum, Process *process, + ExecContext *xc) + { +#ifdef __CYGWIN__ + panic("getdirent not implemented on cygwin!"); +#else + int fd = process->sim_fd(xc->getSyscallArg(0)); + Addr tgt_buf = xc->getSyscallArg(1); + int tgt_nbytes = xc->getSyscallArg(2); + Addr tgt_basep = xc->getSyscallArg(3); + + char * const host_buf = new char[tgt_nbytes]; + + // just pass basep through uninterpreted. + TypedBufferArg basep(tgt_basep); + basep.copyIn(xc->mem); + long host_basep = (off_t)htog((int64_t)*basep); + int host_result = getdirentries(fd, host_buf, tgt_nbytes, &host_basep); + + // check for error + if (host_result < 0) { + delete [] host_buf; + return -errno; + } + + // no error: copy results back to target space + Addr tgt_buf_ptr = tgt_buf; + char *host_buf_ptr = host_buf; + char *host_buf_end = host_buf + host_result; + while (host_buf_ptr < host_buf_end) { + global_dirent *host_dp = (global_dirent *)host_buf_ptr; + int namelen = strlen(host_dp->d_name); + + // Actual size includes padded string rounded up for alignment. + // Subtract 256 for dummy char array in Tru64::dirent definition. + // Add 1 to namelen for terminating null char. + int tgt_bufsize = sizeof(Tru64::dirent) - 256 + roundUp(namelen+1, 8); + TypedBufferArg tgt_dp(tgt_buf_ptr, tgt_bufsize); + tgt_dp->d_ino = host_dp->d_ino; + tgt_dp->d_reclen = tgt_bufsize; + tgt_dp->d_namlen = namelen; + strcpy(tgt_dp->d_name, host_dp->d_name); + tgt_dp.copyOut(xc->mem); + + tgt_buf_ptr += tgt_bufsize; + host_buf_ptr += host_dp->d_reclen; + } + + delete [] host_buf; + + *basep = htog((int64_t)host_basep); + basep.copyOut(xc->mem); + + return tgt_buf_ptr - tgt_buf; +#endif + } + + /// Target sigreturn() handler. + static SyscallReturn + sigreturnFunc(SyscallDesc *desc, int callnum, Process *process, + ExecContext *xc) + { + RegFile *regs = &xc->regs; + TypedBufferArg sc(xc->getSyscallArg(0)); + + sc.copyIn(xc->mem); + + // Restore state from sigcontext structure. + // Note that we'll advance PC <- NPC before the end of the cycle, + // so we need to restore the desired PC into NPC. + // The current regs->pc will get clobbered. + regs->npc = htog(sc->sc_pc); + + for (int i = 0; i < 31; ++i) { + regs->intRegFile[i] = htog(sc->sc_regs[i]); + regs->floatRegFile.q[i] = htog(sc->sc_fpregs[i]); + } + + regs->miscRegs.fpcr = htog(sc->sc_fpcr); + + return 0; + } + + /// Target table() handler. + static SyscallReturn + tableFunc(SyscallDesc *desc, int callnum, Process *process, + ExecContext *xc) + { + int id = xc->getSyscallArg(0); // table ID + int index = xc->getSyscallArg(1); // index into table + // arg 2 is buffer pointer; type depends on table ID + int nel = xc->getSyscallArg(3); // number of elements + int lel = xc->getSyscallArg(4); // expected element size + + switch (id) { + case Tru64::TBL_SYSINFO: { + if (index != 0 || nel != 1 || lel != sizeof(Tru64::tbl_sysinfo)) + return -EINVAL; + TypedBufferArg elp(xc->getSyscallArg(2)); + + const int clk_hz = one_million; + elp->si_user = htog(curTick / (Clock::Frequency / clk_hz)); + elp->si_nice = htog(0); + elp->si_sys = htog(0); + elp->si_idle = htog(0); + elp->wait = htog(0); + elp->si_hz = htog(clk_hz); + elp->si_phz = htog(clk_hz); + elp->si_boottime = htog(seconds_since_epoch); // seconds since epoch? + elp->si_max_procs = htog(process->numCpus()); + elp.copyOut(xc->mem); + return 0; + } + + default: + cerr << "table(): id " << id << " unknown." << endl; + return -EINVAL; + } + } + + // + // Mach syscalls -- identified by negated syscall numbers + // + + /// Create a stack region for a thread. + static SyscallReturn + stack_createFunc(SyscallDesc *desc, int callnum, Process *process, + ExecContext *xc) + { + TypedBufferArg argp(xc->getSyscallArg(0)); + + argp.copyIn(xc->mem); + + // if the user chose an address, just let them have it. Otherwise + // pick one for them. + if (htog(argp->address) == 0) { + argp->address = htog(process->next_thread_stack_base); + int stack_size = (htog(argp->rsize) + htog(argp->ysize) + + htog(argp->gsize)); + process->next_thread_stack_base -= stack_size; + argp.copyOut(xc->mem); + } + + return 0; + } + + /// NXM library version stamp. + static + const int NXM_LIB_VERSION = 301003; + + /// This call sets up the interface between the user and kernel + /// schedulers by creating a shared-memory region. The shared memory + /// region has several structs, some global, some per-RAD, some per-VP. + static SyscallReturn + nxm_task_initFunc(SyscallDesc *desc, int callnum, Process *process, + ExecContext *xc) + { + TypedBufferArg attrp(xc->getSyscallArg(0)); + TypedBufferArg configptr_ptr(xc->getSyscallArg(1)); + + attrp.copyIn(xc->mem); + + if (gtoh(attrp->nxm_version) != NXM_LIB_VERSION) { + cerr << "nxm_task_init: thread library version mismatch! " + << "got " << attrp->nxm_version + << ", expected " << NXM_LIB_VERSION << endl; + abort(); + } + + if (gtoh(attrp->flags) != Tru64::NXM_TASK_INIT_VP) { + cerr << "nxm_task_init: bad flag value " << attrp->flags + << " (expected " << Tru64::NXM_TASK_INIT_VP << ")" << endl; + abort(); + } + + const Addr base_addr = 0x12000; // was 0x3f0000000LL; + Addr cur_addr = base_addr; // next addresses to use + // first comes the config_info struct + Addr config_addr = cur_addr; + cur_addr += sizeof(Tru64::nxm_config_info); + // next comes the per-cpu state vector + Addr slot_state_addr = cur_addr; + int slot_state_size = + process->numCpus() * sizeof(Tru64::nxm_slot_state_t); + cur_addr += slot_state_size; + // now the per-RAD state struct (we only support one RAD) + cur_addr = 0x14000; // bump up addr for alignment + Addr rad_state_addr = cur_addr; + int rad_state_size = + (sizeof(Tru64::nxm_shared) + + (process->numCpus()-1) * sizeof(Tru64::nxm_sched_state)); + cur_addr += rad_state_size; + + // now initialize a config_info struct and copy it out to user space + TypedBufferArg config(config_addr); + + config->nxm_nslots_per_rad = htog(process->numCpus()); + config->nxm_nrads = htog(1); // only one RAD in our system! + config->nxm_slot_state = htog(slot_state_addr); + config->nxm_rad[0] = htog(rad_state_addr); + + config.copyOut(xc->mem); + + // initialize the slot_state array and copy it out + TypedBufferArg slot_state(slot_state_addr, + slot_state_size); + for (int i = 0; i < process->numCpus(); ++i) { + // CPU 0 is bound to the calling process; all others are available + // XXX this code should have an endian conversion, but I don't think + // it works anyway + slot_state[i] = + (i == 0) ? Tru64::NXM_SLOT_BOUND : Tru64::NXM_SLOT_AVAIL; + } + + slot_state.copyOut(xc->mem); + + // same for the per-RAD "shared" struct. Note that we need to + // allocate extra bytes for the per-VP array which is embedded at + // the end. + TypedBufferArg rad_state(rad_state_addr, + rad_state_size); + + rad_state->nxm_callback = attrp->nxm_callback; + rad_state->nxm_version = attrp->nxm_version; + rad_state->nxm_uniq_offset = attrp->nxm_uniq_offset; + for (int i = 0; i < process->numCpus(); ++i) { + Tru64::nxm_sched_state *ssp = &rad_state->nxm_ss[i]; + ssp->nxm_u.sigmask = htog(0); + ssp->nxm_u.sig = htog(0); + ssp->nxm_u.flags = htog(0); + ssp->nxm_u.cancel_state = htog(0); + ssp->nxm_u.nxm_ssig = 0; + ssp->nxm_bits = htog(0); + ssp->nxm_quantum = attrp->nxm_quantum; + ssp->nxm_set_quantum = attrp->nxm_quantum; + ssp->nxm_sysevent = htog(0); + + if (i == 0) { + uint64_t uniq = xc->regs.miscRegs.uniq; + ssp->nxm_u.pth_id = htog(uniq + gtoh(attrp->nxm_uniq_offset)); + ssp->nxm_u.nxm_active = htog(uniq | 1); + } + else { + ssp->nxm_u.pth_id = htog(0); + ssp->nxm_u.nxm_active = htog(0); + } + } + + rad_state.copyOut(xc->mem); + + // + // copy pointer to shared config area out to user + // + *configptr_ptr = htog(config_addr); + configptr_ptr.copyOut(xc->mem); + + // Register this as a valid address range with the process + process->nxm_start = base_addr; + process->nxm_end = cur_addr; + + return 0; + } + + /// Initialize execution context. + static void + init_exec_context(ExecContext *ec, + Tru64::nxm_thread_attr *attrp, uint64_t uniq_val) + { + memset(&ec->regs, 0, sizeof(ec->regs)); + + ec->regs.intRegFile[ArgumentReg0] = gtoh(attrp->registers.a0); + ec->regs.intRegFile[27/*t12*/] = gtoh(attrp->registers.pc); + ec->regs.intRegFile[StackPointerReg] = gtoh(attrp->registers.sp); + ec->regs.miscRegs.uniq = uniq_val; + + ec->regs.pc = gtoh(attrp->registers.pc); + ec->regs.npc = gtoh(attrp->registers.pc) + sizeof(MachInst); + + ec->activate(); + } + + /// Create thread. + static SyscallReturn + nxm_thread_createFunc(SyscallDesc *desc, int callnum, Process *process, + ExecContext *xc) + { + TypedBufferArg attrp(xc->getSyscallArg(0)); + TypedBufferArg kidp(xc->getSyscallArg(1)); + int thread_index = xc->getSyscallArg(2); + + // get attribute args + attrp.copyIn(xc->mem); + + if (gtoh(attrp->version) != NXM_LIB_VERSION) { + cerr << "nxm_thread_create: thread library version mismatch! " + << "got " << attrp->version + << ", expected " << NXM_LIB_VERSION << endl; + abort(); + } + + if (thread_index < 0 | thread_index > process->numCpus()) { + cerr << "nxm_thread_create: bad thread index " << thread_index + << endl; + abort(); + } + + // On a real machine, the per-RAD shared structure is in + // shared memory, so both the user and kernel can get at it. + // We don't have that luxury, so we just copy it in and then + // back out again. + int rad_state_size = + (sizeof(Tru64::nxm_shared) + + (process->numCpus()-1) * sizeof(Tru64::nxm_sched_state)); + + TypedBufferArg rad_state(0x14000, + rad_state_size); + rad_state.copyIn(xc->mem); + + uint64_t uniq_val = gtoh(attrp->pthid) - gtoh(rad_state->nxm_uniq_offset); + + if (gtoh(attrp->type) == Tru64::NXM_TYPE_MANAGER) { + // DEC pthreads seems to always create one of these (in + // addition to N application threads), but we don't use it, + // so don't bother creating it. + + // This is supposed to be a port number. Make something up. + *kidp = htog(99); + kidp.copyOut(xc->mem); + + return 0; + } else if (gtoh(attrp->type) == Tru64::NXM_TYPE_VP) { + // A real "virtual processor" kernel thread. Need to fork + // this thread on another CPU. + Tru64::nxm_sched_state *ssp = &rad_state->nxm_ss[thread_index]; + + if (gtoh(ssp->nxm_u.nxm_active) != 0) + return (int) Tru64::KERN_NOT_RECEIVER; + + ssp->nxm_u.pth_id = attrp->pthid; + ssp->nxm_u.nxm_active = htog(uniq_val | 1); + + rad_state.copyOut(xc->mem); + + Addr slot_state_addr = 0x12000 + sizeof(Tru64::nxm_config_info); + int slot_state_size = + process->numCpus() * sizeof(Tru64::nxm_slot_state_t); + + TypedBufferArg + slot_state(slot_state_addr, + slot_state_size); + + slot_state.copyIn(xc->mem); + + if (slot_state[thread_index] != Tru64::NXM_SLOT_AVAIL) { + cerr << "nxm_thread_createFunc: requested VP slot " + << thread_index << " not available!" << endl; + fatal(""); + } + + // XXX This should have an endian conversion but I think this code + // doesn't work anyway + slot_state[thread_index] = Tru64::NXM_SLOT_BOUND; + + slot_state.copyOut(xc->mem); + + // Find a free simulator execution context. + for (int i = 0; i < process->numCpus(); ++i) { + ExecContext *xc = process->execContexts[i]; + + if (xc->status() == ExecContext::Unallocated) { + // inactive context... grab it + init_exec_context(xc, attrp, uniq_val); + + // This is supposed to be a port number, but we'll try + // and get away with just sticking the thread index + // here. + *kidp = htog(thread_index); + kidp.copyOut(xc->mem); + + return 0; + } + } + + // fell out of loop... no available inactive context + cerr << "nxm_thread_create: no idle contexts available." << endl; + abort(); + } else { + cerr << "nxm_thread_create: can't handle thread type " + << attrp->type << endl; + abort(); + } + + return 0; + } + + /// Thread idle call (like yield()). + static SyscallReturn + nxm_idleFunc(SyscallDesc *desc, int callnum, Process *process, + ExecContext *xc) + { + return 0; + } + + /// Block thread. + static SyscallReturn + nxm_thread_blockFunc(SyscallDesc *desc, int callnum, Process *process, + ExecContext *xc) + { + uint64_t tid = xc->getSyscallArg(0); + uint64_t secs = xc->getSyscallArg(1); + uint64_t flags = xc->getSyscallArg(2); + uint64_t action = xc->getSyscallArg(3); + uint64_t usecs = xc->getSyscallArg(4); + + cout << xc->cpu->name() << ": nxm_thread_block " << tid << " " << secs + << " " << flags << " " << action << " " << usecs << endl; + + return 0; + } + + /// block. + static SyscallReturn + nxm_blockFunc(SyscallDesc *desc, int callnum, Process *process, + ExecContext *xc) + { + Addr uaddr = xc->getSyscallArg(0); + uint64_t val = xc->getSyscallArg(1); + uint64_t secs = xc->getSyscallArg(2); + uint64_t usecs = xc->getSyscallArg(3); + uint64_t flags = xc->getSyscallArg(4); + + BaseCPU *cpu = xc->cpu; + + cout << cpu->name() << ": nxm_block " + << hex << uaddr << dec << " " << val + << " " << secs << " " << usecs + << " " << flags << endl; + + return 0; + } + + /// Unblock thread. + static SyscallReturn + nxm_unblockFunc(SyscallDesc *desc, int callnum, Process *process, + ExecContext *xc) + { + Addr uaddr = xc->getSyscallArg(0); + + cout << xc->cpu->name() << ": nxm_unblock " + << hex << uaddr << dec << endl; + + return 0; + } + + /// Switch thread priority. + static SyscallReturn + swtch_priFunc(SyscallDesc *desc, int callnum, Process *process, + ExecContext *xc) + { + // Attempts to switch to another runnable thread (if there is + // one). Returns false if there are no other threads to run + // (i.e., the thread can reasonably spin-wait) or true if there + // are other threads. + // + // Since we assume at most one "kernel" thread per CPU, it's + // always safe to return false here. + return 0; //false; + } + + + /// Activate exec context waiting on a channel. Just activate one + /// by default. + static int + activate_waiting_context(Addr uaddr, Process *process, + bool activate_all = false) + { + int num_activated = 0; + + list::iterator i = process->waitList.begin(); + list::iterator end = process->waitList.end(); + + while (i != end && (num_activated == 0 || activate_all)) { + if (i->waitChan == uaddr) { + // found waiting process: make it active + ExecContext *newCtx = i->waitingContext; + assert(newCtx->status() == ExecContext::Suspended); + newCtx->activate(); + + // get rid of this record + i = process->waitList.erase(i); + + ++num_activated; + } else { + ++i; + } + } + + return num_activated; + } + + /// M5 hacked-up lock acquire. + static void + m5_lock_mutex(Addr uaddr, Process *process, ExecContext *xc) + { + TypedBufferArg lockp(uaddr); + + lockp.copyIn(xc->mem); + + if (gtoh(*lockp) == 0) { + // lock is free: grab it + *lockp = htog(1); + lockp.copyOut(xc->mem); + } else { + // lock is busy: disable until free + process->waitList.push_back(Process::WaitRec(uaddr, xc)); + xc->suspend(); + } + } + + /// M5 unlock call. + static void + m5_unlock_mutex(Addr uaddr, Process *process, ExecContext *xc) + { + TypedBufferArg lockp(uaddr); + + lockp.copyIn(xc->mem); + assert(*lockp != 0); + + // Check for a process waiting on the lock. + int num_waiting = activate_waiting_context(uaddr, process); + + // clear lock field if no waiting context is taking over the lock + if (num_waiting == 0) { + *lockp = 0; + lockp.copyOut(xc->mem); + } + } + + /// Lock acquire syscall handler. + static SyscallReturn + m5_mutex_lockFunc(SyscallDesc *desc, int callnum, Process *process, + ExecContext *xc) + { + Addr uaddr = xc->getSyscallArg(0); + + m5_lock_mutex(uaddr, process, xc); + + // Return 0 since we will always return to the user with the lock + // acquired. We will just keep the context inactive until that is + // true. + return 0; + } + + /// Try lock (non-blocking). + static SyscallReturn + m5_mutex_trylockFunc(SyscallDesc *desc, int callnum, Process *process, + ExecContext *xc) + { + Addr uaddr = xc->getSyscallArg(0); + TypedBufferArg lockp(uaddr); + + lockp.copyIn(xc->mem); + + if (gtoh(*lockp) == 0) { + // lock is free: grab it + *lockp = htog(1); + lockp.copyOut(xc->mem); + return 0; + } else { + return 1; + } + } + + /// Unlock syscall handler. + static SyscallReturn + m5_mutex_unlockFunc(SyscallDesc *desc, int callnum, Process *process, + ExecContext *xc) + { + Addr uaddr = xc->getSyscallArg(0); + + m5_unlock_mutex(uaddr, process, xc); + + return 0; + } + + /// Signal ocndition. + static SyscallReturn + m5_cond_signalFunc(SyscallDesc *desc, int callnum, Process *process, + ExecContext *xc) + { + Addr cond_addr = xc->getSyscallArg(0); + + // Wake up one process waiting on the condition variable. + activate_waiting_context(cond_addr, process); + + return 0; + } + + /// Wake up all processes waiting on the condition variable. + static SyscallReturn + m5_cond_broadcastFunc(SyscallDesc *desc, int callnum, Process *process, + ExecContext *xc) + { + Addr cond_addr = xc->getSyscallArg(0); + + activate_waiting_context(cond_addr, process, true); + + return 0; + } + + /// Wait on a condition. + static SyscallReturn + m5_cond_waitFunc(SyscallDesc *desc, int callnum, Process *process, + ExecContext *xc) + { + Addr cond_addr = xc->getSyscallArg(0); + Addr lock_addr = xc->getSyscallArg(1); + TypedBufferArg condp(cond_addr); + TypedBufferArg lockp(lock_addr); + + // user is supposed to acquire lock before entering + lockp.copyIn(xc->mem); + assert(gtoh(*lockp) != 0); + + m5_unlock_mutex(lock_addr, process, xc); + + process->waitList.push_back(Process::WaitRec(cond_addr, xc)); + xc->suspend(); + + return 0; + } + + /// Thread exit. + static SyscallReturn + m5_thread_exitFunc(SyscallDesc *desc, int callnum, Process *process, + ExecContext *xc) + { + assert(xc->status() == ExecContext::Active); + xc->deallocate(); + + return 0; + } + + /// Indirect syscall invocation (call #0). + static SyscallReturn + indirectSyscallFunc(SyscallDesc *desc, int callnum, Process *process, + ExecContext *xc) + { + int new_callnum = xc->getSyscallArg(0); + LiveProcess *lp = dynamic_cast(process); + assert(lp); + + for (int i = 0; i < 5; ++i) + xc->setSyscallArg(i, xc->getSyscallArg(i+1)); + + + SyscallDesc *new_desc = lp->getDesc(new_callnum); + if (desc == NULL) + fatal("Syscall %d out of range", callnum); + + new_desc->doSyscall(new_callnum, process, xc); + + return 0; + } + +}; // class Tru64 + + +#endif // FULL_SYSTEM + #endif // __TRU64_HH__ diff --git a/sim/process.cc b/sim/process.cc index 59d122b48..3ae3abb52 100644 --- a/sim/process.cc +++ b/sim/process.cc @@ -46,6 +46,7 @@ #include "sim/fake_syscall.hh" #include "sim/process.hh" #include "sim/stats.hh" +#include "sim/syscall_emul.hh" #ifdef TARGET_ALPHA #include "arch/alpha/alpha_tru64_process.hh" @@ -350,6 +351,19 @@ LiveProcess::LiveProcess(const string &nm, ObjectFile *objFile, init_regs->npc = prog_entry + sizeof(MachInst); } +void +LiveProcess::syscall(ExecContext *xc) +{ + num_syscalls++; + + int64_t callnum = xc->regs.intRegFile[ReturnValueReg]; + + SyscallDesc *desc = getDesc(callnum); + if (desc == NULL) + fatal("Syscall %d out of range", callnum); + + desc->doSyscall(callnum, this, xc); +} LiveProcess * LiveProcess::create(const string &nm, @@ -394,6 +408,7 @@ LiveProcess::create(const string &nm, } + BEGIN_DECLARE_SIM_OBJECT_PARAMS(LiveProcess) VectorParam cmd; diff --git a/sim/process.hh b/sim/process.hh index 43fafd9d7..40143ea04 100644 --- a/sim/process.hh +++ b/sim/process.hh @@ -48,6 +48,7 @@ class ExecContext; class FunctionalMemory; +class SyscallDesc; class Process : public SimObject { public: @@ -200,6 +201,11 @@ class LiveProcess : public Process std::string executable, std::vector &argv, std::vector &envp); + + virtual void syscall(ExecContext *xc); + + virtual SyscallDesc* getDesc(int callnum) { panic("Must be implemented."); } + }; diff --git a/sim/syscall_emul.cc b/sim/syscall_emul.cc index 4b6388a41..a46e991b9 100644 --- a/sim/syscall_emul.cc +++ b/sim/syscall_emul.cc @@ -26,6 +26,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include #include #include @@ -278,3 +279,48 @@ fchownFunc(SyscallDesc *desc, int num, Process *process, ExecContext *xc) int result = fchown(fd, hostOwner, hostGroup); return (result == -1) ? -errno : result; } + + +SyscallReturn +fcntlFunc(SyscallDesc *desc, int num, Process *process, + ExecContext *xc) +{ + int fd = xc->getSyscallArg(0); + + if (fd < 0 || process->sim_fd(fd) < 0) + return -EBADF; + + int cmd = xc->getSyscallArg(1); + switch (cmd) { + case 0: // F_DUPFD + // if we really wanted to support this, we'd need to do it + // in the target fd space. + warn("fcntl(%d, F_DUPFD) not supported, error returned\n", fd); + return -EMFILE; + + case 1: // F_GETFD (get close-on-exec flag) + case 2: // F_SETFD (set close-on-exec flag) + return 0; + + case 3: // F_GETFL (get file flags) + case 4: // F_SETFL (set file flags) + // not sure if this is totally valid, but we'll pass it through + // to the underlying OS + warn("fcntl(%d, %d) passed through to host\n", fd, cmd); + return fcntl(process->sim_fd(fd), cmd); + // return 0; + + case 7: // F_GETLK (get lock) + case 8: // F_SETLK (set lock) + case 9: // F_SETLKW (set lock and wait) + // don't mess with file locking... just act like it's OK + warn("File lock call (fcntl(%d, %d)) ignored.\n", fd, cmd); + return 0; + + default: + warn("Unknown fcntl command %d\n", cmd); + return 0; + } +} + + diff --git a/sim/syscall_emul.hh b/sim/syscall_emul.hh index d8029ddb0..fd5c7b6e6 100644 --- a/sim/syscall_emul.hh +++ b/sim/syscall_emul.hh @@ -239,6 +239,10 @@ SyscallReturn chownFunc(SyscallDesc *desc, int num, SyscallReturn fchownFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc); +/// Target fnctl() handler. +SyscallReturn fcntlFunc(SyscallDesc *desc, int num, + Process *process, ExecContext *xc); + /// This struct is used to build an target-OS-dependent table that /// maps the target's open() flags to the host open() flags. struct OpenFlagTransTable { From 00d58aeb4dc0569bc3d1273d90867148e6500ad9 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Sun, 19 Feb 2006 00:28:53 -0500 Subject: [PATCH 070/180] forgot a negative sign --HG-- extra : convert_revision : 9cdb00198979fca831d3e6840f9c534671ccead3 --- arch/alpha/alpha_tru64_process.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/alpha/alpha_tru64_process.cc b/arch/alpha/alpha_tru64_process.cc index 90f01637d..e6624305c 100644 --- a/arch/alpha/alpha_tru64_process.cc +++ b/arch/alpha/alpha_tru64_process.cc @@ -519,7 +519,7 @@ SyscallDesc AlphaTru64Process::machSyscallDescs[] = { SyscallDesc* AlphaTru64Process::getDesc(int callnum) { - if (callnum < Num_Mach_Syscall_Descs || callnum > Num_Syscall_Descs) + if (callnum < -Num_Mach_Syscall_Descs || callnum > Num_Syscall_Descs) return NULL; if (callnum < 0) From 463aa6d49d49ba9c383f07207df57bad75c58ec9 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 19 Feb 2006 02:34:37 -0500 Subject: [PATCH 071/180] Changes to untemplate StaticInst and StaticInstPtr, change the isa to a namespace instead of a class, an improvement to the architecture specific header file selection system, and fixed up a few include paths. arch/alpha/alpha_linux_process.cc: Added using directive for AlphaISA namespace arch/alpha/alpha_memory.hh: arch/alpha/isa/branch.isa: cpu/pc_event.hh: Added typedefs for Addr arch/alpha/alpha_tru64_process.cc: arch/alpha/arguments.cc: Added using directive for AlphaISA arch/alpha/ev5.hh: Added an include of arch/alpha/isa_traits.hh, and a using directive for the AlphaISA namespace. arch/alpha/faults.hh: Added a typedef for the Addr type, and changed the formatting of the faults slightly. arch/alpha/isa/main.isa: Untemplatized StaticInst, added a using for namespace AlphaISA to show up in decoder.cc and the exec.ccs, relocated makeNop to decoder.hh arch/alpha/isa/mem.isa: Untemplatized StaticInst and StaticInstPtr arch/alpha/isa/pal.isa: cpu/base_dyn_inst.cc: Untemplatized StaticInstPtr arch/alpha/isa_traits.hh: Changed variables to be externs instead of static since they are part of a namespace and not a class. arch/alpha/stacktrace.cc: Untemplatized StaticInstPtr, and added a using directive for AlphaISA. arch/alpha/stacktrace.hh: Added some typedefs for Addr and MachInst, and untemplatized StaticInstPtr arch/alpha/vtophys.cc: Added a using directive for AlphaISA arch/alpha/vtophys.hh: Added the AlphaISA namespace specifier where needed arch/isa_parser.py: Changed the placement of the definition of the decodeInst function to be outside the namespaceInst namespace. base/loader/object_file.hh: cpu/o3/bpred_unit.hh: Added a typedef for Addr base/loader/symtab.hh: Added a typedef for Addr, and added a TheISA to Addr in another typedef base/remote_gdb.cc: Added a using namespace TheISA, and untemplatized StaticInstPtr base/remote_gdb.hh: Added typedefs for Addr and MachInst cpu/base.cc: Added TheISA specifier to some variables exported from the isa. cpu/base.hh: Added a typedef for Addr, and TheISA to some variables from the ISA cpu/base_dyn_inst.hh: Untemplatized StaticInstPtr, and added TheISA specifier to some variables from the ISA. cpu/exec_context.hh: Added some typedefs for types from the isa, and added TheISA specifier to some variables from the isa cpu/exetrace.hh: Added typedefs for some types from the ISA, and untemplatized StaticInstPtr cpu/memtest/memtest.cc: cpu/o3/btb.cc: dev/baddev.cc: dev/ide_ctrl.cc: dev/ide_disk.cc: dev/isa_fake.cc: dev/ns_gige.cc: dev/pciconfigall.cc: dev/platform.cc: dev/sinic.cc: dev/uart8250.cc: kern/freebsd/freebsd_system.cc: kern/linux/linux_system.cc: kern/system_events.cc: kern/tru64/dump_mbuf.cc: kern/tru64/tru64_events.cc: sim/process.cc: sim/pseudo_inst.cc: sim/system.cc: Added using namespace TheISA cpu/memtest/memtest.hh: cpu/trace/opt_cpu.hh: cpu/trace/reader/itx_reader.hh: dev/ide_disk.hh: dev/pcidev.hh: dev/platform.hh: dev/tsunami.hh: sim/system.hh: sim/vptr.hh: Added typedef for Addr cpu/o3/2bit_local_pred.hh: Changed the include to use arch/isa_traits.hh instead of arch/alpha/isa_traits.hh. Added typedef for Addr cpu/o3/alpha_cpu.hh: Added typedefs for Addr and IntReg cpu/o3/alpha_cpu_impl.hh: Added this-> to setNextPC to fix a problem since it didn't depend on template parameters any more. Removed "typename" where it was no longer needed. cpu/o3/alpha_dyn_inst.hh: Cleaned up some typedefs, and untemplatized StaticInst cpu/o3/alpha_dyn_inst_impl.hh: untemplatized StaticInstPtr cpu/o3/alpha_impl.hh: Fixed up a typedef of MachInst cpu/o3/bpred_unit_impl.hh: Added a using TheISA::MachInst to a function cpu/o3/btb.hh: Changed an include from arch/alpha/isa_traits.hh to arch/isa_traits.hh, and added a typedef for Addr cpu/o3/commit.hh: Removed a typedef of Impl::ISA as ISA, since TheISA takes care of this now. cpu/o3/cpu.cc: Cleaned up namespace issues cpu/o3/cpu.hh: Cleaned up namespace usage cpu/o3/decode.hh: Removed typedef of ISA, and changed it to TheISA cpu/o3/fetch.hh: Fized up typedefs, and changed ISA to TheISA cpu/o3/free_list.hh: Changed include of arch/alpha/isa_traits.hh to arch/isa_traits.hh cpu/o3/iew.hh: Removed typedef of ISA cpu/o3/iew_impl.hh: Added TheISA namespace specifier to MachInst cpu/o3/ras.hh: Changed include from arch/alpha/isa_traits.hh to arch/isa_traits.hh, and added a typedef for Addr. cpu/o3/regfile.hh: Changed ISA to TheISA, and added some typedefs for Addr, IntReg, FloatReg, and MiscRegFile cpu/o3/rename.hh: Changed ISA to TheISA, and added a typedef for RegIndex cpu/o3/rename_map.hh: Added an include for arch/isa_traits.hh, and a typedef for RegIndex cpu/o3/rob.hh: Added a typedef for RegIndex cpu/o3/store_set.hh: cpu/o3/tournament_pred.hh: Changed an include of arch/alpha/isa_traits.hh to arch/isa_traits.hh, and added a typedef of Addr cpu/ozone/cpu.hh: Changed ISA into TheISA, and untemplatized StaticInst cpu/pc_event.cc: Added namespace specifier TheISA to Addr types cpu/profile.hh: kern/kernel_stats.hh: Added typedef for Addr, and untemplatized StaticInstPtr cpu/simple/cpu.cc: Changed using directive from LittleEndianGuest to AlphaISA, which will contain both namespaces. Added TheISA where needed, and untemplatized StaticInst cpu/simple/cpu.hh: Added a typedef for MachInst, and untemplatized StaticInst cpu/static_inst.cc: Untemplatized StaticInst cpu/static_inst.hh: Untemplatized StaticInst by using the TheISA namespace dev/alpha_console.cc: Added using namespace AlphaISA dev/simple_disk.hh: Added typedef for Addr and fixed up some formatting dev/sinicreg.hh: Added TheISA namespace specifier where needed dev/tsunami.cc: dev/tsunami_io.cc: dev/tsunami_pchip.cc: Added using namespace TheISA. It might be better for it to be AlphaISA dev/tsunami_cchip.cc: Added typedef for TheISA. It might be better for it to be AlphaISA kern/linux/aligned.hh: sim/pseudo_inst.hh: Added TheISA namespace specifier to Addr kern/linux/linux_threadinfo.hh: Added typedef for Addr, and TheISA namespace specifier to StackPointerReg kern/tru64/mbuf.hh: Added TheISA to Addr type in structs sim/process.hh: Added typedefs of Addr, RegFile, and MachInst sim/syscall_emul.cc: Added using namespace TheISA, and a cast of VMPageSize to the int type sim/syscall_emul.hh: Added typecast for Addr, and TheISA namespace specifier for where needed --HG-- extra : convert_revision : 91d4f6ca33a73b21c1f1771d74bfdea3b80eff45 --- arch/alpha/alpha_linux_process.cc | 1 + arch/alpha/alpha_memory.hh | 2 + arch/alpha/alpha_tru64_process.cc | 1 + arch/alpha/arguments.cc | 2 + arch/alpha/ev5.hh | 4 + arch/alpha/faults.hh | 14 +- arch/alpha/isa/branch.isa | 8 +- arch/alpha/isa/main.isa | 30 ++-- arch/alpha/isa/mem.isa | 20 +-- arch/alpha/isa/pal.isa | 8 +- arch/alpha/isa_traits.hh | 95 +++++----- arch/alpha/stacktrace.cc | 3 +- arch/alpha/stacktrace.hh | 11 +- arch/alpha/vtophys.cc | 1 + arch/alpha/vtophys.hh | 16 +- arch/isa_parser.py | 9 +- base/loader/object_file.hh | 1 + base/loader/symtab.hh | 3 +- base/remote_gdb.cc | 3 +- base/remote_gdb.hh | 3 + cpu/base.cc | 10 +- cpu/base.hh | 5 +- cpu/base_dyn_inst.cc | 2 +- cpu/base_dyn_inst.hh | 20 +-- cpu/exec_context.hh | 20 ++- cpu/exetrace.hh | 10 +- cpu/memtest/memtest.cc | 1 + cpu/memtest/memtest.hh | 2 + cpu/o3/2bit_local_pred.hh | 4 +- cpu/o3/alpha_cpu.hh | 4 +- cpu/o3/alpha_cpu_impl.hh | 4 +- cpu/o3/alpha_dyn_inst.hh | 33 ++-- cpu/o3/alpha_dyn_inst_impl.hh | 2 +- cpu/o3/alpha_impl.hh | 5 +- cpu/o3/bpred_unit.hh | 2 + cpu/o3/bpred_unit_impl.hh | 2 + cpu/o3/btb.cc | 2 + cpu/o3/btb.hh | 4 +- cpu/o3/commit.hh | 1 - cpu/o3/cpu.cc | 18 +- cpu/o3/cpu.hh | 5 +- cpu/o3/decode.hh | 3 +- cpu/o3/fetch.hh | 6 +- cpu/o3/free_list.hh | 2 +- cpu/o3/iew.hh | 1 - cpu/o3/iew_impl.hh | 2 +- cpu/o3/ras.hh | 4 +- cpu/o3/regfile.hh | 288 +++++++++++++++--------------- cpu/o3/rename.hh | 4 +- cpu/o3/rename_map.hh | 4 + cpu/o3/rob.hh | 2 + cpu/o3/store_set.hh | 4 +- cpu/o3/tournament_pred.hh | 4 +- cpu/ozone/cpu.hh | 25 ++- cpu/pc_event.cc | 4 +- cpu/pc_event.hh | 3 + cpu/profile.hh | 8 +- cpu/simple/cpu.cc | 34 ++-- cpu/simple/cpu.hh | 20 ++- cpu/static_inst.cc | 22 +-- cpu/static_inst.hh | 92 +++++----- cpu/trace/opt_cpu.hh | 2 + cpu/trace/reader/itx_reader.hh | 3 + dev/alpha_console.cc | 1 + dev/baddev.cc | 1 + dev/ide_ctrl.cc | 1 + dev/ide_disk.cc | 1 + dev/ide_disk.hh | 2 + dev/isa_fake.cc | 1 + dev/ns_gige.cc | 1 + dev/pciconfigall.cc | 1 + dev/pcidev.hh | 2 + dev/platform.cc | 1 + dev/platform.hh | 2 + dev/simple_disk.hh | 22 +-- dev/sinic.cc | 1 + dev/sinicreg.hh | 4 +- dev/tsunami.cc | 2 + dev/tsunami.hh | 2 + dev/tsunami_cchip.cc | 2 + dev/tsunami_io.cc | 2 + dev/tsunami_pchip.cc | 2 + dev/uart8250.cc | 1 + kern/freebsd/freebsd_system.cc | 1 + kern/kernel_stats.hh | 7 +- kern/linux/aligned.hh | 2 +- kern/linux/linux_system.cc | 1 + kern/linux/linux_threadinfo.hh | 4 +- kern/system_events.cc | 2 + kern/tru64/dump_mbuf.cc | 2 + kern/tru64/mbuf.hh | 22 +-- kern/tru64/tru64_events.cc | 2 + sim/process.cc | 1 + sim/process.hh | 4 + sim/pseudo_inst.cc | 1 + sim/pseudo_inst.hh | 4 +- sim/syscall_emul.cc | 3 +- sim/syscall_emul.hh | 7 +- sim/system.cc | 1 + sim/system.hh | 2 + sim/vptr.hh | 2 + 101 files changed, 586 insertions(+), 462 deletions(-) diff --git a/arch/alpha/alpha_linux_process.cc b/arch/alpha/alpha_linux_process.cc index fb5e32e63..af4df7c30 100644 --- a/arch/alpha/alpha_linux_process.cc +++ b/arch/alpha/alpha_linux_process.cc @@ -52,6 +52,7 @@ #include "base/trace.hh" using namespace std; +using namespace AlphaISA; /// /// This class encapsulates the types, structures, constants, diff --git a/arch/alpha/alpha_memory.hh b/arch/alpha/alpha_memory.hh index 849063f59..b39a1ef26 100644 --- a/arch/alpha/alpha_memory.hh +++ b/arch/alpha/alpha_memory.hh @@ -42,6 +42,7 @@ class ExecContext; class AlphaTLB : public SimObject { protected: + typedef TheISA::Addr Addr; typedef std::multimap PageTable; PageTable lookupTable; // Quick lookup into page table @@ -82,6 +83,7 @@ class AlphaTLB : public SimObject class AlphaITB : public AlphaTLB { protected: + typedef TheISA::Addr Addr; mutable Stats::Scalar<> hits; mutable Stats::Scalar<> misses; mutable Stats::Scalar<> acv; diff --git a/arch/alpha/alpha_tru64_process.cc b/arch/alpha/alpha_tru64_process.cc index 5c24adad9..49e672203 100644 --- a/arch/alpha/alpha_tru64_process.cc +++ b/arch/alpha/alpha_tru64_process.cc @@ -55,6 +55,7 @@ #include "sim/syscall_emul.hh" using namespace std; +using namespace AlphaISA; typedef struct stat global_stat; typedef struct statfs global_statfs; diff --git a/arch/alpha/arguments.cc b/arch/alpha/arguments.cc index a340a2053..4e8190cbc 100644 --- a/arch/alpha/arguments.cc +++ b/arch/alpha/arguments.cc @@ -31,6 +31,8 @@ #include "cpu/exec_context.hh" #include "mem/functional/physical.hh" +using namespace AlphaISA; + AlphaArguments::Data::~Data() { while (!data.empty()) { diff --git a/arch/alpha/ev5.hh b/arch/alpha/ev5.hh index 5173b364f..7c8465cfb 100644 --- a/arch/alpha/ev5.hh +++ b/arch/alpha/ev5.hh @@ -30,9 +30,13 @@ #define __ARCH_ALPHA_EV5_HH__ #include "config/alpha_tlaser.hh" +#include "arch/alpha/isa_traits.hh" namespace EV5 { +//It seems like a safe assumption EV5 only applies to alpha +using namespace AlphaISA; + #if ALPHA_TLASER const uint64_t AsnMask = ULL(0x7f); #else diff --git a/arch/alpha/faults.hh b/arch/alpha/faults.hh index 2bb929a1e..8c281593a 100644 --- a/arch/alpha/faults.hh +++ b/arch/alpha/faults.hh @@ -34,15 +34,21 @@ class AlphaFault : public Fault { -public: - AlphaFault(char * newName, int newId, Addr newVect) : Fault(newName, newId), vect(newVect) {;} - TheISA::Addr vect; + protected: + typedef TheISA::Addr Addr; + public: + AlphaFault(char * newName, int newId, Addr newVect) : + Fault(newName, newId), vect(newVect) + {;} + Addr vect; }; extern class ResetFaultType : public AlphaFault { public: - ResetFaultType(char * newName, int newId, Addr newVect) : AlphaFault(newName, newId, newVect) {;} + ResetFaultType(char * newName, int newId, Addr newVect) : + AlphaFault(newName, newId, newVect) + {;} } * ResetFault; extern class ArithmeticFaultType : public AlphaFault diff --git a/arch/alpha/isa/branch.isa b/arch/alpha/isa/branch.isa index e9c790c53..cc6fd1a09 100644 --- a/arch/alpha/isa/branch.isa +++ b/arch/alpha/isa/branch.isa @@ -39,6 +39,8 @@ output header {{ */ class PCDependentDisassembly : public AlphaStaticInst { + protected: + typedef TheISA::Addr Addr; protected: /// Cached program counter from last disassembly mutable Addr cachedPC; @@ -64,6 +66,7 @@ output header {{ class Branch : public PCDependentDisassembly { protected: + typedef TheISA::Addr Addr; /// Displacement to target address (signed). int32_t disp; @@ -87,6 +90,7 @@ output header {{ class Jump : public PCDependentDisassembly { protected: + typedef TheISA::Addr Addr; /// Displacement to target address (signed). int32_t disp; @@ -205,8 +209,8 @@ output decoder {{ def template JumpOrBranchDecode {{ return (RA == 31) - ? (StaticInst *)new %(class_name)s(machInst) - : (StaticInst *)new %(class_name)sAndLink(machInst); + ? (StaticInst *)new %(class_name)s(machInst) + : (StaticInst *)new %(class_name)sAndLink(machInst); }}; def format CondBranch(code) {{ diff --git a/arch/alpha/isa/main.isa b/arch/alpha/isa/main.isa index 42fb29404..862b2b95e 100644 --- a/arch/alpha/isa/main.isa +++ b/arch/alpha/isa/main.isa @@ -45,6 +45,8 @@ output decoder {{ #include "cpu/exec_context.hh" // for Jump::branchTarget() #include + +using namespace AlphaISA; }}; output exec {{ @@ -58,6 +60,8 @@ output exec {{ #include "cpu/base.hh" #include "cpu/exetrace.hh" #include "sim/sim_exit.hh" + +using namespace AlphaISA; }}; //////////////////////////////////////////////////////////////////// @@ -179,7 +183,7 @@ output header {{ /** * Base class for all Alpha static instructions. */ - class AlphaStaticInst : public StaticInst + class AlphaStaticInst : public StaticInst { protected: @@ -196,7 +200,7 @@ output header {{ /// Constructor. AlphaStaticInst(const char *mnem, MachInst _machInst, OpClass __opClass) - : StaticInst(mnem, _machInst, __opClass) + : StaticInst(mnem, _machInst, __opClass) { } @@ -352,6 +356,17 @@ output header {{ %(BasicExecDeclare)s }; + + /// Helper function for decoding nops. Substitute Nop object + /// for original inst passed in as arg (and delete latter). + static inline + AlphaStaticInst * + makeNop(AlphaStaticInst *inst) + { + AlphaStaticInst *nop = new Nop(inst->disassemble(0), inst->machInst); + delete inst; + return nop; + } }}; output decoder {{ @@ -364,17 +379,6 @@ output decoder {{ return csprintf("%-10s (%s)", "nop", originalDisassembly); #endif } - - /// Helper function for decoding nops. Substitute Nop object - /// for original inst passed in as arg (and delete latter). - inline - AlphaStaticInst * - makeNop(AlphaStaticInst *inst) - { - AlphaStaticInst *nop = new Nop(inst->disassemble(0), inst->machInst); - delete inst; - return nop; - } }}; output exec {{ diff --git a/arch/alpha/isa/mem.isa b/arch/alpha/isa/mem.isa index 0b79bc376..c72806263 100644 --- a/arch/alpha/isa/mem.isa +++ b/arch/alpha/isa/mem.isa @@ -37,14 +37,14 @@ output header {{ /// Memory request flags. See mem_req_base.hh. unsigned memAccessFlags; /// Pointer to EAComp object. - const StaticInstPtr eaCompPtr; + const StaticInstPtr eaCompPtr; /// Pointer to MemAcc object. - const StaticInstPtr memAccPtr; + const StaticInstPtr memAccPtr; /// Constructor Memory(const char *mnem, MachInst _machInst, OpClass __opClass, - StaticInstPtr _eaCompPtr = nullStaticInstPtr, - StaticInstPtr _memAccPtr = nullStaticInstPtr) + StaticInstPtr _eaCompPtr = nullStaticInstPtr, + StaticInstPtr _memAccPtr = nullStaticInstPtr) : AlphaStaticInst(mnem, _machInst, __opClass), memAccessFlags(0), eaCompPtr(_eaCompPtr), memAccPtr(_memAccPtr) { @@ -55,8 +55,8 @@ output header {{ public: - const StaticInstPtr &eaCompInst() const { return eaCompPtr; } - const StaticInstPtr &memAccInst() const { return memAccPtr; } + const StaticInstPtr &eaCompInst() const { return eaCompPtr; } + const StaticInstPtr &memAccInst() const { return memAccPtr; } }; /** @@ -71,8 +71,8 @@ output header {{ /// Constructor. MemoryDisp32(const char *mnem, MachInst _machInst, OpClass __opClass, - StaticInstPtr _eaCompPtr = nullStaticInstPtr, - StaticInstPtr _memAccPtr = nullStaticInstPtr) + StaticInstPtr _eaCompPtr = nullStaticInstPtr, + StaticInstPtr _memAccPtr = nullStaticInstPtr) : Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr), disp(MEMDISP) { @@ -90,8 +90,8 @@ output header {{ protected: /// Constructor MemoryNoDisp(const char *mnem, MachInst _machInst, OpClass __opClass, - StaticInstPtr _eaCompPtr = nullStaticInstPtr, - StaticInstPtr _memAccPtr = nullStaticInstPtr) + StaticInstPtr _eaCompPtr = nullStaticInstPtr, + StaticInstPtr _memAccPtr = nullStaticInstPtr) : Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr) { } diff --git a/arch/alpha/isa/pal.isa b/arch/alpha/isa/pal.isa index b68a7c19f..49e5bff12 100644 --- a/arch/alpha/isa/pal.isa +++ b/arch/alpha/isa/pal.isa @@ -149,8 +149,8 @@ output header {{ /// Constructor HwLoadStore(const char *mnem, MachInst _machInst, OpClass __opClass, - StaticInstPtr _eaCompPtr = nullStaticInstPtr, - StaticInstPtr _memAccPtr = nullStaticInstPtr); + StaticInstPtr _eaCompPtr = nullStaticInstPtr, + StaticInstPtr _memAccPtr = nullStaticInstPtr); std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; @@ -162,8 +162,8 @@ output decoder {{ inline HwLoadStore::HwLoadStore(const char *mnem, MachInst _machInst, OpClass __opClass, - StaticInstPtr _eaCompPtr, - StaticInstPtr _memAccPtr) + StaticInstPtr _eaCompPtr, + StaticInstPtr _memAccPtr) : Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr), disp(HW_LDST_DISP) { diff --git a/arch/alpha/isa_traits.hh b/arch/alpha/isa_traits.hh index a6e34acbb..2da37b2e0 100644 --- a/arch/alpha/isa_traits.hh +++ b/arch/alpha/isa_traits.hh @@ -44,17 +44,16 @@ class Checkpoint; #define TARGET_ALPHA -template class StaticInst; -template class StaticInstPtr; +class StaticInst; +class StaticInstPtr; namespace EV5 { int DTB_ASN_ASN(uint64_t reg); int ITB_ASN_ASN(uint64_t reg); } -class AlphaISA +namespace AlphaISA { - public: typedef uint32_t MachInst; typedef uint64_t Addr; @@ -133,10 +132,10 @@ class AlphaISA Addr lock_addr; // lock address for LL/SC } MiscRegFile; -static const Addr PageShift = 13; -static const Addr PageBytes = ULL(1) << PageShift; -static const Addr PageMask = ~(PageBytes - 1); -static const Addr PageOffset = PageBytes - 1; +extern const Addr PageShift; +extern const Addr PageBytes; +extern const Addr PageMask; +extern const Addr PageOffset; #if FULL_SYSTEM @@ -184,10 +183,10 @@ static const Addr PageOffset = PageBytes - 1; void unserialize(Checkpoint *cp, const std::string §ion); }; - static StaticInstPtr decodeInst(MachInst); + StaticInstPtr decodeInst(MachInst); // return a no-op instruction... used for instruction fetch faults - static const MachInst NoopMachInst; + extern const MachInst NoopMachInst; enum annotes { ANNOTE_NONE = 0, @@ -242,10 +241,10 @@ static const Addr PageOffset = PageBytes - 1; // Machine operations - static void saveMachineReg(AnyReg &savereg, const RegFile ®_file, + void saveMachineReg(AnyReg &savereg, const RegFile ®_file, int regnum); - static void restoreMachineReg(RegFile ®s, const AnyReg ®, + void restoreMachineReg(RegFile ®s, const AnyReg ®, int regnum); #if 0 @@ -263,41 +262,41 @@ static const Addr PageOffset = PageBytes - 1; * @param xc The execution context. */ template - static void zeroRegisters(XC *xc); + void zeroRegisters(XC *xc); + + +//typedef AlphaISA TheISA; + +//typedef TheISA::MachInst MachInst; +//typedef TheISA::Addr Addr; +//typedef TheISA::RegIndex RegIndex; +//typedef TheISA::IntReg IntReg; +//typedef TheISA::IntRegFile IntRegFile; +//typedef TheISA::FloatReg FloatReg; +//typedef TheISA::FloatRegFile FloatRegFile; +//typedef TheISA::MiscReg MiscReg; +//typedef TheISA::MiscRegFile MiscRegFile; +//typedef TheISA::AnyReg AnyReg; +//typedef TheISA::RegFile RegFile; + +//const int NumIntRegs = TheISA::NumIntRegs; +//const int NumFloatRegs = TheISA::NumFloatRegs; +//const int NumMiscRegs = TheISA::NumMiscRegs; +//const int TotalNumRegs = TheISA::TotalNumRegs; +//const int VMPageSize = TheISA::VMPageSize; +//const int LogVMPageSize = TheISA::LogVMPageSize; +//const int ZeroReg = TheISA::ZeroReg; +//const int StackPointerReg = TheISA::StackPointerReg; +//const int GlobalPointerReg = TheISA::GlobalPointerReg; +//const int ReturnAddressReg = TheISA::ReturnAddressReg; +//const int ReturnValueReg = TheISA::ReturnValueReg; +//const int ArgumentReg0 = TheISA::ArgumentReg0; +//const int ArgumentReg1 = TheISA::ArgumentReg1; +//const int ArgumentReg2 = TheISA::ArgumentReg2; +//const int BranchPredAddrShiftAmt = TheISA::BranchPredAddrShiftAmt; +const Addr MaxAddr = (Addr)-1; }; - -typedef AlphaISA TheISA; - -typedef TheISA::MachInst MachInst; -typedef TheISA::Addr Addr; -typedef TheISA::RegIndex RegIndex; -typedef TheISA::IntReg IntReg; -typedef TheISA::IntRegFile IntRegFile; -typedef TheISA::FloatReg FloatReg; -typedef TheISA::FloatRegFile FloatRegFile; -typedef TheISA::MiscReg MiscReg; -typedef TheISA::MiscRegFile MiscRegFile; -typedef TheISA::AnyReg AnyReg; -typedef TheISA::RegFile RegFile; - -const int NumIntRegs = TheISA::NumIntRegs; -const int NumFloatRegs = TheISA::NumFloatRegs; -const int NumMiscRegs = TheISA::NumMiscRegs; -const int TotalNumRegs = TheISA::TotalNumRegs; -const int VMPageSize = TheISA::VMPageSize; -const int LogVMPageSize = TheISA::LogVMPageSize; -const int ZeroReg = TheISA::ZeroReg; -const int StackPointerReg = TheISA::StackPointerReg; -const int GlobalPointerReg = TheISA::GlobalPointerReg; -const int ReturnAddressReg = TheISA::ReturnAddressReg; -const int ReturnValueReg = TheISA::ReturnValueReg; -const int ArgumentReg0 = TheISA::ArgumentReg0; -const int ArgumentReg1 = TheISA::ArgumentReg1; -const int ArgumentReg2 = TheISA::ArgumentReg2; -const int BranchPredAddrShiftAmt = TheISA::BranchPredAddrShiftAmt; -const int MaxAddr = (Addr)-1; - #if !FULL_SYSTEM class SyscallReturn { public: @@ -336,9 +335,9 @@ class SyscallReturn { #if FULL_SYSTEM -typedef TheISA::InternalProcReg InternalProcReg; -const int NumInternalProcRegs = TheISA::NumInternalProcRegs; -const int NumInterruptLevels = TheISA::NumInterruptLevels; +//typedef TheISA::InternalProcReg InternalProcReg; +//const int NumInternalProcRegs = TheISA::NumInternalProcRegs; +//const int NumInterruptLevels = TheISA::NumInterruptLevels; #include "arch/alpha/ev5.hh" #endif diff --git a/arch/alpha/stacktrace.cc b/arch/alpha/stacktrace.cc index 5a8df3d35..30ed07d9d 100644 --- a/arch/alpha/stacktrace.cc +++ b/arch/alpha/stacktrace.cc @@ -37,6 +37,7 @@ #include "cpu/exec_context.hh" using namespace std; +using namespace AlphaISA; ProcessInfo::ProcessInfo(ExecContext *_xc) : xc(_xc) @@ -108,7 +109,7 @@ StackTrace::StackTrace() { } -StackTrace::StackTrace(ExecContext *_xc, StaticInstPtr inst) +StackTrace::StackTrace(ExecContext *_xc, StaticInstPtr inst) : xc(0), stack(64) { trace(_xc, inst); diff --git a/arch/alpha/stacktrace.hh b/arch/alpha/stacktrace.hh index 244e574b6..211909060 100644 --- a/arch/alpha/stacktrace.hh +++ b/arch/alpha/stacktrace.hh @@ -37,6 +37,8 @@ class StackTrace; class ProcessInfo { + protected: + typedef TheISA::Addr Addr; private: ExecContext *xc; @@ -56,6 +58,9 @@ class ProcessInfo class StackTrace { + protected: + typedef TheISA::Addr Addr; + typedef TheISA::MachInst MachInst; private: ExecContext *xc; std::vector stack; @@ -70,7 +75,7 @@ class StackTrace public: StackTrace(); - StackTrace(ExecContext *xc, StaticInstPtr inst); + StackTrace(ExecContext *xc, StaticInstPtr inst); ~StackTrace(); void clear() @@ -80,7 +85,7 @@ class StackTrace } bool valid() const { return xc != NULL; } - bool trace(ExecContext *xc, StaticInstPtr inst); + bool trace(ExecContext *xc, StaticInstPtr inst); public: const std::vector &getstack() const { return stack; } @@ -102,7 +107,7 @@ class StackTrace }; inline bool -StackTrace::trace(ExecContext *xc, StaticInstPtr inst) +StackTrace::trace(ExecContext *xc, StaticInstPtr inst) { if (!inst->isCall() && !inst->isReturn()) return false; diff --git a/arch/alpha/vtophys.cc b/arch/alpha/vtophys.cc index 27014164c..3ffa4bd14 100644 --- a/arch/alpha/vtophys.cc +++ b/arch/alpha/vtophys.cc @@ -34,6 +34,7 @@ #include "mem/functional/physical.hh" using namespace std; +using namespace AlphaISA; AlphaISA::PageTableEntry kernel_pte_lookup(PhysicalMemory *pmem, Addr ptbr, AlphaISA::VAddr vaddr) diff --git a/arch/alpha/vtophys.hh b/arch/alpha/vtophys.hh index 95430ce77..988f050ba 100644 --- a/arch/alpha/vtophys.hh +++ b/arch/alpha/vtophys.hh @@ -35,16 +35,16 @@ class ExecContext; class PhysicalMemory; AlphaISA::PageTableEntry -kernel_pte_lookup(PhysicalMemory *pmem, Addr ptbr, AlphaISA::VAddr vaddr); +kernel_pte_lookup(PhysicalMemory *pmem, AlphaISA::Addr ptbr, AlphaISA::VAddr vaddr); -Addr vtophys(PhysicalMemory *xc, Addr vaddr); -Addr vtophys(ExecContext *xc, Addr vaddr); -uint8_t *vtomem(ExecContext *xc, Addr vaddr, size_t len); -uint8_t *ptomem(ExecContext *xc, Addr paddr, size_t len); +AlphaISA::Addr vtophys(PhysicalMemory *xc, AlphaISA::Addr vaddr); +AlphaISA::Addr vtophys(ExecContext *xc, AlphaISA::Addr vaddr); +uint8_t *vtomem(ExecContext *xc, AlphaISA::Addr vaddr, size_t len); +uint8_t *ptomem(ExecContext *xc, AlphaISA::Addr paddr, size_t len); -void CopyOut(ExecContext *xc, void *dst, Addr src, size_t len); -void CopyIn(ExecContext *xc, Addr dst, void *src, size_t len); -void CopyString(ExecContext *xc, char *dst, Addr vaddr, size_t maxlen); +void CopyOut(ExecContext *xc, void *dst, AlphaISA::Addr src, size_t len); +void CopyIn(ExecContext *xc, AlphaISA::Addr dst, void *src, size_t len); +void CopyString(ExecContext *xc, char *dst, AlphaISA::Addr vaddr, size_t maxlen); #endif // __ARCH_ALPHA_VTOPHYS_H__ diff --git a/arch/isa_parser.py b/arch/isa_parser.py index 96d3e8438..3fbb5276b 100755 --- a/arch/isa_parser.py +++ b/arch/isa_parser.py @@ -224,7 +224,7 @@ def p_specification(t): namespace = isa_name + "Inst" # wrap the decode block as a function definition t[4].wrap_decode_block(''' -StaticInstPtr<%(isa_name)s> +StaticInstPtr %(isa_name)s::decodeInst(%(isa_name)s::MachInst machInst) { using namespace %(namespace)s; @@ -1690,6 +1690,8 @@ namespace %(namespace)s { %(namespace_output)s } // namespace %(namespace)s + +%(decode_function)s ''' @@ -1769,13 +1771,15 @@ def parse_isa_desc(isa_desc_file, output_dir, include_path): includes = '#include "base/bitfield.hh" // for bitfield support' global_output = global_code.header_output namespace_output = namespace_code.header_output + decode_function = '' update_if_needed(output_dir + '/decoder.hh', file_template % vars()) # generate decoder.cc includes = '#include "%s/decoder.hh"' % include_path global_output = global_code.decoder_output namespace_output = namespace_code.decoder_output - namespace_output += namespace_code.decode_block + # namespace_output += namespace_code.decode_block + decode_function = namespace_code.decode_block update_if_needed(output_dir + '/decoder.cc', file_template % vars()) # generate per-cpu exec files @@ -1784,6 +1788,7 @@ def parse_isa_desc(isa_desc_file, output_dir, include_path): includes += cpu.includes global_output = global_code.exec_output[cpu.name] namespace_output = namespace_code.exec_output[cpu.name] + decode_function = '' update_if_needed(output_dir + '/' + cpu.filename, file_template % vars()) diff --git a/base/loader/object_file.hh b/base/loader/object_file.hh index 3c8659e18..e90f93847 100644 --- a/base/loader/object_file.hh +++ b/base/loader/object_file.hh @@ -37,6 +37,7 @@ class SymbolTable; class ObjectFile { public: + typedef TheISA::Addr Addr; enum Arch { UnknownArch, diff --git a/base/loader/symtab.hh b/base/loader/symtab.hh index ebcda1345..38b4cdee2 100644 --- a/base/loader/symtab.hh +++ b/base/loader/symtab.hh @@ -37,8 +37,9 @@ class Checkpoint; class SymbolTable { + typedef TheISA::Addr Addr; public: - typedef std::map ATable; + typedef std::map ATable; typedef std::map STable; private: diff --git a/base/remote_gdb.cc b/base/remote_gdb.cc index 67d745d43..17ec21fed 100644 --- a/base/remote_gdb.cc +++ b/base/remote_gdb.cc @@ -132,6 +132,7 @@ #include "targetarch/vtophys.hh" using namespace std; +using namespace TheISA; #ifndef NDEBUG vector debuggers; @@ -494,7 +495,7 @@ RemoteGDB::setSingleStep() // User was stopped at pc, e.g. the instruction at pc was not // executed. MachInst inst = read(pc); - StaticInstPtr si(inst); + StaticInstPtr si(inst); if (si->hasBranchTarget(pc, context, bpc)) { // Don't bother setting a breakpoint on the taken branch if it // is the same as the next pc diff --git a/base/remote_gdb.hh b/base/remote_gdb.hh index 652a58317..126d5f6f8 100644 --- a/base/remote_gdb.hh +++ b/base/remote_gdb.hh @@ -43,6 +43,9 @@ class PhysicalMemory; class GDBListener; class RemoteGDB { + protected: + typedef TheISA::Addr Addr; + typedef TheISA::MachInst MachInst; private: friend void debugger(); friend class GDBListener; diff --git a/cpu/base.cc b/cpu/base.cc index 8b94b8533..5a7ecf152 100644 --- a/cpu/base.cc +++ b/cpu/base.cc @@ -250,7 +250,7 @@ BaseCPU::takeOverFrom(BaseCPU *oldCPU) } #if FULL_SYSTEM - for (int i = 0; i < NumInterruptLevels; ++i) + for (int i = 0; i < TheISA::NumInterruptLevels; ++i) interrupts[i] = oldCPU->interrupts[i]; intstatus = oldCPU->intstatus; @@ -285,7 +285,7 @@ BaseCPU::post_interrupt(int int_num, int index) { DPRINTF(Interrupt, "Interrupt %d:%d posted\n", int_num, index); - if (int_num < 0 || int_num >= NumInterruptLevels) + if (int_num < 0 || int_num >= TheISA::NumInterruptLevels) panic("int_num out of bounds\n"); if (index < 0 || index >= sizeof(uint64_t) * 8) @@ -301,7 +301,7 @@ BaseCPU::clear_interrupt(int int_num, int index) { DPRINTF(Interrupt, "Interrupt %d:%d cleared\n", int_num, index); - if (int_num < 0 || int_num >= NumInterruptLevels) + if (int_num < 0 || int_num >= TheISA::NumInterruptLevels) panic("int_num out of bounds\n"); if (index < 0 || index >= sizeof(uint64_t) * 8) @@ -325,14 +325,14 @@ BaseCPU::clear_interrupts() void BaseCPU::serialize(std::ostream &os) { - SERIALIZE_ARRAY(interrupts, NumInterruptLevels); + SERIALIZE_ARRAY(interrupts, TheISA::NumInterruptLevels); SERIALIZE_SCALAR(intstatus); } void BaseCPU::unserialize(Checkpoint *cp, const std::string §ion) { - UNSERIALIZE_ARRAY(interrupts, NumInterruptLevels); + UNSERIALIZE_ARRAY(interrupts, TheISA::NumInterruptLevels); UNSERIALIZE_SCALAR(intstatus); } diff --git a/cpu/base.hh b/cpu/base.hh index 2bd1210d8..ab52e7b81 100644 --- a/cpu/base.hh +++ b/cpu/base.hh @@ -48,6 +48,7 @@ class ExecContext; class BaseCPU : public SimObject { protected: + typedef TheISA::Addr Addr; // CPU's clock period in terms of the number of ticks of curTime. Tick clock; @@ -58,7 +59,7 @@ class BaseCPU : public SimObject #if FULL_SYSTEM protected: - uint64_t interrupts[NumInterruptLevels]; + uint64_t interrupts[TheISA::NumInterruptLevels]; uint64_t intstatus; public: @@ -68,7 +69,7 @@ class BaseCPU : public SimObject bool checkInterrupts; bool check_interrupt(int int_num) const { - if (int_num > NumInterruptLevels) + if (int_num > TheISA::NumInterruptLevels) panic("int_num out of bounds\n"); return interrupts[int_num] != 0; diff --git a/cpu/base_dyn_inst.cc b/cpu/base_dyn_inst.cc index 59a12f2d0..9901c90af 100644 --- a/cpu/base_dyn_inst.cc +++ b/cpu/base_dyn_inst.cc @@ -79,7 +79,7 @@ BaseDynInst::BaseDynInst(MachInst machInst, Addr inst_PC, } template -BaseDynInst::BaseDynInst(StaticInstPtr &_staticInst) +BaseDynInst::BaseDynInst(StaticInstPtr &_staticInst) : staticInst(_staticInst), traceData(NULL) { initVars(); diff --git a/cpu/base_dyn_inst.hh b/cpu/base_dyn_inst.hh index 2c91db99c..dd429fc91 100644 --- a/cpu/base_dyn_inst.hh +++ b/cpu/base_dyn_inst.hh @@ -51,7 +51,6 @@ */ // Forward declaration. -template class StaticInstPtr; template @@ -61,25 +60,22 @@ class BaseDynInst : public FastAlloc, public RefCounted // Typedef for the CPU. typedef typename Impl::FullCPU FullCPU; - //Typedef to get the ISA. - typedef typename Impl::ISA ISA; - /// Binary machine instruction type. - typedef typename ISA::MachInst MachInst; + typedef TheISA::MachInst MachInst; /// Memory address type. - typedef typename ISA::Addr Addr; + typedef TheISA::Addr Addr; /// Logical register index type. - typedef typename ISA::RegIndex RegIndex; + typedef TheISA::RegIndex RegIndex; /// Integer register index type. - typedef typename ISA::IntReg IntReg; + typedef TheISA::IntReg IntReg; enum { - MaxInstSrcRegs = ISA::MaxInstSrcRegs, //< Max source regs - MaxInstDestRegs = ISA::MaxInstDestRegs, //< Max dest regs + MaxInstSrcRegs = TheISA::MaxInstSrcRegs, //< Max source regs + MaxInstDestRegs = TheISA::MaxInstDestRegs, //< Max dest regs }; /** The static inst used by this dyn inst. */ - StaticInstPtr staticInst; + StaticInstPtr staticInst; //////////////////////////////////////////// // @@ -214,7 +210,7 @@ class BaseDynInst : public FastAlloc, public RefCounted FullCPU *cpu); /** BaseDynInst constructor given a static inst pointer. */ - BaseDynInst(StaticInstPtr &_staticInst); + BaseDynInst(StaticInstPtr &_staticInst); /** BaseDynInst destructor. */ ~BaseDynInst(); diff --git a/cpu/exec_context.hh b/cpu/exec_context.hh index 7e195af23..7e905e7d3 100644 --- a/cpu/exec_context.hh +++ b/cpu/exec_context.hh @@ -35,6 +35,7 @@ #include "sim/host.hh" #include "sim/serialize.hh" #include "arch/isa_traits.hh" +//#include "arch/isa_registers.hh" #include "sim/byteswap.hh" // forward declaration: see functional_memory.hh @@ -66,6 +67,11 @@ namespace Kernel { class Binning; class Statistics; } class ExecContext { + protected: + typedef TheISA::RegFile RegFile; + typedef TheISA::Addr Addr; + typedef TheISA::MachInst MachInst; + typedef TheISA::MiscRegFile MiscRegFile; public: enum Status { @@ -431,15 +437,15 @@ class ExecContext void trap(Fault * fault); #if !FULL_SYSTEM - IntReg getSyscallArg(int i) + TheISA::IntReg getSyscallArg(int i) { - return regs.intRegFile[ArgumentReg0 + i]; + return regs.intRegFile[TheISA::ArgumentReg0 + i]; } // used to shift args for indirect syscall - void setSyscallArg(int i, IntReg val) + void setSyscallArg(int i, TheISA::IntReg val) { - regs.intRegFile[ArgumentReg0 + i] = val; + regs.intRegFile[TheISA::ArgumentReg0 + i] = val; } void setSyscallReturn(SyscallReturn return_value) @@ -451,11 +457,11 @@ class ExecContext if (return_value.successful()) { // no error regs.intRegFile[RegA3] = 0; - regs.intRegFile[ReturnValueReg] = return_value.value(); + regs.intRegFile[TheISA::ReturnValueReg] = return_value.value(); } else { // got an error, return details - regs.intRegFile[RegA3] = (IntReg) -1; - regs.intRegFile[ReturnValueReg] = -return_value.value(); + regs.intRegFile[RegA3] = (TheISA::IntReg) -1; + regs.intRegFile[TheISA::ReturnValueReg] = -return_value.value(); } } diff --git a/cpu/exetrace.hh b/cpu/exetrace.hh index 48d8966d8..d37c48ddd 100644 --- a/cpu/exetrace.hh +++ b/cpu/exetrace.hh @@ -46,13 +46,15 @@ namespace Trace { class InstRecord : public Record { protected: + typedef TheISA::Addr Addr; + typedef TheISA::IntRegFile IntRegFile; // The following fields are initialized by the constructor and // thus guaranteed to be valid. BaseCPU *cpu; // need to make this ref-counted so it doesn't go away before we // dump the record - StaticInstPtr staticInst; + StaticInstPtr staticInst; Addr PC; bool misspeculating; unsigned thread; @@ -92,7 +94,7 @@ class InstRecord : public Record public: InstRecord(Tick _cycle, BaseCPU *_cpu, - const StaticInstPtr &_staticInst, + const StaticInstPtr &_staticInst, Addr _pc, bool spec, int _thread) : Record(_cycle), cpu(_cpu), staticInst(_staticInst), PC(_pc), misspeculating(spec), thread(_thread) @@ -169,8 +171,8 @@ InstRecord::setRegs(const IntRegFile ®s) inline InstRecord * getInstRecord(Tick cycle, ExecContext *xc, BaseCPU *cpu, - const StaticInstPtr staticInst, - Addr pc, int thread = 0) + const StaticInstPtr staticInst, + TheISA::Addr pc, int thread = 0) { if (DTRACE(InstExec) && (InstRecord::traceMisspec() || !xc->misspeculating())) { diff --git a/cpu/memtest/memtest.cc b/cpu/memtest/memtest.cc index 27f790fac..5a4024587 100644 --- a/cpu/memtest/memtest.cc +++ b/cpu/memtest/memtest.cc @@ -44,6 +44,7 @@ #include "sim/stats.hh" using namespace std; +using namespace TheISA; int TESTER_ALLOCATOR=0; diff --git a/cpu/memtest/memtest.hh b/cpu/memtest/memtest.hh index 7abcf017a..76a89ff2c 100644 --- a/cpu/memtest/memtest.hh +++ b/cpu/memtest/memtest.hh @@ -42,6 +42,8 @@ class ExecContext; class MemTest : public SimObject { + protected: + typedef TheISA::Addr Addr; public: MemTest(const std::string &name, diff --git a/cpu/o3/2bit_local_pred.hh b/cpu/o3/2bit_local_pred.hh index a97ce455c..78efe1e43 100644 --- a/cpu/o3/2bit_local_pred.hh +++ b/cpu/o3/2bit_local_pred.hh @@ -30,11 +30,13 @@ #define __CPU_O3_CPU_2BIT_LOCAL_PRED_HH__ // For Addr type. -#include "arch/alpha/isa_traits.hh" +#include "arch/isa_traits.hh" #include "cpu/o3/sat_counter.hh" class DefaultBP { + protected: + typedef TheISA::Addr Addr; public: /** * Default branch predictor constructor. diff --git a/cpu/o3/alpha_cpu.hh b/cpu/o3/alpha_cpu.hh index 606f9fa0a..bf3556b8e 100644 --- a/cpu/o3/alpha_cpu.hh +++ b/cpu/o3/alpha_cpu.hh @@ -39,8 +39,10 @@ template class AlphaFullCPU : public FullO3CPU { + protected: + typedef AlphaISA::Addr Addr; + typedef TheISA::IntReg IntReg; public: - typedef typename Impl::ISA AlphaISA; typedef typename Impl::Params Params; public: diff --git a/cpu/o3/alpha_cpu_impl.hh b/cpu/o3/alpha_cpu_impl.hh index 408676331..6736cf9bc 100644 --- a/cpu/o3/alpha_cpu_impl.hh +++ b/cpu/o3/alpha_cpu_impl.hh @@ -282,7 +282,7 @@ AlphaFullCPU::hwrei() if (!inPalMode()) return UnimplementedOpcodeFault; - setNextPC(ipr[AlphaISA::IPR_EXC_ADDR]); + this->setNextPC(ipr[AlphaISA::IPR_EXC_ADDR]); // kernelStats.hwrei(); @@ -337,7 +337,7 @@ AlphaFullCPU::trap(Fault * fault) if (fault == ArithmeticFault) panic("Arithmetic traps are unimplemented!"); - typename AlphaISA::InternalProcReg *ipr = getIpr(); + AlphaISA::InternalProcReg *ipr = getIpr(); // exception restart address - Get the commit PC if (fault != InterruptFault || !inPalMode(PC)) diff --git a/cpu/o3/alpha_dyn_inst.hh b/cpu/o3/alpha_dyn_inst.hh index 77dcbaf74..22be2aae5 100644 --- a/cpu/o3/alpha_dyn_inst.hh +++ b/cpu/o3/alpha_dyn_inst.hh @@ -48,21 +48,18 @@ class AlphaDynInst : public BaseDynInst /** Typedef for the CPU. */ typedef typename Impl::FullCPU FullCPU; - /** Typedef to get the ISA. */ - typedef typename Impl::ISA ISA; - /** Binary machine instruction type. */ - typedef typename ISA::MachInst MachInst; + typedef TheISA::MachInst MachInst; /** Memory address type. */ - typedef typename ISA::Addr Addr; + typedef TheISA::Addr Addr; /** Logical register index type. */ - typedef typename ISA::RegIndex RegIndex; + typedef TheISA::RegIndex RegIndex; /** Integer register index type. */ - typedef typename ISA::IntReg IntReg; + typedef TheISA::IntReg IntReg; enum { - MaxInstSrcRegs = ISA::MaxInstSrcRegs, //< Max source regs - MaxInstDestRegs = ISA::MaxInstDestRegs, //< Max dest regs + MaxInstSrcRegs = TheISA::MaxInstSrcRegs, //< Max source regs + MaxInstDestRegs = TheISA::MaxInstDestRegs, //< Max dest regs }; public: @@ -71,7 +68,7 @@ class AlphaDynInst : public BaseDynInst FullCPU *cpu); /** BaseDynInst constructor given a static inst pointer. */ - AlphaDynInst(StaticInstPtr &_staticInst); + AlphaDynInst(StaticInstPtr &_staticInst); /** Executes the instruction.*/ Fault * execute() @@ -130,22 +127,22 @@ class AlphaDynInst : public BaseDynInst // storage (which is pretty hard to imagine they would have reason // to do). - uint64_t readIntReg(const StaticInst *si, int idx) + uint64_t readIntReg(const StaticInst *si, int idx) { return this->cpu->readIntReg(_srcRegIdx[idx]); } - float readFloatRegSingle(const StaticInst *si, int idx) + float readFloatRegSingle(const StaticInst *si, int idx) { return this->cpu->readFloatRegSingle(_srcRegIdx[idx]); } - double readFloatRegDouble(const StaticInst *si, int idx) + double readFloatRegDouble(const StaticInst *si, int idx) { return this->cpu->readFloatRegDouble(_srcRegIdx[idx]); } - uint64_t readFloatRegInt(const StaticInst *si, int idx) + uint64_t readFloatRegInt(const StaticInst *si, int idx) { return this->cpu->readFloatRegInt(_srcRegIdx[idx]); } @@ -153,25 +150,25 @@ class AlphaDynInst : public BaseDynInst /** @todo: Make results into arrays so they can handle multiple dest * registers. */ - void setIntReg(const StaticInst *si, int idx, uint64_t val) + void setIntReg(const StaticInst *si, int idx, uint64_t val) { this->cpu->setIntReg(_destRegIdx[idx], val); this->instResult.integer = val; } - void setFloatRegSingle(const StaticInst *si, int idx, float val) + void setFloatRegSingle(const StaticInst *si, int idx, float val) { this->cpu->setFloatRegSingle(_destRegIdx[idx], val); this->instResult.fp = val; } - void setFloatRegDouble(const StaticInst *si, int idx, double val) + void setFloatRegDouble(const StaticInst *si, int idx, double val) { this->cpu->setFloatRegDouble(_destRegIdx[idx], val); this->instResult.dbl = val; } - void setFloatRegInt(const StaticInst *si, int idx, uint64_t val) + void setFloatRegInt(const StaticInst *si, int idx, uint64_t val) { this->cpu->setFloatRegInt(_destRegIdx[idx], val); this->instResult.integer = val; diff --git a/cpu/o3/alpha_dyn_inst_impl.hh b/cpu/o3/alpha_dyn_inst_impl.hh index b20af48cd..9f9df3da1 100644 --- a/cpu/o3/alpha_dyn_inst_impl.hh +++ b/cpu/o3/alpha_dyn_inst_impl.hh @@ -50,7 +50,7 @@ AlphaDynInst::AlphaDynInst(MachInst inst, Addr PC, Addr Pred_PC, } template -AlphaDynInst::AlphaDynInst(StaticInstPtr &_staticInst) +AlphaDynInst::AlphaDynInst(StaticInstPtr &_staticInst) : BaseDynInst(_staticInst) { // Make sure to have the renamed register entries set to the same diff --git a/cpu/o3/alpha_impl.hh b/cpu/o3/alpha_impl.hh index 6c1156041..5e39fcb37 100644 --- a/cpu/o3/alpha_impl.hh +++ b/cpu/o3/alpha_impl.hh @@ -51,11 +51,8 @@ class AlphaFullCPU; */ struct AlphaSimpleImpl { - /** The ISA to be used. */ - typedef AlphaISA ISA; - /** The type of MachInst. */ - typedef ISA::MachInst MachInst; + typedef TheISA::MachInst MachInst; /** The CPU policy to be used (ie fetch, decode, etc.). */ typedef SimpleCPUPolicy CPUPol; diff --git a/cpu/o3/bpred_unit.hh b/cpu/o3/bpred_unit.hh index 0a77b83dc..c874f9e04 100644 --- a/cpu/o3/bpred_unit.hh +++ b/cpu/o3/bpred_unit.hh @@ -53,6 +53,8 @@ template class TwobitBPredUnit { + protected: + typedef TheISA::Addr Addr; public: typedef typename Impl::Params Params; typedef typename Impl::DynInstPtr DynInstPtr; diff --git a/cpu/o3/bpred_unit_impl.hh b/cpu/o3/bpred_unit_impl.hh index 9cb2e0490..8d16a0cdf 100644 --- a/cpu/o3/bpred_unit_impl.hh +++ b/cpu/o3/bpred_unit_impl.hh @@ -98,6 +98,8 @@ TwobitBPredUnit::predict(DynInstPtr &inst, Addr &PC) // Save off record of branch stuff so the RAS can be fixed // up once it's done. + using TheISA::MachInst; + bool pred_taken = false; Addr target; diff --git a/cpu/o3/btb.cc b/cpu/o3/btb.cc index 7671e61e2..2d39c3856 100644 --- a/cpu/o3/btb.cc +++ b/cpu/o3/btb.cc @@ -30,6 +30,8 @@ #include "base/trace.hh" #include "cpu/o3/btb.hh" +using namespace TheISA; + DefaultBTB::DefaultBTB(unsigned _numEntries, unsigned _tagBits, unsigned _instShiftAmt) diff --git a/cpu/o3/btb.hh b/cpu/o3/btb.hh index a4ddfecb4..f443ddbaf 100644 --- a/cpu/o3/btb.hh +++ b/cpu/o3/btb.hh @@ -30,10 +30,12 @@ #define __CPU_O3_CPU_BTB_HH__ // For Addr type. -#include "arch/alpha/isa_traits.hh" +#include "arch/isa_traits.hh" class DefaultBTB { + protected: + typedef TheISA::Addr Addr; private: struct BTBEntry { diff --git a/cpu/o3/commit.hh b/cpu/o3/commit.hh index 6ddc8d6b9..580c1a316 100644 --- a/cpu/o3/commit.hh +++ b/cpu/o3/commit.hh @@ -52,7 +52,6 @@ class SimpleCommit { public: // Typedefs from the Impl. - typedef typename Impl::ISA ISA; typedef typename Impl::FullCPU FullCPU; typedef typename Impl::DynInstPtr DynInstPtr; typedef typename Impl::Params Params; diff --git a/cpu/o3/cpu.cc b/cpu/o3/cpu.cc index adc7b6bbc..ffa157fbb 100644 --- a/cpu/o3/cpu.cc +++ b/cpu/o3/cpu.cc @@ -84,14 +84,14 @@ FullO3CPU::FullO3CPU(Params ¶ms) regFile(params.numPhysIntRegs, params.numPhysFloatRegs), - freeList(Impl::ISA::NumIntRegs, params.numPhysIntRegs, - Impl::ISA::NumFloatRegs, params.numPhysFloatRegs), + freeList(TheISA::NumIntRegs, params.numPhysIntRegs, + TheISA::NumFloatRegs, params.numPhysFloatRegs), - renameMap(Impl::ISA::NumIntRegs, params.numPhysIntRegs, - Impl::ISA::NumFloatRegs, params.numPhysFloatRegs, - Impl::ISA::NumMiscRegs, - Impl::ISA::ZeroReg, - Impl::ISA::ZeroReg + Impl::ISA::NumIntRegs), + renameMap(TheISA::NumIntRegs, params.numPhysIntRegs, + TheISA::NumFloatRegs, params.numPhysFloatRegs, + TheISA::NumMiscRegs, + TheISA::ZeroReg, + TheISA::ZeroReg + TheISA::NumIntRegs), rob(params.numROBEntries, params.squashWidth), @@ -254,13 +254,13 @@ FullO3CPU::init() ExecContext *src_xc = thread[0]; #endif // First loop through the integer registers. - for (int i = 0; i < Impl::ISA::NumIntRegs; ++i) + for (int i = 0; i < TheISA::NumIntRegs; ++i) { regFile.intRegFile[i] = src_xc->regs.intRegFile[i]; } // Then loop through the floating point registers. - for (int i = 0; i < Impl::ISA::NumFloatRegs; ++i) + for (int i = 0; i < TheISA::NumFloatRegs; ++i) { regFile.floatRegFile[i].d = src_xc->regs.floatRegFile.d[i]; regFile.floatRegFile[i].q = src_xc->regs.floatRegFile.q[i]; diff --git a/cpu/o3/cpu.hh b/cpu/o3/cpu.hh index 75dca5056..321d61dce 100644 --- a/cpu/o3/cpu.hh +++ b/cpu/o3/cpu.hh @@ -78,7 +78,6 @@ class FullO3CPU : public BaseFullCPU { public: //Put typedefs from the Impl here. - typedef typename Impl::ISA ISA; typedef typename Impl::CPUPol CPUPolicy; typedef typename Impl::Params Params; typedef typename Impl::DynInstPtr DynInstPtr; @@ -153,11 +152,11 @@ class FullO3CPU : public BaseFullCPU /** Get instruction asid. */ int getInstAsid() - { return ITB_ASN_ASN(regFile.getIpr()[ISA::IPR_ITB_ASN]); } + { return ITB_ASN_ASN(regFile.getIpr()[TheISA::IPR_ITB_ASN]); } /** Get data asid. */ int getDataAsid() - { return DTB_ASN_ASN(regFile.getIpr()[ISA::IPR_DTB_ASN]); } + { return DTB_ASN_ASN(regFile.getIpr()[TheISA::IPR_DTB_ASN]); } #else bool validInstAddr(Addr addr) { return thread[0]->validInstAddr(addr); } diff --git a/cpu/o3/decode.hh b/cpu/o3/decode.hh index 42313d83a..bae9a7015 100644 --- a/cpu/o3/decode.hh +++ b/cpu/o3/decode.hh @@ -39,7 +39,6 @@ class SimpleDecode { private: // Typedefs from the Impl. - typedef typename Impl::ISA ISA; typedef typename Impl::FullCPU FullCPU; typedef typename Impl::DynInstPtr DynInstPtr; typedef typename Impl::Params Params; @@ -51,7 +50,7 @@ class SimpleDecode typedef typename CPUPol::TimeStruct TimeStruct; // Typedefs from the ISA. - typedef typename ISA::Addr Addr; + typedef TheISA::Addr Addr; public: // The only time decode will become blocked is if dispatch becomes diff --git a/cpu/o3/fetch.hh b/cpu/o3/fetch.hh index 5443d274e..e4d374c1d 100644 --- a/cpu/o3/fetch.hh +++ b/cpu/o3/fetch.hh @@ -49,7 +49,6 @@ class SimpleFetch { public: /** Typedefs from Impl. */ - typedef typename Impl::ISA ISA; typedef typename Impl::CPUPol CPUPol; typedef typename Impl::DynInst DynInst; typedef typename Impl::DynInstPtr DynInstPtr; @@ -61,7 +60,8 @@ class SimpleFetch typedef typename CPUPol::TimeStruct TimeStruct; /** Typedefs from ISA. */ - typedef typename ISA::MachInst MachInst; + typedef TheISA::MachInst MachInst; + typedef TheISA::Addr Addr; public: enum Status { @@ -141,7 +141,7 @@ class SimpleFetch // We fold in the PISA 64- to 32-bit conversion here as well. Addr icacheBlockAlignPC(Addr addr) { - addr = ISA::realPCToFetchPC(addr); + addr = TheISA::realPCToFetchPC(addr); return (addr & ~(cacheBlkMask)); } diff --git a/cpu/o3/free_list.hh b/cpu/o3/free_list.hh index 733d142fc..0b85dba1e 100644 --- a/cpu/o3/free_list.hh +++ b/cpu/o3/free_list.hh @@ -32,7 +32,7 @@ #include #include -#include "arch/alpha/isa_traits.hh" +#include "arch/isa_traits.hh" #include "base/trace.hh" #include "base/traceflags.hh" #include "cpu/o3/comm.hh" diff --git a/cpu/o3/iew.hh b/cpu/o3/iew.hh index af23c6f45..1e370d4e6 100644 --- a/cpu/o3/iew.hh +++ b/cpu/o3/iew.hh @@ -45,7 +45,6 @@ class SimpleIEW { private: //Typedefs from Impl - typedef typename Impl::ISA ISA; typedef typename Impl::CPUPol CPUPol; typedef typename Impl::DynInstPtr DynInstPtr; typedef typename Impl::FullCPU FullCPU; diff --git a/cpu/o3/iew_impl.hh b/cpu/o3/iew_impl.hh index b8a2b4dc9..85217dd10 100644 --- a/cpu/o3/iew_impl.hh +++ b/cpu/o3/iew_impl.hh @@ -256,7 +256,7 @@ SimpleIEW::squashDueToBranch(DynInstPtr &inst) toCommit->branchMispredict = true; // Prediction was incorrect, so send back inverse. toCommit->branchTaken = inst->readNextPC() != - (inst->readPC() + sizeof(MachInst)); + (inst->readPC() + sizeof(TheISA::MachInst)); } template diff --git a/cpu/o3/ras.hh b/cpu/o3/ras.hh index bbc4162a6..fd7f5fe1c 100644 --- a/cpu/o3/ras.hh +++ b/cpu/o3/ras.hh @@ -30,10 +30,12 @@ #define __CPU_O3_CPU_RAS_HH__ // For Addr type. -#include "arch/alpha/isa_traits.hh" +#include "arch/isa_traits.hh" class ReturnAddrStack { + protected: + typedef TheISA::Addr Addr; public: ReturnAddrStack(unsigned numEntries); diff --git a/cpu/o3/regfile.hh b/cpu/o3/regfile.hh index 5aafd5495..655a3cad9 100644 --- a/cpu/o3/regfile.hh +++ b/cpu/o3/regfile.hh @@ -52,6 +52,11 @@ using namespace EV5; template class PhysRegFile { + protected: + typedef TheISA::Addr Addr; + typedef TheISA::IntReg IntReg; + typedef TheISA::FloatReg FloatReg; + typedef TheISA::MiscRegFile MiscRegFile; //Note that most of the definitions of the IntReg, FloatReg, etc. exist //within the Impl/ISA class and not within this PhysRegFile class. @@ -62,7 +67,6 @@ class PhysRegFile //Will make these registers public for now, but they probably should //be private eventually with some accessor functions. public: - typedef typename Impl::ISA ISA; typedef typename Impl::FullCPU FullCPU; PhysRegFile(unsigned _numPhysicalIntRegs, @@ -281,73 +285,73 @@ PhysRegFile::readIpr(int idx, Fault * &fault) uint64_t retval = 0; // return value, default 0 switch (idx) { - case ISA::IPR_PALtemp0: - case ISA::IPR_PALtemp1: - case ISA::IPR_PALtemp2: - case ISA::IPR_PALtemp3: - case ISA::IPR_PALtemp4: - case ISA::IPR_PALtemp5: - case ISA::IPR_PALtemp6: - case ISA::IPR_PALtemp7: - case ISA::IPR_PALtemp8: - case ISA::IPR_PALtemp9: - case ISA::IPR_PALtemp10: - case ISA::IPR_PALtemp11: - case ISA::IPR_PALtemp12: - case ISA::IPR_PALtemp13: - case ISA::IPR_PALtemp14: - case ISA::IPR_PALtemp15: - case ISA::IPR_PALtemp16: - case ISA::IPR_PALtemp17: - case ISA::IPR_PALtemp18: - case ISA::IPR_PALtemp19: - case ISA::IPR_PALtemp20: - case ISA::IPR_PALtemp21: - case ISA::IPR_PALtemp22: - case ISA::IPR_PALtemp23: - case ISA::IPR_PAL_BASE: + case TheISA::IPR_PALtemp0: + case TheISA::IPR_PALtemp1: + case TheISA::IPR_PALtemp2: + case TheISA::IPR_PALtemp3: + case TheISA::IPR_PALtemp4: + case TheISA::IPR_PALtemp5: + case TheISA::IPR_PALtemp6: + case TheISA::IPR_PALtemp7: + case TheISA::IPR_PALtemp8: + case TheISA::IPR_PALtemp9: + case TheISA::IPR_PALtemp10: + case TheISA::IPR_PALtemp11: + case TheISA::IPR_PALtemp12: + case TheISA::IPR_PALtemp13: + case TheISA::IPR_PALtemp14: + case TheISA::IPR_PALtemp15: + case TheISA::IPR_PALtemp16: + case TheISA::IPR_PALtemp17: + case TheISA::IPR_PALtemp18: + case TheISA::IPR_PALtemp19: + case TheISA::IPR_PALtemp20: + case TheISA::IPR_PALtemp21: + case TheISA::IPR_PALtemp22: + case TheISA::IPR_PALtemp23: + case TheISA::IPR_PAL_BASE: - case ISA::IPR_IVPTBR: - case ISA::IPR_DC_MODE: - case ISA::IPR_MAF_MODE: - case ISA::IPR_ISR: - case ISA::IPR_EXC_ADDR: - case ISA::IPR_IC_PERR_STAT: - case ISA::IPR_DC_PERR_STAT: - case ISA::IPR_MCSR: - case ISA::IPR_ASTRR: - case ISA::IPR_ASTER: - case ISA::IPR_SIRR: - case ISA::IPR_ICSR: - case ISA::IPR_ICM: - case ISA::IPR_DTB_CM: - case ISA::IPR_IPLR: - case ISA::IPR_INTID: - case ISA::IPR_PMCTR: + case TheISA::IPR_IVPTBR: + case TheISA::IPR_DC_MODE: + case TheISA::IPR_MAF_MODE: + case TheISA::IPR_ISR: + case TheISA::IPR_EXC_ADDR: + case TheISA::IPR_IC_PERR_STAT: + case TheISA::IPR_DC_PERR_STAT: + case TheISA::IPR_MCSR: + case TheISA::IPR_ASTRR: + case TheISA::IPR_ASTER: + case TheISA::IPR_SIRR: + case TheISA::IPR_ICSR: + case TheISA::IPR_ICM: + case TheISA::IPR_DTB_CM: + case TheISA::IPR_IPLR: + case TheISA::IPR_INTID: + case TheISA::IPR_PMCTR: // no side-effect retval = ipr[idx]; break; - case ISA::IPR_CC: + case TheISA::IPR_CC: retval |= ipr[idx] & ULL(0xffffffff00000000); retval |= curTick & ULL(0x00000000ffffffff); break; - case ISA::IPR_VA: + case TheISA::IPR_VA: retval = ipr[idx]; break; - case ISA::IPR_VA_FORM: - case ISA::IPR_MM_STAT: - case ISA::IPR_IFAULT_VA_FORM: - case ISA::IPR_EXC_MASK: - case ISA::IPR_EXC_SUM: + case TheISA::IPR_VA_FORM: + case TheISA::IPR_MM_STAT: + case TheISA::IPR_IFAULT_VA_FORM: + case TheISA::IPR_EXC_MASK: + case TheISA::IPR_EXC_SUM: retval = ipr[idx]; break; - case ISA::IPR_DTB_PTE: + case TheISA::IPR_DTB_PTE: { - typename ISA::PTE &pte = cpu->dtb->index(1); + TheISA::PTE &pte = cpu->dtb->index(1); retval |= ((u_int64_t)pte.ppn & ULL(0x7ffffff)) << 32; retval |= ((u_int64_t)pte.xre & ULL(0xf)) << 8; @@ -360,15 +364,15 @@ PhysRegFile::readIpr(int idx, Fault * &fault) break; // write only registers - case ISA::IPR_HWINT_CLR: - case ISA::IPR_SL_XMIT: - case ISA::IPR_DC_FLUSH: - case ISA::IPR_IC_FLUSH: - case ISA::IPR_ALT_MODE: - case ISA::IPR_DTB_IA: - case ISA::IPR_DTB_IAP: - case ISA::IPR_ITB_IA: - case ISA::IPR_ITB_IAP: + case TheISA::IPR_HWINT_CLR: + case TheISA::IPR_SL_XMIT: + case TheISA::IPR_DC_FLUSH: + case TheISA::IPR_IC_FLUSH: + case TheISA::IPR_ALT_MODE: + case TheISA::IPR_DTB_IA: + case TheISA::IPR_DTB_IAP: + case TheISA::IPR_ITB_IA: + case TheISA::IPR_ITB_IAP: fault = UnimplementedOpcodeFault; break; @@ -390,195 +394,195 @@ PhysRegFile::setIpr(int idx, uint64_t val) uint64_t old; switch (idx) { - case ISA::IPR_PALtemp0: - case ISA::IPR_PALtemp1: - case ISA::IPR_PALtemp2: - case ISA::IPR_PALtemp3: - case ISA::IPR_PALtemp4: - case ISA::IPR_PALtemp5: - case ISA::IPR_PALtemp6: - case ISA::IPR_PALtemp7: - case ISA::IPR_PALtemp8: - case ISA::IPR_PALtemp9: - case ISA::IPR_PALtemp10: - case ISA::IPR_PALtemp11: - case ISA::IPR_PALtemp12: - case ISA::IPR_PALtemp13: - case ISA::IPR_PALtemp14: - case ISA::IPR_PALtemp15: - case ISA::IPR_PALtemp16: - case ISA::IPR_PALtemp17: - case ISA::IPR_PALtemp18: - case ISA::IPR_PALtemp19: - case ISA::IPR_PALtemp20: - case ISA::IPR_PALtemp21: - case ISA::IPR_PALtemp22: - case ISA::IPR_PAL_BASE: - case ISA::IPR_IC_PERR_STAT: - case ISA::IPR_DC_PERR_STAT: - case ISA::IPR_PMCTR: + case TheISA::IPR_PALtemp0: + case TheISA::IPR_PALtemp1: + case TheISA::IPR_PALtemp2: + case TheISA::IPR_PALtemp3: + case TheISA::IPR_PALtemp4: + case TheISA::IPR_PALtemp5: + case TheISA::IPR_PALtemp6: + case TheISA::IPR_PALtemp7: + case TheISA::IPR_PALtemp8: + case TheISA::IPR_PALtemp9: + case TheISA::IPR_PALtemp10: + case TheISA::IPR_PALtemp11: + case TheISA::IPR_PALtemp12: + case TheISA::IPR_PALtemp13: + case TheISA::IPR_PALtemp14: + case TheISA::IPR_PALtemp15: + case TheISA::IPR_PALtemp16: + case TheISA::IPR_PALtemp17: + case TheISA::IPR_PALtemp18: + case TheISA::IPR_PALtemp19: + case TheISA::IPR_PALtemp20: + case TheISA::IPR_PALtemp21: + case TheISA::IPR_PALtemp22: + case TheISA::IPR_PAL_BASE: + case TheISA::IPR_IC_PERR_STAT: + case TheISA::IPR_DC_PERR_STAT: + case TheISA::IPR_PMCTR: // write entire quad w/ no side-effect ipr[idx] = val; break; - case ISA::IPR_CC_CTL: + case TheISA::IPR_CC_CTL: // This IPR resets the cycle counter. We assume this only // happens once... let's verify that. assert(ipr[idx] == 0); ipr[idx] = 1; break; - case ISA::IPR_CC: + case TheISA::IPR_CC: // This IPR only writes the upper 64 bits. It's ok to write // all 64 here since we mask out the lower 32 in rpcc (see // isa_desc). ipr[idx] = val; break; - case ISA::IPR_PALtemp23: + case TheISA::IPR_PALtemp23: // write entire quad w/ no side-effect old = ipr[idx]; ipr[idx] = val; break; - case ISA::IPR_DTB_PTE: + case TheISA::IPR_DTB_PTE: // write entire quad w/ no side-effect, tag is forthcoming ipr[idx] = val; break; - case ISA::IPR_EXC_ADDR: + case TheISA::IPR_EXC_ADDR: // second least significant bit in PC is always zero ipr[idx] = val & ~2; break; - case ISA::IPR_ASTRR: - case ISA::IPR_ASTER: + case TheISA::IPR_ASTRR: + case TheISA::IPR_ASTER: // only write least significant four bits - privilege mask ipr[idx] = val & 0xf; break; - case ISA::IPR_IPLR: + case TheISA::IPR_IPLR: // only write least significant five bits - interrupt level ipr[idx] = val & 0x1f; break; - case ISA::IPR_DTB_CM: + case TheISA::IPR_DTB_CM: - case ISA::IPR_ICM: + case TheISA::IPR_ICM: // only write two mode bits - processor mode ipr[idx] = val & 0x18; break; - case ISA::IPR_ALT_MODE: + case TheISA::IPR_ALT_MODE: // only write two mode bits - processor mode ipr[idx] = val & 0x18; break; - case ISA::IPR_MCSR: + case TheISA::IPR_MCSR: // more here after optimization... ipr[idx] = val; break; - case ISA::IPR_SIRR: + case TheISA::IPR_SIRR: // only write software interrupt mask ipr[idx] = val & 0x7fff0; break; - case ISA::IPR_ICSR: + case TheISA::IPR_ICSR: ipr[idx] = val & ULL(0xffffff0300); break; - case ISA::IPR_IVPTBR: - case ISA::IPR_MVPTBR: + case TheISA::IPR_IVPTBR: + case TheISA::IPR_MVPTBR: ipr[idx] = val & ULL(0xffffffffc0000000); break; - case ISA::IPR_DC_TEST_CTL: + case TheISA::IPR_DC_TEST_CTL: ipr[idx] = val & 0x1ffb; break; - case ISA::IPR_DC_MODE: - case ISA::IPR_MAF_MODE: + case TheISA::IPR_DC_MODE: + case TheISA::IPR_MAF_MODE: ipr[idx] = val & 0x3f; break; - case ISA::IPR_ITB_ASN: + case TheISA::IPR_ITB_ASN: ipr[idx] = val & 0x7f0; break; - case ISA::IPR_DTB_ASN: + case TheISA::IPR_DTB_ASN: ipr[idx] = val & ULL(0xfe00000000000000); break; - case ISA::IPR_EXC_SUM: - case ISA::IPR_EXC_MASK: + case TheISA::IPR_EXC_SUM: + case TheISA::IPR_EXC_MASK: // any write to this register clears it ipr[idx] = 0; break; - case ISA::IPR_INTID: - case ISA::IPR_SL_RCV: - case ISA::IPR_MM_STAT: - case ISA::IPR_ITB_PTE_TEMP: - case ISA::IPR_DTB_PTE_TEMP: + case TheISA::IPR_INTID: + case TheISA::IPR_SL_RCV: + case TheISA::IPR_MM_STAT: + case TheISA::IPR_ITB_PTE_TEMP: + case TheISA::IPR_DTB_PTE_TEMP: // read-only registers return UnimplementedOpcodeFault; - case ISA::IPR_HWINT_CLR: - case ISA::IPR_SL_XMIT: - case ISA::IPR_DC_FLUSH: - case ISA::IPR_IC_FLUSH: + case TheISA::IPR_HWINT_CLR: + case TheISA::IPR_SL_XMIT: + case TheISA::IPR_DC_FLUSH: + case TheISA::IPR_IC_FLUSH: // the following are write only ipr[idx] = val; break; - case ISA::IPR_DTB_IA: + case TheISA::IPR_DTB_IA: // really a control write ipr[idx] = 0; cpu->dtb->flushAll(); break; - case ISA::IPR_DTB_IAP: + case TheISA::IPR_DTB_IAP: // really a control write ipr[idx] = 0; cpu->dtb->flushProcesses(); break; - case ISA::IPR_DTB_IS: + case TheISA::IPR_DTB_IS: // really a control write ipr[idx] = val; - cpu->dtb->flushAddr(val, DTB_ASN_ASN(ipr[ISA::IPR_DTB_ASN])); + cpu->dtb->flushAddr(val, DTB_ASN_ASN(ipr[TheISA::IPR_DTB_ASN])); break; - case ISA::IPR_DTB_TAG: { - struct ISA::PTE pte; + case TheISA::IPR_DTB_TAG: { + struct TheISA::PTE pte; // FIXME: granularity hints NYI... - if (DTB_PTE_GH(ipr[ISA::IPR_DTB_PTE]) != 0) + if (DTB_PTE_GH(ipr[TheISA::IPR_DTB_PTE]) != 0) panic("PTE GH field != 0"); // write entire quad ipr[idx] = val; // construct PTE for new entry - pte.ppn = DTB_PTE_PPN(ipr[ISA::IPR_DTB_PTE]); - pte.xre = DTB_PTE_XRE(ipr[ISA::IPR_DTB_PTE]); - pte.xwe = DTB_PTE_XWE(ipr[ISA::IPR_DTB_PTE]); - pte.fonr = DTB_PTE_FONR(ipr[ISA::IPR_DTB_PTE]); - pte.fonw = DTB_PTE_FONW(ipr[ISA::IPR_DTB_PTE]); - pte.asma = DTB_PTE_ASMA(ipr[ISA::IPR_DTB_PTE]); - pte.asn = DTB_ASN_ASN(ipr[ISA::IPR_DTB_ASN]); + pte.ppn = DTB_PTE_PPN(ipr[TheISA::IPR_DTB_PTE]); + pte.xre = DTB_PTE_XRE(ipr[TheISA::IPR_DTB_PTE]); + pte.xwe = DTB_PTE_XWE(ipr[TheISA::IPR_DTB_PTE]); + pte.fonr = DTB_PTE_FONR(ipr[TheISA::IPR_DTB_PTE]); + pte.fonw = DTB_PTE_FONW(ipr[TheISA::IPR_DTB_PTE]); + pte.asma = DTB_PTE_ASMA(ipr[TheISA::IPR_DTB_PTE]); + pte.asn = DTB_ASN_ASN(ipr[TheISA::IPR_DTB_ASN]); // insert new TAG/PTE value into data TLB cpu->dtb->insert(val, pte); } break; - case ISA::IPR_ITB_PTE: { - struct ISA::PTE pte; + case TheISA::IPR_ITB_PTE: { + struct TheISA::PTE pte; // FIXME: granularity hints NYI... if (ITB_PTE_GH(val) != 0) @@ -594,32 +598,32 @@ PhysRegFile::setIpr(int idx, uint64_t val) pte.fonr = ITB_PTE_FONR(val); pte.fonw = ITB_PTE_FONW(val); pte.asma = ITB_PTE_ASMA(val); - pte.asn = ITB_ASN_ASN(ipr[ISA::IPR_ITB_ASN]); + pte.asn = ITB_ASN_ASN(ipr[TheISA::IPR_ITB_ASN]); // insert new TAG/PTE value into data TLB - cpu->itb->insert(ipr[ISA::IPR_ITB_TAG], pte); + cpu->itb->insert(ipr[TheISA::IPR_ITB_TAG], pte); } break; - case ISA::IPR_ITB_IA: + case TheISA::IPR_ITB_IA: // really a control write ipr[idx] = 0; cpu->itb->flushAll(); break; - case ISA::IPR_ITB_IAP: + case TheISA::IPR_ITB_IAP: // really a control write ipr[idx] = 0; cpu->itb->flushProcesses(); break; - case ISA::IPR_ITB_IS: + case TheISA::IPR_ITB_IS: // really a control write ipr[idx] = val; - cpu->itb->flushAddr(val, ITB_ASN_ASN(ipr[ISA::IPR_ITB_ASN])); + cpu->itb->flushAddr(val, ITB_ASN_ASN(ipr[TheISA::IPR_ITB_ASN])); break; default: diff --git a/cpu/o3/rename.hh b/cpu/o3/rename.hh index a17ec7311..9781480b6 100644 --- a/cpu/o3/rename.hh +++ b/cpu/o3/rename.hh @@ -46,7 +46,6 @@ class SimpleRename { public: // Typedefs from the Impl. - typedef typename Impl::ISA ISA; typedef typename Impl::CPUPol CPUPol; typedef typename Impl::DynInstPtr DynInstPtr; typedef typename Impl::FullCPU FullCPU; @@ -62,7 +61,8 @@ class SimpleRename typedef typename CPUPol::RenameMap RenameMap; // Typedefs from the ISA. - typedef typename ISA::Addr Addr; + typedef TheISA::Addr Addr; + typedef TheISA::RegIndex RegIndex; public: // Rename will block if ROB becomes full or issue queue becomes full, diff --git a/cpu/o3/rename_map.hh b/cpu/o3/rename_map.hh index c44c7a1ea..57be4a64a 100644 --- a/cpu/o3/rename_map.hh +++ b/cpu/o3/rename_map.hh @@ -38,9 +38,13 @@ #include #include "cpu/o3/free_list.hh" +//For RegIndex +#include "arch/isa_traits.hh" class SimpleRenameMap { + protected: + typedef TheISA::RegIndex RegIndex; public: /** * Pair of a logical register and a physical register. Tells the diff --git a/cpu/o3/rob.hh b/cpu/o3/rob.hh index 29ec48007..1185564ad 100644 --- a/cpu/o3/rob.hh +++ b/cpu/o3/rob.hh @@ -47,6 +47,8 @@ template class ROB { + protected: + typedef TheISA::RegIndex RegIndex; public: //Typedefs from the Impl. typedef typename Impl::FullCPU FullCPU; diff --git a/cpu/o3/store_set.hh b/cpu/o3/store_set.hh index bcd590384..c67d30fcb 100644 --- a/cpu/o3/store_set.hh +++ b/cpu/o3/store_set.hh @@ -31,11 +31,13 @@ #include -#include "arch/alpha/isa_traits.hh" +#include "arch/isa_traits.hh" #include "cpu/inst_seq.hh" class StoreSet { + protected: + typedef TheISA::Addr Addr; public: typedef unsigned SSID; diff --git a/cpu/o3/tournament_pred.hh b/cpu/o3/tournament_pred.hh index 58ea1a7d9..6cfd24cfb 100644 --- a/cpu/o3/tournament_pred.hh +++ b/cpu/o3/tournament_pred.hh @@ -30,11 +30,13 @@ #define __CPU_O3_CPU_TOURNAMENT_PRED_HH__ // For Addr type. -#include "arch/alpha/isa_traits.hh" +#include "arch/isa_traits.hh" #include "cpu/o3/sat_counter.hh" class TournamentBP { + protected: + typedef TheISA::Addr Addr; public: /** * Default branch predictor constructor. diff --git a/cpu/ozone/cpu.hh b/cpu/ozone/cpu.hh index 21fe05b6a..7976632d9 100644 --- a/cpu/ozone/cpu.hh +++ b/cpu/ozone/cpu.hh @@ -77,7 +77,6 @@ class OoOCPU : public BaseCPU private: typedef typename Impl::DynInst DynInst; typedef typename Impl::DynInstPtr DynInstPtr; - typedef typename Impl::ISA ISA; public: // main simulation loop (one cycle) @@ -378,12 +377,12 @@ class OoOCPU : public BaseCPU private: InstSeqNum globalSeqNum; - DynInstPtr renameTable[ISA::TotalNumRegs]; - DynInstPtr commitTable[ISA::TotalNumRegs]; + DynInstPtr renameTable[TheISA::TotalNumRegs]; + DynInstPtr commitTable[TheISA::TotalNumRegs]; // Might need a table of the shadow registers as well. #if FULL_SYSTEM - DynInstPtr palShadowTable[ISA::NumIntRegs]; + DynInstPtr palShadowTable[TheISA::NumIntRegs]; #endif public: @@ -402,47 +401,47 @@ class OoOCPU : public BaseCPU // rename table of DynInsts. Also these likely shouldn't be called very // often, other than when adding things into the xc during say a syscall. - uint64_t readIntReg(StaticInst *si, int idx) + uint64_t readIntReg(StaticInst *si, int idx) { return xc->readIntReg(si->srcRegIdx(idx)); } - float readFloatRegSingle(StaticInst *si, int idx) + float readFloatRegSingle(StaticInst *si, int idx) { int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; return xc->readFloatRegSingle(reg_idx); } - double readFloatRegDouble(StaticInst *si, int idx) + double readFloatRegDouble(StaticInst *si, int idx) { int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; return xc->readFloatRegDouble(reg_idx); } - uint64_t readFloatRegInt(StaticInst *si, int idx) + uint64_t readFloatRegInt(StaticInst *si, int idx) { int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; return xc->readFloatRegInt(reg_idx); } - void setIntReg(StaticInst *si, int idx, uint64_t val) + void setIntReg(StaticInst *si, int idx, uint64_t val) { xc->setIntReg(si->destRegIdx(idx), val); } - void setFloatRegSingle(StaticInst *si, int idx, float val) + void setFloatRegSingle(StaticInst *si, int idx, float val) { int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; xc->setFloatRegSingle(reg_idx, val); } - void setFloatRegDouble(StaticInst *si, int idx, double val) + void setFloatRegDouble(StaticInst *si, int idx, double val) { int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; xc->setFloatRegDouble(reg_idx, val); } - void setFloatRegInt(StaticInst *si, int idx, uint64_t val) + void setFloatRegInt(StaticInst *si, int idx, uint64_t val) { int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; xc->setFloatRegInt(reg_idx, val); @@ -479,7 +478,7 @@ class OoOCPU : public BaseCPU // We fold in the PISA 64- to 32-bit conversion here as well. Addr icacheBlockAlignPC(Addr addr) { - addr = ISA::realPCToFetchPC(addr); + addr = TheISA::realPCToFetchPC(addr); return (addr & ~(cacheBlkMask)); } diff --git a/cpu/pc_event.cc b/cpu/pc_event.cc index 83fbc3e2d..7a294866d 100644 --- a/cpu/pc_event.cc +++ b/cpu/pc_event.cc @@ -136,14 +136,14 @@ BreakPCEvent::process(ExecContext *xc) #if FULL_SYSTEM extern "C" void -sched_break_pc_sys(System *sys, Addr addr) +sched_break_pc_sys(System *sys, TheISA::Addr addr) { new BreakPCEvent(&sys->pcEventQueue, "debug break", addr, true); } extern "C" void -sched_break_pc(Addr addr) +sched_break_pc(TheISA::Addr addr) { for (vector::iterator sysi = System::systemList.begin(); sysi != System::systemList.end(); ++sysi) { diff --git a/cpu/pc_event.hh b/cpu/pc_event.hh index 7fa3902cc..3033a3cfd 100644 --- a/cpu/pc_event.hh +++ b/cpu/pc_event.hh @@ -39,6 +39,7 @@ class PCEventQueue; class PCEvent { protected: + typedef TheISA::Addr Addr; static const Addr badpc = MemReq::inval_addr; protected: @@ -64,6 +65,7 @@ class PCEvent class PCEventQueue { protected: + typedef TheISA::Addr Addr; typedef PCEvent * record_t; class MapCompare { public: @@ -132,6 +134,7 @@ PCEvent::remove() class BreakPCEvent : public PCEvent { protected: + typedef TheISA::Addr Addr; bool remove; public: diff --git a/cpu/profile.hh b/cpu/profile.hh index 58cd7e79f..b55f87a6a 100644 --- a/cpu/profile.hh +++ b/cpu/profile.hh @@ -37,6 +37,8 @@ class ProfileNode { + protected: + typedef TheISA::Addr Addr; private: friend class FunctionProfile; @@ -57,6 +59,8 @@ class ProfileNode class Callback; class FunctionProfile { + public: + typedef TheISA::Addr Addr; private: Callback *reset; const SymbolTable *symtab; @@ -68,7 +72,7 @@ class FunctionProfile FunctionProfile(const SymbolTable *symtab); ~FunctionProfile(); - ProfileNode *consume(ExecContext *xc, StaticInstPtr inst); + ProfileNode *consume(ExecContext *xc, StaticInstPtr inst); ProfileNode *consume(const std::vector &stack); void clear(); void dump(ExecContext *xc, std::ostream &out) const; @@ -76,7 +80,7 @@ class FunctionProfile }; inline ProfileNode * -FunctionProfile::consume(ExecContext *xc, StaticInstPtr inst) +FunctionProfile::consume(ExecContext *xc, StaticInstPtr inst) { if (!trace.trace(xc, inst)) return NULL; diff --git a/cpu/simple/cpu.cc b/cpu/simple/cpu.cc index 6aff94abd..c3f256de9 100644 --- a/cpu/simple/cpu.cc +++ b/cpu/simple/cpu.cc @@ -76,7 +76,7 @@ using namespace std; //The SimpleCPU does alpha only -using namespace LittleEndianGuest; +using namespace AlphaISA; SimpleCPU::TickEvent::TickEvent(SimpleCPU *c, int w) @@ -125,7 +125,7 @@ SimpleCPU::SimpleCPU(Params *p) xc = new ExecContext(this, 0, p->system, p->itb, p->dtb, p->mem); // initialize CPU, including PC - TheISA::initCPU(&xc->regs); + initCPU(&xc->regs); #else xc = new ExecContext(this, /* thread_num */ 0, p->process, /* asid */ 0); #endif // !FULL_SYSTEM @@ -323,7 +323,7 @@ SimpleCPU::copySrcTranslate(Addr src) // Make sure block doesn't span page if (no_warn && - (src & TheISA::PageMask) != ((src + blk_size) & TheISA::PageMask) && + (src & PageMask) != ((src + blk_size) & PageMask) && (src >> 40) != 0xfffffc) { warn("Copied block source spans pages %x.", src); no_warn = false; @@ -359,7 +359,7 @@ SimpleCPU::copy(Addr dest) // Make sure block doesn't span page if (no_warn && - (dest & TheISA::PageMask) != ((dest + blk_size) & TheISA::PageMask) && + (dest & PageMask) != ((dest + blk_size) & PageMask) && (dest >> 40) != 0xfffffc) { no_warn = false; warn("Copied block destination spans pages %x. ", dest); @@ -648,20 +648,20 @@ SimpleCPU::tick() checkInterrupts = false; IntReg *ipr = xc->regs.ipr; - if (xc->regs.ipr[TheISA::IPR_SIRR]) { - for (int i = TheISA::INTLEVEL_SOFTWARE_MIN; - i < TheISA::INTLEVEL_SOFTWARE_MAX; i++) { - if (ipr[TheISA::IPR_SIRR] & (ULL(1) << i)) { + if (xc->regs.ipr[IPR_SIRR]) { + for (int i = INTLEVEL_SOFTWARE_MIN; + i < INTLEVEL_SOFTWARE_MAX; i++) { + if (ipr[IPR_SIRR] & (ULL(1) << i)) { // See table 4-19 of 21164 hardware reference - ipl = (i - TheISA::INTLEVEL_SOFTWARE_MIN) + 1; + ipl = (i - INTLEVEL_SOFTWARE_MIN) + 1; summary |= (ULL(1) << i); } } } uint64_t interrupts = xc->cpu->intr_status(); - for (int i = TheISA::INTLEVEL_EXTERNAL_MIN; - i < TheISA::INTLEVEL_EXTERNAL_MAX; i++) { + for (int i = INTLEVEL_EXTERNAL_MIN; + i < INTLEVEL_EXTERNAL_MAX; i++) { if (interrupts & (ULL(1) << i)) { // See table 4-19 of 21164 hardware reference ipl = i; @@ -669,16 +669,16 @@ SimpleCPU::tick() } } - if (ipr[TheISA::IPR_ASTRR]) + if (ipr[IPR_ASTRR]) panic("asynchronous traps not implemented\n"); - if (ipl && ipl > xc->regs.ipr[TheISA::IPR_IPLR]) { - ipr[TheISA::IPR_ISR] = summary; - ipr[TheISA::IPR_INTID] = ipl; + if (ipl && ipl > xc->regs.ipr[IPR_IPLR]) { + ipr[IPR_ISR] = summary; + ipr[IPR_INTID] = ipl; xc->ev5_trap(InterruptFault); DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n", - ipr[TheISA::IPR_IPLR], ipl, summary); + ipr[IPR_IPLR], ipl, summary); } } #endif @@ -749,7 +749,7 @@ SimpleCPU::tick() // decode the instruction inst = gtoh(inst); - curStaticInst = StaticInst::decode(inst); + curStaticInst = StaticInst::decode(inst); traceData = Trace::getInstRecord(curTick, xc, this, curStaticInst, xc->regs.pc); diff --git a/cpu/simple/cpu.hh b/cpu/simple/cpu.hh index e7a447117..8a3900726 100644 --- a/cpu/simple/cpu.hh +++ b/cpu/simple/cpu.hh @@ -63,6 +63,8 @@ namespace Trace { class SimpleCPU : public BaseCPU { + protected: + typedef TheISA::MachInst MachInst; public: // main simulation loop (one cycle) void tick(); @@ -172,7 +174,7 @@ class SimpleCPU : public BaseCPU // the next switchover Sampler *sampler; - StaticInstPtr curStaticInst; + StaticInstPtr curStaticInst; class CacheCompletionEvent : public Event { @@ -269,47 +271,47 @@ class SimpleCPU : public BaseCPU // storage (which is pretty hard to imagine they would have reason // to do). - uint64_t readIntReg(const StaticInst *si, int idx) + uint64_t readIntReg(const StaticInst *si, int idx) { return xc->readIntReg(si->srcRegIdx(idx)); } - float readFloatRegSingle(const StaticInst *si, int idx) + float readFloatRegSingle(const StaticInst *si, int idx) { int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; return xc->readFloatRegSingle(reg_idx); } - double readFloatRegDouble(const StaticInst *si, int idx) + double readFloatRegDouble(const StaticInst *si, int idx) { int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; return xc->readFloatRegDouble(reg_idx); } - uint64_t readFloatRegInt(const StaticInst *si, int idx) + uint64_t readFloatRegInt(const StaticInst *si, int idx) { int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; return xc->readFloatRegInt(reg_idx); } - void setIntReg(const StaticInst *si, int idx, uint64_t val) + void setIntReg(const StaticInst *si, int idx, uint64_t val) { xc->setIntReg(si->destRegIdx(idx), val); } - void setFloatRegSingle(const StaticInst *si, int idx, float val) + void setFloatRegSingle(const StaticInst *si, int idx, float val) { int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; xc->setFloatRegSingle(reg_idx, val); } - void setFloatRegDouble(const StaticInst *si, int idx, double val) + void setFloatRegDouble(const StaticInst *si, int idx, double val) { int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; xc->setFloatRegDouble(reg_idx, val); } - void setFloatRegInt(const StaticInst *si, int idx, uint64_t val) + void setFloatRegInt(const StaticInst *si, int idx, uint64_t val) { int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; xc->setFloatRegInt(reg_idx, val); diff --git a/cpu/static_inst.cc b/cpu/static_inst.cc index 54bd9914e..c307dc6fc 100644 --- a/cpu/static_inst.cc +++ b/cpu/static_inst.cc @@ -30,19 +30,13 @@ #include "cpu/static_inst.hh" #include "sim/root.hh" -template -StaticInstPtr StaticInst::nullStaticInstPtr; - -template -typename StaticInst::DecodeCache StaticInst::decodeCache; +StaticInstPtr StaticInst::nullStaticInstPtr; // Define the decode cache hash map. -template StaticInst::DecodeCache -StaticInst::decodeCache; +StaticInst::DecodeCache StaticInst::decodeCache; -template void -StaticInst::dumpDecodeCacheStats() +StaticInst::dumpDecodeCacheStats() { using namespace std; @@ -62,13 +56,8 @@ StaticInst::dumpDecodeCacheStats() } } - -template StaticInstPtr -StaticInst::nullStaticInstPtr; - -template bool -StaticInst::hasBranchTarget(Addr pc, ExecContext *xc, Addr &tgt) const +StaticInst::hasBranchTarget(Addr pc, ExecContext *xc, Addr &tgt) const { if (isDirectCtrl()) { tgt = branchTarget(pc); @@ -83,6 +72,3 @@ StaticInst::hasBranchTarget(Addr pc, ExecContext *xc, Addr &tgt) const return false; } - -// force instantiation of template function(s) above -template class StaticInst; diff --git a/cpu/static_inst.hh b/cpu/static_inst.hh index 24997eadc..6be30cd31 100644 --- a/cpu/static_inst.hh +++ b/cpu/static_inst.hh @@ -208,7 +208,6 @@ class StaticInstBase : public RefCounted // forward declaration -template class StaticInstPtr; /** @@ -218,21 +217,20 @@ class StaticInstPtr; * that are generic across all ISAs but that differ in details * according to the specific ISA being used. */ -template class StaticInst : public StaticInstBase { public: /// Binary machine instruction type. - typedef typename ISA::MachInst MachInst; + typedef TheISA::MachInst MachInst; /// Memory address type. - typedef typename ISA::Addr Addr; + typedef TheISA::Addr Addr; /// Logical register index type. - typedef typename ISA::RegIndex RegIndex; + typedef TheISA::RegIndex RegIndex; enum { - MaxInstSrcRegs = ISA::MaxInstSrcRegs, //< Max source regs - MaxInstDestRegs = ISA::MaxInstDestRegs, //< Max dest regs + MaxInstSrcRegs = TheISA::MaxInstSrcRegs, //< Max source regs + MaxInstDestRegs = TheISA::MaxInstDestRegs, //< Max dest regs }; @@ -247,7 +245,7 @@ class StaticInst : public StaticInstBase /// Pointer to a statically allocated "null" instruction object. /// Used to give eaCompInst() and memAccInst() something to return /// when called on non-memory instructions. - static StaticInstPtr nullStaticInstPtr; + static StaticInstPtr nullStaticInstPtr; /** * Memory references only: returns "fake" instruction representing @@ -256,7 +254,7 @@ class StaticInst : public StaticInstBase * just the EA computation. */ virtual const - StaticInstPtr &eaCompInst() const { return nullStaticInstPtr; } + StaticInstPtr &eaCompInst() const { return nullStaticInstPtr; } /** * Memory references only: returns "fake" instruction representing @@ -265,7 +263,7 @@ class StaticInst : public StaticInstBase * just the memory access (not the EA computation). */ virtual const - StaticInstPtr &memAccInst() const { return nullStaticInstPtr; } + StaticInstPtr &memAccInst() const { return nullStaticInstPtr; } /// The binary machine instruction. const MachInst machInst; @@ -364,7 +362,7 @@ class StaticInst : public StaticInstBase /// Decoded instruction cache type. /// For now we're using a generic hash_map; this seems to work /// pretty well. - typedef m5::hash_map > DecodeCache; + typedef m5::hash_map DecodeCache; /// A cache of decoded instruction objects. static DecodeCache decodeCache; @@ -378,63 +376,40 @@ class StaticInst : public StaticInstBase /// Decode a machine instruction. /// @param mach_inst The binary instruction to decode. /// @retval A pointer to the corresponding StaticInst object. - static - StaticInstPtr decode(MachInst mach_inst) - { -#ifdef DECODE_CACHE_HASH_STATS - // Simple stats on decode hash_map. Turns out the default - // hash function is as good as anything I could come up with. - const int dump_every_n = 10000000; - static int decodes_til_dump = dump_every_n; - - if (--decodes_til_dump == 0) { - dumpDecodeCacheStats(); - decodes_til_dump = dump_every_n; - } -#endif - - typename DecodeCache::iterator iter = decodeCache.find(mach_inst); - if (iter != decodeCache.end()) { - return iter->second; - } - - StaticInstPtr si = ISA::decodeInst(mach_inst); - decodeCache[mach_inst] = si; - return si; - } + //This is defined as inline below. + static StaticInstPtr decode(MachInst mach_inst); }; typedef RefCountingPtr StaticInstBasePtr; /// Reference-counted pointer to a StaticInst object. -/// This type should be used instead of "StaticInst *" so that +/// This type should be used instead of "StaticInst *" so that /// StaticInst objects can be properly reference-counted. -template -class StaticInstPtr : public RefCountingPtr > +class StaticInstPtr : public RefCountingPtr { public: /// Constructor. StaticInstPtr() - : RefCountingPtr >() + : RefCountingPtr() { } - /// Conversion from "StaticInst *". - StaticInstPtr(StaticInst *p) - : RefCountingPtr >(p) + /// Conversion from "StaticInst *". + StaticInstPtr(StaticInst *p) + : RefCountingPtr(p) { } /// Copy constructor. StaticInstPtr(const StaticInstPtr &r) - : RefCountingPtr >(r) + : RefCountingPtr(r) { } /// Construct directly from machine instruction. - /// Calls StaticInst::decode(). - StaticInstPtr(typename ISA::MachInst mach_inst) - : RefCountingPtr >(StaticInst::decode(mach_inst)) + /// Calls StaticInst::decode(). + StaticInstPtr(TheISA::MachInst mach_inst) + : RefCountingPtr(StaticInst::decode(mach_inst)) { } @@ -445,4 +420,29 @@ class StaticInstPtr : public RefCountingPtr > } }; +inline StaticInstPtr +StaticInst::decode(StaticInst::MachInst mach_inst) +{ +#ifdef DECODE_CACHE_HASH_STATS + // Simple stats on decode hash_map. Turns out the default + // hash function is as good as anything I could come up with. + const int dump_every_n = 10000000; + static int decodes_til_dump = dump_every_n; + + if (--decodes_til_dump == 0) { + dumpDecodeCacheStats(); + decodes_til_dump = dump_every_n; + } +#endif + + DecodeCache::iterator iter = decodeCache.find(mach_inst); + if (iter != decodeCache.end()) { + return iter->second; + } + + StaticInstPtr si = TheISA::decodeInst(mach_inst); + decodeCache[mach_inst] = si; + return si; +} + #endif // __CPU_STATIC_INST_HH__ diff --git a/cpu/trace/opt_cpu.hh b/cpu/trace/opt_cpu.hh index f81691733..704dc09fa 100644 --- a/cpu/trace/opt_cpu.hh +++ b/cpu/trace/opt_cpu.hh @@ -49,6 +49,8 @@ class MemTraceReader; */ class OptCPU : public SimObject { + protected: + typedef TheISA::Addr Addr; private: typedef int RefIndex; diff --git a/cpu/trace/reader/itx_reader.hh b/cpu/trace/reader/itx_reader.hh index faec73138..e402b2d52 100644 --- a/cpu/trace/reader/itx_reader.hh +++ b/cpu/trace/reader/itx_reader.hh @@ -46,6 +46,9 @@ */ class ITXReader : public MemTraceReader { + protected: + typedef TheISA::Addr Addr; + private: /** Trace file. */ FILE *trace; diff --git a/dev/alpha_console.cc b/dev/alpha_console.cc index 38fbbdef0..a7ef8f641 100644 --- a/dev/alpha_console.cc +++ b/dev/alpha_console.cc @@ -53,6 +53,7 @@ #include "sim/system.hh" using namespace std; +using namespace AlphaISA; AlphaConsole::AlphaConsole(const string &name, SimConsole *cons, SimpleDisk *d, System *s, BaseCPU *c, Platform *p, diff --git a/dev/baddev.cc b/dev/baddev.cc index b6ca919e4..62871e348 100644 --- a/dev/baddev.cc +++ b/dev/baddev.cc @@ -46,6 +46,7 @@ #include "sim/system.hh" using namespace std; +using namespace TheISA; BadDevice::BadDevice(const string &name, Addr a, MemoryController *mmu, HierParams *hier, Bus *pio_bus, const string &devicename) diff --git a/dev/ide_ctrl.cc b/dev/ide_ctrl.cc index a5cb0dfd8..18c988b81 100644 --- a/dev/ide_ctrl.cc +++ b/dev/ide_ctrl.cc @@ -48,6 +48,7 @@ #include "sim/sim_object.hh" using namespace std; +using namespace TheISA; //// // Initialization and destruction diff --git a/dev/ide_disk.cc b/dev/ide_disk.cc index 9d8bb8825..41400c590 100644 --- a/dev/ide_disk.cc +++ b/dev/ide_disk.cc @@ -53,6 +53,7 @@ #include "arch/isa_traits.hh" using namespace std; +using namespace TheISA; IdeDisk::IdeDisk(const string &name, DiskImage *img, PhysicalMemory *phys, int id, Tick delay) diff --git a/dev/ide_disk.hh b/dev/ide_disk.hh index a656ca464..32888c81c 100644 --- a/dev/ide_disk.hh +++ b/dev/ide_disk.hh @@ -187,6 +187,8 @@ class IdeController; */ class IdeDisk : public SimObject { + protected: + typedef TheISA::Addr Addr; protected: /** The IDE controller for this disk. */ IdeController *ctrl; diff --git a/dev/isa_fake.cc b/dev/isa_fake.cc index 93c9eedbf..117c9e5ad 100644 --- a/dev/isa_fake.cc +++ b/dev/isa_fake.cc @@ -45,6 +45,7 @@ #include "sim/system.hh" using namespace std; +using namespace TheISA; IsaFake::IsaFake(const string &name, Addr a, MemoryController *mmu, HierParams *hier, Bus *pio_bus, Addr size) diff --git a/dev/ns_gige.cc b/dev/ns_gige.cc index c28615438..07bf178fc 100644 --- a/dev/ns_gige.cc +++ b/dev/ns_gige.cc @@ -84,6 +84,7 @@ const char *NsDmaState[] = using namespace std; using namespace Net; +using namespace TheISA; /////////////////////////////////////////////////////////////////////// // diff --git a/dev/pciconfigall.cc b/dev/pciconfigall.cc index 1175172c4..c581e1561 100644 --- a/dev/pciconfigall.cc +++ b/dev/pciconfigall.cc @@ -47,6 +47,7 @@ #include "sim/system.hh" using namespace std; +using namespace TheISA; PciConfigAll::PciConfigAll(const string &name, Addr a, MemoryController *mmu, diff --git a/dev/pcidev.hh b/dev/pcidev.hh index c8d9685c1..a100bf746 100644 --- a/dev/pcidev.hh +++ b/dev/pcidev.hh @@ -53,6 +53,8 @@ class MemoryController; */ class PciConfigData : public SimObject { + protected: + typedef TheISA::Addr Addr; public: /** * Constructor to initialize the devices config space to 0. diff --git a/dev/platform.cc b/dev/platform.cc index 58f94db7b..5b667b12c 100644 --- a/dev/platform.cc +++ b/dev/platform.cc @@ -31,6 +31,7 @@ #include "sim/sim_exit.hh" using namespace std; +using namespace TheISA; Platform::Platform(const string &name, IntrControl *intctrl, PciConfigAll *pci) : SimObject(name), intrctrl(intctrl), pciconfig(pci) diff --git a/dev/platform.hh b/dev/platform.hh index 1ee645454..87810250a 100644 --- a/dev/platform.hh +++ b/dev/platform.hh @@ -44,6 +44,8 @@ class Uart; class Platform : public SimObject { + protected: + typedef TheISA::Addr Addr; public: /** Pointer to the interrupt controller */ IntrControl *intrctrl; diff --git a/dev/simple_disk.hh b/dev/simple_disk.hh index 6560e15c2..f68d5bfff 100644 --- a/dev/simple_disk.hh +++ b/dev/simple_disk.hh @@ -44,19 +44,21 @@ class PhysicalMemory; */ class SimpleDisk : public SimObject { -public: - typedef uint64_t baddr_t; + protected: + typedef TheISA::Addr Addr; + public: + typedef uint64_t baddr_t; -protected: - PhysicalMemory *physmem; - DiskImage *image; + protected: + PhysicalMemory *physmem; + DiskImage *image; -public: - SimpleDisk(const std::string &name, PhysicalMemory *pmem, DiskImage *img); - ~SimpleDisk(); + public: + SimpleDisk(const std::string &name, PhysicalMemory *pmem, DiskImage *img); + ~SimpleDisk(); - void read(Addr addr, baddr_t block, int count) const; - void write(Addr addr, baddr_t block, int count); + void read(Addr addr, baddr_t block, int count) const; + void write(Addr addr, baddr_t block, int count); }; #endif // __DEV_SIMPLE_DISK_HH__ diff --git a/dev/sinic.cc b/dev/sinic.cc index e79f80678..829d58d32 100644 --- a/dev/sinic.cc +++ b/dev/sinic.cc @@ -50,6 +50,7 @@ #include "targetarch/vtophys.hh" using namespace Net; +using namespace TheISA; namespace Sinic { diff --git a/dev/sinicreg.hh b/dev/sinicreg.hh index b7008b4e1..343db6303 100644 --- a/dev/sinicreg.hh +++ b/dev/sinicreg.hh @@ -165,7 +165,7 @@ struct Info /* namespace Regs */ } inline const Regs::Info& -regInfo(Addr daddr) +regInfo(TheISA::Addr daddr) { static Regs::Info invalid = { 0, false, false, false, false, "invalid" }; static Regs::Info info [] = { @@ -201,7 +201,7 @@ regInfo(Addr daddr) } inline bool -regValid(Addr daddr) +regValid(TheISA::Addr daddr) { if (daddr > Regs::Size) return false; diff --git a/dev/tsunami.cc b/dev/tsunami.cc index 760848a00..58fc7434e 100644 --- a/dev/tsunami.cc +++ b/dev/tsunami.cc @@ -46,6 +46,8 @@ #include "sim/system.hh" using namespace std; +//Should this be AlphaISA? +using namespace TheISA; Tsunami::Tsunami(const string &name, System *s, IntrControl *ic, PciConfigAll *pci) diff --git a/dev/tsunami.hh b/dev/tsunami.hh index 7fd91d5b2..79b561ed7 100644 --- a/dev/tsunami.hh +++ b/dev/tsunami.hh @@ -55,6 +55,8 @@ class System; class Tsunami : public Platform { + protected: + typedef TheISA::Addr Addr; public: /** Max number of CPUs in a Tsunami */ static const int Max_CPUs = 64; diff --git a/dev/tsunami_cchip.cc b/dev/tsunami_cchip.cc index 4cda9ec36..10c08a7a2 100644 --- a/dev/tsunami_cchip.cc +++ b/dev/tsunami_cchip.cc @@ -47,6 +47,8 @@ #include "sim/system.hh" using namespace std; +//Should this be AlphaISA? +using namespace TheISA; TsunamiCChip::TsunamiCChip(const string &name, Tsunami *t, Addr a, MemoryController *mmu, HierParams *hier, diff --git a/dev/tsunami_io.cc b/dev/tsunami_io.cc index 0d0d27570..e90bb5abc 100644 --- a/dev/tsunami_io.cc +++ b/dev/tsunami_io.cc @@ -50,6 +50,8 @@ #include "mem/functional/memory_control.hh" using namespace std; +//Should this be AlphaISA? +using namespace TheISA; TsunamiIO::RTC::RTC(const string &name, Tsunami* t, Tick i) : _name(name), event(t, i), addr(0) diff --git a/dev/tsunami_pchip.cc b/dev/tsunami_pchip.cc index a4c04a79f..706daf9dc 100644 --- a/dev/tsunami_pchip.cc +++ b/dev/tsunami_pchip.cc @@ -47,6 +47,8 @@ #include "sim/system.hh" using namespace std; +//Should this be AlphaISA? +using namespace TheISA; TsunamiPChip::TsunamiPChip(const string &name, Tsunami *t, Addr a, MemoryController *mmu, HierParams *hier, diff --git a/dev/uart8250.cc b/dev/uart8250.cc index a2e782189..99355e28a 100644 --- a/dev/uart8250.cc +++ b/dev/uart8250.cc @@ -46,6 +46,7 @@ #include "sim/builder.hh" using namespace std; +using namespace TheISA; Uart8250::IntrEvent::IntrEvent(Uart8250 *u, int bit) : Event(&mainEventQueue), uart(u) diff --git a/kern/freebsd/freebsd_system.cc b/kern/freebsd/freebsd_system.cc index dbf60a3fc..cead8caaf 100644 --- a/kern/freebsd/freebsd_system.cc +++ b/kern/freebsd/freebsd_system.cc @@ -46,6 +46,7 @@ #define TIMER_FREQUENCY 1193180 using namespace std; +using namespace TheISA; FreebsdSystem::FreebsdSystem(Params *p) : System(p) diff --git a/kern/kernel_stats.hh b/kern/kernel_stats.hh index 98cc044ac..e4d5ec011 100644 --- a/kern/kernel_stats.hh +++ b/kern/kernel_stats.hh @@ -50,6 +50,8 @@ extern const char *modestr[]; class Binning { + protected: + typedef TheISA::Addr Addr; private: std::string myname; System *system; @@ -106,7 +108,7 @@ class Binning cpu_mode themode; void palSwapContext(ExecContext *xc); - void execute(ExecContext *xc, StaticInstPtr inst); + void execute(ExecContext *xc, StaticInstPtr inst); void call(ExecContext *xc, Stats::MainBin *myBin); void changeMode(cpu_mode mode); @@ -124,6 +126,9 @@ class Binning class Statistics : public Serializable { + protected: + typedef TheISA::Addr Addr; + private: friend class Binning; private: diff --git a/kern/linux/aligned.hh b/kern/linux/aligned.hh index 18d1b43c0..137f65076 100644 --- a/kern/linux/aligned.hh +++ b/kern/linux/aligned.hh @@ -37,7 +37,7 @@ #if __GNUC__ == 3 && __GNUC_MINOR__ != 3 typedef uint64_t uint64_ta __attribute__ ((aligned (8))) ; typedef int64_t int64_ta __attribute__ ((aligned (8))) ; -typedef Addr Addr_a __attribute__ ((aligned (8))) ; +typedef TheISA::Addr Addr_a __attribute__ ((aligned (8))) ; #else #define uint64_ta uint64_t __attribute__ ((aligned (8))) #define int64_ta int64_t __attribute__ ((aligned (8))) diff --git a/kern/linux/linux_system.cc b/kern/linux/linux_system.cc index 26a4c0d3e..c5a9e184a 100644 --- a/kern/linux/linux_system.cc +++ b/kern/linux/linux_system.cc @@ -50,6 +50,7 @@ #include "targetarch/vtophys.hh" using namespace std; +using namespace TheISA; LinuxSystem::LinuxSystem(Params *p) : System(p) diff --git a/kern/linux/linux_threadinfo.hh b/kern/linux/linux_threadinfo.hh index 9bab1dc49..f20188360 100644 --- a/kern/linux/linux_threadinfo.hh +++ b/kern/linux/linux_threadinfo.hh @@ -37,6 +37,8 @@ namespace Linux { class ThreadInfo { + protected: + typedef TheISA::Addr Addr; private: ExecContext *xc; @@ -53,7 +55,7 @@ class ThreadInfo * thread_info struct. So we can get the address by masking off * the lower 14 bits. */ - current = xc->regs.intRegFile[StackPointerReg] & ~0x3fff; + current = xc->regs.intRegFile[TheISA::StackPointerReg] & ~0x3fff; return VPtr(xc, current); } diff --git a/kern/system_events.cc b/kern/system_events.cc index ba3c9274a..55595b9b6 100644 --- a/kern/system_events.cc +++ b/kern/system_events.cc @@ -29,6 +29,8 @@ #include "encumbered/cpu/full/cpu.hh" #include "kern/kernel_stats.hh" +using namespace TheISA; + void SkipFuncEvent::process(ExecContext *xc) { diff --git a/kern/tru64/dump_mbuf.cc b/kern/tru64/dump_mbuf.cc index 85cb4de96..efdaed62d 100644 --- a/kern/tru64/dump_mbuf.cc +++ b/kern/tru64/dump_mbuf.cc @@ -38,6 +38,8 @@ #include "arch/isa_traits.hh" #include "targetarch/vtophys.hh" +using namespace TheISA; + namespace tru64 { void diff --git a/kern/tru64/mbuf.hh b/kern/tru64/mbuf.hh index 93424858f..7b84b5e10 100644 --- a/kern/tru64/mbuf.hh +++ b/kern/tru64/mbuf.hh @@ -35,35 +35,35 @@ namespace tru64 { struct m_hdr { - Addr mh_next; // 0x00 - Addr mh_nextpkt; // 0x08 - Addr mh_data; // 0x10 + TheISA::Addr mh_next; // 0x00 + TheISA::Addr mh_nextpkt; // 0x08 + TheISA::Addr mh_data; // 0x10 int32_t mh_len; // 0x18 int32_t mh_type; // 0x1C int32_t mh_flags; // 0x20 int32_t mh_pad0; // 0x24 - Addr mh_foo[4]; // 0x28, 0x30, 0x38, 0x40 + TheISA::Addr mh_foo[4]; // 0x28, 0x30, 0x38, 0x40 }; struct pkthdr { int32_t len; int32_t protocolSum; - Addr rcvif; + TheISA::Addr rcvif; }; struct m_ext { - Addr ext_buf; // 0x00 - Addr ext_free; // 0x08 + TheISA::Addr ext_buf; // 0x00 + TheISA::Addr ext_free; // 0x08 uint32_t ext_size; // 0x10 uint32_t ext_pad0; // 0x14 - Addr ext_arg; // 0x18 + TheISA::Addr ext_arg; // 0x18 struct ext_refq { - Addr forw, back; // 0x20, 0x28 + TheISA::Addr forw, back; // 0x20, 0x28 } ext_ref; - Addr uiomove_f; // 0x30 + TheISA::Addr uiomove_f; // 0x30 int32_t protocolSum; // 0x38 int32_t bytesSummed; // 0x3C - Addr checksum; // 0x40 + TheISA::Addr checksum; // 0x40 }; struct mbuf { diff --git a/kern/tru64/tru64_events.cc b/kern/tru64/tru64_events.cc index d769aab0f..2fe6a2dc4 100644 --- a/kern/tru64/tru64_events.cc +++ b/kern/tru64/tru64_events.cc @@ -36,6 +36,8 @@ #include "targetarch/arguments.hh" #include "arch/isa_traits.hh" +using namespace TheISA; + //void SkipFuncEvent::process(ExecContext *xc); void diff --git a/sim/process.cc b/sim/process.cc index 59d122b48..b2f3046fb 100644 --- a/sim/process.cc +++ b/sim/process.cc @@ -53,6 +53,7 @@ #endif using namespace std; +using namespace TheISA; // // The purpose of this code is to fake the loader & syscall mechanism diff --git a/sim/process.hh b/sim/process.hh index 43fafd9d7..f5b713e3c 100644 --- a/sim/process.hh +++ b/sim/process.hh @@ -50,6 +50,10 @@ class ExecContext; class FunctionalMemory; class Process : public SimObject { + protected: + typedef TheISA::Addr Addr; + typedef TheISA::RegFile RegFile; + typedef TheISA::MachInst MachInst; public: // have we initialized an execution context from this process? If diff --git a/sim/pseudo_inst.cc b/sim/pseudo_inst.cc index 11ab55f53..58ea8266f 100644 --- a/sim/pseudo_inst.cc +++ b/sim/pseudo_inst.cc @@ -53,6 +53,7 @@ using namespace std; extern Sampler *SampCPU; using namespace Stats; +using namespace TheISA; namespace AlphaPseudo { diff --git a/sim/pseudo_inst.hh b/sim/pseudo_inst.hh index 3857f2050..07bdd7091 100644 --- a/sim/pseudo_inst.hh +++ b/sim/pseudo_inst.hh @@ -52,8 +52,8 @@ namespace AlphaPseudo void dumpstats(ExecContext *xc, Tick delay, Tick period); void dumpresetstats(ExecContext *xc, Tick delay, Tick period); void m5checkpoint(ExecContext *xc, Tick delay, Tick period); - uint64_t readfile(ExecContext *xc, Addr vaddr, uint64_t len, uint64_t offset); + uint64_t readfile(ExecContext *xc, TheISA::Addr vaddr, uint64_t len, uint64_t offset); void debugbreak(ExecContext *xc); void switchcpu(ExecContext *xc); - void addsymbol(ExecContext *xc, Addr addr, Addr symbolAddr); + void addsymbol(ExecContext *xc, TheISA::Addr addr, TheISA::Addr symbolAddr); } diff --git a/sim/syscall_emul.cc b/sim/syscall_emul.cc index 0fac43fc5..68001b0d1 100644 --- a/sim/syscall_emul.cc +++ b/sim/syscall_emul.cc @@ -40,6 +40,7 @@ #include "sim/sim_events.hh" using namespace std; +using namespace TheISA; void SyscallDesc::doSyscall(int callnum, Process *process, ExecContext *xc) @@ -89,7 +90,7 @@ exitFunc(SyscallDesc *desc, int callnum, Process *process, SyscallReturn getpagesizeFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) { - return VMPageSize; + return (int)VMPageSize; } diff --git a/sim/syscall_emul.hh b/sim/syscall_emul.hh index 739cd20e5..bc22c5c4c 100644 --- a/sim/syscall_emul.hh +++ b/sim/syscall_emul.hh @@ -90,6 +90,9 @@ class SyscallDesc { class BaseBufferArg { + protected: + typedef TheISA::Addr Addr; + public: BaseBufferArg(Addr _addr, int _size) : addr(_addr), size(_size) @@ -636,7 +639,7 @@ template SyscallReturn mmapFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) { - Addr start = xc->getSyscallArg(0); + TheISA::Addr start = xc->getSyscallArg(0); uint64_t length = xc->getSyscallArg(1); // int prot = xc->getSyscallArg(2); int flags = xc->getSyscallArg(3); @@ -646,7 +649,7 @@ mmapFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) if (start == 0) { // user didn't give an address... pick one from our "mmap region" start = p->mmap_end; - p->mmap_end += roundUp(length, VMPageSize); + p->mmap_end += roundUp(length, TheISA::VMPageSize); if (p->nxm_start != 0) { //If we have an nxm space, make sure we haven't colided assert(p->mmap_end < p->nxm_start); diff --git a/sim/system.cc b/sim/system.cc index 990145826..ebeb5b244 100644 --- a/sim/system.cc +++ b/sim/system.cc @@ -41,6 +41,7 @@ #include "base/trace.hh" using namespace std; +using namespace TheISA; vector System::systemList; diff --git a/sim/system.hh b/sim/system.hh index aa697c040..4bf33a170 100644 --- a/sim/system.hh +++ b/sim/system.hh @@ -50,6 +50,8 @@ namespace Kernel { class Binning; } class System : public SimObject { + protected: + typedef TheISA::Addr Addr; public: MemoryController *memctrl; PhysicalMemory *physmem; diff --git a/sim/vptr.hh b/sim/vptr.hh index 7ec43602d..1baa00610 100644 --- a/sim/vptr.hh +++ b/sim/vptr.hh @@ -37,6 +37,8 @@ class ExecContext; template class VPtr { + protected: + typedef TheISA::Addr Addr; public: typedef T Type; From ed25d326174f8086a8224ecb9e798410db14cddb Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 19 Feb 2006 03:04:44 -0500 Subject: [PATCH 072/180] Remade some changes which were undone cpu/base.hh: cpu/static_inst.hh: Changed include of targetarch/isa_traits.hh back to arch/isa_traits.hh cpu/exec_context.hh: Changed Fault back to Fault * --HG-- extra : convert_revision : 410f2e2472f8aa5bf92619a5defdf85f689a5597 --- cpu/base.hh | 2 +- cpu/exec_context.hh | 36 ++++++++++++++++++------------------ cpu/static_inst.hh | 2 +- 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/cpu/base.hh b/cpu/base.hh index 82a47bf4c..311b50f7f 100644 --- a/cpu/base.hh +++ b/cpu/base.hh @@ -36,7 +36,7 @@ #include "cpu/sampler/sampler.hh" #include "sim/eventq.hh" #include "sim/sim_object.hh" -#include "targetarch/isa_traits.hh" +#include "arch/isa_traits.hh" #if FULL_SYSTEM class System; diff --git a/cpu/exec_context.hh b/cpu/exec_context.hh index f11d69273..3c6bad34d 100644 --- a/cpu/exec_context.hh +++ b/cpu/exec_context.hh @@ -214,17 +214,17 @@ class ExecContext int getInstAsid() { return regs.instAsid(); } int getDataAsid() { return regs.dataAsid(); } - Fault translateInstReq(MemReqPtr &req) + Fault * translateInstReq(MemReqPtr &req) { return itb->translate(req); } - Fault translateDataReadReq(MemReqPtr &req) + Fault * translateDataReadReq(MemReqPtr &req) { return dtb->translate(req, false); } - Fault translateDataWriteReq(MemReqPtr &req) + Fault * translateDataWriteReq(MemReqPtr &req) { return dtb->translate(req, true); } @@ -239,7 +239,7 @@ class ExecContext int getInstAsid() { return asid; } int getDataAsid() { return asid; } - Fault dummyTranslation(MemReqPtr &req) + Fault * dummyTranslation(MemReqPtr &req) { #if 0 assert((req->vaddr >> 48 & 0xffff) == 0); @@ -248,17 +248,17 @@ class ExecContext // put the asid in the upper 16 bits of the paddr req->paddr = req->vaddr & ~((Addr)0xffff << sizeof(Addr) * 8 - 16); req->paddr = req->paddr | (Addr)req->asid << sizeof(Addr) * 8 - 16; - return No_Fault; + return NoFault; } - Fault translateInstReq(MemReqPtr &req) + Fault * translateInstReq(MemReqPtr &req) { return dummyTranslation(req); } - Fault translateDataReadReq(MemReqPtr &req) + Fault * translateDataReadReq(MemReqPtr &req) { return dummyTranslation(req); } - Fault translateDataWriteReq(MemReqPtr &req) + Fault * translateDataWriteReq(MemReqPtr &req) { return dummyTranslation(req); } @@ -266,7 +266,7 @@ class ExecContext #endif template - Fault read(MemReqPtr &req, T &data) + Fault * read(MemReqPtr &req, T &data) { #if FULL_SYSTEM && defined(TARGET_ALPHA) if (req->flags & LOCKED) { @@ -276,14 +276,14 @@ class ExecContext } #endif - Fault error; + Fault * error; error = mem->read(req, data); data = LittleEndianGuest::gtoh(data); return error; } template - Fault write(MemReqPtr &req, T &data) + Fault * write(MemReqPtr &req, T &data) { #if FULL_SYSTEM && defined(TARGET_ALPHA) @@ -309,7 +309,7 @@ class ExecContext << "on cpu " << req->xc->cpu_id << std::endl; } - return No_Fault; + return NoFault; } else req->xc->storeCondFailures = 0; } @@ -341,7 +341,7 @@ class ExecContext inst = new_inst; } - Fault instRead(MemReqPtr &req) + Fault * instRead(MemReqPtr &req) { return mem->read(req, inst); } @@ -420,13 +420,13 @@ class ExecContext } #if FULL_SYSTEM - uint64_t readIpr(int idx, Fault &fault); - Fault setIpr(int idx, uint64_t val); + uint64_t readIpr(int idx, Fault * &fault); + Fault * setIpr(int idx, uint64_t val); int readIntrFlag() { return regs.intrflag; } void setIntrFlag(int val) { regs.intrflag = val; } - Fault hwrei(); + Fault * hwrei(); bool inPalMode() { return AlphaISA::PcPAL(regs.pc); } - void ev5_trap(Fault fault); + void ev5_trap(Fault * fault); bool simPalCheck(int palFunc); #endif @@ -436,7 +436,7 @@ class ExecContext * @todo How to do this properly so it's dependent upon ISA only? */ - void trap(Fault fault); + void trap(Fault * fault); #if !FULL_SYSTEM TheISA::IntReg getSyscallArg(int i) diff --git a/cpu/static_inst.hh b/cpu/static_inst.hh index 333a6f1ca..1ff14df08 100644 --- a/cpu/static_inst.hh +++ b/cpu/static_inst.hh @@ -36,7 +36,7 @@ #include "base/refcnt.hh" #include "encumbered/cpu/full/op_class.hh" #include "sim/host.hh" -#include "targetarch/isa_traits.hh" +#include "arch/isa_traits.hh" // forward declarations struct AlphaSimpleImpl; From 7c642b710679f01d4ec43e6562dd854180dd8c41 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 19 Feb 2006 04:00:05 -0500 Subject: [PATCH 073/180] Reapplied changes which were undone by a pull arch/alpha/faults.hh: kern/linux/linux.hh: Added typedef for Addr kern/tru64/tru64.hh: Fixed up namespaces --HG-- extra : convert_revision : bf968e615bc0acc96abeb0eec0872f5b02b5a065 --- arch/alpha/faults.hh | 2 ++ kern/linux/linux.hh | 3 +++ kern/tru64/tru64.hh | 56 +++++++++++++++++++++++++++----------------- 3 files changed, 39 insertions(+), 22 deletions(-) diff --git a/arch/alpha/faults.hh b/arch/alpha/faults.hh index 06605861a..7676d751c 100644 --- a/arch/alpha/faults.hh +++ b/arch/alpha/faults.hh @@ -34,6 +34,8 @@ class AlphaFault : public Fault { + protected: + typedef TheISA::Addr Addr; public: AlphaFault(char * newName, int newId, Addr newVect) : Fault(newName, newId), vect(newVect) diff --git a/kern/linux/linux.hh b/kern/linux/linux.hh index 0dbccf546..bac6d6a7d 100644 --- a/kern/linux/linux.hh +++ b/kern/linux/linux.hh @@ -53,6 +53,9 @@ class Linux {}; /// class Linux { + protected: + typedef TheISA::Addr Addr; + public: //@{ diff --git a/kern/tru64/tru64.hh b/kern/tru64/tru64.hh index f3dabb0f8..a21cd6be2 100644 --- a/kern/tru64/tru64.hh +++ b/kern/tru64/tru64.hh @@ -392,7 +392,7 @@ class Tru64 { /// For stack_create. struct vm_stack { // was void * - Addr address; //!< address hint + TheISA::Addr address; //!< address hint size_t rsize; //!< red zone size size_t ysize; //!< yellow zone size size_t gsize; //!< green zone size @@ -401,7 +401,7 @@ class Tru64 { uint64_t align; //!< address alignment uint64_t flags; //!< MAP_FIXED etc. // was struct memalloc_attr * - Addr attr; //!< allocation policy + TheISA::Addr attr; //!< allocation policy uint64_t reserved; //!< reserved }; @@ -433,7 +433,7 @@ class Tru64 { sigset_t sigmask; //!< thread signal mask sigset_t sig; //!< thread pending mask // struct nxm_pth_state * - Addr pth_id; //!< out-of-line state + TheISA::Addr pth_id; //!< out-of-line state int flags; //!< shared flags #define US_SIGSTACK 0x1 // thread called sigaltstack #define US_ONSTACK 0x2 // thread is running on altstack @@ -469,12 +469,12 @@ class Tru64 { int nxm_set_quantum; //!< quantum reset value int nxm_sysevent; //!< syscall state // struct nxm_upcall * - Addr nxm_uc_ret; //!< stack ptr of null thread + TheISA::Addr nxm_uc_ret; //!< stack ptr of null thread // void * - Addr nxm_tid; //!< scheduler's thread id + TheISA::Addr nxm_tid; //!< scheduler's thread id int64_t nxm_va; //!< page fault address // struct nxm_pth_state * - Addr nxm_pthid; //!< id of null thread + TheISA::Addr nxm_pthid; //!< id of null thread uint64_t nxm_bound_pcs_count; //!< bound PCS thread count int64_t pad[2]; //!< pad }; @@ -502,9 +502,9 @@ class Tru64 { int nxm_nslots_per_rad; //!< max number of VP slots per RAD int nxm_nrads; //!< max number of RADs // nxm_slot_state_t * - Addr nxm_slot_state; //!< per-VP slot state + TheISA::Addr nxm_slot_state; //!< per-VP slot state // struct nxm_shared * - Addr nxm_rad[1]; //!< per-RAD shared areas + TheISA::Addr nxm_rad[1]; //!< per-RAD shared areas }; /// For nxm_thread_create. @@ -523,7 +523,7 @@ class Tru64 { int policy; //!< policy int signal_type; //!< signal_type // void * - Addr pthid; //!< pthid + TheISA::Addr pthid; //!< pthid sigset_t sigmask; //!< sigmask /// Initial register values. struct { @@ -539,7 +539,7 @@ class Tru64 { /// memory space. Used by stat(), fstat(), and lstat(). template static void - copyOutStatBuf(FunctionalMemory *mem, Addr addr, global_stat *host) + copyOutStatBuf(FunctionalMemory *mem, TheISA::Addr addr, global_stat *host) { TypedBufferArg tgt(addr); @@ -565,7 +565,7 @@ class Tru64 { /// memory space. Used by statfs() and fstatfs(). template static void - copyOutStatfsBuf(FunctionalMemory *mem, Addr addr, global_statfs *host) + copyOutStatfsBuf(FunctionalMemory *mem, TheISA::Addr addr, global_statfs *host) { TypedBufferArg tgt(addr); @@ -589,13 +589,13 @@ class Tru64 { class F64 { public: - static void copyOutStatBuf(FunctionalMemory *mem, Addr addr, + static void copyOutStatBuf(FunctionalMemory *mem, TheISA::Addr addr, global_stat *host) { Tru64::copyOutStatBuf(mem, addr, host); } - static void copyOutStatfsBuf(FunctionalMemory *mem, Addr addr, + static void copyOutStatfsBuf(FunctionalMemory *mem, TheISA::Addr addr, global_statfs *host) { Tru64::copyOutStatfsBuf(mem, addr, host); @@ -604,13 +604,13 @@ class Tru64 { class PreF64 { public: - static void copyOutStatBuf(FunctionalMemory *mem, Addr addr, + static void copyOutStatBuf(FunctionalMemory *mem, TheISA::Addr addr, global_stat *host) { Tru64::copyOutStatBuf(mem, addr, host); } - static void copyOutStatfsBuf(FunctionalMemory *mem, Addr addr, + static void copyOutStatfsBuf(FunctionalMemory *mem, TheISA::Addr addr, global_statfs *host) { Tru64::copyOutStatfsBuf(mem, addr, host); @@ -622,7 +622,7 @@ class Tru64 { /// the simulated memory space. Used by pre_F64_stat(), /// pre_F64_fstat(), and pre_F64_lstat(). static void - copyOutPreF64StatBuf(FunctionalMemory *mem, Addr addr, struct stat *host) + copyOutPreF64StatBuf(FunctionalMemory *mem, TheISA::Addr addr, struct stat *host) { TypedBufferArg tgt(addr); @@ -653,6 +653,7 @@ class Tru64 { getdirentriesFunc(SyscallDesc *desc, int callnum, Process *process, ExecContext *xc) { + using TheISA::Addr; #ifdef __CYGWIN__ panic("getdirent not implemented on cygwin!"); #else @@ -712,6 +713,7 @@ class Tru64 { sigreturnFunc(SyscallDesc *desc, int callnum, Process *process, ExecContext *xc) { + using TheISA::RegFile; RegFile *regs = &xc->regs; TypedBufferArg sc(xc->getSyscallArg(0)); @@ -807,6 +809,7 @@ class Tru64 { nxm_task_initFunc(SyscallDesc *desc, int callnum, Process *process, ExecContext *xc) { + using TheISA::Addr; TypedBufferArg attrp(xc->getSyscallArg(0)); TypedBufferArg configptr_ptr(xc->getSyscallArg(1)); @@ -920,13 +923,13 @@ class Tru64 { { memset(&ec->regs, 0, sizeof(ec->regs)); - ec->regs.intRegFile[ArgumentReg0] = gtoh(attrp->registers.a0); + ec->regs.intRegFile[TheISA::ArgumentReg0] = gtoh(attrp->registers.a0); ec->regs.intRegFile[27/*t12*/] = gtoh(attrp->registers.pc); - ec->regs.intRegFile[StackPointerReg] = gtoh(attrp->registers.sp); + ec->regs.intRegFile[TheISA::StackPointerReg] = gtoh(attrp->registers.sp); ec->regs.miscRegs.uniq = uniq_val; ec->regs.pc = gtoh(attrp->registers.pc); - ec->regs.npc = gtoh(attrp->registers.pc) + sizeof(MachInst); + ec->regs.npc = gtoh(attrp->registers.pc) + sizeof(TheISA::MachInst); ec->activate(); } @@ -936,6 +939,7 @@ class Tru64 { nxm_thread_createFunc(SyscallDesc *desc, int callnum, Process *process, ExecContext *xc) { + using TheISA::Addr; TypedBufferArg attrp(xc->getSyscallArg(0)); TypedBufferArg kidp(xc->getSyscallArg(1)); int thread_index = xc->getSyscallArg(2); @@ -1075,6 +1079,7 @@ class Tru64 { nxm_blockFunc(SyscallDesc *desc, int callnum, Process *process, ExecContext *xc) { + using TheISA::Addr; Addr uaddr = xc->getSyscallArg(0); uint64_t val = xc->getSyscallArg(1); uint64_t secs = xc->getSyscallArg(2); @@ -1096,6 +1101,7 @@ class Tru64 { nxm_unblockFunc(SyscallDesc *desc, int callnum, Process *process, ExecContext *xc) { + using TheISA::Addr; Addr uaddr = xc->getSyscallArg(0); cout << xc->cpu->name() << ": nxm_unblock " @@ -1123,7 +1129,7 @@ class Tru64 { /// Activate exec context waiting on a channel. Just activate one /// by default. static int - activate_waiting_context(Addr uaddr, Process *process, + activate_waiting_context(TheISA::Addr uaddr, Process *process, bool activate_all = false) { int num_activated = 0; @@ -1152,7 +1158,7 @@ class Tru64 { /// M5 hacked-up lock acquire. static void - m5_lock_mutex(Addr uaddr, Process *process, ExecContext *xc) + m5_lock_mutex(TheISA::Addr uaddr, Process *process, ExecContext *xc) { TypedBufferArg lockp(uaddr); @@ -1171,7 +1177,7 @@ class Tru64 { /// M5 unlock call. static void - m5_unlock_mutex(Addr uaddr, Process *process, ExecContext *xc) + m5_unlock_mutex(TheISA::Addr uaddr, Process *process, ExecContext *xc) { TypedBufferArg lockp(uaddr); @@ -1193,6 +1199,7 @@ class Tru64 { m5_mutex_lockFunc(SyscallDesc *desc, int callnum, Process *process, ExecContext *xc) { + using TheISA::Addr; Addr uaddr = xc->getSyscallArg(0); m5_lock_mutex(uaddr, process, xc); @@ -1208,6 +1215,7 @@ class Tru64 { m5_mutex_trylockFunc(SyscallDesc *desc, int callnum, Process *process, ExecContext *xc) { + using TheISA::Addr; Addr uaddr = xc->getSyscallArg(0); TypedBufferArg lockp(uaddr); @@ -1228,6 +1236,7 @@ class Tru64 { m5_mutex_unlockFunc(SyscallDesc *desc, int callnum, Process *process, ExecContext *xc) { + using TheISA::Addr; Addr uaddr = xc->getSyscallArg(0); m5_unlock_mutex(uaddr, process, xc); @@ -1240,6 +1249,7 @@ class Tru64 { m5_cond_signalFunc(SyscallDesc *desc, int callnum, Process *process, ExecContext *xc) { + using TheISA::Addr; Addr cond_addr = xc->getSyscallArg(0); // Wake up one process waiting on the condition variable. @@ -1253,6 +1263,7 @@ class Tru64 { m5_cond_broadcastFunc(SyscallDesc *desc, int callnum, Process *process, ExecContext *xc) { + using TheISA::Addr; Addr cond_addr = xc->getSyscallArg(0); activate_waiting_context(cond_addr, process, true); @@ -1265,6 +1276,7 @@ class Tru64 { m5_cond_waitFunc(SyscallDesc *desc, int callnum, Process *process, ExecContext *xc) { + using TheISA::Addr; Addr cond_addr = xc->getSyscallArg(0); Addr lock_addr = xc->getSyscallArg(1); TypedBufferArg condp(cond_addr); From 38ce95db3b7cf471dcd3c12b784877c4dc238d6f Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Mon, 20 Feb 2006 01:49:16 -0500 Subject: [PATCH 074/180] Support for All Jump Instructions ... Redo format for Branches and Jumps ( Must update NNPC not NPC ) Now all branches and jumps look like they auto-generate correctly from isa_parser.py!!! arch/mips/isa/decoder.isa: Support for All Jump Instructions .. arch/mips/isa/formats/branch.isa: Redo format for Branches and Jumps ( Must update NNPC not NPC ) arch/mips/isa/formats/util.isa: define clear_exe_inst_hazards for later use --HG-- extra : convert_revision : 63618ed12ee6ed94c47d29619cc1cab2cbaf5cda --- arch/mips/isa/decoder.isa | 20 +++++++++------- arch/mips/isa/formats/branch.isa | 40 ++++++++++++++++++++------------ arch/mips/isa/formats/util.isa | 10 ++++++++ 3 files changed, 46 insertions(+), 24 deletions(-) diff --git a/arch/mips/isa/decoder.isa b/arch/mips/isa/decoder.isa index f46024f15..e3889ef7a 100644 --- a/arch/mips/isa/decoder.isa +++ b/arch/mips/isa/decoder.isa @@ -58,15 +58,17 @@ decode OPCODE_HI default Unknown::unknown() { //Table A-3 Note: "Specific encodings of the hint field are used //to distinguish JR from JR.HB and JALR from JALR.HB" - format Unconditional { + format Jump { 0x0: decode HINT { - 0:jr({{ }},IsReturn,IsLink); - 1:jr_hb({{ }},IsReturn,IsLink); + 0:jr({{ NNPC = Rs; }},IsReturn); + + 1:jr_hb({{ NNPC = Rs; clear_exe_inst_hazards(); }},IsReturn); } 0x1: decode HINT { - 0: jalr({{ }},'IsCall','IsReturn','IsLink'); - 1: jalr_hb({{ }},IsCall,IsReturn,IsLink); + 0: jalr({{ NNPC = Rs; }},IsCall,IsReturn); + + 1: jalr_hb({{ NNPC = Rs; clear_exe_inst_hazards();}},IsCall,IsReturn); } } @@ -75,7 +77,6 @@ decode OPCODE_HI default Unknown::unknown() { 0x3: movn({{ if (Rt != 0) Rd = Rs; }}); } - format WarnUnimpl { 0x4: syscall();//{{ xc->syscall()}},IsNonSpeculative 0x5: break(); @@ -196,9 +197,10 @@ decode OPCODE_HI default Unknown::unknown() { } } - format Unconditional { - 0x2: j({{ }}); - 0x3: jal({{ }},IsCall,IsLink); + format Jump { + 0x2: j({{ NNPC = (NPC & 0xF0000000) & (0x00000000 & JMPTARG << 2);}}); + + 0x3: jal({{ NNPC = (NPC & 0xF0000000) & (0x00000000 & JMPTARG << 2);}},IsCall,IsLink); } format Branch { diff --git a/arch/mips/isa/formats/branch.isa b/arch/mips/isa/formats/branch.isa index 1f7a6f330..fc207fd3f 100644 --- a/arch/mips/isa/formats/branch.isa +++ b/arch/mips/isa/formats/branch.isa @@ -250,20 +250,22 @@ output decoder {{ }}; def format Branch(code,*flags) {{ - code = 'bool cond;\n\t' + code + '\n' - #Add Link Code if Link instruction strlen = len(name) if name[strlen-2:] == 'al': - code += 'R31 = NPC + 4;\n' + code += 'R31 = NNPC;\n' - # condition code - code += 'if (cond) {' - code += ' NPC = NPC + disp;\n' - code += ' NNPC = NNPC + disp;\n } \n' + #Condition code + code = 'bool cond;\n' + code + code += 'if (cond) {\n' + #code += '//NPC=NPC: just placeholder to force parser to writeback NPC\n' + #code += ' NPC = NPC; \n' + code += ' NNPC = NPC + disp;\n' + code += '} \n' iop = InstObjParams(name, Name, 'Branch', CodeBlock(code), ('IsDirectControl', 'IsCondControl')) + header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) decode_block = BasicDecode.subst(iop) @@ -272,30 +274,38 @@ def format Branch(code,*flags) {{ def format BranchLikely(code,*flags) {{ - code = 'bool cond;\n\t\t\t' + code - #Add Link Code if Link instruction strlen = len(name) if name[strlen-3:] == 'all': - code += 'R31 = NPC + 4;\n' + code += 'R31 = NNPC;\n' - #condition code + #Condition code + code = 'bool cond;\n' + code code += 'if (cond) {' - code += ' NPC = NPC + disp;\n' - code += ' NNPC = NNPC + disp;\n } \n' + #code += '//NPC=NPC: just placeholder to force parser to writeback NPC\n' + #code += 'NPC = NPC; \n' + code += 'NNPC = NPC + disp;\n' + code += '} \n' iop = InstObjParams(name, Name, 'Branch', CodeBlock(code), ('IsDirectControl', 'IsCondControl','IsCondDelaySlot')) + header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) decode_block = BasicDecode.subst(iop) exec_output = BasicExecute.subst(iop) }}; -def format Unconditional(code,*flags) {{ - iop = InstObjParams(name, Name, 'Jump', CodeBlock(code), +def format Jump(code,*flags) {{ + #Add Link Code if Link instruction + strlen = len(name) + if strlen >= 3 and name[2:3] == 'al': + code = 'R31 = NNPC;\n' + code + + iop = InstObjParams(name, Name, 'Jump', CodeBlock(code),\ ('IsIndirectControl', 'IsUncondControl')) + header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) decode_block = BasicDecode.subst(iop) diff --git a/arch/mips/isa/formats/util.isa b/arch/mips/isa/formats/util.isa index c6dae6783..1eff92269 100644 --- a/arch/mips/isa/formats/util.isa +++ b/arch/mips/isa/formats/util.isa @@ -24,3 +24,13 @@ def UncondCtrlBase(name, Name, base_class, npc_expr, flags): return (header_output, decoder_output, JumpOrBranchDecode.subst(nolink_iop), exec_output) }}; + +output exec {{ + + /// CLEAR ALL CPU INST/EXE HAZARDS + inline void + clear_exe_inst_hazards() + { + //CODE HERE + } +} From 19534176e06578cb167d5f10d9146f6b1c361cb5 Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Mon, 20 Feb 2006 14:30:23 -0500 Subject: [PATCH 075/180] load/store instruction format ... now generates load/store code and breaks it into a separate EA and MemAccess templated from how the Alpha ARch. was coded to do the same thing. arch/mips/isa/bitfields.isa: comment change arch/mips/isa/decoder.isa: re-structuring of load/store instruction definitions arch/mips/isa/formats/mem.isa: Define LoadMemory & Store Memory formats Use style of formatting & base class similar to what was used for ALPHA arch/mips/isa/formats/util.isa: Insert LoadStoreBase function here from alpha/arch/isa/mem.isa arch/mips/isa/operands.isa: change shw->sh and uhw->uh --HG-- extra : convert_revision : 5d85f15f4a600dd4c473a3b4a170ba39cf07fc8a --- arch/mips/isa/bitfields.isa | 4 +- arch/mips/isa/decoder.isa | 52 ++-- arch/mips/isa/formats/mem.isa | 496 +++++++++++++++++++++++++++++---- arch/mips/isa/formats/util.isa | 89 ++++++ arch/mips/isa/operands.isa | 4 +- 5 files changed, 560 insertions(+), 85 deletions(-) diff --git a/arch/mips/isa/bitfields.isa b/arch/mips/isa/bitfields.isa index bead9c151..532b3793a 100644 --- a/arch/mips/isa/bitfields.isa +++ b/arch/mips/isa/bitfields.isa @@ -1,3 +1,5 @@ +// -*- mode:c++ -*- + //////////////////////////////////////////////////////////////////// // // Bitfield definitions. @@ -41,7 +43,7 @@ def bitfield SC < 5: 5>; // Branch format def bitfield OFFSET <15: 0>; // displacement -// Memory-format jumps +// Jmp format def bitfield JMPTARG <25: 0>; def bitfield JMPHINT <10: 6>; diff --git a/arch/mips/isa/decoder.isa b/arch/mips/isa/decoder.isa index e3889ef7a..7dd08ac49 100644 --- a/arch/mips/isa/decoder.isa +++ b/arch/mips/isa/decoder.isa @@ -200,7 +200,7 @@ decode OPCODE_HI default Unknown::unknown() { format Jump { 0x2: j({{ NNPC = (NPC & 0xF0000000) & (0x00000000 & JMPTARG << 2);}}); - 0x3: jal({{ NNPC = (NPC & 0xF0000000) & (0x00000000 & JMPTARG << 2);}},IsCall,IsLink); + 0x3: jal({{ NNPC = (NPC & 0xF0000000) & (0x00000000 & JMPTARG << 2);}},IsCall,IsReturn); } format Branch { @@ -676,8 +676,8 @@ decode OPCODE_HI default Unknown::unknown() { //operations are enabled." 0x3: decode FUNCTION_HI { 0x0: decode FUNCTION_LO { - format Memory { - 0x0: lwxc1({{ EA = Rs + Rt; }},{{ Ft<31:0> = Mem.uf; }}); + format LoadMemory2 { + 0x0: lwxc1({{ EA = Rs + Rt; }},{{ Ft<31:0> = Mem.sf; }}); 0x1: ldxc1({{ EA = Rs + Rt; }},{{ Ft<63:0> = Mem.df; }}); 0x5: luxc1({{ //Need to make EA<2:0> = 0 EA = Rs + Rt; @@ -687,9 +687,9 @@ decode OPCODE_HI default Unknown::unknown() { } 0x1: decode FUNCTION_LO { - format Memory { - 0x0: swxc1({{ EA = Rs + Rt; }},{{ Mem.uf = Ft<31:0>; }}); - 0x1: sdxc1({{ EA = Rs + Rt; }},{{ Mem.uf = Ft<63:0>}}); + 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; }}, @@ -861,26 +861,26 @@ decode OPCODE_HI default Unknown::unknown() { } 0x4: decode OPCODE_LO default FailUnimpl::reserved() { - format Memory { - 0x0: lb({{ EA = Rs + disp; }}, {{ Rb.sw = Mem.sb; }}); - 0x1: lh({{ EA = Rs + disp; }}, {{ Rb.sw = Mem.sh; }}); - 0x2: lwl({{ EA = Rs + disp; }}, {{ Rb.sw = Mem.sw; }});//, WordAlign); - 0x3: lw({{ EA = Rs + disp; }}, {{ Rb.uq = Mem.sb; }}); - 0x4: lbu({{ EA = Rs + disp; }}, {{ Rb.uw = Mem.ub; }}); - 0x5: lhu({{ EA = Rs + disp; }}, {{ Rb.uw = Mem.uh; }}); - 0x6: lwr({{ EA = Rs + disp; }}, {{ Rb.uw = Mem.uw; }});//, WordAlign); + format LoadMemory { + 0x0: lb({{ Rb.sw = Mem.sb; }}); + 0x1: lh({{ Rb.sw = Mem.sh; }}); + 0x2: lwl({{ Rb.sw = Mem.sw; }});//, WordAlign); + 0x3: lw({{ Rb.uq = Mem.sb; }}); + 0x4: lbu({{ Rb.uw = Mem.ub; }}); + 0x5: lhu({{ Rb.uw = Mem.uh; }}); + 0x6: lwr({{ Rb.uw = Mem.uw; }});//, WordAlign); } 0x7: FailUnimpl::reserved(); } 0x5: decode OPCODE_LO default FailUnimpl::reserved() { - format Memory { - 0x0: sb({{ EA = Rs + disp; }}, {{ Mem.ub = Rt<7:0>; }}); - 0x1: sh({{ EA = Rs + disp; }},{{ Mem.uh = Rt<15:0>; }}); - 0x2: swl({{ EA = Rs + disp; }},{{ Mem.ub = Rt<31:0>; }});//,WordAlign); - 0x3: sw({{ EA = Rs + disp; }},{{ Mem.ub = Rt<31:0>; }}); - 0x6: swr({{ EA = Rs + disp; }},{{ Mem.ub = Rt<31:0>; }});//,WordAlign); + format StoreMemory { + 0x0: sb({{ Mem.ub = Rt<7:0>; }}); + 0x1: sh({{ Mem.uh = Rt<15:0>; }}); + 0x2: swl({{ Mem.ub = Rt<31:0>; }});//,WordAlign); + 0x3: sw({{ Mem.ub = Rt<31:0>; }}); + 0x6: swr({{ Mem.ub = Rt<31:0>; }});//,WordAlign); } format WarnUnimpl { @@ -892,18 +892,18 @@ decode OPCODE_HI default Unknown::unknown() { 0x6: decode OPCODE_LO default FailUnimpl::reserved() { 0x0: WarnUnimpl::ll(); - format Memory { - 0x1: lwc1({{ EA = Rs + disp; }},{{ Ft<31:0> = Mem.uf; }}); - 0x5: ldc1({{ EA = Rs + disp; }},{{ Ft<63:0> = Mem.df; }}); + format LoadMemory { + 0x1: lwc1({{ Ft<31:0> = Mem.sf; }}); + 0x5: ldc1({{ Ft<63:0> = Mem.df; }}); } } 0x7: decode OPCODE_LO default FailUnimpl::reserved() { 0x0: WarnUnimpl::sc(); - format Memory { - 0x1: swc1({{ EA = Rs + disp; }},{{ Mem.uf = Ft<31:0>; }}); - 0x5: sdc1({{ EA = Rs + disp; }},{{ Mem.df = Ft<63:0>; }}); + format StoreMemory { + 0x1: swc1({{ Mem.sf = Ft<31:0>; }}); + 0x5: sdc1({{ Mem.df = Ft<63:0>; }}); } } diff --git a/arch/mips/isa/formats/mem.isa b/arch/mips/isa/formats/mem.isa index e3028eb7c..18ae3df5f 100644 --- a/arch/mips/isa/formats/mem.isa +++ b/arch/mips/isa/formats/mem.isa @@ -1,78 +1,462 @@ -//////////////////////////////////////////////////////////////////// +// -*- mode:c++ -*- + +// Copyright (c) 2003-2005 The Regents of The University of Michigan +// All rights reserved. // -// Mem instructions +// 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. output header {{ - /** - * Base class for integer operations. - */ - class Mem : public MipsStaticInst + /** + * Base class for general Mips memory-format instructions. + */ + class Memory : public MipsStaticInst + { + protected: + + /// Memory request flags. See mem_req_base.hh. + unsigned memAccessFlags; + /// Pointer to EAComp object. + const StaticInstPtr eaCompPtr; + /// Pointer to MemAcc object. + const StaticInstPtr memAccPtr; + /// Displacement for EA calculation (signed). + int32_t disp; + + /// Constructor + Memory(const char *mnem, MachInst _machInst, OpClass __opClass, + StaticInstPtr _eaCompPtr = nullStaticInstPtr, + StaticInstPtr _memAccPtr = nullStaticInstPtr) + : MipsStaticInst(mnem, _machInst, __opClass), + memAccessFlags(0), eaCompPtr(_eaCompPtr), memAccPtr(_memAccPtr), + disp(OFFSET) { - protected: + } - /// Constructor - Mem(const char *mnem, MachInst _machInst, OpClass __opClass) : MipsStaticInst(mnem, _machInst, __opClass) - { - } + std::string + generateDisassembly(Addr pc, const SymbolTable *symtab) const; + + public: + + const StaticInstPtr &eaCompInst() const { return eaCompPtr; } + const StaticInstPtr &memAccInst() const { return memAccPtr; } + }; - std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; - }; }}; + output decoder {{ - std::string Mem::generateDisassembly(Addr pc, const SymbolTable *symtab) const + std::string + Memory::generateDisassembly(Addr pc, const SymbolTable *symtab) const + { + return csprintf("%-10s %c%d,%d(r%d)", mnemonic, + flags[IsFloating] ? 'f' : 'r', RA, MEMDISP, RB); + } + +}}; + +def format LoadAddress(code) {{ + iop = InstObjParams(name, Name, 'MemoryDisp32', CodeBlock(code)) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecode.subst(iop) + exec_output = BasicExecute.subst(iop) +}}; + + +def template LoadStoreDeclare {{ + /** + * Static instruction class for "%(mnemonic)s". + */ + class %(class_name)s : public %(base_class)s + { + protected: + + /** + * "Fake" effective address computation class for "%(mnemonic)s". + */ + class EAComp : public %(base_class)s { - return "Disassembly of integer instruction\n"; - } -}}; + public: + /// Constructor + EAComp(MachInst machInst); -def template MemExecute {{ - Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const + %(BasicExecDeclare)s + }; + + /** + * "Fake" memory access instruction class for "%(mnemonic)s". + */ + class MemAcc : public %(base_class)s { - //Attempt to execute the instruction - try - { + public: + /// Constructor + MemAcc(MachInst machInst); - %(op_decl)s; - %(op_rd)s; - ea_code - %(code)s; - } - //If we have an exception for some reason, - //deal with it - catch(MipsException except) - { - //Deal with exception - return No_Fault; - } + %(BasicExecDeclare)s + }; - //Write the resulting state to the execution context - %(op_wb)s; + public: - return No_Fault; + /// Constructor. + %(class_name)s(MachInst machInst); + + %(BasicExecDeclare)s + + %(InitiateAccDeclare)s + + %(CompleteAccDeclare)s + }; +}}; + + +def template InitiateAccDeclare {{ + Fault * initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const; +}}; + + +def template CompleteAccDeclare {{ + Fault * completeAcc(uint8_t *, %(CPU_exec_context)s *, Trace::InstRecord *) const; +}}; + + +def template LoadStoreConstructor {{ + /** TODO: change op_class to AddrGenOp or something (requires + * creating new member of OpClass enum in op_class.hh, updating + * config files, etc.). */ + inline %(class_name)s::EAComp::EAComp(MachInst machInst) + : %(base_class)s("%(mnemonic)s (EAComp)", machInst, IntAluOp) + { + %(ea_constructor)s; + } + + inline %(class_name)s::MemAcc::MemAcc(MachInst machInst) + : %(base_class)s("%(mnemonic)s (MemAcc)", machInst, %(op_class)s) + { + %(memacc_constructor)s; + } + + inline %(class_name)s::%(class_name)s(MachInst machInst) + : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, + new EAComp(machInst), new MemAcc(machInst)) + { + %(constructor)s; + } +}}; + + +def template EACompExecute {{ + Fault * + %(class_name)s::EAComp::execute(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + Addr EA; + Fault * fault = NoFault; + + %(fp_enable_check)s; + %(op_decl)s; + %(op_rd)s; + %(code)s; + + if (fault == NoFault) { + %(op_wb)s; + xc->setEA(EA); } + + return fault; + } }}; -// Primary format for integer operate instructions: -def format Memory(code, ea_code = {{ EA = Rb + disp; }},*opt_flags) {{ - orig_code = code - cblk = CodeBlock(code) - iop = InstObjParams(name, Name, 'MipsStaticInst', cblk, opt_flags) - header_output = BasicDeclare.subst(iop) - decoder_output = BasicConstructor.subst(iop) - decode_block = BasicDecodeWithMnemonic.subst(iop) - exec_output = MemExecute.subst(iop) - exec_output.replace('ea_code', 'EA = I ? (R1 + SIMM13) : R1 + R2;'); +def template LoadMemAccExecute {{ + Fault * + %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + Addr EA; + Fault * fault = NoFault; + + %(fp_enable_check)s; + %(op_decl)s; + %(op_rd)s; + EA = xc->getEA(); + + if (fault == NoFault) { + fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags); + %(code)s; + } + + if (fault == NoFault) { + %(op_wb)s; + } + + return fault; + } }}; -def format Cas(code, *opt_flags) {{ - orig_code = code - cblk = CodeBlock(code) - iop = InstObjParams(name, Name, 'MipsStaticInst', cblk, opt_flags) - header_output = BasicDeclare.subst(iop) - decoder_output = BasicConstructor.subst(iop) - decode_block = BasicDecodeWithMnemonic.subst(iop) - exec_output = MemExecute.subst(iop) - exec_output.replace('ea_code', 'EA = R1;'); + +def template LoadExecute {{ + Fault * %(class_name)s::execute(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + Addr EA; + Fault * fault = NoFault; + + %(fp_enable_check)s; + %(op_decl)s; + %(op_rd)s; + %(ea_code)s; + + if (fault == NoFault) { + fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags); + %(memacc_code)s; + } + + if (fault == NoFault) { + %(op_wb)s; + } + + return fault; + } }}; + + +def template LoadInitiateAcc {{ + Fault * %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + Addr EA; + Fault * fault = NoFault; + + %(fp_enable_check)s; + %(op_src_decl)s; + %(op_rd)s; + %(ea_code)s; + + if (fault == NoFault) { + fault = xc->read(EA, (uint%(mem_acc_size)d_t &)Mem, memAccessFlags); + } + + return fault; + } +}}; + + +def template LoadCompleteAcc {{ + Fault * %(class_name)s::completeAcc(uint8_t *data, + %(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + Fault * fault = NoFault; + + %(fp_enable_check)s; + %(op_src_decl)s; + %(op_dest_decl)s; + + memcpy(&Mem, data, sizeof(Mem)); + + if (fault == NoFault) { + %(memacc_code)s; + } + + if (fault == NoFault) { + %(op_wb)s; + } + + return fault; + } +}}; + + +def template StoreMemAccExecute {{ + Fault * + %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + Addr EA; + Fault * fault = NoFault; + uint64_t write_result = 0; + + %(fp_enable_check)s; + %(op_decl)s; + %(op_rd)s; + EA = xc->getEA(); + + if (fault == NoFault) { + %(code)s; + } + + if (fault == NoFault) { + fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, + memAccessFlags, &write_result); + if (traceData) { traceData->setData(Mem); } + } + + if (fault == NoFault) { + %(postacc_code)s; + } + + if (fault == NoFault) { + %(op_wb)s; + } + + return fault; + } +}}; + + +def template StoreExecute {{ + Fault * %(class_name)s::execute(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + Addr EA; + Fault * fault = NoFault; + uint64_t write_result = 0; + + %(fp_enable_check)s; + %(op_decl)s; + %(op_rd)s; + %(ea_code)s; + + if (fault == NoFault) { + %(memacc_code)s; + } + + if (fault == NoFault) { + fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, + memAccessFlags, &write_result); + if (traceData) { traceData->setData(Mem); } + } + + if (fault == NoFault) { + %(postacc_code)s; + } + + if (fault == NoFault) { + %(op_wb)s; + } + + return fault; + } +}}; + +def template StoreInitiateAcc {{ + Fault * %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + Addr EA; + Fault * fault = NoFault; + uint64_t write_result = 0; + + %(fp_enable_check)s; + %(op_src_decl)s; + %(op_dest_decl)s; + %(op_rd)s; + %(ea_code)s; + + if (fault == NoFault) { + %(memacc_code)s; + } + + if (fault == NoFault) { + fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, + memAccessFlags, &write_result); + if (traceData) { traceData->setData(Mem); } + } + + return fault; + } +}}; + + +def template StoreCompleteAcc {{ + Fault * %(class_name)s::completeAcc(uint8_t *data, + %(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + Fault * fault = NoFault; + uint64_t write_result = 0; + + %(fp_enable_check)s; + %(op_dest_decl)s; + + memcpy(&write_result, data, sizeof(write_result)); + + if (fault == NoFault) { + %(postacc_code)s; + } + + if (fault == NoFault) { + %(op_wb)s; + } + + return fault; + } +}}; + +// load instructions use Rt as dest, so check for +// Rt == 31 to detect nops +def template LoadNopCheckDecode {{ + { + MipsStaticInst *i = new %(class_name)s(machInst); + if (RT == 0) { + i = makeNop(i); + } + return i; + } +}}; + +def format LoadMemory(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') +}}; + + +def format StoreMemory(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, + exec_template_base = 'Store') +}}; + +//FP loads are offloaded to these formats for now ... +def format LoadMemory2(ea_code = {{ EA = Rs + disp; }}, memacc_code = {{ }}, + 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') +}}; + + +//FP stores are offloaded to these formats for now ... +def format StoreMemory2(ea_code = {{ EA = Rs + disp; }},memacc_code = {{ }}, + 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') +}}; + diff --git a/arch/mips/isa/formats/util.isa b/arch/mips/isa/formats/util.isa index 1eff92269..f0671726c 100644 --- a/arch/mips/isa/formats/util.isa +++ b/arch/mips/isa/formats/util.isa @@ -23,8 +23,97 @@ def UncondCtrlBase(name, Name, base_class, npc_expr, flags): return (header_output, decoder_output, JumpOrBranchDecode.subst(nolink_iop), exec_output) + +def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, + postacc_code = '', base_class = 'Memory', + decode_template = BasicDecode, exec_template_base = ''): + # Make sure flags are in lists (convert to lists if not). + mem_flags = makeList(mem_flags) + inst_flags = makeList(inst_flags) + + # add hook to get effective addresses into execution trace output. + ea_code += '\nif (traceData) { traceData->setAddr(EA); }\n' + + # generate code block objects + ea_cblk = CodeBlock(ea_code) + memacc_cblk = CodeBlock(memacc_code) + postacc_cblk = CodeBlock(postacc_code) + + # Some CPU models execute the memory operation as an atomic unit, + # while others want to separate them into an effective address + # computation and a memory access operation. As a result, we need + # to generate three StaticInst objects. Note that the latter two + # are nested inside the larger "atomic" one. + + # generate InstObjParams for EAComp object + ea_iop = InstObjParams(name, Name, base_class, ea_cblk, inst_flags) + + # generate InstObjParams for MemAcc object + memacc_iop = InstObjParams(name, Name, base_class, memacc_cblk, inst_flags) + # in the split execution model, the MemAcc portion is responsible + # for the post-access code. + memacc_iop.postacc_code = postacc_cblk.code + + # generate InstObjParams for InitiateAcc, CompleteAcc object + # The code used depends on the template being used + if (exec_template_base == 'Load'): + initiateacc_cblk = CodeBlock(ea_code + memacc_code) + completeacc_cblk = CodeBlock(memacc_code + postacc_code) + elif (exec_template_base == 'Store'): + initiateacc_cblk = CodeBlock(ea_code + memacc_code) + completeacc_cblk = CodeBlock(postacc_code) + else: + initiateacc_cblk = '' + completeacc_cblk = '' + + initiateacc_iop = InstObjParams(name, Name, base_class, initiateacc_cblk, + inst_flags) + + completeacc_iop = InstObjParams(name, Name, base_class, completeacc_cblk, + inst_flags) + + if (exec_template_base == 'Load'): + initiateacc_iop.ea_code = ea_cblk.code + initiateacc_iop.memacc_code = memacc_cblk.code + completeacc_iop.memacc_code = memacc_cblk.code + completeacc_iop.postacc_code = postacc_cblk.code + elif (exec_template_base == 'Store'): + initiateacc_iop.ea_code = ea_cblk.code + initiateacc_iop.memacc_code = memacc_cblk.code + completeacc_iop.postacc_code = postacc_cblk.code + + # generate InstObjParams for unified execution + cblk = CodeBlock(ea_code + memacc_code + postacc_code) + iop = InstObjParams(name, Name, base_class, cblk, inst_flags) + + iop.ea_constructor = ea_cblk.constructor + iop.ea_code = ea_cblk.code + iop.memacc_constructor = memacc_cblk.constructor + iop.memacc_code = memacc_cblk.code + iop.postacc_code = postacc_cblk.code + + if mem_flags: + s = '\n\tmemAccessFlags = ' + string.join(mem_flags, '|') + ';' + iop.constructor += s + memacc_iop.constructor += s + + # select templates + memAccExecTemplate = eval(exec_template_base + 'MemAccExecute') + fullExecTemplate = eval(exec_template_base + 'Execute') + initiateAccTemplate = eval(exec_template_base + 'InitiateAcc') + completeAccTemplate = eval(exec_template_base + 'CompleteAcc') + + # (header_output, decoder_output, decode_block, exec_output) + return (LoadStoreDeclare.subst(iop), LoadStoreConstructor.subst(iop), + decode_template.subst(iop), + EACompExecute.subst(ea_iop) + + memAccExecTemplate.subst(memacc_iop) + + fullExecTemplate.subst(iop) + + initiateAccTemplate.subst(initiateacc_iop) + + completeAccTemplate.subst(completeacc_iop)) }}; + output exec {{ /// CLEAR ALL CPU INST/EXE HAZARDS diff --git a/arch/mips/isa/operands.isa b/arch/mips/isa/operands.isa index 77035f04c..65ef2245f 100644 --- a/arch/mips/isa/operands.isa +++ b/arch/mips/isa/operands.isa @@ -1,8 +1,8 @@ def operand_types {{ 'sb' : ('signed int', 8), 'ub' : ('unsigned int', 8), - 'shw' : ('signed int', 16), - 'uhw' : ('unsigned int', 16), + 'sh' : ('signed int', 16), + 'uh' : ('unsigned int', 16), 'sw' : ('signed int', 32), 'uw' : ('unsigned int', 32), 'sd' : ('signed int', 64), From bdf3fd92ba3ebe1fd300238e8fd9cca4ae5c2614 Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Mon, 20 Feb 2006 14:48:10 -0500 Subject: [PATCH 076/180] make MIPS specific --HG-- extra : convert_revision : c019fad60fbf1a316bc6201b8ce8acf5a9875989 --- arch/mips/SConscript | 12 ++++++------ arch/mips/isa/base.isa | 2 +- arch/mips/isa/formats/unimp.isa | 12 ++++++------ arch/mips/isa_traits.hh | 6 +++--- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/arch/mips/SConscript b/arch/mips/SConscript index bd67c98e9..a6af91669 100644 --- a/arch/mips/SConscript +++ b/arch/mips/SConscript @@ -42,7 +42,7 @@ Import('env') # Base sources used by all configurations. arch_base_sources = Split(''' arch/mips/decoder.cc - arch/mips/alpha_o3_exec.cc + arch/mips/mips_o3_exec.cc arch/mips/fast_cpu_exec.cc arch/mips/simple_cpu_exec.cc arch/mips/full_cpu_exec.cc @@ -52,9 +52,9 @@ arch_base_sources = Split(''' # Full-system sources arch_full_system_sources = Split(''' - arch/mips/alpha_memory.cc + arch/mips/memory.cc arch/mips/arguments.cc - arch/mips/ev5.cc + arch/mips/mips34k.cc arch/mips/osfpal.cc arch/mips/stacktrace.cc arch/mips/vtophys.cc @@ -62,9 +62,9 @@ arch_full_system_sources = Split(''' # Syscall emulation (non-full-system) sources arch_syscall_emulation_sources = Split(''' - arch/mips/alpha_common_syscall_emul.cc - arch/mips/alpha_linux_process.cc - arch/mips/alpha_tru64_process.cc + arch/mips/common_syscall_emul.cc + arch/mips/linux_process.cc + arch/mips/tru64_process.cc ''') # Set up complete list of sources based on configuration. diff --git a/arch/mips/isa/base.isa b/arch/mips/isa/base.isa index db37cf49c..846d161b9 100644 --- a/arch/mips/isa/base.isa +++ b/arch/mips/isa/base.isa @@ -8,7 +8,7 @@ //Outputs to decoder.hh output header {{ /** - * Base class for all SPARC static instructions. + * Base class for all MIPS static instructions. */ class MipsStaticInst : public StaticInst { diff --git a/arch/mips/isa/formats/unimp.isa b/arch/mips/isa/formats/unimp.isa index 767888157..a7a71c681 100644 --- a/arch/mips/isa/formats/unimp.isa +++ b/arch/mips/isa/formats/unimp.isa @@ -34,12 +34,12 @@ output header {{ * 'Unknown' class is used for unrecognized/illegal instructions. * This is a leaf class. */ - class FailUnimplemented : public AlphaStaticInst + class FailUnimplemented : public MipsStaticInst { public: /// Constructor FailUnimplemented(const char *_mnemonic, MachInst _machInst) - : AlphaStaticInst(_mnemonic, _machInst, No_OpClass) + : MipsStaticInst(_mnemonic, _machInst, No_OpClass) { // don't call execute() (which panics) if we're on a // speculative path @@ -61,7 +61,7 @@ output header {{ * probably make the 'warned' flag a static member of the derived * class. */ - class WarnUnimplemented : public AlphaStaticInst + class WarnUnimplemented : public MipsStaticInst { private: /// Have we warned on this instruction yet? @@ -70,7 +70,7 @@ output header {{ public: /// Constructor WarnUnimplemented(const char *_mnemonic, MachInst _machInst) - : AlphaStaticInst(_mnemonic, _machInst, No_OpClass), warned(false) + : MipsStaticInst(_mnemonic, _machInst, No_OpClass), warned(false) { // don't call execute() (which panics) if we're on a // speculative path @@ -144,12 +144,12 @@ output header {{ * These cause simulator termination if they are executed in a * non-speculative mode. This is a leaf class. */ - class Unknown : public AlphaStaticInst + class Unknown : public MipsStaticInst { public: /// Constructor Unknown(MachInst _machInst) - : AlphaStaticInst("unknown", _machInst, No_OpClass) + : MipsStaticInst("unknown", _machInst, No_OpClass) { // don't call execute() (which panics) if we're on a // speculative path diff --git a/arch/mips/isa_traits.hh b/arch/mips/isa_traits.hh index e171737a3..603af60e2 100644 --- a/arch/mips/isa_traits.hh +++ b/arch/mips/isa_traits.hh @@ -46,7 +46,7 @@ class Checkpoint; template class StaticInst; template class StaticInstPtr; -//namespace EV5 +//namespace MIPS34K //{ // int DTB_ASN_ASN(uint64_t reg); // int ITB_ASN_ASN(uint64_t reg); @@ -437,7 +437,7 @@ class MipsISA void unserialize(Checkpoint *cp, const std::string §ion); }; - static StaticInstPtr decodeInst(MachInst); + static StaticInstPtr decodeInst(MachInst); // return a no-op instruction... used for instruction fetch faults static const MachInst NoopMachInst; @@ -528,7 +528,7 @@ class SyscallReturn { #ifdef FULL_SYSTEM -#include "arch/alpha/ev5.hh" +#include "arch/mips/mips34k.hh" #endif #endif // __ARCH_MIPS_ISA_TRAITS_HH__ From 3a0102536bdbf00629e6ba944bd55ee0ec77fb52 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Mon, 20 Feb 2006 23:41:50 -0500 Subject: [PATCH 077/180] Get rid of the code that delays PIO write accesses until the cache access occurs. The fundamental problem is that a subsequent read that occurs functionally will get a functionally incorrect result that can break driver code. dev/ns_gige.cc: dev/ns_gige.hh: dev/sinic.cc: dev/sinic.hh: get rid of pio_delay write and the associated code to move the write to the cache access function dev/sinicreg.hh: no more write delays python/m5/objects/Ethernet.py: get rid of pio_delay write --HG-- extra : convert_revision : 1dcb51b8f4514e717bc334a782dfdf06d29ae69d --- dev/ns_gige.cc | 61 +++++------------------------------ dev/ns_gige.hh | 10 ------ dev/sinic.cc | 35 +------------------- dev/sinic.hh | 12 ------- dev/sinicreg.hh | 40 +++++++++++------------ python/m5/objects/Ethernet.py | 1 - 6 files changed, 28 insertions(+), 131 deletions(-) diff --git a/dev/ns_gige.cc b/dev/ns_gige.cc index 07bf178fc..02eb72ca4 100644 --- a/dev/ns_gige.cc +++ b/dev/ns_gige.cc @@ -131,8 +131,6 @@ NSGigE::NSGigE(Params *p) } else if (p->payload_bus) panic("Must define a header bus if defining a payload bus"); - pioDelayWrite = p->pio_delay_write && pioInterface; - intrDelay = p->intr_delay; dmaReadDelay = p->dma_read_delay; dmaWriteDelay = p->dma_write_delay; @@ -805,13 +803,6 @@ NSGigE::write(MemReqPtr &req, const uint8_t *data) } else if (daddr > 0x3FC) panic("Something is messed up!\n"); - if (pioDelayWrite) { - int cpu = (req->xc->regs.ipr[TheISA::IPR_PALtemp16] >> 8) & 0xff; - if (cpu >= writeQueue.size()) - writeQueue.resize(cpu + 1); - writeQueue[cpu].push_back(RegWriteData(daddr, *(uint32_t *)data)); - } - if (req->size == sizeof(uint32_t)) { uint32_t reg = *(uint32_t *)data; uint16_t rfaddr; @@ -824,24 +815,20 @@ NSGigE::write(MemReqPtr &req, const uint8_t *data) if (reg & CR_TXD) { txEnable = false; } else if (reg & CR_TXE) { - if (!pioDelayWrite) { - txEnable = true; + txEnable = true; - // the kernel is enabling the transmit machine - if (txState == txIdle) - txKick(); - } + // the kernel is enabling the transmit machine + if (txState == txIdle) + txKick(); } if (reg & CR_RXD) { rxEnable = false; } else if (reg & CR_RXE) { - if (!pioDelayWrite) { - rxEnable = true; + rxEnable = true; - if (rxState == rxIdle) - rxKick(); - } + if (rxState == rxIdle) + rxKick(); } if (reg & CR_TXR) @@ -2949,38 +2936,9 @@ NSGigE::unserialize(Checkpoint *cp, const std::string §ion) Tick NSGigE::cacheAccess(MemReqPtr &req) { - Addr daddr = req->paddr & 0xfff; DPRINTF(EthernetPIO, "timing access to paddr=%#x (daddr=%#x)\n", - req->paddr, daddr); + req->paddr, req->paddr & 0xfff); - if (!pioDelayWrite || !req->cmd.isWrite()) - return curTick + pioLatency; - - int cpu = (req->xc->regs.ipr[TheISA::IPR_PALtemp16] >> 8) & 0xff; - std::list &wq = writeQueue[cpu]; - if (wq.empty()) - panic("WriteQueue for cpu %d empty timing daddr=%#x", cpu, daddr); - - const RegWriteData &data = wq.front(); - if (data.daddr != daddr) - panic("read mismatch on cpu %d, daddr functional=%#x timing=%#x", - cpu, data.daddr, daddr); - - if (daddr == CR) { - if ((data.value & (CR_TXD | CR_TXE)) == CR_TXE) { - txEnable = true; - if (txState == txIdle) - txKick(); - } - - if ((data.value & (CR_RXD | CR_RXE)) == CR_RXE) { - rxEnable = true; - if (rxState == rxIdle) - rxKick(); - } - } - - wq.pop_front(); return curTick + pioLatency; } @@ -3040,7 +2998,6 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(NSGigE) Param dma_write_factor; Param dma_no_allocate; Param pio_latency; - Param pio_delay_write; Param intr_delay; Param rx_delay; @@ -3081,7 +3038,6 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(NSGigE) INIT_PARAM(dma_write_factor, "multiplier for dma writes"), INIT_PARAM(dma_no_allocate, "Should DMA reads allocate cache lines"), INIT_PARAM(pio_latency, "Programmed IO latency in bus cycles"), - INIT_PARAM(pio_delay_write, ""), INIT_PARAM(intr_delay, "Interrupt Delay in microseconds"), INIT_PARAM(rx_delay, "Receive Delay"), @@ -3126,7 +3082,6 @@ CREATE_SIM_OBJECT(NSGigE) params->dma_write_factor = dma_write_factor; params->dma_no_allocate = dma_no_allocate; params->pio_latency = pio_latency; - params->pio_delay_write = pio_delay_write; params->intr_delay = intr_delay; params->rx_delay = rx_delay; diff --git a/dev/ns_gige.hh b/dev/ns_gige.hh index 181837c8d..a14fde146 100644 --- a/dev/ns_gige.hh +++ b/dev/ns_gige.hh @@ -236,15 +236,6 @@ class NSGigE : public PciDev uint32_t rxDescCnt; DmaState rxDmaState; - struct RegWriteData { - Addr daddr; - uint32_t value; - RegWriteData(Addr da, uint32_t val) : daddr(da), value(val) {} - }; - - std::vector > writeQueue; - bool pioDelayWrite; - bool extstsEnable; /** EEPROM State Machine */ @@ -382,7 +373,6 @@ class NSGigE : public PciDev Tick tx_delay; Tick rx_delay; Tick pio_latency; - bool pio_delay_write; bool dma_desc_free; bool dma_data_free; Tick dma_read_delay; diff --git a/dev/sinic.cc b/dev/sinic.cc index 829d58d32..3f73d81c5 100644 --- a/dev/sinic.cc +++ b/dev/sinic.cc @@ -113,8 +113,6 @@ Device::Device(Params *p) p->dma_no_allocate); } else if (p->payload_bus) panic("must define a header bus if defining a payload bus"); - - pioDelayWrite = p->pio_delay_write && pioInterface; } Device::~Device() @@ -353,9 +351,6 @@ Device::prepareRead(int cpu, int index) void Device::prepareWrite(int cpu, int index) { - if (cpu >= writeQueue.size()) - writeQueue.resize(cpu + 1); - prepareIO(cpu, index); } @@ -503,11 +498,7 @@ Device::writeBar0(MemReqPtr &req, Addr daddr, const uint8_t *data) prepareWrite(cpu, index); - if (pioDelayWrite) - writeQueue[cpu].push_back(RegWriteData(daddr, reg64)); - - if (!pioDelayWrite || !info.delay_write) - regWrite(daddr, cpu, data); + regWrite(daddr, cpu, data); return NoFault; } @@ -1571,27 +1562,6 @@ Device::cacheAccess(MemReqPtr &req) DPRINTF(EthernetPIO, "timing %s to paddr=%#x bar=%d daddr=%#x\n", req->cmd.toString(), req->paddr, bar, daddr); - if (!pioDelayWrite || !req->cmd.isWrite()) - return curTick + pioLatency; - - if (bar == 0) { - int cpu = (req->xc->regs.ipr[TheISA::IPR_PALtemp16] >> 8) & 0xff; - std::list &wq = writeQueue[cpu]; - if (wq.empty()) - panic("WriteQueue for cpu %d empty timing daddr=%#x", cpu, daddr); - - const RegWriteData &data = wq.front(); - if (data.daddr != daddr) - panic("read mismatch on cpu %d, daddr functional=%#x timing=%#x", - cpu, data.daddr, daddr); - - const Regs::Info &info = regInfo(data.daddr); - if (info.delay_write) - regWrite(daddr, cpu, (uint8_t *)&data.value); - - wq.pop_front(); - } - return curTick + pioLatency; } @@ -1649,7 +1619,6 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(Device) Param dma_write_factor; Param dma_no_allocate; Param pio_latency; - Param pio_delay_write; Param intr_delay; Param rx_delay; @@ -1693,7 +1662,6 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(Device) INIT_PARAM(dma_write_factor, "multiplier for dma writes"), INIT_PARAM(dma_no_allocate, "Should we allocat on read in cache"), INIT_PARAM(pio_latency, "Programmed IO latency in bus cycles"), - INIT_PARAM(pio_delay_write, ""), INIT_PARAM(intr_delay, "Interrupt Delay"), INIT_PARAM(rx_delay, "Receive Delay"), @@ -1741,7 +1709,6 @@ CREATE_SIM_OBJECT(Device) params->dma_write_factor = dma_write_factor; params->dma_no_allocate = dma_no_allocate; params->pio_latency = pio_latency; - params->pio_delay_write = pio_delay_write; params->intr_delay = intr_delay; params->tx_delay = tx_delay; diff --git a/dev/sinic.hh b/dev/sinic.hh index 7935a7cdc..06751a955 100644 --- a/dev/sinic.hh +++ b/dev/sinic.hh @@ -283,17 +283,6 @@ class Device : public Base void regWrite(Addr daddr, int cpu, const uint8_t *data); Tick cacheAccess(MemReqPtr &req); - protected: - struct RegWriteData { - Addr daddr; - uint64_t value; - RegWriteData(Addr da, uint64_t val) : daddr(da), value(val) {} - }; - - std::vector > writeQueue; - - bool pioDelayWrite; - /** * Statistics */ @@ -349,7 +338,6 @@ class Device : public Base Bus *header_bus; Bus *payload_bus; Tick pio_latency; - bool pio_delay_write; PhysicalMemory *physmem; IntrControl *intctrl; bool rx_filter; diff --git a/dev/sinicreg.hh b/dev/sinicreg.hh index 343db6303..1378e079d 100644 --- a/dev/sinicreg.hh +++ b/dev/sinicreg.hh @@ -157,8 +157,6 @@ struct Info uint8_t size; bool read; bool write; - bool delay_read; - bool delay_write; const char *name; }; @@ -167,33 +165,33 @@ struct Info inline const Regs::Info& regInfo(TheISA::Addr daddr) { - static Regs::Info invalid = { 0, false, false, false, false, "invalid" }; + static Regs::Info invalid = { 0, false, false, "invalid" }; static Regs::Info info [] = { - { 4, true, true, false, false, "Config" }, - { 4, false, true, false, false, "Command" }, - { 4, true, true, false, false, "IntrStatus" }, - { 4, true, true, false, false, "IntrMask" }, - { 4, true, false, false, false, "RxMaxCopy" }, - { 4, true, false, false, false, "TxMaxCopy" }, - { 4, true, false, false, false, "RxMaxIntr" }, + { 4, true, true, "Config" }, + { 4, false, true, "Command" }, + { 4, true, true, "IntrStatus" }, + { 4, true, true, "IntrMask" }, + { 4, true, false, "RxMaxCopy" }, + { 4, true, false, "TxMaxCopy" }, + { 4, true, false, "RxMaxIntr" }, invalid, - { 4, true, false, false, false, "RxFifoSize" }, - { 4, true, false, false, false, "TxFifoSize" }, - { 4, true, false, false, false, "RxFifoMark" }, - { 4, true, false, false, false, "TxFifoMark" }, - { 8, true, true, false, true, "RxData" }, + { 4, true, false, "RxFifoSize" }, + { 4, true, false, "TxFifoSize" }, + { 4, true, false, "RxFifoMark" }, + { 4, true, false, "TxFifoMark" }, + { 8, true, true, "RxData" }, invalid, - { 8, true, false, false, false, "RxDone" }, + { 8, true, false, "RxDone" }, invalid, - { 8, true, false, false, false, "RxWait" }, + { 8, true, false, "RxWait" }, invalid, - { 8, true, true, false, true, "TxData" }, + { 8, true, true, "TxData" }, invalid, - { 8, true, false, false, false, "TxDone" }, + { 8, true, false, "TxDone" }, invalid, - { 8, true, false, false, false, "TxWait" }, + { 8, true, false, "TxWait" }, invalid, - { 8, true, false, false, false, "HwAddr" }, + { 8, true, false, "HwAddr" }, invalid, }; diff --git a/python/m5/objects/Ethernet.py b/python/m5/objects/Ethernet.py index f58ece0be..3a7f88d04 100644 --- a/python/m5/objects/Ethernet.py +++ b/python/m5/objects/Ethernet.py @@ -76,7 +76,6 @@ class EtherDevBase(PciDevice): dma_write_delay = Param.Latency('0us', "fixed delay for dma writes") dma_write_factor = Param.Latency('0us', "multiplier for dma writes") dma_no_allocate = Param.Bool(True, "Should we allocate cache on read") - pio_delay_write = Param.Bool(False, "Delay pio writes until timing occurs") rx_delay = Param.Latency('1us', "Receive Delay") tx_delay = Param.Latency('1us', "Transmit Delay") From c22664845900727493097e961d2bc17fd9c60372 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Mon, 20 Feb 2006 23:53:14 -0500 Subject: [PATCH 078/180] Finished the implementing the change of the ISA from a class to a namespace dev/sinic.cc: When DPRINTF disappears, reg32 becomes an unused variable. With -Werror, this causes the compile to fail. --HG-- extra : convert_revision : c003c714228491e060155070d192521c53d9e929 --- dev/sinic.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dev/sinic.cc b/dev/sinic.cc index 829d58d32..6ffd0a664 100644 --- a/dev/sinic.cc +++ b/dev/sinic.cc @@ -494,11 +494,11 @@ Device::writeBar0(MemReqPtr &req, Addr daddr, const uint8_t *data) panic("invalid size for %s: cpu=%d da=%#x pa=%#x va=%#x size=%d", info.name, cpu, daddr, req->paddr, req->vaddr, req->size); - uint32_t reg32 = *(uint32_t *)data; + //uint32_t reg32 = *(uint32_t *)data; uint64_t reg64 = *(uint64_t *)data; DPRINTF(EthernetPIO, "write %s: cpu=%d val=%#x da=%#x pa=%#x va=%#x size=%d\n", - info.name, cpu, info.size == 4 ? reg32 : reg64, daddr, + info.name, cpu, info.size == 4 ? (*(uint32_t *)data) : reg64, daddr, req->paddr, req->vaddr, req->size); prepareWrite(cpu, index); From 3f7979c99d8dc4f434e3daa2e179616f1669e16e Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 21 Feb 2006 03:38:21 -0500 Subject: [PATCH 079/180] Made Addr a global type --HG-- extra : convert_revision : 869bd9fa5d8591115ac9b4a7401eb2490986b835 --- arch/alpha/alpha_memory.hh | 2 -- arch/alpha/faults.hh | 4 +-- arch/alpha/isa/branch.isa | 4 --- arch/alpha/isa_traits.hh | 2 +- arch/alpha/stacktrace.hh | 3 --- arch/alpha/vtophys.hh | 16 +++++------ base/loader/object_file.hh | 1 - base/loader/symtab.hh | 3 +-- base/remote_gdb.hh | 1 - cpu/base.hh | 1 - cpu/base_dyn_inst.hh | 2 -- cpu/exec_context.hh | 1 - cpu/exetrace.hh | 3 +-- cpu/memtest/memtest.hh | 2 -- cpu/o3/2bit_local_pred.hh | 2 -- cpu/o3/alpha_cpu.hh | 1 - cpu/o3/alpha_dyn_inst.hh | 2 -- cpu/o3/bpred_unit.hh | 2 -- cpu/o3/btb.hh | 2 -- cpu/o3/decode.hh | 3 --- cpu/o3/fetch.hh | 1 - cpu/o3/ras.hh | 2 -- cpu/o3/regfile.hh | 1 - cpu/o3/rename.hh | 1 - cpu/o3/store_set.hh | 2 -- cpu/o3/tournament_pred.hh | 2 -- cpu/pc_event.cc | 4 +-- cpu/pc_event.hh | 3 --- cpu/profile.hh | 4 --- cpu/static_inst.hh | 2 -- cpu/trace/opt_cpu.hh | 2 -- cpu/trace/reader/itx_reader.hh | 2 -- dev/ide_disk.hh | 2 -- dev/pcidev.hh | 2 -- dev/platform.hh | 2 -- dev/simple_disk.hh | 2 -- dev/sinicreg.hh | 4 +-- dev/tsunami.hh | 2 -- kern/kernel_stats.hh | 4 --- kern/linux/aligned.hh | 2 +- kern/linux/linux.hh | 3 --- kern/linux/linux_threadinfo.hh | 2 -- kern/tru64/mbuf.hh | 22 +++++++-------- kern/tru64/tru64.hh | 49 +++++++++++++--------------------- sim/host.hh | 8 ++++++ sim/process.hh | 1 - sim/pseudo_inst.hh | 4 +-- sim/syscall_emul.hh | 5 +--- sim/system.hh | 2 -- sim/vptr.hh | 2 -- 50 files changed, 58 insertions(+), 143 deletions(-) diff --git a/arch/alpha/alpha_memory.hh b/arch/alpha/alpha_memory.hh index b39a1ef26..849063f59 100644 --- a/arch/alpha/alpha_memory.hh +++ b/arch/alpha/alpha_memory.hh @@ -42,7 +42,6 @@ class ExecContext; class AlphaTLB : public SimObject { protected: - typedef TheISA::Addr Addr; typedef std::multimap PageTable; PageTable lookupTable; // Quick lookup into page table @@ -83,7 +82,6 @@ class AlphaTLB : public SimObject class AlphaITB : public AlphaTLB { protected: - typedef TheISA::Addr Addr; mutable Stats::Scalar<> hits; mutable Stats::Scalar<> misses; mutable Stats::Scalar<> acv; diff --git a/arch/alpha/faults.hh b/arch/alpha/faults.hh index 7676d751c..60c9e735c 100644 --- a/arch/alpha/faults.hh +++ b/arch/alpha/faults.hh @@ -34,14 +34,12 @@ class AlphaFault : public Fault { - protected: - typedef TheISA::Addr Addr; public: AlphaFault(char * newName, int newId, Addr newVect) : Fault(newName, newId), vect(newVect) {;} - TheISA::Addr vect; + Addr vect; }; extern class ResetFaultType : public AlphaFault diff --git a/arch/alpha/isa/branch.isa b/arch/alpha/isa/branch.isa index cc6fd1a09..9a7fb9d79 100644 --- a/arch/alpha/isa/branch.isa +++ b/arch/alpha/isa/branch.isa @@ -39,8 +39,6 @@ output header {{ */ class PCDependentDisassembly : public AlphaStaticInst { - protected: - typedef TheISA::Addr Addr; protected: /// Cached program counter from last disassembly mutable Addr cachedPC; @@ -66,7 +64,6 @@ output header {{ class Branch : public PCDependentDisassembly { protected: - typedef TheISA::Addr Addr; /// Displacement to target address (signed). int32_t disp; @@ -90,7 +87,6 @@ output header {{ class Jump : public PCDependentDisassembly { protected: - typedef TheISA::Addr Addr; /// Displacement to target address (signed). int32_t disp; diff --git a/arch/alpha/isa_traits.hh b/arch/alpha/isa_traits.hh index 2da37b2e0..f47e90f86 100644 --- a/arch/alpha/isa_traits.hh +++ b/arch/alpha/isa_traits.hh @@ -56,7 +56,7 @@ namespace AlphaISA { typedef uint32_t MachInst; - typedef uint64_t Addr; +// typedef uint64_t Addr; typedef uint8_t RegIndex; enum { diff --git a/arch/alpha/stacktrace.hh b/arch/alpha/stacktrace.hh index 211909060..1d8d97a79 100644 --- a/arch/alpha/stacktrace.hh +++ b/arch/alpha/stacktrace.hh @@ -37,8 +37,6 @@ class StackTrace; class ProcessInfo { - protected: - typedef TheISA::Addr Addr; private: ExecContext *xc; @@ -59,7 +57,6 @@ class ProcessInfo class StackTrace { protected: - typedef TheISA::Addr Addr; typedef TheISA::MachInst MachInst; private: ExecContext *xc; diff --git a/arch/alpha/vtophys.hh b/arch/alpha/vtophys.hh index 988f050ba..95430ce77 100644 --- a/arch/alpha/vtophys.hh +++ b/arch/alpha/vtophys.hh @@ -35,16 +35,16 @@ class ExecContext; class PhysicalMemory; AlphaISA::PageTableEntry -kernel_pte_lookup(PhysicalMemory *pmem, AlphaISA::Addr ptbr, AlphaISA::VAddr vaddr); +kernel_pte_lookup(PhysicalMemory *pmem, Addr ptbr, AlphaISA::VAddr vaddr); -AlphaISA::Addr vtophys(PhysicalMemory *xc, AlphaISA::Addr vaddr); -AlphaISA::Addr vtophys(ExecContext *xc, AlphaISA::Addr vaddr); -uint8_t *vtomem(ExecContext *xc, AlphaISA::Addr vaddr, size_t len); -uint8_t *ptomem(ExecContext *xc, AlphaISA::Addr paddr, size_t len); +Addr vtophys(PhysicalMemory *xc, Addr vaddr); +Addr vtophys(ExecContext *xc, Addr vaddr); +uint8_t *vtomem(ExecContext *xc, Addr vaddr, size_t len); +uint8_t *ptomem(ExecContext *xc, Addr paddr, size_t len); -void CopyOut(ExecContext *xc, void *dst, AlphaISA::Addr src, size_t len); -void CopyIn(ExecContext *xc, AlphaISA::Addr dst, void *src, size_t len); -void CopyString(ExecContext *xc, char *dst, AlphaISA::Addr vaddr, size_t maxlen); +void CopyOut(ExecContext *xc, void *dst, Addr src, size_t len); +void CopyIn(ExecContext *xc, Addr dst, void *src, size_t len); +void CopyString(ExecContext *xc, char *dst, Addr vaddr, size_t maxlen); #endif // __ARCH_ALPHA_VTOPHYS_H__ diff --git a/base/loader/object_file.hh b/base/loader/object_file.hh index e90f93847..3c8659e18 100644 --- a/base/loader/object_file.hh +++ b/base/loader/object_file.hh @@ -37,7 +37,6 @@ class SymbolTable; class ObjectFile { public: - typedef TheISA::Addr Addr; enum Arch { UnknownArch, diff --git a/base/loader/symtab.hh b/base/loader/symtab.hh index 38b4cdee2..ebcda1345 100644 --- a/base/loader/symtab.hh +++ b/base/loader/symtab.hh @@ -37,9 +37,8 @@ class Checkpoint; class SymbolTable { - typedef TheISA::Addr Addr; public: - typedef std::map ATable; + typedef std::map ATable; typedef std::map STable; private: diff --git a/base/remote_gdb.hh b/base/remote_gdb.hh index 126d5f6f8..b7abf5116 100644 --- a/base/remote_gdb.hh +++ b/base/remote_gdb.hh @@ -44,7 +44,6 @@ class GDBListener; class RemoteGDB { protected: - typedef TheISA::Addr Addr; typedef TheISA::MachInst MachInst; private: friend void debugger(); diff --git a/cpu/base.hh b/cpu/base.hh index 311b50f7f..d5764d495 100644 --- a/cpu/base.hh +++ b/cpu/base.hh @@ -48,7 +48,6 @@ class ExecContext; class BaseCPU : public SimObject { protected: - typedef TheISA::Addr Addr; // CPU's clock period in terms of the number of ticks of curTime. Tick clock; diff --git a/cpu/base_dyn_inst.hh b/cpu/base_dyn_inst.hh index dd429fc91..84fd5403e 100644 --- a/cpu/base_dyn_inst.hh +++ b/cpu/base_dyn_inst.hh @@ -62,8 +62,6 @@ class BaseDynInst : public FastAlloc, public RefCounted /// Binary machine instruction type. typedef TheISA::MachInst MachInst; - /// Memory address type. - typedef TheISA::Addr Addr; /// Logical register index type. typedef TheISA::RegIndex RegIndex; /// Integer register index type. diff --git a/cpu/exec_context.hh b/cpu/exec_context.hh index 3c6bad34d..3fa7d078e 100644 --- a/cpu/exec_context.hh +++ b/cpu/exec_context.hh @@ -69,7 +69,6 @@ class ExecContext { protected: typedef TheISA::RegFile RegFile; - typedef TheISA::Addr Addr; typedef TheISA::MachInst MachInst; typedef TheISA::MiscRegFile MiscRegFile; public: diff --git a/cpu/exetrace.hh b/cpu/exetrace.hh index d37c48ddd..67d042ec8 100644 --- a/cpu/exetrace.hh +++ b/cpu/exetrace.hh @@ -46,7 +46,6 @@ namespace Trace { class InstRecord : public Record { protected: - typedef TheISA::Addr Addr; typedef TheISA::IntRegFile IntRegFile; // The following fields are initialized by the constructor and @@ -172,7 +171,7 @@ inline InstRecord * getInstRecord(Tick cycle, ExecContext *xc, BaseCPU *cpu, const StaticInstPtr staticInst, - TheISA::Addr pc, int thread = 0) + Addr pc, int thread = 0) { if (DTRACE(InstExec) && (InstRecord::traceMisspec() || !xc->misspeculating())) { diff --git a/cpu/memtest/memtest.hh b/cpu/memtest/memtest.hh index 76a89ff2c..7abcf017a 100644 --- a/cpu/memtest/memtest.hh +++ b/cpu/memtest/memtest.hh @@ -42,8 +42,6 @@ class ExecContext; class MemTest : public SimObject { - protected: - typedef TheISA::Addr Addr; public: MemTest(const std::string &name, diff --git a/cpu/o3/2bit_local_pred.hh b/cpu/o3/2bit_local_pred.hh index 78efe1e43..97433e542 100644 --- a/cpu/o3/2bit_local_pred.hh +++ b/cpu/o3/2bit_local_pred.hh @@ -35,8 +35,6 @@ class DefaultBP { - protected: - typedef TheISA::Addr Addr; public: /** * Default branch predictor constructor. diff --git a/cpu/o3/alpha_cpu.hh b/cpu/o3/alpha_cpu.hh index bf3556b8e..2be70f5c2 100644 --- a/cpu/o3/alpha_cpu.hh +++ b/cpu/o3/alpha_cpu.hh @@ -40,7 +40,6 @@ template class AlphaFullCPU : public FullO3CPU { protected: - typedef AlphaISA::Addr Addr; typedef TheISA::IntReg IntReg; public: typedef typename Impl::Params Params; diff --git a/cpu/o3/alpha_dyn_inst.hh b/cpu/o3/alpha_dyn_inst.hh index 22be2aae5..b113d9487 100644 --- a/cpu/o3/alpha_dyn_inst.hh +++ b/cpu/o3/alpha_dyn_inst.hh @@ -50,8 +50,6 @@ class AlphaDynInst : public BaseDynInst /** Binary machine instruction type. */ typedef TheISA::MachInst MachInst; - /** Memory address type. */ - typedef TheISA::Addr Addr; /** Logical register index type. */ typedef TheISA::RegIndex RegIndex; /** Integer register index type. */ diff --git a/cpu/o3/bpred_unit.hh b/cpu/o3/bpred_unit.hh index c874f9e04..0a77b83dc 100644 --- a/cpu/o3/bpred_unit.hh +++ b/cpu/o3/bpred_unit.hh @@ -53,8 +53,6 @@ template class TwobitBPredUnit { - protected: - typedef TheISA::Addr Addr; public: typedef typename Impl::Params Params; typedef typename Impl::DynInstPtr DynInstPtr; diff --git a/cpu/o3/btb.hh b/cpu/o3/btb.hh index f443ddbaf..77bdc32ea 100644 --- a/cpu/o3/btb.hh +++ b/cpu/o3/btb.hh @@ -34,8 +34,6 @@ class DefaultBTB { - protected: - typedef TheISA::Addr Addr; private: struct BTBEntry { diff --git a/cpu/o3/decode.hh b/cpu/o3/decode.hh index bae9a7015..5b9a0f822 100644 --- a/cpu/o3/decode.hh +++ b/cpu/o3/decode.hh @@ -49,9 +49,6 @@ class SimpleDecode typedef typename CPUPol::DecodeStruct DecodeStruct; typedef typename CPUPol::TimeStruct TimeStruct; - // Typedefs from the ISA. - typedef TheISA::Addr Addr; - public: // The only time decode will become blocked is if dispatch becomes // blocked, which means IQ or ROB is probably full. diff --git a/cpu/o3/fetch.hh b/cpu/o3/fetch.hh index e4d374c1d..82a6cd818 100644 --- a/cpu/o3/fetch.hh +++ b/cpu/o3/fetch.hh @@ -61,7 +61,6 @@ class SimpleFetch /** Typedefs from ISA. */ typedef TheISA::MachInst MachInst; - typedef TheISA::Addr Addr; public: enum Status { diff --git a/cpu/o3/ras.hh b/cpu/o3/ras.hh index fd7f5fe1c..46d98181e 100644 --- a/cpu/o3/ras.hh +++ b/cpu/o3/ras.hh @@ -34,8 +34,6 @@ class ReturnAddrStack { - protected: - typedef TheISA::Addr Addr; public: ReturnAddrStack(unsigned numEntries); diff --git a/cpu/o3/regfile.hh b/cpu/o3/regfile.hh index 655a3cad9..021f9b0b6 100644 --- a/cpu/o3/regfile.hh +++ b/cpu/o3/regfile.hh @@ -53,7 +53,6 @@ template class PhysRegFile { protected: - typedef TheISA::Addr Addr; typedef TheISA::IntReg IntReg; typedef TheISA::FloatReg FloatReg; typedef TheISA::MiscRegFile MiscRegFile; diff --git a/cpu/o3/rename.hh b/cpu/o3/rename.hh index 9781480b6..07b442964 100644 --- a/cpu/o3/rename.hh +++ b/cpu/o3/rename.hh @@ -61,7 +61,6 @@ class SimpleRename typedef typename CPUPol::RenameMap RenameMap; // Typedefs from the ISA. - typedef TheISA::Addr Addr; typedef TheISA::RegIndex RegIndex; public: diff --git a/cpu/o3/store_set.hh b/cpu/o3/store_set.hh index c67d30fcb..5a885d838 100644 --- a/cpu/o3/store_set.hh +++ b/cpu/o3/store_set.hh @@ -36,8 +36,6 @@ class StoreSet { - protected: - typedef TheISA::Addr Addr; public: typedef unsigned SSID; diff --git a/cpu/o3/tournament_pred.hh b/cpu/o3/tournament_pred.hh index 6cfd24cfb..cb93c2f67 100644 --- a/cpu/o3/tournament_pred.hh +++ b/cpu/o3/tournament_pred.hh @@ -35,8 +35,6 @@ class TournamentBP { - protected: - typedef TheISA::Addr Addr; public: /** * Default branch predictor constructor. diff --git a/cpu/pc_event.cc b/cpu/pc_event.cc index 7a294866d..83fbc3e2d 100644 --- a/cpu/pc_event.cc +++ b/cpu/pc_event.cc @@ -136,14 +136,14 @@ BreakPCEvent::process(ExecContext *xc) #if FULL_SYSTEM extern "C" void -sched_break_pc_sys(System *sys, TheISA::Addr addr) +sched_break_pc_sys(System *sys, Addr addr) { new BreakPCEvent(&sys->pcEventQueue, "debug break", addr, true); } extern "C" void -sched_break_pc(TheISA::Addr addr) +sched_break_pc(Addr addr) { for (vector::iterator sysi = System::systemList.begin(); sysi != System::systemList.end(); ++sysi) { diff --git a/cpu/pc_event.hh b/cpu/pc_event.hh index 3033a3cfd..7fa3902cc 100644 --- a/cpu/pc_event.hh +++ b/cpu/pc_event.hh @@ -39,7 +39,6 @@ class PCEventQueue; class PCEvent { protected: - typedef TheISA::Addr Addr; static const Addr badpc = MemReq::inval_addr; protected: @@ -65,7 +64,6 @@ class PCEvent class PCEventQueue { protected: - typedef TheISA::Addr Addr; typedef PCEvent * record_t; class MapCompare { public: @@ -134,7 +132,6 @@ PCEvent::remove() class BreakPCEvent : public PCEvent { protected: - typedef TheISA::Addr Addr; bool remove; public: diff --git a/cpu/profile.hh b/cpu/profile.hh index b55f87a6a..18061f9bf 100644 --- a/cpu/profile.hh +++ b/cpu/profile.hh @@ -37,8 +37,6 @@ class ProfileNode { - protected: - typedef TheISA::Addr Addr; private: friend class FunctionProfile; @@ -59,8 +57,6 @@ class ProfileNode class Callback; class FunctionProfile { - public: - typedef TheISA::Addr Addr; private: Callback *reset; const SymbolTable *symtab; diff --git a/cpu/static_inst.hh b/cpu/static_inst.hh index 1ff14df08..5106dcf06 100644 --- a/cpu/static_inst.hh +++ b/cpu/static_inst.hh @@ -229,8 +229,6 @@ class StaticInst : public StaticInstBase /// Binary machine instruction type. typedef TheISA::MachInst MachInst; - /// Memory address type. - typedef TheISA::Addr Addr; /// Logical register index type. typedef TheISA::RegIndex RegIndex; diff --git a/cpu/trace/opt_cpu.hh b/cpu/trace/opt_cpu.hh index 704dc09fa..f81691733 100644 --- a/cpu/trace/opt_cpu.hh +++ b/cpu/trace/opt_cpu.hh @@ -49,8 +49,6 @@ class MemTraceReader; */ class OptCPU : public SimObject { - protected: - typedef TheISA::Addr Addr; private: typedef int RefIndex; diff --git a/cpu/trace/reader/itx_reader.hh b/cpu/trace/reader/itx_reader.hh index e402b2d52..a16a08085 100644 --- a/cpu/trace/reader/itx_reader.hh +++ b/cpu/trace/reader/itx_reader.hh @@ -46,8 +46,6 @@ */ class ITXReader : public MemTraceReader { - protected: - typedef TheISA::Addr Addr; private: /** Trace file. */ FILE *trace; diff --git a/dev/ide_disk.hh b/dev/ide_disk.hh index 32888c81c..a656ca464 100644 --- a/dev/ide_disk.hh +++ b/dev/ide_disk.hh @@ -187,8 +187,6 @@ class IdeController; */ class IdeDisk : public SimObject { - protected: - typedef TheISA::Addr Addr; protected: /** The IDE controller for this disk. */ IdeController *ctrl; diff --git a/dev/pcidev.hh b/dev/pcidev.hh index a100bf746..c8d9685c1 100644 --- a/dev/pcidev.hh +++ b/dev/pcidev.hh @@ -53,8 +53,6 @@ class MemoryController; */ class PciConfigData : public SimObject { - protected: - typedef TheISA::Addr Addr; public: /** * Constructor to initialize the devices config space to 0. diff --git a/dev/platform.hh b/dev/platform.hh index 87810250a..1ee645454 100644 --- a/dev/platform.hh +++ b/dev/platform.hh @@ -44,8 +44,6 @@ class Uart; class Platform : public SimObject { - protected: - typedef TheISA::Addr Addr; public: /** Pointer to the interrupt controller */ IntrControl *intrctrl; diff --git a/dev/simple_disk.hh b/dev/simple_disk.hh index f68d5bfff..57f81c5a9 100644 --- a/dev/simple_disk.hh +++ b/dev/simple_disk.hh @@ -44,8 +44,6 @@ class PhysicalMemory; */ class SimpleDisk : public SimObject { - protected: - typedef TheISA::Addr Addr; public: typedef uint64_t baddr_t; diff --git a/dev/sinicreg.hh b/dev/sinicreg.hh index 1378e079d..fc1f4c06b 100644 --- a/dev/sinicreg.hh +++ b/dev/sinicreg.hh @@ -163,7 +163,7 @@ struct Info /* namespace Regs */ } inline const Regs::Info& -regInfo(TheISA::Addr daddr) +regInfo(Addr daddr) { static Regs::Info invalid = { 0, false, false, "invalid" }; static Regs::Info info [] = { @@ -199,7 +199,7 @@ regInfo(TheISA::Addr daddr) } inline bool -regValid(TheISA::Addr daddr) +regValid(Addr daddr) { if (daddr > Regs::Size) return false; diff --git a/dev/tsunami.hh b/dev/tsunami.hh index 79b561ed7..7fd91d5b2 100644 --- a/dev/tsunami.hh +++ b/dev/tsunami.hh @@ -55,8 +55,6 @@ class System; class Tsunami : public Platform { - protected: - typedef TheISA::Addr Addr; public: /** Max number of CPUs in a Tsunami */ static const int Max_CPUs = 64; diff --git a/kern/kernel_stats.hh b/kern/kernel_stats.hh index 3e4fdf9e6..273a56ec3 100644 --- a/kern/kernel_stats.hh +++ b/kern/kernel_stats.hh @@ -50,8 +50,6 @@ extern const char *modestr[]; class Binning { - protected: - typedef TheISA::Addr Addr; private: std::string myname; System *system; @@ -126,8 +124,6 @@ class Binning class Statistics : public Serializable { - protected: - typedef TheISA::Addr Addr; private: friend class Binning; diff --git a/kern/linux/aligned.hh b/kern/linux/aligned.hh index 137f65076..18d1b43c0 100644 --- a/kern/linux/aligned.hh +++ b/kern/linux/aligned.hh @@ -37,7 +37,7 @@ #if __GNUC__ == 3 && __GNUC_MINOR__ != 3 typedef uint64_t uint64_ta __attribute__ ((aligned (8))) ; typedef int64_t int64_ta __attribute__ ((aligned (8))) ; -typedef TheISA::Addr Addr_a __attribute__ ((aligned (8))) ; +typedef Addr Addr_a __attribute__ ((aligned (8))) ; #else #define uint64_ta uint64_t __attribute__ ((aligned (8))) #define int64_ta int64_t __attribute__ ((aligned (8))) diff --git a/kern/linux/linux.hh b/kern/linux/linux.hh index bac6d6a7d..0dbccf546 100644 --- a/kern/linux/linux.hh +++ b/kern/linux/linux.hh @@ -53,9 +53,6 @@ class Linux {}; /// class Linux { - protected: - typedef TheISA::Addr Addr; - public: //@{ diff --git a/kern/linux/linux_threadinfo.hh b/kern/linux/linux_threadinfo.hh index f20188360..a1c378d6a 100644 --- a/kern/linux/linux_threadinfo.hh +++ b/kern/linux/linux_threadinfo.hh @@ -37,8 +37,6 @@ namespace Linux { class ThreadInfo { - protected: - typedef TheISA::Addr Addr; private: ExecContext *xc; diff --git a/kern/tru64/mbuf.hh b/kern/tru64/mbuf.hh index 7b84b5e10..93424858f 100644 --- a/kern/tru64/mbuf.hh +++ b/kern/tru64/mbuf.hh @@ -35,35 +35,35 @@ namespace tru64 { struct m_hdr { - TheISA::Addr mh_next; // 0x00 - TheISA::Addr mh_nextpkt; // 0x08 - TheISA::Addr mh_data; // 0x10 + Addr mh_next; // 0x00 + Addr mh_nextpkt; // 0x08 + Addr mh_data; // 0x10 int32_t mh_len; // 0x18 int32_t mh_type; // 0x1C int32_t mh_flags; // 0x20 int32_t mh_pad0; // 0x24 - TheISA::Addr mh_foo[4]; // 0x28, 0x30, 0x38, 0x40 + Addr mh_foo[4]; // 0x28, 0x30, 0x38, 0x40 }; struct pkthdr { int32_t len; int32_t protocolSum; - TheISA::Addr rcvif; + Addr rcvif; }; struct m_ext { - TheISA::Addr ext_buf; // 0x00 - TheISA::Addr ext_free; // 0x08 + Addr ext_buf; // 0x00 + Addr ext_free; // 0x08 uint32_t ext_size; // 0x10 uint32_t ext_pad0; // 0x14 - TheISA::Addr ext_arg; // 0x18 + Addr ext_arg; // 0x18 struct ext_refq { - TheISA::Addr forw, back; // 0x20, 0x28 + Addr forw, back; // 0x20, 0x28 } ext_ref; - TheISA::Addr uiomove_f; // 0x30 + Addr uiomove_f; // 0x30 int32_t protocolSum; // 0x38 int32_t bytesSummed; // 0x3C - TheISA::Addr checksum; // 0x40 + Addr checksum; // 0x40 }; struct mbuf { diff --git a/kern/tru64/tru64.hh b/kern/tru64/tru64.hh index a21cd6be2..1579a54d8 100644 --- a/kern/tru64/tru64.hh +++ b/kern/tru64/tru64.hh @@ -392,7 +392,7 @@ class Tru64 { /// For stack_create. struct vm_stack { // was void * - TheISA::Addr address; //!< address hint + Addr address; //!< address hint size_t rsize; //!< red zone size size_t ysize; //!< yellow zone size size_t gsize; //!< green zone size @@ -401,7 +401,7 @@ class Tru64 { uint64_t align; //!< address alignment uint64_t flags; //!< MAP_FIXED etc. // was struct memalloc_attr * - TheISA::Addr attr; //!< allocation policy + Addr attr; //!< allocation policy uint64_t reserved; //!< reserved }; @@ -433,7 +433,7 @@ class Tru64 { sigset_t sigmask; //!< thread signal mask sigset_t sig; //!< thread pending mask // struct nxm_pth_state * - TheISA::Addr pth_id; //!< out-of-line state + Addr pth_id; //!< out-of-line state int flags; //!< shared flags #define US_SIGSTACK 0x1 // thread called sigaltstack #define US_ONSTACK 0x2 // thread is running on altstack @@ -469,12 +469,12 @@ class Tru64 { int nxm_set_quantum; //!< quantum reset value int nxm_sysevent; //!< syscall state // struct nxm_upcall * - TheISA::Addr nxm_uc_ret; //!< stack ptr of null thread + Addr nxm_uc_ret; //!< stack ptr of null thread // void * - TheISA::Addr nxm_tid; //!< scheduler's thread id + Addr nxm_tid; //!< scheduler's thread id int64_t nxm_va; //!< page fault address // struct nxm_pth_state * - TheISA::Addr nxm_pthid; //!< id of null thread + Addr nxm_pthid; //!< id of null thread uint64_t nxm_bound_pcs_count; //!< bound PCS thread count int64_t pad[2]; //!< pad }; @@ -502,9 +502,9 @@ class Tru64 { int nxm_nslots_per_rad; //!< max number of VP slots per RAD int nxm_nrads; //!< max number of RADs // nxm_slot_state_t * - TheISA::Addr nxm_slot_state; //!< per-VP slot state + Addr nxm_slot_state; //!< per-VP slot state // struct nxm_shared * - TheISA::Addr nxm_rad[1]; //!< per-RAD shared areas + Addr nxm_rad[1]; //!< per-RAD shared areas }; /// For nxm_thread_create. @@ -523,7 +523,7 @@ class Tru64 { int policy; //!< policy int signal_type; //!< signal_type // void * - TheISA::Addr pthid; //!< pthid + Addr pthid; //!< pthid sigset_t sigmask; //!< sigmask /// Initial register values. struct { @@ -539,7 +539,7 @@ class Tru64 { /// memory space. Used by stat(), fstat(), and lstat(). template static void - copyOutStatBuf(FunctionalMemory *mem, TheISA::Addr addr, global_stat *host) + copyOutStatBuf(FunctionalMemory *mem, Addr addr, global_stat *host) { TypedBufferArg tgt(addr); @@ -565,7 +565,7 @@ class Tru64 { /// memory space. Used by statfs() and fstatfs(). template static void - copyOutStatfsBuf(FunctionalMemory *mem, TheISA::Addr addr, global_statfs *host) + copyOutStatfsBuf(FunctionalMemory *mem, Addr addr, global_statfs *host) { TypedBufferArg tgt(addr); @@ -589,13 +589,13 @@ class Tru64 { class F64 { public: - static void copyOutStatBuf(FunctionalMemory *mem, TheISA::Addr addr, + static void copyOutStatBuf(FunctionalMemory *mem, Addr addr, global_stat *host) { Tru64::copyOutStatBuf(mem, addr, host); } - static void copyOutStatfsBuf(FunctionalMemory *mem, TheISA::Addr addr, + static void copyOutStatfsBuf(FunctionalMemory *mem, Addr addr, global_statfs *host) { Tru64::copyOutStatfsBuf(mem, addr, host); @@ -604,13 +604,13 @@ class Tru64 { class PreF64 { public: - static void copyOutStatBuf(FunctionalMemory *mem, TheISA::Addr addr, + static void copyOutStatBuf(FunctionalMemory *mem, Addr addr, global_stat *host) { Tru64::copyOutStatBuf(mem, addr, host); } - static void copyOutStatfsBuf(FunctionalMemory *mem, TheISA::Addr addr, + static void copyOutStatfsBuf(FunctionalMemory *mem, Addr addr, global_statfs *host) { Tru64::copyOutStatfsBuf(mem, addr, host); @@ -622,7 +622,7 @@ class Tru64 { /// the simulated memory space. Used by pre_F64_stat(), /// pre_F64_fstat(), and pre_F64_lstat(). static void - copyOutPreF64StatBuf(FunctionalMemory *mem, TheISA::Addr addr, struct stat *host) + copyOutPreF64StatBuf(FunctionalMemory *mem, Addr addr, struct stat *host) { TypedBufferArg tgt(addr); @@ -653,7 +653,6 @@ class Tru64 { getdirentriesFunc(SyscallDesc *desc, int callnum, Process *process, ExecContext *xc) { - using TheISA::Addr; #ifdef __CYGWIN__ panic("getdirent not implemented on cygwin!"); #else @@ -809,7 +808,6 @@ class Tru64 { nxm_task_initFunc(SyscallDesc *desc, int callnum, Process *process, ExecContext *xc) { - using TheISA::Addr; TypedBufferArg attrp(xc->getSyscallArg(0)); TypedBufferArg configptr_ptr(xc->getSyscallArg(1)); @@ -939,7 +937,6 @@ class Tru64 { nxm_thread_createFunc(SyscallDesc *desc, int callnum, Process *process, ExecContext *xc) { - using TheISA::Addr; TypedBufferArg attrp(xc->getSyscallArg(0)); TypedBufferArg kidp(xc->getSyscallArg(1)); int thread_index = xc->getSyscallArg(2); @@ -1079,7 +1076,6 @@ class Tru64 { nxm_blockFunc(SyscallDesc *desc, int callnum, Process *process, ExecContext *xc) { - using TheISA::Addr; Addr uaddr = xc->getSyscallArg(0); uint64_t val = xc->getSyscallArg(1); uint64_t secs = xc->getSyscallArg(2); @@ -1101,7 +1097,6 @@ class Tru64 { nxm_unblockFunc(SyscallDesc *desc, int callnum, Process *process, ExecContext *xc) { - using TheISA::Addr; Addr uaddr = xc->getSyscallArg(0); cout << xc->cpu->name() << ": nxm_unblock " @@ -1129,7 +1124,7 @@ class Tru64 { /// Activate exec context waiting on a channel. Just activate one /// by default. static int - activate_waiting_context(TheISA::Addr uaddr, Process *process, + activate_waiting_context(Addr uaddr, Process *process, bool activate_all = false) { int num_activated = 0; @@ -1158,7 +1153,7 @@ class Tru64 { /// M5 hacked-up lock acquire. static void - m5_lock_mutex(TheISA::Addr uaddr, Process *process, ExecContext *xc) + m5_lock_mutex(Addr uaddr, Process *process, ExecContext *xc) { TypedBufferArg lockp(uaddr); @@ -1177,7 +1172,7 @@ class Tru64 { /// M5 unlock call. static void - m5_unlock_mutex(TheISA::Addr uaddr, Process *process, ExecContext *xc) + m5_unlock_mutex(Addr uaddr, Process *process, ExecContext *xc) { TypedBufferArg lockp(uaddr); @@ -1199,7 +1194,6 @@ class Tru64 { m5_mutex_lockFunc(SyscallDesc *desc, int callnum, Process *process, ExecContext *xc) { - using TheISA::Addr; Addr uaddr = xc->getSyscallArg(0); m5_lock_mutex(uaddr, process, xc); @@ -1215,7 +1209,6 @@ class Tru64 { m5_mutex_trylockFunc(SyscallDesc *desc, int callnum, Process *process, ExecContext *xc) { - using TheISA::Addr; Addr uaddr = xc->getSyscallArg(0); TypedBufferArg lockp(uaddr); @@ -1236,7 +1229,6 @@ class Tru64 { m5_mutex_unlockFunc(SyscallDesc *desc, int callnum, Process *process, ExecContext *xc) { - using TheISA::Addr; Addr uaddr = xc->getSyscallArg(0); m5_unlock_mutex(uaddr, process, xc); @@ -1249,7 +1241,6 @@ class Tru64 { m5_cond_signalFunc(SyscallDesc *desc, int callnum, Process *process, ExecContext *xc) { - using TheISA::Addr; Addr cond_addr = xc->getSyscallArg(0); // Wake up one process waiting on the condition variable. @@ -1263,7 +1254,6 @@ class Tru64 { m5_cond_broadcastFunc(SyscallDesc *desc, int callnum, Process *process, ExecContext *xc) { - using TheISA::Addr; Addr cond_addr = xc->getSyscallArg(0); activate_waiting_context(cond_addr, process, true); @@ -1276,7 +1266,6 @@ class Tru64 { m5_cond_waitFunc(SyscallDesc *desc, int callnum, Process *process, ExecContext *xc) { - using TheISA::Addr; Addr cond_addr = xc->getSyscallArg(0); Addr lock_addr = xc->getSyscallArg(1); TypedBufferArg condp(cond_addr); diff --git a/sim/host.hh b/sim/host.hh index ef7008042..f7e64f23c 100644 --- a/sim/host.hh +++ b/sim/host.hh @@ -54,4 +54,12 @@ typedef int64_t Counter; */ typedef int64_t Tick; +/** + * Address type + * This will probably be moved somewhere else in the near future. + * This should be at least as big as the biggest address width in use + * in the system, which will probably be 64 bits. + */ +typedef uint64_t Addr; + #endif // __HOST_H__ diff --git a/sim/process.hh b/sim/process.hh index 6e91bb0ab..71b7d02b3 100644 --- a/sim/process.hh +++ b/sim/process.hh @@ -52,7 +52,6 @@ class SyscallDesc; class Process : public SimObject { protected: - typedef TheISA::Addr Addr; typedef TheISA::RegFile RegFile; typedef TheISA::MachInst MachInst; public: diff --git a/sim/pseudo_inst.hh b/sim/pseudo_inst.hh index 07bdd7091..3857f2050 100644 --- a/sim/pseudo_inst.hh +++ b/sim/pseudo_inst.hh @@ -52,8 +52,8 @@ namespace AlphaPseudo void dumpstats(ExecContext *xc, Tick delay, Tick period); void dumpresetstats(ExecContext *xc, Tick delay, Tick period); void m5checkpoint(ExecContext *xc, Tick delay, Tick period); - uint64_t readfile(ExecContext *xc, TheISA::Addr vaddr, uint64_t len, uint64_t offset); + uint64_t readfile(ExecContext *xc, Addr vaddr, uint64_t len, uint64_t offset); void debugbreak(ExecContext *xc); void switchcpu(ExecContext *xc); - void addsymbol(ExecContext *xc, TheISA::Addr addr, TheISA::Addr symbolAddr); + void addsymbol(ExecContext *xc, Addr addr, Addr symbolAddr); } diff --git a/sim/syscall_emul.hh b/sim/syscall_emul.hh index 4e4f9a5d7..f49248dea 100644 --- a/sim/syscall_emul.hh +++ b/sim/syscall_emul.hh @@ -90,9 +90,6 @@ class SyscallDesc { class BaseBufferArg { - protected: - typedef TheISA::Addr Addr; - public: BaseBufferArg(Addr _addr, int _size) : addr(_addr), size(_size) @@ -643,7 +640,7 @@ template SyscallReturn mmapFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) { - TheISA::Addr start = xc->getSyscallArg(0); + Addr start = xc->getSyscallArg(0); uint64_t length = xc->getSyscallArg(1); // int prot = xc->getSyscallArg(2); int flags = xc->getSyscallArg(3); diff --git a/sim/system.hh b/sim/system.hh index 4bf33a170..aa697c040 100644 --- a/sim/system.hh +++ b/sim/system.hh @@ -50,8 +50,6 @@ namespace Kernel { class Binning; } class System : public SimObject { - protected: - typedef TheISA::Addr Addr; public: MemoryController *memctrl; PhysicalMemory *physmem; diff --git a/sim/vptr.hh b/sim/vptr.hh index 1baa00610..7ec43602d 100644 --- a/sim/vptr.hh +++ b/sim/vptr.hh @@ -37,8 +37,6 @@ class ExecContext; template class VPtr { - protected: - typedef TheISA::Addr Addr; public: typedef T Type; From 8d80fd1477fa39ebc5bad4ca5c727b2871fd9b8d Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 21 Feb 2006 20:10:40 -0500 Subject: [PATCH 080/180] Changed Fault * to Fault, which is a typedef to FaultBase *, which is the old Fault class renamed. --HG-- extra : convert_revision : 5b2f457401f8ff94fe39fe071288eb117814b7bb --- arch/alpha/alpha_memory.cc | 6 ++-- arch/alpha/alpha_memory.hh | 4 +-- arch/alpha/ev5.cc | 12 ++++---- arch/alpha/faults.cc | 38 ++++++++++++------------- arch/alpha/faults.hh | 6 ++-- arch/alpha/isa/fp.isa | 14 +++++----- arch/alpha/isa/main.isa | 8 +++--- arch/alpha/isa/mem.isa | 52 +++++++++++++++++------------------ arch/alpha/isa/unimp.isa | 4 +-- arch/alpha/isa/unknown.isa | 2 +- arch/mips/isa/formats/mem.isa | 40 +++++++++++++-------------- cpu/base_dyn_inst.cc | 14 +++++----- cpu/base_dyn_inst.hh | 18 ++++++------ cpu/exec_context.cc | 2 +- cpu/exec_context.hh | 32 ++++++++++----------- cpu/o3/alpha_cpu.hh | 34 +++++++++++------------ cpu/o3/alpha_cpu_impl.hh | 8 +++--- cpu/o3/alpha_dyn_inst.hh | 14 +++++----- cpu/o3/alpha_dyn_inst_impl.hh | 8 +++--- cpu/o3/commit_impl.hh | 2 +- cpu/o3/fetch.hh | 2 +- cpu/o3/fetch_impl.hh | 6 ++-- cpu/o3/regfile.hh | 8 +++--- cpu/ozone/cpu.hh | 40 +++++++++++++-------------- cpu/simple/cpu.cc | 48 ++++++++++++++++---------------- cpu/simple/cpu.hh | 16 +++++------ dev/alpha_console.cc | 4 +-- dev/alpha_console.hh | 4 +-- dev/baddev.cc | 4 +-- dev/baddev.hh | 4 +-- dev/ide_ctrl.cc | 4 +-- dev/ide_ctrl.hh | 4 +-- dev/isa_fake.cc | 4 +-- dev/isa_fake.hh | 4 +-- dev/ns_gige.cc | 4 +-- dev/ns_gige.hh | 4 +-- dev/pciconfigall.cc | 4 +-- dev/pciconfigall.hh | 4 +-- dev/pcidev.cc | 28 +++++++++---------- dev/pcidev.hh | 36 ++++++++++++------------ dev/sinic.cc | 14 +++++----- dev/sinic.hh | 10 +++---- dev/tsunami_cchip.cc | 4 +-- dev/tsunami_cchip.hh | 4 +-- dev/tsunami_io.cc | 4 +-- dev/tsunami_io.hh | 4 +-- dev/tsunami_pchip.cc | 4 +-- dev/tsunami_pchip.hh | 4 +-- dev/uart.hh | 4 +-- dev/uart8250.cc | 4 +-- dev/uart8250.hh | 4 +-- kern/kernel_stats.hh | 3 +- sim/faults.hh | 19 +++++++------ 53 files changed, 317 insertions(+), 315 deletions(-) diff --git a/arch/alpha/alpha_memory.cc b/arch/alpha/alpha_memory.cc index 615ce92a4..d00186d95 100644 --- a/arch/alpha/alpha_memory.cc +++ b/arch/alpha/alpha_memory.cc @@ -303,7 +303,7 @@ AlphaITB::fault(Addr pc, ExecContext *xc) const } -Fault * +Fault AlphaITB::translate(MemReqPtr &req) const { InternalProcReg *ipr = req->xc->regs.ipr; @@ -493,7 +493,7 @@ AlphaDTB::fault(MemReqPtr &req, uint64_t flags) const } } -Fault * +Fault AlphaDTB::translate(MemReqPtr &req, bool write) const { RegFile *regs = &req->xc->regs; @@ -575,7 +575,7 @@ AlphaDTB::translate(MemReqPtr &req, bool write) const fault(req, (write ? MM_STAT_WR_MASK : 0) | MM_STAT_DTB_MISS_MASK); if (write) { write_misses++; } else { read_misses++; } - return (req->flags & VPTE) ? (Fault *)PDtbMissFault : (Fault *)NDtbMissFault; + return (req->flags & VPTE) ? (Fault)PDtbMissFault : (Fault)NDtbMissFault; } req->paddr = (pte->ppn << AlphaISA::PageShift) + diff --git a/arch/alpha/alpha_memory.hh b/arch/alpha/alpha_memory.hh index 849063f59..de955fa46 100644 --- a/arch/alpha/alpha_memory.hh +++ b/arch/alpha/alpha_memory.hh @@ -94,7 +94,7 @@ class AlphaITB : public AlphaTLB AlphaITB(const std::string &name, int size); virtual void regStats(); - Fault * translate(MemReqPtr &req) const; + Fault translate(MemReqPtr &req) const; }; class AlphaDTB : public AlphaTLB @@ -120,7 +120,7 @@ class AlphaDTB : public AlphaTLB AlphaDTB(const std::string &name, int size); virtual void regStats(); - Fault * translate(MemReqPtr &req, bool write) const; + Fault translate(MemReqPtr &req, bool write) const; }; #endif // __ALPHA_MEMORY_HH__ diff --git a/arch/alpha/ev5.cc b/arch/alpha/ev5.cc index 72f48bfb2..4777907e0 100644 --- a/arch/alpha/ev5.cc +++ b/arch/alpha/ev5.cc @@ -85,7 +85,7 @@ AlphaISA::initCPU(RegFile *regs) // alpha exceptions - value equals trap address, update with MD_FAULT_TYPE // const Addr -AlphaISA::fault_addr(Fault * fault) +AlphaISA::fault_addr(Fault fault) { //Check for the system wide faults if(fault == NoFault) return 0x0000; @@ -177,7 +177,7 @@ AlphaISA::zeroRegisters(CPU *cpu) } void -ExecContext::ev5_trap(Fault * fault) +ExecContext::ev5_trap(Fault fault) { DPRINTF(Fault, "Fault %s at PC: %#x\n", fault->name, regs.pc); cpu->recordEvent(csprintf("Fault %s", fault->name)); @@ -209,7 +209,7 @@ ExecContext::ev5_trap(Fault * fault) void -AlphaISA::intr_post(RegFile *regs, Fault * fault, Addr pc) +AlphaISA::intr_post(RegFile *regs, Fault fault, Addr pc) { InternalProcReg *ipr = regs->ipr; bool use_pc = (fault == NoFault); @@ -235,7 +235,7 @@ AlphaISA::intr_post(RegFile *regs, Fault * fault, Addr pc) // that's it! (orders of magnitude less painful than x86) } -Fault * +Fault ExecContext::hwrei() { uint64_t *ipr = regs.ipr; @@ -259,7 +259,7 @@ ExecContext::hwrei() } uint64_t -ExecContext::readIpr(int idx, Fault * &fault) +ExecContext::readIpr(int idx, Fault &fault) { uint64_t *ipr = regs.ipr; uint64_t retval = 0; // return value, default 0 @@ -370,7 +370,7 @@ ExecContext::readIpr(int idx, Fault * &fault) int break_ipl = -1; #endif -Fault * +Fault ExecContext::setIpr(int idx, uint64_t val) { uint64_t *ipr = regs.ipr; diff --git a/arch/alpha/faults.cc b/arch/alpha/faults.cc index e05b3fe59..fa4950198 100644 --- a/arch/alpha/faults.cc +++ b/arch/alpha/faults.cc @@ -57,24 +57,24 @@ PalFaultType * const PalFault = IntegerOverflowFaultType * const IntegerOverflowFault = new IntegerOverflowFaultType("intover", 16, 0x0501); -Fault ** ListOfFaults[] = { - (Fault **)&NoFault, - (Fault **)&ResetFault, - (Fault **)&MachineCheckFault, - (Fault **)&ArithmeticFault, - (Fault **)&InterruptFault, - (Fault **)&NDtbMissFault, - (Fault **)&PDtbMissFault, - (Fault **)&AlignmentFault, - (Fault **)&DtbPageFault, - (Fault **)&DtbAcvFault, - (Fault **)&ItbMissFault, - (Fault **)&ItbPageFault, - (Fault **)&ItbAcvFault, - (Fault **)&UnimplementedOpcodeFault, - (Fault **)&FloatEnableFault, - (Fault **)&PalFault, - (Fault **)&IntegerOverflowFault, +Fault * ListOfFaults[] = { + (Fault *)&NoFault, + (Fault *)&ResetFault, + (Fault *)&MachineCheckFault, + (Fault *)&ArithmeticFault, + (Fault *)&InterruptFault, + (Fault *)&NDtbMissFault, + (Fault *)&PDtbMissFault, + (Fault *)&AlignmentFault, + (Fault *)&DtbPageFault, + (Fault *)&DtbAcvFault, + (Fault *)&ItbMissFault, + (Fault *)&ItbPageFault, + (Fault *)&ItbAcvFault, + (Fault *)&UnimplementedOpcodeFault, + (Fault *)&FloatEnableFault, + (Fault *)&PalFault, + (Fault *)&IntegerOverflowFault, }; -int NumFaults = sizeof(ListOfFaults) / sizeof(Fault **); +int NumFaults = sizeof(ListOfFaults) / sizeof(Fault *); diff --git a/arch/alpha/faults.hh b/arch/alpha/faults.hh index 60c9e735c..3e25adc4e 100644 --- a/arch/alpha/faults.hh +++ b/arch/alpha/faults.hh @@ -32,11 +32,11 @@ #include "sim/faults.hh" #include "arch/isa_traits.hh" //For the Addr type -class AlphaFault : public Fault +class AlphaFault : public FaultBase { public: AlphaFault(char * newName, int newId, Addr newVect) - : Fault(newName, newId), vect(newVect) + : FaultBase(newName, newId), vect(newVect) {;} Addr vect; @@ -154,7 +154,7 @@ extern class IntegerOverflowFaultType : public AlphaFault {;} } * const IntegerOverflowFault; -extern Fault ** ListOfFaults[]; +extern Fault * ListOfFaults[]; extern int NumFaults; #endif // __FAULTS_HH__ diff --git a/arch/alpha/isa/fp.isa b/arch/alpha/isa/fp.isa index c718c5524..7e81fb830 100644 --- a/arch/alpha/isa/fp.isa +++ b/arch/alpha/isa/fp.isa @@ -32,16 +32,16 @@ output exec {{ /// @retval Full-system mode: NoFault if FP is enabled, FenFault /// if not. Non-full-system mode: always returns NoFault. #if FULL_SYSTEM - inline Fault * checkFpEnableFault(%(CPU_exec_context)s *xc) + inline Fault checkFpEnableFault(%(CPU_exec_context)s *xc) { - Fault * fault = NoFault; // dummy... this ipr access should not fault + Fault fault = NoFault; // dummy... this ipr access should not fault if (!EV5::ICSR_FPE(xc->readIpr(AlphaISA::IPR_ICSR, fault))) { fault = FloatEnableFault; } return fault; } #else - inline Fault * checkFpEnableFault(%(CPU_exec_context)s *xc) + inline Fault checkFpEnableFault(%(CPU_exec_context)s *xc) { return NoFault; } @@ -199,7 +199,7 @@ output decoder {{ // FP instruction class execute method template. Handles non-standard // rounding modes. def template FloatingPointExecute {{ - Fault * %(class_name)s::execute(%(CPU_exec_context)s *xc, + Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const { if (trappingMode != Imprecise && !warnedOnTrapping) { @@ -208,7 +208,7 @@ def template FloatingPointExecute {{ warnedOnTrapping = true; } - Fault * fault = NoFault; + Fault fault = NoFault; %(fp_enable_check)s; %(op_decl)s; @@ -242,7 +242,7 @@ def template FloatingPointExecute {{ // rounding mode control is needed. Like BasicExecute, but includes // check & warning for non-standard trapping mode. def template FPFixedRoundingExecute {{ - Fault * %(class_name)s::execute(%(CPU_exec_context)s *xc, + Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const { if (trappingMode != Imprecise && !warnedOnTrapping) { @@ -251,7 +251,7 @@ def template FPFixedRoundingExecute {{ warnedOnTrapping = true; } - Fault * fault = NoFault; + Fault fault = NoFault; %(fp_enable_check)s; %(op_decl)s; diff --git a/arch/alpha/isa/main.isa b/arch/alpha/isa/main.isa index 862b2b95e..b8d03c0be 100644 --- a/arch/alpha/isa/main.isa +++ b/arch/alpha/isa/main.isa @@ -258,7 +258,7 @@ output decoder {{ // Declarations for execute() methods. def template BasicExecDeclare {{ - Fault * execute(%(CPU_exec_context)s *, Trace::InstRecord *) const; + Fault execute(%(CPU_exec_context)s *, Trace::InstRecord *) const; }}; // Basic instruction class declaration template. @@ -287,10 +287,10 @@ def template BasicConstructor {{ // Basic instruction class execute method template. def template BasicExecute {{ - Fault * %(class_name)s::execute(%(CPU_exec_context)s *xc, + Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const { - Fault * fault = NoFault; + Fault fault = NoFault; %(fp_enable_check)s; %(op_decl)s; @@ -382,7 +382,7 @@ output decoder {{ }}; output exec {{ - Fault * + Fault Nop::execute(%(CPU_exec_context)s *, Trace::InstRecord *) const { return NoFault; diff --git a/arch/alpha/isa/mem.isa b/arch/alpha/isa/mem.isa index 33b7341ef..61d6ea8fa 100644 --- a/arch/alpha/isa/mem.isa +++ b/arch/alpha/isa/mem.isa @@ -173,12 +173,12 @@ def template LoadStoreDeclare {{ def template InitiateAccDeclare {{ - Fault * initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const; + Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const; }}; def template CompleteAccDeclare {{ - Fault * completeAcc(uint8_t *, %(CPU_exec_context)s *, Trace::InstRecord *) const; + Fault completeAcc(uint8_t *, %(CPU_exec_context)s *, Trace::InstRecord *) const; }}; @@ -208,12 +208,12 @@ def template LoadStoreConstructor {{ def template EACompExecute {{ - Fault * + Fault %(class_name)s::EAComp::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const { Addr EA; - Fault * fault = NoFault; + Fault fault = NoFault; %(fp_enable_check)s; %(op_decl)s; @@ -230,12 +230,12 @@ def template EACompExecute {{ }}; def template LoadMemAccExecute {{ - Fault * + Fault %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const { Addr EA; - Fault * fault = NoFault; + Fault fault = NoFault; %(fp_enable_check)s; %(op_decl)s; @@ -257,11 +257,11 @@ def template LoadMemAccExecute {{ def template LoadExecute {{ - Fault * %(class_name)s::execute(%(CPU_exec_context)s *xc, + Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const { Addr EA; - Fault * fault = NoFault; + Fault fault = NoFault; %(fp_enable_check)s; %(op_decl)s; @@ -283,11 +283,11 @@ def template LoadExecute {{ def template LoadInitiateAcc {{ - Fault * %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, + Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const { Addr EA; - Fault * fault = NoFault; + Fault fault = NoFault; %(fp_enable_check)s; %(op_src_decl)s; @@ -304,11 +304,11 @@ def template LoadInitiateAcc {{ def template LoadCompleteAcc {{ - Fault * %(class_name)s::completeAcc(uint8_t *data, + Fault %(class_name)s::completeAcc(uint8_t *data, %(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const { - Fault * fault = NoFault; + Fault fault = NoFault; %(fp_enable_check)s; %(op_src_decl)s; @@ -330,12 +330,12 @@ def template LoadCompleteAcc {{ def template StoreMemAccExecute {{ - Fault * + Fault %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const { Addr EA; - Fault * fault = NoFault; + Fault fault = NoFault; uint64_t write_result = 0; %(fp_enable_check)s; @@ -367,11 +367,11 @@ def template StoreMemAccExecute {{ def template StoreExecute {{ - Fault * %(class_name)s::execute(%(CPU_exec_context)s *xc, + Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const { Addr EA; - Fault * fault = NoFault; + Fault fault = NoFault; uint64_t write_result = 0; %(fp_enable_check)s; @@ -402,11 +402,11 @@ def template StoreExecute {{ }}; def template StoreInitiateAcc {{ - Fault * %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, + Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const { Addr EA; - Fault * fault = NoFault; + Fault fault = NoFault; uint64_t write_result = 0; %(fp_enable_check)s; @@ -431,11 +431,11 @@ def template StoreInitiateAcc {{ def template StoreCompleteAcc {{ - Fault * %(class_name)s::completeAcc(uint8_t *data, + Fault %(class_name)s::completeAcc(uint8_t *data, %(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const { - Fault * fault = NoFault; + Fault fault = NoFault; uint64_t write_result = 0; %(fp_enable_check)s; @@ -457,11 +457,11 @@ def template StoreCompleteAcc {{ def template MiscMemAccExecute {{ - Fault * %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc, + Fault %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const { Addr EA; - Fault * fault = NoFault; + Fault fault = NoFault; %(fp_enable_check)s; %(op_decl)s; @@ -477,11 +477,11 @@ def template MiscMemAccExecute {{ }}; def template MiscExecute {{ - Fault * %(class_name)s::execute(%(CPU_exec_context)s *xc, + Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const { Addr EA; - Fault * fault = NoFault; + Fault fault = NoFault; %(fp_enable_check)s; %(op_decl)s; @@ -497,7 +497,7 @@ def template MiscExecute {{ }}; def template MiscInitiateAcc {{ - Fault * %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, + Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const { panic("Misc instruction does not support split access method!"); @@ -507,7 +507,7 @@ def template MiscInitiateAcc {{ def template MiscCompleteAcc {{ - Fault * %(class_name)s::completeAcc(uint8_t *data, + Fault %(class_name)s::completeAcc(uint8_t *data, %(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const { diff --git a/arch/alpha/isa/unimp.isa b/arch/alpha/isa/unimp.isa index ce8197708..de4ac3eaf 100644 --- a/arch/alpha/isa/unimp.isa +++ b/arch/alpha/isa/unimp.isa @@ -105,7 +105,7 @@ output decoder {{ }}; output exec {{ - Fault * + Fault FailUnimplemented::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const { @@ -114,7 +114,7 @@ output exec {{ return UnimplementedOpcodeFault; } - Fault * + Fault WarnUnimplemented::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const { diff --git a/arch/alpha/isa/unknown.isa b/arch/alpha/isa/unknown.isa index e7f8bc8db..4601b3684 100644 --- a/arch/alpha/isa/unknown.isa +++ b/arch/alpha/isa/unknown.isa @@ -36,7 +36,7 @@ output decoder {{ }}; output exec {{ - Fault * + Fault Unknown::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const { diff --git a/arch/mips/isa/formats/mem.isa b/arch/mips/isa/formats/mem.isa index 18ae3df5f..134548746 100644 --- a/arch/mips/isa/formats/mem.isa +++ b/arch/mips/isa/formats/mem.isa @@ -131,12 +131,12 @@ def template LoadStoreDeclare {{ def template InitiateAccDeclare {{ - Fault * initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const; + Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const; }}; def template CompleteAccDeclare {{ - Fault * completeAcc(uint8_t *, %(CPU_exec_context)s *, Trace::InstRecord *) const; + Fault completeAcc(uint8_t *, %(CPU_exec_context)s *, Trace::InstRecord *) const; }}; @@ -166,12 +166,12 @@ def template LoadStoreConstructor {{ def template EACompExecute {{ - Fault * + Fault %(class_name)s::EAComp::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const { Addr EA; - Fault * fault = NoFault; + Fault fault = NoFault; %(fp_enable_check)s; %(op_decl)s; @@ -188,12 +188,12 @@ def template EACompExecute {{ }}; def template LoadMemAccExecute {{ - Fault * + Fault %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const { Addr EA; - Fault * fault = NoFault; + Fault fault = NoFault; %(fp_enable_check)s; %(op_decl)s; @@ -215,11 +215,11 @@ def template LoadMemAccExecute {{ def template LoadExecute {{ - Fault * %(class_name)s::execute(%(CPU_exec_context)s *xc, + Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const { Addr EA; - Fault * fault = NoFault; + Fault fault = NoFault; %(fp_enable_check)s; %(op_decl)s; @@ -241,11 +241,11 @@ def template LoadExecute {{ def template LoadInitiateAcc {{ - Fault * %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, + Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const { Addr EA; - Fault * fault = NoFault; + Fault fault = NoFault; %(fp_enable_check)s; %(op_src_decl)s; @@ -262,11 +262,11 @@ def template LoadInitiateAcc {{ def template LoadCompleteAcc {{ - Fault * %(class_name)s::completeAcc(uint8_t *data, + Fault %(class_name)s::completeAcc(uint8_t *data, %(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const { - Fault * fault = NoFault; + Fault fault = NoFault; %(fp_enable_check)s; %(op_src_decl)s; @@ -288,12 +288,12 @@ def template LoadCompleteAcc {{ def template StoreMemAccExecute {{ - Fault * + Fault %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const { Addr EA; - Fault * fault = NoFault; + Fault fault = NoFault; uint64_t write_result = 0; %(fp_enable_check)s; @@ -325,11 +325,11 @@ def template StoreMemAccExecute {{ def template StoreExecute {{ - Fault * %(class_name)s::execute(%(CPU_exec_context)s *xc, + Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const { Addr EA; - Fault * fault = NoFault; + Fault fault = NoFault; uint64_t write_result = 0; %(fp_enable_check)s; @@ -360,11 +360,11 @@ def template StoreExecute {{ }}; def template StoreInitiateAcc {{ - Fault * %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, + Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const { Addr EA; - Fault * fault = NoFault; + Fault fault = NoFault; uint64_t write_result = 0; %(fp_enable_check)s; @@ -389,11 +389,11 @@ def template StoreInitiateAcc {{ def template StoreCompleteAcc {{ - Fault * %(class_name)s::completeAcc(uint8_t *data, + Fault %(class_name)s::completeAcc(uint8_t *data, %(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const { - Fault * fault = NoFault; + Fault fault = NoFault; uint64_t write_result = 0; %(fp_enable_check)s; diff --git a/cpu/base_dyn_inst.cc b/cpu/base_dyn_inst.cc index 9901c90af..86314bef1 100644 --- a/cpu/base_dyn_inst.cc +++ b/cpu/base_dyn_inst.cc @@ -145,7 +145,7 @@ BaseDynInst::prefetch(Addr addr, unsigned flags) fault = NoFault; // note this is a local, not BaseDynInst::fault - Fault * trans_fault = xc->translateDataReadReq(req); + Fault trans_fault = xc->translateDataReadReq(req); if (trans_fault == NoFault && !(req->flags & UNCACHEABLE)) { // It's a valid address to cacheable space. Record key MemReq @@ -208,14 +208,14 @@ BaseDynInst::writeHint(Addr addr, int size, unsigned flags) * @todo Need to find a way to get the cache block size here. */ template -Fault * +Fault BaseDynInst::copySrcTranslate(Addr src) { MemReqPtr req = new MemReq(src, xc, 64); req->asid = asid; // translate to physical address - Fault * fault = xc->translateDataReadReq(req); + Fault fault = xc->translateDataReadReq(req); if (fault == NoFault) { xc->copySrcAddr = src; @@ -231,7 +231,7 @@ BaseDynInst::copySrcTranslate(Addr src) * @todo Need to find a way to get the cache block size here. */ template -Fault * +Fault BaseDynInst::copy(Addr dest) { uint8_t data[64]; @@ -241,7 +241,7 @@ BaseDynInst::copy(Addr dest) req->asid = asid; // translate to physical address - Fault * fault = xc->translateDataWriteReq(req); + Fault fault = xc->translateDataWriteReq(req); if (fault == NoFault) { Addr dest_addr = req->paddr; @@ -277,10 +277,10 @@ BaseDynInst::dump(std::string &outstring) #if 0 template -Fault * +Fault BaseDynInst::mem_access(mem_cmd cmd, Addr addr, void *p, int nbytes) { - Fault * fault; + Fault fault; // check alignments, even speculative this test should always pass if ((nbytes & nbytes - 1) != 0 || (addr & nbytes - 1) != 0) { diff --git a/cpu/base_dyn_inst.hh b/cpu/base_dyn_inst.hh index 84fd5403e..e94c44151 100644 --- a/cpu/base_dyn_inst.hh +++ b/cpu/base_dyn_inst.hh @@ -83,16 +83,16 @@ class BaseDynInst : public FastAlloc, public RefCounted Trace::InstRecord *traceData; template - Fault * read(Addr addr, T &data, unsigned flags); + Fault read(Addr addr, T &data, unsigned flags); template - Fault * write(T data, Addr addr, unsigned flags, + Fault write(T data, Addr addr, unsigned flags, uint64_t *res); void prefetch(Addr addr, unsigned flags); void writeHint(Addr addr, int size, unsigned flags); - Fault * copySrcTranslate(Addr src); - Fault * copy(Addr dest); + Fault copySrcTranslate(Addr src); + Fault copy(Addr dest); /** @todo: Consider making this private. */ public: @@ -148,7 +148,7 @@ class BaseDynInst : public FastAlloc, public RefCounted ExecContext *xc; /** The kind of fault this instruction has generated. */ - Fault * fault; + Fault fault; /** The effective virtual address (lds & stores only). */ Addr effAddr; @@ -219,7 +219,7 @@ class BaseDynInst : public FastAlloc, public RefCounted public: void - trace_mem(Fault * fault, // last fault + trace_mem(Fault fault, // last fault MemCmd cmd, // last command Addr addr, // virtual address of access void *p, // memory accessed @@ -232,7 +232,7 @@ class BaseDynInst : public FastAlloc, public RefCounted void dump(std::string &outstring); /** Returns the fault type. */ - Fault * getFault() { return fault; } + Fault getFault() { return fault; } /** Checks whether or not this instruction has had its branch target * calculated yet. For now it is not utilized and is hacked to be @@ -441,7 +441,7 @@ class BaseDynInst : public FastAlloc, public RefCounted template template -inline Fault * +inline Fault BaseDynInst::read(Addr addr, T &data, unsigned flags) { MemReqPtr req = new MemReq(addr, xc, sizeof(T), flags); @@ -484,7 +484,7 @@ BaseDynInst::read(Addr addr, T &data, unsigned flags) template template -inline Fault * +inline Fault BaseDynInst::write(T data, Addr addr, unsigned flags, uint64_t *res) { if (traceData) { diff --git a/cpu/exec_context.cc b/cpu/exec_context.cc index e7facbebb..9bed3ba47 100644 --- a/cpu/exec_context.cc +++ b/cpu/exec_context.cc @@ -221,7 +221,7 @@ ExecContext::regStats(const string &name) } void -ExecContext::trap(Fault * fault) +ExecContext::trap(Fault fault) { //TheISA::trap(fault); //One possible way to do it... diff --git a/cpu/exec_context.hh b/cpu/exec_context.hh index 3fa7d078e..3e0d77254 100644 --- a/cpu/exec_context.hh +++ b/cpu/exec_context.hh @@ -213,17 +213,17 @@ class ExecContext int getInstAsid() { return regs.instAsid(); } int getDataAsid() { return regs.dataAsid(); } - Fault * translateInstReq(MemReqPtr &req) + Fault translateInstReq(MemReqPtr &req) { return itb->translate(req); } - Fault * translateDataReadReq(MemReqPtr &req) + Fault translateDataReadReq(MemReqPtr &req) { return dtb->translate(req, false); } - Fault * translateDataWriteReq(MemReqPtr &req) + Fault translateDataWriteReq(MemReqPtr &req) { return dtb->translate(req, true); } @@ -238,7 +238,7 @@ class ExecContext int getInstAsid() { return asid; } int getDataAsid() { return asid; } - Fault * dummyTranslation(MemReqPtr &req) + Fault dummyTranslation(MemReqPtr &req) { #if 0 assert((req->vaddr >> 48 & 0xffff) == 0); @@ -249,15 +249,15 @@ class ExecContext req->paddr = req->paddr | (Addr)req->asid << sizeof(Addr) * 8 - 16; return NoFault; } - Fault * translateInstReq(MemReqPtr &req) + Fault translateInstReq(MemReqPtr &req) { return dummyTranslation(req); } - Fault * translateDataReadReq(MemReqPtr &req) + Fault translateDataReadReq(MemReqPtr &req) { return dummyTranslation(req); } - Fault * translateDataWriteReq(MemReqPtr &req) + Fault translateDataWriteReq(MemReqPtr &req) { return dummyTranslation(req); } @@ -265,7 +265,7 @@ class ExecContext #endif template - Fault * read(MemReqPtr &req, T &data) + Fault read(MemReqPtr &req, T &data) { #if FULL_SYSTEM && defined(TARGET_ALPHA) if (req->flags & LOCKED) { @@ -275,14 +275,14 @@ class ExecContext } #endif - Fault * error; + Fault error; error = mem->read(req, data); data = LittleEndianGuest::gtoh(data); return error; } template - Fault * write(MemReqPtr &req, T &data) + Fault write(MemReqPtr &req, T &data) { #if FULL_SYSTEM && defined(TARGET_ALPHA) @@ -340,7 +340,7 @@ class ExecContext inst = new_inst; } - Fault * instRead(MemReqPtr &req) + Fault instRead(MemReqPtr &req) { return mem->read(req, inst); } @@ -419,13 +419,13 @@ class ExecContext } #if FULL_SYSTEM - uint64_t readIpr(int idx, Fault * &fault); - Fault * setIpr(int idx, uint64_t val); + uint64_t readIpr(int idx, Fault &fault); + Fault setIpr(int idx, uint64_t val); int readIntrFlag() { return regs.intrflag; } void setIntrFlag(int val) { regs.intrflag = val; } - Fault * hwrei(); + Fault hwrei(); bool inPalMode() { return AlphaISA::PcPAL(regs.pc); } - void ev5_trap(Fault * fault); + void ev5_trap(Fault fault); bool simPalCheck(int palFunc); #endif @@ -435,7 +435,7 @@ class ExecContext * @todo How to do this properly so it's dependent upon ISA only? */ - void trap(Fault * fault); + void trap(Fault fault); #if !FULL_SYSTEM TheISA::IntReg getSyscallArg(int i) diff --git a/cpu/o3/alpha_cpu.hh b/cpu/o3/alpha_cpu.hh index 2be70f5c2..b35bcf9e3 100644 --- a/cpu/o3/alpha_cpu.hh +++ b/cpu/o3/alpha_cpu.hh @@ -63,23 +63,23 @@ class AlphaFullCPU : public FullO3CPU // void clear_interrupt(int int_num, int index); // void clear_interrupts(); - Fault * translateInstReq(MemReqPtr &req) + Fault translateInstReq(MemReqPtr &req) { return itb->translate(req); } - Fault * translateDataReadReq(MemReqPtr &req) + Fault translateDataReadReq(MemReqPtr &req) { return dtb->translate(req, false); } - Fault * translateDataWriteReq(MemReqPtr &req) + Fault translateDataWriteReq(MemReqPtr &req) { return dtb->translate(req, true); } #else - Fault * dummyTranslation(MemReqPtr &req) + Fault dummyTranslation(MemReqPtr &req) { #if 0 assert((req->vaddr >> 48 & 0xffff) == 0); @@ -91,17 +91,17 @@ class AlphaFullCPU : public FullO3CPU return NoFault; } - Fault * translateInstReq(MemReqPtr &req) + Fault translateInstReq(MemReqPtr &req) { return dummyTranslation(req); } - Fault * translateDataReadReq(MemReqPtr &req) + Fault translateDataReadReq(MemReqPtr &req) { return dummyTranslation(req); } - Fault * translateDataWriteReq(MemReqPtr &req) + Fault translateDataWriteReq(MemReqPtr &req) { return dummyTranslation(req); } @@ -136,16 +136,16 @@ class AlphaFullCPU : public FullO3CPU // look like. #if FULL_SYSTEM uint64_t *getIpr(); - uint64_t readIpr(int idx, Fault * &fault); - Fault * setIpr(int idx, uint64_t val); + uint64_t readIpr(int idx, Fault &fault); + Fault setIpr(int idx, uint64_t val); int readIntrFlag(); void setIntrFlag(int val); - Fault * hwrei(); + Fault hwrei(); bool inPalMode() { return AlphaISA::PcPAL(this->regFile.readPC()); } bool inPalMode(uint64_t PC) { return AlphaISA::PcPAL(PC); } - void trap(Fault * fault); + void trap(Fault fault); bool simPalCheck(int palFunc); void processInterrupts(); @@ -198,7 +198,7 @@ class AlphaFullCPU : public FullO3CPU bool palShadowEnabled; // Not sure this is used anywhere. - void intr_post(RegFile *regs, Fault * fault, Addr pc); + void intr_post(RegFile *regs, Fault fault, Addr pc); // Actually used within exec files. Implement properly. void swapPALShadow(bool use_shadow); // Called by CPU constructor. Can implement as I please. @@ -211,7 +211,7 @@ class AlphaFullCPU : public FullO3CPU template - Fault * read(MemReqPtr &req, T &data) + Fault read(MemReqPtr &req, T &data) { #if FULL_SYSTEM && defined(TARGET_ALPHA) if (req->flags & LOCKED) { @@ -221,20 +221,20 @@ class AlphaFullCPU : public FullO3CPU } #endif - Fault * error; + Fault error; error = this->mem->read(req, data); data = gtoh(data); return error; } template - Fault * read(MemReqPtr &req, T &data, int load_idx) + Fault read(MemReqPtr &req, T &data, int load_idx) { return this->iew.ldstQueue.read(req, data, load_idx); } template - Fault * write(MemReqPtr &req, T &data) + Fault write(MemReqPtr &req, T &data) { #if FULL_SYSTEM && defined(TARGET_ALPHA) @@ -284,7 +284,7 @@ class AlphaFullCPU : public FullO3CPU } template - Fault * write(MemReqPtr &req, T &data, int store_idx) + Fault write(MemReqPtr &req, T &data, int store_idx) { return this->iew.ldstQueue.write(req, data, store_idx); } diff --git a/cpu/o3/alpha_cpu_impl.hh b/cpu/o3/alpha_cpu_impl.hh index 6736cf9bc..7ec1ba663 100644 --- a/cpu/o3/alpha_cpu_impl.hh +++ b/cpu/o3/alpha_cpu_impl.hh @@ -246,13 +246,13 @@ AlphaFullCPU::getIpr() template uint64_t -AlphaFullCPU::readIpr(int idx, Fault * &fault) +AlphaFullCPU::readIpr(int idx, Fault &fault) { return this->regFile.readIpr(idx, fault); } template -Fault * +Fault AlphaFullCPU::setIpr(int idx, uint64_t val) { return this->regFile.setIpr(idx, val); @@ -274,7 +274,7 @@ AlphaFullCPU::setIntrFlag(int val) // Can force commit stage to squash and stuff. template -Fault * +Fault AlphaFullCPU::hwrei() { uint64_t *ipr = getIpr(); @@ -323,7 +323,7 @@ AlphaFullCPU::simPalCheck(int palFunc) // stage. template void -AlphaFullCPU::trap(Fault * fault) +AlphaFullCPU::trap(Fault fault) { // Keep in mind that a trap may be initiated by fetch if there's a TLB // miss diff --git a/cpu/o3/alpha_dyn_inst.hh b/cpu/o3/alpha_dyn_inst.hh index b113d9487..f282c287c 100644 --- a/cpu/o3/alpha_dyn_inst.hh +++ b/cpu/o3/alpha_dyn_inst.hh @@ -69,7 +69,7 @@ class AlphaDynInst : public BaseDynInst AlphaDynInst(StaticInstPtr &_staticInst); /** Executes the instruction.*/ - Fault * execute() + Fault execute() { return this->fault = this->staticInst->execute(this, this->traceData); } @@ -82,13 +82,13 @@ class AlphaDynInst : public BaseDynInst void setFpcr(uint64_t val); #if FULL_SYSTEM - uint64_t readIpr(int idx, Fault * &fault); - Fault * setIpr(int idx, uint64_t val); - Fault * hwrei(); + uint64_t readIpr(int idx, Fault &fault); + Fault setIpr(int idx, uint64_t val); + Fault hwrei(); int readIntrFlag(); void setIntrFlag(int val); bool inPalMode(); - void trap(Fault * fault); + void trap(Fault fault); bool simPalCheck(int palFunc); #else void syscall(); @@ -215,12 +215,12 @@ class AlphaDynInst : public BaseDynInst } public: - Fault * calcEA() + Fault calcEA() { return this->staticInst->eaCompInst()->execute(this, this->traceData); } - Fault * memAccess() + Fault memAccess() { return this->staticInst->memAccInst()->execute(this, this->traceData); } diff --git a/cpu/o3/alpha_dyn_inst_impl.hh b/cpu/o3/alpha_dyn_inst_impl.hh index 9f9df3da1..eebe7675a 100644 --- a/cpu/o3/alpha_dyn_inst_impl.hh +++ b/cpu/o3/alpha_dyn_inst_impl.hh @@ -98,20 +98,20 @@ AlphaDynInst::setFpcr(uint64_t val) #if FULL_SYSTEM template uint64_t -AlphaDynInst::readIpr(int idx, Fault * &fault) +AlphaDynInst::readIpr(int idx, Fault &fault) { return this->cpu->readIpr(idx, fault); } template -Fault * +Fault AlphaDynInst::setIpr(int idx, uint64_t val) { return this->cpu->setIpr(idx, val); } template -Fault * +Fault AlphaDynInst::hwrei() { return this->cpu->hwrei(); @@ -140,7 +140,7 @@ AlphaDynInst::inPalMode() template void -AlphaDynInst::trap(Fault * fault) +AlphaDynInst::trap(Fault fault) { this->cpu->trap(fault); } diff --git a/cpu/o3/commit_impl.hh b/cpu/o3/commit_impl.hh index 47b4dfd00..e289bc0c0 100644 --- a/cpu/o3/commit_impl.hh +++ b/cpu/o3/commit_impl.hh @@ -393,7 +393,7 @@ SimpleCommit::commitHead(DynInstPtr &head_inst, unsigned inst_num) } // Check if the instruction caused a fault. If so, trap. - Fault * inst_fault = head_inst->getFault(); + Fault inst_fault = head_inst->getFault(); if (inst_fault != NoFault) { if (!head_inst->isNop()) { diff --git a/cpu/o3/fetch.hh b/cpu/o3/fetch.hh index 82a6cd818..cc64800d9 100644 --- a/cpu/o3/fetch.hh +++ b/cpu/o3/fetch.hh @@ -122,7 +122,7 @@ class SimpleFetch * @param fetch_PC The PC address that is being fetched from. * @return Any fault that occured. */ - Fault * fetchCacheLine(Addr fetch_PC); + Fault fetchCacheLine(Addr fetch_PC); inline void doSquash(const Addr &new_PC); diff --git a/cpu/o3/fetch_impl.hh b/cpu/o3/fetch_impl.hh index e8d333ed4..8029fc732 100644 --- a/cpu/o3/fetch_impl.hh +++ b/cpu/o3/fetch_impl.hh @@ -221,7 +221,7 @@ SimpleFetch::lookupAndUpdateNextPC(DynInstPtr &inst, Addr &next_PC) } template -Fault * +Fault SimpleFetch::fetchCacheLine(Addr fetch_PC) { // Check if the instruction exists within the cache. @@ -236,7 +236,7 @@ SimpleFetch::fetchCacheLine(Addr fetch_PC) unsigned flags = 0; #endif // FULL_SYSTEM - Fault * fault = NoFault; + Fault fault = NoFault; // Align the fetch PC so it's at the start of a cache block. fetch_PC = icacheBlockAlignPC(fetch_PC); @@ -468,7 +468,7 @@ SimpleFetch::fetch() Addr fetch_PC = cpu->readPC(); // Fault code for memory access. - Fault * fault = NoFault; + Fault fault = NoFault; // If returning from the delay of a cache miss, then update the status // to running, otherwise do the cache access. Possibly move this up diff --git a/cpu/o3/regfile.hh b/cpu/o3/regfile.hh index 021f9b0b6..ee7b8858e 100644 --- a/cpu/o3/regfile.hh +++ b/cpu/o3/regfile.hh @@ -215,8 +215,8 @@ class PhysRegFile } #if FULL_SYSTEM - uint64_t readIpr(int idx, Fault * &fault); - Fault * setIpr(int idx, uint64_t val); + uint64_t readIpr(int idx, Fault &fault); + Fault setIpr(int idx, uint64_t val); InternalProcReg *getIpr() { return ipr; } int readIntrFlag() { return intrflag; } void setIntrFlag(int val) { intrflag = val; } @@ -279,7 +279,7 @@ PhysRegFile::PhysRegFile(unsigned _numPhysicalIntRegs, //the DynInst level. template uint64_t -PhysRegFile::readIpr(int idx, Fault * &fault) +PhysRegFile::readIpr(int idx, Fault &fault) { uint64_t retval = 0; // return value, default 0 @@ -387,7 +387,7 @@ PhysRegFile::readIpr(int idx, Fault * &fault) extern int break_ipl; template -Fault * +Fault PhysRegFile::setIpr(int idx, uint64_t val) { uint64_t old; diff --git a/cpu/ozone/cpu.hh b/cpu/ozone/cpu.hh index 7976632d9..667e2b3f8 100644 --- a/cpu/ozone/cpu.hh +++ b/cpu/ozone/cpu.hh @@ -285,17 +285,17 @@ class OoOCPU : public BaseCPU int getInstAsid() { return xc->regs.instAsid(); } int getDataAsid() { return xc->regs.dataAsid(); } - Fault * translateInstReq(MemReqPtr &req) + Fault translateInstReq(MemReqPtr &req) { return itb->translate(req); } - Fault * translateDataReadReq(MemReqPtr &req) + Fault translateDataReadReq(MemReqPtr &req) { return dtb->translate(req, false); } - Fault * translateDataWriteReq(MemReqPtr &req) + Fault translateDataWriteReq(MemReqPtr &req) { return dtb->translate(req, true); } @@ -310,7 +310,7 @@ class OoOCPU : public BaseCPU int getInstAsid() { return xc->asid; } int getDataAsid() { return xc->asid; } - Fault * dummyTranslation(MemReqPtr &req) + Fault dummyTranslation(MemReqPtr &req) { #if 0 assert((req->vaddr >> 48 & 0xffff) == 0); @@ -321,15 +321,15 @@ class OoOCPU : public BaseCPU req->paddr = req->paddr | (Addr)req->asid << sizeof(Addr) * 8 - 16; return NoFault; } - Fault * translateInstReq(MemReqPtr &req) + Fault translateInstReq(MemReqPtr &req) { return dummyTranslation(req); } - Fault * translateDataReadReq(MemReqPtr &req) + Fault translateDataReadReq(MemReqPtr &req) { return dummyTranslation(req); } - Fault * translateDataWriteReq(MemReqPtr &req) + Fault translateDataWriteReq(MemReqPtr &req) { return dummyTranslation(req); } @@ -337,10 +337,10 @@ class OoOCPU : public BaseCPU #endif template - Fault * read(Addr addr, T &data, unsigned flags, DynInstPtr inst); + Fault read(Addr addr, T &data, unsigned flags, DynInstPtr inst); template - Fault * write(T data, Addr addr, unsigned flags, + Fault write(T data, Addr addr, unsigned flags, uint64_t *res, DynInstPtr inst); void prefetch(Addr addr, unsigned flags) @@ -353,9 +353,9 @@ class OoOCPU : public BaseCPU // need to do this... } - Fault * copySrcTranslate(Addr src); + Fault copySrcTranslate(Addr src); - Fault * copy(Addr dest); + Fault copy(Addr dest); private: bool executeInst(DynInstPtr &inst); @@ -368,7 +368,7 @@ class OoOCPU : public BaseCPU bool getOneInst(); - Fault * fetchCacheLine(); + Fault fetchCacheLine(); InstSeqNum getAndIncrementInstSeq(); @@ -511,13 +511,13 @@ class OoOCPU : public BaseCPU void setFpcr(uint64_t val) { xc->setFpcr(val); } #if FULL_SYSTEM - uint64_t readIpr(int idx, Fault * &fault) { return xc->readIpr(idx, fault); } - Fault * setIpr(int idx, uint64_t val) { return xc->setIpr(idx, val); } - Fault * hwrei() { return xc->hwrei(); } + uint64_t readIpr(int idx, Fault &fault) { return xc->readIpr(idx, fault); } + Fault setIpr(int idx, uint64_t val) { return xc->setIpr(idx, val); } + Fault hwrei() { return xc->hwrei(); } int readIntrFlag() { return xc->readIntrFlag(); } void setIntrFlag(int val) { xc->setIntrFlag(val); } bool inPalMode() { return xc->inPalMode(); } - void ev5_trap(Fault * fault) { xc->ev5_trap(fault); } + void ev5_trap(Fault fault) { xc->ev5_trap(fault); } bool simPalCheck(int palFunc) { return xc->simPalCheck(palFunc); } #else void syscall() { xc->syscall(); } @@ -530,7 +530,7 @@ class OoOCPU : public BaseCPU // precise architected memory state accessor macros template template -Fault * +Fault OoOCPU::read(Addr addr, T &data, unsigned flags, DynInstPtr inst) { MemReqPtr readReq = new MemReq(); @@ -541,7 +541,7 @@ OoOCPU::read(Addr addr, T &data, unsigned flags, DynInstPtr inst) readReq->reset(addr, sizeof(T), flags); // translate to physical address - This might be an ISA impl call - Fault * fault = translateDataReadReq(readReq); + Fault fault = translateDataReadReq(readReq); // do functional access if (fault == NoFault) @@ -575,7 +575,7 @@ OoOCPU::read(Addr addr, T &data, unsigned flags, DynInstPtr inst) template template -Fault * +Fault OoOCPU::write(T data, Addr addr, unsigned flags, uint64_t *res, DynInstPtr inst) { @@ -594,7 +594,7 @@ OoOCPU::write(T data, Addr addr, unsigned flags, writeReq->reset(addr, sizeof(T), flags); // translate to physical address - Fault * fault = translateDataWriteReq(writeReq); + Fault fault = translateDataWriteReq(writeReq); // do functional access if (fault == NoFault) diff --git a/cpu/simple/cpu.cc b/cpu/simple/cpu.cc index c3f256de9..f7a6d2c21 100644 --- a/cpu/simple/cpu.cc +++ b/cpu/simple/cpu.cc @@ -312,7 +312,7 @@ change_thread_state(int thread_number, int activate, int priority) { } -Fault * +Fault SimpleCPU::copySrcTranslate(Addr src) { static bool no_warn = true; @@ -332,7 +332,7 @@ SimpleCPU::copySrcTranslate(Addr src) memReq->reset(src & ~(blk_size - 1), blk_size); // translate to physical address - Fault * fault = xc->translateDataReadReq(memReq); + Fault fault = xc->translateDataReadReq(memReq); assert(fault != AlignmentFault); @@ -346,7 +346,7 @@ SimpleCPU::copySrcTranslate(Addr src) return fault; } -Fault * +Fault SimpleCPU::copy(Addr dest) { static bool no_warn = true; @@ -367,7 +367,7 @@ SimpleCPU::copy(Addr dest) memReq->reset(dest & ~(blk_size -1), blk_size); // translate to physical address - Fault * fault = xc->translateDataWriteReq(memReq); + Fault fault = xc->translateDataWriteReq(memReq); assert(fault != AlignmentFault); @@ -394,11 +394,11 @@ SimpleCPU::copy(Addr dest) // precise architected memory state accessor macros template -Fault * +Fault SimpleCPU::read(Addr addr, T &data, unsigned flags) { if (status() == DcacheMissStall || status() == DcacheMissSwitch) { - Fault * fault = xc->read(memReq,data); + Fault fault = xc->read(memReq,data); if (traceData) { traceData->setAddr(addr); @@ -409,7 +409,7 @@ SimpleCPU::read(Addr addr, T &data, unsigned flags) memReq->reset(addr, sizeof(T), flags); // translate to physical address - Fault * fault = xc->translateDataReadReq(memReq); + Fault fault = xc->translateDataReadReq(memReq); // if we have a cache, do cache access too if (fault == NoFault && dcacheInterface) { @@ -447,32 +447,32 @@ SimpleCPU::read(Addr addr, T &data, unsigned flags) #ifndef DOXYGEN_SHOULD_SKIP_THIS template -Fault * +Fault SimpleCPU::read(Addr addr, uint64_t &data, unsigned flags); template -Fault * +Fault SimpleCPU::read(Addr addr, uint32_t &data, unsigned flags); template -Fault * +Fault SimpleCPU::read(Addr addr, uint16_t &data, unsigned flags); template -Fault * +Fault SimpleCPU::read(Addr addr, uint8_t &data, unsigned flags); #endif //DOXYGEN_SHOULD_SKIP_THIS template<> -Fault * +Fault SimpleCPU::read(Addr addr, double &data, unsigned flags) { return read(addr, *(uint64_t*)&data, flags); } template<> -Fault * +Fault SimpleCPU::read(Addr addr, float &data, unsigned flags) { return read(addr, *(uint32_t*)&data, flags); @@ -480,7 +480,7 @@ SimpleCPU::read(Addr addr, float &data, unsigned flags) template<> -Fault * +Fault SimpleCPU::read(Addr addr, int32_t &data, unsigned flags) { return read(addr, (uint32_t&)data, flags); @@ -488,13 +488,13 @@ SimpleCPU::read(Addr addr, int32_t &data, unsigned flags) template -Fault * +Fault SimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res) { memReq->reset(addr, sizeof(T), flags); // translate to physical address - Fault * fault = xc->translateDataWriteReq(memReq); + Fault fault = xc->translateDataWriteReq(memReq); // do functional access if (fault == NoFault) @@ -531,32 +531,32 @@ SimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res) #ifndef DOXYGEN_SHOULD_SKIP_THIS template -Fault * +Fault SimpleCPU::write(uint64_t data, Addr addr, unsigned flags, uint64_t *res); template -Fault * +Fault SimpleCPU::write(uint32_t data, Addr addr, unsigned flags, uint64_t *res); template -Fault * +Fault SimpleCPU::write(uint16_t data, Addr addr, unsigned flags, uint64_t *res); template -Fault * +Fault SimpleCPU::write(uint8_t data, Addr addr, unsigned flags, uint64_t *res); #endif //DOXYGEN_SHOULD_SKIP_THIS template<> -Fault * +Fault SimpleCPU::write(double data, Addr addr, unsigned flags, uint64_t *res) { return write(*(uint64_t*)&data, addr, flags, res); } template<> -Fault * +Fault SimpleCPU::write(float data, Addr addr, unsigned flags, uint64_t *res) { return write(*(uint32_t*)&data, addr, flags, res); @@ -564,7 +564,7 @@ SimpleCPU::write(float data, Addr addr, unsigned flags, uint64_t *res) template<> -Fault * +Fault SimpleCPU::write(int32_t data, Addr addr, unsigned flags, uint64_t *res) { return write((uint32_t)data, addr, flags, res); @@ -638,7 +638,7 @@ SimpleCPU::tick() traceData = NULL; - Fault * fault = NoFault; + Fault fault = NoFault; #if FULL_SYSTEM if (checkInterrupts && check_interrupts() && !xc->inPalMode() && diff --git a/cpu/simple/cpu.hh b/cpu/simple/cpu.hh index 8a3900726..d3e0323b6 100644 --- a/cpu/simple/cpu.hh +++ b/cpu/simple/cpu.hh @@ -236,10 +236,10 @@ class SimpleCPU : public BaseCPU virtual void unserialize(Checkpoint *cp, const std::string §ion); template - Fault * read(Addr addr, T &data, unsigned flags); + Fault read(Addr addr, T &data, unsigned flags); template - Fault * write(T data, Addr addr, unsigned flags, uint64_t *res); + Fault write(T data, Addr addr, unsigned flags, uint64_t *res); // These functions are only used in CPU models that split // effective address computation from the actual memory access. @@ -256,9 +256,9 @@ class SimpleCPU : public BaseCPU // need to do this... } - Fault * copySrcTranslate(Addr src); + Fault copySrcTranslate(Addr src); - Fault * copy(Addr dest); + Fault copy(Addr dest); // The register accessor methods provide the index of the // instruction's operand (e.g., 0 or 1), not the architectural @@ -327,13 +327,13 @@ class SimpleCPU : public BaseCPU void setFpcr(uint64_t val) { xc->setFpcr(val); } #if FULL_SYSTEM - uint64_t readIpr(int idx, Fault * &fault) { return xc->readIpr(idx, fault); } - Fault * setIpr(int idx, uint64_t val) { return xc->setIpr(idx, val); } - Fault * hwrei() { return xc->hwrei(); } + uint64_t readIpr(int idx, Fault &fault) { return xc->readIpr(idx, fault); } + Fault setIpr(int idx, uint64_t val) { return xc->setIpr(idx, val); } + Fault hwrei() { return xc->hwrei(); } int readIntrFlag() { return xc->readIntrFlag(); } void setIntrFlag(int val) { xc->setIntrFlag(val); } bool inPalMode() { return xc->inPalMode(); } - void ev5_trap(Fault * fault) { xc->ev5_trap(fault); } + void ev5_trap(Fault fault) { xc->ev5_trap(fault); } bool simPalCheck(int palFunc) { return xc->simPalCheck(palFunc); } #else void syscall() { xc->syscall(); } diff --git a/dev/alpha_console.cc b/dev/alpha_console.cc index a7ef8f641..0f36e63fb 100644 --- a/dev/alpha_console.cc +++ b/dev/alpha_console.cc @@ -100,7 +100,7 @@ AlphaConsole::startup() alphaAccess->intrClockFrequency = platform->intrFrequency(); } -Fault * +Fault AlphaConsole::read(MemReqPtr &req, uint8_t *data) { memset(data, 0, req->size); @@ -190,7 +190,7 @@ AlphaConsole::read(MemReqPtr &req, uint8_t *data) return NoFault; } -Fault * +Fault AlphaConsole::write(MemReqPtr &req, const uint8_t *data) { uint64_t val; diff --git a/dev/alpha_console.hh b/dev/alpha_console.hh index 75f0a3a67..74ad795f0 100644 --- a/dev/alpha_console.hh +++ b/dev/alpha_console.hh @@ -110,8 +110,8 @@ class AlphaConsole : public PioDevice /** * memory mapped reads and writes */ - virtual Fault * read(MemReqPtr &req, uint8_t *data); - virtual Fault * write(MemReqPtr &req, const uint8_t *data); + virtual Fault read(MemReqPtr &req, uint8_t *data); + virtual Fault write(MemReqPtr &req, const uint8_t *data); /** * standard serialization routines for checkpointing diff --git a/dev/baddev.cc b/dev/baddev.cc index 62871e348..87d683a5d 100644 --- a/dev/baddev.cc +++ b/dev/baddev.cc @@ -62,7 +62,7 @@ BadDevice::BadDevice(const string &name, Addr a, MemoryController *mmu, } -Fault * +Fault BadDevice::read(MemReqPtr &req, uint8_t *data) { @@ -70,7 +70,7 @@ BadDevice::read(MemReqPtr &req, uint8_t *data) return NoFault; } -Fault * +Fault BadDevice::write(MemReqPtr &req, const uint8_t *data) { panic("Device %s not imlpmented\n", devname); diff --git a/dev/baddev.hh b/dev/baddev.hh index b7b67e31a..c2a204c05 100644 --- a/dev/baddev.hh +++ b/dev/baddev.hh @@ -71,7 +71,7 @@ class BadDevice : public PioDevice * @param data A pointer to write the read data to. * @return The fault condition of the access. */ - virtual Fault * read(MemReqPtr &req, uint8_t *data); + virtual Fault read(MemReqPtr &req, uint8_t *data); /** * On a write event we just panic aand hopefully print a @@ -80,7 +80,7 @@ class BadDevice : public PioDevice * @param data The data to write. * @return The fault condition of the access. */ - virtual Fault * write(MemReqPtr &req, const uint8_t *data); + virtual Fault write(MemReqPtr &req, const uint8_t *data); /** * Return how long this access will take. diff --git a/dev/ide_ctrl.cc b/dev/ide_ctrl.cc index 18c988b81..56682a224 100644 --- a/dev/ide_ctrl.cc +++ b/dev/ide_ctrl.cc @@ -391,7 +391,7 @@ IdeController::writeConfig(int offset, int size, const uint8_t *data) } } -Fault * +Fault IdeController::read(MemReqPtr &req, uint8_t *data) { Addr offset; @@ -461,7 +461,7 @@ IdeController::read(MemReqPtr &req, uint8_t *data) return NoFault; } -Fault * +Fault IdeController::write(MemReqPtr &req, const uint8_t *data) { Addr offset; diff --git a/dev/ide_ctrl.hh b/dev/ide_ctrl.hh index 72523f57c..0fbaf9207 100644 --- a/dev/ide_ctrl.hh +++ b/dev/ide_ctrl.hh @@ -213,7 +213,7 @@ class IdeController : public PciDev * @param data Return the field read. * @return The fault condition of the access. */ - virtual Fault * read(MemReqPtr &req, uint8_t *data); + virtual Fault read(MemReqPtr &req, uint8_t *data); /** * Write to the mmapped I/O control registers. @@ -221,7 +221,7 @@ class IdeController : public PciDev * @param data The data to write. * @return The fault condition of the access. */ - virtual Fault * write(MemReqPtr &req, const uint8_t *data); + virtual Fault write(MemReqPtr &req, const uint8_t *data); /** * Serialize this object to the given output stream. diff --git a/dev/isa_fake.cc b/dev/isa_fake.cc index 117c9e5ad..2afebbded 100644 --- a/dev/isa_fake.cc +++ b/dev/isa_fake.cc @@ -60,7 +60,7 @@ IsaFake::IsaFake(const string &name, Addr a, MemoryController *mmu, } } -Fault * +Fault IsaFake::read(MemReqPtr &req, uint8_t *data) { DPRINTF(Tsunami, "read va=%#x size=%d\n", @@ -93,7 +93,7 @@ IsaFake::read(MemReqPtr &req, uint8_t *data) return NoFault; } -Fault * +Fault IsaFake::write(MemReqPtr &req, const uint8_t *data) { DPRINTF(Tsunami, "write - va=%#x size=%d \n", diff --git a/dev/isa_fake.hh b/dev/isa_fake.hh index 60ca5f90a..290b24b54 100644 --- a/dev/isa_fake.hh +++ b/dev/isa_fake.hh @@ -65,14 +65,14 @@ class IsaFake : public PioDevice * @param req The memory request. * @param data Where to put the data. */ - virtual Fault * read(MemReqPtr &req, uint8_t *data); + virtual Fault read(MemReqPtr &req, uint8_t *data); /** * All writes are simply ignored. * @param req The memory request. * @param data the data to not write. */ - virtual Fault * write(MemReqPtr &req, const uint8_t *data); + virtual Fault write(MemReqPtr &req, const uint8_t *data); /** * Return how long this access will take. diff --git a/dev/ns_gige.cc b/dev/ns_gige.cc index 02eb72ca4..4b08d8497 100644 --- a/dev/ns_gige.cc +++ b/dev/ns_gige.cc @@ -557,7 +557,7 @@ NSGigE::writeConfig(int offset, int size, const uint8_t* data) * This reads the device registers, which are detailed in the NS83820 * spec sheet */ -Fault * +Fault NSGigE::read(MemReqPtr &req, uint8_t *data) { assert(ioEnable); @@ -786,7 +786,7 @@ NSGigE::read(MemReqPtr &req, uint8_t *data) return NoFault; } -Fault * +Fault NSGigE::write(MemReqPtr &req, const uint8_t *data) { assert(ioEnable); diff --git a/dev/ns_gige.hh b/dev/ns_gige.hh index a14fde146..cdd8e4b9e 100644 --- a/dev/ns_gige.hh +++ b/dev/ns_gige.hh @@ -395,8 +395,8 @@ class NSGigE : public PciDev virtual void writeConfig(int offset, int size, const uint8_t *data); virtual void readConfig(int offset, int size, uint8_t *data); - virtual Fault * read(MemReqPtr &req, uint8_t *data); - virtual Fault * write(MemReqPtr &req, const uint8_t *data); + virtual Fault read(MemReqPtr &req, uint8_t *data); + virtual Fault write(MemReqPtr &req, const uint8_t *data); bool cpuIntrPending() const; void cpuIntrAck() { cpuIntrClear(); } diff --git a/dev/pciconfigall.cc b/dev/pciconfigall.cc index c581e1561..d55084fa5 100644 --- a/dev/pciconfigall.cc +++ b/dev/pciconfigall.cc @@ -96,7 +96,7 @@ PciConfigAll::startup() } -Fault * +Fault PciConfigAll::read(MemReqPtr &req, uint8_t *data) { @@ -144,7 +144,7 @@ PciConfigAll::read(MemReqPtr &req, uint8_t *data) return NoFault; } -Fault * +Fault PciConfigAll::write(MemReqPtr &req, const uint8_t *data) { Addr daddr = (req->paddr - (addr & EV5::PAddrImplMask)); diff --git a/dev/pciconfigall.hh b/dev/pciconfigall.hh index 6df033286..c6a0241d8 100644 --- a/dev/pciconfigall.hh +++ b/dev/pciconfigall.hh @@ -103,7 +103,7 @@ class PciConfigAll : public PioDevice * @param data Return the field read. * @return The fault condition of the access. */ - virtual Fault * read(MemReqPtr &req, uint8_t *data); + virtual Fault read(MemReqPtr &req, uint8_t *data); /** * Write to PCI config spcae. If the device does not exit the simulator @@ -114,7 +114,7 @@ class PciConfigAll : public PioDevice * @return The fault condition of the access. */ - virtual Fault * write(MemReqPtr &req, const uint8_t *data); + virtual Fault write(MemReqPtr &req, const uint8_t *data); /** * Start up function to check if more than one person is using an interrupt line diff --git a/dev/pcidev.cc b/dev/pcidev.cc index c469e716a..a05ee3803 100644 --- a/dev/pcidev.cc +++ b/dev/pcidev.cc @@ -70,59 +70,59 @@ PciDev::PciDev(Params *p) p->configSpace->registerDevice(p->deviceNum, p->functionNum, this); } -Fault * +Fault PciDev::read(MemReqPtr &req, uint8_t *data) { return NoFault; } -Fault * +Fault PciDev::write(MemReqPtr &req, const uint8_t *data) { return NoFault; } -Fault * +Fault PciDev::readBar0(MemReqPtr &req, Addr daddr, uint8_t *data) { panic("not implemented"); } -Fault * +Fault PciDev::readBar1(MemReqPtr &req, Addr daddr, uint8_t *data) { panic("not implemented"); } -Fault * +Fault PciDev::readBar2(MemReqPtr &req, Addr daddr, uint8_t *data) { panic("not implemented"); } -Fault * +Fault PciDev::readBar3(MemReqPtr &req, Addr daddr, uint8_t *data) { panic("not implemented"); } -Fault * +Fault PciDev::readBar4(MemReqPtr &req, Addr daddr, uint8_t *data) { panic("not implemented"); } -Fault * +Fault PciDev::readBar5(MemReqPtr &req, Addr daddr, uint8_t *data) { panic("not implemented"); } -Fault * +Fault PciDev::writeBar0(MemReqPtr &req, Addr daddr, const uint8_t *data) { panic("not implemented"); } -Fault * +Fault PciDev::writeBar1(MemReqPtr &req, Addr daddr, const uint8_t *data) { panic("not implemented"); } -Fault * +Fault PciDev::writeBar2(MemReqPtr &req, Addr daddr, const uint8_t *data) { panic("not implemented"); } -Fault * +Fault PciDev::writeBar3(MemReqPtr &req, Addr daddr, const uint8_t *data) { panic("not implemented"); } -Fault * +Fault PciDev::writeBar4(MemReqPtr &req, Addr daddr, const uint8_t *data) { panic("not implemented"); } -Fault * +Fault PciDev::writeBar5(MemReqPtr &req, Addr daddr, const uint8_t *data) { panic("not implemented"); } diff --git a/dev/pcidev.hh b/dev/pcidev.hh index c8d9685c1..9427463bf 100644 --- a/dev/pcidev.hh +++ b/dev/pcidev.hh @@ -189,37 +189,37 @@ class PciDev : public DmaDevice */ PciDev(Params *params); - virtual Fault * read(MemReqPtr &req, uint8_t *data); - virtual Fault * write(MemReqPtr &req, const uint8_t *data); + virtual Fault read(MemReqPtr &req, uint8_t *data); + virtual Fault write(MemReqPtr &req, const uint8_t *data); public: /** * Implement the read/write as BAR accesses */ - Fault * readBar(MemReqPtr &req, uint8_t *data); - Fault * writeBar(MemReqPtr &req, const uint8_t *data); + Fault readBar(MemReqPtr &req, uint8_t *data); + Fault writeBar(MemReqPtr &req, const uint8_t *data); public: /** * Read from a specific BAR */ - virtual Fault * readBar0(MemReqPtr &req, Addr daddr, uint8_t *data); - virtual Fault * readBar1(MemReqPtr &req, Addr daddr, uint8_t *data); - virtual Fault * readBar2(MemReqPtr &req, Addr daddr, uint8_t *data); - virtual Fault * readBar3(MemReqPtr &req, Addr daddr, uint8_t *data); - virtual Fault * readBar4(MemReqPtr &req, Addr daddr, uint8_t *data); - virtual Fault * readBar5(MemReqPtr &req, Addr daddr, uint8_t *data); + virtual Fault readBar0(MemReqPtr &req, Addr daddr, uint8_t *data); + virtual Fault readBar1(MemReqPtr &req, Addr daddr, uint8_t *data); + virtual Fault readBar2(MemReqPtr &req, Addr daddr, uint8_t *data); + virtual Fault readBar3(MemReqPtr &req, Addr daddr, uint8_t *data); + virtual Fault readBar4(MemReqPtr &req, Addr daddr, uint8_t *data); + virtual Fault readBar5(MemReqPtr &req, Addr daddr, uint8_t *data); public: /** * Write to a specific BAR */ - virtual Fault * writeBar0(MemReqPtr &req, Addr daddr, const uint8_t *data); - virtual Fault * writeBar1(MemReqPtr &req, Addr daddr, const uint8_t *data); - virtual Fault * writeBar2(MemReqPtr &req, Addr daddr, const uint8_t *data); - virtual Fault * writeBar3(MemReqPtr &req, Addr daddr, const uint8_t *data); - virtual Fault * writeBar4(MemReqPtr &req, Addr daddr, const uint8_t *data); - virtual Fault * writeBar5(MemReqPtr &req, Addr daddr, const uint8_t *data); + virtual Fault writeBar0(MemReqPtr &req, Addr daddr, const uint8_t *data); + virtual Fault writeBar1(MemReqPtr &req, Addr daddr, const uint8_t *data); + virtual Fault writeBar2(MemReqPtr &req, Addr daddr, const uint8_t *data); + virtual Fault writeBar3(MemReqPtr &req, Addr daddr, const uint8_t *data); + virtual Fault writeBar4(MemReqPtr &req, Addr daddr, const uint8_t *data); + virtual Fault writeBar5(MemReqPtr &req, Addr daddr, const uint8_t *data); public: /** @@ -257,7 +257,7 @@ class PciDev : public DmaDevice virtual void unserialize(Checkpoint *cp, const std::string §ion); }; -inline Fault * +inline Fault PciDev::readBar(MemReqPtr &req, uint8_t *data) { if (isBAR(req->paddr, 0)) @@ -275,7 +275,7 @@ PciDev::readBar(MemReqPtr &req, uint8_t *data) return MachineCheckFault; } -inline Fault * +inline Fault PciDev::writeBar(MemReqPtr &req, const uint8_t *data) { if (isBAR(req->paddr, 0)) diff --git a/dev/sinic.cc b/dev/sinic.cc index d175a1796..c499d2f49 100644 --- a/dev/sinic.cc +++ b/dev/sinic.cc @@ -357,11 +357,11 @@ Device::prepareWrite(int cpu, int index) /** * I/O read of device register */ -Fault * +Fault Device::read(MemReqPtr &req, uint8_t *data) { assert(config.command & PCI_CMD_MSE); - Fault * fault = readBar(req, data); + Fault fault = readBar(req, data); if (fault == MachineCheckFault) { panic("address does not map to a BAR pa=%#x va=%#x size=%d", @@ -373,7 +373,7 @@ Device::read(MemReqPtr &req, uint8_t *data) return fault; } -Fault * +Fault Device::readBar0(MemReqPtr &req, Addr daddr, uint8_t *data) { int cpu = (req->xc->regs.ipr[TheISA::IPR_PALtemp16] >> 8) & 0xff; @@ -423,7 +423,7 @@ Device::readBar0(MemReqPtr &req, Addr daddr, uint8_t *data) /** * IPR read of device register */ -Fault * +Fault Device::iprRead(Addr daddr, int cpu, uint64_t &result) { if (!regValid(daddr)) @@ -453,11 +453,11 @@ Device::iprRead(Addr daddr, int cpu, uint64_t &result) /** * I/O write of device register */ -Fault * +Fault Device::write(MemReqPtr &req, const uint8_t *data) { assert(config.command & PCI_CMD_MSE); - Fault * fault = writeBar(req, data); + Fault fault = writeBar(req, data); if (fault == MachineCheckFault) { panic("address does not map to a BAR pa=%#x va=%#x size=%d", @@ -469,7 +469,7 @@ Device::write(MemReqPtr &req, const uint8_t *data) return fault; } -Fault * +Fault Device::writeBar0(MemReqPtr &req, Addr daddr, const uint8_t *data) { int cpu = (req->xc->regs.ipr[TheISA::IPR_PALtemp16] >> 8) & 0xff; diff --git a/dev/sinic.hh b/dev/sinic.hh index 06751a955..97ebf4c30 100644 --- a/dev/sinic.hh +++ b/dev/sinic.hh @@ -271,15 +271,15 @@ class Device : public Base * Memory Interface */ public: - virtual Fault * read(MemReqPtr &req, uint8_t *data); - virtual Fault * write(MemReqPtr &req, const uint8_t *data); + virtual Fault read(MemReqPtr &req, uint8_t *data); + virtual Fault write(MemReqPtr &req, const uint8_t *data); void prepareIO(int cpu, int index); void prepareRead(int cpu, int index); void prepareWrite(int cpu, int index); - Fault * iprRead(Addr daddr, int cpu, uint64_t &result); - Fault * readBar0(MemReqPtr &req, Addr daddr, uint8_t *data); - Fault * writeBar0(MemReqPtr &req, Addr daddr, const uint8_t *data); + Fault iprRead(Addr daddr, int cpu, uint64_t &result); + Fault readBar0(MemReqPtr &req, Addr daddr, uint8_t *data); + Fault writeBar0(MemReqPtr &req, Addr daddr, const uint8_t *data); void regWrite(Addr daddr, int cpu, const uint8_t *data); Tick cacheAccess(MemReqPtr &req); diff --git a/dev/tsunami_cchip.cc b/dev/tsunami_cchip.cc index 10c08a7a2..4dc4413a1 100644 --- a/dev/tsunami_cchip.cc +++ b/dev/tsunami_cchip.cc @@ -78,7 +78,7 @@ TsunamiCChip::TsunamiCChip(const string &name, Tsunami *t, Addr a, tsunami->cchip = this; } -Fault * +Fault TsunamiCChip::read(MemReqPtr &req, uint8_t *data) { DPRINTF(Tsunami, "read va=%#x size=%d\n", req->vaddr, req->size); @@ -192,7 +192,7 @@ TsunamiCChip::read(MemReqPtr &req, uint8_t *data) return NoFault; } -Fault * +Fault TsunamiCChip::write(MemReqPtr &req, const uint8_t *data) { DPRINTF(Tsunami, "write - va=%#x value=%#x size=%d \n", diff --git a/dev/tsunami_cchip.hh b/dev/tsunami_cchip.hh index dadbdb0e3..d88ad375f 100644 --- a/dev/tsunami_cchip.hh +++ b/dev/tsunami_cchip.hh @@ -105,7 +105,7 @@ class TsunamiCChip : public PioDevice * @param data A pointer to write the read data to. * @return The fault condition of the access. */ - virtual Fault * read(MemReqPtr &req, uint8_t *data); + virtual Fault read(MemReqPtr &req, uint8_t *data); /** @@ -114,7 +114,7 @@ class TsunamiCChip : public PioDevice * @param data The data to write. * @return The fault condition of the access. */ - virtual Fault * write(MemReqPtr &req, const uint8_t *data); + virtual Fault write(MemReqPtr &req, const uint8_t *data); /** * post an RTC interrupt to the CPU diff --git a/dev/tsunami_io.cc b/dev/tsunami_io.cc index e90bb5abc..e66d6653b 100644 --- a/dev/tsunami_io.cc +++ b/dev/tsunami_io.cc @@ -446,7 +446,7 @@ TsunamiIO::frequency() const return Clock::Frequency / clockInterval; } -Fault * +Fault TsunamiIO::read(MemReqPtr &req, uint8_t *data) { DPRINTF(Tsunami, "io read va=%#x size=%d IOPorrt=%#x\n", @@ -523,7 +523,7 @@ TsunamiIO::read(MemReqPtr &req, uint8_t *data) return NoFault; } -Fault * +Fault TsunamiIO::write(MemReqPtr &req, const uint8_t *data) { diff --git a/dev/tsunami_io.hh b/dev/tsunami_io.hh index 3b26ebfaa..b024ecd14 100644 --- a/dev/tsunami_io.hh +++ b/dev/tsunami_io.hh @@ -330,7 +330,7 @@ class TsunamiIO : public PioDevice * @param data A pointer to write the read data to. * @return The fault condition of the access. */ - virtual Fault * read(MemReqPtr &req, uint8_t *data); + virtual Fault read(MemReqPtr &req, uint8_t *data); /** * Process a write to one of the devices we emulate. @@ -338,7 +338,7 @@ class TsunamiIO : public PioDevice * @param data The data to write. * @return The fault condition of the access. */ - virtual Fault * write(MemReqPtr &req, const uint8_t *data); + virtual Fault write(MemReqPtr &req, const uint8_t *data); /** * Post an PIC interrupt to the CPU via the CChip diff --git a/dev/tsunami_pchip.cc b/dev/tsunami_pchip.cc index 706daf9dc..46efc3dfe 100644 --- a/dev/tsunami_pchip.cc +++ b/dev/tsunami_pchip.cc @@ -78,7 +78,7 @@ TsunamiPChip::TsunamiPChip(const string &name, Tsunami *t, Addr a, tsunami->pchip = this; } -Fault * +Fault TsunamiPChip::read(MemReqPtr &req, uint8_t *data) { DPRINTF(Tsunami, "read va=%#x size=%d\n", @@ -167,7 +167,7 @@ TsunamiPChip::read(MemReqPtr &req, uint8_t *data) return NoFault; } -Fault * +Fault TsunamiPChip::write(MemReqPtr &req, const uint8_t *data) { DPRINTF(Tsunami, "write - va=%#x size=%d \n", diff --git a/dev/tsunami_pchip.hh b/dev/tsunami_pchip.hh index ff888bea1..c1d95431b 100644 --- a/dev/tsunami_pchip.hh +++ b/dev/tsunami_pchip.hh @@ -99,7 +99,7 @@ class TsunamiPChip : public PioDevice * @param data A pointer to write the read data to. * @return The fault condition of the access. */ - virtual Fault * read(MemReqPtr &req, uint8_t *data); + virtual Fault read(MemReqPtr &req, uint8_t *data); /** * Process a write to the PChip. @@ -107,7 +107,7 @@ class TsunamiPChip : public PioDevice * @param data The data to write. * @return The fault condition of the access. */ - virtual Fault * write(MemReqPtr &req, const uint8_t *data); + virtual Fault write(MemReqPtr &req, const uint8_t *data); /** * Serialize this object to the given output stream. diff --git a/dev/uart.hh b/dev/uart.hh index 96c22025c..145b9ca9e 100644 --- a/dev/uart.hh +++ b/dev/uart.hh @@ -57,8 +57,8 @@ class Uart : public PioDevice Addr a, Addr s, HierParams *hier, Bus *bus, Tick pio_latency, Platform *p); - virtual Fault * read(MemReqPtr &req, uint8_t *data) = 0; - virtual Fault * write(MemReqPtr &req, const uint8_t *data) = 0; + virtual Fault read(MemReqPtr &req, uint8_t *data) = 0; + virtual Fault write(MemReqPtr &req, const uint8_t *data) = 0; /** diff --git a/dev/uart8250.cc b/dev/uart8250.cc index 99355e28a..65bccee86 100644 --- a/dev/uart8250.cc +++ b/dev/uart8250.cc @@ -112,7 +112,7 @@ Uart8250::Uart8250(const string &name, SimConsole *c, MemoryController *mmu, } -Fault * +Fault Uart8250::read(MemReqPtr &req, uint8_t *data) { Addr daddr = req->paddr - (addr & EV5::PAddrImplMask); @@ -188,7 +188,7 @@ Uart8250::read(MemReqPtr &req, uint8_t *data) } -Fault * +Fault Uart8250::write(MemReqPtr &req, const uint8_t *data) { Addr daddr = req->paddr - (addr & EV5::PAddrImplMask); diff --git a/dev/uart8250.hh b/dev/uart8250.hh index a0e2d344a..88abf8e24 100644 --- a/dev/uart8250.hh +++ b/dev/uart8250.hh @@ -82,8 +82,8 @@ class Uart8250 : public Uart Addr a, Addr s, HierParams *hier, Bus *pio_bus, Tick pio_latency, Platform *p); - virtual Fault * read(MemReqPtr &req, uint8_t *data); - virtual Fault * write(MemReqPtr &req, const uint8_t *data); + virtual Fault read(MemReqPtr &req, uint8_t *data); + virtual Fault write(MemReqPtr &req, const uint8_t *data); /** diff --git a/kern/kernel_stats.hh b/kern/kernel_stats.hh index 273a56ec3..02d78e4d9 100644 --- a/kern/kernel_stats.hh +++ b/kern/kernel_stats.hh @@ -41,7 +41,6 @@ class ExecContext; class FnEvent; // What does kernel stats expect is included? class System; -class Fault; namespace Kernel { @@ -177,7 +176,7 @@ class Statistics : public Serializable void ivlb() { _ivlb++; } void ivle() { _ivle++; } void hwrei() { _hwrei++; } - void fault(Fault * fault) + void fault(Fault fault) { if(fault == NoFault) _faults[0]++; else if(fault == MachineCheckFault) _faults[2]++; diff --git a/sim/faults.hh b/sim/faults.hh index d9c742b90..dbec399af 100644 --- a/sim/faults.hh +++ b/sim/faults.hh @@ -29,30 +29,33 @@ #ifndef __FAULTS_HH__ #define __FAULTS_HH__ -class Fault +class FaultBase; +typedef FaultBase * Fault; + +class FaultBase { public: - Fault(char * newName, int newId = 0) : name(newName), id(newId) {;} + FaultBase(char * newName, int newId = 0) : name(newName), id(newId) {;} const char * name; int id; }; -extern class NoFaultType : public Fault +extern class NoFaultType : public FaultBase { public: - NoFaultType(char * newName) : Fault(newName) {;} + NoFaultType(char * newName) : FaultBase(newName) {;} } * const NoFault; -extern class MachineCheckFaultType : public Fault +extern class MachineCheckFaultType : public FaultBase { public: - MachineCheckFaultType(char * newName) : Fault(newName) {;} + MachineCheckFaultType(char * newName) : FaultBase(newName) {;} } * const MachineCheckFault; -extern class AlignmentFaultType : public Fault +extern class AlignmentFaultType : public FaultBase { public: - AlignmentFaultType(char * newName) : Fault(newName) {;} + AlignmentFaultType(char * newName) : FaultBase(newName) {;} } * const AlignmentFault; From a4799a89ded3b2ebddd682dbcb0f8d2dd968b68a Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Tue, 21 Feb 2006 22:02:05 -0500 Subject: [PATCH 081/180] Renaming alpha files and changing some MIPS stuff to be more like Alpha version SConscript: changed the alpha_memory.hh to memory.hh in SConscript arch/isa_parser.py: temporarily comment out o3 model arch/mips/isa/base.isa: arch/mips/isa_traits.cc: arch/mips/isa_traits.hh: Fix Up Base Class to mirror how Alpha generates StaticInsts arch/mips/faults.cc: MIPS fault.cc file arch/mips/faults.hh: MIPS fault.hh file --HG-- rename : arch/alpha/alpha_linux_process.cc => arch/alpha/linux_process.cc rename : arch/alpha/alpha_linux_process.hh => arch/alpha/linux_process.hh rename : arch/alpha/alpha_memory.cc => arch/alpha/memory.cc rename : arch/alpha/alpha_memory.hh => arch/alpha/memory.hh rename : arch/alpha/alpha_tru64_process.cc => arch/alpha/tru64_process.cc rename : arch/alpha/alpha_tru64_process.hh => arch/alpha/tru64_process.hh extra : convert_revision : f92d6e765ca96a8b952aef79ed119fa29464563b --- SConscript | 2 +- ...lpha_linux_process.cc => linux_process.cc} | 0 ...lpha_linux_process.hh => linux_process.hh} | 0 arch/alpha/{alpha_memory.cc => memory.cc} | 0 arch/alpha/{alpha_memory.hh => memory.hh} | 0 ...lpha_tru64_process.cc => tru64_process.cc} | 0 ...lpha_tru64_process.hh => tru64_process.hh} | 0 arch/isa_parser.py | 7 +- arch/mips/faults.cc | 80 +++ arch/mips/faults.hh | 163 +++++ arch/mips/isa/base.isa | 108 +-- arch/mips/isa_traits.cc | 109 ++- arch/mips/isa_traits.hh | 659 +++++++----------- 13 files changed, 648 insertions(+), 480 deletions(-) rename arch/alpha/{alpha_linux_process.cc => linux_process.cc} (100%) rename arch/alpha/{alpha_linux_process.hh => linux_process.hh} (100%) rename arch/alpha/{alpha_memory.cc => memory.cc} (100%) rename arch/alpha/{alpha_memory.hh => memory.hh} (100%) rename arch/alpha/{alpha_tru64_process.cc => tru64_process.cc} (100%) rename arch/alpha/{alpha_tru64_process.hh => tru64_process.hh} (100%) create mode 100644 arch/mips/faults.cc create mode 100644 arch/mips/faults.hh diff --git a/SConscript b/SConscript index b8db3ff71..1939894fb 100644 --- a/SConscript +++ b/SConscript @@ -344,7 +344,7 @@ syscall_emulation_sources = Split(''' targetarch_files = Split(''' alpha_linux_process.hh - alpha_memory.hh + memory.hh alpha_tru64_process.hh aout_machdep.h arguments.hh diff --git a/arch/alpha/alpha_linux_process.cc b/arch/alpha/linux_process.cc similarity index 100% rename from arch/alpha/alpha_linux_process.cc rename to arch/alpha/linux_process.cc diff --git a/arch/alpha/alpha_linux_process.hh b/arch/alpha/linux_process.hh similarity index 100% rename from arch/alpha/alpha_linux_process.hh rename to arch/alpha/linux_process.hh diff --git a/arch/alpha/alpha_memory.cc b/arch/alpha/memory.cc similarity index 100% rename from arch/alpha/alpha_memory.cc rename to arch/alpha/memory.cc diff --git a/arch/alpha/alpha_memory.hh b/arch/alpha/memory.hh similarity index 100% rename from arch/alpha/alpha_memory.hh rename to arch/alpha/memory.hh diff --git a/arch/alpha/alpha_tru64_process.cc b/arch/alpha/tru64_process.cc similarity index 100% rename from arch/alpha/alpha_tru64_process.cc rename to arch/alpha/tru64_process.cc diff --git a/arch/alpha/alpha_tru64_process.hh b/arch/alpha/tru64_process.hh similarity index 100% rename from arch/alpha/alpha_tru64_process.hh rename to arch/alpha/tru64_process.hh diff --git a/arch/isa_parser.py b/arch/isa_parser.py index b92d267c9..7c511a8b3 100755 --- a/arch/isa_parser.py +++ b/arch/isa_parser.py @@ -745,9 +745,10 @@ CpuModel('FastCPU', 'fast_cpu_exec.cc', CpuModel('FullCPU', 'full_cpu_exec.cc', '#include "encumbered/cpu/full/dyn_inst.hh"', { 'CPU_exec_context': 'DynInst' }) -CpuModel('AlphaFullCPU', 'alpha_o3_exec.cc', - '#include "cpu/o3/alpha_dyn_inst.hh"', - { 'CPU_exec_context': 'AlphaDynInst' }) + +#CpuModel('AlphaFullCPU', 'alpha_o3_exec.cc', +# '#include "cpu/o3/alpha_dyn_inst.hh"', +# { 'CPU_exec_context': 'AlphaDynInst' }) # Expand template with CPU-specific references into a dictionary with # an entry for each CPU model name. The entry key is the model name diff --git a/arch/mips/faults.cc b/arch/mips/faults.cc new file mode 100644 index 000000000..e05b3fe59 --- /dev/null +++ b/arch/mips/faults.cc @@ -0,0 +1,80 @@ +/* + * 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/alpha/faults.hh" + +ResetFaultType * const ResetFault = + new ResetFaultType("reset", 1, 0x0001); +ArithmeticFaultType * const ArithmeticFault = + new ArithmeticFaultType("arith", 3, 0x0501); +InterruptFaultType * const InterruptFault = + new InterruptFaultType("interrupt", 4, 0x0101); +NDtbMissFaultType * const NDtbMissFault = + new NDtbMissFaultType("dtb_miss_single", 5, 0x0201); +PDtbMissFaultType * const PDtbMissFault = + new PDtbMissFaultType("dtb_miss_double", 6, 0x0281); +DtbPageFaultType * const DtbPageFault = + new DtbPageFaultType("dfault", 8, 0x0381); +DtbAcvFaultType * const DtbAcvFault = + new DtbAcvFaultType("dfault", 9, 0x0381); +ItbMissFaultType * const ItbMissFault = + new ItbMissFaultType("itbmiss", 10, 0x0181); +ItbPageFaultType * const ItbPageFault = + new ItbPageFaultType("itbmiss", 11, 0x0181); +ItbAcvFaultType * const ItbAcvFault = + new ItbAcvFaultType("iaccvio", 12, 0x0081); +UnimplementedOpcodeFaultType * const UnimplementedOpcodeFault = + new UnimplementedOpcodeFaultType("opdec", 13, 0x0481); +FloatEnableFaultType * const FloatEnableFault = + new FloatEnableFaultType("fen", 14, 0x0581); +PalFaultType * const PalFault = + new PalFaultType("pal", 15, 0x2001); +IntegerOverflowFaultType * const IntegerOverflowFault = + new IntegerOverflowFaultType("intover", 16, 0x0501); + +Fault ** ListOfFaults[] = { + (Fault **)&NoFault, + (Fault **)&ResetFault, + (Fault **)&MachineCheckFault, + (Fault **)&ArithmeticFault, + (Fault **)&InterruptFault, + (Fault **)&NDtbMissFault, + (Fault **)&PDtbMissFault, + (Fault **)&AlignmentFault, + (Fault **)&DtbPageFault, + (Fault **)&DtbAcvFault, + (Fault **)&ItbMissFault, + (Fault **)&ItbPageFault, + (Fault **)&ItbAcvFault, + (Fault **)&UnimplementedOpcodeFault, + (Fault **)&FloatEnableFault, + (Fault **)&PalFault, + (Fault **)&IntegerOverflowFault, + }; + +int NumFaults = sizeof(ListOfFaults) / sizeof(Fault **); diff --git a/arch/mips/faults.hh b/arch/mips/faults.hh new file mode 100644 index 000000000..4e1cb5ed6 --- /dev/null +++ b/arch/mips/faults.hh @@ -0,0 +1,163 @@ +/* + * 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 __ALPHA_FAULTS_HH__ +#define __ALPHA_FAULTS_HH__ + +#include "sim/faults.hh" +#include "arch/isa_traits.hh" //For the Addr type + +class Garbage; +class Fault; + +class AlphaFault : public Fault +{ + public: + AlphaFault(char * newName, int newId, Addr newVect) + : Fault(newName, newId), vect(newVect) + {;} + + Addr vect; +}; + +extern class ResetFaultType : public AlphaFault +{ + public: + ResetFaultType(char * newName, int newId, Addr newVect) + : AlphaFault(newName, newId, newVect) + {;} +} * const ResetFault; + +extern class ArithmeticFaultType : public AlphaFault +{ + public: + ArithmeticFaultType(char * newName, int newId, Addr newVect) + : AlphaFault(newName, newId, newVect) + {;} +} * const ArithmeticFault; + +extern class InterruptFaultType : public AlphaFault +{ + public: + InterruptFaultType(char * newName, int newId, Addr newVect) + : AlphaFault(newName, newId, newVect) + {;} +} * const InterruptFault; + +extern class NDtbMissFaultType : public AlphaFault +{ + public: + NDtbMissFaultType(char * newName, int newId, Addr newVect) + : AlphaFault(newName, newId, newVect) + {;} +} * const NDtbMissFault; + +extern class PDtbMissFaultType : public AlphaFault +{ + public: + PDtbMissFaultType(char * newName, int newId, Addr newVect) + : AlphaFault(newName, newId, newVect) + {;} +} * const PDtbMissFault; + +extern class DtbPageFaultType : public AlphaFault +{ + public: + DtbPageFaultType(char * newName, int newId, Addr newVect) + : AlphaFault(newName, newId, newVect) + {;} +} * const DtbPageFault; + +extern class DtbAcvFaultType : public AlphaFault +{ + public: + DtbAcvFaultType(char * newName, int newId, Addr newVect) + : AlphaFault(newName, newId, newVect) + {;} +} * const DtbAcvFault; + +extern class ItbMissFaultType : public AlphaFault +{ + public: + ItbMissFaultType(char * newName, int newId, Addr newVect) + : AlphaFault(newName, newId, newVect) + {;} +} * const ItbMissFault; + +extern class ItbPageFaultType : public AlphaFault +{ + public: + ItbPageFaultType(char * newName, int newId, Addr newVect) + : AlphaFault(newName, newId, newVect) + {;} +} * const ItbPageFault; + +extern class ItbAcvFaultType : public AlphaFault +{ + public: + ItbAcvFaultType(char * newName, int newId, Addr newVect) + : AlphaFault(newName, newId, newVect) + {;} +} * const ItbAcvFault; + +extern class UnimplementedOpcodeFaultType : public AlphaFault +{ + public: + UnimplementedOpcodeFaultType(char * newName, int newId, Addr newVect) + : AlphaFault(newName, newId, newVect) + {;} +} * const UnimplementedOpcodeFault; + +extern class FloatEnableFaultType : public AlphaFault +{ + public: + FloatEnableFaultType(char * newName, int newId, Addr newVect) + : AlphaFault(newName, newId, newVect) + {;} +} * const FloatEnableFault; + +extern class PalFaultType : public AlphaFault +{ + public: + PalFaultType(char * newName, int newId, Addr newVect) + : AlphaFault(newName, newId, newVect) + {;} +} * const PalFault; + +extern class IntegerOverflowFaultType : public AlphaFault +{ + public: + IntegerOverflowFaultType(char * newName, int newId, Addr newVect) + : AlphaFault(newName, newId, newVect) + {;} +} * const IntegerOverflowFault; + +extern Fault ** ListOfFaults[]; +extern int NumFaults; + +#endif // __FAULTS_HH__ diff --git a/arch/mips/isa/base.isa b/arch/mips/isa/base.isa index 846d161b9..49de59e55 100644 --- a/arch/mips/isa/base.isa +++ b/arch/mips/isa/base.isa @@ -7,57 +7,81 @@ //Outputs to decoder.hh output header {{ - /** - * Base class for all MIPS static instructions. - */ - class MipsStaticInst : public StaticInst - { - protected: + /** + * Base class for all MIPS static instructions. + */ + class MipsStaticInst : public StaticInst + { + protected: - // Constructor. - MipsStaticInst(const char *mnem, MachInst _machInst, OpClass __opClass) - : StaticInst(mnem, _machInst, __opClass) - { - } - - std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; + /// Make MipsISA register dependence tags directly visible in + /// this class and derived classes. Maybe these should really + /// live here and not in the MipsISA namespace. + enum DependenceTags { + FP_Base_DepTag = MipsISA::FP_Base_DepTag, + Fpcr_DepTag = MipsISA::Fpcr_DepTag, + Uniq_DepTag = MipsISA::Uniq_DepTag, + IPR_Base_DepTag = MipsISA::IPR_Base_DepTag }; + // Constructor + MipsStaticInst(const char *mnem, MachInst _machInst, OpClass __opClass) + : StaticInst(mnem, _machInst, __opClass) + { + } + + /// Print a register name for disassembly given the unique + /// dependence tag number (FP or int). + void printReg(std::ostream &os, int reg) const; + + std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; + }; + }}; //Ouputs to decoder.cc output decoder {{ - std::string MipsStaticInst::generateDisassembly(Addr pc, const SymbolTable *symtab) const - { - std::stringstream ss; - - ccprintf(ss, "%-10s ", mnemonic); - - // just print the first two source regs... if there's - // a third one, it's a read-modify-write dest (Rc), - // e.g. for CMOVxx - if(_numSrcRegs > 0) - { - printReg(ss, _srcRegIdx[0]); - } - if(_numSrcRegs > 1) - { - ss << ","; - printReg(ss, _srcRegIdx[1]); - } - - // just print the first dest... if there's a second one, - // it's generally implicit - if(_numDestRegs > 0) - { - if(_numSrcRegs > 0) - ss << ","; - printReg(ss, _destRegIdx[0]); - } - - return ss.str(); + void MipsStaticInst::printReg(std::ostream &os, int reg) const + { + if (reg < FP_Base_DepTag) { + ccprintf(os, "r%d", reg); } + else { + ccprintf(os, "f%d", reg - FP_Base_DepTag); + } + } + + std::string MipsStaticInst::generateDisassembly(Addr pc, const SymbolTable *symtab) const + { + std::stringstream ss; + + ccprintf(ss, "%-10s ", mnemonic); + + // just print the first two source regs... if there's + // a third one, it's a read-modify-write dest (Rc), + // e.g. for CMOVxx + if(_numSrcRegs > 0) + { + printReg(ss, _srcRegIdx[0]); + } + if(_numSrcRegs > 1) + { + ss << ","; + printReg(ss, _srcRegIdx[1]); + } + + // just print the first dest... if there's a second one, + // it's generally implicit + if(_numDestRegs > 0) + { + if(_numSrcRegs > 0) + ss << ","; + printReg(ss, _destRegIdx[0]); + } + + return ss.str(); + } }}; diff --git a/arch/mips/isa_traits.cc b/arch/mips/isa_traits.cc index 90a85feb6..02a857af7 100644 --- a/arch/mips/isa_traits.cc +++ b/arch/mips/isa_traits.cc @@ -27,32 +27,121 @@ */ #include "arch/mips/isa_traits.hh" +#include "config/full_system.hh" #include "cpu/static_inst.hh" #include "sim/serialize.hh" -// Alpha UNOP (ldq_u r31,0(r0)) -// @todo: fix to MIPS specific +using namespace MipsISA; + +const Addr MipsISA::PageShift = 13; +const Addr MipsISA::PageBytes = ULL(1) << PageShift; +const Addr MipsISA::PageMask = ~(PageBytes - 1); +const Addr MipsISA::PageOffset = PageBytes - 1; + +#if FULL_SYSTEM + +//////////////////////////////////////////////////////////////////////// +// +// Translation stuff +// + +const Addr MipsISA::PteShift = 3; +const Addr MipsISA::NPtePageShift = PageShift - PteShift; +const Addr MipsISA::NPtePage = ULL(1) << NPtePageShift; +const Addr MipsISA::PteMask = NPtePage - 1; + +// User Virtual +const Addr MipsISA::USegBase = ULL(0x0); +const Addr MipsISA::USegEnd = ULL(0x000003ffffffffff); + +// Kernel Direct Mapped +const Addr MipsISA::K0SegBase = ULL(0xfffffc0000000000); +const Addr MipsISA::K0SegEnd = ULL(0xfffffdffffffffff); + +// Kernel Virtual +const Addr MipsISA::K1SegBase = ULL(0xfffffe0000000000); +const Addr MipsISA::K1SegEnd = ULL(0xffffffffffffffff); + +#endif + +// Mips UNOP (ldq_u r31,0(r0)) const MachInst MipsISA::NoopMachInst = 0x2ffe0000; +static inline Addr +TruncPage(Addr addr) +{ return addr & ~(MipsISA::PageBytes - 1); } + +static inline Addr +RoundPage(Addr addr) +{ return (addr + MipsISA::PageBytes - 1) & ~(MipsISA::PageBytes - 1); } void -MipsISA::RegFile::serialize(std::ostream &os) +RegFile::serialize(std::ostream &os) { - intRegFile.serialize(os); - floatRegFile.serialize(os); - miscRegs.serialize(os); + SERIALIZE_ARRAY(intRegFile, NumIntRegs); + SERIALIZE_ARRAY(floatRegFile.q, NumFloatRegs); + SERIALIZE_SCALAR(miscRegs.fpcr); + SERIALIZE_SCALAR(miscRegs.uniq); + SERIALIZE_SCALAR(miscRegs.lock_flag); + SERIALIZE_SCALAR(miscRegs.lock_addr); SERIALIZE_SCALAR(pc); SERIALIZE_SCALAR(npc); +#if FULL_SYSTEM + SERIALIZE_ARRAY(palregs, NumIntRegs); + SERIALIZE_ARRAY(ipr, NumInternalProcRegs); + SERIALIZE_SCALAR(intrflag); + SERIALIZE_SCALAR(pal_shadow); +#endif } void -MipsISA::RegFile::unserialize(Checkpoint *cp, const std::string §ion) +RegFile::unserialize(Checkpoint *cp, const std::string §ion) { - intRegFile.unserialize(cp, section); - floatRegFile.unserialize(cp, section); - miscRegs.unserialize(cp, section); + UNSERIALIZE_ARRAY(intRegFile, NumIntRegs); + UNSERIALIZE_ARRAY(floatRegFile.q, NumFloatRegs); + UNSERIALIZE_SCALAR(miscRegs.fpcr); + UNSERIALIZE_SCALAR(miscRegs.uniq); + UNSERIALIZE_SCALAR(miscRegs.lock_flag); + UNSERIALIZE_SCALAR(miscRegs.lock_addr); UNSERIALIZE_SCALAR(pc); UNSERIALIZE_SCALAR(npc); +#if FULL_SYSTEM + UNSERIALIZE_ARRAY(palregs, NumIntRegs); + UNSERIALIZE_ARRAY(ipr, NumInternalProcRegs); + UNSERIALIZE_SCALAR(intrflag); + UNSERIALIZE_SCALAR(pal_shadow); +#endif +} + + +#if FULL_SYSTEM +void +PTE::serialize(std::ostream &os) +{ + SERIALIZE_SCALAR(tag); + SERIALIZE_SCALAR(ppn); + SERIALIZE_SCALAR(xre); + SERIALIZE_SCALAR(xwe); + SERIALIZE_SCALAR(asn); + SERIALIZE_SCALAR(asma); + SERIALIZE_SCALAR(fonr); + SERIALIZE_SCALAR(fonw); + SERIALIZE_SCALAR(valid); +} + + +void +PTE::unserialize(Checkpoint *cp, const std::string §ion) +{ + UNSERIALIZE_SCALAR(tag); + UNSERIALIZE_SCALAR(ppn); + UNSERIALIZE_SCALAR(xre); + UNSERIALIZE_SCALAR(xwe); + UNSERIALIZE_SCALAR(asn); + UNSERIALIZE_SCALAR(asma); + UNSERIALIZE_SCALAR(fonr); + UNSERIALIZE_SCALAR(fonw); + UNSERIALIZE_SCALAR(valid); } #endif //FULL_SYSTEM diff --git a/arch/mips/isa_traits.hh b/arch/mips/isa_traits.hh index 603af60e2..c636cd241 100644 --- a/arch/mips/isa_traits.hh +++ b/arch/mips/isa_traits.hh @@ -29,13 +29,14 @@ #ifndef __ARCH_MIPS_ISA_TRAITS_HH__ #define __ARCH_MIPS_ISA_TRAITS_HH__ -//This makes sure the big endian versions of certain functions are used. namespace LittleEndianGuest {} -using namespace LittleEndianGuest +using namespace LittleEndianGuest; -#include "arch/mips/faults.hh" +//#include "arch/mips/faults.hh" #include "base/misc.hh" +#include "config/full_system.hh" #include "sim/host.hh" +#include "sim/faults.hh" class FastCPU; class FullCPU; @@ -43,453 +44,260 @@ class Checkpoint; #define TARGET_MIPS -template class StaticInst; -template class StaticInstPtr; +class StaticInst; +class StaticInstPtr; -//namespace MIPS34K -//{ -// int DTB_ASN_ASN(uint64_t reg); -// int ITB_ASN_ASN(uint64_t reg); -//} +namespace MIPS34K { +int DTB_ASN_ASN(uint64_t reg); +int ITB_ASN_ASN(uint64_t reg); +} -class MipsISA +namespace MipsISA { - public: - typedef uint32_t MachInst; - typedef uint64_t Addr; - typedef uint8_t RegIndex; + typedef uint32_t MachInst; +// typedef uint64_t Addr; + typedef uint8_t RegIndex; - enum - { - MemoryEnd = 0xffffffffffffffffULL, + enum { + MemoryEnd = 0xffffffffffffffffULL, - NumFloatRegs = 32, - NumMiscRegs = 32, + NumIntRegs = 32, + NumFloatRegs = 32, + NumMiscRegs = 32, - MaxRegsOfAnyType = 32, - // Static instruction parameters - MaxInstSrcRegs = 3, - MaxInstDestRegs = 2, + MaxRegsOfAnyType = 32, + // Static instruction parameters + MaxInstSrcRegs = 3, + MaxInstDestRegs = 2, - // Maximum trap level - MaxTL = 4 + // semantically meaningful register indices + ZeroReg = 31, // architecturally meaningful + // the rest of these depend on the ABI + StackPointerReg = 30, + GlobalPointerReg = 29, + ProcedureValueReg = 27, + ReturnAddressReg = 26, + ReturnValueReg = 0, + FramePointerReg = 15, + ArgumentReg0 = 16, + ArgumentReg1 = 17, + ArgumentReg2 = 18, + ArgumentReg3 = 19, + ArgumentReg4 = 20, + ArgumentReg5 = 21, - // semantically meaningful register indices - ZeroReg = 0, // architecturally meaningful - // the rest of these depend on the ABI - } - typedef uint64_t IntReg; + LogVMPageSize = 13, // 8K bytes + VMPageSize = (1 << LogVMPageSize), - class IntRegFile - { - private: - //For right now, let's pretend the register file is static - IntReg regs[32]; - public: - IntReg & operator [] (RegIndex index) - { - //Don't allow indexes outside of the 32 registers - index &= 0x1F - return regs[index]; - } - }; + BranchPredAddrShiftAmt = 2, // instructions are 4-byte aligned - void inline serialize(std::ostream & os) - { - SERIALIZE_ARRAY(regs, 32); - } + WordBytes = 4, + HalfwordBytes = 2, + ByteBytes = 1, + DepNA = 0, + }; - void inline unserialize(Checkpoint &*cp, const std::string §ion) - { - UNSERIALIZE_ARRAY(regs, 32); - } + // These enumerate all the registers for dependence tracking. + enum DependenceTags { + // 0..31 are the integer regs 0..31 + // 32..63 are the FP regs 0..31, i.e. use (reg + FP_Base_DepTag) + FP_Base_DepTag = 32, + Ctrl_Base_DepTag = 64, + Fpcr_DepTag = 64, // floating point control register + Uniq_DepTag = 65, + IPR_Base_DepTag = 66 + }; - class FloatRegFile - { - private: - //By using the largest data type, we ensure everything - //is aligned correctly in memory - union - { - double double rawRegs[16]; - uint64_t regDump[32]; - }; - class QuadRegs - { - private: - FloatRegFile * parent; - public: - QuadRegs(FloatRegFile * p) : parent(p) {;} - double double & operator [] (RegIndex index) - { - //Quad floats are index by the single - //precision register the start on, - //and only 16 should be accessed - index = (index >> 2) & 0xF; - return parent->rawRegs[index]; - } - }; - class DoubleRegs - { - private: - FloatRegFile * parent; - public: - DoubleRegs(FloatRegFile * p) : parent(p) {;} - double & operator [] (RegIndex index) - { - //Double floats are index by the single - //precision register the start on, - //and only 32 should be accessed - index = (index >> 1) & 0x1F - return ((double [])parent->rawRegs)[index]; - } - } - class SingleRegs - { - private: - FloatRegFile * parent; - public: - SingleRegs(FloatRegFile * p) : parent(p) {;} - double & operator [] (RegFile index) - { - //Only 32 single floats should be accessed - index &= 0x1F - return ((float [])parent->rawRegs)[index]; - } - } - public: - void inline serialize(std::ostream & os) - { - SERIALIZE_ARRAY(regDump, 32); - } + typedef uint64_t IntReg; + typedef IntReg IntRegFile[NumIntRegs]; - void inline unserialize(Checkpoint &* cp, std::string & section) - { - UNSERIALIZE_ARRAY(regDump, 32); - } + // floating point register file entry type + typedef union { + uint64_t q; + double d; + } FloatReg; - QuadRegs quadRegs; - DoubleRegs doubleRegs; - SingleRegs singleRegs; - FloatRegFile() : quadRegs(this), doubleRegs(this), singleRegs(this) - {;} - }; + typedef union { + uint64_t q[NumFloatRegs]; // integer qword view + double d[NumFloatRegs]; // double-precision floating point view + } FloatRegFile; - // control register file contents - typedef uint64_t MiscReg; - // The control registers, broken out into fields - class MiscRegFile - { - public: - union - { - uint16_t pstate; // Process State Register - struct - { - uint16_t ag:1; // Alternate Globals - uint16_t ie:1; // Interrupt enable - uint16_t priv:1; // Privelege mode - uint16_t am:1; // Address mask - uint16_t pef:1; // PSTATE enable floating-point - uint16_t red:1; // RED (reset, error, debug) state - uint16_t mm:2; // Memory Model - uint16_t tle:1; // Trap little-endian - uint16_t cle:1; // Current little-endian - } pstateFields; - } - uint64_t tba; // Trap Base Address - union - { - uint64_t y; // Y (used in obsolete multiplication) - struct - { - uint64_t value:32; // The actual value stored in y - const uint64_t :32; // reserved bits - } yFields; - } - uint8_t pil; // Process Interrupt Register - uint8_t cwp; // Current Window Pointer - uint16_t tt[MaxTL]; // Trap Type (Type of trap which occured on the previous level) - union - { - uint8_t ccr; // Condition Code Register - struct - { - union - { - uint8_t icc:4; // 32-bit condition codes - struct - { - uint8_t c:1; // Carry - uint8_t v:1; // Overflow - uint8_t z:1; // Zero - uint8_t n:1; // Negative - } iccFields:4; - } :4; - union - { - uint8_t xcc:4; // 64-bit condition codes - struct - { - uint8_t c:1; // Carry - uint8_t v:1; // Overflow - uint8_t z:1; // Zero - uint8_t n:1; // Negative - } xccFields:4; - } :4; - } ccrFields; - } - uint8_t asi; // Address Space Identifier - uint8_t tl; // Trap Level - uint64_t tpc[MaxTL]; // Trap Program Counter (value from previous trap level) - uint64_t tnpc[MaxTL]; // Trap Next Program Counter (value from previous trap level) - union - { - uint64_t tstate[MaxTL]; // Trap State - struct - { - //Values are from previous trap level - uint64_t cwp:5; // Current Window Pointer - const uint64_t :2; // Reserved bits - uint64_t pstate:10; // Process State - const uint64_t :6; // Reserved bits - uint64_t asi:8; // Address Space Identifier - uint64_t ccr:8; // Condition Code Register - } tstateFields[MaxTL]; - } - union - { - uint64_t tick; // Hardware clock-tick counter - struct - { - uint64_t counter:63; // Clock-tick count - uint64_t npt:1; // Non-priveleged trap - } tickFields; - } - uint8_t cansave; // Savable windows - uint8_t canrestore; // Restorable windows - uint8_t otherwin; // Other windows - uint8_t cleanwin; // Clean windows - union - { - uint8_t wstate; // Window State - struct - { - uint8_t normal:3; // Bits TT<4:2> are set to on a normal - // register window trap - uint8_t other:3; // Bits TT<4:2> are set to on an "otherwin" - // register window trap - } wstateFields; - } - union - { - uint64_t ver; // Version - struct - { - uint64_t maxwin:5; // Max CWP value - const uint64_t :2; // Reserved bits - uint64_t maxtl:8; // Maximum trap level - const uint64_t :8; // Reserved bits - uint64_t mask:8; // Processor mask set revision number - uint64_t impl:16; // Implementation identification number - uint64_t manuf:16; // Manufacturer code - } verFields; - } - union - { - uint64_t fsr; // Floating-Point State Register - struct - { - union - { - uint64_t cexc:5; // Current excpetion - struct - { - uint64_t nxc:1; // Inexact - uint64_t dzc:1; // Divide by zero - uint64_t ufc:1; // Underflow - uint64_t ofc:1; // Overflow - uint64_t nvc:1; // Invalid operand - } cexecFields:5; - } :5; - union - { - uint64_t aexc:5; // Accrued exception - struct - { - uint64_t nxc:1; // Inexact - uint64_t dzc:1; // Divide by zero - uint64_t ufc:1; // Underflow - uint64_t ofc:1; // Overflow - uint64_t nvc:1; // Invalid operand - } aexecFields:5; - } :5; - uint64_t fcc0:2; // Floating-Point condtion codes - const uint64_t :1; // Reserved bits - uint64_t qne:1; // Deferred trap queue not empty - // with no queue, it should read 0 - uint64_t ftt:3; // Floating-Point trap type - uint64_t ver:3; // Version (of the FPU) - const uint64_t :2; // Reserved bits - uint64_t ns:1; // Nonstandard floating point - union - { - uint64_t tem:5; // Trap Enable Mask - struct - { - uint64_t nxm:1; // Inexact - uint64_t dzm:1; // Divide by zero - uint64_t ufm:1; // Underflow - uint64_t ofm:1; // Overflow - uint64_t nvm:1; // Invalid operand - } temFields:5; - } :5; - const uint64_t :2; // Reserved bits - uint64_t rd:2; // Rounding direction - uint64_t fcc1:2; // Floating-Point condition codes - uint64_t fcc2:2; // Floating-Point condition codes - uint64_t fcc3:2; // Floating-Point condition codes - const uint64_t :26; // Reserved bits - } fsrFields; - } - union - { - uint8_t fprs; // Floating-Point Register State - struct - { - dl:1; // Dirty lower - du:1; // Dirty upper - fef:1; // FPRS enable floating-Point - } fprsFields; - }; + // control register file contents + typedef uint64_t MiscReg; + typedef struct { + uint64_t fpcr; // floating point condition codes + uint64_t uniq; // process-unique register + bool lock_flag; // lock flag for LL/SC + Addr lock_addr; // lock address for LL/SC + } MiscRegFile; - void serialize(std::ostream & os) - { - SERIALIZE_SCALAR(pstate); - SERIAlIZE_SCALAR(tba); - SERIALIZE_SCALAR(y); - SERIALIZE_SCALAR(pil); - SERIALIZE_SCALAR(cwp); - SERIALIZE_ARRAY(tt, MaxTL); - SERIALIZE_SCALAR(ccr); - SERIALIZE_SCALAR(asi); - SERIALIZE_SCALAR(tl); - SERIALIZE_SCALAR(tpc); - SERIALIZE_SCALAR(tnpc); - SERIALIZE_ARRAY(tstate, MaxTL); - SERIALIZE_SCALAR(tick); - SERIALIZE_SCALAR(cansave); - SERIALIZE_SCALAR(canrestore); - SERIALIZE_SCALAR(otherwin); - SERIALIZE_SCALAR(cleanwin); - SERIALIZE_SCALAR(wstate); - SERIALIZE_SCALAR(ver); - SERIALIZE_SCALAR(fsr); - SERIALIZE_SCALAR(fprs); - } +extern const Addr PageShift; +extern const Addr PageBytes; +extern const Addr PageMask; +extern const Addr PageOffset; - void unserialize(Checkpoint &* cp, std::string & section) - { - UNSERIALIZE_SCALAR(pstate); - UNSERIAlIZE_SCALAR(tba); - UNSERIALIZE_SCALAR(y); - UNSERIALIZE_SCALAR(pil); - UNSERIALIZE_SCALAR(cwp); - UNSERIALIZE_ARRAY(tt, MaxTL); - UNSERIALIZE_SCALAR(ccr); - UNSERIALIZE_SCALAR(asi); - UNSERIALIZE_SCALAR(tl); - UNSERIALIZE_SCALAR(tpc); - UNSERIALIZE_SCALAR(tnpc); - UNSERIALIZE_ARRAY(tstate, MaxTL); - UNSERIALIZE_SCALAR(tick); - UNSERIALIZE_SCALAR(cansave); - UNSERIALIZE_SCALAR(canrestore); - UNSERIALIZE_SCALAR(otherwin); - UNSERIALIZE_SCALAR(cleanwin); - UNSERIALIZE_SCALAR(wstate); - UNSERIALIZE_SCALAR(ver); - UNSERIALIZE_SCALAR(fsr); - UNSERIALIZE_SCALAR(fprs); - } - }; +#if FULL_SYSTEM - typedef union - { - IntReg intreg; - FloatReg fpreg; - MiscReg ctrlreg; - } AnyReg; + typedef uint64_t InternalProcReg; - struct RegFile - { - IntRegFile intRegFile; // (signed) integer register file - FloatRegFile floatRegFile; // floating point register file - MiscRegFile miscRegFile; // control register file +#include "arch/mips/isa_fullsys_traits.hh" - Addr pc; // Program Counter - Addr npc; // Next Program Counter - Addr nnpc; // Next next program Counter +#else + enum { + NumInternalProcRegs = 0 + }; +#endif + + enum { + TotalNumRegs = + NumIntRegs + NumFloatRegs + NumMiscRegs + NumInternalProcRegs + }; + + enum { + TotalDataRegs = NumIntRegs + NumFloatRegs + }; + + typedef union { + IntReg intreg; + FloatReg fpreg; + MiscReg ctrlreg; + } AnyReg; + + struct RegFile { + IntRegFile intRegFile; // (signed) integer register file + FloatRegFile floatRegFile; // floating point register file + MiscRegFile miscRegs; // control register file + Addr pc; // program counter + Addr npc; // next-cycle program counter +#if FULL_SYSTEM + IntReg palregs[NumIntRegs]; // PAL shadow registers + InternalProcReg ipr[NumInternalProcRegs]; // internal processor regs + int intrflag; // interrupt flag + bool pal_shadow; // using pal_shadow registers + inline int instAsid() { return EV5::ITB_ASN_ASN(ipr[IPR_ITB_ASN]); } + inline int dataAsid() { return EV5::DTB_ASN_ASN(ipr[IPR_DTB_ASN]); } +#endif // FULL_SYSTEM + + void serialize(std::ostream &os); + void unserialize(Checkpoint *cp, const std::string §ion); + }; + + StaticInstPtr decodeInst(MachInst); + + // return a no-op instruction... used for instruction fetch faults + extern const MachInst NoopMachInst; + + enum annotes { + ANNOTE_NONE = 0, + // An impossible number for instruction annotations + ITOUCH_ANNOTE = 0xffffffff, + }; + + static inline bool isCallerSaveIntegerRegister(unsigned int reg) { + panic("register classification not implemented"); + return (reg >= 1 && reg <= 8 || reg >= 22 && reg <= 25 || reg == 27); + } + + static inline bool isCalleeSaveIntegerRegister(unsigned int reg) { + panic("register classification not implemented"); + return (reg >= 9 && reg <= 15); + } + + static inline bool isCallerSaveFloatRegister(unsigned int reg) { + panic("register classification not implemented"); + return false; + } + + static inline bool isCalleeSaveFloatRegister(unsigned int reg) { + panic("register classification not implemented"); + return false; + } + + static inline Addr alignAddress(const Addr &addr, + unsigned int nbytes) { + return (addr & ~(nbytes - 1)); + } + + // Instruction address compression hooks + static inline Addr realPCToFetchPC(const Addr &addr) { + return addr; + } + + static inline Addr fetchPCToRealPC(const Addr &addr) { + return addr; + } + + // the size of "fetched" instructions (not necessarily the size + // of real instructions for PISA) + static inline size_t fetchInstSize() { + return sizeof(MachInst); + } + + static inline MachInst makeRegisterCopy(int dest, int src) { + panic("makeRegisterCopy not implemented"); + return 0; + } + + // Machine operations + + void saveMachineReg(AnyReg &savereg, const RegFile ®_file, + int regnum); + + void restoreMachineReg(RegFile ®s, const AnyReg ®, + int regnum); + +#if 0 + static void serializeSpecialRegs(const Serializable::Proxy &proxy, + const RegFile ®s); + + static void unserializeSpecialRegs(const IniFile *db, + const std::string &category, + ConfigNode *node, + RegFile ®s); +#endif + + /** + * Function to insure ISA semantics about 0 registers. + * @param xc The execution context. + */ + template + void zeroRegisters(XC *xc); - void serialize(std::ostream &os); - void unserialize(Checkpoint *cp, const std::string §ion); - }; +//typedef MipsISA TheISA; - static StaticInstPtr decodeInst(MachInst); +//typedef TheISA::MachInst MachInst; +//typedef TheISA::Addr Addr; +//typedef TheISA::RegIndex RegIndex; +//typedef TheISA::IntReg IntReg; +//typedef TheISA::IntRegFile IntRegFile; +//typedef TheISA::FloatReg FloatReg; +//typedef TheISA::FloatRegFile FloatRegFile; +//typedef TheISA::MiscReg MiscReg; +//typedef TheISA::MiscRegFile MiscRegFile; +//typedef TheISA::AnyReg AnyReg; +//typedef TheISA::RegFile RegFile; - // return a no-op instruction... used for instruction fetch faults - static const MachInst NoopMachInst; - - // Instruction address compression hooks - static inline Addr realPCToFetchPC(const Addr &addr) - { - return addr; - } - - static inline Addr fetchPCToRealPC(const Addr &addr) - { - return addr; - } - - // the size of "fetched" instructions (not necessarily the size - // of real instructions for PISA) - static inline size_t fetchInstSize() - { - return sizeof(MachInst); - } - - /** - * Function to insure ISA semantics about 0 registers. - * @param xc The execution context. - */ - template - static void zeroRegisters(XC *xc); +//const int NumIntRegs = TheISA::NumIntRegs; +//const int NumFloatRegs = TheISA::NumFloatRegs; +//const int NumMiscRegs = TheISA::NumMiscRegs; +//const int TotalNumRegs = TheISA::TotalNumRegs; +//const int VMPageSize = TheISA::VMPageSize; +//const int LogVMPageSize = TheISA::LogVMPageSize; +//const int ZeroReg = TheISA::ZeroReg; +//const int StackPointerReg = TheISA::StackPointerReg; +//const int GlobalPointerReg = TheISA::GlobalPointerReg; +//const int ReturnAddressReg = TheISA::ReturnAddressReg; +//const int ReturnValueReg = TheISA::ReturnValueReg; +//const int ArgumentReg0 = TheISA::ArgumentReg0; +//const int ArgumentReg1 = TheISA::ArgumentReg1; +//const int ArgumentReg2 = TheISA::ArgumentReg2; +//const int BranchPredAddrShiftAmt = TheISA::BranchPredAddrShiftAmt; +const Addr MaxAddr = (Addr)-1; }; - -typedef MIPSISA TheISA; - -typedef TheISA::MachInst MachInst; -typedef TheISA::Addr Addr; -typedef TheISA::RegIndex RegIndex; -typedef TheISA::IntReg IntReg; -typedef TheISA::IntRegFile IntRegFile; -typedef TheISA::FloatReg FloatReg; -typedef TheISA::FloatRegFile FloatRegFile; -typedef TheISA::MiscReg MiscReg; -typedef TheISA::MiscRegFile MiscRegFile; -typedef TheISA::AnyReg AnyReg; -typedef TheISA::RegFile RegFile; - -const int VMPageSize = TheISA::VMPageSize; -const int LogVMPageSize = TheISA::LogVMPageSize; -const int ZeroReg = TheISA::ZeroReg; -const int BranchPredAddrShiftAmt = TheISA::BranchPredAddrShiftAmt; -const int MaxAddr = (Addr)-1; - -#ifndef FULL_SYSTEM +#if !FULL_SYSTEM class SyscallReturn { public: template @@ -526,7 +334,10 @@ class SyscallReturn { #endif -#ifdef FULL_SYSTEM +#if FULL_SYSTEM +//typedef TheISA::InternalProcReg InternalProcReg; +//const int NumInternalProcRegs = TheISA::NumInternalProcRegs; +//const int NumInterruptLevels = TheISA::NumInterruptLevels; #include "arch/mips/mips34k.hh" #endif From 54b47bc5ae7993558412de6c458727171b630594 Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Wed, 22 Feb 2006 03:33:35 -0500 Subject: [PATCH 082/180] MIPS Compiles scons/MIPS_SE/arch/mips/decoder.do!!!!!! arch/mips/faults.hh: remove nonsense arch/mips/isa/base.isa: define R31 arch/mips/isa/bitfields.isa: forgotten bitfields arch/mips/isa/decoder.isa: INT64 -> int64_t arch/mips/isa/formats.isa: fix comments arch/mips/isa/formats/branch.isa: Branch -> BranchLikely RB -> RT arch/mips/isa/formats/fp.isa: Make FP ops generates arch/mips/isa/formats/mem.isa: RA,RB -> RS,RT arch/mips/isa/formats/noop.isa: Rc -> Rd arch/mips/isa/formats/util.isa: forgot brace and semicolon arch/mips/isa/includes.isa: remove unnecessary files arch/mips/isa_traits.hh: spacing cpu/static_inst.hh: add cond_delay_slot flag --HG-- extra : convert_revision : 3bc7353b437f9a764e85cc462bed86c9d654eb37 --- arch/mips/faults.hh | 3 -- arch/mips/isa/base.isa | 2 + arch/mips/isa/bitfields.isa | 10 ++++- arch/mips/isa/decoder.isa | 43 ++++++++++++---------- arch/mips/isa/formats.isa | 3 +- arch/mips/isa/formats/branch.isa | 4 +- arch/mips/isa/formats/fp.isa | 63 ++++++-------------------------- arch/mips/isa/formats/mem.isa | 2 +- arch/mips/isa/formats/noop.isa | 6 +-- arch/mips/isa/formats/util.isa | 2 +- arch/mips/isa/includes.isa | 1 - arch/mips/isa_traits.hh | 2 +- cpu/static_inst.hh | 2 + 13 files changed, 57 insertions(+), 86 deletions(-) diff --git a/arch/mips/faults.hh b/arch/mips/faults.hh index 4e1cb5ed6..60c9e735c 100644 --- a/arch/mips/faults.hh +++ b/arch/mips/faults.hh @@ -32,9 +32,6 @@ #include "sim/faults.hh" #include "arch/isa_traits.hh" //For the Addr type -class Garbage; -class Fault; - class AlphaFault : public Fault { public: diff --git a/arch/mips/isa/base.isa b/arch/mips/isa/base.isa index 49de59e55..7600632d3 100644 --- a/arch/mips/isa/base.isa +++ b/arch/mips/isa/base.isa @@ -7,6 +7,8 @@ //Outputs to decoder.hh output header {{ +#define R31 31 + /** * Base class for all MIPS static instructions. */ diff --git a/arch/mips/isa/bitfields.isa b/arch/mips/isa/bitfields.isa index 532b3793a..3a01b64ee 100644 --- a/arch/mips/isa/bitfields.isa +++ b/arch/mips/isa/bitfields.isa @@ -5,9 +5,15 @@ // Bitfield definitions. // +def bitfield OPCODE <31:26>; def bitfield OPCODE_HI <31:29>; def bitfield OPCODE_LO <28:26>; +def bitfield REGIMM <20:16>; +def bitfield REGIMM_HI <20:19>; +def bitfield REGIMM_LO <18:16>; + +def bitfield FUNCTION < 5: 0>; def bitfield FUNCTION_HI < 5: 3>; def bitfield FUNCTION_LO < 2: 0>; @@ -31,6 +37,8 @@ def bitfield FT <20:16>; def bitfield FS <15:11>; def bitfield FD <10:6>; +def bitfield ND <17:17>; +def bitfield TF <16:16>; def bitfield MOVCI <16:16>; def bitfield MOVCF <16:16>; def bitfield SRL <21:21>; @@ -45,7 +53,7 @@ def bitfield OFFSET <15: 0>; // displacement // Jmp format def bitfield JMPTARG <25: 0>; -def bitfield JMPHINT <10: 6>; +def bitfield HINT <10: 6>; def bitfield SYSCALLCODE <25: 6>; def bitfield TRAPCODE <15:13>; diff --git a/arch/mips/isa/decoder.isa b/arch/mips/isa/decoder.isa index 7dd08ac49..f16da7f87 100644 --- a/arch/mips/isa/decoder.isa +++ b/arch/mips/isa/decoder.isa @@ -96,13 +96,13 @@ decode OPCODE_HI default Unknown::unknown() { 0x3: decode FUNCTION_LO { format IntOp { 0x0: mult({{ - INT64 temp1 = Rs.sw * Rt.sw; + int64_t temp1 = Rs.sw * Rt.sw; xc->miscRegs.hi->temp1<63:32>; xc->miscRegs.lo->temp1<31:0>; }}); 0x1: multu({{ - INT64 temp1 = Rs.uw * Rt.uw; + int64_t temp1 = Rs.uw * Rt.uw; xc->miscRegs.hi->temp1<63:32>; xc->miscRegs.lo->temp1<31:0> Rd.sw = Rs.uw * Rt.uw; @@ -141,7 +141,7 @@ decode OPCODE_HI default Unknown::unknown() { } 0x6: decode FUNCTION_LO { - format Trap { + format BasicOp { 0x0: tge({{ cond = (Rs.sw >= Rt.sw); }}); 0x1: tgeu({{ cond = (Rs.uw >= Rt.uw); }}); 0x2: tlt({{ cond = (Rs.sw < Rt.sw); }}); @@ -167,7 +167,7 @@ decode OPCODE_HI default Unknown::unknown() { } 0x1: decode REGIMM_LO { - format Trap { + format BasicOp { 0x0: tgei( {{ cond = (Rs.sw >= INTIMM); }}); 0x1: tgeiu({{ cond = (Rs.uw >= INTIMM); }}); 0x2: tlti( {{ cond = (Rs.sw < INTIMM); }}); @@ -179,14 +179,14 @@ decode OPCODE_HI default Unknown::unknown() { 0x2: decode REGIMM_LO { format Branch { - 0x0: bltzal({{ cond = (Rs.sw < 0); }}, IsLink); - 0x1: bgezal({{ cond = (Rs.sw >= 0); }}, IsLink); + 0x0: bltzal({{ cond = (Rs.sw < 0); }}, IsCall,IsReturn); + 0x1: bgezal({{ cond = (Rs.sw >= 0); }}, IsCall,IsReturn); } format BranchLikely { //Will be removed in future MIPS releases - 0x2: bltzall({{ cond = (Rs.sw < 0); }}, IsLink); - 0x3: bgezall({{ cond = (Rs.sw >= 0); }}, IsLink); + 0x2: bltzall({{ cond = (Rs.sw < 0); }}, IsCall, IsReturn); + 0x3: bgezall({{ cond = (Rs.sw >= 0); }}, IsCall, IsReturn); } } @@ -336,7 +336,7 @@ decode OPCODE_HI default Unknown::unknown() { //Table A-12 MIPS32 COP0 Encoding of Function Field When rs=CO 0x1: decode FUNCTION { - format Trap { + format BasicOp { 0x01: tlbr({{ }}); 0x02: tlbwi({{ }}); 0x06: tlbwr({{ }}); @@ -433,8 +433,8 @@ decode OPCODE_HI default Unknown::unknown() { } format Float64Op { - 0x2: recips({{ Fd = 1 / Fs; }}); - 0x3: rsqrts({{ Fd = 1 / sqrt(Fs.ud);}}); + 0x5: recips({{ Fd = 1 / Fs; }}); + 0x6: rsqrts({{ Fd = 1 / sqrt(Fs.ud);}}); } } @@ -502,8 +502,8 @@ decode OPCODE_HI default Unknown::unknown() { } format BasicOp { - 0x2: movz({{ if (Rt == 0) Fd.df = Fs.df; }}); - 0x3: movn({{ if (Rt != 0) Fd.df = Fs.df; }}); + 0x2: movzd({{ if (Rt == 0) Fd.df = Fs.df; }}); + 0x3: movnd({{ if (Rt != 0) Fd.df = Fs.df; }}); } format Float64Op { @@ -538,12 +538,12 @@ decode OPCODE_HI default Unknown::unknown() { //Table A-16 MIPS32 COP1 Encoding of Function Field When rs=W 0x4: decode FUNCTION { format FloatOp { - 0x10: cvt_s({{ + 0x20: cvt_s({{ int rnd_mode = xc->miscRegs.fcsr; Fd = convert_and_round(Fs.df,rnd_mode,FP_SINGLE,FP_WORD); }}); - 0x10: cvt_d({{ + 0x21: cvt_d({{ int rnd_mode = xc->miscRegs.fcsr; Fd = convert_and_round(Fs.df,rnd_mode,FP_DOUBLE,FP_WORD); }}); @@ -613,6 +613,11 @@ decode OPCODE_HI default Unknown::unknown() { } } + format BasicOp { + 0x2: movzps({{ if ( FPConditionCode(CC) == 0) Fd = Fs; }}); + 0x3: movnps({{ if ( FPConditionCode(CC) == 0) Fd = Fs; }}); + } + } 0x4: decode RS_LO { @@ -763,14 +768,14 @@ decode OPCODE_HI default Unknown::unknown() { 0x0: decode FUNCTION_LO { format IntOp { 0x0: madd({{ - INT64 temp1 = Hi.sw << 32 | Lo.sw >> 32; + int64_t temp1 = Hi.sw << 32 | Lo.sw >> 32; temp1 = temp1 + (Rs.sw * Rt.sw); xc->miscRegs.hi->temp1<63:32>; xc->miscRegs.lo->temp1<31:0> }}); 0x1: maddu({{ - INT64 temp1 = Hi.uw << 32 | Lo.uw >> 32; + int64_t temp1 = Hi.uw << 32 | Lo.uw >> 32; temp1 = temp1 + (Rs.uw * Rt.uw); xc->miscRegs.hi->temp1<63:32>; xc->miscRegs.lo->temp1<31:0> @@ -779,14 +784,14 @@ decode OPCODE_HI default Unknown::unknown() { 0x2: mul({{ Rd.sw = Rs.sw * Rt.sw; }}); 0x4: msub({{ - INT64 temp1 = Hi.sw << 32 | Lo.sw >> 32; + int64_t temp1 = Hi.sw << 32 | Lo.sw >> 32; temp1 = temp1 - (Rs.sw * Rt.sw); xc->miscRegs.hi->temp1<63:32>; xc->miscRegs.lo->temp1<31:0> }}); 0x5: msubu({{ - INT64 temp1 = Hi.uw << 32 | Lo.uw >> 32; + int64_t temp1 = Hi.uw << 32 | Lo.uw >> 32; temp1 = temp1 - (Rs.uw * Rt.uw); xc->miscRegs.hi->temp1<63:32>; xc->miscRegs.lo->temp1<31:0> diff --git a/arch/mips/isa/formats.isa b/arch/mips/isa/formats.isa index c244013df..a6aec9437 100644 --- a/arch/mips/isa/formats.isa +++ b/arch/mips/isa/formats.isa @@ -10,7 +10,7 @@ //Include utility formats/functions ##include "m5/arch/mips/isa/formats/util.isa" -//Include the integerOp and integerOpCc format +//Include the integer formats ##include "m5/arch/mips/isa/formats/int.isa" //Include the floatOp format @@ -30,4 +30,3 @@ //Include the noop format ##include "m5/arch/mips/isa/formats/unknown.isa" - diff --git a/arch/mips/isa/formats/branch.isa b/arch/mips/isa/formats/branch.isa index fc207fd3f..c896e9b2d 100644 --- a/arch/mips/isa/formats/branch.isa +++ b/arch/mips/isa/formats/branch.isa @@ -70,7 +70,7 @@ output header {{ int32_t disp; /// Constructor. - Branch(const char *mnem, MachInst _machInst, OpClass __opClass) + BranchLikely(const char *mnem, MachInst _machInst, OpClass __opClass) : PCDependentDisassembly(mnem, _machInst, __opClass), disp(OFFSET << 2) { @@ -243,7 +243,7 @@ output decoder {{ ss << ","; } - ccprintf(ss, "(r%d)", RB); + ccprintf(ss, "(r%d)", RT); return ss.str(); } diff --git a/arch/mips/isa/formats/fp.isa b/arch/mips/isa/formats/fp.isa index 23fcbaa67..7dd1e8442 100644 --- a/arch/mips/isa/formats/fp.isa +++ b/arch/mips/isa/formats/fp.isa @@ -1,3 +1,5 @@ +// -*- mode:c++ -*- + //////////////////////////////////////////////////////////////////// // // Floating Point operate instructions @@ -5,7 +7,7 @@ output header {{ /** - * Base class for integer operations. + * Base class for FP operations. */ class FPOp : public MipsStaticInst { @@ -70,62 +72,19 @@ def template FloatingPointExecute {{ }}; // Primary format for integer operate instructions: -def format FloatOp(code, *opt_flags) {{ - orig_code = code - cblk = CodeBlock(code) - checkPriv = (code.find('checkPriv') != -1) - code.replace('checkPriv', '') - if checkPriv: - code.replace('checkPriv;', 'if(!xc->regs.miscRegFile.pstateFields.priv) throw privileged_opcode;') - else: - code.replace('checkPriv;', '') - for (marker, value) in (('ivValue', '0'), ('icValue', '0'), - ('xvValue', '0'), ('xcValue', '0')): - code.replace(marker, value) - iop = InstObjParams(name, Name, 'MipsStaticInst', cblk, opt_flags) +def format FloatOp(code, *flags) {{ + iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags) header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) - decode_block = BasicDecodeWithMnemonic.subst(iop) - exec_output = FloatingPointExecute.subst(iop) + decode_block = BasicDecode.subst(iop) + exec_output = BasicExecute.subst(iop) }}; // Primary format for integer operate instructions: -def format Float64Op(code, *opt_flags) {{ - orig_code = code - cblk = CodeBlock(code) - checkPriv = (code.find('checkPriv') != -1) - code.replace('checkPriv', '') - if checkPriv: - code.replace('checkPriv;', 'if(!xc->regs.miscRegFile.pstateFields.priv) throw privileged_opcode;') - else: - code.replace('checkPriv;', '') - for (marker, value) in (('ivValue', '0'), ('icValue', '0'), - ('xvValue', '0'), ('xcValue', '0')): - code.replace(marker, value) - iop = InstObjParams(name, Name, 'MipsStaticInst', cblk, opt_flags) +def format Float64Op(code, *flags) {{ + iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags) header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) - decode_block = BasicDecodeWithMnemonic.subst(iop) - exec_output = FloatingPointExecute.subst(iop) -}}; - -// Primary format for integer operate instructions: -def format FPOpCc(code, icValue, ivValue, xcValue, xvValue, *opt_flags) {{ - orig_code = code - - cblk = CodeBlock(code) - checkPriv = (code.find('checkPriv') != -1) - code.replace('checkPriv', '') - if checkPriv: - code.replace('checkPriv;', 'if(!xc->regs.miscRegFile.pstateFields.priv) throw privileged_opcode;') - else: - code.replace('checkPriv;', '') - for (marker, value) in (('ivValue', ivValue), ('icValue', icValue), - ('xvValue', xvValue), ('xcValue', xcValue)): - code.replace(marker, value) - iop = InstObjParams(name, Name, 'MipsStaticInst', cblk, opt_flags) - header_output = BasicDeclare.subst(iop) - decoder_output = BasicConstructor.subst(iop) - decode_block = BasicDecodeWithMnemonic.subst(iop) - exec_output = IntegerExecute.subst(iop) + decode_block = BasicDecode.subst(iop) + exec_output = BasicExecute.subst(iop) }}; diff --git a/arch/mips/isa/formats/mem.isa b/arch/mips/isa/formats/mem.isa index 134548746..fcdb577c6 100644 --- a/arch/mips/isa/formats/mem.isa +++ b/arch/mips/isa/formats/mem.isa @@ -70,7 +70,7 @@ output decoder {{ Memory::generateDisassembly(Addr pc, const SymbolTable *symtab) const { return csprintf("%-10s %c%d,%d(r%d)", mnemonic, - flags[IsFloating] ? 'f' : 'r', RA, MEMDISP, RB); + flags[IsFloating] ? 'f' : 'r', RS, JMPTARG, RT); } }}; diff --git a/arch/mips/isa/formats/noop.isa b/arch/mips/isa/formats/noop.isa index d366461e2..05c5ac10f 100644 --- a/arch/mips/isa/formats/noop.isa +++ b/arch/mips/isa/formats/noop.isa @@ -63,12 +63,12 @@ output exec {{ } }}; -// integer & FP operate instructions use Rc as dest, so check for -// Rc == 31 to detect nops +// integer & FP operate instructions use RT as dest, so check for +// RT == 0 to detect nops def template OperateNopCheckDecode {{ { MipsStaticInst *i = new %(class_name)s(machInst); - if (RC == 31) { + if (RD == 0) { i = makeNop(i); } return i; diff --git a/arch/mips/isa/formats/util.isa b/arch/mips/isa/formats/util.isa index f0671726c..c06877b35 100644 --- a/arch/mips/isa/formats/util.isa +++ b/arch/mips/isa/formats/util.isa @@ -122,4 +122,4 @@ output exec {{ { //CODE HERE } -} +}}; diff --git a/arch/mips/isa/includes.isa b/arch/mips/isa/includes.isa index ff7cb7d1d..da919be00 100644 --- a/arch/mips/isa/includes.isa +++ b/arch/mips/isa/includes.isa @@ -9,7 +9,6 @@ output header {{ #include #include "cpu/static_inst.hh" -#include "traps.hh" #include "mem/mem_req.hh" // some constructors use MemReq flags }}; diff --git a/arch/mips/isa_traits.hh b/arch/mips/isa_traits.hh index c636cd241..71da82ffa 100644 --- a/arch/mips/isa_traits.hh +++ b/arch/mips/isa_traits.hh @@ -56,7 +56,7 @@ namespace MipsISA { typedef uint32_t MachInst; -// typedef uint64_t Addr; +// typedef uint64_t Addr; typedef uint8_t RegIndex; enum { diff --git a/cpu/static_inst.hh b/cpu/static_inst.hh index 5106dcf06..db9e73714 100644 --- a/cpu/static_inst.hh +++ b/cpu/static_inst.hh @@ -109,6 +109,8 @@ class StaticInstBase : public RefCounted IsCall, ///< Subroutine call. IsReturn, ///< Subroutine return. + IsCondDelaySlot,///< Conditional Delay-Slot Instruction + IsThreadSync, ///< Thread synchronization operation. IsSerializing, ///< Serializes pipeline: won't execute until all From 2d2510e94f6fc60ae5acc656be5fa6d03a9583c8 Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Wed, 22 Feb 2006 03:44:21 -0500 Subject: [PATCH 083/180] Still builds "../MIPS_SE/arch/mips/decoder.do with no errors! ----- uncomment out detailed model ... just commented to supress some compile errors arch/isa_parser.py: uncomment out detailed model ... just commented to supress some compile errors --HG-- extra : convert_revision : e884b9bd47794409f74043ad1aca6dadd1323185 --- arch/isa_parser.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/isa_parser.py b/arch/isa_parser.py index 7c511a8b3..0d18f4d89 100755 --- a/arch/isa_parser.py +++ b/arch/isa_parser.py @@ -746,9 +746,9 @@ CpuModel('FullCPU', 'full_cpu_exec.cc', '#include "encumbered/cpu/full/dyn_inst.hh"', { 'CPU_exec_context': 'DynInst' }) -#CpuModel('AlphaFullCPU', 'alpha_o3_exec.cc', -# '#include "cpu/o3/alpha_dyn_inst.hh"', -# { 'CPU_exec_context': 'AlphaDynInst' }) +CpuModel('AlphaFullCPU', 'alpha_o3_exec.cc', + '#include "cpu/o3/alpha_dyn_inst.hh"', + { 'CPU_exec_context': 'AlphaDynInst' }) # Expand template with CPU-specific references into a dictionary with # an entry for each CPU model name. The entry key is the model name From 9bc7f13eebbec26357ce722faa9bf2db4740bb9d Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Wed, 22 Feb 2006 04:08:08 -0500 Subject: [PATCH 084/180] make sure alpha still compiles , rename files back to original naming ... Now that we have decoder.do, add new files so we can start compiling other files needed for MIPS syscall emulation mode arch/mips/linux_process.cc: arch/mips/linux_process.hh: New MIPS-specific file --HG-- rename : arch/alpha/linux_process.cc => arch/alpha/alpha_linux_process.cc rename : arch/alpha/linux_process.hh => arch/alpha/alpha_linux_process.hh rename : arch/alpha/tru64_process.cc => arch/alpha/alpha_tru64_process.cc rename : arch/alpha/tru64_process.hh => arch/alpha/alpha_tru64_process.hh extra : convert_revision : 2bfc27e8772523cbeb95f40684f9a32fe5554f87 --- ...inux_process.cc => alpha_linux_process.cc} | 0 ...inux_process.hh => alpha_linux_process.hh} | 0 ...ru64_process.cc => alpha_tru64_process.cc} | 0 ...ru64_process.hh => alpha_tru64_process.hh} | 0 arch/mips/linux_process.cc | 588 ++++++++++++++++++ arch/mips/linux_process.hh | 58 ++ 6 files changed, 646 insertions(+) rename arch/alpha/{linux_process.cc => alpha_linux_process.cc} (100%) rename arch/alpha/{linux_process.hh => alpha_linux_process.hh} (100%) rename arch/alpha/{tru64_process.cc => alpha_tru64_process.cc} (100%) rename arch/alpha/{tru64_process.hh => alpha_tru64_process.hh} (100%) create mode 100644 arch/mips/linux_process.cc create mode 100644 arch/mips/linux_process.hh diff --git a/arch/alpha/linux_process.cc b/arch/alpha/alpha_linux_process.cc similarity index 100% rename from arch/alpha/linux_process.cc rename to arch/alpha/alpha_linux_process.cc diff --git a/arch/alpha/linux_process.hh b/arch/alpha/alpha_linux_process.hh similarity index 100% rename from arch/alpha/linux_process.hh rename to arch/alpha/alpha_linux_process.hh diff --git a/arch/alpha/tru64_process.cc b/arch/alpha/alpha_tru64_process.cc similarity index 100% rename from arch/alpha/tru64_process.cc rename to arch/alpha/alpha_tru64_process.cc diff --git a/arch/alpha/tru64_process.hh b/arch/alpha/alpha_tru64_process.hh similarity index 100% rename from arch/alpha/tru64_process.hh rename to arch/alpha/alpha_tru64_process.hh diff --git a/arch/mips/linux_process.cc b/arch/mips/linux_process.cc new file mode 100644 index 000000000..d3aca15bc --- /dev/null +++ b/arch/mips/linux_process.cc @@ -0,0 +1,588 @@ +/* + * 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/mips/mips_common_syscall_emul.hh" +#include "arch/mips/mips_linux_process.hh" +#include "arch/mips/isa_traits.hh" + +#include "base/trace.hh" +#include "cpu/exec_context.hh" +#include "kern/linux/linux.hh" +#include "mem/functional/functional.hh" + +#include "sim/process.hh" +#include "sim/syscall_emul.hh" + +using namespace std; +using namespace MipsISA; + +/// Target uname() handler. +static SyscallReturn +unameFunc(SyscallDesc *desc, int callnum, Process *process, + ExecContext *xc) +{ + TypedBufferArg name(xc->getSyscallArg(0)); + + strcpy(name->sysname, "Linux"); + strcpy(name->nodename, "m5.eecs.umich.edu"); + strcpy(name->release, "2.4.20"); + strcpy(name->version, "#1 Mon Aug 18 11:32:15 EDT 2003"); + strcpy(name->machine, "mips"); + + name.copyOut(xc->mem); + return 0; +} + +/// Target osf_getsysyinfo() handler. Even though this call is +/// borrowed from Tru64, the subcases that get used appear to be +/// different in practice from those used by Tru64 processes. +static SyscallReturn +osf_getsysinfoFunc(SyscallDesc *desc, int callnum, Process *process, + ExecContext *xc) +{ + unsigned op = xc->getSyscallArg(0); + // unsigned nbytes = xc->getSyscallArg(2); + + switch (op) { + + case 45: { // GSI_IEEE_FP_CONTROL + TypedBufferArg fpcr(xc->getSyscallArg(1)); + // I don't think this exactly matches the HW FPCR + *fpcr = 0; + fpcr.copyOut(xc->mem); + return 0; + } + + default: + cerr << "osf_getsysinfo: unknown op " << op << endl; + abort(); + break; + } + + return 1; +} + +/// Target osf_setsysinfo() handler. +static SyscallReturn +osf_setsysinfoFunc(SyscallDesc *desc, int callnum, Process *process, + ExecContext *xc) +{ + unsigned op = xc->getSyscallArg(0); + // unsigned nbytes = xc->getSyscallArg(2); + + switch (op) { + + case 14: { // SSI_IEEE_FP_CONTROL + TypedBufferArg fpcr(xc->getSyscallArg(1)); + // I don't think this exactly matches the HW FPCR + fpcr.copyIn(xc->mem); + DPRINTFR(SyscallVerbose, "osf_setsysinfo(SSI_IEEE_FP_CONTROL): " + " setting FPCR to 0x%x\n", gtoh(*(uint64_t*)fpcr)); + return 0; + } + + default: + cerr << "osf_setsysinfo: unknown op " << op << endl; + abort(); + break; + } + + return 1; +} + + +SyscallDesc MipsLinuxProcess::syscallDescs[] = { + /* 0 */ SyscallDesc("osf_syscall", unimplementedFunc), + /* 1 */ SyscallDesc("exit", exitFunc), + /* 2 */ SyscallDesc("fork", unimplementedFunc), + /* 3 */ SyscallDesc("read", readFunc), + /* 4 */ SyscallDesc("write", writeFunc), + /* 5 */ SyscallDesc("osf_old_open", unimplementedFunc), + /* 6 */ SyscallDesc("close", closeFunc), + /* 7 */ SyscallDesc("osf_wait4", unimplementedFunc), + /* 8 */ SyscallDesc("osf_old_creat", unimplementedFunc), + /* 9 */ SyscallDesc("link", unimplementedFunc), + /* 10 */ SyscallDesc("unlink", unlinkFunc), + /* 11 */ SyscallDesc("osf_execve", unimplementedFunc), + /* 12 */ SyscallDesc("chdir", unimplementedFunc), + /* 13 */ SyscallDesc("fchdir", unimplementedFunc), + /* 14 */ SyscallDesc("mknod", unimplementedFunc), + /* 15 */ SyscallDesc("chmod", chmodFunc), + /* 16 */ SyscallDesc("chown", chownFunc), + /* 17 */ SyscallDesc("brk", obreakFunc), + /* 18 */ SyscallDesc("osf_getfsstat", unimplementedFunc), + /* 19 */ SyscallDesc("lseek", lseekFunc), + /* 20 */ SyscallDesc("getxpid", getpidFunc), + /* 21 */ SyscallDesc("osf_mount", unimplementedFunc), + /* 22 */ SyscallDesc("umount", unimplementedFunc), + /* 23 */ SyscallDesc("setuid", setuidFunc), + /* 24 */ SyscallDesc("getxuid", getuidFunc), + /* 25 */ SyscallDesc("exec_with_loader", unimplementedFunc), + /* 26 */ SyscallDesc("osf_ptrace", unimplementedFunc), + /* 27 */ SyscallDesc("osf_nrecvmsg", unimplementedFunc), + /* 28 */ SyscallDesc("osf_nsendmsg", unimplementedFunc), + /* 29 */ SyscallDesc("osf_nrecvfrom", unimplementedFunc), + /* 30 */ SyscallDesc("osf_naccept", unimplementedFunc), + /* 31 */ SyscallDesc("osf_ngetpeername", unimplementedFunc), + /* 32 */ SyscallDesc("osf_ngetsockname", unimplementedFunc), + /* 33 */ SyscallDesc("access", unimplementedFunc), + /* 34 */ SyscallDesc("osf_chflags", unimplementedFunc), + /* 35 */ SyscallDesc("osf_fchflags", unimplementedFunc), + /* 36 */ SyscallDesc("sync", unimplementedFunc), + /* 37 */ SyscallDesc("kill", unimplementedFunc), + /* 38 */ SyscallDesc("osf_old_stat", unimplementedFunc), + /* 39 */ SyscallDesc("setpgid", unimplementedFunc), + /* 40 */ SyscallDesc("osf_old_lstat", unimplementedFunc), + /* 41 */ SyscallDesc("dup", unimplementedFunc), + /* 42 */ SyscallDesc("pipe", unimplementedFunc), + /* 43 */ SyscallDesc("osf_set_program_attributes", unimplementedFunc), + /* 44 */ SyscallDesc("osf_profil", unimplementedFunc), + /* 45 */ SyscallDesc("open", openFunc), + /* 46 */ SyscallDesc("osf_old_sigaction", unimplementedFunc), + /* 47 */ SyscallDesc("getxgid", getgidFunc), + /* 48 */ SyscallDesc("osf_sigprocmask", ignoreFunc), + /* 49 */ SyscallDesc("osf_getlogin", unimplementedFunc), + /* 50 */ SyscallDesc("osf_setlogin", unimplementedFunc), + /* 51 */ SyscallDesc("acct", unimplementedFunc), + /* 52 */ SyscallDesc("sigpending", unimplementedFunc), + /* 53 */ SyscallDesc("osf_classcntl", unimplementedFunc), + /* 54 */ SyscallDesc("ioctl", ioctlFunc), + /* 55 */ SyscallDesc("osf_reboot", unimplementedFunc), + /* 56 */ SyscallDesc("osf_revoke", unimplementedFunc), + /* 57 */ SyscallDesc("symlink", unimplementedFunc), + /* 58 */ SyscallDesc("readlink", unimplementedFunc), + /* 59 */ SyscallDesc("execve", unimplementedFunc), + /* 60 */ SyscallDesc("umask", unimplementedFunc), + /* 61 */ SyscallDesc("chroot", unimplementedFunc), + /* 62 */ SyscallDesc("osf_old_fstat", unimplementedFunc), + /* 63 */ SyscallDesc("getpgrp", unimplementedFunc), + /* 64 */ SyscallDesc("getpagesize", getpagesizeFunc), + /* 65 */ SyscallDesc("osf_mremap", unimplementedFunc), + /* 66 */ SyscallDesc("vfork", unimplementedFunc), + /* 67 */ SyscallDesc("stat", statFunc), + /* 68 */ SyscallDesc("lstat", lstatFunc), + /* 69 */ SyscallDesc("osf_sbrk", unimplementedFunc), + /* 70 */ SyscallDesc("osf_sstk", unimplementedFunc), + /* 71 */ SyscallDesc("mmap", mmapFunc), + /* 72 */ SyscallDesc("osf_old_vadvise", unimplementedFunc), + /* 73 */ SyscallDesc("munmap", munmapFunc), + /* 74 */ SyscallDesc("mprotect", ignoreFunc), + /* 75 */ SyscallDesc("madvise", unimplementedFunc), + /* 76 */ SyscallDesc("vhangup", unimplementedFunc), + /* 77 */ SyscallDesc("osf_kmodcall", unimplementedFunc), + /* 78 */ SyscallDesc("osf_mincore", unimplementedFunc), + /* 79 */ SyscallDesc("getgroups", unimplementedFunc), + /* 80 */ SyscallDesc("setgroups", unimplementedFunc), + /* 81 */ SyscallDesc("osf_old_getpgrp", unimplementedFunc), + /* 82 */ SyscallDesc("setpgrp", unimplementedFunc), + /* 83 */ SyscallDesc("osf_setitimer", unimplementedFunc), + /* 84 */ SyscallDesc("osf_old_wait", unimplementedFunc), + /* 85 */ SyscallDesc("osf_table", unimplementedFunc), + /* 86 */ SyscallDesc("osf_getitimer", unimplementedFunc), + /* 87 */ SyscallDesc("gethostname", gethostnameFunc), + /* 88 */ SyscallDesc("sethostname", unimplementedFunc), + /* 89 */ SyscallDesc("getdtablesize", unimplementedFunc), + /* 90 */ SyscallDesc("dup2", unimplementedFunc), + /* 91 */ SyscallDesc("fstat", fstatFunc), + /* 92 */ SyscallDesc("fcntl", fcntlFunc), + /* 93 */ SyscallDesc("osf_select", unimplementedFunc), + /* 94 */ SyscallDesc("poll", unimplementedFunc), + /* 95 */ SyscallDesc("fsync", unimplementedFunc), + /* 96 */ SyscallDesc("setpriority", unimplementedFunc), + /* 97 */ SyscallDesc("socket", unimplementedFunc), + /* 98 */ SyscallDesc("connect", unimplementedFunc), + /* 99 */ SyscallDesc("accept", unimplementedFunc), + /* 100 */ SyscallDesc("getpriority", unimplementedFunc), + /* 101 */ SyscallDesc("send", unimplementedFunc), + /* 102 */ SyscallDesc("recv", unimplementedFunc), + /* 103 */ SyscallDesc("sigreturn", unimplementedFunc), + /* 104 */ SyscallDesc("bind", unimplementedFunc), + /* 105 */ SyscallDesc("setsockopt", unimplementedFunc), + /* 106 */ SyscallDesc("listen", unimplementedFunc), + /* 107 */ SyscallDesc("osf_plock", unimplementedFunc), + /* 108 */ SyscallDesc("osf_old_sigvec", unimplementedFunc), + /* 109 */ SyscallDesc("osf_old_sigblock", unimplementedFunc), + /* 110 */ SyscallDesc("osf_old_sigsetmask", unimplementedFunc), + /* 111 */ SyscallDesc("sigsuspend", unimplementedFunc), + /* 112 */ SyscallDesc("osf_sigstack", ignoreFunc), + /* 113 */ SyscallDesc("recvmsg", unimplementedFunc), + /* 114 */ SyscallDesc("sendmsg", unimplementedFunc), + /* 115 */ SyscallDesc("osf_old_vtrace", unimplementedFunc), + /* 116 */ SyscallDesc("osf_gettimeofday", unimplementedFunc), + /* 117 */ SyscallDesc("osf_getrusage", unimplementedFunc), + /* 118 */ SyscallDesc("getsockopt", unimplementedFunc), + /* 119 */ SyscallDesc("numa_syscalls", unimplementedFunc), + /* 120 */ SyscallDesc("readv", unimplementedFunc), + /* 121 */ SyscallDesc("writev", writevFunc), + /* 122 */ SyscallDesc("osf_settimeofday", unimplementedFunc), + /* 123 */ SyscallDesc("fchown", fchownFunc), + /* 124 */ SyscallDesc("fchmod", fchmodFunc), + /* 125 */ SyscallDesc("recvfrom", unimplementedFunc), + /* 126 */ SyscallDesc("setreuid", unimplementedFunc), + /* 127 */ SyscallDesc("setregid", unimplementedFunc), + /* 128 */ SyscallDesc("rename", renameFunc), + /* 129 */ SyscallDesc("truncate", unimplementedFunc), + /* 130 */ SyscallDesc("ftruncate", unimplementedFunc), + /* 131 */ SyscallDesc("flock", unimplementedFunc), + /* 132 */ SyscallDesc("setgid", unimplementedFunc), + /* 133 */ SyscallDesc("sendto", unimplementedFunc), + /* 134 */ SyscallDesc("shutdown", unimplementedFunc), + /* 135 */ SyscallDesc("socketpair", unimplementedFunc), + /* 136 */ SyscallDesc("mkdir", unimplementedFunc), + /* 137 */ SyscallDesc("rmdir", unimplementedFunc), + /* 138 */ SyscallDesc("osf_utimes", unimplementedFunc), + /* 139 */ SyscallDesc("osf_old_sigreturn", unimplementedFunc), + /* 140 */ SyscallDesc("osf_adjtime", unimplementedFunc), + /* 141 */ SyscallDesc("getpeername", unimplementedFunc), + /* 142 */ SyscallDesc("osf_gethostid", unimplementedFunc), + /* 143 */ SyscallDesc("osf_sethostid", unimplementedFunc), + /* 144 */ SyscallDesc("getrlimit", getrlimitFunc), + /* 145 */ SyscallDesc("setrlimit", ignoreFunc), + /* 146 */ SyscallDesc("osf_old_killpg", unimplementedFunc), + /* 147 */ SyscallDesc("setsid", unimplementedFunc), + /* 148 */ SyscallDesc("quotactl", unimplementedFunc), + /* 149 */ SyscallDesc("osf_oldquota", unimplementedFunc), + /* 150 */ SyscallDesc("getsockname", unimplementedFunc), + /* 151 */ SyscallDesc("osf_pread", unimplementedFunc), + /* 152 */ SyscallDesc("osf_pwrite", unimplementedFunc), + /* 153 */ SyscallDesc("osf_pid_block", unimplementedFunc), + /* 154 */ SyscallDesc("osf_pid_unblock", unimplementedFunc), + /* 155 */ SyscallDesc("osf_signal_urti", unimplementedFunc), + /* 156 */ SyscallDesc("sigaction", ignoreFunc), + /* 157 */ SyscallDesc("osf_sigwaitprim", unimplementedFunc), + /* 158 */ SyscallDesc("osf_nfssvc", unimplementedFunc), + /* 159 */ SyscallDesc("osf_getdirentries", unimplementedFunc), + /* 160 */ SyscallDesc("osf_statfs", unimplementedFunc), + /* 161 */ SyscallDesc("osf_fstatfs", unimplementedFunc), + /* 162 */ SyscallDesc("unknown #162", unimplementedFunc), + /* 163 */ SyscallDesc("osf_async_daemon", unimplementedFunc), + /* 164 */ SyscallDesc("osf_getfh", unimplementedFunc), + /* 165 */ SyscallDesc("osf_getdomainname", unimplementedFunc), + /* 166 */ SyscallDesc("setdomainname", unimplementedFunc), + /* 167 */ SyscallDesc("unknown #167", unimplementedFunc), + /* 168 */ SyscallDesc("unknown #168", unimplementedFunc), + /* 169 */ SyscallDesc("osf_exportfs", unimplementedFunc), + /* 170 */ SyscallDesc("unknown #170", unimplementedFunc), + /* 171 */ SyscallDesc("unknown #171", unimplementedFunc), + /* 172 */ SyscallDesc("unknown #172", unimplementedFunc), + /* 173 */ SyscallDesc("unknown #173", unimplementedFunc), + /* 174 */ SyscallDesc("unknown #174", unimplementedFunc), + /* 175 */ SyscallDesc("unknown #175", unimplementedFunc), + /* 176 */ SyscallDesc("unknown #176", unimplementedFunc), + /* 177 */ SyscallDesc("unknown #177", unimplementedFunc), + /* 178 */ SyscallDesc("unknown #178", unimplementedFunc), + /* 179 */ SyscallDesc("unknown #179", unimplementedFunc), + /* 180 */ SyscallDesc("unknown #180", unimplementedFunc), + /* 181 */ SyscallDesc("osf_alt_plock", unimplementedFunc), + /* 182 */ SyscallDesc("unknown #182", unimplementedFunc), + /* 183 */ SyscallDesc("unknown #183", unimplementedFunc), + /* 184 */ SyscallDesc("osf_getmnt", unimplementedFunc), + /* 185 */ SyscallDesc("unknown #185", unimplementedFunc), + /* 186 */ SyscallDesc("unknown #186", unimplementedFunc), + /* 187 */ SyscallDesc("osf_alt_sigpending", unimplementedFunc), + /* 188 */ SyscallDesc("osf_alt_setsid", unimplementedFunc), + /* 189 */ SyscallDesc("unknown #189", unimplementedFunc), + /* 190 */ SyscallDesc("unknown #190", unimplementedFunc), + /* 191 */ SyscallDesc("unknown #191", unimplementedFunc), + /* 192 */ SyscallDesc("unknown #192", unimplementedFunc), + /* 193 */ SyscallDesc("unknown #193", unimplementedFunc), + /* 194 */ SyscallDesc("unknown #194", unimplementedFunc), + /* 195 */ SyscallDesc("unknown #195", unimplementedFunc), + /* 196 */ SyscallDesc("unknown #196", unimplementedFunc), + /* 197 */ SyscallDesc("unknown #197", unimplementedFunc), + /* 198 */ SyscallDesc("unknown #198", unimplementedFunc), + /* 199 */ SyscallDesc("osf_swapon", unimplementedFunc), + /* 200 */ SyscallDesc("msgctl", unimplementedFunc), + /* 201 */ SyscallDesc("msgget", unimplementedFunc), + /* 202 */ SyscallDesc("msgrcv", unimplementedFunc), + /* 203 */ SyscallDesc("msgsnd", unimplementedFunc), + /* 204 */ SyscallDesc("semctl", unimplementedFunc), + /* 205 */ SyscallDesc("semget", unimplementedFunc), + /* 206 */ SyscallDesc("semop", unimplementedFunc), + /* 207 */ SyscallDesc("osf_utsname", unimplementedFunc), + /* 208 */ SyscallDesc("lchown", unimplementedFunc), + /* 209 */ SyscallDesc("osf_shmat", unimplementedFunc), + /* 210 */ SyscallDesc("shmctl", unimplementedFunc), + /* 211 */ SyscallDesc("shmdt", unimplementedFunc), + /* 212 */ SyscallDesc("shmget", unimplementedFunc), + /* 213 */ SyscallDesc("osf_mvalid", unimplementedFunc), + /* 214 */ SyscallDesc("osf_getaddressconf", unimplementedFunc), + /* 215 */ SyscallDesc("osf_msleep", unimplementedFunc), + /* 216 */ SyscallDesc("osf_mwakeup", unimplementedFunc), + /* 217 */ SyscallDesc("msync", unimplementedFunc), + /* 218 */ SyscallDesc("osf_signal", unimplementedFunc), + /* 219 */ SyscallDesc("osf_utc_gettime", unimplementedFunc), + /* 220 */ SyscallDesc("osf_utc_adjtime", unimplementedFunc), + /* 221 */ SyscallDesc("unknown #221", unimplementedFunc), + /* 222 */ SyscallDesc("osf_security", unimplementedFunc), + /* 223 */ SyscallDesc("osf_kloadcall", unimplementedFunc), + /* 224 */ SyscallDesc("unknown #224", unimplementedFunc), + /* 225 */ SyscallDesc("unknown #225", unimplementedFunc), + /* 226 */ SyscallDesc("unknown #226", unimplementedFunc), + /* 227 */ SyscallDesc("unknown #227", unimplementedFunc), + /* 228 */ SyscallDesc("unknown #228", unimplementedFunc), + /* 229 */ SyscallDesc("unknown #229", unimplementedFunc), + /* 230 */ SyscallDesc("unknown #230", unimplementedFunc), + /* 231 */ SyscallDesc("unknown #231", unimplementedFunc), + /* 232 */ SyscallDesc("unknown #232", unimplementedFunc), + /* 233 */ SyscallDesc("getpgid", unimplementedFunc), + /* 234 */ SyscallDesc("getsid", unimplementedFunc), + /* 235 */ SyscallDesc("sigaltstack", ignoreFunc), + /* 236 */ SyscallDesc("osf_waitid", unimplementedFunc), + /* 237 */ SyscallDesc("osf_priocntlset", unimplementedFunc), + /* 238 */ SyscallDesc("osf_sigsendset", unimplementedFunc), + /* 239 */ SyscallDesc("osf_set_speculative", unimplementedFunc), + /* 240 */ SyscallDesc("osf_msfs_syscall", unimplementedFunc), + /* 241 */ SyscallDesc("osf_sysinfo", unimplementedFunc), + /* 242 */ SyscallDesc("osf_uadmin", unimplementedFunc), + /* 243 */ SyscallDesc("osf_fuser", unimplementedFunc), + /* 244 */ SyscallDesc("osf_proplist_syscall", unimplementedFunc), + /* 245 */ SyscallDesc("osf_ntp_adjtime", unimplementedFunc), + /* 246 */ SyscallDesc("osf_ntp_gettime", unimplementedFunc), + /* 247 */ SyscallDesc("osf_pathconf", unimplementedFunc), + /* 248 */ SyscallDesc("osf_fpathconf", unimplementedFunc), + /* 249 */ SyscallDesc("unknown #249", unimplementedFunc), + /* 250 */ SyscallDesc("osf_uswitch", unimplementedFunc), + /* 251 */ SyscallDesc("osf_usleep_thread", unimplementedFunc), + /* 252 */ SyscallDesc("osf_audcntl", unimplementedFunc), + /* 253 */ SyscallDesc("osf_audgen", unimplementedFunc), + /* 254 */ SyscallDesc("sysfs", unimplementedFunc), + /* 255 */ SyscallDesc("osf_subsys_info", unimplementedFunc), + /* 256 */ SyscallDesc("osf_getsysinfo", osf_getsysinfoFunc), + /* 257 */ SyscallDesc("osf_setsysinfo", osf_setsysinfoFunc), + /* 258 */ SyscallDesc("osf_afs_syscall", unimplementedFunc), + /* 259 */ SyscallDesc("osf_swapctl", unimplementedFunc), + /* 260 */ SyscallDesc("osf_memcntl", unimplementedFunc), + /* 261 */ SyscallDesc("osf_fdatasync", unimplementedFunc), + /* 262 */ SyscallDesc("unknown #262", unimplementedFunc), + /* 263 */ SyscallDesc("unknown #263", unimplementedFunc), + /* 264 */ SyscallDesc("unknown #264", unimplementedFunc), + /* 265 */ SyscallDesc("unknown #265", unimplementedFunc), + /* 266 */ SyscallDesc("unknown #266", unimplementedFunc), + /* 267 */ SyscallDesc("unknown #267", unimplementedFunc), + /* 268 */ SyscallDesc("unknown #268", unimplementedFunc), + /* 269 */ SyscallDesc("unknown #269", unimplementedFunc), + /* 270 */ SyscallDesc("unknown #270", unimplementedFunc), + /* 271 */ SyscallDesc("unknown #271", unimplementedFunc), + /* 272 */ SyscallDesc("unknown #272", unimplementedFunc), + /* 273 */ SyscallDesc("unknown #273", unimplementedFunc), + /* 274 */ SyscallDesc("unknown #274", unimplementedFunc), + /* 275 */ SyscallDesc("unknown #275", unimplementedFunc), + /* 276 */ SyscallDesc("unknown #276", unimplementedFunc), + /* 277 */ SyscallDesc("unknown #277", unimplementedFunc), + /* 278 */ SyscallDesc("unknown #278", unimplementedFunc), + /* 279 */ SyscallDesc("unknown #279", unimplementedFunc), + /* 280 */ SyscallDesc("unknown #280", unimplementedFunc), + /* 281 */ SyscallDesc("unknown #281", unimplementedFunc), + /* 282 */ SyscallDesc("unknown #282", unimplementedFunc), + /* 283 */ SyscallDesc("unknown #283", unimplementedFunc), + /* 284 */ SyscallDesc("unknown #284", unimplementedFunc), + /* 285 */ SyscallDesc("unknown #285", unimplementedFunc), + /* 286 */ SyscallDesc("unknown #286", unimplementedFunc), + /* 287 */ SyscallDesc("unknown #287", unimplementedFunc), + /* 288 */ SyscallDesc("unknown #288", unimplementedFunc), + /* 289 */ SyscallDesc("unknown #289", unimplementedFunc), + /* 290 */ SyscallDesc("unknown #290", unimplementedFunc), + /* 291 */ SyscallDesc("unknown #291", unimplementedFunc), + /* 292 */ SyscallDesc("unknown #292", unimplementedFunc), + /* 293 */ SyscallDesc("unknown #293", unimplementedFunc), + /* 294 */ SyscallDesc("unknown #294", unimplementedFunc), + /* 295 */ SyscallDesc("unknown #295", unimplementedFunc), + /* 296 */ SyscallDesc("unknown #296", unimplementedFunc), + /* 297 */ SyscallDesc("unknown #297", unimplementedFunc), + /* 298 */ SyscallDesc("unknown #298", unimplementedFunc), + /* 299 */ SyscallDesc("unknown #299", unimplementedFunc), +/* + * Linux-specific system calls begin at 300 + */ + /* 300 */ SyscallDesc("bdflush", unimplementedFunc), + /* 301 */ SyscallDesc("sethae", unimplementedFunc), + /* 302 */ SyscallDesc("mount", unimplementedFunc), + /* 303 */ SyscallDesc("old_adjtimex", unimplementedFunc), + /* 304 */ SyscallDesc("swapoff", unimplementedFunc), + /* 305 */ SyscallDesc("getdents", unimplementedFunc), + /* 306 */ SyscallDesc("create_module", unimplementedFunc), + /* 307 */ SyscallDesc("init_module", unimplementedFunc), + /* 308 */ SyscallDesc("delete_module", unimplementedFunc), + /* 309 */ SyscallDesc("get_kernel_syms", unimplementedFunc), + /* 310 */ SyscallDesc("syslog", unimplementedFunc), + /* 311 */ SyscallDesc("reboot", unimplementedFunc), + /* 312 */ SyscallDesc("clone", unimplementedFunc), + /* 313 */ SyscallDesc("uselib", unimplementedFunc), + /* 314 */ SyscallDesc("mlock", unimplementedFunc), + /* 315 */ SyscallDesc("munlock", unimplementedFunc), + /* 316 */ SyscallDesc("mlockall", unimplementedFunc), + /* 317 */ SyscallDesc("munlockall", unimplementedFunc), + /* 318 */ SyscallDesc("sysinfo", unimplementedFunc), + /* 319 */ SyscallDesc("_sysctl", unimplementedFunc), + /* 320 */ SyscallDesc("was sys_idle", unimplementedFunc), + /* 321 */ SyscallDesc("oldumount", unimplementedFunc), + /* 322 */ SyscallDesc("swapon", unimplementedFunc), + /* 323 */ SyscallDesc("times", ignoreFunc), + /* 324 */ SyscallDesc("personality", unimplementedFunc), + /* 325 */ SyscallDesc("setfsuid", unimplementedFunc), + /* 326 */ SyscallDesc("setfsgid", unimplementedFunc), + /* 327 */ SyscallDesc("ustat", unimplementedFunc), + /* 328 */ SyscallDesc("statfs", unimplementedFunc), + /* 329 */ SyscallDesc("fstatfs", unimplementedFunc), + /* 330 */ SyscallDesc("sched_setparam", unimplementedFunc), + /* 331 */ SyscallDesc("sched_getparam", unimplementedFunc), + /* 332 */ SyscallDesc("sched_setscheduler", unimplementedFunc), + /* 333 */ SyscallDesc("sched_getscheduler", unimplementedFunc), + /* 334 */ SyscallDesc("sched_yield", unimplementedFunc), + /* 335 */ SyscallDesc("sched_get_priority_max", unimplementedFunc), + /* 336 */ SyscallDesc("sched_get_priority_min", unimplementedFunc), + /* 337 */ SyscallDesc("sched_rr_get_interval", unimplementedFunc), + /* 338 */ SyscallDesc("afs_syscall", unimplementedFunc), + /* 339 */ SyscallDesc("uname", unameFunc), + /* 340 */ SyscallDesc("nanosleep", unimplementedFunc), + /* 341 */ SyscallDesc("mremap", unimplementedFunc), + /* 342 */ SyscallDesc("nfsservctl", unimplementedFunc), + /* 343 */ SyscallDesc("setresuid", unimplementedFunc), + /* 344 */ SyscallDesc("getresuid", unimplementedFunc), + /* 345 */ SyscallDesc("pciconfig_read", unimplementedFunc), + /* 346 */ SyscallDesc("pciconfig_write", unimplementedFunc), + /* 347 */ SyscallDesc("query_module", unimplementedFunc), + /* 348 */ SyscallDesc("prctl", unimplementedFunc), + /* 349 */ SyscallDesc("pread", unimplementedFunc), + /* 350 */ SyscallDesc("pwrite", unimplementedFunc), + /* 351 */ SyscallDesc("rt_sigreturn", unimplementedFunc), + /* 352 */ SyscallDesc("rt_sigaction", ignoreFunc), + /* 353 */ SyscallDesc("rt_sigprocmask", unimplementedFunc), + /* 354 */ SyscallDesc("rt_sigpending", unimplementedFunc), + /* 355 */ SyscallDesc("rt_sigtimedwait", unimplementedFunc), + /* 356 */ SyscallDesc("rt_sigqueueinfo", unimplementedFunc), + /* 357 */ SyscallDesc("rt_sigsuspend", unimplementedFunc), + /* 358 */ SyscallDesc("select", unimplementedFunc), + /* 359 */ SyscallDesc("gettimeofday", gettimeofdayFunc), + /* 360 */ SyscallDesc("settimeofday", unimplementedFunc), + /* 361 */ SyscallDesc("getitimer", unimplementedFunc), + /* 362 */ SyscallDesc("setitimer", unimplementedFunc), + /* 363 */ SyscallDesc("utimes", utimesFunc), + /* 364 */ SyscallDesc("getrusage", getrusageFunc), + /* 365 */ SyscallDesc("wait4", unimplementedFunc), + /* 366 */ SyscallDesc("adjtimex", unimplementedFunc), + /* 367 */ SyscallDesc("getcwd", unimplementedFunc), + /* 368 */ SyscallDesc("capget", unimplementedFunc), + /* 369 */ SyscallDesc("capset", unimplementedFunc), + /* 370 */ SyscallDesc("sendfile", unimplementedFunc), + /* 371 */ SyscallDesc("setresgid", unimplementedFunc), + /* 372 */ SyscallDesc("getresgid", unimplementedFunc), + /* 373 */ SyscallDesc("dipc", unimplementedFunc), + /* 374 */ SyscallDesc("pivot_root", unimplementedFunc), + /* 375 */ SyscallDesc("mincore", unimplementedFunc), + /* 376 */ SyscallDesc("pciconfig_iobase", unimplementedFunc), + /* 377 */ SyscallDesc("getdents64", unimplementedFunc), + /* 378 */ SyscallDesc("gettid", unimplementedFunc), + /* 379 */ SyscallDesc("readahead", unimplementedFunc), + /* 380 */ SyscallDesc("security", unimplementedFunc), + /* 381 */ SyscallDesc("tkill", unimplementedFunc), + /* 382 */ SyscallDesc("setxattr", unimplementedFunc), + /* 383 */ SyscallDesc("lsetxattr", unimplementedFunc), + /* 384 */ SyscallDesc("fsetxattr", unimplementedFunc), + /* 385 */ SyscallDesc("getxattr", unimplementedFunc), + /* 386 */ SyscallDesc("lgetxattr", unimplementedFunc), + /* 387 */ SyscallDesc("fgetxattr", unimplementedFunc), + /* 388 */ SyscallDesc("listxattr", unimplementedFunc), + /* 389 */ SyscallDesc("llistxattr", unimplementedFunc), + /* 390 */ SyscallDesc("flistxattr", unimplementedFunc), + /* 391 */ SyscallDesc("removexattr", unimplementedFunc), + /* 392 */ SyscallDesc("lremovexattr", unimplementedFunc), + /* 393 */ SyscallDesc("fremovexattr", unimplementedFunc), + /* 394 */ SyscallDesc("futex", unimplementedFunc), + /* 395 */ SyscallDesc("sched_setaffinity", unimplementedFunc), + /* 396 */ SyscallDesc("sched_getaffinity", unimplementedFunc), + /* 397 */ SyscallDesc("tuxcall", unimplementedFunc), + /* 398 */ SyscallDesc("io_setup", unimplementedFunc), + /* 399 */ SyscallDesc("io_destroy", unimplementedFunc), + /* 400 */ SyscallDesc("io_getevents", unimplementedFunc), + /* 401 */ SyscallDesc("io_submit", unimplementedFunc), + /* 402 */ SyscallDesc("io_cancel", unimplementedFunc), + /* 403 */ SyscallDesc("unknown #403", unimplementedFunc), + /* 404 */ SyscallDesc("unknown #404", unimplementedFunc), + /* 405 */ SyscallDesc("exit_group", exitFunc), // exit all threads... + /* 406 */ SyscallDesc("lookup_dcookie", unimplementedFunc), + /* 407 */ SyscallDesc("sys_epoll_create", unimplementedFunc), + /* 408 */ SyscallDesc("sys_epoll_ctl", unimplementedFunc), + /* 409 */ SyscallDesc("sys_epoll_wait", unimplementedFunc), + /* 410 */ SyscallDesc("remap_file_pages", unimplementedFunc), + /* 411 */ SyscallDesc("set_tid_address", unimplementedFunc), + /* 412 */ SyscallDesc("restart_syscall", unimplementedFunc), + /* 413 */ SyscallDesc("fadvise64", unimplementedFunc), + /* 414 */ SyscallDesc("timer_create", unimplementedFunc), + /* 415 */ SyscallDesc("timer_settime", unimplementedFunc), + /* 416 */ SyscallDesc("timer_gettime", unimplementedFunc), + /* 417 */ SyscallDesc("timer_getoverrun", unimplementedFunc), + /* 418 */ SyscallDesc("timer_delete", unimplementedFunc), + /* 419 */ SyscallDesc("clock_settime", unimplementedFunc), + /* 420 */ SyscallDesc("clock_gettime", unimplementedFunc), + /* 421 */ SyscallDesc("clock_getres", unimplementedFunc), + /* 422 */ SyscallDesc("clock_nanosleep", unimplementedFunc), + /* 423 */ SyscallDesc("semtimedop", unimplementedFunc), + /* 424 */ SyscallDesc("tgkill", unimplementedFunc), + /* 425 */ SyscallDesc("stat64", unimplementedFunc), + /* 426 */ SyscallDesc("lstat64", lstat64Func), + /* 427 */ SyscallDesc("fstat64", fstat64Func), + /* 428 */ SyscallDesc("vserver", unimplementedFunc), + /* 429 */ SyscallDesc("mbind", unimplementedFunc), + /* 430 */ SyscallDesc("get_mempolicy", unimplementedFunc), + /* 431 */ SyscallDesc("set_mempolicy", unimplementedFunc), + /* 432 */ SyscallDesc("mq_open", unimplementedFunc), + /* 433 */ SyscallDesc("mq_unlink", unimplementedFunc), + /* 434 */ SyscallDesc("mq_timedsend", unimplementedFunc), + /* 435 */ SyscallDesc("mq_timedreceive", unimplementedFunc), + /* 436 */ SyscallDesc("mq_notify", unimplementedFunc), + /* 437 */ SyscallDesc("mq_getsetattr", unimplementedFunc), + /* 438 */ SyscallDesc("waitid", unimplementedFunc), + /* 439 */ SyscallDesc("add_key", unimplementedFunc), + /* 440 */ SyscallDesc("request_key", unimplementedFunc), + /* 441 */ SyscallDesc("keyctl", unimplementedFunc) +}; + +MipsLinuxProcess::MipsLinuxProcess(const std::string &name, + ObjectFile *objFile, + int stdin_fd, + int stdout_fd, + int stderr_fd, + std::vector &argv, + std::vector &envp) + : LiveProcess(name, objFile, stdin_fd, stdout_fd, stderr_fd, argv, envp), + Num_Syscall_Descs(sizeof(syscallDescs) / sizeof(SyscallDesc)) +{ + init_regs->intRegFile[0] = 0; +} + + + +SyscallDesc* +MipsLinuxProcess::getDesc(int callnum) +{ + if (callnum < 0 || callnum > Num_Syscall_Descs) + return NULL; + return &syscallDescs[callnum]; +} diff --git a/arch/mips/linux_process.hh b/arch/mips/linux_process.hh new file mode 100644 index 000000000..5408a6c44 --- /dev/null +++ b/arch/mips/linux_process.hh @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2003-2004 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_LINUX_PROCESS_HH__ +#define __MIPS_LINUX_PROCESS_HH__ + +#include "sim/process.hh" + + +/// A process with emulated Mips/Linux syscalls. +class MipsLinuxProcess : public LiveProcess +{ + public: + /// Constructor. + MipsLinuxProcess(const std::string &name, + ObjectFile *objFile, + int stdin_fd, int stdout_fd, int stderr_fd, + std::vector &argv, + std::vector &envp); + + virtual SyscallDesc* getDesc(int callnum); + + /// The target system's hostname. + static const char *hostname; + + /// Array of syscall descriptors, indexed by call number. + static SyscallDesc syscallDescs[]; + + const int Num_Syscall_Descs; +}; + + +#endif // __MIPS_LINUX_PROCESS_HH__ From b37f5da98f59700f2646ec25b9496d9ab7a7b417 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 22 Feb 2006 20:52:03 -0500 Subject: [PATCH 085/180] Cleaned up the mapping of isa_parser.py inputs to outputs. --HG-- extra : convert_revision : a8431a67001b2916eb8d0548f1f34e1c948bb356 --- SConscript | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/SConscript b/SConscript index b8db3ff71..ee0dd03e0 100644 --- a/SConscript +++ b/SConscript @@ -426,18 +426,13 @@ env.Command(Split('base/traceflags.hh base/traceflags.cc'), # several files are generated from arch/$TARGET_ISA/isa_desc. env.Command(Split(''' - arch/%s/decoder.cc - arch/%s/decoder.hh - arch/%s/alpha_o3_exec.cc - arch/%s/fast_cpu_exec.cc - arch/%s/simple_cpu_exec.cc - arch/%s/full_cpu_exec.cc''' % - (env['TARGET_ISA'], - env['TARGET_ISA'], - env['TARGET_ISA'], - env['TARGET_ISA'], - env['TARGET_ISA'], - env['TARGET_ISA'])), + arch/%(targetisa)s/decoder.cc + arch/%(targetisa)s/decoder.hh + arch/%(targetisa)s/alpha_o3_exec.cc + arch/%(targetisa)s/fast_cpu_exec.cc + arch/%(targetisa)s/simple_cpu_exec.cc + arch/%(targetisa)s/full_cpu_exec.cc''' % + {'targetisa': env['TARGET_ISA']}), Split(''' arch/%s/isa/main.isa arch/isa_parser.py''' % From 9a4c0f12ef63a701f9ce0918e604bcdcc679fe32 Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Wed, 22 Feb 2006 21:11:45 -0500 Subject: [PATCH 086/180] Clean excess comments out of SConscripts. SConscript: arch/alpha/SConscript: Clean out excess comments. --HG-- extra : convert_revision : 7aae68d36f9fce5f236d117d803b5e3cd4a3769d --- SConscript | 29 --- arch/alpha/SConscript | 405 ------------------------------------------ 2 files changed, 434 deletions(-) diff --git a/SConscript b/SConscript index b8db3ff71..d2f6b0497 100644 --- a/SConscript +++ b/SConscript @@ -223,14 +223,6 @@ base_sources = Split(''' sim/stat_control.cc sim/trace_context.cc ''') -# These are now included by the architecture specific SConscript -# arch/alpha/decoder.cc -# arch/alpha/alpha_o3_exec.cc -# arch/alpha/fast_cpu_exec.cc -# arch/alpha/simple_cpu_exec.cc -# arch/alpha/full_cpu_exec.cc -# arch/alpha/faults.cc -# arch/alpha/isa_traits.cc # MySql sources mysql_sources = Split(''' @@ -296,15 +288,6 @@ full_system_sources = Split(''' sim/pseudo_inst.cc ''') -# These are now included by the architecture specific SConscript -# arch/alpha/alpha_memory.cc -# arch/alpha/arguments.cc -# arch/alpha/ev5.cc -# arch/alpha/osfpal.cc -# arch/alpha/pseudo_inst.cc -# arch/alpha/stacktrace.cc -# arch/alpha/vtophys.cc - # turbolaser encumbered sources turbolaser_sources = Split(''' encumbered/dev/dma.cc @@ -337,11 +320,6 @@ syscall_emulation_sources = Split(''' sim/syscall_emul.cc ''') -# These are now included by the architecture specific SConscript -# arch/alpha/alpha_common_syscall_emul.cc -# arch/alpha/alpha_linux_process.cc -# arch/alpha/alpha_tru64_process.cc - targetarch_files = Split(''' alpha_linux_process.hh alpha_memory.hh @@ -354,13 +332,6 @@ targetarch_files = Split(''' stacktrace.hh vtophys.hh ''') -# pseudo_inst.hh -# isa_traits.hh -# osfpal.hh -# byte_swap.hh -# alpha_common_syscall_emul.hh -# vptr.hh -# isa_fullsys_traits.hh # Set up bridging headers to the architecture specific versions for f in targetarch_files: diff --git a/arch/alpha/SConscript b/arch/alpha/SConscript index 8bf408c06..a5ae77dac 100644 --- a/arch/alpha/SConscript +++ b/arch/alpha/SConscript @@ -53,191 +53,6 @@ arch_base_sources = Split(''' arch/alpha/isa_traits.cc ''') -# base/circlebuf.cc -# base/copyright.cc -# base/cprintf.cc -# base/embedfile.cc -# base/fast_alloc.cc -# base/fifo_buffer.cc -# base/hostinfo.cc -# base/hybrid_pred.cc -# base/inifile.cc -# base/intmath.cc -# base/match.cc -# base/misc.cc -# base/output.cc -# base/pollevent.cc -# base/range.cc -# base/random.cc -# base/sat_counter.cc -# base/socket.cc -# base/statistics.cc -# base/str.cc -# base/time.cc -# base/trace.cc -# base/traceflags.cc -# base/userinfo.cc -# base/compression/lzss_compression.cc -# base/loader/aout_object.cc -# base/loader/ecoff_object.cc -# base/loader/elf_object.cc -# base/loader/object_file.cc -# base/loader/symtab.cc -# base/stats/events.cc -# base/stats/statdb.cc -# base/stats/visit.cc -# base/stats/text.cc -# -# cpu/base.cc -# cpu/base_dyn_inst.cc -# cpu/exec_context.cc -# cpu/exetrace.cc -# cpu/pc_event.cc -# cpu/static_inst.cc -# cpu/o3/2bit_local_pred.cc -# cpu/o3/alpha_dyn_inst.cc -# cpu/o3/alpha_cpu.cc -# cpu/o3/alpha_cpu_builder.cc -# cpu/o3/bpred_unit.cc -# cpu/o3/btb.cc -# cpu/o3/commit.cc -# cpu/o3/decode.cc -# cpu/o3/fetch.cc -# cpu/o3/free_list.cc -# cpu/o3/cpu.cc -# cpu/o3/iew.cc -# cpu/o3/inst_queue.cc -# cpu/o3/ldstq.cc -# cpu/o3/mem_dep_unit.cc -# cpu/o3/ras.cc -# cpu/o3/rename.cc -# cpu/o3/rename_map.cc -# cpu/o3/rob.cc -# cpu/o3/sat_counter.cc -# cpu/o3/store_set.cc -# cpu/o3/tournament_pred.cc -# cpu/fast/cpu.cc -# cpu/sampler/sampler.cc -# cpu/simple/cpu.cc -# cpu/trace/reader/mem_trace_reader.cc -# cpu/trace/reader/ibm_reader.cc -# cpu/trace/reader/itx_reader.cc -# cpu/trace/reader/m5_reader.cc -# cpu/trace/opt_cpu.cc -# cpu/trace/trace_cpu.cc -# -# encumbered/cpu/full/bpred.cc -# encumbered/cpu/full/commit.cc -# encumbered/cpu/full/cpu.cc -# encumbered/cpu/full/create_vector.cc -# encumbered/cpu/full/cv_spec_state.cc -# encumbered/cpu/full/dd_queue.cc -# encumbered/cpu/full/dep_link.cc -# encumbered/cpu/full/dispatch.cc -# encumbered/cpu/full/dyn_inst.cc -# encumbered/cpu/full/execute.cc -# encumbered/cpu/full/fetch.cc -# encumbered/cpu/full/floss_reasons.cc -# encumbered/cpu/full/fu_pool.cc -# encumbered/cpu/full/inst_fifo.cc -# encumbered/cpu/full/instpipe.cc -# encumbered/cpu/full/issue.cc -# encumbered/cpu/full/ls_queue.cc -# encumbered/cpu/full/machine_queue.cc -# encumbered/cpu/full/pipetrace.cc -# encumbered/cpu/full/readyq.cc -# encumbered/cpu/full/reg_info.cc -# encumbered/cpu/full/rob_station.cc -# encumbered/cpu/full/spec_memory.cc -# encumbered/cpu/full/spec_state.cc -# encumbered/cpu/full/storebuffer.cc -# encumbered/cpu/full/writeback.cc -# encumbered/cpu/full/iq/iq_station.cc -# encumbered/cpu/full/iq/iqueue.cc -# encumbered/cpu/full/iq/segmented/chain_info.cc -# encumbered/cpu/full/iq/segmented/chain_wire.cc -# encumbered/cpu/full/iq/segmented/iq_seg.cc -# encumbered/cpu/full/iq/segmented/iq_segmented.cc -# encumbered/cpu/full/iq/segmented/seg_chain.cc -# encumbered/cpu/full/iq/seznec/iq_seznec.cc -# encumbered/cpu/full/iq/standard/iq_standard.cc -# encumbered/mem/functional/main.cc -# -# mem/base_hier.cc -# mem/base_mem.cc -# mem/hier_params.cc -# mem/mem_cmd.cc -# mem/mem_debug.cc -# mem/mem_req.cc -# mem/memory_interface.cc -# mem/bus/base_interface.cc -# mem/bus/bus.cc -# mem/bus/bus_bridge.cc -# mem/bus/bus_bridge_master.cc -# mem/bus/bus_bridge_slave.cc -# mem/bus/bus_interface.cc -# mem/bus/dma_bus_interface.cc -# mem/bus/dma_interface.cc -# mem/bus/master_interface.cc -# mem/bus/slave_interface.cc -# mem/cache/base_cache.cc -# mem/cache/cache.cc -# mem/cache/cache_builder.cc -# mem/cache/coherence/coherence_protocol.cc -# mem/cache/coherence/uni_coherence.cc -# mem/cache/miss/blocking_buffer.cc -# mem/cache/miss/miss_queue.cc -# mem/cache/miss/mshr.cc -# mem/cache/miss/mshr_queue.cc -# mem/cache/prefetch/base_prefetcher.cc -# mem/cache/prefetch/prefetcher.cc -# mem/cache/prefetch/tagged_prefetcher.cc -# mem/cache/tags/base_tags.cc -# mem/cache/tags/cache_tags.cc -# mem/cache/tags/fa_lru.cc -# mem/cache/tags/iic.cc -# mem/cache/tags/lru.cc -# mem/cache/tags/repl/gen.cc -# mem/cache/tags/repl/repl.cc -# mem/cache/tags/split.cc -# mem/cache/tags/split_lru.cc -# mem/cache/tags/split_lifo.cc -# mem/functional/functional.cc -# mem/timing/base_memory.cc -# mem/timing/memory_builder.cc -# mem/timing/simple_mem_bank.cc -# mem/trace/itx_writer.cc -# mem/trace/mem_trace_writer.cc -# mem/trace/m5_writer.cc -# -# python/pyconfig.cc -# python/embedded_py.cc -# -# sim/builder.cc -# sim/configfile.cc -# sim/debug.cc -# sim/eventq.cc -# sim/main.cc -# sim/param.cc -# sim/profile.cc -# sim/root.cc -# sim/serialize.cc -# sim/sim_events.cc -# sim/sim_exit.cc -# sim/sim_object.cc -# sim/startup.cc -# sim/stat_context.cc -# sim/stat_control.cc -# sim/trace_context.cc -# ''') - -# MySql sources -arch_mysql_sources = Split(''' - ''') -# base/mysql.cc -# base/stats/mysql.cc -# ''') - # Full-system sources arch_full_system_sources = Split(''' arch/alpha/alpha_memory.cc @@ -248,81 +63,6 @@ arch_full_system_sources = Split(''' arch/alpha/vtophys.cc ''') -# base/crc.cc -# base/inet.cc -# base/remote_gdb.cc -# -# cpu/intr_control.cc -# cpu/profile.cc -# -# dev/alpha_console.cc -# dev/baddev.cc -# dev/simconsole.cc -# dev/disk_image.cc -# dev/etherbus.cc -# dev/etherdump.cc -# dev/etherint.cc -# dev/etherlink.cc -# dev/etherpkt.cc -# dev/ethertap.cc -# dev/ide_ctrl.cc -# dev/ide_disk.cc -# dev/io_device.cc -# dev/ns_gige.cc -# dev/pciconfigall.cc -# dev/pcidev.cc -# dev/pcifake.cc -# dev/pktfifo.cc -# dev/platform.cc -# dev/sinic.cc -# dev/simple_disk.cc -# dev/tsunami.cc -# dev/tsunami_cchip.cc -# dev/isa_fake.cc -# dev/tsunami_io.cc -# dev/tsunami_pchip.cc -# dev/uart.cc -# dev/uart8250.cc -# -# kern/kernel_binning.cc -# kern/kernel_stats.cc -# kern/system_events.cc -# kern/freebsd/freebsd_system.cc -# kern/linux/linux_syscalls.cc -# kern/linux/linux_system.cc -# kern/linux/printk.cc -# kern/tru64/dump_mbuf.cc -# kern/tru64/printf.cc -# kern/tru64/tru64_events.cc -# kern/tru64/tru64_syscalls.cc -# kern/tru64/tru64_system.cc -# -# mem/functional/memory_control.cc -# mem/functional/physical.cc -# -# sim/system.cc -# ''') - -# turbolaser encumbered sources -arch_turbolaser_sources = Split(''' - ''') -# encumbered/dev/dma.cc -# encumbered/dev/etherdev.cc -# encumbered/dev/scsi.cc -# encumbered/dev/scsi_ctrl.cc -# encumbered/dev/scsi_disk.cc -# encumbered/dev/scsi_none.cc -# encumbered/dev/tlaser_clock.cc -# encumbered/dev/tlaser_ipi.cc -# encumbered/dev/tlaser_mbox.cc -# encumbered/dev/tlaser_mc146818.cc -# encumbered/dev/tlaser_node.cc -# encumbered/dev/tlaser_pcia.cc -# encumbered/dev/tlaser_pcidev.cc -# encumbered/dev/tlaser_serial.cc -# encumbered/dev/turbolaser.cc -# encumbered/dev/uart8530.cc -# ''') # Syscall emulation (non-full-system) sources arch_syscall_emulation_sources = Split(''' @@ -330,158 +70,13 @@ arch_syscall_emulation_sources = Split(''' arch/alpha/alpha_linux_process.cc arch/alpha/alpha_tru64_process.cc ''') -# cpu/memtest/memtest.cc -# encumbered/eio/eio.cc -# encumbered/eio/exolex.cc -# encumbered/eio/libexo.cc -# sim/process.cc -# sim/syscall_emul.cc -# ''') - -#targetarch_files = Split(''' -# alpha_common_syscall_emul.hh -# alpha_linux_process.hh -# alpha_memory.hh -# alpha_tru64_process.hh -# aout_machdep.h -# arguments.hh -# byte_swap.hh -# ecoff_machdep.h -# ev5.hh -# faults.hh -# isa_fullsys_traits.hh -# isa_traits.hh -# osfpal.hh -# pseudo_inst.hh -# stacktrace.hh -# vptr.hh -# vtophys.hh -# ''') - -#for f in targetarch_files: -# env.Command('targetarch/' + f, 'arch/alpha/' + f, -# '''echo '#include "arch/alpha/%s"' > $TARGET''' % f) - # Set up complete list of sources based on configuration. sources = arch_base_sources if env['FULL_SYSTEM']: sources += arch_full_system_sources - if env['ALPHA_TLASER']: - sources += arch_turbolaser_sources else: sources += arch_syscall_emulation_sources -if env['USE_MYSQL']: - sources += arch_mysql_sources - -for opt in env.ExportOptions: - env.ConfigFile(opt) - -################################################### -# -# Special build rules. -# -################################################### - -# base/traceflags.{cc,hh} are generated from base/traceflags.py. -# $TARGET.base will expand to "/base/traceflags". -# env.Command(Split('base/traceflags.hh base/traceflags.cc'), -# 'base/traceflags.py', -# 'python $SOURCE $TARGET.base') - -# several files are generated from arch/$TARGET_ISA/isa_desc. -#env.Command(Split('''decoder.cc -# decoder.hh -# alpha_o3_exec.cc -# fast_cpu_exec.cc -# simple_cpu_exec.cc -# full_cpu_exec.cc'''), -# Split('''isa_desc -# ../isa_parser.py'''), -# '$SRCDIR/arch/isa_parser.py $SOURCE $TARGET.dir arch/alpha') - - -# libelf build is described in its own SConscript file. -# SConscript-local is the per-config build, which just copies some -# header files into a place where they can be found. -# SConscript('libelf/SConscript-local', exports = 'env', duplicate=0) -# SConscript('python/SConscript', exports = ['env'], duplicate=0) - -# This function adds the specified sources to the given build -# environment, and returns a list of all the corresponding SCons -# Object nodes (including an extra one for date.cc). We explicitly -# add the Object nodes so we can set up special dependencies for -# date.cc. -# def make_objs(sources, env): -# objs = [env.Object(s) for s in sources] -# # make date.cc depend on all other objects so it always gets -# # recompiled whenever anything else does -# date_obj = env.Object('base/date.cc') -# base/traceflags.{cc,hh} are generated from base/traceflags.py. -# $TARGET.base will expand to "/base/traceflags". -# env.Command(Split('base/traceflags.hh base/traceflags.cc'), -# 'base/traceflags.py', -# 'python $SOURCE $TARGET.base') -# -# Split('''arch/alpha/isa_desc -# arch/isa_parser.py'''), -# env.Depends(date_obj, objs) -# objs.append(date_obj) -# return objs - -################################################### -# -# Define binaries. Each different build type (debug, opt, etc.) gets -# a slightly different build environment. -# -################################################### - -# Include file paths are rooted in this directory. SCons will -# automatically expand '.' to refer to both the source directory and -# the corresponding build directory to pick up generated include -# files. -# env.Append(CPPPATH='.') - -# Debug binary -# debugEnv = env.Copy(OBJSUFFIX='.do') -# debugEnv.Label = 'debug' -# debugEnv.Append(CCFLAGS=Split('-g -gstabs+ -O0')) -# debugEnv.Append(CPPDEFINES='DEBUG') -# tlist = debugEnv.Program(target = 'm5.debug', -# source = make_objs(sources, debugEnv)) -# debugEnv.M5Binary = tlist[0] - -# Optimized binary -# optEnv = env.Copy() -# optEnv.Label = 'opt' -# optEnv.Append(CCFLAGS=Split('-g -O5')) -# tlist = optEnv.Program(target = 'm5.opt', -# source = make_objs(sources, optEnv)) -# optEnv.M5Binary = tlist[0] - -# "Fast" binary -# fastEnv = env.Copy(OBJSUFFIX='.fo') -# fastEnv.Label = 'fast' -# fastEnv.Append(CCFLAGS=Split('-O5')) -# fastEnv.Append(CPPDEFINES='NDEBUG') -# fastEnv.Program(target = 'm5.fast.unstripped', -# source = make_objs(sources, fastEnv)) -# tlist = fastEnv.Command(target = 'm5.fast', -# source = 'm5.fast.unstripped', -# action = 'strip $SOURCE -o $TARGET') -# fastEnv.M5Binary = tlist[0] - -# Profiled binary -# profEnv = env.Copy(OBJSUFFIX='.po') -# profEnv.Label = 'prof' -# profEnv.Append(CCFLAGS=Split('-O5 -g -pg'), LINKFLAGS='-pg') -# tlist = profEnv.Program(target = 'm5.prof', -# source = make_objs(sources, profEnv)) -# profEnv.M5Binary = tlist[0] -# -# envList = [debugEnv, optEnv, fastEnv, profEnv] -# -# Return('envList') Return('sources') From f67a99d1c96fab60e16a8739803de27a3fba6420 Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Wed, 22 Feb 2006 22:22:06 -0500 Subject: [PATCH 087/180] Auto-generate arch/foo.hh "switch headers" in scons. SConscript: Include new arch/SConscript file. arch/isa_specific.hh: Get rid of unnecessary ISA_INCLUDE() macro and other things that were used only for that purpose. build/SConstruct: Move list of ISAs to env var ALL_ISA_LIST. --HG-- extra : convert_revision : 612c7ee4279d57209662be88dc577d80fdbd692c --- SConscript | 2 ++ arch/SConscript | 74 ++++++++++++++++++++++++++++++++++++++++++++ arch/isa_specific.hh | 14 --------- build/SConstruct | 5 ++- 4 files changed, 80 insertions(+), 15 deletions(-) create mode 100644 arch/SConscript diff --git a/SConscript b/SConscript index d2f6b0497..49f06af7d 100644 --- a/SConscript +++ b/SConscript @@ -346,6 +346,8 @@ arch_source = SConscript('arch/%s/SConscript' % env['TARGET_ISA'], # Add a flag defining what THE_ISA should be for all compilation env.Append(CPPDEFINES=[('THE_ISA','%s_ISA' % env['TARGET_ISA'].upper())]) +SConscript('arch/SConscript', exports = 'env', duplicate = False) + # Set up complete list of sources based on configuration. sources = base_sources + arch_source diff --git a/arch/SConscript b/arch/SConscript new file mode 100644 index 000000000..2d8e34b7b --- /dev/null +++ b/arch/SConscript @@ -0,0 +1,74 @@ +# -*- mode:python -*- + +# Copyright (c) 2006 The Regents of The University of Michigan +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import os.path + +# Import build environment variable from SConstruct. +Import('env') + +# +# ISA "switch header" generation. +# +# Auto-generate arch headers that include the right ISA-specific +# header based on the setting of THE_ISA preprocessor variable. + +# List of headers to generate +isa_switch_hdrs = Split(''' + isa_traits.hh + ''') + +# Generate the header. target[0] is the full path of the output +# header to generate. 'source' is a dummy variable, since we get the +# list of ISAs from env['ALL_ISA_LIST']. +def gen_switch_hdr(target, source, env): + fname = str(target[0]) + basename = os.path.basename(fname) + f = open(fname, 'w') + f.write('#include "arch/isa_specific.hh"\n') + cond = '#if' + for isa in env['ALL_ISA_LIST']: + f.write('%s THE_ISA == %s_ISA\n#include "arch/%s/%s"\n' + % (cond, isa.upper(), isa, basename)) + cond = '#elif' + f.write('#else\n#error "THE_ISA not set"\n#endif\n') + f.close() + return 0 + +# String to print when generating header +def gen_switch_hdr_string(target, source, env): + return "Generating ISA switch header " + str(target[0]) + +# Build SCons Action object. 'varlist' specifies env vars that this +# action depdnds on; when env['ALL_ISA_LIST'] changes these actions +# should get re-executed. +switch_hdr_action = Action(gen_switch_hdr, gen_switch_hdr_string, + varlist=['ALL_ISA_LIST']) + +# Instantiate actions for each header +for hdr in isa_switch_hdrs: + env.Command(hdr, [], switch_hdr_action) diff --git a/arch/isa_specific.hh b/arch/isa_specific.hh index e11e6c292..44f8e9d64 100644 --- a/arch/isa_specific.hh +++ b/arch/isa_specific.hh @@ -50,27 +50,13 @@ //These tell the preprocessor where to find the files of a particular //ISA, and set the "TheISA" macro for use elsewhere. #if THE_ISA == ALPHA_ISA - #define ISA_PATH arch/alpha/ #define TheISA AlphaISA #elif THE_ISA == SPARC_ISA - #define ISA_PATH arch/sparc/ #define TheISA SparcISA #elif THE_ISA == MIPS_ISA - #define ISA_PATH arch/mips/ #define TheISA MipsISA #else #error "THE_ISA not set" #endif -//The following is some preprocessor voodoo to allow redirectable includes -//The end result is the ISA_INCLUDE() macro which is used inside stub -//include files in arch and which redirect to the isa in use. -#define STRINGIFY(token) #token -#define EXPAND(token) token -#define STICK_TOGETHER(firstpart, secondpart) \ - EXPAND(firstpart)EXPAND(secondpart) -#define EXPAND_AND_STRINGIFY(pathAndFile) \ - STRINGIFY(pathAndFile) -#define ISA_INCLUDE(filename) \ - EXPAND_AND_STRINGIFY(STICK_TOGETHER(ISA_PATH, filename)) #endif diff --git a/build/SConstruct b/build/SConstruct index c552e5639..38d404846 100644 --- a/build/SConstruct +++ b/build/SConstruct @@ -218,12 +218,15 @@ if have_mysql: env = conf.Finish() +# Define the universe of supported ISAs +env['ALL_ISA_LIST'] = ['alpha', 'sparc', 'mips'] + # Sticky options get saved in the options file so they persist from # one invocation to the next (unless overridden, in which case the new # value becomes sticky). sticky_opts = Options(args=ARGUMENTS) sticky_opts.AddOptions( - EnumOption('TARGET_ISA', 'Target ISA', 'alpha', ('alpha', 'sparc', 'mips')), + EnumOption('TARGET_ISA', 'Target ISA', 'alpha', env['ALL_ISA_LIST']), BoolOption('FULL_SYSTEM', 'Full-system support', False), BoolOption('ALPHA_TLASER', 'Model Alpha TurboLaser platform (vs. Tsunami)', False), From 35094fb0fe7113be4d2faa88beb505d3e9155a77 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Thu, 23 Feb 2006 00:20:32 -0500 Subject: [PATCH 089/180] make it possible to add filters for job names so that parts of the full crossproduct of jobs can be ignored. --HG-- extra : convert_revision : c44b3daea0cf4b487b1d99eae92da16573b15930 --- util/pbs/jobfile.py | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/util/pbs/jobfile.py b/util/pbs/jobfile.py index d36b5ee6d..5cdd343de 100644 --- a/util/pbs/jobfile.py +++ b/util/pbs/jobfile.py @@ -1,4 +1,4 @@ -# Copyright (c) 2005 The Regents of The University of Michigan +# Copyright (c) 2005-2006 The Regents of The University of Michigan # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -356,6 +356,8 @@ class Configuration(Data): def __init__(self, name, desc, **kwargs): super(Configuration, self).__init__(name, desc, **kwargs) self._groups = [] + self._posfilters = [] + self._negfilters = [] def group(self, name, desc, **kwargs): grp = Group(name, desc, **kwargs) @@ -402,13 +404,39 @@ class Configuration(Data): if checkpoint: yield options + def addfilter(self, filt, pos=True): + import re + filt = re.compile(filt) + if pos: + self._posfilters.append(filt) + else: + self._negfilters.append(filt) + + def jobfilter(self, job): + for filt in self._negfilters: + if filt.match(job.name): + return False + + if not self._posfilters: + return True + + for filt in self._posfilters: + if filt.match(job.name): + return True + + return False + def checkpoints(self, groups = None): for options in self.options(groups, True): - yield Job(options) + job = Job(options) + if self.jobfilter(job): + yield job def jobs(self, groups = None): for options in self.options(groups, False): - yield Job(options) + job = Job(options) + if self.jobfilter(job): + yield job def alljobs(self, groups = None): for options in self.options(groups, True): From f462266b30abcad6b69c8b29fb1d856c04d6ac1f Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Thu, 23 Feb 2006 00:21:35 -0500 Subject: [PATCH 090/180] don't add an empty suboption description --HG-- extra : convert_revision : 594744c3d438aed08a23db376959930071b2c368 --- util/pbs/jobfile.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/util/pbs/jobfile.py b/util/pbs/jobfile.py index 5cdd343de..fd19b3bf5 100644 --- a/util/pbs/jobfile.py +++ b/util/pbs/jobfile.py @@ -277,10 +277,11 @@ class Option(Data): return name if attr == 'desc': - desc = self.__dict__[attr] - if self._suboption is not None: - desc = '%s, %s' % (desc, self._suboption.desc) - return desc + desc = [ self.__dict__[attr] ] + if self._suboption is not None and self._suboption.desc: + desc.append(self._suboption.desc) + return ', '.join(desc) + return super(Option, self).__getattribute__(attr) From c13ea339dccf54261f753424ff9eb516d97b34a1 Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Thu, 23 Feb 2006 08:16:59 -0500 Subject: [PATCH 091/180] Add pipe() syscall to Alpha Linux emulation. arch/alpha/alpha_linux_process.cc: Add pipeFunc. --HG-- extra : convert_revision : c094d2dff993d5e60bc43b7cd4b9586c15c634a3 --- arch/alpha/alpha_linux_process.cc | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/arch/alpha/alpha_linux_process.cc b/arch/alpha/alpha_linux_process.cc index 783b189cc..16ebcca7b 100644 --- a/arch/alpha/alpha_linux_process.cc +++ b/arch/alpha/alpha_linux_process.cc @@ -41,6 +41,31 @@ using namespace std; using namespace AlphaISA; +/// Target pipe() handler. Even though this is a generic Posix call, +/// the Alpha return convention is funky, so that makes it +/// Alpha-specific. +SyscallReturn +pipeFunc(SyscallDesc *desc, int callnum, Process *process, + ExecContext *xc) +{ + int fds[2], sim_fds[2]; + int pipe_retval = pipe(fds); + + if (pipe_retval < 0) { + // error + return pipe_retval; + } + + sim_fds[0] = process->alloc_fd(fds[0]); + sim_fds[1] = process->alloc_fd(fds[1]); + + // Alpha Linux convention for pipe() is that fd[0] is returned as + // the return value of the function, and fd[1] is returned in r20. + xc->regs.intRegFile[20] = sim_fds[1]; + return sim_fds[0]; +} + + /// Target uname() handler. static SyscallReturn unameFunc(SyscallDesc *desc, int callnum, Process *process, @@ -159,7 +184,7 @@ SyscallDesc AlphaLinuxProcess::syscallDescs[] = { /* 39 */ SyscallDesc("setpgid", unimplementedFunc), /* 40 */ SyscallDesc("osf_old_lstat", unimplementedFunc), /* 41 */ SyscallDesc("dup", unimplementedFunc), - /* 42 */ SyscallDesc("pipe", unimplementedFunc), + /* 42 */ SyscallDesc("pipe", pipeFunc), /* 43 */ SyscallDesc("osf_set_program_attributes", unimplementedFunc), /* 44 */ SyscallDesc("osf_profil", unimplementedFunc), /* 45 */ SyscallDesc("open", openFunc), From 99484cfae81f3f01ccdfcd273ddc2bdb41e6456b Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Thu, 23 Feb 2006 14:31:15 -0500 Subject: [PATCH 093/180] Create a Builder object for .isa files in arch/SConscript. Start using SCons File objects to avoid fixed paths in subordinate SConscripts. SConscript: Push isa_parser stuff (including .isa scanner) down into arch/SConscript. arch/SConscript: Create a Builder object for .isa files, including existing scanner. Return file objects generated by isa-specific SConscript back up to parent. arch/alpha/SConscript: arch/mips/SConscript: arch/sparc/SConscript: Convert sources to scons File objects, so file names can be specified relative to the current directory. Invoke new builder for isa description, and get generated sources from there (instead of listing them explicitly). arch/isa_parser.py: Get rid of third argument ("include_path"). It was a pain to generate this from scons, and it turned out it's not needed anyway, since the only included file (decoder.hh) will be in the same directory as the sources. --HG-- extra : convert_revision : 36861bcef36763f229704d8cb7a642b4486a3581 --- SConscript | 57 +++++----------------------------- arch/SConscript | 72 +++++++++++++++++++++++++++++++++++++++++++ arch/alpha/SConscript | 49 ++++++++++++++++------------- arch/isa_parser.py | 8 ++--- arch/mips/SConscript | 50 +++++++++++++++--------------- arch/sparc/SConscript | 52 +++++++++++++++---------------- 6 files changed, 163 insertions(+), 125 deletions(-) diff --git a/SConscript b/SConscript index 49f06af7d..3e607caa4 100644 --- a/SConscript +++ b/SConscript @@ -320,6 +320,11 @@ syscall_emulation_sources = Split(''' sim/syscall_emul.cc ''') +# The following stuff (targetarch code and global define of THE_ISA) +# are legacy things that assume we're only compiling one ISA at a +# time. These will have to go away if we want to build a binary that +# supports multiple ISAs. + targetarch_files = Split(''' alpha_linux_process.hh alpha_memory.hh @@ -338,18 +343,14 @@ for f in targetarch_files: env.Command('targetarch/' + f, 'arch/%s/%s' % (env['TARGET_ISA'], f), '''echo '#include "arch/%s/%s"' > $TARGET''' % (env['TARGET_ISA'], f)) -# Let the target architecture define what sources it needs -arch_source = SConscript('arch/%s/SConscript' % env['TARGET_ISA'], - build_dir = 'build/%s/' % env['BUILD_DIR'], - exports = 'env', duplicate = False) - # Add a flag defining what THE_ISA should be for all compilation env.Append(CPPDEFINES=[('THE_ISA','%s_ISA' % env['TARGET_ISA'].upper())]) -SConscript('arch/SConscript', exports = 'env', duplicate = False) +arch_sources = SConscript('arch/SConscript', + exports = 'env', duplicate = False) # Set up complete list of sources based on configuration. -sources = base_sources + arch_source +sources = base_sources + arch_sources if env['FULL_SYSTEM']: sources += full_system_sources @@ -364,27 +365,6 @@ if env['USE_MYSQL']: for opt in env.ExportOptions: env.ConfigFile(opt) -################################################### -# -# Add an SCons scanner for ISA files -# -################################################### -import SCons.Scanner - -def ISAScan(): - return SCons.Scanner.Classic("ISAScan", - "$ISASUFFIXES", - "SRCDIR", - '^[ \t]*##[ \t]*include[ \t]*"([^>"]+)"') - -def ISAPath(env, dir, target=None, source=None, a=None): - return (Dir(env['SRCDIR']), Dir('.')) - -iscan = Scanner(function = ISAScan().scan, skeys = [".isa", ".ISA"], - path_function = ISAPath) -env.Append(SCANNERS = iscan) - - ################################################### # # Special build rules. @@ -397,27 +377,6 @@ env.Command(Split('base/traceflags.hh base/traceflags.cc'), 'base/traceflags.py', 'python $SOURCE $TARGET.base') -# several files are generated from arch/$TARGET_ISA/isa_desc. -env.Command(Split(''' - arch/%s/decoder.cc - arch/%s/decoder.hh - arch/%s/alpha_o3_exec.cc - arch/%s/fast_cpu_exec.cc - arch/%s/simple_cpu_exec.cc - arch/%s/full_cpu_exec.cc''' % - (env['TARGET_ISA'], - env['TARGET_ISA'], - env['TARGET_ISA'], - env['TARGET_ISA'], - env['TARGET_ISA'], - env['TARGET_ISA'])), - Split(''' - arch/%s/isa/main.isa - arch/isa_parser.py''' % - env['TARGET_ISA']), - '$SRCDIR/arch/isa_parser.py $SOURCE $TARGET.dir arch/%s' % env['TARGET_ISA']) - - # libelf build is described in its own SConscript file. # SConscript-local is the per-config build, which just copies some # header files into a place where they can be found. diff --git a/arch/SConscript b/arch/SConscript index 2d8e34b7b..51f6cc023 100644 --- a/arch/SConscript +++ b/arch/SConscript @@ -31,11 +31,17 @@ import os.path # Import build environment variable from SConstruct. Import('env') +# Right now there are no source files immediately in this directory +sources = [] + +################################################################# # # ISA "switch header" generation. # # Auto-generate arch headers that include the right ISA-specific # header based on the setting of THE_ISA preprocessor variable. +# +################################################################# # List of headers to generate isa_switch_hdrs = Split(''' @@ -72,3 +78,69 @@ switch_hdr_action = Action(gen_switch_hdr, gen_switch_hdr_string, # Instantiate actions for each header for hdr in isa_switch_hdrs: env.Command(hdr, [], switch_hdr_action) + +################################################################# +# +# Include architecture-specific files. +# +################################################################# + +# +# Build a SCons scanner for ISA files +# +import SCons.Scanner + +def ISAScan(): + return SCons.Scanner.Classic("ISAScan", + "$ISASUFFIXES", + "SRCDIR", + '^[ \t]*##[ \t]*include[ \t]*"([^>"]+)"') + +def ISAPath(env, dir, target=None, source=None, a=None): + return (Dir(env['SRCDIR']), Dir('.')) + +iscan = Scanner(function = ISAScan().scan, skeys = [".isa", ".ISA"], + path_function = ISAPath) +env.Append(SCANNERS = iscan) + +# +# Now create a Builder object that uses isa_parser.py to generate C++ +# output from the ISA description (*.isa) files. +# + +# several files are generated from the ISA description +isa_desc_gen_files = Split(''' + decoder.cc + alpha_o3_exec.cc + fast_cpu_exec.cc + simple_cpu_exec.cc + full_cpu_exec.cc + decoder.hh + ''') + +# Convert to File node to fix path +isa_parser = File('isa_parser.py') + +# The emitter patches up the sources & targets to include the +# autogenerated files as targets and isa parser itself as a source. +def isa_desc_emitter(target, source, env): + return (isa_desc_gen_files, [isa_parser] + source) + +# Pieces are in place, so create the builder. +isa_desc_builder = Builder(action='${SOURCES[0]} ${SOURCES[1]} $TARGET.dir', + source_scanner = iscan, + emitter = isa_desc_emitter) + +env.Append(BUILDERS = { 'ISADesc' : isa_desc_builder }) + +# +# Now include other ISA-specific sources from the ISA subdirectories. +# + +isa = env['TARGET_ISA'] # someday this may be a list of ISAs + +# Let the target architecture define what additional sources it needs +sources += SConscript(os.path.join(isa, 'SConscript'), + exports = 'env', duplicate = False) + +Return('sources') diff --git a/arch/alpha/SConscript b/arch/alpha/SConscript index a5ae77dac..050dfb9cf 100644 --- a/arch/alpha/SConscript +++ b/arch/alpha/SConscript @@ -43,40 +43,45 @@ Import('env') ################################################### # Base sources used by all configurations. -arch_base_sources = Split(''' - arch/alpha/decoder.cc - arch/alpha/alpha_o3_exec.cc - arch/alpha/fast_cpu_exec.cc - arch/alpha/simple_cpu_exec.cc - arch/alpha/full_cpu_exec.cc - arch/alpha/faults.cc - arch/alpha/isa_traits.cc +base_sources = Split(''' + faults.cc + isa_traits.cc ''') # Full-system sources -arch_full_system_sources = Split(''' - arch/alpha/alpha_memory.cc - arch/alpha/arguments.cc - arch/alpha/ev5.cc - arch/alpha/osfpal.cc - arch/alpha/stacktrace.cc - arch/alpha/vtophys.cc +full_system_sources = Split(''' + alpha_memory.cc + arguments.cc + ev5.cc + osfpal.cc + stacktrace.cc + vtophys.cc ''') # Syscall emulation (non-full-system) sources -arch_syscall_emulation_sources = Split(''' - arch/alpha/alpha_common_syscall_emul.cc - arch/alpha/alpha_linux_process.cc - arch/alpha/alpha_tru64_process.cc +syscall_emulation_sources = Split(''' + alpha_common_syscall_emul.cc + alpha_linux_process.cc + alpha_tru64_process.cc ''') # Set up complete list of sources based on configuration. -sources = arch_base_sources +sources = base_sources if env['FULL_SYSTEM']: - sources += arch_full_system_sources + sources += full_system_sources else: - sources += arch_syscall_emulation_sources + sources += syscall_emulation_sources + +# Convert file names to SCons File objects. This takes care of the +# path relative to the top of the directory tree. +sources = [File(s) for s in sources] + +# Add in files generated by the ISA description. +isa_desc_files = env.ISADesc('isa/main.isa') +# Only non-header files need to be compiled. +isa_desc_sources = [f for f in isa_desc_files if not f.path.endswith('.hh')] +sources += isa_desc_sources Return('sources') diff --git a/arch/isa_parser.py b/arch/isa_parser.py index b92d267c9..a2bf31a0c 100755 --- a/arch/isa_parser.py +++ b/arch/isa_parser.py @@ -1751,7 +1751,7 @@ def preprocess_isa_desc(isa_desc): # # Read in and parse the ISA description. # -def parse_isa_desc(isa_desc_file, output_dir, include_path): +def parse_isa_desc(isa_desc_file, output_dir): # set a global var for the input filename... used in error messages global input_filename input_filename = isa_desc_file @@ -1781,7 +1781,7 @@ def parse_isa_desc(isa_desc_file, output_dir, include_path): update_if_needed(output_dir + '/decoder.hh', file_template % vars()) # generate decoder.cc - includes = '#include "%s/decoder.hh"' % include_path + includes = '#include "decoder.hh"' global_output = global_code.decoder_output namespace_output = namespace_code.decoder_output # namespace_output += namespace_code.decode_block @@ -1790,7 +1790,7 @@ def parse_isa_desc(isa_desc_file, output_dir, include_path): # generate per-cpu exec files for cpu in CpuModel.list: - includes = '#include "%s/decoder.hh"\n' % include_path + includes = '#include "decoder.hh"\n' includes += cpu.includes global_output = global_code.exec_output[cpu.name] namespace_output = namespace_code.exec_output[cpu.name] @@ -1800,4 +1800,4 @@ def parse_isa_desc(isa_desc_file, output_dir, include_path): # Called as script: get args from command line. if __name__ == '__main__': - parse_isa_desc(sys.argv[1], sys.argv[2], sys.argv[3]) + parse_isa_desc(sys.argv[1], sys.argv[2]) diff --git a/arch/mips/SConscript b/arch/mips/SConscript index a6af91669..b8efa7ef9 100644 --- a/arch/mips/SConscript +++ b/arch/mips/SConscript @@ -40,42 +40,44 @@ Import('env') ################################################### # Base sources used by all configurations. -arch_base_sources = Split(''' - arch/mips/decoder.cc - arch/mips/mips_o3_exec.cc - arch/mips/fast_cpu_exec.cc - arch/mips/simple_cpu_exec.cc - arch/mips/full_cpu_exec.cc - arch/mips/faults.cc - arch/mips/isa_traits.cc +base_sources = Split(''' + faults.cc + isa_traits.cc ''') # Full-system sources -arch_full_system_sources = Split(''' - arch/mips/memory.cc - arch/mips/arguments.cc - arch/mips/mips34k.cc - arch/mips/osfpal.cc - arch/mips/stacktrace.cc - arch/mips/vtophys.cc +full_system_sources = Split(''' + memory.cc + arguments.cc + mips34k.cc + osfpal.cc + stacktrace.cc + vtophys.cc ''') # Syscall emulation (non-full-system) sources -arch_syscall_emulation_sources = Split(''' - arch/mips/common_syscall_emul.cc - arch/mips/linux_process.cc - arch/mips/tru64_process.cc +syscall_emulation_sources = Split(''' + common_syscall_emul.cc + linux_process.cc + tru64_process.cc ''') # Set up complete list of sources based on configuration. -sources = arch_base_sources +sources = base_sources if env['FULL_SYSTEM']: - sources += arch_full_system_sources + sources += full_system_sources else: - sources += arch_syscall_emulation_sources + sources += syscall_emulation_sources -for opt in env.ExportOptions: - env.ConfigFile(opt) +# Convert file names to SCons File objects. This takes care of the +# path relative to the top of the directory tree. +sources = [File(s) for s in sources] + +# Add in files generated by the ISA description. +isa_desc_files = env.ISADesc('isa/main.isa') +# Only non-header files need to be compiled. +isa_desc_sources = [f for f in isa_desc_files if not f.path.endswith('.hh')] +sources += isa_desc_sources Return('sources') diff --git a/arch/sparc/SConscript b/arch/sparc/SConscript index d8a3749a1..fea31fd5d 100644 --- a/arch/sparc/SConscript +++ b/arch/sparc/SConscript @@ -40,43 +40,43 @@ Import('env') ################################################### # Base sources used by all configurations. -arch_base_sources = Split(''' - arch/sparc/decoder.cc - arch/sparc/alpha_o3_exec.cc - arch/sparc/fast_cpu_exec.cc - arch/sparc/simple_cpu_exec.cc - arch/sparc/full_cpu_exec.cc - arch/sparc/faults.cc - arch/sparc/isa_traits.cc +base_sources = Split(''' + faults.cc + isa_traits.cc ''') # Full-system sources -arch_full_system_sources = Split(''' - arch/sparc/alpha_memory.cc - arch/sparc/arguments.cc - arch/sparc/ev5.cc - arch/sparc/osfpal.cc - arch/sparc/stacktrace.cc - arch/sparc/vtophys.cc +full_system_sources = Split(''' + alpha_memory.cc + arguments.cc + ev5.cc + osfpal.cc + stacktrace.cc + vtophys.cc ''') # Syscall emulation (non-full-system) sources -arch_syscall_emulation_sources = Split(''' - arch/sparc/alpha_common_syscall_emul.cc - arch/sparc/alpha_linux_process.cc - arch/sparc/alpha_tru64_process.cc +syscall_emulation_sources = Split(''' + alpha_common_syscall_emul.cc + alpha_linux_process.cc + alpha_tru64_process.cc ''') -sources = arch_base_sources +sources = base_sources if env['FULL_SYSTEM']: - sources += arch_full_system_sources - if env['ALPHA_TLASER']: - sources += arch_turbolaser_sources + sources += full_system_sources else: - sources += arch_syscall_emulation_sources + sources += syscall_emulation_sources -for opt in env.ExportOptions: - env.ConfigFile(opt) +# Convert file names to SCons File objects. This takes care of the +# path relative to the top of the directory tree. +sources = [File(s) for s in sources] + +# Add in files generated by the ISA description. +isa_desc_files = env.ISADesc('isa/main.isa') +# Only non-header files need to be compiled. +isa_desc_sources = [f for f in isa_desc_files if not f.path.endswith('.hh')] +sources += isa_desc_sources Return('sources') From 1166d4f0bfe67a9dc178be3454b4f0eac38663ad Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Thu, 23 Feb 2006 14:50:16 -0500 Subject: [PATCH 094/180] Get rid of the xc from the alphaAccess/alphaConsole backdoor device. Now allocate an array of stacks indexed by cpu number which specify cpu stacks and are initialized by cpu 0. Othe cpus spin waiting for their stacks before continuing. This change *REQUIRES* a the new console code to operate correctly. arch/alpha/ev5.cc: Add cpuId to initCPU/initIPR functions cpu/o3/cpu.cc: cpu/simple/cpu.cc: cpu/simple/cpu.hh: Move the cpu initilization into an init() function since it now needs the CPU id which isn't known at construction dev/alpha_access.h: dev/alpha_console.cc: dev/alpha_console.hh: instead of the bootstrap variables, add space for 64 cpu stacks in the alpha access structure. sim/system.cc: start all cpus immediately rather than just the first one --HG-- extra : convert_revision : 28c218af49d885a0f203ada419f16f25d5a3f37b --- arch/alpha/ev5.cc | 10 +++++++--- cpu/o3/cpu.cc | 3 +-- cpu/simple/cpu.cc | 17 ++++++++++++++-- cpu/simple/cpu.hh | 1 + dev/alpha_access.h | 6 ++---- dev/alpha_console.cc | 46 +++++++++++++++++--------------------------- dev/alpha_console.hh | 2 +- sim/system.cc | 8 +++----- 8 files changed, 48 insertions(+), 45 deletions(-) diff --git a/arch/alpha/ev5.cc b/arch/alpha/ev5.cc index 125affd03..bd076dae4 100644 --- a/arch/alpha/ev5.cc +++ b/arch/alpha/ev5.cc @@ -70,12 +70,15 @@ AlphaISA::swap_palshadow(RegFile *regs, bool use_shadow) // Machine dependent functions // void -AlphaISA::initCPU(RegFile *regs) +AlphaISA::initCPU(RegFile *regs, int cpuId) { - initIPRs(regs); + initIPRs(regs, cpuId); // CPU comes up with PAL regs enabled swap_palshadow(regs, true); + regs->intRegFile[16] = cpuId; + regs->intRegFile[0] = cpuId; + regs->pc = regs->ipr[IPR_PAL_BASE] + fault_addr[Reset_Fault]; regs->npc = regs->pc + sizeof(MachInst); } @@ -116,13 +119,14 @@ const int AlphaISA::reg_redir[AlphaISA::NumIntRegs] = { // // void -AlphaISA::initIPRs(RegFile *regs) +AlphaISA::initIPRs(RegFile *regs, int cpuId) { uint64_t *ipr = regs->ipr; bzero((char *)ipr, NumInternalProcRegs * sizeof(InternalProcReg)); ipr[IPR_PAL_BASE] = PalBase; ipr[IPR_MCSR] = 0x6; + ipr[IPR_PALtemp16] = cpuId; } diff --git a/cpu/o3/cpu.cc b/cpu/o3/cpu.cc index adc7b6bbc..6ea0ed7c7 100644 --- a/cpu/o3/cpu.cc +++ b/cpu/o3/cpu.cc @@ -137,8 +137,6 @@ FullO3CPU::FullO3CPU(Params ¶ms) system->execContexts[i] = new ExecContext(this, i, system, itb, dtb, mem); - // initialize CPU, including PC - TheISA::initCPU(&system->execContexts[i]->regs); execContexts.push_back(system->execContexts[i]); #else if (i < params.workload.size()) { @@ -250,6 +248,7 @@ FullO3CPU::init() // that it can start properly. #if FULL_SYSTEM ExecContext *src_xc = system->execContexts[0]; + TheISA::initCPU(&src_xc->regs, src_xc->cpu_id); #else ExecContext *src_xc = thread[0]; #endif diff --git a/cpu/simple/cpu.cc b/cpu/simple/cpu.cc index 70217f0bb..2438e49f6 100644 --- a/cpu/simple/cpu.cc +++ b/cpu/simple/cpu.cc @@ -84,6 +84,21 @@ SimpleCPU::TickEvent::TickEvent(SimpleCPU *c, int w) { } + +void +SimpleCPU::init() +{ + BaseCPU::init(); +#if FULL_SYSTEM + for (int i = 0; i < execContexts.size(); ++i) { + ExecContext *xc = execContexts[i]; + + // initialize CPU, including PC + TheISA::initCPU(&xc->regs, xc->cpu_id); + } +#endif +} + void SimpleCPU::TickEvent::process() { @@ -124,8 +139,6 @@ SimpleCPU::SimpleCPU(Params *p) #if FULL_SYSTEM xc = new ExecContext(this, 0, p->system, p->itb, p->dtb, p->mem); - // initialize CPU, including PC - TheISA::initCPU(&xc->regs); #else xc = new ExecContext(this, /* thread_num */ 0, p->process, /* asid */ 0); #endif // !FULL_SYSTEM diff --git a/cpu/simple/cpu.hh b/cpu/simple/cpu.hh index 0f7251237..564749592 100644 --- a/cpu/simple/cpu.hh +++ b/cpu/simple/cpu.hh @@ -66,6 +66,7 @@ class SimpleCPU : public BaseCPU public: // main simulation loop (one cycle) void tick(); + virtual void init(); private: struct TickEvent : public Event diff --git a/dev/alpha_access.h b/dev/alpha_access.h index a20a05535..5a1df6f39 100644 --- a/dev/alpha_access.h +++ b/dev/alpha_access.h @@ -33,7 +33,7 @@ * System Console Memory Mapped Register Definition */ -#define ALPHA_ACCESS_VERSION (1303) +#define ALPHA_ACCESS_VERSION (1305) #ifdef CONSOLE typedef unsigned uint32_t; @@ -67,9 +67,7 @@ struct AlphaAccess uint64_t inputChar; // 68: Placeholder for input // MP boot - uint64_t bootStrapImpure; // 70: - uint32_t bootStrapCPU; // 78: - uint32_t align2; // 7C: Dummy placeholder for alignment + uint64_t cpuStack[64]; // 70: }; #endif // __ALPHA_ACCESS_H__ diff --git a/dev/alpha_console.cc b/dev/alpha_console.cc index 61b444628..a520e7ea9 100644 --- a/dev/alpha_console.cc +++ b/dev/alpha_console.cc @@ -80,9 +80,7 @@ AlphaConsole::AlphaConsole(const string &name, SimConsole *cons, SimpleDisk *d, alphaAccess->diskOperation = 0; alphaAccess->outputChar = 0; alphaAccess->inputChar = 0; - alphaAccess->bootStrapImpure = 0; - alphaAccess->bootStrapCPU = 0; - alphaAccess->align2 = 0; + bzero(alphaAccess->cpuStack, sizeof(alphaAccess->cpuStack)); system->setAlphaAccess(addr); } @@ -122,9 +120,6 @@ AlphaConsole::read(MemReqPtr &req, uint8_t *data) case offsetof(AlphaAccess, numCPUs): *(uint32_t*)data = alphaAccess->numCPUs; break; - case offsetof(AlphaAccess, bootStrapCPU): - *(uint32_t*)data = alphaAccess->bootStrapCPU; - break; case offsetof(AlphaAccess, intrClockFrequency): *(uint32_t*)data = alphaAccess->intrClockFrequency; break; @@ -175,11 +170,14 @@ AlphaConsole::read(MemReqPtr &req, uint8_t *data) case offsetof(AlphaAccess, outputChar): *(uint64_t*)data = alphaAccess->outputChar; break; - case offsetof(AlphaAccess, bootStrapImpure): - *(uint64_t*)data = alphaAccess->bootStrapImpure; - break; default: - panic("Unknown 64bit access, %#x\n", daddr); + int cpunum = (daddr - offsetof(AlphaAccess, cpuStack)) / + sizeof(alphaAccess->cpuStack[0]); + + if (cpunum >= 0 && cpunum < 64) + *(uint64_t*)data = alphaAccess->cpuStack[cpunum]; + else + panic("Unknown 64bit access, %#x\n", daddr); } break; default: @@ -239,24 +237,18 @@ AlphaConsole::write(MemReqPtr &req, const uint8_t *data) console->out((char)(val & 0xff)); break; - case offsetof(AlphaAccess, bootStrapImpure): - alphaAccess->bootStrapImpure = val; - break; - - case offsetof(AlphaAccess, bootStrapCPU): - warn("%d: Trying to launch another CPU!", curTick); - assert(val > 0 && "Must not access primary cpu"); - - other_xc = req->xc->system->execContexts[val]; - other_xc->regs.intRegFile[16] = val; - other_xc->regs.ipr[TheISA::IPR_PALtemp16] = val; - other_xc->regs.intRegFile[0] = val; - other_xc->regs.intRegFile[30] = alphaAccess->bootStrapImpure; other_xc->activate(); //Start the cpu break; default: - return Machine_Check_Fault; + int cpunum = (daddr - offsetof(AlphaAccess, cpuStack)) / + sizeof(alphaAccess->cpuStack[0]); + warn("%d: Trying to launch CPU number %d!", curTick, cpunum); + assert(val > 0 && "Must not access primary cpu"); + if (cpunum >= 0 && cpunum < 64) + alphaAccess->cpuStack[cpunum] = val; + else + panic("Unknown 64bit access, %#x\n", daddr); } return No_Fault; @@ -287,8 +279,7 @@ AlphaConsole::Access::serialize(ostream &os) SERIALIZE_SCALAR(diskOperation); SERIALIZE_SCALAR(outputChar); SERIALIZE_SCALAR(inputChar); - SERIALIZE_SCALAR(bootStrapImpure); - SERIALIZE_SCALAR(bootStrapCPU); + SERIALIZE_ARRAY(cpuStack,64); } void @@ -310,8 +301,7 @@ AlphaConsole::Access::unserialize(Checkpoint *cp, const std::string §ion) UNSERIALIZE_SCALAR(diskOperation); UNSERIALIZE_SCALAR(outputChar); UNSERIALIZE_SCALAR(inputChar); - UNSERIALIZE_SCALAR(bootStrapImpure); - UNSERIALIZE_SCALAR(bootStrapCPU); + UNSERIALIZE_ARRAY(cpuStack, 64); } void diff --git a/dev/alpha_console.hh b/dev/alpha_console.hh index 74ad795f0..2d1c1e634 100644 --- a/dev/alpha_console.hh +++ b/dev/alpha_console.hh @@ -96,7 +96,7 @@ class AlphaConsole : public PioDevice BaseCPU *cpu; Addr addr; - static const Addr size = 0x80; // equal to sizeof(alpha_access); + static const Addr size = sizeof(struct AlphaAccess); public: /** Standard Constructor */ diff --git a/sim/system.cc b/sim/system.cc index 990145826..bf639b408 100644 --- a/sim/system.cc +++ b/sim/system.cc @@ -306,11 +306,9 @@ System::registerExecContext(ExecContext *xc, int id) void System::startup() { - if (!execContexts.empty()) { - // activate with zero delay so that we start ticking right - // away on cycle 0 - execContexts[0]->activate(0); - } + int i; + for (i = 0; i < execContexts.size(); i++) + execContexts[i]->activate(0); } void From 4f831bc5610abfdb94ddfed9af5f1398182ff0b4 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Thu, 23 Feb 2006 15:08:08 -0500 Subject: [PATCH 095/180] ev5.cc: SCCS merged arch/alpha/ev5.cc: SCCS merged --HG-- extra : convert_revision : 9d70c1d461dab0ec016fd0616d74a49942aac659 --- arch/alpha/ev5.cc | 70 ++++++++++++++++++++--------------------------- 1 file changed, 30 insertions(+), 40 deletions(-) diff --git a/arch/alpha/ev5.cc b/arch/alpha/ev5.cc index bd076dae4..14b87b16f 100644 --- a/arch/alpha/ev5.cc +++ b/arch/alpha/ev5.cc @@ -79,7 +79,7 @@ AlphaISA::initCPU(RegFile *regs, int cpuId) regs->intRegFile[16] = cpuId; regs->intRegFile[0] = cpuId; - regs->pc = regs->ipr[IPR_PAL_BASE] + fault_addr[Reset_Fault]; + regs->pc = regs->ipr[IPR_PAL_BASE] + fault_addr(ResetFault); regs->npc = regs->pc + sizeof(MachInst); } @@ -87,25 +87,15 @@ AlphaISA::initCPU(RegFile *regs, int cpuId) // // alpha exceptions - value equals trap address, update with MD_FAULT_TYPE // -Addr -AlphaISA::fault_addr[Num_Faults] = { - 0x0000, /* No_Fault */ - 0x0001, /* Reset_Fault */ - 0x0401, /* Machine_Check_Fault */ - 0x0501, /* Arithmetic_Fault */ - 0x0101, /* Interrupt_Fault */ - 0x0201, /* Ndtb_Miss_Fault */ - 0x0281, /* Pdtb_Miss_Fault */ - 0x0301, /* Alignment_Fault */ - 0x0381, /* DTB_Fault_Fault */ - 0x0381, /* DTB_Acv_Fault */ - 0x0181, /* ITB_Miss_Fault */ - 0x0181, /* ITB_Fault_Fault */ - 0x0081, /* ITB_Acv_Fault */ - 0x0481, /* Unimplemented_Opcode_Fault */ - 0x0581, /* Fen_Fault */ - 0x2001, /* Pal_Fault */ - 0x0501, /* Integer_Overflow_Fault: maps to Arithmetic_Fault */ +const Addr +AlphaISA::fault_addr(Fault fault) +{ + //Check for the system wide faults + if(fault == NoFault) return 0x0000; + else if(fault == MachineCheckFault) return 0x0401; + else if(fault == AlignmentFault) return 0x0301; + //Deal with the alpha specific faults + return ((AlphaFault*)fault)->vect; }; const int AlphaISA::reg_redir[AlphaISA::NumIntRegs] = { @@ -172,7 +162,7 @@ AlphaISA::processInterrupts(CPU *cpu) if (ipl && ipl > ipr[IPR_IPLR]) { ipr[IPR_ISR] = summary; ipr[IPR_INTID] = ipl; - cpu->trap(Interrupt_Fault); + cpu->trap(InterruptFault); DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n", ipr[IPR_IPLR], ipl, summary); } @@ -193,23 +183,23 @@ AlphaISA::zeroRegisters(CPU *cpu) void ExecContext::ev5_trap(Fault fault) { - DPRINTF(Fault, "Fault %s at PC: %#x\n", FaultName(fault), regs.pc); - cpu->recordEvent(csprintf("Fault %s", FaultName(fault))); + DPRINTF(Fault, "Fault %s at PC: %#x\n", fault->name, regs.pc); + cpu->recordEvent(csprintf("Fault %s", fault->name)); assert(!misspeculating()); kernelStats->fault(fault); - if (fault == Arithmetic_Fault) + if (fault == ArithmeticFault) panic("Arithmetic traps are unimplemented!"); AlphaISA::InternalProcReg *ipr = regs.ipr; // exception restart address - if (fault != Interrupt_Fault || !inPalMode()) + if (fault != InterruptFault || !inPalMode()) ipr[AlphaISA::IPR_EXC_ADDR] = regs.pc; - if (fault == Pal_Fault || fault == Arithmetic_Fault /* || - fault == Interrupt_Fault && !inPalMode() */) { + if (fault == PalFault || fault == ArithmeticFault /* || + fault == InterruptFault && !inPalMode() */) { // traps... skip faulting instruction ipr[AlphaISA::IPR_EXC_ADDR] += 4; } @@ -217,7 +207,7 @@ ExecContext::ev5_trap(Fault fault) if (!inPalMode()) AlphaISA::swap_palshadow(®s, true); - regs.pc = ipr[AlphaISA::IPR_PAL_BASE] + AlphaISA::fault_addr[fault]; + regs.pc = ipr[AlphaISA::IPR_PAL_BASE] + AlphaISA::fault_addr(fault); regs.npc = regs.pc + sizeof(MachInst); } @@ -226,13 +216,13 @@ void AlphaISA::intr_post(RegFile *regs, Fault fault, Addr pc) { InternalProcReg *ipr = regs->ipr; - bool use_pc = (fault == No_Fault); + bool use_pc = (fault == NoFault); - if (fault == Arithmetic_Fault) + if (fault == ArithmeticFault) panic("arithmetic faults NYI..."); // compute exception restart address - if (use_pc || fault == Pal_Fault || fault == Arithmetic_Fault) { + if (use_pc || fault == PalFault || fault == ArithmeticFault) { // traps... skip faulting instruction ipr[IPR_EXC_ADDR] = regs->pc + 4; } else { @@ -242,7 +232,7 @@ AlphaISA::intr_post(RegFile *regs, Fault fault, Addr pc) // jump to expection address (PAL PC bit set here as well...) if (!use_pc) - regs->npc = ipr[IPR_PAL_BASE] + fault_addr[fault]; + regs->npc = ipr[IPR_PAL_BASE] + fault_addr(fault); else regs->npc = ipr[IPR_PAL_BASE] + pc; @@ -255,7 +245,7 @@ ExecContext::hwrei() uint64_t *ipr = regs.ipr; if (!inPalMode()) - return Unimplemented_Opcode_Fault; + return UnimplementedOpcodeFault; setNextPC(ipr[AlphaISA::IPR_EXC_ADDR]); @@ -269,7 +259,7 @@ ExecContext::hwrei() } // FIXME: XXX check for interrupts? XXX - return No_Fault; + return NoFault; } uint64_t @@ -367,12 +357,12 @@ ExecContext::readIpr(int idx, Fault &fault) case AlphaISA::IPR_DTB_IAP: case AlphaISA::IPR_ITB_IA: case AlphaISA::IPR_ITB_IAP: - fault = Unimplemented_Opcode_Fault; + fault = UnimplementedOpcodeFault; break; default: // invalid IPR - fault = Unimplemented_Opcode_Fault; + fault = UnimplementedOpcodeFault; break; } @@ -391,7 +381,7 @@ ExecContext::setIpr(int idx, uint64_t val) uint64_t old; if (misspeculating()) - return No_Fault; + return NoFault; switch (idx) { case AlphaISA::IPR_PALtemp0: @@ -537,7 +527,7 @@ ExecContext::setIpr(int idx, uint64_t val) case AlphaISA::IPR_ITB_PTE_TEMP: case AlphaISA::IPR_DTB_PTE_TEMP: // read-only registers - return Unimplemented_Opcode_Fault; + return UnimplementedOpcodeFault; case AlphaISA::IPR_HWINT_CLR: case AlphaISA::IPR_SL_XMIT: @@ -639,11 +629,11 @@ ExecContext::setIpr(int idx, uint64_t val) default: // invalid IPR - return Unimplemented_Opcode_Fault; + return UnimplementedOpcodeFault; } // no error... - return No_Fault; + return NoFault; } /** From 51647e7bec8e8607fc5713b4ace2c24ce8a7455a Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Thu, 23 Feb 2006 17:00:29 -0500 Subject: [PATCH 096/180] Enable building only selected CPU models via new scons CPU_MODELS parameter. For example: scons CPU_MODELS="SimpleCPU,FullCPU" ALPHA_SE/m5.debug Unfortunately the option is not sticky due to a scons bug with saving & restoring ListOption parameters. SConscript: Separate out cpu-model-specific files so they can be conditionally included based on value of new CPU_MODELS parameter. Most of these are now handled in cpu/SConscript, except for FullCPU which is still in this file. arch/SConscript: The set of CPU-model-specific execute files must now be determined from the CPU_MODELS parameter, via the new cpu_models.py file. Also pass the list of configured CPU models to isa_parser.py. arch/isa_parser.py: Move CpuModel definition and objects out to a separate file so they can be shared with scons. Global list of CPU models to generate code for is now controlled by command-line parameters (so we can do only a subset of the available ones). build/SConstruct: Define new CPU_MODELS ListOption. cpu/static_inst.hh: Rename static_inst_impl.hh to static_inst_exec_sigs.hh. --HG-- extra : convert_revision : 163df32a76d4c05900490b2bce4c7962a5e3f614 --- SConscript | 108 ++++++++++++++++++++------------------------- arch/SConscript | 25 ++++++----- arch/isa_parser.py | 53 +++++----------------- build/SConstruct | 9 ++++ cpu/SConscript | 99 +++++++++++++++++++++++++++++++++++++++++ cpu/cpu_models.py | 71 +++++++++++++++++++++++++++++ cpu/static_inst.hh | 6 ++- 7 files changed, 256 insertions(+), 115 deletions(-) create mode 100644 cpu/SConscript create mode 100644 cpu/cpu_models.py diff --git a/SConscript b/SConscript index 3e607caa4..966cb6d3e 100644 --- a/SConscript +++ b/SConscript @@ -86,31 +86,7 @@ base_sources = Split(''' cpu/exetrace.cc cpu/pc_event.cc cpu/static_inst.cc - cpu/o3/2bit_local_pred.cc - cpu/o3/alpha_dyn_inst.cc - cpu/o3/alpha_cpu.cc - cpu/o3/alpha_cpu_builder.cc - cpu/o3/bpred_unit.cc - cpu/o3/btb.cc - cpu/o3/commit.cc - cpu/o3/decode.cc - cpu/o3/fetch.cc - cpu/o3/free_list.cc - cpu/o3/cpu.cc - cpu/o3/iew.cc - cpu/o3/inst_queue.cc - cpu/o3/ldstq.cc - cpu/o3/mem_dep_unit.cc - cpu/o3/ras.cc - cpu/o3/rename.cc - cpu/o3/rename_map.cc - cpu/o3/rob.cc - cpu/o3/sat_counter.cc - cpu/o3/store_set.cc - cpu/o3/tournament_pred.cc - cpu/fast/cpu.cc cpu/sampler/sampler.cc - cpu/simple/cpu.cc cpu/trace/reader/mem_trace_reader.cc cpu/trace/reader/ibm_reader.cc cpu/trace/reader/itx_reader.cc @@ -118,41 +94,6 @@ base_sources = Split(''' cpu/trace/opt_cpu.cc cpu/trace/trace_cpu.cc - encumbered/cpu/full/bpred.cc - encumbered/cpu/full/commit.cc - encumbered/cpu/full/cpu.cc - encumbered/cpu/full/create_vector.cc - encumbered/cpu/full/cv_spec_state.cc - encumbered/cpu/full/dd_queue.cc - encumbered/cpu/full/dep_link.cc - encumbered/cpu/full/dispatch.cc - encumbered/cpu/full/dyn_inst.cc - encumbered/cpu/full/execute.cc - encumbered/cpu/full/fetch.cc - encumbered/cpu/full/floss_reasons.cc - encumbered/cpu/full/fu_pool.cc - encumbered/cpu/full/inst_fifo.cc - encumbered/cpu/full/instpipe.cc - encumbered/cpu/full/issue.cc - encumbered/cpu/full/ls_queue.cc - encumbered/cpu/full/machine_queue.cc - encumbered/cpu/full/pipetrace.cc - encumbered/cpu/full/readyq.cc - encumbered/cpu/full/reg_info.cc - encumbered/cpu/full/rob_station.cc - encumbered/cpu/full/spec_memory.cc - encumbered/cpu/full/spec_state.cc - encumbered/cpu/full/storebuffer.cc - encumbered/cpu/full/writeback.cc - encumbered/cpu/full/iq/iq_station.cc - encumbered/cpu/full/iq/iqueue.cc - encumbered/cpu/full/iq/segmented/chain_info.cc - encumbered/cpu/full/iq/segmented/chain_wire.cc - encumbered/cpu/full/iq/segmented/iq_seg.cc - encumbered/cpu/full/iq/segmented/iq_segmented.cc - encumbered/cpu/full/iq/segmented/seg_chain.cc - encumbered/cpu/full/iq/seznec/iq_seznec.cc - encumbered/cpu/full/iq/standard/iq_standard.cc encumbered/mem/functional/main.cc mem/base_hier.cc @@ -224,6 +165,45 @@ base_sources = Split(''' sim/trace_context.cc ''') +# Old FullCPU sources +full_cpu_sources = Split(''' + encumbered/cpu/full/bpred.cc + encumbered/cpu/full/commit.cc + encumbered/cpu/full/cpu.cc + encumbered/cpu/full/create_vector.cc + encumbered/cpu/full/cv_spec_state.cc + encumbered/cpu/full/dd_queue.cc + encumbered/cpu/full/dep_link.cc + encumbered/cpu/full/dispatch.cc + encumbered/cpu/full/dyn_inst.cc + encumbered/cpu/full/execute.cc + encumbered/cpu/full/fetch.cc + encumbered/cpu/full/floss_reasons.cc + encumbered/cpu/full/fu_pool.cc + encumbered/cpu/full/inst_fifo.cc + encumbered/cpu/full/instpipe.cc + encumbered/cpu/full/issue.cc + encumbered/cpu/full/ls_queue.cc + encumbered/cpu/full/machine_queue.cc + encumbered/cpu/full/pipetrace.cc + encumbered/cpu/full/readyq.cc + encumbered/cpu/full/reg_info.cc + encumbered/cpu/full/rob_station.cc + encumbered/cpu/full/spec_memory.cc + encumbered/cpu/full/spec_state.cc + encumbered/cpu/full/storebuffer.cc + encumbered/cpu/full/writeback.cc + encumbered/cpu/full/iq/iq_station.cc + encumbered/cpu/full/iq/iqueue.cc + encumbered/cpu/full/iq/segmented/chain_info.cc + encumbered/cpu/full/iq/segmented/chain_wire.cc + encumbered/cpu/full/iq/segmented/iq_seg.cc + encumbered/cpu/full/iq/segmented/iq_segmented.cc + encumbered/cpu/full/iq/segmented/seg_chain.cc + encumbered/cpu/full/iq/seznec/iq_seznec.cc + encumbered/cpu/full/iq/standard/iq_standard.cc + ''') + # MySql sources mysql_sources = Split(''' base/mysql.cc @@ -349,8 +329,16 @@ env.Append(CPPDEFINES=[('THE_ISA','%s_ISA' % env['TARGET_ISA'].upper())]) arch_sources = SConscript('arch/SConscript', exports = 'env', duplicate = False) +cpu_sources = SConscript('cpu/SConscript', + exports = 'env', duplicate = False) + +# This is outside of cpu/SConscript since the source directory isn't +# underneath 'cpu'. +if 'FullCPU' in env['CPU_MODELS']: + cpu_sources += full_cpu_sources + # Set up complete list of sources based on configuration. -sources = base_sources + arch_sources +sources = base_sources + arch_sources + cpu_sources if env['FULL_SYSTEM']: sources += full_system_sources diff --git a/arch/SConscript b/arch/SConscript index 51f6cc023..d237b0b1f 100644 --- a/arch/SConscript +++ b/arch/SConscript @@ -108,26 +108,27 @@ env.Append(SCANNERS = iscan) # output from the ISA description (*.isa) files. # -# several files are generated from the ISA description -isa_desc_gen_files = Split(''' - decoder.cc - alpha_o3_exec.cc - fast_cpu_exec.cc - simple_cpu_exec.cc - full_cpu_exec.cc - decoder.hh - ''') - # Convert to File node to fix path isa_parser = File('isa_parser.py') +cpu_models_file = File('#m5/cpu/cpu_models.py') + +# This sucks in the defintions of the CpuModel objects. +execfile(cpu_models_file.srcnode().abspath) + +# Several files are generated from the ISA description. +# We always get the basic decoder and header file. +isa_desc_gen_files = Split('decoder.cc decoder.hh') +# We also get an execute file for each selected CPU model. +isa_desc_gen_files += [CpuModel.dict[cpu].filename + for cpu in env['CPU_MODELS']] # The emitter patches up the sources & targets to include the # autogenerated files as targets and isa parser itself as a source. def isa_desc_emitter(target, source, env): - return (isa_desc_gen_files, [isa_parser] + source) + return (isa_desc_gen_files, [isa_parser, cpu_models_file] + source) # Pieces are in place, so create the builder. -isa_desc_builder = Builder(action='${SOURCES[0]} ${SOURCES[1]} $TARGET.dir', +isa_desc_builder = Builder(action='$SOURCES $TARGET.dir $CPU_MODELS', source_scanner = iscan, emitter = isa_desc_emitter) diff --git a/arch/isa_parser.py b/arch/isa_parser.py index a2bf31a0c..6508ca02a 100755 --- a/arch/isa_parser.py +++ b/arch/isa_parser.py @@ -712,43 +712,6 @@ yacc.yacc() # ##################################################################### -################ -# CpuModel class -# -# The CpuModel class encapsulates everything we need to know about a -# particular CPU model. - -class CpuModel: - # List of all CPU models. Accessible as CpuModel.list. - list = [] - - # Constructor. Automatically adds models to CpuModel.list. - def __init__(self, name, filename, includes, strings): - self.name = name - self.filename = filename # filename for output exec code - self.includes = includes # include files needed in exec file - # The 'strings' dict holds all the per-CPU symbols we can - # substitute into templates etc. - self.strings = strings - # Add self to list. - CpuModel.list.append(self) - -# Define CPU models. The following lines should contain the only -# CPU-model-specific information in this file. Note that the ISA -# description itself should have *no* CPU-model-specific content. -CpuModel('SimpleCPU', 'simple_cpu_exec.cc', - '#include "cpu/simple/cpu.hh"', - { 'CPU_exec_context': 'SimpleCPU' }) -CpuModel('FastCPU', 'fast_cpu_exec.cc', - '#include "cpu/fast/cpu.hh"', - { 'CPU_exec_context': 'FastCPU' }) -CpuModel('FullCPU', 'full_cpu_exec.cc', - '#include "encumbered/cpu/full/dyn_inst.hh"', - { 'CPU_exec_context': 'DynInst' }) -CpuModel('AlphaFullCPU', 'alpha_o3_exec.cc', - '#include "cpu/o3/alpha_dyn_inst.hh"', - { 'CPU_exec_context': 'AlphaDynInst' }) - # Expand template with CPU-specific references into a dictionary with # an entry for each CPU model name. The entry key is the model name # and the corresponding value is the template with the CPU-specific @@ -757,7 +720,7 @@ def expand_cpu_symbols_to_dict(template): # Protect '%'s that don't go with CPU-specific terms t = re.sub(r'%(?!\(CPU_)', '%%', template) result = {} - for cpu in CpuModel.list: + for cpu in cpu_models: result[cpu.name] = t % cpu.strings return result @@ -816,7 +779,7 @@ class GenCode: # concatenates all the individual strings in the operands. def __add__(self, other): exec_output = {} - for cpu in CpuModel.list: + for cpu in cpu_models: n = cpu.name exec_output[n] = self.exec_output[n] + other.exec_output[n] return GenCode(self.header_output + other.header_output, @@ -830,7 +793,7 @@ class GenCode: self.header_output = pre + self.header_output self.decoder_output = pre + self.decoder_output self.decode_block = pre + self.decode_block - for cpu in CpuModel.list: + for cpu in cpu_models: self.exec_output[cpu.name] = pre + self.exec_output[cpu.name] # Wrap the decode block in a pair of strings (e.g., 'case foo:' @@ -1789,7 +1752,7 @@ def parse_isa_desc(isa_desc_file, output_dir): update_if_needed(output_dir + '/decoder.cc', file_template % vars()) # generate per-cpu exec files - for cpu in CpuModel.list: + for cpu in cpu_models: includes = '#include "decoder.hh"\n' includes += cpu.includes global_output = global_code.exec_output[cpu.name] @@ -1798,6 +1761,12 @@ def parse_isa_desc(isa_desc_file, output_dir): update_if_needed(output_dir + '/' + cpu.filename, file_template % vars()) +# global list of CpuModel objects (see cpu_models.py) +cpu_models = [] + # Called as script: get args from command line. +# Args are: if __name__ == '__main__': - parse_isa_desc(sys.argv[1], sys.argv[2]) + execfile(sys.argv[1]) # read in CpuModel definitions + cpu_models = [CpuModel.dict[cpu] for cpu in sys.argv[4:]] + parse_isa_desc(sys.argv[2], sys.argv[3]) diff --git a/build/SConstruct b/build/SConstruct index 38d404846..2d64afb3e 100644 --- a/build/SConstruct +++ b/build/SConstruct @@ -221,6 +221,9 @@ env = conf.Finish() # Define the universe of supported ISAs env['ALL_ISA_LIST'] = ['alpha', 'sparc', 'mips'] +# Define the universe of supported CPU models +env['ALL_CPU_LIST'] = ['SimpleCPU', 'FastCPU', 'FullCPU', 'AlphaFullCPU'] + # Sticky options get saved in the options file so they persist from # one invocation to the next (unless overridden, in which case the new # value becomes sticky). @@ -251,6 +254,12 @@ sticky_opts.AddOptions( # Non-sticky options only apply to the current build. nonsticky_opts = Options(args=ARGUMENTS) nonsticky_opts.AddOptions( + # This really should be a sticky option, but there's a bug in + # scons 0.96.1 that causes ListOptions not to be able to be + # restored from a saved option file. It looks like this is fixed + # in 0.96.9, but there's a different bug in that version that means we + # can't just upgrade. + ListOption('CPU_MODELS', 'CPU models', 'all', env['ALL_CPU_LIST']), BoolOption('update_ref', 'Update test reference outputs', False) ) diff --git a/cpu/SConscript b/cpu/SConscript new file mode 100644 index 000000000..dbe174660 --- /dev/null +++ b/cpu/SConscript @@ -0,0 +1,99 @@ +# -*- mode:python -*- + +# Copyright (c) 2006 The Regents of The University of Michigan +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import os +import os.path + +# Import build environment variable from SConstruct. +Import('env') + +models_db = File('cpu_models.py') +execfile(models_db.srcnode().abspath) + +exec_sig_template = ''' +virtual Fault execute(%s *xc, Trace::InstRecord *traceData) const = 0; +''' + +def gen_cpu_exec_signatures(target, source, env): + f = open(str(target[0]), 'w') + print >> f, ''' +#ifndef __CPU_STATIC_INST_EXEC_SIGS_HH__ +#define __CPU_STATIC_INST_EXEC_SIGS_HH__ +''' + for cpu in env['CPU_MODELS']: + xc_type = CpuModel.dict[cpu].strings['CPU_exec_context'] + print >> f, exec_sig_template % xc_type + print >> f, ''' +#endif // __CPU_STATIC_INST_EXEC_SIGS_HH__ +''' + +env.Command('static_inst_exec_sigs.hh', models_db, gen_cpu_exec_signatures) + +sources = [] + +if 'SimpleCPU' in env['CPU_MODELS']: + sources += Split('simple/cpu.cc') + +if 'FastCPU' in env['CPU_MODELS']: + sources += Split('fast/cpu.cc') + +if 'AlphaFullCPU' in env['CPU_MODELS']: + sources += Split(''' + o3/2bit_local_pred.cc + o3/alpha_dyn_inst.cc + o3/alpha_cpu.cc + o3/alpha_cpu_builder.cc + o3/bpred_unit.cc + o3/btb.cc + o3/commit.cc + o3/decode.cc + o3/fetch.cc + o3/free_list.cc + o3/cpu.cc + o3/iew.cc + o3/inst_queue.cc + o3/ldstq.cc + o3/mem_dep_unit.cc + o3/ras.cc + o3/rename.cc + o3/rename_map.cc + o3/rob.cc + o3/sat_counter.cc + o3/store_set.cc + o3/tournament_pred.cc + ''') + +# FullCPU sources are included from m5/SConscript since they're not +# below this point in the file hierarchy. + +# Convert file names to SCons File objects. This takes care of the +# path relative to the top of the directory tree. +sources = [File(s) for s in sources] + +Return('sources') + diff --git a/cpu/cpu_models.py b/cpu/cpu_models.py new file mode 100644 index 000000000..675204e5b --- /dev/null +++ b/cpu/cpu_models.py @@ -0,0 +1,71 @@ +# Copyright (c) 2003-2006 The Regents of The University of Michigan +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +################ +# CpuModel class +# +# The CpuModel class encapsulates everything the ISA parser needs to +# know about a particular CPU model. + +class CpuModel: + # Dict of available CPU model objects. Accessible as CpuModel.dict. + dict = {} + + # Constructor. Automatically adds models to CpuModel.dict. + def __init__(self, name, filename, includes, strings): + self.name = name + self.filename = filename # filename for output exec code + self.includes = includes # include files needed in exec file + # The 'strings' dict holds all the per-CPU symbols we can + # substitute into templates etc. + self.strings = strings + # Add self to dict + CpuModel.dict[name] = self + + +# +# Define CPU models. +# +# Parameters are: +# - name of model +# - filename for generated ISA execution file +# - includes needed for generated ISA execution file +# - substitution strings for ISA description templates +# + +CpuModel('SimpleCPU', 'simple_cpu_exec.cc', + '#include "cpu/simple/cpu.hh"', + { 'CPU_exec_context': 'SimpleCPU' }) +CpuModel('FastCPU', 'fast_cpu_exec.cc', + '#include "cpu/fast/cpu.hh"', + { 'CPU_exec_context': 'FastCPU' }) +CpuModel('FullCPU', 'full_cpu_exec.cc', + '#include "encumbered/cpu/full/dyn_inst.hh"', + { 'CPU_exec_context': 'DynInst' }) +CpuModel('AlphaFullCPU', 'alpha_o3_exec.cc', + '#include "cpu/o3/alpha_dyn_inst.hh"', + { 'CPU_exec_context': 'AlphaDynInst' }) + diff --git a/cpu/static_inst.hh b/cpu/static_inst.hh index 5106dcf06..a0287a2de 100644 --- a/cpu/static_inst.hh +++ b/cpu/static_inst.hh @@ -314,7 +314,11 @@ class StaticInst : public StaticInstBase delete cachedDisassembly; } -#include "static_inst_impl.hh" +/** + * The execute() signatures are auto-generated by scons based on the + * set of CPU models we are compiling in today. + */ +#include "cpu/static_inst_exec_sigs.hh" /** * Return the target address for a PC-relative branch. From f6cac25dcfbeed77642026deb81979f651104efe Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Thu, 23 Feb 2006 18:46:12 -0500 Subject: [PATCH 097/180] name changes ... SConscript: change to alpha_memory.hh --HG-- rename : arch/alpha/memory.cc => arch/alpha/alpha_memory.cc rename : arch/alpha/memory.hh => arch/alpha/alpha_memory.hh extra : convert_revision : 62b1a41de22701160f04cb7a78242746cfcde819 --- SConscript | 2 +- arch/alpha/{memory.cc => alpha_memory.cc} | 0 arch/alpha/{memory.hh => alpha_memory.hh} | 0 3 files changed, 1 insertion(+), 1 deletion(-) rename arch/alpha/{memory.cc => alpha_memory.cc} (100%) rename arch/alpha/{memory.hh => alpha_memory.hh} (100%) diff --git a/SConscript b/SConscript index 7afb84e67..49f06af7d 100644 --- a/SConscript +++ b/SConscript @@ -322,7 +322,7 @@ syscall_emulation_sources = Split(''' targetarch_files = Split(''' alpha_linux_process.hh - memory.hh + alpha_memory.hh alpha_tru64_process.hh aout_machdep.h arguments.hh diff --git a/arch/alpha/memory.cc b/arch/alpha/alpha_memory.cc similarity index 100% rename from arch/alpha/memory.cc rename to arch/alpha/alpha_memory.cc diff --git a/arch/alpha/memory.hh b/arch/alpha/alpha_memory.hh similarity index 100% rename from arch/alpha/memory.hh rename to arch/alpha/alpha_memory.hh From 08637efadc40a1003d68bba91dedb007fe10798c Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 24 Feb 2006 01:51:45 -0500 Subject: [PATCH 098/180] Changed Fault from a FaultBase * to a RefCountingPtr, added "new"s where appropriate, and took away the constant examples of each fault which where for comparing to a fault to determine its type. arch/alpha/alpha_memory.cc: arch/alpha/isa/decoder.isa: Added news where faults are created. arch/alpha/ev5.cc: Changed places where a fault was compared to a fault type to use isA rather than == arch/alpha/faults.cc: arch/alpha/faults.hh: Changed Fault to be a RefCountingPtr arch/alpha/isa/fp.isa: Added a new where a FloatEnableFault was created. arch/alpha/isa/unimp.isa: arch/alpha/isa/unknown.isa: Added a new where an UnimplementedFault is created. base/refcnt.hh: Added include of stddef.h for the NULL macro cpu/base_dyn_inst.cc: Added a new where an UnimplementedOpcodeFault is created. cpu/o3/alpha_cpu_impl.hh: Changed places where a fault was compared to a fault type to use isA rather than ==. Also changed fault->name to fault->name() cpu/o3/regfile.hh: Added new where UnimplementedOpcodeFaults are created. cpu/simple/cpu.cc: Changed places where a fault was compared to a fault type to use isA rather than ==. Also added a new where an Interrupt fault is created. dev/alpha_console.cc: Added news where MachineCheckFaults are created. dev/pcidev.hh: Added news where MachineCheckFaults are generated. dev/sinic.cc: Changed places where a fault was compared to a fault type to use isA rather than ==. Added news where MachineCheckFaults are created. Fixed a problem where m5.fast had unused variables. kern/kernel_stats.cc: Commented out where _faults is initialized. This statistic will probably be moved elsewhere in the future. kern/kernel_stats.hh: Commented out the declaration of _fault. when fault() is called, the fault increments its own stat. sim/faults.cc: sim/faults.hh: Changed Fault from a FaultBase * to a RefCountingPtr. --HG-- extra : convert_revision : b40ccfc42482d5a115e111dd897fa378d23c6c7d --- arch/alpha/alpha_memory.cc | 30 ++--- arch/alpha/ev5.cc | 34 +++--- arch/alpha/faults.cc | 91 +++++++++++----- arch/alpha/faults.hh | 217 ++++++++++++++++++++++++------------- arch/alpha/isa/decoder.isa | 26 ++--- arch/alpha/isa/fp.isa | 2 +- arch/alpha/isa/unimp.isa | 2 +- arch/alpha/isa/unknown.isa | 2 +- base/refcnt.hh | 2 + cpu/base_dyn_inst.cc | 2 +- cpu/o3/alpha_cpu_impl.hh | 14 +-- cpu/o3/regfile.hh | 8 +- cpu/simple/cpu.cc | 6 +- dev/alpha_console.cc | 6 +- dev/pcidev.hh | 4 +- dev/sinic.cc | 19 ++-- kern/kernel_stats.cc | 4 +- kern/kernel_stats.hh | 8 +- sim/faults.cc | 9 +- sim/faults.hh | 61 +++++++---- 20 files changed, 333 insertions(+), 214 deletions(-) diff --git a/arch/alpha/alpha_memory.cc b/arch/alpha/alpha_memory.cc index d00186d95..b2a829711 100644 --- a/arch/alpha/alpha_memory.cc +++ b/arch/alpha/alpha_memory.cc @@ -322,7 +322,7 @@ AlphaITB::translate(MemReqPtr &req) const if (!validVirtualAddress(req->vaddr)) { fault(req->vaddr, req->xc); acv++; - return ItbAcvFault; + return new ItbAcvFault; } @@ -339,7 +339,7 @@ AlphaITB::translate(MemReqPtr &req) const AlphaISA::mode_kernel) { fault(req->vaddr, req->xc); acv++; - return ItbAcvFault; + return new ItbAcvFault; } req->paddr = req->vaddr & PAddrImplMask; @@ -360,7 +360,7 @@ AlphaITB::translate(MemReqPtr &req) const if (!pte) { fault(req->vaddr, req->xc); misses++; - return ItbPageFault; + return new ItbPageFault; } req->paddr = (pte->ppn << AlphaISA::PageShift) + @@ -371,7 +371,7 @@ AlphaITB::translate(MemReqPtr &req) const // instruction access fault fault(req->vaddr, req->xc); acv++; - return ItbAcvFault; + return new ItbAcvFault; } hits++; @@ -380,7 +380,7 @@ AlphaITB::translate(MemReqPtr &req) const // check that the physical address is ok (catch bad physical addresses) if (req->paddr & ~PAddrImplMask) - return MachineCheckFault; + return new MachineCheckFault; checkCacheability(req); @@ -511,7 +511,7 @@ AlphaDTB::translate(MemReqPtr &req, bool write) const fault(req, write ? MM_STAT_WR_MASK : 0); DPRINTF(TLB, "Alignment Fault on %#x, size = %d", req->vaddr, req->size); - return AlignmentFault; + return new AlignmentFault; } if (pc & 0x1) { @@ -530,7 +530,7 @@ AlphaDTB::translate(MemReqPtr &req, bool write) const MM_STAT_ACV_MASK); if (write) { write_acv++; } else { read_acv++; } - return DtbPageFault; + return new DtbPageFault; } // Check for "superpage" mapping @@ -547,7 +547,7 @@ AlphaDTB::translate(MemReqPtr &req, bool write) const fault(req, ((write ? MM_STAT_WR_MASK : 0) | MM_STAT_ACV_MASK)); if (write) { write_acv++; } else { read_acv++; } - return DtbAcvFault; + return new DtbAcvFault; } req->paddr = req->vaddr & PAddrImplMask; @@ -575,7 +575,9 @@ AlphaDTB::translate(MemReqPtr &req, bool write) const fault(req, (write ? MM_STAT_WR_MASK : 0) | MM_STAT_DTB_MISS_MASK); if (write) { write_misses++; } else { read_misses++; } - return (req->flags & VPTE) ? (Fault)PDtbMissFault : (Fault)NDtbMissFault; + return (req->flags & VPTE) ? + (Fault)(new PDtbMissFault) : + (Fault)(new NDtbMissFault); } req->paddr = (pte->ppn << AlphaISA::PageShift) + @@ -588,25 +590,25 @@ AlphaDTB::translate(MemReqPtr &req, bool write) const MM_STAT_ACV_MASK | (pte->fonw ? MM_STAT_FONW_MASK : 0)); write_acv++; - return DtbPageFault; + return new DtbPageFault; } if (pte->fonw) { fault(req, MM_STAT_WR_MASK | MM_STAT_FONW_MASK); write_acv++; - return DtbPageFault; + return new DtbPageFault; } } else { if (!(pte->xre & MODE2MASK(mode))) { fault(req, MM_STAT_ACV_MASK | (pte->fonr ? MM_STAT_FONR_MASK : 0)); read_acv++; - return DtbAcvFault; + return new DtbAcvFault; } if (pte->fonr) { fault(req, MM_STAT_FONR_MASK); read_acv++; - return DtbPageFault; + return new DtbPageFault; } } } @@ -619,7 +621,7 @@ AlphaDTB::translate(MemReqPtr &req, bool write) const // check that the physical address is ok (catch bad physical addresses) if (req->paddr & ~PAddrImplMask) - return MachineCheckFault; + return new MachineCheckFault; checkCacheability(req); diff --git a/arch/alpha/ev5.cc b/arch/alpha/ev5.cc index 4777907e0..3f1c17adc 100644 --- a/arch/alpha/ev5.cc +++ b/arch/alpha/ev5.cc @@ -76,7 +76,7 @@ AlphaISA::initCPU(RegFile *regs) // CPU comes up with PAL regs enabled swap_palshadow(regs, true); - regs->pc = regs->ipr[IPR_PAL_BASE] + fault_addr(ResetFault); + regs->pc = regs->ipr[IPR_PAL_BASE] + (new ResetFault)->vect(); regs->npc = regs->pc + sizeof(MachInst); } @@ -89,10 +89,10 @@ AlphaISA::fault_addr(Fault fault) { //Check for the system wide faults if(fault == NoFault) return 0x0000; - else if(fault == MachineCheckFault) return 0x0401; - else if(fault == AlignmentFault) return 0x0301; + else if(fault->isA()) return 0x0401; + else if(fault->isA()) return 0x0301; //Deal with the alpha specific faults - return ((AlphaFault*)fault)->vect; + return ((AlphaFault *)(fault.get()))->vect(); }; const int AlphaISA::reg_redir[AlphaISA::NumIntRegs] = { @@ -158,7 +158,7 @@ AlphaISA::processInterrupts(CPU *cpu) if (ipl && ipl > ipr[IPR_IPLR]) { ipr[IPR_ISR] = summary; ipr[IPR_INTID] = ipl; - cpu->trap(InterruptFault); + cpu->trap(new InterruptFault); DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n", ipr[IPR_IPLR], ipl, summary); } @@ -179,22 +179,22 @@ AlphaISA::zeroRegisters(CPU *cpu) void ExecContext::ev5_trap(Fault fault) { - DPRINTF(Fault, "Fault %s at PC: %#x\n", fault->name, regs.pc); - cpu->recordEvent(csprintf("Fault %s", fault->name)); + DPRINTF(Fault, "Fault %s at PC: %#x\n", fault->name(), regs.pc); + cpu->recordEvent(csprintf("Fault %s", fault->name())); assert(!misspeculating()); kernelStats->fault(fault); - if (fault == ArithmeticFault) + if (fault->isA()) panic("Arithmetic traps are unimplemented!"); AlphaISA::InternalProcReg *ipr = regs.ipr; // exception restart address - if (fault != InterruptFault || !inPalMode()) + if (!fault->isA() || !inPalMode()) ipr[AlphaISA::IPR_EXC_ADDR] = regs.pc; - if (fault == PalFault || fault == ArithmeticFault /* || + if (fault->isA() || fault->isA() /* || fault == InterruptFault && !inPalMode() */) { // traps... skip faulting instruction ipr[AlphaISA::IPR_EXC_ADDR] += 4; @@ -214,11 +214,11 @@ AlphaISA::intr_post(RegFile *regs, Fault fault, Addr pc) InternalProcReg *ipr = regs->ipr; bool use_pc = (fault == NoFault); - if (fault == ArithmeticFault) + if (fault->isA()) panic("arithmetic faults NYI..."); // compute exception restart address - if (use_pc || fault == PalFault || fault == ArithmeticFault) { + if (use_pc || fault->isA() || fault->isA()) { // traps... skip faulting instruction ipr[IPR_EXC_ADDR] = regs->pc + 4; } else { @@ -241,7 +241,7 @@ ExecContext::hwrei() uint64_t *ipr = regs.ipr; if (!inPalMode()) - return UnimplementedOpcodeFault; + return new UnimplementedOpcodeFault; setNextPC(ipr[AlphaISA::IPR_EXC_ADDR]); @@ -353,12 +353,12 @@ ExecContext::readIpr(int idx, Fault &fault) case AlphaISA::IPR_DTB_IAP: case AlphaISA::IPR_ITB_IA: case AlphaISA::IPR_ITB_IAP: - fault = UnimplementedOpcodeFault; + fault = new UnimplementedOpcodeFault; break; default: // invalid IPR - fault = UnimplementedOpcodeFault; + fault = new UnimplementedOpcodeFault; break; } @@ -523,7 +523,7 @@ ExecContext::setIpr(int idx, uint64_t val) case AlphaISA::IPR_ITB_PTE_TEMP: case AlphaISA::IPR_DTB_PTE_TEMP: // read-only registers - return UnimplementedOpcodeFault; + return new UnimplementedOpcodeFault; case AlphaISA::IPR_HWINT_CLR: case AlphaISA::IPR_SL_XMIT: @@ -625,7 +625,7 @@ ExecContext::setIpr(int idx, uint64_t val) default: // invalid IPR - return UnimplementedOpcodeFault; + return new UnimplementedOpcodeFault; } // no error... diff --git a/arch/alpha/faults.cc b/arch/alpha/faults.cc index fa4950198..bbddadabf 100644 --- a/arch/alpha/faults.cc +++ b/arch/alpha/faults.cc @@ -28,36 +28,67 @@ #include "arch/alpha/faults.hh" -ResetFaultType * const ResetFault = - new ResetFaultType("reset", 1, 0x0001); -ArithmeticFaultType * const ArithmeticFault = - new ArithmeticFaultType("arith", 3, 0x0501); -InterruptFaultType * const InterruptFault = - new InterruptFaultType("interrupt", 4, 0x0101); -NDtbMissFaultType * const NDtbMissFault = - new NDtbMissFaultType("dtb_miss_single", 5, 0x0201); -PDtbMissFaultType * const PDtbMissFault = - new PDtbMissFaultType("dtb_miss_double", 6, 0x0281); -DtbPageFaultType * const DtbPageFault = - new DtbPageFaultType("dfault", 8, 0x0381); -DtbAcvFaultType * const DtbAcvFault = - new DtbAcvFaultType("dfault", 9, 0x0381); -ItbMissFaultType * const ItbMissFault = - new ItbMissFaultType("itbmiss", 10, 0x0181); -ItbPageFaultType * const ItbPageFault = - new ItbPageFaultType("itbmiss", 11, 0x0181); -ItbAcvFaultType * const ItbAcvFault = - new ItbAcvFaultType("iaccvio", 12, 0x0081); -UnimplementedOpcodeFaultType * const UnimplementedOpcodeFault = - new UnimplementedOpcodeFaultType("opdec", 13, 0x0481); -FloatEnableFaultType * const FloatEnableFault = - new FloatEnableFaultType("fen", 14, 0x0581); -PalFaultType * const PalFault = - new PalFaultType("pal", 15, 0x2001); -IntegerOverflowFaultType * const IntegerOverflowFault = - new IntegerOverflowFaultType("intover", 16, 0x0501); +FaultName AlphaFault::_name = "alphafault"; +FaultVect AlphaFault::_vect = 0x0000; +FaultStat AlphaFault::_stat; -Fault * ListOfFaults[] = { +FaultName ResetFault::_name = "reset"; +FaultVect ResetFault::_vect = 0x0001; +FaultStat ResetFault::_stat; + +FaultName ArithmeticFault::_name = "arith"; +FaultVect ArithmeticFault::_vect = 0x0501; +FaultStat ArithmeticFault::_stat; + +FaultName InterruptFault::_name = "interrupt"; +FaultVect InterruptFault::_vect = 0x0101; +FaultStat InterruptFault::_stat; + +FaultName NDtbMissFault::_name = "dtb_miss_single"; +FaultVect NDtbMissFault::_vect = 0x0201; +FaultStat NDtbMissFault::_stat; + +FaultName PDtbMissFault::_name = "dtb_miss_double"; +FaultVect PDtbMissFault::_vect = 0x0281; +FaultStat PDtbMissFault::_stat; + +FaultName DtbPageFault::_name = "dfault"; +FaultVect DtbPageFault::_vect = 0x0381; +FaultStat DtbPageFault::_stat; + +FaultName DtbAcvFault::_name = "dfault"; +FaultVect DtbAcvFault::_vect = 0x0381; +FaultStat DtbAcvFault::_stat; + +FaultName ItbMissFault::_name = "itbmiss"; +FaultVect ItbMissFault::_vect = 0x0181; +FaultStat ItbMissFault::_stat; + +FaultName ItbPageFault::_name = "itbmiss"; +FaultVect ItbPageFault::_vect = 0x0181; +FaultStat ItbPageFault::_stat; + +FaultName ItbAcvFault::_name = "iaccvio"; +FaultVect ItbAcvFault::_vect = 0x0081; +FaultStat ItbAcvFault::_stat; + +FaultName UnimplementedOpcodeFault::_name = "opdec"; +FaultVect UnimplementedOpcodeFault::_vect = 0x0481; +FaultStat UnimplementedOpcodeFault::_stat; + +FaultName FloatEnableFault::_name = "fen"; +FaultVect FloatEnableFault::_vect = 0x0581; +FaultStat FloatEnableFault::_stat; + +FaultName PalFault::_name = "pal"; +FaultVect PalFault::_vect = 0x2001; +FaultStat PalFault::_stat; + +FaultName IntegerOverflowFault::_name = "intover"; +FaultVect IntegerOverflowFault::_vect = 0x0501; +FaultStat IntegerOverflowFault::_stat; + +/*Fault * ListOfFaults[] = { (Fault *)&NoFault, (Fault *)&ResetFault, (Fault *)&MachineCheckFault, @@ -77,4 +108,4 @@ Fault * ListOfFaults[] = { (Fault *)&IntegerOverflowFault, }; -int NumFaults = sizeof(ListOfFaults) / sizeof(Fault *); +int NumFaults = sizeof(ListOfFaults) / sizeof(Fault *);*/ diff --git a/arch/alpha/faults.hh b/arch/alpha/faults.hh index 3e25adc4e..bd5163a7d 100644 --- a/arch/alpha/faults.hh +++ b/arch/alpha/faults.hh @@ -30,131 +30,192 @@ #define __ALPHA_FAULTS_HH__ #include "sim/faults.hh" -#include "arch/isa_traits.hh" //For the Addr type + +// The reasoning behind the name and vect functions is in sim/faults.hh + +typedef const Addr FaultVect; class AlphaFault : public FaultBase { + private: + static FaultName _name; + static FaultVect _vect; + static FaultStat _stat; public: - AlphaFault(char * newName, int newId, Addr newVect) - : FaultBase(newName, newId), vect(newVect) - {;} - - Addr vect; + FaultName name() {return _name;} + virtual FaultVect vect() {return _vect;} + virtual FaultStat & stat() {return _stat;} }; -extern class ResetFaultType : public AlphaFault +class ResetFault : public AlphaFault { + private: + static FaultName _name; + static FaultVect _vect; + static FaultStat _stat; public: - ResetFaultType(char * newName, int newId, Addr newVect) - : AlphaFault(newName, newId, newVect) - {;} -} * const ResetFault; + FaultName name() {return _name;} + FaultVect vect() {return _vect;} + FaultStat & stat() {return _stat;} +}; -extern class ArithmeticFaultType : public AlphaFault +class ArithmeticFault : public AlphaFault { + private: + static FaultName _name; + static FaultVect _vect; + static FaultStat _stat; public: - ArithmeticFaultType(char * newName, int newId, Addr newVect) - : AlphaFault(newName, newId, newVect) - {;} -} * const ArithmeticFault; + FaultName name() {return _name;} + FaultVect vect() {return _vect;} + FaultStat & stat() {return _stat;} +}; -extern class InterruptFaultType : public AlphaFault +class InterruptFault : public AlphaFault { + private: + static FaultName _name; + static FaultVect _vect; + static FaultStat _stat; public: - InterruptFaultType(char * newName, int newId, Addr newVect) - : AlphaFault(newName, newId, newVect) - {;} -} * const InterruptFault; + FaultName name() {return _name;} + FaultVect vect() {return _vect;} + FaultStat & stat() {return _stat;} +}; -extern class NDtbMissFaultType : public AlphaFault +class NDtbMissFault : public AlphaFault { + private: + static FaultName _name; + static FaultVect _vect; + static FaultStat _stat; public: - NDtbMissFaultType(char * newName, int newId, Addr newVect) - : AlphaFault(newName, newId, newVect) - {;} -} * const NDtbMissFault; + FaultName name() {return _name;} + FaultVect vect() {return _vect;} + FaultStat & stat() {return _stat;} +}; -extern class PDtbMissFaultType : public AlphaFault +class PDtbMissFault : public AlphaFault { + private: + static FaultName _name; + static FaultVect _vect; + static FaultStat _stat; public: - PDtbMissFaultType(char * newName, int newId, Addr newVect) - : AlphaFault(newName, newId, newVect) - {;} -} * const PDtbMissFault; + FaultName name() {return _name;} + FaultVect vect() {return _vect;} + FaultStat & stat() {return _stat;} +}; -extern class DtbPageFaultType : public AlphaFault +class DtbPageFault : public AlphaFault { + private: + static FaultName _name; + static FaultVect _vect; + static FaultStat _stat; public: - DtbPageFaultType(char * newName, int newId, Addr newVect) - : AlphaFault(newName, newId, newVect) - {;} -} * const DtbPageFault; + FaultName name() {return _name;} + FaultVect vect() {return _vect;} + FaultStat & stat() {return _stat;} +}; -extern class DtbAcvFaultType : public AlphaFault +class DtbAcvFault : public AlphaFault { + private: + static FaultName _name; + static FaultVect _vect; + static FaultStat _stat; public: - DtbAcvFaultType(char * newName, int newId, Addr newVect) - : AlphaFault(newName, newId, newVect) - {;} -} * const DtbAcvFault; + FaultName name() {return _name;} + FaultVect vect() {return _vect;} + FaultStat & stat() {return _stat;} +}; -extern class ItbMissFaultType : public AlphaFault +class ItbMissFault : public AlphaFault { + private: + static FaultName _name; + static FaultVect _vect; + static FaultStat _stat; public: - ItbMissFaultType(char * newName, int newId, Addr newVect) - : AlphaFault(newName, newId, newVect) - {;} -} * const ItbMissFault; + FaultName name() {return _name;} + FaultVect vect() {return _vect;} + FaultStat & stat() {return _stat;} +}; -extern class ItbPageFaultType : public AlphaFault +class ItbPageFault : public AlphaFault { + private: + static FaultName _name; + static FaultVect _vect; + static FaultStat _stat; public: - ItbPageFaultType(char * newName, int newId, Addr newVect) - : AlphaFault(newName, newId, newVect) - {;} -} * const ItbPageFault; + FaultName name() {return _name;} + FaultVect vect() {return _vect;} + FaultStat & stat() {return _stat;} +}; -extern class ItbAcvFaultType : public AlphaFault +class ItbAcvFault : public AlphaFault { + private: + static FaultName _name; + static FaultVect _vect; + static FaultStat _stat; public: - ItbAcvFaultType(char * newName, int newId, Addr newVect) - : AlphaFault(newName, newId, newVect) - {;} -} * const ItbAcvFault; + FaultName name() {return _name;} + FaultVect vect() {return _vect;} + FaultStat & stat() {return _stat;} +}; -extern class UnimplementedOpcodeFaultType : public AlphaFault +class UnimplementedOpcodeFault : public AlphaFault { + private: + static FaultName _name; + static FaultVect _vect; + static FaultStat _stat; public: - UnimplementedOpcodeFaultType(char * newName, int newId, Addr newVect) - : AlphaFault(newName, newId, newVect) - {;} -} * const UnimplementedOpcodeFault; + FaultName name() {return _name;} + FaultVect vect() {return _vect;} + FaultStat & stat() {return _stat;} +}; -extern class FloatEnableFaultType : public AlphaFault +class FloatEnableFault : public AlphaFault { + private: + static FaultName _name; + static FaultVect _vect; + static FaultStat _stat; public: - FloatEnableFaultType(char * newName, int newId, Addr newVect) - : AlphaFault(newName, newId, newVect) - {;} -} * const FloatEnableFault; + FaultName name() {return _name;} + FaultVect vect() {return _vect;} + FaultStat & stat() {return _stat;} +}; -extern class PalFaultType : public AlphaFault +class PalFault : public AlphaFault { + private: + static FaultName _name; + static FaultVect _vect; + static FaultStat _stat; public: - PalFaultType(char * newName, int newId, Addr newVect) - : AlphaFault(newName, newId, newVect) - {;} -} * const PalFault; + FaultName name() {return _name;} + FaultVect vect() {return _vect;} + FaultStat & stat() {return _stat;} +}; -extern class IntegerOverflowFaultType : public AlphaFault +class IntegerOverflowFault : public AlphaFault { + private: + static FaultName _name; + static FaultVect _vect; + static FaultStat _stat; public: - IntegerOverflowFaultType(char * newName, int newId, Addr newVect) - : AlphaFault(newName, newId, newVect) - {;} -} * const IntegerOverflowFault; + FaultName name() {return _name;} + FaultVect vect() {return _vect;} + FaultStat & stat() {return _stat;} +}; -extern Fault * ListOfFaults[]; -extern int NumFaults; +//Fault * ListOfFaults[]; +//int NumFaults; #endif // __FAULTS_HH__ diff --git a/arch/alpha/isa/decoder.isa b/arch/alpha/isa/decoder.isa index 37b15416b..cdcf96215 100644 --- a/arch/alpha/isa/decoder.isa +++ b/arch/alpha/isa/decoder.isa @@ -98,7 +98,7 @@ decode OPCODE default Unknown::unknown() { // signed overflow occurs when operands have same sign // and sign of result does not match. if (Ra.sl<31:> == Rb_or_imm.sl<31:> && tmp<31:> != Ra.sl<31:>) - fault = IntegerOverflowFault; + fault = new IntegerOverflowFault; Rc.sl = tmp; }}); 0x02: s4addl({{ Rc.sl = (Ra.sl << 2) + Rb_or_imm.sl; }}); @@ -110,7 +110,7 @@ decode OPCODE default Unknown::unknown() { // signed overflow occurs when operands have same sign // and sign of result does not match. if (Ra<63:> == Rb_or_imm<63:> && tmp<63:> != Ra<63:>) - fault = IntegerOverflowFault; + fault = new IntegerOverflowFault; Rc = tmp; }}); 0x22: s4addq({{ Rc = (Ra << 2) + Rb_or_imm; }}); @@ -124,7 +124,7 @@ decode OPCODE default Unknown::unknown() { // sign bit of the subtrahend (Rb), i.e., if the initial // signs are the *same* then no overflow can occur if (Ra.sl<31:> != Rb_or_imm.sl<31:> && tmp<31:> != Ra.sl<31:>) - fault = IntegerOverflowFault; + fault = new IntegerOverflowFault; Rc.sl = tmp; }}); 0x0b: s4subl({{ Rc.sl = (Ra.sl << 2) - Rb_or_imm.sl; }}); @@ -138,7 +138,7 @@ decode OPCODE default Unknown::unknown() { // sign bit of the subtrahend (Rb), i.e., if the initial // signs are the *same* then no overflow can occur if (Ra<63:> != Rb_or_imm<63:> && tmp<63:> != Ra<63:>) - fault = IntegerOverflowFault; + fault = new IntegerOverflowFault; Rc = tmp; }}); 0x2b: s4subq({{ Rc = (Ra << 2) - Rb_or_imm; }}); @@ -299,7 +299,7 @@ decode OPCODE default Unknown::unknown() { // checking the upper 33 bits for all 0s or all 1s. uint64_t sign_bits = tmp<63:31>; if (sign_bits != 0 && sign_bits != mask(33)) - fault = IntegerOverflowFault; + fault = new IntegerOverflowFault; Rc.sl = tmp<31:0>; }}, IntMultOp); 0x60: mulqv({{ @@ -310,7 +310,7 @@ decode OPCODE default Unknown::unknown() { // the lower 64 if (!((hi == 0 && lo<63:> == 0) || (hi == mask(64) && lo<63:> == 1))) - fault = IntegerOverflowFault; + fault = new IntegerOverflowFault; Rc = lo; }}, IntMultOp); } @@ -427,19 +427,19 @@ decode OPCODE default Unknown::unknown() { #if SS_COMPATIBLE_FP 0x0b: sqrts({{ if (Fb < 0.0) - fault = ArithmeticFault; + fault = new ArithmeticFault; Fc = sqrt(Fb); }}, FloatSqrtOp); #else 0x0b: sqrts({{ if (Fb.sf < 0.0) - fault = ArithmeticFault; + fault = new ArithmeticFault; Fc.sf = sqrt(Fb.sf); }}, FloatSqrtOp); #endif 0x2b: sqrtt({{ if (Fb < 0.0) - fault = ArithmeticFault; + fault = new ArithmeticFault; Fc = sqrt(Fb); }}, FloatSqrtOp); } @@ -570,7 +570,7 @@ decode OPCODE default Unknown::unknown() { // checking the upper 33 bits for all 0s or all 1s. uint64_t sign_bits = Fb.uq<63:31>; if (sign_bits != 0 && sign_bits != mask(33)) - fault = IntegerOverflowFault; + fault = new IntegerOverflowFault; Fc.uq = (Fb.uq<31:30> << 62) | (Fb.uq<29:0> << 29); }}); @@ -673,7 +673,7 @@ decode OPCODE default Unknown::unknown() { && xc->readIpr(AlphaISA::IPR_ICM, fault) != AlphaISA::mode_kernel)) { // invalid pal function code, or attempt to do privileged // PAL call in non-kernel mode - fault = UnimplementedOpcodeFault; + fault = new UnimplementedOpcodeFault; } else { // check to see if simulator wants to do something special @@ -729,7 +729,7 @@ decode OPCODE default Unknown::unknown() { 0x19: hw_mfpr({{ // this instruction is only valid in PAL mode if (!xc->inPalMode()) { - fault = UnimplementedOpcodeFault; + fault = new UnimplementedOpcodeFault; } else { Ra = xc->readIpr(ipr_index, fault); @@ -738,7 +738,7 @@ decode OPCODE default Unknown::unknown() { 0x1d: hw_mtpr({{ // this instruction is only valid in PAL mode if (!xc->inPalMode()) { - fault = UnimplementedOpcodeFault; + fault = new UnimplementedOpcodeFault; } else { xc->setIpr(ipr_index, Ra); diff --git a/arch/alpha/isa/fp.isa b/arch/alpha/isa/fp.isa index 7e81fb830..2ee714b0f 100644 --- a/arch/alpha/isa/fp.isa +++ b/arch/alpha/isa/fp.isa @@ -36,7 +36,7 @@ output exec {{ { Fault fault = NoFault; // dummy... this ipr access should not fault if (!EV5::ICSR_FPE(xc->readIpr(AlphaISA::IPR_ICSR, fault))) { - fault = FloatEnableFault; + fault = new FloatEnableFault; } return fault; } diff --git a/arch/alpha/isa/unimp.isa b/arch/alpha/isa/unimp.isa index de4ac3eaf..09df39706 100644 --- a/arch/alpha/isa/unimp.isa +++ b/arch/alpha/isa/unimp.isa @@ -111,7 +111,7 @@ output exec {{ { panic("attempt to execute unimplemented instruction '%s' " "(inst 0x%08x, opcode 0x%x)", mnemonic, machInst, OPCODE); - return UnimplementedOpcodeFault; + return new UnimplementedOpcodeFault; } Fault diff --git a/arch/alpha/isa/unknown.isa b/arch/alpha/isa/unknown.isa index 4601b3684..47d166255 100644 --- a/arch/alpha/isa/unknown.isa +++ b/arch/alpha/isa/unknown.isa @@ -42,7 +42,7 @@ output exec {{ { panic("attempt to execute unknown instruction " "(inst 0x%08x, opcode 0x%x)", machInst, OPCODE); - return UnimplementedOpcodeFault; + return new UnimplementedOpcodeFault; } }}; diff --git a/base/refcnt.hh b/base/refcnt.hh index 9d9ed4337..de589f7c5 100644 --- a/base/refcnt.hh +++ b/base/refcnt.hh @@ -29,6 +29,8 @@ #ifndef __REFCNT_HH__ #define __REFCNT_HH__ +#include //For the NULL macro definition + class RefCounted { private: diff --git a/cpu/base_dyn_inst.cc b/cpu/base_dyn_inst.cc index 86314bef1..296717f2a 100644 --- a/cpu/base_dyn_inst.cc +++ b/cpu/base_dyn_inst.cc @@ -113,7 +113,7 @@ BaseDynInst::initVars() asid = 0; // Initialize the fault to be unimplemented opcode. - fault = UnimplementedOpcodeFault; + fault = new UnimplementedOpcodeFault; ++instcount; diff --git a/cpu/o3/alpha_cpu_impl.hh b/cpu/o3/alpha_cpu_impl.hh index 7ec1ba663..c0ec1fb33 100644 --- a/cpu/o3/alpha_cpu_impl.hh +++ b/cpu/o3/alpha_cpu_impl.hh @@ -280,7 +280,7 @@ AlphaFullCPU::hwrei() uint64_t *ipr = getIpr(); if (!inPalMode()) - return UnimplementedOpcodeFault; + return new UnimplementedOpcodeFault; this->setNextPC(ipr[AlphaISA::IPR_EXC_ADDR]); @@ -329,21 +329,21 @@ AlphaFullCPU::trap(Fault fault) // miss uint64_t PC = this->commit.readCommitPC(); - DPRINTF(Fault, "Fault %s\n", fault ? fault->name : "name"); - this->recordEvent(csprintf("Fault %s", fault ? fault->name : "name")); + DPRINTF(Fault, "Fault %s\n", fault->name()); + this->recordEvent(csprintf("Fault %s", fault->name())); -// kernelStats.fault(fault); + //kernelStats.fault(fault); - if (fault == ArithmeticFault) + if (fault->isA()) panic("Arithmetic traps are unimplemented!"); AlphaISA::InternalProcReg *ipr = getIpr(); // exception restart address - Get the commit PC - if (fault != InterruptFault || !inPalMode(PC)) + if (!fault->isA() || !inPalMode(PC)) ipr[AlphaISA::IPR_EXC_ADDR] = PC; - if (fault == PalFault || fault == ArithmeticFault /* || + if (fault->isA() || fault->isA() /* || fault == InterruptFault && !PC_PAL(regs.pc) */) { // traps... skip faulting instruction ipr[AlphaISA::IPR_EXC_ADDR] += 4; diff --git a/cpu/o3/regfile.hh b/cpu/o3/regfile.hh index ee7b8858e..7e36a6ead 100644 --- a/cpu/o3/regfile.hh +++ b/cpu/o3/regfile.hh @@ -372,12 +372,12 @@ PhysRegFile::readIpr(int idx, Fault &fault) case TheISA::IPR_DTB_IAP: case TheISA::IPR_ITB_IA: case TheISA::IPR_ITB_IAP: - fault = UnimplementedOpcodeFault; + fault = new UnimplementedOpcodeFault; break; default: // invalid IPR - fault = UnimplementedOpcodeFault; + fault = new UnimplementedOpcodeFault; break; } @@ -525,7 +525,7 @@ PhysRegFile::setIpr(int idx, uint64_t val) case TheISA::IPR_ITB_PTE_TEMP: case TheISA::IPR_DTB_PTE_TEMP: // read-only registers - return UnimplementedOpcodeFault; + return new UnimplementedOpcodeFault; case TheISA::IPR_HWINT_CLR: case TheISA::IPR_SL_XMIT: @@ -627,7 +627,7 @@ PhysRegFile::setIpr(int idx, uint64_t val) default: // invalid IPR - return UnimplementedOpcodeFault; + return new UnimplementedOpcodeFault; } // no error... diff --git a/cpu/simple/cpu.cc b/cpu/simple/cpu.cc index f7a6d2c21..d6f2ffd9f 100644 --- a/cpu/simple/cpu.cc +++ b/cpu/simple/cpu.cc @@ -334,7 +334,7 @@ SimpleCPU::copySrcTranslate(Addr src) // translate to physical address Fault fault = xc->translateDataReadReq(memReq); - assert(fault != AlignmentFault); + assert(!fault->isA()); if (fault == NoFault) { xc->copySrcAddr = src; @@ -369,7 +369,7 @@ SimpleCPU::copy(Addr dest) // translate to physical address Fault fault = xc->translateDataWriteReq(memReq); - assert(fault != AlignmentFault); + assert(!fault->isA()); if (fault == NoFault) { Addr dest_addr = memReq->paddr + offset; @@ -675,7 +675,7 @@ SimpleCPU::tick() if (ipl && ipl > xc->regs.ipr[IPR_IPLR]) { ipr[IPR_ISR] = summary; ipr[IPR_INTID] = ipl; - xc->ev5_trap(InterruptFault); + xc->ev5_trap(new InterruptFault); DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n", ipr[IPR_IPLR], ipl, summary); diff --git a/dev/alpha_console.cc b/dev/alpha_console.cc index 0f36e63fb..87d8c4e93 100644 --- a/dev/alpha_console.cc +++ b/dev/alpha_console.cc @@ -184,7 +184,7 @@ AlphaConsole::read(MemReqPtr &req, uint8_t *data) } break; default: - return MachineCheckFault; + return new MachineCheckFault; } return NoFault; @@ -204,7 +204,7 @@ AlphaConsole::write(MemReqPtr &req, const uint8_t *data) val = *(uint64_t *)data; break; default: - return MachineCheckFault; + return new MachineCheckFault; } Addr daddr = req->paddr - (addr & EV5::PAddrImplMask); @@ -257,7 +257,7 @@ AlphaConsole::write(MemReqPtr &req, const uint8_t *data) break; default: - return MachineCheckFault; + return new MachineCheckFault; } return NoFault; diff --git a/dev/pcidev.hh b/dev/pcidev.hh index 9427463bf..4f08c2cf9 100644 --- a/dev/pcidev.hh +++ b/dev/pcidev.hh @@ -272,7 +272,7 @@ PciDev::readBar(MemReqPtr &req, uint8_t *data) return readBar4(req, req->paddr - BARAddrs[4], data); if (isBAR(req->paddr, 5)) return readBar5(req, req->paddr - BARAddrs[5], data); - return MachineCheckFault; + return new MachineCheckFault; } inline Fault @@ -290,7 +290,7 @@ PciDev::writeBar(MemReqPtr &req, const uint8_t *data) return writeBar4(req, req->paddr - BARAddrs[4], data); if (isBAR(req->paddr, 5)) return writeBar5(req, req->paddr - BARAddrs[5], data); - return MachineCheckFault; + return new MachineCheckFault; } #endif // __DEV_PCIDEV_HH__ diff --git a/dev/sinic.cc b/dev/sinic.cc index c499d2f49..3f7226817 100644 --- a/dev/sinic.cc +++ b/dev/sinic.cc @@ -363,11 +363,11 @@ Device::read(MemReqPtr &req, uint8_t *data) assert(config.command & PCI_CMD_MSE); Fault fault = readBar(req, data); - if (fault == MachineCheckFault) { + if (fault->isA()) { panic("address does not map to a BAR pa=%#x va=%#x size=%d", req->paddr, req->vaddr, req->size); - return MachineCheckFault; + return new MachineCheckFault; } return fault; @@ -459,11 +459,11 @@ Device::write(MemReqPtr &req, const uint8_t *data) assert(config.command & PCI_CMD_MSE); Fault fault = writeBar(req, data); - if (fault == MachineCheckFault) { + if (fault->isA()) { panic("address does not map to a BAR pa=%#x va=%#x size=%d", req->paddr, req->vaddr, req->size); - return MachineCheckFault; + return new MachineCheckFault; } return fault; @@ -489,12 +489,17 @@ Device::writeBar0(MemReqPtr &req, Addr daddr, const uint8_t *data) panic("invalid size for %s: cpu=%d da=%#x pa=%#x va=%#x size=%d", info.name, cpu, daddr, req->paddr, req->vaddr, req->size); + //These are commmented out because when the DPRINTF below isn't used, + //these values aren't used and gcc issues a warning. With -Werror, + //this prevents compilation. //uint32_t reg32 = *(uint32_t *)data; - uint64_t reg64 = *(uint64_t *)data; + //uint64_t reg64 = *(uint64_t *)data; DPRINTF(EthernetPIO, "write %s: cpu=%d val=%#x da=%#x pa=%#x va=%#x size=%d\n", - info.name, cpu, info.size == 4 ? (*(uint32_t *)data) : reg64, daddr, - req->paddr, req->vaddr, req->size); + info.name, cpu, info.size == 4 ? + (*(uint32_t *)data) : + (*(uint32_t *)data), + daddr, req->paddr, req->vaddr, req->size); prepareWrite(cpu, index); diff --git a/kern/kernel_stats.cc b/kern/kernel_stats.cc index 50bbaee00..31a3049f1 100644 --- a/kern/kernel_stats.cc +++ b/kern/kernel_stats.cc @@ -136,7 +136,7 @@ Statistics::regStats(const string &_name) } } - _faults +/* _faults .init(NumFaults) .name(name() + ".faults") .desc("number of faults") @@ -147,7 +147,7 @@ Statistics::regStats(const string &_name) const char *str = (*ListOfFaults[i])->name; if (str) _faults.subname(i, str); - } + }*/ _mode .init(cpu_mode_num) diff --git a/kern/kernel_stats.hh b/kern/kernel_stats.hh index 02d78e4d9..4896a0705 100644 --- a/kern/kernel_stats.hh +++ b/kern/kernel_stats.hh @@ -151,7 +151,7 @@ class Statistics : public Serializable Stats::Vector<> _callpal; Stats::Vector<> _syscall; - Stats::Vector<> _faults; +// Stats::Vector<> _faults; Stats::Vector<> _mode; Stats::Vector<> _modeGood; @@ -178,10 +178,8 @@ class Statistics : public Serializable void hwrei() { _hwrei++; } void fault(Fault fault) { - if(fault == NoFault) _faults[0]++; - else if(fault == MachineCheckFault) _faults[2]++; - else if(fault == AlignmentFault) _faults[7]++; - else _faults[fault->id]++; + if(fault != NoFault) + fault->stat()++; }// FIXME: When there are no generic system fault objects, this will go back to _faults[fault]++; } void swpipl(int ipl); void mode(cpu_mode newmode); diff --git a/sim/faults.cc b/sim/faults.cc index 58a631263..17efaf1c4 100644 --- a/sim/faults.cc +++ b/sim/faults.cc @@ -28,9 +28,8 @@ #include "sim/faults.hh" -NoFaultType * const NoFault = new NoFaultType("none"); -MachineCheckFaultType * const MachineCheckFault = - new MachineCheckFaultType("mchk"); -AlignmentFaultType * const AlignmentFault = - new AlignmentFaultType("unalign"); +FaultName MachineCheckFault::_name = "mchk"; +FaultStat MachineCheckFault::_stat; +FaultName AlignmentFault::_name = "unalign"; +FaultStat AlignmentFault::_stat; diff --git a/sim/faults.hh b/sim/faults.hh index dbec399af..ea2e21a7d 100644 --- a/sim/faults.hh +++ b/sim/faults.hh @@ -29,34 +29,55 @@ #ifndef __FAULTS_HH__ #define __FAULTS_HH__ -class FaultBase; -typedef FaultBase * Fault; +#include "base/refcnt.hh" +#include "sim/stats.hh" -class FaultBase +class FaultBase; +typedef RefCountingPtr Fault; + +typedef const char * FaultName; +typedef Stats::Scalar<> FaultStat; + +// Each class has it's name statically define in _name, +// and has a virtual function to access it's name. +// The function is necessary because otherwise, all objects +// which are being accessed cast as a FaultBase * (namely +// all faults returned using the Fault type) will use the +// generic FaultBase name. + +class FaultBase : public RefCounted { -public: - FaultBase(char * newName, int newId = 0) : name(newName), id(newId) {;} - const char * name; - int id; + public: + virtual FaultName name() + { + return "none"; + } + virtual FaultStat & stat() = 0; + template + bool isA() {return dynamic_cast(this);} }; -extern class NoFaultType : public FaultBase -{ -public: - NoFaultType(char * newName) : FaultBase(newName) {;} -} * const NoFault; +static FaultBase * const NoFault __attribute__ ((unused)) = 0; -extern class MachineCheckFaultType : public FaultBase +class MachineCheckFault : public FaultBase { -public: - MachineCheckFaultType(char * newName) : FaultBase(newName) {;} -} * const MachineCheckFault; + private: + static FaultName _name; + static FaultStat _stat; + public: + FaultName name() {return _name;} + FaultStat & stat() {return _stat;} +}; -extern class AlignmentFaultType : public FaultBase +class AlignmentFault : public FaultBase { -public: - AlignmentFaultType(char * newName) : FaultBase(newName) {;} -} * const AlignmentFault; + private: + static FaultName _name; + static FaultStat _stat; + public: + FaultName name() {return _name;} + FaultStat & stat() {return _stat;} +}; #endif // __FAULTS_HH__ From 802fd04f640b34d713f7ef75142e51d3d82559b9 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 24 Feb 2006 03:51:21 -0500 Subject: [PATCH 099/180] Removed a stray ::. --HG-- extra : convert_revision : f6114b78e30e8cba5af6276042b0f043d8773739 --- cpu/o3/alpha_cpu.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpu/o3/alpha_cpu.hh b/cpu/o3/alpha_cpu.hh index b35bcf9e3..ea0aae41f 100644 --- a/cpu/o3/alpha_cpu.hh +++ b/cpu/o3/alpha_cpu.hh @@ -280,7 +280,7 @@ class AlphaFullCPU : public FullO3CPU #endif - return this->mem->write(req, (T)::htog(data)); + return this->mem->write(req, (T)htog(data)); } template From fcb9718dcd45240f447c91cac02185ff7985b197 Mon Sep 17 00:00:00 2001 From: Lisa Hsu Date: Fri, 24 Feb 2006 18:08:14 -0500 Subject: [PATCH 100/180] 1) make it pretty for large clusters 2) make subticks vertical so they can be longer 3) make inner and outer axes farther apart to make room for subtick's vertical labels --HG-- extra : convert_revision : 91a1aab3f1078921edd53428e6712744210c9f1b --- util/stats/barchart.py | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/util/stats/barchart.py b/util/stats/barchart.py index 3f202d9bf..dd3bf0180 100644 --- a/util/stats/barchart.py +++ b/util/stats/barchart.py @@ -151,9 +151,9 @@ class BarChart(ChartOptions): self.metaaxes.set_yticks([]) size = [0] * 4 size[0] = self.figure_size[0] - size[1] = self.figure_size[1] + .05 + size[1] = self.figure_size[1] + .12 size[2] = self.figure_size[2] - size[3] = self.figure_size[3] - .05 + size[3] = self.figure_size[3] - .12 self.axes = self.figure.add_axes(size) outer_axes = self.metaaxes inner_axes = self.axes @@ -163,12 +163,9 @@ class BarChart(ChartOptions): inner_axes = self.axes bars_in_group = len(self.chartdata) - if bars_in_group < 5: - width = 1.0 / ( bars_in_group + 1) - center = width / 2 - else: - width = .8 / bars_in_group - center = .1 + + width = 1.0 / ( bars_in_group + 1) + center = width / 2 bars = [] for i,stackdata in enumerate(self.chartdata): @@ -179,7 +176,7 @@ class BarChart(ChartOptions): ind = arange(len(bardata)) + i * width + center bar = self.axes.bar(ind, bardata, width, bottom=bottom, color=colors[i][j]) - if dim != 1: + if self.xsubticks is not None: self.metaaxes.bar(ind, [0] * len(bardata), width) stack.append(bar) bottom += bardata @@ -207,7 +204,7 @@ class BarChart(ChartOptions): if self.xsubticks is not None: inner_axes.set_xticks(arange((cshape[0] + 1)*cshape[2])*width + 2*center) self.xsubticks.append('') - inner_axes.set_xticklabels(self.xsubticks * cshape[2], fontsize=8) + inner_axes.set_xticklabels(self.xsubticks * cshape[2], fontsize=7, rotation=90) if self.legend is not None: if dim == 1: @@ -281,7 +278,6 @@ if __name__ == '__main__': chart1.legend = [ 'x%d' % x for x in xrange(myshape[-1]) ] chart1.xticks = [ 'xtick%d' % x for x in xrange(myshape[0]) ] chart1.title = 'this is the title' - chart1.figure_size = [0.1, 0.2, 0.7, 0.85 ] if len(myshape) > 2: chart1.xsubticks = [ '%d' % x for x in xrange(myshape[1]) ] chart1.graph() @@ -298,4 +294,4 @@ if __name__ == '__main__': chart2.savefig('/tmp/test2.png') chart2.savefig('/tmp/test2.ps') - pylab.myshow() +# pylab.show() From 25b39da69d4267b34a87b7324008b6d4480a2b09 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Sat, 25 Feb 2006 22:01:05 -0500 Subject: [PATCH 101/180] Since the delayed write stuff is gone, get rid of regWrite and merge it with writeBar0 --HG-- extra : convert_revision : 354642e0d528b6a5a7f2cdf0264d93e738b2d4eb --- dev/sinic.cc | 29 +++++++++-------------------- dev/sinic.hh | 1 - 2 files changed, 9 insertions(+), 21 deletions(-) diff --git a/dev/sinic.cc b/dev/sinic.cc index c499d2f49..a9363954b 100644 --- a/dev/sinic.cc +++ b/dev/sinic.cc @@ -489,30 +489,17 @@ Device::writeBar0(MemReqPtr &req, Addr daddr, const uint8_t *data) panic("invalid size for %s: cpu=%d da=%#x pa=%#x va=%#x size=%d", info.name, cpu, daddr, req->paddr, req->vaddr, req->size); - //uint32_t reg32 = *(uint32_t *)data; - uint64_t reg64 = *(uint64_t *)data; - DPRINTF(EthernetPIO, - "write %s: cpu=%d val=%#x da=%#x pa=%#x va=%#x size=%d\n", - info.name, cpu, info.size == 4 ? (*(uint32_t *)data) : reg64, daddr, - req->paddr, req->vaddr, req->size); - - prepareWrite(cpu, index); - - regWrite(daddr, cpu, data); - - return NoFault; -} - -void -Device::regWrite(Addr daddr, int cpu, const uint8_t *data) -{ - Addr index = daddr >> Regs::VirtualShift; - Addr raddr = daddr & Regs::VirtualMask; - uint32_t reg32 = *(uint32_t *)data; uint64_t reg64 = *(uint64_t *)data; VirtualReg &vnic = virtualRegs[index]; + DPRINTF(EthernetPIO, + "write %s: cpu=%d val=%#x da=%#x pa=%#x va=%#x size=%d\n", + info.name, cpu, info.size == 4 ? reg32 : reg64, daddr, + req->paddr, req->vaddr, req->size); + + prepareWrite(cpu, index); + switch (raddr) { case Regs::Config: changeConfig(reg32); @@ -559,6 +546,8 @@ Device::regWrite(Addr daddr, int cpu, const uint8_t *data) } break; } + + return NoFault; } void diff --git a/dev/sinic.hh b/dev/sinic.hh index 97ebf4c30..c4027be86 100644 --- a/dev/sinic.hh +++ b/dev/sinic.hh @@ -280,7 +280,6 @@ class Device : public Base Fault iprRead(Addr daddr, int cpu, uint64_t &result); Fault readBar0(MemReqPtr &req, Addr daddr, uint8_t *data); Fault writeBar0(MemReqPtr &req, Addr daddr, const uint8_t *data); - void regWrite(Addr daddr, int cpu, const uint8_t *data); Tick cacheAccess(MemReqPtr &req); /** From 63db9860cf4ef1bfdfe97bf7f276c27dc5d13eea Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Sat, 25 Feb 2006 22:57:46 -0500 Subject: [PATCH 103/180] Make sure cpu/static_inst_exec_sigs.hh get rebuilt when CPU_MODELS parameter changes. arch/SConscript: Fix typo in comment. cpu/SConscript: Convert exec signature generator to Action so we can add dependency on CPU_MODELS environment var. Print nicer string while we're at it. Also add some comments. --HG-- extra : convert_revision : bcb38a7941943cf071dac34cdbb2ece5456b8620 --- arch/SConscript | 2 +- cpu/SConscript | 32 +++++++++++++++++++++++++++++++- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/arch/SConscript b/arch/SConscript index d237b0b1f..142bd763b 100644 --- a/arch/SConscript +++ b/arch/SConscript @@ -70,7 +70,7 @@ def gen_switch_hdr_string(target, source, env): return "Generating ISA switch header " + str(target[0]) # Build SCons Action object. 'varlist' specifies env vars that this -# action depdnds on; when env['ALL_ISA_LIST'] changes these actions +# action depends on; when env['ALL_ISA_LIST'] changes these actions # should get re-executed. switch_hdr_action = Action(gen_switch_hdr, gen_switch_hdr_string, varlist=['ALL_ISA_LIST']) diff --git a/cpu/SConscript b/cpu/SConscript index dbe174660..af6bab4eb 100644 --- a/cpu/SConscript +++ b/cpu/SConscript @@ -32,13 +32,28 @@ import os.path # Import build environment variable from SConstruct. Import('env') +################################################################# +# +# Generate StaticInst execute() method signatures. +# +# There must be one signature for each CPU model compiled in. +# Since the set of compiled-in models is flexible, we generate a +# header containing the appropriate set of signatures on the fly. +# +################################################################# + +# CPU model-specific data is contained in cpu_models.py +# Convert to SCons File node to get path handling models_db = File('cpu_models.py') +# slurp in contents of file execfile(models_db.srcnode().abspath) +# Template for execute() signature. exec_sig_template = ''' virtual Fault execute(%s *xc, Trace::InstRecord *traceData) const = 0; ''' +# Generate header. def gen_cpu_exec_signatures(target, source, env): f = open(str(target[0]), 'w') print >> f, ''' @@ -52,7 +67,22 @@ def gen_cpu_exec_signatures(target, source, env): #endif // __CPU_STATIC_INST_EXEC_SIGS_HH__ ''' -env.Command('static_inst_exec_sigs.hh', models_db, gen_cpu_exec_signatures) +# Generate string that gets printed when header is rebuilt +def gen_sigs_string(target, source, env): + return "Generating static_inst_exec_sigs.hh: " \ + + ', '.join(env['CPU_MODELS']) + +# Add command to generate header to environment. +env.Command('static_inst_exec_sigs.hh', models_db, + Action(gen_cpu_exec_signatures, gen_sigs_string, + varlist = ['CPU_MODELS'])) + +################################################################# +# +# Include CPU-model-specific files based on set of models +# specified in CPU_MODELS build option. +# +################################################################# sources = [] From 46189e9e2b4d36cb2aa3587919cb4d532118fa9c Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Sat, 25 Feb 2006 23:48:13 -0500 Subject: [PATCH 104/180] better colors for barcharts util/stats/barchart.py: If there are fewer than 5 colors, pick from a subset of 5 so there is more consistency in colors between graphs --HG-- extra : convert_revision : 6cf64c2f8ed81e714e24a3ebe5a7a60ca168b231 --- util/stats/barchart.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/util/stats/barchart.py b/util/stats/barchart.py index dd3bf0180..87d0eb5bb 100644 --- a/util/stats/barchart.py +++ b/util/stats/barchart.py @@ -47,8 +47,11 @@ class BarChart(ChartOptions): cmap = matplotlib.cm.get_cmap(self.colormap) if count == 1: return cmap([ 0.5 ]) - else: - return cmap(arange(count) / float(count - 1)) + + if count < 5: + return cmap(arange(5) / float(4))[:count] + + return cmap(arange(count) / float(count - 1)) # The input data format does not match the data format that the # graph function takes because it is intuitive. The conversion From cf3667a0e435fe707cf318caecc151c4b311b755 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Sun, 26 Feb 2006 00:11:54 -0500 Subject: [PATCH 105/180] add error bars and more options for legend placement util/stats/barchart.py: Add support for error bars util/stats/barchart.py: add support to choose between a legend inside or outside the figure. --HG-- extra : convert_revision : 14273e385c106bf27a2013991f9f34ca6551b96c --- util/stats/barchart.py | 44 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 41 insertions(+), 3 deletions(-) diff --git a/util/stats/barchart.py b/util/stats/barchart.py index 87d0eb5bb..f26a88d51 100644 --- a/util/stats/barchart.py +++ b/util/stats/barchart.py @@ -42,6 +42,8 @@ class BarChart(ChartOptions): super(BarChart, self).__init__(default, **kwargs) self.inputdata = None self.chartdata = None + self.inputerr = None + self.charterr = None def gen_colors(self, count): cmap = matplotlib.cm.get_cmap(self.colormap) @@ -92,6 +94,32 @@ class BarChart(ChartOptions): data = property(get_data, set_data) + def set_err(self, err): + if err is None: + self.inputerr = None + self.charterr = None + return + + err = array(err) + dim = len(shape(err)) + if dim not in (1, 2, 3): + raise AttributeError, "Input err must be a 1, 2, or 3d matrix" + self.inputerr = err + + if dim == 1: + self.charterr = array([[err]]) + + if dim == 2: + self.charterr = transpose([err], axes=(2,0,1)) + + if dim == 3: + self.charterr = transpose(err, axes=(1,2,0)) + + def get_err(self): + return self.inputerr + + err = property(get_err, set_err) + # Graph the chart data. # Input is a 3d matrix that describes a plot that has multiple # groups, multiple bars in each group, and multiple values stacked @@ -126,6 +154,9 @@ class BarChart(ChartOptions): dim = len(shape(self.inputdata)) cshape = shape(self.chartdata) + if self.charterr is not None and shape(self.charterr) != cshape: + raise AttributeError, 'Dimensions of error and data do not match' + if dim == 1: colors = self.gen_colors(cshape[2]) colors = [ [ colors ] * cshape[1] ] * cshape[0] @@ -177,8 +208,11 @@ class BarChart(ChartOptions): for j,bardata in enumerate(stackdata): bardata = array(bardata) ind = arange(len(bardata)) + i * width + center + yerr = None + if self.charterr is not None: + yerr = self.charterr[i][j] bar = self.axes.bar(ind, bardata, width, bottom=bottom, - color=colors[i][j]) + color=colors[i][j], yerr=yerr) if self.xsubticks is not None: self.metaaxes.bar(ind, [0] * len(bardata), width) stack.append(bar) @@ -218,8 +252,12 @@ class BarChart(ChartOptions): number = len(bars[0]) lbars = [ bars[0][number - j - 1][0] for j in xrange(number)] - self.figure.legend(lbars, self.legend, self.legend_loc, - prop=FontProperties(size=self.legend_size)) + if self.fig_legend: + self.figure.legend(lbars, self.legend, self.legend_loc, + prop=FontProperties(size=self.legend_size)) + else: + self.axes.legend(lbars, self.legend, self.legend_loc, + prop=FontProperties(size=self.legend_size)) if self.title is not None: self.axes.set_title(self.title) From 0d71a17ed89cc1cfa3b2b2b5b2844687c45c2102 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Sun, 26 Feb 2006 00:19:02 -0500 Subject: [PATCH 106/180] forgot to add a chart option util/stats/chart.py: add a bool config option for determining if the legend is inside or outside the figure --HG-- extra : convert_revision : e862d1832a0cc3c1837758cc247bc77c0a02ec12 --- util/stats/chart.py | 1 + 1 file changed, 1 insertion(+) diff --git a/util/stats/chart.py b/util/stats/chart.py index 095620172..369a57fc6 100644 --- a/util/stats/chart.py +++ b/util/stats/chart.py @@ -31,6 +31,7 @@ class ChartOptions(object): defaults = { 'chart_size' : (8, 4), 'figure_size' : [0.1, 0.1, 0.6, 0.85], 'title' : None, + 'fig_legend' : True, 'legend' : None, 'legend_loc' : 'upper right', 'legend_size' : 6, From b7e4d16ea94bbfe49ac3baa5e73f04d44ee2f2f0 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Sun, 26 Feb 2006 00:35:10 -0500 Subject: [PATCH 107/180] code cleanup util/stats/barchart.py: clean up some of lisa's messy code remove trailing whitespace while I'm at it. --HG-- extra : convert_revision : f2fe6777fb4b458fa1d5b5b743f6274014c229ad --- util/stats/barchart.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/util/stats/barchart.py b/util/stats/barchart.py index f26a88d51..5d6dd0ab1 100644 --- a/util/stats/barchart.py +++ b/util/stats/barchart.py @@ -177,7 +177,8 @@ class BarChart(ChartOptions): inner_axes = None if self.xsubticks is not None: color = self.figure.get_facecolor() - self.metaaxes = self.figure.add_axes(self.figure_size, axisbg=color, frameon=False) + self.metaaxes = self.figure.add_axes(self.figure_size, + axisbg=color, frameon=False) for tick in self.metaaxes.xaxis.majorTicks: tick.tick1On = False tick.tick2On = False @@ -239,9 +240,11 @@ class BarChart(ChartOptions): outer_axes.set_xticklabels(self.xticks) if self.xsubticks is not None: - inner_axes.set_xticks(arange((cshape[0] + 1)*cshape[2])*width + 2*center) + numticks = (cshape[0] + 1) * cshape[2] + inner_axes.set_xticks(arange(numticks) * width + 2 * center) self.xsubticks.append('') - inner_axes.set_xticklabels(self.xsubticks * cshape[2], fontsize=7, rotation=90) + inner_axes.set_xticklabels(self.xsubticks * cshape[2], fontsize=7, + rotation=90) if self.legend is not None: if dim == 1: @@ -281,7 +284,7 @@ class BarChart(ChartOptions): ylabel = [] #if self.ylabel: # ylabel = [ self.ylabel[i] ] - f.write(', '.join(ylabel + [ '%f' % val for val in row]) + '\n') + f.write(', '.join(ylabel + [ '%f' % v for v in row]) + '\n') if dim == 3: f.write("don't do 3D csv files\n") pass From 2c3e8d148cd349e5cb73c0d018271d171da0571c Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Sun, 26 Feb 2006 00:57:37 -0500 Subject: [PATCH 108/180] fix small python bug in database processing code util/stats/db.py: fix usage of hasattr --HG-- extra : convert_revision : b384e1efeda76921c565f9f391694c27273edcec --- util/stats/db.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/stats/db.py b/util/stats/db.py index d9b78c7d1..c0e7796eb 100644 --- a/util/stats/db.py +++ b/util/stats/db.py @@ -158,7 +158,7 @@ class Database(object): return None from info import ProxyError, scalar, vector, value, values, total, len - if system is None and hasattr('system', job): + if system is None and hasattr(job, 'system'): system = job.system if system is not None: From 57092567bac410c521738c7d30affa57c7b45b96 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Sun, 26 Feb 2006 01:00:15 -0500 Subject: [PATCH 109/180] better function categorization util/stats/categories.py: bit more stuff for categorizing functions --HG-- extra : convert_revision : 03617246a9254a580684dce82836517d1efdfc5b --- util/stats/categories.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/util/stats/categories.py b/util/stats/categories.py index 8d5d506a2..6d8568879 100644 --- a/util/stats/categories.py +++ b/util/stats/categories.py @@ -1,4 +1,4 @@ -# Copyright (c) 2005 The Regents of The University of Michigan +# Copyright (c) 2005-2006 The Regents of The University of Michigan # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -33,10 +33,14 @@ func_categories = { \ 'skb_clone_fraglist' : 'buffer', 'skb_seq_read' : 'buffer', 'sock_alloc_send_skb' : 'buffer', + 'sinic_rxskb_alloc' : 'buffer', # Copy functions + 'sinic_copyfrom' : 'copy', '__copy_user' : 'copy', 'skb_copy_bits' : 'copy', + 'skb_copy_datagram_iovec' : 'copy', + 'sinic_vcopy_iov' : 'idle', # Driver functions 'do_tx_done' : 'driver', From 10fcad4ce099118fde1e61a907fb96abd617ac68 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Sun, 26 Feb 2006 10:44:01 -0500 Subject: [PATCH 110/180] Allow graph_group to not be selected so we can have a normal ungrouped barchart --HG-- extra : convert_revision : 7d55440c9bb060607eddbb72448a3413944bb6ba --- util/stats/output.py | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/util/stats/output.py b/util/stats/output.py index e67751bbc..abfb8d901 100644 --- a/util/stats/output.py +++ b/util/stats/output.py @@ -1,4 +1,4 @@ -# Copyright (c) 2005 The Regents of The University of Michigan +# Copyright (c) 2005-2006 The Regents of The University of Michigan # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -103,15 +103,17 @@ class StatOutput(ChartOptions): else: groups.append(group) - if not groupopts: - raise AttributeError, 'No group selected for graph group' + has_group = bool(groupopts) + if has_group: + groupopts = [ group for group in crossproduct(groupopts) ] + else: + groupopts = [ None ] - if not baropts: + if baropts: + baropts = [ bar for bar in crossproduct(baropts) ] + else: raise AttributeError, 'No group selected for graph bars' - groupopts = [ group for group in crossproduct(groupopts) ] - baropts = [ bar for bar in crossproduct(baropts) ] - directory = expanduser(graphdir) if not isdir(directory): os.mkdir(directory) @@ -124,12 +126,13 @@ class StatOutput(ChartOptions): for options in self.jobfile.options(groups): chart = BarChart(self) - data = zeros((len(groupopts), len(baropts)), Float) data = [ [ None ] * len(baropts) for i in xrange(len(groupopts)) ] enabled = False stacked = 0 for g,gopt in enumerate(groupopts): for b,bopt in enumerate(baropts): + if gopt is None: + gopt = [] job = self.jobfile.job(options + gopt + bopt) if not job: continue @@ -168,19 +171,24 @@ class StatOutput(ChartOptions): if data.sum() == 0: continue + dim = len(data.shape) x = data.shape[0] - y = data.shape[1] xkeep = [ i for i in xrange(x) if data[i].sum() != 0 ] + y = data.shape[1] ykeep = [ i for i in xrange(y) if data[:,i].sum() != 0 ] data = data.take(xkeep, axis=0) data = data.take(ykeep, axis=1) + if not has_group: + data = data.take([ 0 ], axis=0) chart.data = data - gopts = [ groupopts[i] for i in xkeep ] - bopts = [ baropts[i] for i in ykeep ] + bopts = [ baropts[i] for i in ykeep ] bdescs = [ ' '.join([o.desc for o in opt]) for opt in bopts] - gdescs = [ ' '.join([o.desc for o in opt]) for opt in gopts] + + if has_group: + gopts = [ groupopts[i] for i in xkeep ] + gdescs = [ ' '.join([o.desc for o in opt]) for opt in gopts] if chart.legend is None: if stacked: @@ -192,7 +200,10 @@ class StatOutput(ChartOptions): chart.legend = bdescs if chart.xticks is None: - chart.xticks = gdescs + if has_group: + chart.xticks = gdescs + else: + chart.xticks = [] chart.graph() names = [ opt.name for opt in options ] From 9b18c0e87272b35a34e39ce2a9924963402e5b29 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Sun, 26 Feb 2006 20:31:08 -0500 Subject: [PATCH 111/180] add some support for random access of data in packet fifos dev/pktfifo.cc: add support for copying arbitrary data out of a packet fifo dev/pktfifo.hh: add support for copying arbitrary data out of a packet fifo. Add functions to determine where in the fifo a particular packet is --HG-- extra : convert_revision : f8ddc994ce8577f29af0de3fa418a01e4e2cb0f1 --- dev/pktfifo.cc | 34 ++++++++++++++++++++++++++++++++-- dev/pktfifo.hh | 29 +++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 2 deletions(-) diff --git a/dev/pktfifo.cc b/dev/pktfifo.cc index b4fab2d6f..639009be9 100644 --- a/dev/pktfifo.cc +++ b/dev/pktfifo.cc @@ -31,6 +31,36 @@ using namespace std; +bool +PacketFifo::copyout(void *dest, int offset, int len) +{ + char *data = (char *)dest; + if (offset + len >= size()) + return false; + + list::iterator p = fifo.begin(); + list::iterator end = fifo.end(); + while (len > 0) { + while (offset >= (*p)->length) { + offset -= (*p)->length; + ++p; + } + + if (p == end) + panic("invalid fifo"); + + int size = min((*p)->length - offset, len); + memcpy(data, (*p)->data, size); + offset = 0; + len -= size; + data += size; + ++p; + } + + return true; +} + + void PacketFifo::serialize(const string &base, ostream &os) { @@ -40,8 +70,8 @@ PacketFifo::serialize(const string &base, ostream &os) paramOut(os, base + ".packets", fifo.size()); int i = 0; - std::list::iterator p = fifo.begin(); - std::list::iterator end = fifo.end(); + list::iterator p = fifo.begin(); + list::iterator end = fifo.end(); while (p != end) { (*p)->serialize(csprintf("%s.packet%d", base, i), os); ++p; diff --git a/dev/pktfifo.hh b/dev/pktfifo.hh index e63fd291f..e245840a8 100644 --- a/dev/pktfifo.hh +++ b/dev/pktfifo.hh @@ -127,6 +127,35 @@ class PacketFifo fifo.erase(i); } + bool copyout(void *dest, int offset, int len); + + int countPacketsBefore(iterator end) + { + iterator i = fifo.begin(); + int count = 0; + + while (i != end) { + ++count; + ++i; + } + + return count; + } + + int countPacketsAfter(iterator i) + { + iterator end = fifo.end(); + int count = 0; + + while (i != end) { + ++count; + ++i; + } + + return count; + } + + /** * Serialization stuff */ From 29f50d934549f10b073a5492bd0d441d71534ace Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Sun, 26 Feb 2006 23:06:21 -0500 Subject: [PATCH 112/180] fix some minor stats stuff util/stats/stats.py: fix up a few of the stats. --HG-- extra : convert_revision : 61c600cd146900c8cc0cf60a9036f2e999a5e244 --- util/stats/stats.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/util/stats/stats.py b/util/stats/stats.py index b75d9fec0..08281287f 100755 --- a/util/stats/stats.py +++ b/util/stats/stats.py @@ -262,6 +262,7 @@ def commands(options, command, args): from output import StatOutput output = StatOutput(options.jobfile, source) output.xlabel = 'System Configuration' + output.colormap = 'RdYlGn' if command == 'stat' or command == 'formula': if len(args) != 1: @@ -286,7 +287,6 @@ def commands(options, command, args): raise CommandException from info import ProxyGroup - sim_seconds = source['sim_seconds'] proxy = ProxyGroup(system = source[options.system]) system = proxy.system @@ -294,7 +294,6 @@ def commands(options, command, args): bytes = etherdev.rxBytes + etherdev.txBytes kbytes = bytes / 1024 packets = etherdev.rxPackets + etherdev.txPackets - bps = etherdev.rxBandwidth + etherdev.txBandwidth def display(): if options.graph: @@ -337,7 +336,7 @@ def commands(options, command, args): return if command == 'pps': - output.stat = packets / sim_seconds + output.stat = packets / source['sim_seconds'] output.ylabel = 'Packets/s' display() return @@ -355,7 +354,7 @@ def commands(options, command, args): if command == 'txbps': output.stat = etherdev.txBandwidth / 1e9 if command == 'bps': - output.stat = bps / 1e9 + output.stat = (etherdev.rxBandwidth + etherdev.txBandwidth) / 1e9 output.ylabel = 'Bandwidth (Gbps)' output.ylim = [ 0.0, 10.0 ] From 4b256577e01111e676f021c67478afec2289e175 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Mon, 27 Feb 2006 01:32:49 -0500 Subject: [PATCH 113/180] Where architecture independent sources included arch/alpha/xxx.hh, they were changed to include targetarch/xxx.hh cpu/base_dyn_inst.cc: cpu/o3/bpred_unit.hh: cpu/o3/comm.hh: cpu/o3/cpu.hh: cpu/o3/regfile.hh: cpu/ozone/cpu_impl.hh: cpu/ozone/ea_list.cc: cpu/ozone/ea_list.hh: kern/kernel_stats.cc: Changed arch/alpha to targetarch sim/process.cc: Changed arch/alpha to targetarch, and removed gaurding ifdef --HG-- extra : convert_revision : 3c29e6baeb1cd900f7b5e11144a5d547a6c7c5ab --- cpu/base_dyn_inst.cc | 2 +- cpu/o3/bpred_unit.hh | 2 +- cpu/o3/comm.hh | 2 +- cpu/o3/cpu.hh | 2 +- cpu/o3/regfile.hh | 6 +++--- cpu/ozone/cpu_impl.hh | 2 +- cpu/ozone/ea_list.cc | 2 +- cpu/ozone/ea_list.hh | 2 +- kern/kernel_stats.cc | 2 +- sim/process.cc | 6 ++---- 10 files changed, 13 insertions(+), 15 deletions(-) diff --git a/cpu/base_dyn_inst.cc b/cpu/base_dyn_inst.cc index 296717f2a..633c0ee28 100644 --- a/cpu/base_dyn_inst.cc +++ b/cpu/base_dyn_inst.cc @@ -36,7 +36,7 @@ #include "base/cprintf.hh" #include "base/trace.hh" -#include "arch/alpha/faults.hh" +#include "targetarch/faults.hh" #include "cpu/exetrace.hh" #include "mem/mem_req.hh" diff --git a/cpu/o3/bpred_unit.hh b/cpu/o3/bpred_unit.hh index 0a77b83dc..786ed861d 100644 --- a/cpu/o3/bpred_unit.hh +++ b/cpu/o3/bpred_unit.hh @@ -30,7 +30,7 @@ #define __BPRED_UNIT_HH__ // For Addr type. -#include "arch/alpha/isa_traits.hh" +#include "targetarch/isa_traits.hh" #include "base/statistics.hh" #include "cpu/inst_seq.hh" diff --git a/cpu/o3/comm.hh b/cpu/o3/comm.hh index e4de1d304..76ff4d689 100644 --- a/cpu/o3/comm.hh +++ b/cpu/o3/comm.hh @@ -31,7 +31,7 @@ #include -#include "arch/alpha/isa_traits.hh" +#include "targetarch/isa_traits.hh" #include "cpu/inst_seq.hh" #include "sim/host.hh" diff --git a/cpu/o3/cpu.hh b/cpu/o3/cpu.hh index 321d61dce..f9e449548 100644 --- a/cpu/o3/cpu.hh +++ b/cpu/o3/cpu.hh @@ -50,7 +50,7 @@ #include "sim/process.hh" #if FULL_SYSTEM -#include "arch/alpha/ev5.hh" +#include "targetarch/ev5.hh" using namespace EV5; #endif diff --git a/cpu/o3/regfile.hh b/cpu/o3/regfile.hh index 7e36a6ead..85df06b76 100644 --- a/cpu/o3/regfile.hh +++ b/cpu/o3/regfile.hh @@ -31,14 +31,14 @@ // @todo: Destructor -#include "arch/alpha/isa_traits.hh" -#include "arch/alpha/faults.hh" +#include "targetarch/isa_traits.hh" +#include "targetarch/faults.hh" #include "base/trace.hh" #include "config/full_system.hh" #include "cpu/o3/comm.hh" #if FULL_SYSTEM -#include "arch/alpha/ev5.hh" +#include "targetarch/ev5.hh" #include "kern/kernel_stats.hh" using namespace EV5; diff --git a/cpu/ozone/cpu_impl.hh b/cpu/ozone/cpu_impl.hh index 009a81b98..581a72520 100644 --- a/cpu/ozone/cpu_impl.hh +++ b/cpu/ozone/cpu_impl.hh @@ -29,7 +29,7 @@ #ifndef __CPU_OOO_CPU_OOO_IMPL_HH__ #define __CPU_OOO_CPU_OOO_IMPL_HH__ -#include "arch/alpha/isa_traits.hh" +#include "targetarch/isa_traits.hh" template class OoOCPU; diff --git a/cpu/ozone/ea_list.cc b/cpu/ozone/ea_list.cc index 80cf80fb8..e7922902a 100644 --- a/cpu/ozone/ea_list.cc +++ b/cpu/ozone/ea_list.cc @@ -26,7 +26,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "arch/alpha/isa_traits.hh" +#include "targetarch/isa_traits.hh" #include "cpu/inst_seq.hh" #include "cpu/ooo_cpu/ea_list.hh" diff --git a/cpu/ozone/ea_list.hh b/cpu/ozone/ea_list.hh index def7e67d5..8eee3b1ec 100644 --- a/cpu/ozone/ea_list.hh +++ b/cpu/ozone/ea_list.hh @@ -32,7 +32,7 @@ #include #include -#include "arch/alpha/isa_traits.hh" +#include "targetarch/isa_traits.hh" #include "cpu/inst_seq.hh" /** diff --git a/kern/kernel_stats.cc b/kern/kernel_stats.cc index 31a3049f1..ff65389d2 100644 --- a/kern/kernel_stats.cc +++ b/kern/kernel_stats.cc @@ -30,7 +30,7 @@ #include #include -#include "arch/alpha/osfpal.hh" +#include "targetarch/osfpal.hh" #include "base/trace.hh" #include "cpu/exec_context.hh" #include "kern/kernel_stats.hh" diff --git a/sim/process.cc b/sim/process.cc index 0a7e46082..171470eb2 100644 --- a/sim/process.cc +++ b/sim/process.cc @@ -48,10 +48,8 @@ #include "sim/stats.hh" #include "sim/syscall_emul.hh" -#ifdef TARGET_ALPHA -#include "arch/alpha/alpha_tru64_process.hh" -#include "arch/alpha/alpha_linux_process.hh" -#endif +#include "targetarch/alpha_tru64_process.hh" +#include "targetarch/alpha_linux_process.hh" using namespace std; using namespace TheISA; From 1a0b326f5d4fafaef206a97ddd02598e120aebb9 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Mon, 27 Feb 2006 01:38:47 -0500 Subject: [PATCH 114/180] Changed targetarch to arch for isa_traits.hh include --HG-- extra : convert_revision : e7ae43d812140ec99b782394e54903153f8d0476 --- cpu/o3/bpred_unit.hh | 2 +- cpu/o3/comm.hh | 2 +- cpu/o3/regfile.hh | 2 +- cpu/ozone/cpu_impl.hh | 2 +- cpu/ozone/ea_list.cc | 2 +- cpu/ozone/ea_list.hh | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/cpu/o3/bpred_unit.hh b/cpu/o3/bpred_unit.hh index 786ed861d..2725684f7 100644 --- a/cpu/o3/bpred_unit.hh +++ b/cpu/o3/bpred_unit.hh @@ -30,7 +30,7 @@ #define __BPRED_UNIT_HH__ // For Addr type. -#include "targetarch/isa_traits.hh" +#include "arch/isa_traits.hh" #include "base/statistics.hh" #include "cpu/inst_seq.hh" diff --git a/cpu/o3/comm.hh b/cpu/o3/comm.hh index 76ff4d689..c74c77ddf 100644 --- a/cpu/o3/comm.hh +++ b/cpu/o3/comm.hh @@ -31,7 +31,7 @@ #include -#include "targetarch/isa_traits.hh" +#include "arch/isa_traits.hh" #include "cpu/inst_seq.hh" #include "sim/host.hh" diff --git a/cpu/o3/regfile.hh b/cpu/o3/regfile.hh index 85df06b76..9009db919 100644 --- a/cpu/o3/regfile.hh +++ b/cpu/o3/regfile.hh @@ -31,7 +31,7 @@ // @todo: Destructor -#include "targetarch/isa_traits.hh" +#include "arch/isa_traits.hh" #include "targetarch/faults.hh" #include "base/trace.hh" #include "config/full_system.hh" diff --git a/cpu/ozone/cpu_impl.hh b/cpu/ozone/cpu_impl.hh index 581a72520..e7ed3cfe0 100644 --- a/cpu/ozone/cpu_impl.hh +++ b/cpu/ozone/cpu_impl.hh @@ -29,7 +29,7 @@ #ifndef __CPU_OOO_CPU_OOO_IMPL_HH__ #define __CPU_OOO_CPU_OOO_IMPL_HH__ -#include "targetarch/isa_traits.hh" +#include "arch/isa_traits.hh" template class OoOCPU; diff --git a/cpu/ozone/ea_list.cc b/cpu/ozone/ea_list.cc index e7922902a..6114a0ca1 100644 --- a/cpu/ozone/ea_list.cc +++ b/cpu/ozone/ea_list.cc @@ -26,7 +26,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "targetarch/isa_traits.hh" +#include "arch/isa_traits.hh" #include "cpu/inst_seq.hh" #include "cpu/ooo_cpu/ea_list.hh" diff --git a/cpu/ozone/ea_list.hh b/cpu/ozone/ea_list.hh index 8eee3b1ec..c0eee4bb8 100644 --- a/cpu/ozone/ea_list.hh +++ b/cpu/ozone/ea_list.hh @@ -32,7 +32,7 @@ #include #include -#include "targetarch/isa_traits.hh" +#include "arch/isa_traits.hh" #include "cpu/inst_seq.hh" /** From 444f520f7e2da9468fa622dcf51859915bd31fd6 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Mon, 27 Feb 2006 03:57:15 -0500 Subject: [PATCH 115/180] MachineCheckFaults and AlignmentFaults are now generated by the ISA, rather than being created directly. arch/alpha/alpha_memory.cc: cpu/base_dyn_inst.cc: dev/alpha_console.cc: dev/pcidev.hh: dev/sinic.cc: MachineCheckFaults are now generated by the ISA, rather than being created directly. --HG-- extra : convert_revision : 34a7da41639e93be21ed70dac681b27480008d19 --- arch/alpha/alpha_memory.cc | 6 +++--- arch/alpha/faults.cc | 4 ++++ arch/alpha/faults.hh | 31 +++++++++++++++++++++++++++---- cpu/base_dyn_inst.cc | 3 ++- dev/alpha_console.cc | 4 ++-- dev/pcidev.hh | 6 ++++-- dev/sinic.cc | 8 ++++---- 7 files changed, 46 insertions(+), 16 deletions(-) diff --git a/arch/alpha/alpha_memory.cc b/arch/alpha/alpha_memory.cc index b2a829711..11baed106 100644 --- a/arch/alpha/alpha_memory.cc +++ b/arch/alpha/alpha_memory.cc @@ -380,7 +380,7 @@ AlphaITB::translate(MemReqPtr &req) const // check that the physical address is ok (catch bad physical addresses) if (req->paddr & ~PAddrImplMask) - return new MachineCheckFault; + return genMachineCheckFault(); checkCacheability(req); @@ -511,7 +511,7 @@ AlphaDTB::translate(MemReqPtr &req, bool write) const fault(req, write ? MM_STAT_WR_MASK : 0); DPRINTF(TLB, "Alignment Fault on %#x, size = %d", req->vaddr, req->size); - return new AlignmentFault; + return genAlignmentFault(); } if (pc & 0x1) { @@ -621,7 +621,7 @@ AlphaDTB::translate(MemReqPtr &req, bool write) const // check that the physical address is ok (catch bad physical addresses) if (req->paddr & ~PAddrImplMask) - return new MachineCheckFault; + return genMachineCheckFault(); checkCacheability(req); diff --git a/arch/alpha/faults.cc b/arch/alpha/faults.cc index bbddadabf..1df0de7c1 100644 --- a/arch/alpha/faults.cc +++ b/arch/alpha/faults.cc @@ -32,6 +32,10 @@ FaultName AlphaFault::_name = "alphafault"; FaultVect AlphaFault::_vect = 0x0000; FaultStat AlphaFault::_stat; +FaultVect AlphaMachineCheckFault::_vect = 0x0401; + +FaultVect AlphaAlignmentFault::_vect = 0x0301; + FaultName ResetFault::_name = "reset"; FaultVect ResetFault::_vect = 0x0001; FaultStat ResetFault::_stat; diff --git a/arch/alpha/faults.hh b/arch/alpha/faults.hh index bd5163a7d..2004c0911 100644 --- a/arch/alpha/faults.hh +++ b/arch/alpha/faults.hh @@ -31,7 +31,7 @@ #include "sim/faults.hh" -// The reasoning behind the name and vect functions is in sim/faults.hh +// The design of the "name" and "vect" functions is in sim/faults.hh typedef const Addr FaultVect; @@ -47,6 +47,32 @@ class AlphaFault : public FaultBase virtual FaultStat & stat() {return _stat;} }; +class AlphaMachineCheckFault : public MachineCheckFault +{ + private: + static FaultVect _vect; + public: + FaultVect vect() {return _vect;} +}; + +class AlphaAlignmentFault : public AlignmentFault +{ + private: + static FaultVect _vect; + public: + FaultVect vect() {return _vect;} +}; + +static inline Fault genMachineCheckFault() +{ + return new AlphaMachineCheckFault; +} + +static inline Fault genAlignmentFault() +{ + return new AlphaAlignmentFault; +} + class ResetFault : public AlphaFault { private: @@ -215,7 +241,4 @@ class IntegerOverflowFault : public AlphaFault FaultStat & stat() {return _stat;} }; -//Fault * ListOfFaults[]; -//int NumFaults; - #endif // __FAULTS_HH__ diff --git a/cpu/base_dyn_inst.cc b/cpu/base_dyn_inst.cc index 633c0ee28..b3dffbf94 100644 --- a/cpu/base_dyn_inst.cc +++ b/cpu/base_dyn_inst.cc @@ -45,6 +45,7 @@ #include "cpu/o3/alpha_cpu.hh" using namespace std; +using namespace TheISA; #define NOHASH #ifndef NOHASH @@ -325,7 +326,7 @@ BaseDynInst::mem_access(mem_cmd cmd, Addr addr, void *p, int nbytes) break; default: - fault = MachineCheckFault; + fault = genMachineCheckFault(); break; } diff --git a/dev/alpha_console.cc b/dev/alpha_console.cc index 85134b435..c8327736f 100644 --- a/dev/alpha_console.cc +++ b/dev/alpha_console.cc @@ -182,7 +182,7 @@ AlphaConsole::read(MemReqPtr &req, uint8_t *data) } break; default: - return new MachineCheckFault; + return genMachineCheckFault(); } return NoFault; @@ -202,7 +202,7 @@ AlphaConsole::write(MemReqPtr &req, const uint8_t *data) val = *(uint64_t *)data; break; default: - return new MachineCheckFault; + return genMachineCheckFault(); } Addr daddr = req->paddr - (addr & EV5::PAddrImplMask); diff --git a/dev/pcidev.hh b/dev/pcidev.hh index 4f08c2cf9..bdfc6b932 100644 --- a/dev/pcidev.hh +++ b/dev/pcidev.hh @@ -260,6 +260,7 @@ class PciDev : public DmaDevice inline Fault PciDev::readBar(MemReqPtr &req, uint8_t *data) { + using namespace TheISA; if (isBAR(req->paddr, 0)) return readBar0(req, req->paddr - BARAddrs[0], data); if (isBAR(req->paddr, 1)) @@ -272,12 +273,13 @@ PciDev::readBar(MemReqPtr &req, uint8_t *data) return readBar4(req, req->paddr - BARAddrs[4], data); if (isBAR(req->paddr, 5)) return readBar5(req, req->paddr - BARAddrs[5], data); - return new MachineCheckFault; + return genMachineCheckFault(); } inline Fault PciDev::writeBar(MemReqPtr &req, const uint8_t *data) { + using namespace TheISA; if (isBAR(req->paddr, 0)) return writeBar0(req, req->paddr - BARAddrs[0], data); if (isBAR(req->paddr, 1)) @@ -290,7 +292,7 @@ PciDev::writeBar(MemReqPtr &req, const uint8_t *data) return writeBar4(req, req->paddr - BARAddrs[4], data); if (isBAR(req->paddr, 5)) return writeBar5(req, req->paddr - BARAddrs[5], data); - return new MachineCheckFault; + return genMachineCheckFault(); } #endif // __DEV_PCIDEV_HH__ diff --git a/dev/sinic.cc b/dev/sinic.cc index 3f7226817..ba643de4b 100644 --- a/dev/sinic.cc +++ b/dev/sinic.cc @@ -363,11 +363,11 @@ Device::read(MemReqPtr &req, uint8_t *data) assert(config.command & PCI_CMD_MSE); Fault fault = readBar(req, data); - if (fault->isA()) { + if (fault->isMachineCheckFault()) { panic("address does not map to a BAR pa=%#x va=%#x size=%d", req->paddr, req->vaddr, req->size); - return new MachineCheckFault; + return genMachineCheckFault(); } return fault; @@ -459,11 +459,11 @@ Device::write(MemReqPtr &req, const uint8_t *data) assert(config.command & PCI_CMD_MSE); Fault fault = writeBar(req, data); - if (fault->isA()) { + if (fault->isMachineCheckFault()) { panic("address does not map to a BAR pa=%#x va=%#x size=%d", req->paddr, req->vaddr, req->size); - return new MachineCheckFault; + return genMachineCheckFault(); } return fault; From f9c2b9e74fc459dc221035cb98e2a2e6a1540f9f Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Mon, 27 Feb 2006 04:00:24 -0500 Subject: [PATCH 116/180] Put the Alpha faults into the AlphaISA namespace --HG-- extra : convert_revision : d9586bb8ffaab74673aa0b3d17bb676b949ff212 --- arch/alpha/faults.cc | 5 +++++ arch/alpha/faults.hh | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/arch/alpha/faults.cc b/arch/alpha/faults.cc index 1df0de7c1..5033f9fcd 100644 --- a/arch/alpha/faults.cc +++ b/arch/alpha/faults.cc @@ -28,6 +28,9 @@ #include "arch/alpha/faults.hh" +namespace AlphaISA +{ + FaultName AlphaFault::_name = "alphafault"; FaultVect AlphaFault::_vect = 0x0000; FaultStat AlphaFault::_stat; @@ -92,6 +95,8 @@ FaultName IntegerOverflowFault::_name = "intover"; FaultVect IntegerOverflowFault::_vect = 0x0501; FaultStat IntegerOverflowFault::_stat; +} // namespace AlphaISA + /*Fault * ListOfFaults[] = { (Fault *)&NoFault, (Fault *)&ResetFault, diff --git a/arch/alpha/faults.hh b/arch/alpha/faults.hh index 2004c0911..fedbadd4d 100644 --- a/arch/alpha/faults.hh +++ b/arch/alpha/faults.hh @@ -33,6 +33,9 @@ // The design of the "name" and "vect" functions is in sim/faults.hh +namespace AlphaISA +{ + typedef const Addr FaultVect; class AlphaFault : public FaultBase @@ -241,4 +244,6 @@ class IntegerOverflowFault : public AlphaFault FaultStat & stat() {return _stat;} }; +} // AlphaISA namespace + #endif // __FAULTS_HH__ From 07cd7e966e6ee6715345b2f6ed2d4ea849fc7a36 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Mon, 27 Feb 2006 04:02:45 -0500 Subject: [PATCH 117/180] Added isMachineCheckFault and isAlignmentFault virtual functions to the fault base class, and replaced the isA templated function with them where appropriate. arch/alpha/ev5.cc: cpu/simple/cpu.cc: Changed from the isA templated function to isMachineCheckFault and isAlignmentFault sim/faults.hh: Added isMachineCheckFault and isAlignmentFault virtual functions to the fault base class. --HG-- extra : convert_revision : 3bf3a4369bc24a039648ee4f2a9c1663362ff2e2 --- arch/alpha/ev5.cc | 4 ++-- cpu/simple/cpu.cc | 4 ++-- sim/faults.hh | 12 +++++++++++- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/arch/alpha/ev5.cc b/arch/alpha/ev5.cc index 34b328a39..b89a6d10d 100644 --- a/arch/alpha/ev5.cc +++ b/arch/alpha/ev5.cc @@ -92,8 +92,8 @@ AlphaISA::fault_addr(Fault fault) { //Check for the system wide faults if(fault == NoFault) return 0x0000; - else if(fault->isA()) return 0x0401; - else if(fault->isA()) return 0x0301; + else if(fault->isMachineCheckFault()) return 0x0401; + else if(fault->isAlignmentFault()) return 0x0301; //Deal with the alpha specific faults return ((AlphaFault *)(fault.get()))->vect(); }; diff --git a/cpu/simple/cpu.cc b/cpu/simple/cpu.cc index a0a37f45a..4693c78c9 100644 --- a/cpu/simple/cpu.cc +++ b/cpu/simple/cpu.cc @@ -347,7 +347,7 @@ SimpleCPU::copySrcTranslate(Addr src) // translate to physical address Fault fault = xc->translateDataReadReq(memReq); - assert(!fault->isA()); + assert(!fault->isAlignmentFault()); if (fault == NoFault) { xc->copySrcAddr = src; @@ -382,7 +382,7 @@ SimpleCPU::copy(Addr dest) // translate to physical address Fault fault = xc->translateDataWriteReq(memReq); - assert(!fault->isA()); + assert(!fault->isAlignmentFault()); if (fault == NoFault) { Addr dest_addr = memReq->paddr + offset; diff --git a/sim/faults.hh b/sim/faults.hh index ea2e21a7d..e4880f820 100644 --- a/sim/faults.hh +++ b/sim/faults.hh @@ -55,9 +55,17 @@ class FaultBase : public RefCounted virtual FaultStat & stat() = 0; template bool isA() {return dynamic_cast(this);} + virtual bool isMachineCheckFault() {return false;} + virtual bool isAlignmentFault() {return false;} }; -static FaultBase * const NoFault __attribute__ ((unused)) = 0; +FaultBase * const NoFault = 0; + +//The ISAs are each responsible for providing a genMachineCheckFault and a +//genAlignmentFault functions, which return faults to use in the case of a +//machine check fault or an alignment fault, respectively. Base classes which +//provide the name() function, and the isMachineCheckFault and isAlignmentFault +//functions are provided below. class MachineCheckFault : public FaultBase { @@ -67,6 +75,7 @@ class MachineCheckFault : public FaultBase public: FaultName name() {return _name;} FaultStat & stat() {return _stat;} + bool isMachineCheckFault() {return true;} }; class AlignmentFault : public FaultBase @@ -77,6 +86,7 @@ class AlignmentFault : public FaultBase public: FaultName name() {return _name;} FaultStat & stat() {return _stat;} + bool isAlignmentFault() {return true;} }; From f56d42c53dbea1017d4fdd6b9f4ff9e976538246 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Mon, 27 Feb 2006 04:05:02 -0500 Subject: [PATCH 118/180] Fixed up some include paths. kern/kernel_stats.cc: Replaced targetarch with arch/alpha, since osfpal.hh is not a targetarched file. --HG-- extra : convert_revision : 24a25f27e5912cb949568cf5fd0ab856771ba0d1 --- kern/kernel_stats.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kern/kernel_stats.cc b/kern/kernel_stats.cc index ff65389d2..31a3049f1 100644 --- a/kern/kernel_stats.cc +++ b/kern/kernel_stats.cc @@ -30,7 +30,7 @@ #include #include -#include "targetarch/osfpal.hh" +#include "arch/alpha/osfpal.hh" #include "base/trace.hh" #include "cpu/exec_context.hh" #include "kern/kernel_stats.hh" From c5dcd152f264a837f50d39f98d0f4f81478e3553 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Mon, 27 Feb 2006 05:35:43 -0500 Subject: [PATCH 119/180] Changed targetarch to just arch. SConscript: Changed all of the "targetarch" files to be "arch" files arch/SConscript: Added all of the remaining targetarch files to isa_switch_hdrs --HG-- extra : convert_revision : a37d18349e27cf92dce12814f21944daa7fe9480 --- SConscript | 30 +++++++++++++++--------------- arch/SConscript | 10 ++++++++++ base/loader/exec_aout.h | 2 +- base/loader/exec_ecoff.h | 2 +- base/remote_gdb.cc | 2 +- cpu/base_dyn_inst.cc | 2 +- cpu/exec_context.cc | 2 +- cpu/exec_context.hh | 2 +- cpu/o3/alpha_cpu_builder.cc | 4 ++-- cpu/o3/cpu.hh | 2 +- cpu/o3/regfile.hh | 4 ++-- cpu/profile.hh | 2 +- cpu/simple/cpu.cc | 6 +++--- dev/ns_gige.cc | 2 +- dev/sinic.cc | 2 +- kern/freebsd/freebsd_system.cc | 2 +- kern/linux/linux_system.cc | 4 ++-- kern/linux/printk.cc | 2 +- kern/tru64/dump_mbuf.cc | 4 ++-- kern/tru64/printf.cc | 4 ++-- kern/tru64/tru64_events.cc | 2 +- kern/tru64/tru64_system.cc | 2 +- sim/process.cc | 4 ++-- sim/pseudo_inst.cc | 2 +- sim/system.cc | 2 +- sim/vptr.hh | 2 +- 26 files changed, 57 insertions(+), 47 deletions(-) diff --git a/SConscript b/SConscript index 966cb6d3e..540876699 100644 --- a/SConscript +++ b/SConscript @@ -305,23 +305,23 @@ syscall_emulation_sources = Split(''' # time. These will have to go away if we want to build a binary that # supports multiple ISAs. -targetarch_files = Split(''' - alpha_linux_process.hh - alpha_memory.hh - alpha_tru64_process.hh - aout_machdep.h - arguments.hh - ecoff_machdep.h - ev5.hh - faults.hh - stacktrace.hh - vtophys.hh - ''') +#targetarch_files = Split(''' +# alpha_linux_process.hh +# alpha_memory.hh +# alpha_tru64_process.hh +# aout_machdep.h +# arguments.hh +# ecoff_machdep.h +# ev5.hh +# faults.hh +# stacktrace.hh +# vtophys.hh +# ''') # Set up bridging headers to the architecture specific versions -for f in targetarch_files: - env.Command('targetarch/' + f, 'arch/%s/%s' % (env['TARGET_ISA'], f), - '''echo '#include "arch/%s/%s"' > $TARGET''' % (env['TARGET_ISA'], f)) +#for f in targetarch_files: +# env.Command('targetarch/' + f, 'arch/%s/%s' % (env['TARGET_ISA'], f), +# '''echo '#include "arch/%s/%s"' > $TARGET''' % (env['TARGET_ISA'], f)) # Add a flag defining what THE_ISA should be for all compilation env.Append(CPPDEFINES=[('THE_ISA','%s_ISA' % env['TARGET_ISA'].upper())]) diff --git a/arch/SConscript b/arch/SConscript index d237b0b1f..2036b6a56 100644 --- a/arch/SConscript +++ b/arch/SConscript @@ -46,6 +46,16 @@ sources = [] # List of headers to generate isa_switch_hdrs = Split(''' isa_traits.hh + alpha_linux_process.hh + alpha_tru64_process.hh + alpha_memory.hh + aout_machdep.h + ecoff_machdep.h + arguments.hh + stacktrace.hh + vtophys.hh + faults.hh + ev5.hh ''') # Generate the header. target[0] is the full path of the output diff --git a/base/loader/exec_aout.h b/base/loader/exec_aout.h index 76ebe9bb5..3863a92fb 100644 --- a/base/loader/exec_aout.h +++ b/base/loader/exec_aout.h @@ -55,6 +55,6 @@ (N_GETMAGIC(ex) != NMAGIC && N_GETMAGIC(ex) != OMAGIC && \ N_GETMAGIC(ex) != ZMAGIC) -#include "targetarch/aout_machdep.h" +#include "arch/aout_machdep.h" #endif /* !_SYS_EXEC_AOUT_H_ */ diff --git a/base/loader/exec_ecoff.h b/base/loader/exec_ecoff.h index 4eece4318..79cd22a6e 100644 --- a/base/loader/exec_ecoff.h +++ b/base/loader/exec_ecoff.h @@ -37,7 +37,7 @@ #ifndef _SYS_EXEC_ECOFF_H_ #define _SYS_EXEC_ECOFF_H_ -#include "targetarch/ecoff_machdep.h" +#include "arch/ecoff_machdep.h" struct ecoff_filehdr { coff_ushort f_magic; /* magic number */ diff --git a/base/remote_gdb.cc b/base/remote_gdb.cc index 17ec21fed..24280244f 100644 --- a/base/remote_gdb.cc +++ b/base/remote_gdb.cc @@ -129,7 +129,7 @@ #include "cpu/static_inst.hh" #include "mem/functional/physical.hh" #include "sim/system.hh" -#include "targetarch/vtophys.hh" +#include "arch/vtophys.hh" using namespace std; using namespace TheISA; diff --git a/cpu/base_dyn_inst.cc b/cpu/base_dyn_inst.cc index b3dffbf94..5905cdad2 100644 --- a/cpu/base_dyn_inst.cc +++ b/cpu/base_dyn_inst.cc @@ -36,7 +36,7 @@ #include "base/cprintf.hh" #include "base/trace.hh" -#include "targetarch/faults.hh" +#include "arch/faults.hh" #include "cpu/exetrace.hh" #include "mem/mem_req.hh" diff --git a/cpu/exec_context.cc b/cpu/exec_context.cc index 9bed3ba47..cf0ced7b0 100644 --- a/cpu/exec_context.cc +++ b/cpu/exec_context.cc @@ -40,7 +40,7 @@ #include "sim/serialize.hh" #include "sim/sim_exit.hh" #include "sim/system.hh" -#include "targetarch/stacktrace.hh" +#include "arch/stacktrace.hh" #else #include "sim/process.hh" #endif diff --git a/cpu/exec_context.hh b/cpu/exec_context.hh index 3e0d77254..4083381ea 100644 --- a/cpu/exec_context.hh +++ b/cpu/exec_context.hh @@ -46,7 +46,7 @@ class BaseCPU; #if FULL_SYSTEM #include "sim/system.hh" -#include "targetarch/alpha_memory.hh" +#include "arch/alpha_memory.hh" class FunctionProfile; class ProfileNode; diff --git a/cpu/o3/alpha_cpu_builder.cc b/cpu/o3/alpha_cpu_builder.cc index 3547fb1b5..0f6d0d35c 100644 --- a/cpu/o3/alpha_cpu_builder.cc +++ b/cpu/o3/alpha_cpu_builder.cc @@ -50,8 +50,8 @@ #include "mem/functional/memory_control.hh" #include "mem/functional/physical.hh" #include "sim/system.hh" -#include "targetarch/alpha_memory.hh" -#include "targetarch/vtophys.hh" +#include "arch/alpha_memory.hh" +#include "arch/vtophys.hh" #else // !FULL_SYSTEM #include "mem/functional/functional.hh" #endif // FULL_SYSTEM diff --git a/cpu/o3/cpu.hh b/cpu/o3/cpu.hh index f9e449548..802860ab5 100644 --- a/cpu/o3/cpu.hh +++ b/cpu/o3/cpu.hh @@ -50,7 +50,7 @@ #include "sim/process.hh" #if FULL_SYSTEM -#include "targetarch/ev5.hh" +#include "arch/ev5.hh" using namespace EV5; #endif diff --git a/cpu/o3/regfile.hh b/cpu/o3/regfile.hh index 9009db919..3bf96a37b 100644 --- a/cpu/o3/regfile.hh +++ b/cpu/o3/regfile.hh @@ -32,13 +32,13 @@ // @todo: Destructor #include "arch/isa_traits.hh" -#include "targetarch/faults.hh" +#include "arch/faults.hh" #include "base/trace.hh" #include "config/full_system.hh" #include "cpu/o3/comm.hh" #if FULL_SYSTEM -#include "targetarch/ev5.hh" +#include "arch/ev5.hh" #include "kern/kernel_stats.hh" using namespace EV5; diff --git a/cpu/profile.hh b/cpu/profile.hh index 18061f9bf..1eb012a27 100644 --- a/cpu/profile.hh +++ b/cpu/profile.hh @@ -33,7 +33,7 @@ #include "cpu/static_inst.hh" #include "sim/host.hh" -#include "targetarch/stacktrace.hh" +#include "arch/stacktrace.hh" class ProfileNode { diff --git a/cpu/simple/cpu.cc b/cpu/simple/cpu.cc index 4693c78c9..02ecbb12c 100644 --- a/cpu/simple/cpu.cc +++ b/cpu/simple/cpu.cc @@ -67,9 +67,9 @@ #include "mem/functional/memory_control.hh" #include "mem/functional/physical.hh" #include "sim/system.hh" -#include "targetarch/alpha_memory.hh" -#include "targetarch/stacktrace.hh" -#include "targetarch/vtophys.hh" +#include "arch/alpha_memory.hh" +#include "arch/stacktrace.hh" +#include "arch/vtophys.hh" #else // !FULL_SYSTEM #include "mem/functional/functional.hh" #endif // FULL_SYSTEM diff --git a/dev/ns_gige.cc b/dev/ns_gige.cc index 4b08d8497..d6df347bc 100644 --- a/dev/ns_gige.cc +++ b/dev/ns_gige.cc @@ -49,7 +49,7 @@ #include "sim/debug.hh" #include "sim/host.hh" #include "sim/stats.hh" -#include "targetarch/vtophys.hh" +#include "arch/vtophys.hh" const char *NsRxStateStrings[] = { diff --git a/dev/sinic.cc b/dev/sinic.cc index ba643de4b..c28ab335b 100644 --- a/dev/sinic.cc +++ b/dev/sinic.cc @@ -47,7 +47,7 @@ #include "sim/eventq.hh" #include "sim/host.hh" #include "sim/stats.hh" -#include "targetarch/vtophys.hh" +#include "arch/vtophys.hh" using namespace Net; using namespace TheISA; diff --git a/kern/freebsd/freebsd_system.cc b/kern/freebsd/freebsd_system.cc index cead8caaf..24d228b5f 100644 --- a/kern/freebsd/freebsd_system.cc +++ b/kern/freebsd/freebsd_system.cc @@ -41,7 +41,7 @@ #include "sim/builder.hh" #include "arch/isa_traits.hh" #include "sim/byteswap.hh" -#include "targetarch/vtophys.hh" +#include "arch/vtophys.hh" #define TIMER_FREQUENCY 1193180 diff --git a/kern/linux/linux_system.cc b/kern/linux/linux_system.cc index c5a9e184a..eb189658c 100644 --- a/kern/linux/linux_system.cc +++ b/kern/linux/linux_system.cc @@ -46,8 +46,8 @@ #include "sim/builder.hh" #include "sim/byteswap.hh" #include "dev/platform.hh" -#include "targetarch/arguments.hh" -#include "targetarch/vtophys.hh" +#include "arch/arguments.hh" +#include "arch/vtophys.hh" using namespace std; using namespace TheISA; diff --git a/kern/linux/printk.cc b/kern/linux/printk.cc index fbc8bdad1..f5313759b 100644 --- a/kern/linux/printk.cc +++ b/kern/linux/printk.cc @@ -30,7 +30,7 @@ #include #include "base/trace.hh" -#include "targetarch/arguments.hh" +#include "arch/arguments.hh" using namespace std; diff --git a/kern/tru64/dump_mbuf.cc b/kern/tru64/dump_mbuf.cc index efdaed62d..10137ceb0 100644 --- a/kern/tru64/dump_mbuf.cc +++ b/kern/tru64/dump_mbuf.cc @@ -34,9 +34,9 @@ #include "cpu/exec_context.hh" #include "kern/tru64/mbuf.hh" #include "sim/host.hh" -#include "targetarch/arguments.hh" +#include "arch/arguments.hh" #include "arch/isa_traits.hh" -#include "targetarch/vtophys.hh" +#include "arch/vtophys.hh" using namespace TheISA; diff --git a/kern/tru64/printf.cc b/kern/tru64/printf.cc index 12a089c40..77ac17c3a 100644 --- a/kern/tru64/printf.cc +++ b/kern/tru64/printf.cc @@ -32,8 +32,8 @@ #include "base/cprintf.hh" #include "base/trace.hh" #include "sim/host.hh" -#include "targetarch/arguments.hh" -#include "targetarch/vtophys.hh" +#include "arch/arguments.hh" +#include "arch/vtophys.hh" using namespace std; diff --git a/kern/tru64/tru64_events.cc b/kern/tru64/tru64_events.cc index 2fe6a2dc4..1fd26b87b 100644 --- a/kern/tru64/tru64_events.cc +++ b/kern/tru64/tru64_events.cc @@ -33,7 +33,7 @@ #include "kern/tru64/dump_mbuf.hh" #include "kern/tru64/printf.hh" #include "mem/functional/memory_control.hh" -#include "targetarch/arguments.hh" +#include "arch/arguments.hh" #include "arch/isa_traits.hh" using namespace TheISA; diff --git a/kern/tru64/tru64_system.cc b/kern/tru64/tru64_system.cc index ebcdc1553..48e02d90b 100644 --- a/kern/tru64/tru64_system.cc +++ b/kern/tru64/tru64_system.cc @@ -37,7 +37,7 @@ #include "mem/functional/physical.hh" #include "sim/builder.hh" #include "arch/isa_traits.hh" -#include "targetarch/vtophys.hh" +#include "arch/vtophys.hh" using namespace std; diff --git a/sim/process.cc b/sim/process.cc index 171470eb2..f026afc51 100644 --- a/sim/process.cc +++ b/sim/process.cc @@ -48,8 +48,8 @@ #include "sim/stats.hh" #include "sim/syscall_emul.hh" -#include "targetarch/alpha_tru64_process.hh" -#include "targetarch/alpha_linux_process.hh" +#include "arch/alpha_tru64_process.hh" +#include "arch/alpha_linux_process.hh" using namespace std; using namespace TheISA; diff --git a/sim/pseudo_inst.cc b/sim/pseudo_inst.cc index 58ea8266f..36c854d1c 100644 --- a/sim/pseudo_inst.cc +++ b/sim/pseudo_inst.cc @@ -34,7 +34,7 @@ #include #include "sim/pseudo_inst.hh" -#include "targetarch/vtophys.hh" +#include "arch/vtophys.hh" #include "cpu/base.hh" #include "cpu/sampler/sampler.hh" #include "cpu/exec_context.hh" diff --git a/sim/system.cc b/sim/system.cc index 41de8cee4..378568a8a 100644 --- a/sim/system.cc +++ b/sim/system.cc @@ -33,7 +33,7 @@ #include "kern/kernel_stats.hh" #include "mem/functional/memory_control.hh" #include "mem/functional/physical.hh" -#include "targetarch/vtophys.hh" +#include "arch/vtophys.hh" #include "sim/builder.hh" #include "arch/isa_traits.hh" #include "sim/byteswap.hh" diff --git a/sim/vptr.hh b/sim/vptr.hh index 7ec43602d..0ec452f25 100644 --- a/sim/vptr.hh +++ b/sim/vptr.hh @@ -29,7 +29,7 @@ #ifndef __ARCH_ALPHA_VPTR_HH__ #define __ARCH_ALPHA_VPTR_HH__ -#include "targetarch/vtophys.hh" +#include "arch/vtophys.hh" #include "arch/isa_traits.hh" class ExecContext; From f1ef4a8f06184df55e26268381cb4f8f56b77a50 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Mon, 27 Feb 2006 06:05:10 -0500 Subject: [PATCH 120/180] Renamed arch files to remove alpha prefix, and changed alpha_memory.hh and cc to a more accurate tlb.hh and cc --HG-- rename : arch/alpha/alpha_linux_process.cc => arch/alpha/linux_process.cc rename : arch/alpha/alpha_linux_process.hh => arch/alpha/linux_process.hh rename : arch/alpha/alpha_memory.cc => arch/alpha/tlb.cc rename : arch/alpha/alpha_memory.hh => arch/alpha/tlb.hh rename : arch/alpha/alpha_tru64_process.cc => arch/alpha/tru64_process.cc rename : arch/alpha/alpha_tru64_process.hh => arch/alpha/tru64_process.hh extra : convert_revision : 9fe6863cc37347d2a6bd716c529b0a4a50b36ea7 --- arch/SConscript | 6 +++--- arch/alpha/SConscript | 8 ++++---- arch/alpha/ev5.cc | 2 +- arch/alpha/{alpha_linux_process.cc => linux_process.cc} | 4 ++-- arch/alpha/{alpha_linux_process.hh => linux_process.hh} | 0 arch/alpha/{alpha_memory.cc => tlb.cc} | 2 +- arch/alpha/{alpha_memory.hh => tlb.hh} | 0 arch/alpha/{alpha_tru64_process.cc => tru64_process.cc} | 4 ++-- arch/alpha/{alpha_tru64_process.hh => tru64_process.hh} | 0 cpu/exec_context.hh | 2 +- cpu/o3/alpha_cpu_builder.cc | 2 +- cpu/simple/cpu.cc | 2 +- sim/process.cc | 4 ++-- 13 files changed, 18 insertions(+), 18 deletions(-) rename arch/alpha/{alpha_linux_process.cc => linux_process.cc} (99%) rename arch/alpha/{alpha_linux_process.hh => linux_process.hh} (100%) rename arch/alpha/{alpha_memory.cc => tlb.cc} (99%) rename arch/alpha/{alpha_memory.hh => tlb.hh} (100%) rename arch/alpha/{alpha_tru64_process.cc => tru64_process.cc} (99%) rename arch/alpha/{alpha_tru64_process.hh => tru64_process.hh} (100%) diff --git a/arch/SConscript b/arch/SConscript index 2036b6a56..c62e45763 100644 --- a/arch/SConscript +++ b/arch/SConscript @@ -46,9 +46,9 @@ sources = [] # List of headers to generate isa_switch_hdrs = Split(''' isa_traits.hh - alpha_linux_process.hh - alpha_tru64_process.hh - alpha_memory.hh + linux_process.hh + tru64_process.hh + tlb.hh aout_machdep.h ecoff_machdep.h arguments.hh diff --git a/arch/alpha/SConscript b/arch/alpha/SConscript index 050dfb9cf..3b0e69b7a 100644 --- a/arch/alpha/SConscript +++ b/arch/alpha/SConscript @@ -50,7 +50,7 @@ base_sources = Split(''' # Full-system sources full_system_sources = Split(''' - alpha_memory.cc + tlb.cc arguments.cc ev5.cc osfpal.cc @@ -61,9 +61,9 @@ full_system_sources = Split(''' # Syscall emulation (non-full-system) sources syscall_emulation_sources = Split(''' - alpha_common_syscall_emul.cc - alpha_linux_process.cc - alpha_tru64_process.cc + common_syscall_emul.cc + linux_process.cc + tru64_process.cc ''') # Set up complete list of sources based on configuration. diff --git a/arch/alpha/ev5.cc b/arch/alpha/ev5.cc index b89a6d10d..0520de1ed 100644 --- a/arch/alpha/ev5.cc +++ b/arch/alpha/ev5.cc @@ -26,7 +26,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "arch/alpha/alpha_memory.hh" +#include "arch/alpha/tlb.hh" #include "arch/alpha/isa_traits.hh" #include "arch/alpha/osfpal.hh" #include "base/kgdb.h" diff --git a/arch/alpha/alpha_linux_process.cc b/arch/alpha/linux_process.cc similarity index 99% rename from arch/alpha/alpha_linux_process.cc rename to arch/alpha/linux_process.cc index 16ebcca7b..0b193fb55 100644 --- a/arch/alpha/alpha_linux_process.cc +++ b/arch/alpha/linux_process.cc @@ -26,8 +26,8 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "arch/alpha/alpha_common_syscall_emul.hh" -#include "arch/alpha/alpha_linux_process.hh" +#include "arch/alpha/common_syscall_emul.hh" +#include "arch/alpha/linux_process.hh" #include "arch/alpha/isa_traits.hh" #include "base/trace.hh" diff --git a/arch/alpha/alpha_linux_process.hh b/arch/alpha/linux_process.hh similarity index 100% rename from arch/alpha/alpha_linux_process.hh rename to arch/alpha/linux_process.hh diff --git a/arch/alpha/alpha_memory.cc b/arch/alpha/tlb.cc similarity index 99% rename from arch/alpha/alpha_memory.cc rename to arch/alpha/tlb.cc index 11baed106..8297737bd 100644 --- a/arch/alpha/alpha_memory.cc +++ b/arch/alpha/tlb.cc @@ -30,7 +30,7 @@ #include #include -#include "arch/alpha/alpha_memory.hh" +#include "arch/alpha/tlb.hh" #include "base/inifile.hh" #include "base/str.hh" #include "base/trace.hh" diff --git a/arch/alpha/alpha_memory.hh b/arch/alpha/tlb.hh similarity index 100% rename from arch/alpha/alpha_memory.hh rename to arch/alpha/tlb.hh diff --git a/arch/alpha/alpha_tru64_process.cc b/arch/alpha/tru64_process.cc similarity index 99% rename from arch/alpha/alpha_tru64_process.cc rename to arch/alpha/tru64_process.cc index 8121d3452..90e8b1139 100644 --- a/arch/alpha/alpha_tru64_process.cc +++ b/arch/alpha/tru64_process.cc @@ -27,8 +27,8 @@ */ #include "arch/alpha/isa_traits.hh" -#include "arch/alpha/alpha_common_syscall_emul.hh" -#include "arch/alpha/alpha_tru64_process.hh" +#include "arch/alpha/common_syscall_emul.hh" +#include "arch/alpha/tru64_process.hh" #include "cpu/exec_context.hh" #include "kern/tru64/tru64.hh" #include "mem/functional/functional.hh" diff --git a/arch/alpha/alpha_tru64_process.hh b/arch/alpha/tru64_process.hh similarity index 100% rename from arch/alpha/alpha_tru64_process.hh rename to arch/alpha/tru64_process.hh diff --git a/cpu/exec_context.hh b/cpu/exec_context.hh index 4083381ea..834eacec8 100644 --- a/cpu/exec_context.hh +++ b/cpu/exec_context.hh @@ -46,7 +46,7 @@ class BaseCPU; #if FULL_SYSTEM #include "sim/system.hh" -#include "arch/alpha_memory.hh" +#include "arch/tlb.hh" class FunctionProfile; class ProfileNode; diff --git a/cpu/o3/alpha_cpu_builder.cc b/cpu/o3/alpha_cpu_builder.cc index 0f6d0d35c..95d2f8f37 100644 --- a/cpu/o3/alpha_cpu_builder.cc +++ b/cpu/o3/alpha_cpu_builder.cc @@ -50,7 +50,7 @@ #include "mem/functional/memory_control.hh" #include "mem/functional/physical.hh" #include "sim/system.hh" -#include "arch/alpha_memory.hh" +#include "arch/tlb.hh" #include "arch/vtophys.hh" #else // !FULL_SYSTEM #include "mem/functional/functional.hh" diff --git a/cpu/simple/cpu.cc b/cpu/simple/cpu.cc index 02ecbb12c..4b0eda386 100644 --- a/cpu/simple/cpu.cc +++ b/cpu/simple/cpu.cc @@ -67,7 +67,7 @@ #include "mem/functional/memory_control.hh" #include "mem/functional/physical.hh" #include "sim/system.hh" -#include "arch/alpha_memory.hh" +#include "arch/tlb.hh" #include "arch/stacktrace.hh" #include "arch/vtophys.hh" #else // !FULL_SYSTEM diff --git a/sim/process.cc b/sim/process.cc index f026afc51..e3cae2855 100644 --- a/sim/process.cc +++ b/sim/process.cc @@ -48,8 +48,8 @@ #include "sim/stats.hh" #include "sim/syscall_emul.hh" -#include "arch/alpha_tru64_process.hh" -#include "arch/alpha_linux_process.hh" +#include "arch/tru64_process.hh" +#include "arch/linux_process.hh" using namespace std; using namespace TheISA; From 70b35bab5778799805fe9b6040b23eb1885dbfc3 Mon Sep 17 00:00:00 2001 From: Kevin Lim Date: Mon, 27 Feb 2006 11:44:35 -0500 Subject: [PATCH 121/180] Changes to put all the misc regs within the misc reg file. This includes the FPCR, Uniq, lock flag, lock addr, and IPRs. They are now accessed by calling readMiscReg()/setMiscReg() on the XC. Old IPR accesses are supported by using readMiscRegWithEffect() and setMiscRegWithEffect() (names may change in the future). arch/alpha/alpha_memory.cc: Change accesses to IPR to go through the XC. arch/alpha/ev5.cc: Change accesses for IPRs to go through the misc regs. arch/alpha/isa/decoder.isa: Change accesses to IPRs to go through the misc regs. readIpr() and setIpr() are now changed to calls to readMiscRegWithEffect() and setMiscRegWithEffect(). arch/alpha/isa/fp.isa: Change accesses to IPRs and Fpcr to go through the misc regs. arch/alpha/isa/main.isa: Add support for all misc regs being accessed through readMiscReg() and setMiscReg(). Instead of readUniq and readFpcr, they are replaced by calls with Uniq_DepTag and Fpcr_DepTag passed in as the register index. arch/alpha/isa_traits.hh: Change the MiscRegFile to a class that handles all accesses to MiscRegs, which in Alpha include the FPCR, Uniq, Lock Addr, Lock Flag, and IPRs. Two flavors of accesses are supported: normal register reads/writes, and reads/writes with effect. The latter are basically the original read/write IPR functions, while the former are normal reads/writes. The lock flag and lock addr registers are added to the dependence tags in order to support being accessed through the misc regs. arch/alpha/stacktrace.cc: cpu/simple/cpu.cc: dev/sinic.cc: Change accesses to the IPRs to go through the XC. arch/alpha/vtophys.cc: Change access to the IPR to go through the XC. arch/isa_parser.py: Change generation of code for control registers to use the readMiscReg and setMiscReg functions. base/remote_gdb.cc: Change accesses to the IPR to go through the XC. cpu/exec_context.hh: Use the miscRegs to access the lock addr, lock flag, and other misc registers. cpu/o3/alpha_cpu.hh: cpu/simple/cpu.hh: Support interface for reading and writing misc registers, which replaces readUniq, readFpcr, readIpr, and their set functions. cpu/o3/alpha_cpu_impl.hh: Change accesses to the IPRs to go through the miscRegs. For now comment out some of the accesses to the misc regs until the proxy exec context is completed. cpu/o3/alpha_dyn_inst.hh: Change accesses to misc regs to use readMiscReg and setMiscReg. cpu/o3/alpha_dyn_inst_impl.hh: Remove old misc reg accessors. cpu/o3/cpu.cc: Comment out old misc reg accesses until the proxy exec context is completed. cpu/o3/cpu.hh: Change accesses to the misc regs. cpu/o3/regfile.hh: Remove old access methods for the misc regs, replace them with readMiscReg and setMiscReg. They are dummy functions for now until the proxy exec context is completed. kern/kernel_stats.cc: kern/system_events.cc: Have accesses to the IPRs go through the XC. kern/tru64/tru64.hh: Have accesses to the misc regs use the new access methods. --HG-- extra : convert_revision : e32e0a3fe99522e17294bbe106ff5591cb1a9d76 --- arch/alpha/alpha_memory.cc | 47 ++-- arch/alpha/ev5.cc | 99 +++++---- arch/alpha/isa/decoder.isa | 12 +- arch/alpha/isa/fp.isa | 5 +- arch/alpha/isa/main.isa | 6 +- arch/alpha/isa_traits.hh | 55 +++-- arch/alpha/stacktrace.cc | 14 +- arch/alpha/vtophys.cc | 2 +- arch/isa_parser.py | 8 +- base/remote_gdb.cc | 2 +- cpu/exec_context.hh | 38 ++-- cpu/o3/alpha_cpu.hh | 50 ++--- cpu/o3/alpha_cpu_impl.hh | 46 ++-- cpu/o3/alpha_dyn_inst.hh | 34 ++- cpu/o3/alpha_dyn_inst_impl.hh | 42 ---- cpu/o3/cpu.cc | 4 +- cpu/o3/cpu.hh | 4 +- cpu/o3/regfile.hh | 391 +--------------------------------- cpu/simple/cpu.cc | 17 +- cpu/simple/cpu.hh | 25 ++- dev/sinic.cc | 4 +- kern/kernel_stats.cc | 2 +- kern/system_events.cc | 2 +- kern/tru64/tru64.hh | 6 +- 24 files changed, 273 insertions(+), 642 deletions(-) diff --git a/arch/alpha/alpha_memory.cc b/arch/alpha/alpha_memory.cc index d00186d95..fb619d8b3 100644 --- a/arch/alpha/alpha_memory.cc +++ b/arch/alpha/alpha_memory.cc @@ -293,12 +293,11 @@ AlphaITB::regStats() void AlphaITB::fault(Addr pc, ExecContext *xc) const { - uint64_t *ipr = xc->regs.ipr; - if (!xc->misspeculating()) { - ipr[AlphaISA::IPR_ITB_TAG] = pc; - ipr[AlphaISA::IPR_IFAULT_VA_FORM] = - ipr[AlphaISA::IPR_IVPTBR] | (AlphaISA::VAddr(pc).vpn() << 3); + xc->setMiscReg(AlphaISA::IPR_ITB_TAG, pc); + xc->setMiscReg(AlphaISA::IPR_IFAULT_VA_FORM, + xc->readMiscReg(AlphaISA::IPR_IVPTBR) | + (AlphaISA::VAddr(pc).vpn() << 3)); } } @@ -306,7 +305,7 @@ AlphaITB::fault(Addr pc, ExecContext *xc) const Fault AlphaITB::translate(MemReqPtr &req) const { - InternalProcReg *ipr = req->xc->regs.ipr; + ExecContext *xc = req->xc; if (AlphaISA::PcPAL(req->vaddr)) { // strip off PAL PC marker (lsb is 1) @@ -329,13 +328,13 @@ AlphaITB::translate(MemReqPtr &req) const // VA<42:41> == 2, VA<39:13> maps directly to PA<39:13> for EV5 // VA<47:41> == 0x7e, VA<40:13> maps directly to PA<40:13> for EV6 #if ALPHA_TLASER - if ((MCSR_SP(ipr[AlphaISA::IPR_MCSR]) & 2) && + if ((MCSR_SP(xc->readMiscReg(AlphaISA::IPR_MCSR)) & 2) && VAddrSpaceEV5(req->vaddr) == 2) { #else if (VAddrSpaceEV6(req->vaddr) == 0x7e) { #endif // only valid in kernel mode - if (ICM_CM(ipr[AlphaISA::IPR_ICM]) != + if (ICM_CM(xc->readMiscReg(AlphaISA::IPR_ICM)) != AlphaISA::mode_kernel) { fault(req->vaddr, req->xc); acv++; @@ -354,8 +353,9 @@ AlphaITB::translate(MemReqPtr &req) const } else { // not a physical address: need to look up pte + int asn = DTB_ASN_ASN(xc->readMiscReg(AlphaISA::IPR_DTB_ASN)); AlphaISA::PTE *pte = lookup(AlphaISA::VAddr(req->vaddr).vpn(), - DTB_ASN_ASN(ipr[AlphaISA::IPR_DTB_ASN])); + asn); if (!pte) { fault(req->vaddr, req->xc); @@ -367,7 +367,8 @@ AlphaITB::translate(MemReqPtr &req) const (AlphaISA::VAddr(req->vaddr).offset() & ~3); // check permissions for this access - if (!(pte->xre & (1 << ICM_CM(ipr[AlphaISA::IPR_ICM])))) { + if (!(pte->xre & + (1 << ICM_CM(xc->readMiscReg(AlphaISA::IPR_ICM))))) { // instruction access fault fault(req->vaddr, req->xc); acv++; @@ -469,7 +470,6 @@ AlphaDTB::fault(MemReqPtr &req, uint64_t flags) const { ExecContext *xc = req->xc; AlphaISA::VAddr vaddr = req->vaddr; - uint64_t *ipr = xc->regs.ipr; // Set fault address and flags. Even though we're modeling an // EV5, we use the EV6 technique of not latching fault registers @@ -479,17 +479,17 @@ AlphaDTB::fault(MemReqPtr &req, uint64_t flags) const if (!xc->misspeculating() && !(req->flags & VPTE) && !(req->flags & NO_FAULT)) { // set VA register with faulting address - ipr[AlphaISA::IPR_VA] = req->vaddr; + xc->setMiscReg(AlphaISA::IPR_VA, req->vaddr); // set MM_STAT register flags - ipr[AlphaISA::IPR_MM_STAT] = + xc->setMiscReg(AlphaISA::IPR_MM_STAT, (((Opcode(xc->getInst()) & 0x3f) << 11) | ((Ra(xc->getInst()) & 0x1f) << 6) - | (flags & 0x3f)); + | (flags & 0x3f))); // set VA_FORM register with faulting formatted address - ipr[AlphaISA::IPR_VA_FORM] = - ipr[AlphaISA::IPR_MVPTBR] | (vaddr.vpn() << 3); + xc->setMiscReg(AlphaISA::IPR_VA_FORM, + xc->readMiscReg(AlphaISA::IPR_MVPTBR) | (vaddr.vpn() << 3)); } } @@ -497,11 +497,11 @@ Fault AlphaDTB::translate(MemReqPtr &req, bool write) const { RegFile *regs = &req->xc->regs; + ExecContext *xc = req->xc; Addr pc = regs->pc; - InternalProcReg *ipr = regs->ipr; AlphaISA::mode_type mode = - (AlphaISA::mode_type)DTB_CM_CM(ipr[AlphaISA::IPR_DTB_CM]); + (AlphaISA::mode_type)DTB_CM_CM(xc->readMiscReg(AlphaISA::IPR_DTB_CM)); /** @@ -516,7 +516,8 @@ AlphaDTB::translate(MemReqPtr &req, bool write) const if (pc & 0x1) { mode = (req->flags & ALTMODE) ? - (AlphaISA::mode_type)ALT_MODE_AM(ipr[AlphaISA::IPR_ALT_MODE]) + (AlphaISA::mode_type)ALT_MODE_AM( + xc->readMiscReg(AlphaISA::IPR_ALT_MODE)) : AlphaISA::mode_kernel; } @@ -535,14 +536,14 @@ AlphaDTB::translate(MemReqPtr &req, bool write) const // Check for "superpage" mapping #if ALPHA_TLASER - if ((MCSR_SP(ipr[AlphaISA::IPR_MCSR]) & 2) && + if ((MCSR_SP(xc->readMiscReg(AlphaISA::IPR_MCSR)) & 2) && VAddrSpaceEV5(req->vaddr) == 2) { #else if (VAddrSpaceEV6(req->vaddr) == 0x7e) { #endif // only valid in kernel mode - if (DTB_CM_CM(ipr[AlphaISA::IPR_DTB_CM]) != + if (DTB_CM_CM(xc->readMiscReg(AlphaISA::IPR_DTB_CM)) != AlphaISA::mode_kernel) { fault(req, ((write ? MM_STAT_WR_MASK : 0) | MM_STAT_ACV_MASK)); @@ -566,9 +567,11 @@ AlphaDTB::translate(MemReqPtr &req, bool write) const else read_accesses++; + int asn = DTB_ASN_ASN(xc->readMiscReg(AlphaISA::IPR_DTB_ASN)); + // not a physical address: need to look up pte AlphaISA::PTE *pte = lookup(AlphaISA::VAddr(req->vaddr).vpn(), - DTB_ASN_ASN(ipr[AlphaISA::IPR_DTB_ASN])); + asn); if (!pte) { // page fault diff --git a/arch/alpha/ev5.cc b/arch/alpha/ev5.cc index 14b87b16f..f292c6c46 100644 --- a/arch/alpha/ev5.cc +++ b/arch/alpha/ev5.cc @@ -72,14 +72,14 @@ AlphaISA::swap_palshadow(RegFile *regs, bool use_shadow) void AlphaISA::initCPU(RegFile *regs, int cpuId) { - initIPRs(regs, cpuId); + initIPRs(®s->miscRegs, cpuId); // CPU comes up with PAL regs enabled swap_palshadow(regs, true); regs->intRegFile[16] = cpuId; regs->intRegFile[0] = cpuId; - regs->pc = regs->ipr[IPR_PAL_BASE] + fault_addr(ResetFault); + regs->pc = regs->miscRegs.readReg(IPR_PAL_BASE) + fault_addr(ResetFault); regs->npc = regs->pc + sizeof(MachInst); } @@ -109,14 +109,13 @@ const int AlphaISA::reg_redir[AlphaISA::NumIntRegs] = { // // void -AlphaISA::initIPRs(RegFile *regs, int cpuId) +AlphaISA::initIPRs(MiscRegFile *miscRegs, int cpuId) { - uint64_t *ipr = regs->ipr; + miscRegs->clearIprs(); - bzero((char *)ipr, NumInternalProcRegs * sizeof(InternalProcReg)); - ipr[IPR_PAL_BASE] = PalBase; - ipr[IPR_MCSR] = 0x6; - ipr[IPR_PALtemp16] = cpuId; + miscRegs->setReg(IPR_PAL_BASE, PalBase); + miscRegs->setReg(IPR_MCSR, 0x6); + miscRegs->setReg(IPR_PALtemp16, cpuId); } @@ -128,17 +127,16 @@ AlphaISA::processInterrupts(CPU *cpu) //Handle the interrupts int ipl = 0; int summary = 0; - IntReg *ipr = cpu->getIprPtr(); cpu->checkInterrupts = false; - if (ipr[IPR_ASTRR]) + if (cpu->readMiscReg(IPR_ASTRR)) panic("asynchronous traps not implemented\n"); - if (ipr[IPR_SIRR]) { + if (cpu->readMiscReg(IPR_SIRR)) { for (int i = INTLEVEL_SOFTWARE_MIN; i < INTLEVEL_SOFTWARE_MAX; i++) { - if (ipr[IPR_SIRR] & (ULL(1) << i)) { + if (cpu->readMiscReg(IPR_SIRR) & (ULL(1) << i)) { // See table 4-19 of the 21164 hardware reference ipl = (i - INTLEVEL_SOFTWARE_MIN) + 1; summary |= (ULL(1) << i); @@ -159,12 +157,12 @@ AlphaISA::processInterrupts(CPU *cpu) } } - if (ipl && ipl > ipr[IPR_IPLR]) { - ipr[IPR_ISR] = summary; - ipr[IPR_INTID] = ipl; + if (ipl && ipl > cpu->readMiscReg(IPR_IPLR)) { + cpu->setMiscReg(IPR_ISR, summary); + cpu->setMiscReg(IPR_INTID, ipl); cpu->trap(InterruptFault); DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n", - ipr[IPR_IPLR], ipl, summary); + cpu->readMiscReg(IPR_IPLR), ipl, summary); } } @@ -192,22 +190,21 @@ ExecContext::ev5_trap(Fault fault) if (fault == ArithmeticFault) panic("Arithmetic traps are unimplemented!"); - AlphaISA::InternalProcReg *ipr = regs.ipr; - // exception restart address if (fault != InterruptFault || !inPalMode()) - ipr[AlphaISA::IPR_EXC_ADDR] = regs.pc; + setMiscReg(AlphaISA::IPR_EXC_ADDR, regs.pc); if (fault == PalFault || fault == ArithmeticFault /* || fault == InterruptFault && !inPalMode() */) { // traps... skip faulting instruction - ipr[AlphaISA::IPR_EXC_ADDR] += 4; + setMiscReg(AlphaISA::IPR_EXC_ADDR, + readMiscReg(AlphaISA::IPR_EXC_ADDR) + 4); } if (!inPalMode()) AlphaISA::swap_palshadow(®s, true); - regs.pc = ipr[AlphaISA::IPR_PAL_BASE] + AlphaISA::fault_addr(fault); + regs.pc = readMiscReg(AlphaISA::IPR_PAL_BASE) + AlphaISA::fault_addr(fault); regs.npc = regs.pc + sizeof(MachInst); } @@ -215,7 +212,6 @@ ExecContext::ev5_trap(Fault fault) void AlphaISA::intr_post(RegFile *regs, Fault fault, Addr pc) { - InternalProcReg *ipr = regs->ipr; bool use_pc = (fault == NoFault); if (fault == ArithmeticFault) @@ -224,17 +220,18 @@ AlphaISA::intr_post(RegFile *regs, Fault fault, Addr pc) // compute exception restart address if (use_pc || fault == PalFault || fault == ArithmeticFault) { // traps... skip faulting instruction - ipr[IPR_EXC_ADDR] = regs->pc + 4; + regs->miscRegs.setReg(IPR_EXC_ADDR, regs->pc + 4); } else { // fault, post fault at excepting instruction - ipr[IPR_EXC_ADDR] = regs->pc; + regs->miscRegs.setReg(IPR_EXC_ADDR, regs->pc); } // jump to expection address (PAL PC bit set here as well...) if (!use_pc) - regs->npc = ipr[IPR_PAL_BASE] + fault_addr(fault); + regs->npc = regs->miscRegs.readReg(IPR_PAL_BASE) + + fault_addr(fault); else - regs->npc = ipr[IPR_PAL_BASE] + pc; + regs->npc = regs->miscRegs.readReg(IPR_PAL_BASE) + pc; // that's it! (orders of magnitude less painful than x86) } @@ -242,17 +239,15 @@ AlphaISA::intr_post(RegFile *regs, Fault fault, Addr pc) Fault ExecContext::hwrei() { - uint64_t *ipr = regs.ipr; - if (!inPalMode()) return UnimplementedOpcodeFault; - setNextPC(ipr[AlphaISA::IPR_EXC_ADDR]); + setNextPC(readMiscReg(AlphaISA::IPR_EXC_ADDR)); if (!misspeculating()) { kernelStats->hwrei(); - if ((ipr[AlphaISA::IPR_EXC_ADDR] & 1) == 0) + if ((readMiscReg(AlphaISA::IPR_EXC_ADDR) & 1) == 0) AlphaISA::swap_palshadow(®s, false); cpu->checkInterrupts = true; @@ -262,10 +257,15 @@ ExecContext::hwrei() return NoFault; } -uint64_t -ExecContext::readIpr(int idx, Fault &fault) +void +AlphaISA::MiscRegFile::clearIprs() +{ + bzero((char *)ipr, NumInternalProcRegs * sizeof(InternalProcReg)); +} + +AlphaISA::MiscReg +AlphaISA::MiscRegFile::readIpr(int idx, Fault &fault, ExecContext *xc) { - uint64_t *ipr = regs.ipr; uint64_t retval = 0; // return value, default 0 switch (idx) { @@ -318,7 +318,7 @@ ExecContext::readIpr(int idx, Fault &fault) case AlphaISA::IPR_CC: retval |= ipr[idx] & ULL(0xffffffff00000000); - retval |= cpu->curCycle() & ULL(0x00000000ffffffff); + retval |= xc->cpu->curCycle() & ULL(0x00000000ffffffff); break; case AlphaISA::IPR_VA: @@ -335,7 +335,7 @@ ExecContext::readIpr(int idx, Fault &fault) case AlphaISA::IPR_DTB_PTE: { - AlphaISA::PTE &pte = dtb->index(!misspeculating()); + AlphaISA::PTE &pte = xc->dtb->index(!xc->misspeculating()); retval |= ((u_int64_t)pte.ppn & ULL(0x7ffffff)) << 32; retval |= ((u_int64_t)pte.xre & ULL(0xf)) << 8; @@ -375,12 +375,11 @@ int break_ipl = -1; #endif Fault -ExecContext::setIpr(int idx, uint64_t val) +AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ExecContext *xc) { - uint64_t *ipr = regs.ipr; uint64_t old; - if (misspeculating()) + if (xc->misspeculating()) return NoFault; switch (idx) { @@ -433,7 +432,7 @@ ExecContext::setIpr(int idx, uint64_t val) // write entire quad w/ no side-effect old = ipr[idx]; ipr[idx] = val; - kernelStats->context(old, val); + xc->kernelStats->context(old, val); break; case AlphaISA::IPR_DTB_PTE: @@ -460,14 +459,14 @@ ExecContext::setIpr(int idx, uint64_t val) // only write least significant five bits - interrupt level ipr[idx] = val & 0x1f; - kernelStats->swpipl(ipr[idx]); + xc->kernelStats->swpipl(ipr[idx]); break; case AlphaISA::IPR_DTB_CM: if (val & 0x18) - kernelStats->mode(Kernel::user); + xc->kernelStats->mode(Kernel::user); else - kernelStats->mode(Kernel::kernel); + xc->kernelStats->mode(Kernel::kernel); case AlphaISA::IPR_ICM: // only write two mode bits - processor mode @@ -541,21 +540,21 @@ ExecContext::setIpr(int idx, uint64_t val) // really a control write ipr[idx] = 0; - dtb->flushAll(); + xc->dtb->flushAll(); break; case AlphaISA::IPR_DTB_IAP: // really a control write ipr[idx] = 0; - dtb->flushProcesses(); + xc->dtb->flushProcesses(); break; case AlphaISA::IPR_DTB_IS: // really a control write ipr[idx] = val; - dtb->flushAddr(val, DTB_ASN_ASN(ipr[AlphaISA::IPR_DTB_ASN])); + xc->dtb->flushAddr(val, DTB_ASN_ASN(ipr[AlphaISA::IPR_DTB_ASN])); break; case AlphaISA::IPR_DTB_TAG: { @@ -578,7 +577,7 @@ ExecContext::setIpr(int idx, uint64_t val) pte.asn = DTB_ASN_ASN(ipr[AlphaISA::IPR_DTB_ASN]); // insert new TAG/PTE value into data TLB - dtb->insert(val, pte); + xc->dtb->insert(val, pte); } break; @@ -602,7 +601,7 @@ ExecContext::setIpr(int idx, uint64_t val) pte.asn = ITB_ASN_ASN(ipr[AlphaISA::IPR_ITB_ASN]); // insert new TAG/PTE value into data TLB - itb->insert(ipr[AlphaISA::IPR_ITB_TAG], pte); + xc->itb->insert(ipr[AlphaISA::IPR_ITB_TAG], pte); } break; @@ -610,21 +609,21 @@ ExecContext::setIpr(int idx, uint64_t val) // really a control write ipr[idx] = 0; - itb->flushAll(); + xc->itb->flushAll(); break; case AlphaISA::IPR_ITB_IAP: // really a control write ipr[idx] = 0; - itb->flushProcesses(); + xc->itb->flushProcesses(); break; case AlphaISA::IPR_ITB_IS: // really a control write ipr[idx] = val; - itb->flushAddr(val, ITB_ASN_ASN(ipr[AlphaISA::IPR_ITB_ASN])); + xc->itb->flushAddr(val, ITB_ASN_ASN(ipr[AlphaISA::IPR_ITB_ASN])); break; default: diff --git a/arch/alpha/isa/decoder.isa b/arch/alpha/isa/decoder.isa index 37b15416b..c72f14a71 100644 --- a/arch/alpha/isa/decoder.isa +++ b/arch/alpha/isa/decoder.isa @@ -618,7 +618,7 @@ decode OPCODE default Unknown::unknown() { /* Rb is a fake dependency so here is a fun way to get * the parser to understand that. */ - Ra = xc->readIpr(AlphaISA::IPR_CC, fault) + (Rb & 0); + Ra = xc->readMiscRegWithEffect(AlphaISA::IPR_CC, fault) + (Rb & 0); #else Ra = curTick; @@ -670,7 +670,7 @@ decode OPCODE default Unknown::unknown() { 0x00: CallPal::call_pal({{ if (!palValid || (palPriv - && xc->readIpr(AlphaISA::IPR_ICM, fault) != AlphaISA::mode_kernel)) { + && xc->readMiscRegWithEffect(AlphaISA::IPR_ICM, fault) != AlphaISA::mode_kernel)) { // invalid pal function code, or attempt to do privileged // PAL call in non-kernel mode fault = UnimplementedOpcodeFault; @@ -682,8 +682,8 @@ decode OPCODE default Unknown::unknown() { if (dopal) { AlphaISA::swap_palshadow(&xc->xcBase()->regs, true); - xc->setIpr(AlphaISA::IPR_EXC_ADDR, NPC); - NPC = xc->readIpr(AlphaISA::IPR_PAL_BASE, fault) + palOffset; + xc->setMiscRegWithEffect(AlphaISA::IPR_EXC_ADDR, NPC); + NPC = xc->readMiscRegWithEffect(AlphaISA::IPR_PAL_BASE, fault) + palOffset; } } }}, IsNonSpeculative); @@ -732,7 +732,7 @@ decode OPCODE default Unknown::unknown() { fault = UnimplementedOpcodeFault; } else { - Ra = xc->readIpr(ipr_index, fault); + Ra = xc->readMiscRegWithEffect(ipr_index, fault); } }}); 0x1d: hw_mtpr({{ @@ -741,7 +741,7 @@ decode OPCODE default Unknown::unknown() { fault = UnimplementedOpcodeFault; } else { - xc->setIpr(ipr_index, Ra); + xc->setMiscRegWithEffect(ipr_index, Ra); if (traceData) { traceData->setData(Ra); } } }}); diff --git a/arch/alpha/isa/fp.isa b/arch/alpha/isa/fp.isa index 7e81fb830..20a564045 100644 --- a/arch/alpha/isa/fp.isa +++ b/arch/alpha/isa/fp.isa @@ -35,7 +35,7 @@ output exec {{ inline Fault checkFpEnableFault(%(CPU_exec_context)s *xc) { Fault fault = NoFault; // dummy... this ipr access should not fault - if (!EV5::ICSR_FPE(xc->readIpr(AlphaISA::IPR_ICSR, fault))) { + if (!EV5::ICSR_FPE(xc->readMiscRegWithEffect(AlphaISA::IPR_ICSR, fault))) { fault = FloatEnableFault; } return fault; @@ -217,7 +217,8 @@ def template FloatingPointExecute {{ if (roundingMode == Normal) { %(code)s; } else { - fesetround(getC99RoundingMode(xc->readFpcr())); + fesetround(getC99RoundingMode( + xc->readMiscReg(AlphaISA::Fpcr_DepTag))); %(code)s; fesetround(FE_TONEAREST); } diff --git a/arch/alpha/isa/main.isa b/arch/alpha/isa/main.isa index b8d03c0be..ad9c2a55e 100644 --- a/arch/alpha/isa/main.isa +++ b/arch/alpha/isa/main.isa @@ -161,8 +161,8 @@ def operands {{ 'Fc': ('FloatReg', 'df', 'FC', 'IsFloating', 3), 'Mem': ('Mem', 'uq', None, ('IsMemRef', 'IsLoad', 'IsStore'), 4), 'NPC': ('NPC', 'uq', None, ( None, None, 'IsControl' ), 4), - 'Runiq': ('ControlReg', 'uq', 'Uniq', None, 1), - 'FPCR': (' ControlReg', 'uq', 'Fpcr', None, 1), + 'Runiq': ('ControlReg', 'uq', 'TheISA::Uniq_DepTag', None, 1), + 'FPCR': (' ControlReg', 'uq', 'TheISA::Fpcr_DepTag', None, 1), # The next two are hacks for non-full-system call-pal emulation 'R0': ('IntReg', 'uq', '0', None, 1), 'R16': ('IntReg', 'uq', '16', None, 1), @@ -194,6 +194,8 @@ output header {{ FP_Base_DepTag = AlphaISA::FP_Base_DepTag, Fpcr_DepTag = AlphaISA::Fpcr_DepTag, Uniq_DepTag = AlphaISA::Uniq_DepTag, + Lock_Flag_DepTag = AlphaISA::Lock_Flag_DepTag, + Lock_Addr_DepTag = AlphaISA::Lock_Addr_DepTag, IPR_Base_DepTag = AlphaISA::IPR_Base_DepTag }; diff --git a/arch/alpha/isa_traits.hh b/arch/alpha/isa_traits.hh index f47e90f86..938ba696e 100644 --- a/arch/alpha/isa_traits.hh +++ b/arch/alpha/isa_traits.hh @@ -38,6 +38,7 @@ using namespace LittleEndianGuest; #include "sim/host.hh" #include "sim/faults.hh" +class ExecContext; class FastCPU; class FullCPU; class Checkpoint; @@ -64,6 +65,7 @@ namespace AlphaISA NumIntRegs = 32, NumFloatRegs = 32, + // @todo: Figure out what this number really should be. NumMiscRegs = 32, MaxRegsOfAnyType = 32, @@ -106,7 +108,9 @@ namespace AlphaISA Ctrl_Base_DepTag = 64, Fpcr_DepTag = 64, // floating point control register Uniq_DepTag = 65, - IPR_Base_DepTag = 66 + Lock_Flag_DepTag = 66, + Lock_Addr_DepTag = 67, + IPR_Base_DepTag = 68 }; typedef uint64_t IntReg; @@ -123,15 +127,6 @@ namespace AlphaISA double d[NumFloatRegs]; // double-precision floating point view } FloatRegFile; - // control register file contents - typedef uint64_t MiscReg; - typedef struct { - uint64_t fpcr; // floating point condition codes - uint64_t uniq; // process-unique register - bool lock_flag; // lock flag for LL/SC - Addr lock_addr; // lock address for LL/SC - } MiscRegFile; - extern const Addr PageShift; extern const Addr PageBytes; extern const Addr PageMask; @@ -149,6 +144,39 @@ extern const Addr PageOffset; }; #endif + // control register file contents + typedef uint64_t MiscReg; + class MiscRegFile { + protected: + uint64_t fpcr; // floating point condition codes + uint64_t uniq; // process-unique register + bool lock_flag; // lock flag for LL/SC + Addr lock_addr; // lock address for LL/SC + + public: + MiscReg readReg(int misc_reg); + + MiscReg readRegWithEffect(int misc_reg, Fault &fault, ExecContext *xc); + + Fault setReg(int misc_reg, const MiscReg &val); + + Fault setRegWithEffect(int misc_reg, const MiscReg &val, + ExecContext *xc); + +#if FULL_SYSTEM + void clearIprs(); + + protected: + InternalProcReg ipr[NumInternalProcRegs]; // Internal processor regs + + private: + MiscReg readIpr(int idx, Fault &fault, ExecContext *xc); + + Fault setIpr(int idx, uint64_t val, ExecContext *xc); +#endif + friend class RegFile; + }; + enum { TotalNumRegs = NumIntRegs + NumFloatRegs + NumMiscRegs + NumInternalProcRegs @@ -172,11 +200,12 @@ extern const Addr PageOffset; Addr npc; // next-cycle program counter #if FULL_SYSTEM IntReg palregs[NumIntRegs]; // PAL shadow registers - InternalProcReg ipr[NumInternalProcRegs]; // internal processor regs int intrflag; // interrupt flag bool pal_shadow; // using pal_shadow registers - inline int instAsid() { return EV5::ITB_ASN_ASN(ipr[IPR_ITB_ASN]); } - inline int dataAsid() { return EV5::DTB_ASN_ASN(ipr[IPR_DTB_ASN]); } + inline int instAsid() + { return EV5::ITB_ASN_ASN(miscRegs.ipr[IPR_ITB_ASN]); } + inline int dataAsid() + { return EV5::DTB_ASN_ASN(miscRegs.ipr[IPR_DTB_ASN]); } #endif // FULL_SYSTEM void serialize(std::ostream &os); diff --git a/arch/alpha/stacktrace.cc b/arch/alpha/stacktrace.cc index 30ed07d9d..89b6b73a9 100644 --- a/arch/alpha/stacktrace.cc +++ b/arch/alpha/stacktrace.cc @@ -124,7 +124,7 @@ StackTrace::trace(ExecContext *_xc, bool is_call) { xc = _xc; - bool usermode = (xc->regs.ipr[AlphaISA::IPR_DTB_CM] & 0x18) != 0; + bool usermode = (xc->readMiscReg(AlphaISA::IPR_DTB_CM) & 0x18) != 0; Addr pc = xc->regs.npc; bool kernel = xc->system->kernelStart <= pc && pc <= xc->system->kernelEnd; @@ -196,22 +196,22 @@ StackTrace::trace(ExecContext *_xc, bool is_call) bool StackTrace::isEntry(Addr addr) { - if (addr == xc->regs.ipr[AlphaISA::IPR_PALtemp12]) + if (addr == xc->readMiscReg(AlphaISA::IPR_PALtemp12)) return true; - if (addr == xc->regs.ipr[AlphaISA::IPR_PALtemp7]) + if (addr == xc->readMiscReg(AlphaISA::IPR_PALtemp7)) return true; - if (addr == xc->regs.ipr[AlphaISA::IPR_PALtemp11]) + if (addr == xc->readMiscReg(AlphaISA::IPR_PALtemp11)) return true; - if (addr == xc->regs.ipr[AlphaISA::IPR_PALtemp21]) + if (addr == xc->readMiscReg(AlphaISA::IPR_PALtemp21)) return true; - if (addr == xc->regs.ipr[AlphaISA::IPR_PALtemp9]) + if (addr == xc->readMiscReg(AlphaISA::IPR_PALtemp9)) return true; - if (addr == xc->regs.ipr[AlphaISA::IPR_PALtemp2]) + if (addr == xc->readMiscReg(AlphaISA::IPR_PALtemp2)) return true; return false; diff --git a/arch/alpha/vtophys.cc b/arch/alpha/vtophys.cc index 3ffa4bd14..1d70196c5 100644 --- a/arch/alpha/vtophys.cc +++ b/arch/alpha/vtophys.cc @@ -82,7 +82,7 @@ Addr vtophys(ExecContext *xc, Addr addr) { AlphaISA::VAddr vaddr = addr; - Addr ptbr = xc->regs.ipr[AlphaISA::IPR_PALtemp20]; + Addr ptbr = xc->readMiscReg(AlphaISA::IPR_PALtemp20); Addr paddr = 0; //@todo Andrew couldn't remember why he commented some of this code //so I put it back in. Perhaps something to do with gdb debugging? diff --git a/arch/isa_parser.py b/arch/isa_parser.py index 6508ca02a..5185ed573 100755 --- a/arch/isa_parser.py +++ b/arch/isa_parser.py @@ -1263,10 +1263,10 @@ class ControlRegOperand(Operand): def makeConstructor(self): c = '' if self.is_src: - c += '\n\t_srcRegIdx[%d] = %s_DepTag;' % \ + c += '\n\t_srcRegIdx[%d] = %s;' % \ (self.src_reg_idx, self.reg_spec) if self.is_dest: - c += '\n\t_destRegIdx[%d] = %s_DepTag;' % \ + c += '\n\t_destRegIdx[%d] = %s;' % \ (self.dest_reg_idx, self.reg_spec) return c @@ -1274,7 +1274,7 @@ class ControlRegOperand(Operand): bit_select = 0 if (self.ctype == 'float' or self.ctype == 'double'): error(0, 'Attempt to read control register as FP') - base = 'xc->read%s()' % self.reg_spec + base = 'xc->readMiscReg(%s)' % self.reg_spec if self.size == self.dflt_size: return '%s = %s;\n' % (self.base_name, base) else: @@ -1284,7 +1284,7 @@ class ControlRegOperand(Operand): def makeWrite(self): if (self.ctype == 'float' or self.ctype == 'double'): error(0, 'Attempt to write control register as FP') - wb = 'xc->set%s(%s);\n' % (self.reg_spec, self.base_name) + wb = 'xc->setMiscReg(%s, %s);\n' % (self.reg_spec, self.base_name) wb += 'if (traceData) { traceData->setData(%s); }' % \ self.base_name return wb diff --git a/base/remote_gdb.cc b/base/remote_gdb.cc index 17ec21fed..5f1a2db2c 100644 --- a/base/remote_gdb.cc +++ b/base/remote_gdb.cc @@ -371,7 +371,7 @@ RemoteGDB::acc(Addr va, size_t len) if (AlphaISA::PcPAL(va) || va < 0x10000) return true; - Addr ptbr = context->regs.ipr[AlphaISA::IPR_PALtemp20]; + Addr ptbr = context->readMiscReg(AlphaISA::IPR_PALtemp20); TheISA::PageTableEntry pte = kernel_pte_lookup(pmem, ptbr, va); if (!pte.valid()) { DPRINTF(GDBAcc, "acc: %#x pte is invalid\n", va); diff --git a/cpu/exec_context.hh b/cpu/exec_context.hh index 3e0d77254..88b12c301 100644 --- a/cpu/exec_context.hh +++ b/cpu/exec_context.hh @@ -71,6 +71,7 @@ class ExecContext typedef TheISA::RegFile RegFile; typedef TheISA::MachInst MachInst; typedef TheISA::MiscRegFile MiscRegFile; + typedef TheISA::MiscReg MiscReg; public: enum Status { @@ -270,8 +271,8 @@ class ExecContext #if FULL_SYSTEM && defined(TARGET_ALPHA) if (req->flags & LOCKED) { MiscRegFile *cregs = &req->xc->regs.miscRegs; - cregs->lock_addr = req->paddr; - cregs->lock_flag = true; + cregs->setReg(TheISA::Lock_Addr_DepTag, req->paddr); + cregs->setReg(TheISA::Lock_Flag_DepTag, true); } #endif @@ -297,10 +298,12 @@ class ExecContext req->result = 2; req->xc->storeCondFailures = 0;//Needed? [RGD] } else { - req->result = cregs->lock_flag; - if (!cregs->lock_flag || - ((cregs->lock_addr & ~0xf) != (req->paddr & ~0xf))) { - cregs->lock_flag = false; + bool lock_flag = cregs->readReg(TheISA::Lock_Flag_DepTag); + Addr lock_addr = cregs->readReg(TheISA::Lock_Addr_DepTag); + req->result = lock_flag; + if (!lock_flag || + ((lock_addr & ~0xf) != (req->paddr & ~0xf))) { + cregs->setReg(TheISA::Lock_Flag_DepTag, false); if (((++req->xc->storeCondFailures) % 100000) == 0) { std::cerr << "Warning: " << req->xc->storeCondFailures @@ -321,8 +324,9 @@ class ExecContext // through. for (int i = 0; i < system->execContexts.size(); i++){ cregs = &system->execContexts[i]->regs.miscRegs; - if ((cregs->lock_addr & ~0xf) == (req->paddr & ~0xf)) { - cregs->lock_flag = false; + if ((cregs->readReg(TheISA::Lock_Addr_DepTag) & ~0xf) == + (req->paddr & ~0xf)) { + cregs->setReg(TheISA::Lock_Flag_DepTag, false); } } @@ -398,29 +402,27 @@ class ExecContext regs.npc = val; } - uint64_t readUniq() + MiscReg readMiscReg(int misc_reg) { - return regs.miscRegs.uniq; + return regs.miscRegs.readReg(misc_reg); } - void setUniq(uint64_t val) + MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault) { - regs.miscRegs.uniq = val; + return regs.miscRegs.readRegWithEffect(misc_reg, fault, this); } - uint64_t readFpcr() + Fault setMiscReg(int misc_reg, const MiscReg &val) { - return regs.miscRegs.fpcr; + return regs.miscRegs.setReg(misc_reg, val); } - void setFpcr(uint64_t val) + Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val) { - regs.miscRegs.fpcr = val; + return regs.miscRegs.setRegWithEffect(misc_reg, val, this); } #if FULL_SYSTEM - uint64_t readIpr(int idx, Fault &fault); - Fault setIpr(int idx, uint64_t val); int readIntrFlag() { return regs.intrflag; } void setIntrFlag(int val) { regs.intrflag = val; } Fault hwrei(); diff --git a/cpu/o3/alpha_cpu.hh b/cpu/o3/alpha_cpu.hh index b35bcf9e3..47ea532a6 100644 --- a/cpu/o3/alpha_cpu.hh +++ b/cpu/o3/alpha_cpu.hh @@ -41,6 +41,8 @@ class AlphaFullCPU : public FullO3CPU { protected: typedef TheISA::IntReg IntReg; + typedef TheISA::MiscReg MiscReg; + public: typedef typename Impl::Params Params; @@ -111,33 +113,24 @@ class AlphaFullCPU : public FullO3CPU // Later on may want to remove this misc stuff from the regfile and // have it handled at this level. Might prove to be an issue when // trying to rename source/destination registers... - uint64_t readUniq() + MiscReg readMiscReg(int misc_reg) { - return this->regFile.readUniq(); + // Dummy function for now. + // @todo: Fix this once reg file gets fixed. + return 0; } - void setUniq(uint64_t val) + Fault setMiscReg(int misc_reg, const MiscReg &val) { - this->regFile.setUniq(val); - } - - uint64_t readFpcr() - { - return this->regFile.readFpcr(); - } - - void setFpcr(uint64_t val) - { - this->regFile.setFpcr(val); + // Dummy function for now. + // @todo: Fix this once reg file gets fixed. + return NoFault; } // Most of the full system code and syscall emulation is not yet // implemented. These functions do show what the final interface will // look like. #if FULL_SYSTEM - uint64_t *getIpr(); - uint64_t readIpr(int idx, Fault &fault); - Fault setIpr(int idx, uint64_t val); int readIntrFlag(); void setIntrFlag(int val); Fault hwrei(); @@ -216,8 +209,8 @@ class AlphaFullCPU : public FullO3CPU #if FULL_SYSTEM && defined(TARGET_ALPHA) if (req->flags & LOCKED) { MiscRegFile *cregs = &req->xc->regs.miscRegs; - cregs->lock_addr = req->paddr; - cregs->lock_flag = true; + cregs->setReg(TheISA::Lock_Addr_DepTag, req->paddr); + cregs->setReg(TheISA::Lock_Flag_DepTag, true); } #endif @@ -242,22 +235,24 @@ class AlphaFullCPU : public FullO3CPU // If this is a store conditional, act appropriately if (req->flags & LOCKED) { - cregs = &this->xc->regs.miscRegs; + cregs = &req->xc->regs.miscRegs; if (req->flags & UNCACHEABLE) { // Don't update result register (see stq_c in isa_desc) req->result = 2; req->xc->storeCondFailures = 0;//Needed? [RGD] } else { - req->result = cregs->lock_flag; - if (!cregs->lock_flag || - ((cregs->lock_addr & ~0xf) != (req->paddr & ~0xf))) { - cregs->lock_flag = false; + bool lock_flag = cregs->readReg(TheISA::Lock_Flag_DepTag); + Addr lock_addr = cregs->readReg(TheISA::Lock_Addr_DepTag); + req->result = lock_flag; + if (!lock_flag || + ((lock_addr & ~0xf) != (req->paddr & ~0xf))) { + cregs->setReg(TheISA::Lock_Flag_DepTag, false); if (((++req->xc->storeCondFailures) % 100000) == 0) { std::cerr << "Warning: " << req->xc->storeCondFailures << " consecutive store conditional failures " - << "on cpu " << this->cpu_id + << "on cpu " << req->xc->cpu_id << std::endl; } return NoFault; @@ -273,8 +268,9 @@ class AlphaFullCPU : public FullO3CPU // through. for (int i = 0; i < this->system->execContexts.size(); i++){ cregs = &this->system->execContexts[i]->regs.miscRegs; - if ((cregs->lock_addr & ~0xf) == (req->paddr & ~0xf)) { - cregs->lock_flag = false; + if ((cregs->readReg(TheISA::Lock_Addr_DepTag) & ~0xf) == + (req->paddr & ~0xf)) { + cregs->setReg(TheISA::Lock_Flag_DepTag, false); } } diff --git a/cpu/o3/alpha_cpu_impl.hh b/cpu/o3/alpha_cpu_impl.hh index 7ec1ba663..bd4e34914 100644 --- a/cpu/o3/alpha_cpu_impl.hh +++ b/cpu/o3/alpha_cpu_impl.hh @@ -179,12 +179,12 @@ AlphaFullCPU::copyToXC() this->xc->regs.floatRegFile.q[i] = this->regFile.readFloatRegInt(renamed_reg); } - +/* this->xc->regs.miscRegs.fpcr = this->regFile.miscRegs.fpcr; this->xc->regs.miscRegs.uniq = this->regFile.miscRegs.uniq; this->xc->regs.miscRegs.lock_flag = this->regFile.miscRegs.lock_flag; this->xc->regs.miscRegs.lock_addr = this->regFile.miscRegs.lock_addr; - +*/ this->xc->regs.pc = this->rob.readHeadPC(); this->xc->regs.npc = this->xc->regs.pc+4; @@ -221,13 +221,13 @@ AlphaFullCPU::copyFromXC() this->regFile.setFloatRegInt(renamed_reg, this->xc->regs.floatRegFile.q[i]); } - + /* // Then loop through the misc registers. this->regFile.miscRegs.fpcr = this->xc->regs.miscRegs.fpcr; this->regFile.miscRegs.uniq = this->xc->regs.miscRegs.uniq; this->regFile.miscRegs.lock_flag = this->xc->regs.miscRegs.lock_flag; this->regFile.miscRegs.lock_addr = this->xc->regs.miscRegs.lock_addr; - + */ // Then finally set the PC and the next PC. // regFile.pc = xc->regs.pc; // regFile.npc = xc->regs.npc; @@ -237,27 +237,6 @@ AlphaFullCPU::copyFromXC() #if FULL_SYSTEM -template -uint64_t * -AlphaFullCPU::getIpr() -{ - return this->regFile.getIpr(); -} - -template -uint64_t -AlphaFullCPU::readIpr(int idx, Fault &fault) -{ - return this->regFile.readIpr(idx, fault); -} - -template -Fault -AlphaFullCPU::setIpr(int idx, uint64_t val) -{ - return this->regFile.setIpr(idx, val); -} - template int AlphaFullCPU::readIntrFlag() @@ -277,16 +256,14 @@ template Fault AlphaFullCPU::hwrei() { - uint64_t *ipr = getIpr(); - if (!inPalMode()) return UnimplementedOpcodeFault; - this->setNextPC(ipr[AlphaISA::IPR_EXC_ADDR]); + this->setNextPC(this->regFile.miscRegs.readReg(AlphaISA::IPR_EXC_ADDR)); // kernelStats.hwrei(); - if ((ipr[AlphaISA::IPR_EXC_ADDR] & 1) == 0) + if ((this->regFile.miscRegs.readReg(AlphaISA::IPR_EXC_ADDR) & 1) == 0) // AlphaISA::swap_palshadow(®s, false); this->checkInterrupts = true; @@ -337,22 +314,23 @@ AlphaFullCPU::trap(Fault fault) if (fault == ArithmeticFault) panic("Arithmetic traps are unimplemented!"); - AlphaISA::InternalProcReg *ipr = getIpr(); - // exception restart address - Get the commit PC if (fault != InterruptFault || !inPalMode(PC)) - ipr[AlphaISA::IPR_EXC_ADDR] = PC; + this->regFile.miscRegs.setReg(AlphaISA::IPR_EXC_ADDR, PC); if (fault == PalFault || fault == ArithmeticFault /* || fault == InterruptFault && !PC_PAL(regs.pc) */) { // traps... skip faulting instruction - ipr[AlphaISA::IPR_EXC_ADDR] += 4; + AlphaISA::MiscReg ipr_exc_addr = + this->regFile.miscRegs.readReg(AlphaISA::IPR_EXC_ADDR); + this->regFile.miscRegs.setReg(AlphaISA::IPR_EXC_ADDR, + ipr_exc_addr + 4); } if (!inPalMode(PC)) swapPALShadow(true); - this->regFile.setPC( ipr[AlphaISA::IPR_PAL_BASE] + + this->regFile.setPC(this->regFile.miscRegs.readReg(AlphaISA::IPR_PAL_BASE) + AlphaISA::fault_addr(fault) ); this->regFile.setNextPC(PC + sizeof(MachInst)); } diff --git a/cpu/o3/alpha_dyn_inst.hh b/cpu/o3/alpha_dyn_inst.hh index f282c287c..e7f7d3a57 100644 --- a/cpu/o3/alpha_dyn_inst.hh +++ b/cpu/o3/alpha_dyn_inst.hh @@ -54,6 +54,8 @@ class AlphaDynInst : public BaseDynInst typedef TheISA::RegIndex RegIndex; /** Integer register index type. */ typedef TheISA::IntReg IntReg; + /** Misc register index type. */ + typedef TheISA::MiscReg MiscReg; enum { MaxInstSrcRegs = TheISA::MaxInstSrcRegs, //< Max source regs @@ -75,15 +77,35 @@ class AlphaDynInst : public BaseDynInst } public: - uint64_t readUniq(); - void setUniq(uint64_t val); + MiscReg readMiscReg(int misc_reg) + { + // Dummy function for now. + // @todo: Fix this once reg file gets fixed. + return 0; + } - uint64_t readFpcr(); - void setFpcr(uint64_t val); + MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault) + { + // Dummy function for now. + // @todo: Fix this once reg file gets fixed. + return 0; + } + + Fault setMiscReg(int misc_reg, const MiscReg &val) + { + // Dummy function for now. + // @todo: Fix this once reg file gets fixed. + return NoFault; + } + + Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val) + { + // Dummy function for now. + // @todo: Fix this once reg file gets fixed. + return NoFault; + } #if FULL_SYSTEM - uint64_t readIpr(int idx, Fault &fault); - Fault setIpr(int idx, uint64_t val); Fault hwrei(); int readIntrFlag(); void setIntrFlag(int val); diff --git a/cpu/o3/alpha_dyn_inst_impl.hh b/cpu/o3/alpha_dyn_inst_impl.hh index eebe7675a..96b7d3430 100644 --- a/cpu/o3/alpha_dyn_inst_impl.hh +++ b/cpu/o3/alpha_dyn_inst_impl.hh @@ -67,49 +67,7 @@ AlphaDynInst::AlphaDynInst(StaticInstPtr &_staticInst) } } -template -uint64_t -AlphaDynInst::readUniq() -{ - return this->cpu->readUniq(); -} - -template -void -AlphaDynInst::setUniq(uint64_t val) -{ - this->cpu->setUniq(val); -} - -template -uint64_t -AlphaDynInst::readFpcr() -{ - return this->cpu->readFpcr(); -} - -template -void -AlphaDynInst::setFpcr(uint64_t val) -{ - this->cpu->setFpcr(val); -} - #if FULL_SYSTEM -template -uint64_t -AlphaDynInst::readIpr(int idx, Fault &fault) -{ - return this->cpu->readIpr(idx, fault); -} - -template -Fault -AlphaDynInst::setIpr(int idx, uint64_t val) -{ - return this->cpu->setIpr(idx, val); -} - template Fault AlphaDynInst::hwrei() diff --git a/cpu/o3/cpu.cc b/cpu/o3/cpu.cc index 706657887..a8c620028 100644 --- a/cpu/o3/cpu.cc +++ b/cpu/o3/cpu.cc @@ -264,13 +264,13 @@ FullO3CPU::init() regFile.floatRegFile[i].d = src_xc->regs.floatRegFile.d[i]; regFile.floatRegFile[i].q = src_xc->regs.floatRegFile.q[i]; } - +/* // Then loop through the misc registers. regFile.miscRegs.fpcr = src_xc->regs.miscRegs.fpcr; regFile.miscRegs.uniq = src_xc->regs.miscRegs.uniq; regFile.miscRegs.lock_flag = src_xc->regs.miscRegs.lock_flag; regFile.miscRegs.lock_addr = src_xc->regs.miscRegs.lock_addr; - +*/ // Then finally set the PC and the next PC. regFile.pc = src_xc->regs.pc; regFile.npc = src_xc->regs.npc; diff --git a/cpu/o3/cpu.hh b/cpu/o3/cpu.hh index 321d61dce..09d9c3d66 100644 --- a/cpu/o3/cpu.hh +++ b/cpu/o3/cpu.hh @@ -152,11 +152,11 @@ class FullO3CPU : public BaseFullCPU /** Get instruction asid. */ int getInstAsid() - { return ITB_ASN_ASN(regFile.getIpr()[TheISA::IPR_ITB_ASN]); } + { return ITB_ASN_ASN(regFile.miscRegs.readReg(TheISA::IPR_ITB_ASN)); } /** Get data asid. */ int getDataAsid() - { return DTB_ASN_ASN(regFile.getIpr()[TheISA::IPR_DTB_ASN]); } + { return DTB_ASN_ASN(regFile.miscRegs.readReg(TheISA::IPR_DTB_ASN)); } #else bool validInstAddr(Addr addr) { return thread[0]->validInstAddr(addr); } diff --git a/cpu/o3/regfile.hh b/cpu/o3/regfile.hh index ee7b8858e..1bc7159f6 100644 --- a/cpu/o3/regfile.hh +++ b/cpu/o3/regfile.hh @@ -56,6 +56,8 @@ class PhysRegFile typedef TheISA::IntReg IntReg; typedef TheISA::FloatReg FloatReg; typedef TheISA::MiscRegFile MiscRegFile; + typedef TheISA::MiscReg MiscReg; + //Note that most of the definitions of the IntReg, FloatReg, etc. exist //within the Impl/ISA class and not within this PhysRegFile class. @@ -194,30 +196,21 @@ class PhysRegFile //Consider leaving this stuff and below in some implementation specific //file as opposed to the general register file. Or have a derived class. - uint64_t readUniq() + MiscReg readMiscReg(int misc_reg) { - return miscRegs.uniq; + // Dummy function for now. + // @todo: Fix this once proxy XC is used. + return 0; } - void setUniq(uint64_t val) + Fault setMiscReg(int misc_reg, const MiscReg &val) { - miscRegs.uniq = val; - } - - uint64_t readFpcr() - { - return miscRegs.fpcr; - } - - void setFpcr(uint64_t val) - { - miscRegs.fpcr = val; + // Dummy function for now. + // @todo: Fix this once proxy XC is used. + return NoFault; } #if FULL_SYSTEM - uint64_t readIpr(int idx, Fault &fault); - Fault setIpr(int idx, uint64_t val); - InternalProcReg *getIpr() { return ipr; } int readIntrFlag() { return intrflag; } void setIntrFlag(int val) { intrflag = val; } #endif @@ -272,368 +265,4 @@ PhysRegFile::PhysRegFile(unsigned _numPhysicalIntRegs, memset(floatRegFile, 0, sizeof(*floatRegFile)); } -#if FULL_SYSTEM - -//Problem: This code doesn't make sense at the RegFile level because it -//needs things such as the itb and dtb. Either put it at the CPU level or -//the DynInst level. -template -uint64_t -PhysRegFile::readIpr(int idx, Fault &fault) -{ - uint64_t retval = 0; // return value, default 0 - - switch (idx) { - case TheISA::IPR_PALtemp0: - case TheISA::IPR_PALtemp1: - case TheISA::IPR_PALtemp2: - case TheISA::IPR_PALtemp3: - case TheISA::IPR_PALtemp4: - case TheISA::IPR_PALtemp5: - case TheISA::IPR_PALtemp6: - case TheISA::IPR_PALtemp7: - case TheISA::IPR_PALtemp8: - case TheISA::IPR_PALtemp9: - case TheISA::IPR_PALtemp10: - case TheISA::IPR_PALtemp11: - case TheISA::IPR_PALtemp12: - case TheISA::IPR_PALtemp13: - case TheISA::IPR_PALtemp14: - case TheISA::IPR_PALtemp15: - case TheISA::IPR_PALtemp16: - case TheISA::IPR_PALtemp17: - case TheISA::IPR_PALtemp18: - case TheISA::IPR_PALtemp19: - case TheISA::IPR_PALtemp20: - case TheISA::IPR_PALtemp21: - case TheISA::IPR_PALtemp22: - case TheISA::IPR_PALtemp23: - case TheISA::IPR_PAL_BASE: - - case TheISA::IPR_IVPTBR: - case TheISA::IPR_DC_MODE: - case TheISA::IPR_MAF_MODE: - case TheISA::IPR_ISR: - case TheISA::IPR_EXC_ADDR: - case TheISA::IPR_IC_PERR_STAT: - case TheISA::IPR_DC_PERR_STAT: - case TheISA::IPR_MCSR: - case TheISA::IPR_ASTRR: - case TheISA::IPR_ASTER: - case TheISA::IPR_SIRR: - case TheISA::IPR_ICSR: - case TheISA::IPR_ICM: - case TheISA::IPR_DTB_CM: - case TheISA::IPR_IPLR: - case TheISA::IPR_INTID: - case TheISA::IPR_PMCTR: - // no side-effect - retval = ipr[idx]; - break; - - case TheISA::IPR_CC: - retval |= ipr[idx] & ULL(0xffffffff00000000); - retval |= curTick & ULL(0x00000000ffffffff); - break; - - case TheISA::IPR_VA: - retval = ipr[idx]; - break; - - case TheISA::IPR_VA_FORM: - case TheISA::IPR_MM_STAT: - case TheISA::IPR_IFAULT_VA_FORM: - case TheISA::IPR_EXC_MASK: - case TheISA::IPR_EXC_SUM: - retval = ipr[idx]; - break; - - case TheISA::IPR_DTB_PTE: - { - TheISA::PTE &pte = cpu->dtb->index(1); - - retval |= ((u_int64_t)pte.ppn & ULL(0x7ffffff)) << 32; - retval |= ((u_int64_t)pte.xre & ULL(0xf)) << 8; - retval |= ((u_int64_t)pte.xwe & ULL(0xf)) << 12; - retval |= ((u_int64_t)pte.fonr & ULL(0x1)) << 1; - retval |= ((u_int64_t)pte.fonw & ULL(0x1))<< 2; - retval |= ((u_int64_t)pte.asma & ULL(0x1)) << 4; - retval |= ((u_int64_t)pte.asn & ULL(0x7f)) << 57; - } - break; - - // write only registers - case TheISA::IPR_HWINT_CLR: - case TheISA::IPR_SL_XMIT: - case TheISA::IPR_DC_FLUSH: - case TheISA::IPR_IC_FLUSH: - case TheISA::IPR_ALT_MODE: - case TheISA::IPR_DTB_IA: - case TheISA::IPR_DTB_IAP: - case TheISA::IPR_ITB_IA: - case TheISA::IPR_ITB_IAP: - fault = UnimplementedOpcodeFault; - break; - - default: - // invalid IPR - fault = UnimplementedOpcodeFault; - break; - } - - return retval; -} - -extern int break_ipl; - -template -Fault -PhysRegFile::setIpr(int idx, uint64_t val) -{ - uint64_t old; - - switch (idx) { - case TheISA::IPR_PALtemp0: - case TheISA::IPR_PALtemp1: - case TheISA::IPR_PALtemp2: - case TheISA::IPR_PALtemp3: - case TheISA::IPR_PALtemp4: - case TheISA::IPR_PALtemp5: - case TheISA::IPR_PALtemp6: - case TheISA::IPR_PALtemp7: - case TheISA::IPR_PALtemp8: - case TheISA::IPR_PALtemp9: - case TheISA::IPR_PALtemp10: - case TheISA::IPR_PALtemp11: - case TheISA::IPR_PALtemp12: - case TheISA::IPR_PALtemp13: - case TheISA::IPR_PALtemp14: - case TheISA::IPR_PALtemp15: - case TheISA::IPR_PALtemp16: - case TheISA::IPR_PALtemp17: - case TheISA::IPR_PALtemp18: - case TheISA::IPR_PALtemp19: - case TheISA::IPR_PALtemp20: - case TheISA::IPR_PALtemp21: - case TheISA::IPR_PALtemp22: - case TheISA::IPR_PAL_BASE: - case TheISA::IPR_IC_PERR_STAT: - case TheISA::IPR_DC_PERR_STAT: - case TheISA::IPR_PMCTR: - // write entire quad w/ no side-effect - ipr[idx] = val; - break; - - case TheISA::IPR_CC_CTL: - // This IPR resets the cycle counter. We assume this only - // happens once... let's verify that. - assert(ipr[idx] == 0); - ipr[idx] = 1; - break; - - case TheISA::IPR_CC: - // This IPR only writes the upper 64 bits. It's ok to write - // all 64 here since we mask out the lower 32 in rpcc (see - // isa_desc). - ipr[idx] = val; - break; - - case TheISA::IPR_PALtemp23: - // write entire quad w/ no side-effect - old = ipr[idx]; - ipr[idx] = val; - break; - - case TheISA::IPR_DTB_PTE: - // write entire quad w/ no side-effect, tag is forthcoming - ipr[idx] = val; - break; - - case TheISA::IPR_EXC_ADDR: - // second least significant bit in PC is always zero - ipr[idx] = val & ~2; - break; - - case TheISA::IPR_ASTRR: - case TheISA::IPR_ASTER: - // only write least significant four bits - privilege mask - ipr[idx] = val & 0xf; - break; - - case TheISA::IPR_IPLR: - // only write least significant five bits - interrupt level - ipr[idx] = val & 0x1f; - break; - - case TheISA::IPR_DTB_CM: - - case TheISA::IPR_ICM: - // only write two mode bits - processor mode - ipr[idx] = val & 0x18; - break; - - case TheISA::IPR_ALT_MODE: - // only write two mode bits - processor mode - ipr[idx] = val & 0x18; - break; - - case TheISA::IPR_MCSR: - // more here after optimization... - ipr[idx] = val; - break; - - case TheISA::IPR_SIRR: - // only write software interrupt mask - ipr[idx] = val & 0x7fff0; - break; - - case TheISA::IPR_ICSR: - ipr[idx] = val & ULL(0xffffff0300); - break; - - case TheISA::IPR_IVPTBR: - case TheISA::IPR_MVPTBR: - ipr[idx] = val & ULL(0xffffffffc0000000); - break; - - case TheISA::IPR_DC_TEST_CTL: - ipr[idx] = val & 0x1ffb; - break; - - case TheISA::IPR_DC_MODE: - case TheISA::IPR_MAF_MODE: - ipr[idx] = val & 0x3f; - break; - - case TheISA::IPR_ITB_ASN: - ipr[idx] = val & 0x7f0; - break; - - case TheISA::IPR_DTB_ASN: - ipr[idx] = val & ULL(0xfe00000000000000); - break; - - case TheISA::IPR_EXC_SUM: - case TheISA::IPR_EXC_MASK: - // any write to this register clears it - ipr[idx] = 0; - break; - - case TheISA::IPR_INTID: - case TheISA::IPR_SL_RCV: - case TheISA::IPR_MM_STAT: - case TheISA::IPR_ITB_PTE_TEMP: - case TheISA::IPR_DTB_PTE_TEMP: - // read-only registers - return UnimplementedOpcodeFault; - - case TheISA::IPR_HWINT_CLR: - case TheISA::IPR_SL_XMIT: - case TheISA::IPR_DC_FLUSH: - case TheISA::IPR_IC_FLUSH: - // the following are write only - ipr[idx] = val; - break; - - case TheISA::IPR_DTB_IA: - // really a control write - ipr[idx] = 0; - - cpu->dtb->flushAll(); - break; - - case TheISA::IPR_DTB_IAP: - // really a control write - ipr[idx] = 0; - - cpu->dtb->flushProcesses(); - break; - - case TheISA::IPR_DTB_IS: - // really a control write - ipr[idx] = val; - - cpu->dtb->flushAddr(val, DTB_ASN_ASN(ipr[TheISA::IPR_DTB_ASN])); - break; - - case TheISA::IPR_DTB_TAG: { - struct TheISA::PTE pte; - - // FIXME: granularity hints NYI... - if (DTB_PTE_GH(ipr[TheISA::IPR_DTB_PTE]) != 0) - panic("PTE GH field != 0"); - - // write entire quad - ipr[idx] = val; - - // construct PTE for new entry - pte.ppn = DTB_PTE_PPN(ipr[TheISA::IPR_DTB_PTE]); - pte.xre = DTB_PTE_XRE(ipr[TheISA::IPR_DTB_PTE]); - pte.xwe = DTB_PTE_XWE(ipr[TheISA::IPR_DTB_PTE]); - pte.fonr = DTB_PTE_FONR(ipr[TheISA::IPR_DTB_PTE]); - pte.fonw = DTB_PTE_FONW(ipr[TheISA::IPR_DTB_PTE]); - pte.asma = DTB_PTE_ASMA(ipr[TheISA::IPR_DTB_PTE]); - pte.asn = DTB_ASN_ASN(ipr[TheISA::IPR_DTB_ASN]); - - // insert new TAG/PTE value into data TLB - cpu->dtb->insert(val, pte); - } - break; - - case TheISA::IPR_ITB_PTE: { - struct TheISA::PTE pte; - - // FIXME: granularity hints NYI... - if (ITB_PTE_GH(val) != 0) - panic("PTE GH field != 0"); - - // write entire quad - ipr[idx] = val; - - // construct PTE for new entry - pte.ppn = ITB_PTE_PPN(val); - pte.xre = ITB_PTE_XRE(val); - pte.xwe = 0; - pte.fonr = ITB_PTE_FONR(val); - pte.fonw = ITB_PTE_FONW(val); - pte.asma = ITB_PTE_ASMA(val); - pte.asn = ITB_ASN_ASN(ipr[TheISA::IPR_ITB_ASN]); - - // insert new TAG/PTE value into data TLB - cpu->itb->insert(ipr[TheISA::IPR_ITB_TAG], pte); - } - break; - - case TheISA::IPR_ITB_IA: - // really a control write - ipr[idx] = 0; - - cpu->itb->flushAll(); - break; - - case TheISA::IPR_ITB_IAP: - // really a control write - ipr[idx] = 0; - - cpu->itb->flushProcesses(); - break; - - case TheISA::IPR_ITB_IS: - // really a control write - ipr[idx] = val; - - cpu->itb->flushAddr(val, ITB_ASN_ASN(ipr[TheISA::IPR_ITB_ASN])); - break; - - default: - // invalid IPR - return UnimplementedOpcodeFault; - } - - // no error... - return NoFault; -} - -#endif // #if FULL_SYSTEM - #endif // __CPU_O3_CPU_REGFILE_HH__ diff --git a/cpu/simple/cpu.cc b/cpu/simple/cpu.cc index 944bdbb0a..dd2d53c17 100644 --- a/cpu/simple/cpu.cc +++ b/cpu/simple/cpu.cc @@ -659,12 +659,11 @@ SimpleCPU::tick() int ipl = 0; int summary = 0; checkInterrupts = false; - IntReg *ipr = xc->regs.ipr; - if (xc->regs.ipr[IPR_SIRR]) { + if (xc->readMiscReg(IPR_SIRR)) { for (int i = INTLEVEL_SOFTWARE_MIN; i < INTLEVEL_SOFTWARE_MAX; i++) { - if (ipr[IPR_SIRR] & (ULL(1) << i)) { + if (xc->readMiscReg(IPR_SIRR) & (ULL(1) << i)) { // See table 4-19 of 21164 hardware reference ipl = (i - INTLEVEL_SOFTWARE_MIN) + 1; summary |= (ULL(1) << i); @@ -682,16 +681,16 @@ SimpleCPU::tick() } } - if (ipr[IPR_ASTRR]) + if (xc->readMiscReg(IPR_ASTRR)) panic("asynchronous traps not implemented\n"); - if (ipl && ipl > xc->regs.ipr[IPR_IPLR]) { - ipr[IPR_ISR] = summary; - ipr[IPR_INTID] = ipl; + if (ipl && ipl > xc->readMiscReg(IPR_IPLR)) { + xc->setMiscReg(IPR_ISR, summary); + xc->setMiscReg(IPR_INTID, ipl); xc->ev5_trap(InterruptFault); DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n", - ipr[IPR_IPLR], ipl, summary); + xc->readMiscReg(IPR_IPLR), ipl, summary); } } #endif @@ -782,7 +781,7 @@ SimpleCPU::tick() } if (xc->profile) { - bool usermode = (xc->regs.ipr[AlphaISA::IPR_DTB_CM] & 0x18) != 0; + bool usermode = (xc->readMiscReg(AlphaISA::IPR_DTB_CM) & 0x18) != 0; xc->profilePC = usermode ? 1 : xc->regs.pc; ProfileNode *node = xc->profile->consume(xc, inst); if (node) diff --git a/cpu/simple/cpu.hh b/cpu/simple/cpu.hh index ed7b1e29b..3bc905be1 100644 --- a/cpu/simple/cpu.hh +++ b/cpu/simple/cpu.hh @@ -65,6 +65,7 @@ class SimpleCPU : public BaseCPU { protected: typedef TheISA::MachInst MachInst; + typedef TheISA::MiscReg MiscReg; public: // main simulation loop (one cycle) void tick(); @@ -321,15 +322,27 @@ class SimpleCPU : public BaseCPU uint64_t readPC() { return xc->readPC(); } void setNextPC(uint64_t val) { xc->setNextPC(val); } - uint64_t readUniq() { return xc->readUniq(); } - void setUniq(uint64_t val) { xc->setUniq(val); } + MiscReg readMiscReg(int misc_reg) + { + return xc->readMiscReg(misc_reg); + } - uint64_t readFpcr() { return xc->readFpcr(); } - void setFpcr(uint64_t val) { xc->setFpcr(val); } + MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault) + { + return xc->readMiscRegWithEffect(misc_reg, fault); + } + + Fault setMiscReg(int misc_reg, const MiscReg &val) + { + return xc->setMiscReg(misc_reg, val); + } + + Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val) + { + return xc->setMiscRegWithEffect(misc_reg, val); + } #if FULL_SYSTEM - uint64_t readIpr(int idx, Fault &fault) { return xc->readIpr(idx, fault); } - Fault setIpr(int idx, uint64_t val) { return xc->setIpr(idx, val); } Fault hwrei() { return xc->hwrei(); } int readIntrFlag() { return xc->readIntrFlag(); } void setIntrFlag(int val) { xc->setIntrFlag(val); } diff --git a/dev/sinic.cc b/dev/sinic.cc index c499d2f49..84f5c70df 100644 --- a/dev/sinic.cc +++ b/dev/sinic.cc @@ -376,7 +376,7 @@ Device::read(MemReqPtr &req, uint8_t *data) Fault Device::readBar0(MemReqPtr &req, Addr daddr, uint8_t *data) { - int cpu = (req->xc->regs.ipr[TheISA::IPR_PALtemp16] >> 8) & 0xff; + int cpu = (req->xc->readMiscReg(TheISA::IPR_PALtemp16) >> 8) & 0xff; Addr index = daddr >> Regs::VirtualShift; Addr raddr = daddr & Regs::VirtualMask; @@ -472,7 +472,7 @@ Device::write(MemReqPtr &req, const uint8_t *data) Fault Device::writeBar0(MemReqPtr &req, Addr daddr, const uint8_t *data) { - int cpu = (req->xc->regs.ipr[TheISA::IPR_PALtemp16] >> 8) & 0xff; + int cpu = (req->xc->readMiscReg(TheISA::IPR_PALtemp16) >> 8) & 0xff; Addr index = daddr >> Regs::VirtualShift; Addr raddr = daddr & Regs::VirtualMask; diff --git a/kern/kernel_stats.cc b/kern/kernel_stats.cc index 50bbaee00..3beeaa14a 100644 --- a/kern/kernel_stats.cc +++ b/kern/kernel_stats.cc @@ -240,7 +240,7 @@ Statistics::swpipl(int ipl) void Statistics::mode(cpu_mode newmode) { - Addr pcbb = xc->regs.ipr[AlphaISA::IPR_PALtemp23]; + Addr pcbb = xc->readMiscReg(AlphaISA::IPR_PALtemp23); if ((newmode == kernel || newmode == interrupt) && pcbb == idleProcess) diff --git a/kern/system_events.cc b/kern/system_events.cc index 55595b9b6..91625e60a 100644 --- a/kern/system_events.cc +++ b/kern/system_events.cc @@ -67,7 +67,7 @@ FnEvent::process(ExecContext *xc) void IdleStartEvent::process(ExecContext *xc) { - xc->kernelStats->setIdleProcess(xc->regs.ipr[AlphaISA::IPR_PALtemp23]); + xc->kernelStats->setIdleProcess(xc->readMiscReg(AlphaISA::IPR_PALtemp23)); remove(); } diff --git a/kern/tru64/tru64.hh b/kern/tru64/tru64.hh index 1579a54d8..ad568cb0c 100644 --- a/kern/tru64/tru64.hh +++ b/kern/tru64/tru64.hh @@ -729,7 +729,7 @@ class Tru64 { regs->floatRegFile.q[i] = htog(sc->sc_fpregs[i]); } - regs->miscRegs.fpcr = htog(sc->sc_fpcr); + xc->setMiscReg(TheISA::Fpcr_DepTag, htog(sc->sc_fpcr)); return 0; } @@ -889,7 +889,7 @@ class Tru64 { ssp->nxm_sysevent = htog(0); if (i == 0) { - uint64_t uniq = xc->regs.miscRegs.uniq; + uint64_t uniq = xc->readMiscReg(TheISA::Uniq_DepTag); ssp->nxm_u.pth_id = htog(uniq + gtoh(attrp->nxm_uniq_offset)); ssp->nxm_u.nxm_active = htog(uniq | 1); } @@ -924,7 +924,7 @@ class Tru64 { ec->regs.intRegFile[TheISA::ArgumentReg0] = gtoh(attrp->registers.a0); ec->regs.intRegFile[27/*t12*/] = gtoh(attrp->registers.pc); ec->regs.intRegFile[TheISA::StackPointerReg] = gtoh(attrp->registers.sp); - ec->regs.miscRegs.uniq = uniq_val; + ec->setMiscReg(TheISA::Uniq_DepTag, uniq_val); ec->regs.pc = gtoh(attrp->registers.pc); ec->regs.npc = gtoh(attrp->registers.pc) + sizeof(TheISA::MachInst); From 2f7b8ab1ec301eaf0f1a57d3c566c3358780a117 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Mon, 27 Feb 2006 16:27:01 -0500 Subject: [PATCH 122/180] Got rid of the fault_addr function. --HG-- extra : convert_revision : deb54cd82db47abb6d9bac76e072f2a4b1c883b2 --- arch/alpha/ev5.cc | 21 +++------------------ cpu/o3/alpha_cpu_impl.hh | 2 +- 2 files changed, 4 insertions(+), 19 deletions(-) diff --git a/arch/alpha/ev5.cc b/arch/alpha/ev5.cc index 0520de1ed..349c2930f 100644 --- a/arch/alpha/ev5.cc +++ b/arch/alpha/ev5.cc @@ -83,21 +83,6 @@ AlphaISA::initCPU(RegFile *regs, int cpuId) regs->npc = regs->pc + sizeof(MachInst); } -//////////////////////////////////////////////////////////////////////// -// -// alpha exceptions - value equals trap address, update with MD_FAULT_TYPE -// -const Addr -AlphaISA::fault_addr(Fault fault) -{ - //Check for the system wide faults - if(fault == NoFault) return 0x0000; - else if(fault->isMachineCheckFault()) return 0x0401; - else if(fault->isAlignmentFault()) return 0x0301; - //Deal with the alpha specific faults - return ((AlphaFault *)(fault.get()))->vect(); -}; - const int AlphaISA::reg_redir[AlphaISA::NumIntRegs] = { /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, /* 8 */ 1, 1, 1, 1, 1, 1, 1, 0, @@ -200,14 +185,14 @@ ExecContext::ev5_trap(Fault fault) if (fault->isA() || fault->isA() /* || fault == InterruptFault && !inPalMode() */) { - // traps... skip faulting instruction + // traps... skip faulting instruction. ipr[AlphaISA::IPR_EXC_ADDR] += 4; } if (!inPalMode()) AlphaISA::swap_palshadow(®s, true); - regs.pc = ipr[AlphaISA::IPR_PAL_BASE] + AlphaISA::fault_addr(fault); + regs.pc = ipr[AlphaISA::IPR_PAL_BASE] + ((AlphaFault *)(fault.get()))->vect(); regs.npc = regs.pc + sizeof(MachInst); } @@ -232,7 +217,7 @@ AlphaISA::intr_post(RegFile *regs, Fault fault, Addr pc) // jump to expection address (PAL PC bit set here as well...) if (!use_pc) - regs->npc = ipr[IPR_PAL_BASE] + fault_addr(fault); + regs->npc = ipr[IPR_PAL_BASE] + ((AlphaFault *)(fault.get()))->vect(); else regs->npc = ipr[IPR_PAL_BASE] + pc; diff --git a/cpu/o3/alpha_cpu_impl.hh b/cpu/o3/alpha_cpu_impl.hh index c0ec1fb33..db94f8c9a 100644 --- a/cpu/o3/alpha_cpu_impl.hh +++ b/cpu/o3/alpha_cpu_impl.hh @@ -353,7 +353,7 @@ AlphaFullCPU::trap(Fault fault) swapPALShadow(true); this->regFile.setPC( ipr[AlphaISA::IPR_PAL_BASE] + - AlphaISA::fault_addr(fault) ); + ((AlphaFault *)(fault.get()))->vect()); this->regFile.setNextPC(PC + sizeof(MachInst)); } From 36b2d9815e32781aba1f51acb0b89cdd4f3e2da9 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Mon, 27 Feb 2006 16:46:00 -0500 Subject: [PATCH 123/180] Moved the _stat for MachineCheckFault and AlignmentFault into the isa specific classes to prevent instantiation of the generic classes. --HG-- extra : convert_revision : 0378261342df008c2bf6d260295ef21b15f119a8 --- arch/alpha/faults.cc | 2 ++ arch/alpha/faults.hh | 4 ++++ sim/faults.cc | 2 -- sim/faults.hh | 4 ---- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/arch/alpha/faults.cc b/arch/alpha/faults.cc index 5033f9fcd..99365f8d2 100644 --- a/arch/alpha/faults.cc +++ b/arch/alpha/faults.cc @@ -36,8 +36,10 @@ FaultVect AlphaFault::_vect = 0x0000; FaultStat AlphaFault::_stat; FaultVect AlphaMachineCheckFault::_vect = 0x0401; +FaultStat AlphaMachineCheckFault::_stat; FaultVect AlphaAlignmentFault::_vect = 0x0301; +FaultStat AlphaAlignmentFault::_stat; FaultName ResetFault::_name = "reset"; FaultVect ResetFault::_vect = 0x0001; diff --git a/arch/alpha/faults.hh b/arch/alpha/faults.hh index fedbadd4d..f8cb44017 100644 --- a/arch/alpha/faults.hh +++ b/arch/alpha/faults.hh @@ -54,16 +54,20 @@ class AlphaMachineCheckFault : public MachineCheckFault { private: static FaultVect _vect; + static FaultStat _stat; public: FaultVect vect() {return _vect;} + FaultStat & stat() {return _stat;} }; class AlphaAlignmentFault : public AlignmentFault { private: static FaultVect _vect; + static FaultStat _stat; public: FaultVect vect() {return _vect;} + FaultStat & stat() {return _stat;} }; static inline Fault genMachineCheckFault() diff --git a/sim/faults.cc b/sim/faults.cc index 17efaf1c4..78bfc8092 100644 --- a/sim/faults.cc +++ b/sim/faults.cc @@ -29,7 +29,5 @@ #include "sim/faults.hh" FaultName MachineCheckFault::_name = "mchk"; -FaultStat MachineCheckFault::_stat; FaultName AlignmentFault::_name = "unalign"; -FaultStat AlignmentFault::_stat; diff --git a/sim/faults.hh b/sim/faults.hh index e4880f820..d0bf78815 100644 --- a/sim/faults.hh +++ b/sim/faults.hh @@ -71,10 +71,8 @@ class MachineCheckFault : public FaultBase { private: static FaultName _name; - static FaultStat _stat; public: FaultName name() {return _name;} - FaultStat & stat() {return _stat;} bool isMachineCheckFault() {return true;} }; @@ -82,10 +80,8 @@ class AlignmentFault : public FaultBase { private: static FaultName _name; - static FaultStat _stat; public: FaultName name() {return _name;} - FaultStat & stat() {return _stat;} bool isAlignmentFault() {return true;} }; From 6165419d356fb0cdbcb70d22dcd2f32e689eb7db Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Mon, 27 Feb 2006 23:26:13 -0500 Subject: [PATCH 124/180] Changed ev5_trap from a function of the execution context to a function of the fault. The actual function still resides in the execution context. --HG-- extra : convert_revision : 56e33536cdd9079ace03896b85ea3c84b6eb4e57 --- arch/alpha/ev5.cc | 2 +- arch/alpha/faults.cc | 20 ++++++++++++++++++++ arch/alpha/faults.hh | 9 +++++++++ cpu/exec_context.cc | 2 +- cpu/exec_context.hh | 2 +- cpu/simple/cpu.cc | 4 ++-- cpu/simple/cpu.hh | 2 +- sim/faults.hh | 5 +++++ 8 files changed, 40 insertions(+), 6 deletions(-) diff --git a/arch/alpha/ev5.cc b/arch/alpha/ev5.cc index 349c2930f..23546bbe2 100644 --- a/arch/alpha/ev5.cc +++ b/arch/alpha/ev5.cc @@ -166,7 +166,7 @@ AlphaISA::zeroRegisters(CPU *cpu) } void -ExecContext::ev5_trap(Fault fault) +ExecContext::ev5_temp_trap(Fault fault) { DPRINTF(Fault, "Fault %s at PC: %#x\n", fault->name(), regs.pc); cpu->recordEvent(csprintf("Fault %s", fault->name())); diff --git a/arch/alpha/faults.cc b/arch/alpha/faults.cc index 99365f8d2..2eedfedbd 100644 --- a/arch/alpha/faults.cc +++ b/arch/alpha/faults.cc @@ -27,6 +27,7 @@ */ #include "arch/alpha/faults.hh" +#include "cpu/exec_context.hh" namespace AlphaISA { @@ -97,6 +98,25 @@ FaultName IntegerOverflowFault::_name = "intover"; FaultVect IntegerOverflowFault::_vect = 0x0501; FaultStat IntegerOverflowFault::_stat; +#if FULL_SYSTEM + +void AlphaFault::ev5_trap(ExecContext * xc) +{ + xc->ev5_temp_trap(this); +} + +void AlphaMachineCheckFault::ev5_trap(ExecContext * xc) +{ + xc->ev5_temp_trap(this); +} + +void AlphaAlignmentFault::ev5_trap(ExecContext * xc) +{ + xc->ev5_temp_trap(this); +} + +#endif + } // namespace AlphaISA /*Fault * ListOfFaults[] = { diff --git a/arch/alpha/faults.hh b/arch/alpha/faults.hh index f8cb44017..7c52738c1 100644 --- a/arch/alpha/faults.hh +++ b/arch/alpha/faults.hh @@ -45,6 +45,9 @@ class AlphaFault : public FaultBase static FaultVect _vect; static FaultStat _stat; public: +#if FULL_SYSTEM + void ev5_trap(ExecContext * xc); +#endif FaultName name() {return _name;} virtual FaultVect vect() {return _vect;} virtual FaultStat & stat() {return _stat;} @@ -56,6 +59,9 @@ class AlphaMachineCheckFault : public MachineCheckFault static FaultVect _vect; static FaultStat _stat; public: +#if FULL_SYSTEM + void ev5_trap(ExecContext * xc); +#endif FaultVect vect() {return _vect;} FaultStat & stat() {return _stat;} }; @@ -66,6 +72,9 @@ class AlphaAlignmentFault : public AlignmentFault static FaultVect _vect; static FaultStat _stat; public: +#if FULL_SYSTEM + void ev5_trap(ExecContext * xc); +#endif FaultVect vect() {return _vect;} FaultStat & stat() {return _stat;} }; diff --git a/cpu/exec_context.cc b/cpu/exec_context.cc index cf0ced7b0..7e8b81e18 100644 --- a/cpu/exec_context.cc +++ b/cpu/exec_context.cc @@ -227,7 +227,7 @@ ExecContext::trap(Fault fault) /** @todo: Going to hack it for now. Do a true fixup later. */ #if FULL_SYSTEM - ev5_trap(fault); + fault->ev5_trap(this); #else fatal("fault (%d) detected @ PC 0x%08p", fault, readPC()); #endif diff --git a/cpu/exec_context.hh b/cpu/exec_context.hh index 834eacec8..e23370d0b 100644 --- a/cpu/exec_context.hh +++ b/cpu/exec_context.hh @@ -425,7 +425,7 @@ class ExecContext void setIntrFlag(int val) { regs.intrflag = val; } Fault hwrei(); bool inPalMode() { return AlphaISA::PcPAL(regs.pc); } - void ev5_trap(Fault fault); + void ev5_temp_trap(Fault fault); bool simPalCheck(int palFunc); #endif diff --git a/cpu/simple/cpu.cc b/cpu/simple/cpu.cc index 4b0eda386..1f362876f 100644 --- a/cpu/simple/cpu.cc +++ b/cpu/simple/cpu.cc @@ -688,7 +688,7 @@ SimpleCPU::tick() if (ipl && ipl > xc->regs.ipr[IPR_IPLR]) { ipr[IPR_ISR] = summary; ipr[IPR_INTID] = ipl; - xc->ev5_trap(new InterruptFault); + (new InterruptFault)->ev5_trap(xc); DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n", ipr[IPR_IPLR], ipl, summary); @@ -812,7 +812,7 @@ SimpleCPU::tick() if (fault != NoFault) { #if FULL_SYSTEM - xc->ev5_trap(fault); + fault->ev5_trap(xc); #else // !FULL_SYSTEM fatal("fault (%d) detected @ PC 0x%08p", fault, xc->regs.pc); #endif // FULL_SYSTEM diff --git a/cpu/simple/cpu.hh b/cpu/simple/cpu.hh index ed7b1e29b..c58b3c5ba 100644 --- a/cpu/simple/cpu.hh +++ b/cpu/simple/cpu.hh @@ -334,7 +334,7 @@ class SimpleCPU : public BaseCPU int readIntrFlag() { return xc->readIntrFlag(); } void setIntrFlag(int val) { xc->setIntrFlag(val); } bool inPalMode() { return xc->inPalMode(); } - void ev5_trap(Fault fault) { xc->ev5_trap(fault); } + void ev5_trap(Fault fault) { fault->ev5_trap(xc); } bool simPalCheck(int palFunc) { return xc->simPalCheck(palFunc); } #else void syscall() { xc->syscall(); } diff --git a/sim/faults.hh b/sim/faults.hh index d0bf78815..69e592485 100644 --- a/sim/faults.hh +++ b/sim/faults.hh @@ -31,7 +31,9 @@ #include "base/refcnt.hh" #include "sim/stats.hh" +#include "config/full_system.hh" +class ExecContext; class FaultBase; typedef RefCountingPtr Fault; @@ -53,6 +55,9 @@ class FaultBase : public RefCounted return "none"; } virtual FaultStat & stat() = 0; +#if FULL_SYSTEM + virtual void ev5_trap(ExecContext * xc) = 0; +#endif template bool isA() {return dynamic_cast(this);} virtual bool isMachineCheckFault() {return false;} From 299efffaf5eb5fb55b2109a643e1e0e985f89ce6 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 28 Feb 2006 06:02:18 -0500 Subject: [PATCH 125/180] Cleaned up and slightly reorganized the Fault class heirarchy. arch/alpha/ev5.cc: Changed c style casts of Faults to dynamic_casts arch/alpha/faults.cc: AlphaFault is now an abstract class. arch/alpha/faults.hh: AlphaFault is now an abstract class. Also, AlphaMachineCheckFault and AlphaAlignmentFault multiply inherit from both AlphaFault and from MachineCheckFault and AlignmentFault respectively. These classes get their name from the generic classes. cpu/o3/alpha_cpu_impl.hh: Changed a c style cast to a dynamic_cast for a Fault sim/faults.hh: All generic Fault classes are now abstract. Also, MachineCheckFault and AlignmentFault inherit FaultBase as a virtual base class to help resolve ambiguities when they are multiply inherited in ISA specific classes. The override the isMachineCheckFault and isAlignmentFault functions appropriately, and provide a standard name for these faults. --HG-- extra : convert_revision : 2cb906708e3eaec4a12587484c09e50ed6ef88fc --- arch/alpha/ev5.cc | 6 ++++-- arch/alpha/faults.cc | 4 ---- arch/alpha/faults.hh | 18 ++++++++---------- cpu/o3/alpha_cpu_impl.hh | 2 +- sim/faults.hh | 9 +++------ 5 files changed, 16 insertions(+), 23 deletions(-) diff --git a/arch/alpha/ev5.cc b/arch/alpha/ev5.cc index 23546bbe2..ca26fc257 100644 --- a/arch/alpha/ev5.cc +++ b/arch/alpha/ev5.cc @@ -192,7 +192,8 @@ ExecContext::ev5_temp_trap(Fault fault) if (!inPalMode()) AlphaISA::swap_palshadow(®s, true); - regs.pc = ipr[AlphaISA::IPR_PAL_BASE] + ((AlphaFault *)(fault.get()))->vect(); + regs.pc = ipr[AlphaISA::IPR_PAL_BASE] + + (dynamic_cast(fault.get()))->vect(); regs.npc = regs.pc + sizeof(MachInst); } @@ -217,7 +218,8 @@ AlphaISA::intr_post(RegFile *regs, Fault fault, Addr pc) // jump to expection address (PAL PC bit set here as well...) if (!use_pc) - regs->npc = ipr[IPR_PAL_BASE] + ((AlphaFault *)(fault.get()))->vect(); + regs->npc = ipr[IPR_PAL_BASE] + + (dynamic_cast(fault.get()))->vect(); else regs->npc = ipr[IPR_PAL_BASE] + pc; diff --git a/arch/alpha/faults.cc b/arch/alpha/faults.cc index 2eedfedbd..78613761d 100644 --- a/arch/alpha/faults.cc +++ b/arch/alpha/faults.cc @@ -32,10 +32,6 @@ namespace AlphaISA { -FaultName AlphaFault::_name = "alphafault"; -FaultVect AlphaFault::_vect = 0x0000; -FaultStat AlphaFault::_stat; - FaultVect AlphaMachineCheckFault::_vect = 0x0401; FaultStat AlphaMachineCheckFault::_stat; diff --git a/arch/alpha/faults.hh b/arch/alpha/faults.hh index 7c52738c1..156faa8fb 100644 --- a/arch/alpha/faults.hh +++ b/arch/alpha/faults.hh @@ -38,22 +38,18 @@ namespace AlphaISA typedef const Addr FaultVect; -class AlphaFault : public FaultBase +class AlphaFault : public virtual FaultBase { - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _stat; public: #if FULL_SYSTEM void ev5_trap(ExecContext * xc); #endif - FaultName name() {return _name;} - virtual FaultVect vect() {return _vect;} - virtual FaultStat & stat() {return _stat;} + virtual FaultVect vect() = 0; }; -class AlphaMachineCheckFault : public MachineCheckFault +class AlphaMachineCheckFault : + public MachineCheckFault, + public AlphaFault { private: static FaultVect _vect; @@ -66,7 +62,9 @@ class AlphaMachineCheckFault : public MachineCheckFault FaultStat & stat() {return _stat;} }; -class AlphaAlignmentFault : public AlignmentFault +class AlphaAlignmentFault : + public AlignmentFault, + public AlphaFault { private: static FaultVect _vect; diff --git a/cpu/o3/alpha_cpu_impl.hh b/cpu/o3/alpha_cpu_impl.hh index db94f8c9a..9b7cd8a0e 100644 --- a/cpu/o3/alpha_cpu_impl.hh +++ b/cpu/o3/alpha_cpu_impl.hh @@ -353,7 +353,7 @@ AlphaFullCPU::trap(Fault fault) swapPALShadow(true); this->regFile.setPC( ipr[AlphaISA::IPR_PAL_BASE] + - ((AlphaFault *)(fault.get()))->vect()); + (dynamic_cast(fault.get()))->vect()); this->regFile.setNextPC(PC + sizeof(MachInst)); } diff --git a/sim/faults.hh b/sim/faults.hh index 69e592485..9b8c94cda 100644 --- a/sim/faults.hh +++ b/sim/faults.hh @@ -50,10 +50,7 @@ typedef Stats::Scalar<> FaultStat; class FaultBase : public RefCounted { public: - virtual FaultName name() - { - return "none"; - } + virtual FaultName name() = 0; virtual FaultStat & stat() = 0; #if FULL_SYSTEM virtual void ev5_trap(ExecContext * xc) = 0; @@ -72,7 +69,7 @@ FaultBase * const NoFault = 0; //provide the name() function, and the isMachineCheckFault and isAlignmentFault //functions are provided below. -class MachineCheckFault : public FaultBase +class MachineCheckFault : public virtual FaultBase { private: static FaultName _name; @@ -81,7 +78,7 @@ class MachineCheckFault : public FaultBase bool isMachineCheckFault() {return true;} }; -class AlignmentFault : public FaultBase +class AlignmentFault : public virtual FaultBase { private: static FaultName _name; From 8e6b8cb212ba79978056b57dd60c60a39f6428e9 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 28 Feb 2006 06:17:57 -0500 Subject: [PATCH 126/180] Hand merged --HG-- extra : convert_revision : 0fd5ecbba5dc6299dd046926ec27595ca4d97ee7 --- dev/sinic.cc | 21 +++++---------------- 1 file changed, 5 insertions(+), 16 deletions(-) diff --git a/dev/sinic.cc b/dev/sinic.cc index c28ab335b..1c0e59e0a 100644 --- a/dev/sinic.cc +++ b/dev/sinic.cc @@ -494,30 +494,17 @@ Device::writeBar0(MemReqPtr &req, Addr daddr, const uint8_t *data) //this prevents compilation. //uint32_t reg32 = *(uint32_t *)data; //uint64_t reg64 = *(uint64_t *)data; + VirtualReg &vnic = virtualRegs[index]; + DPRINTF(EthernetPIO, "write %s: cpu=%d val=%#x da=%#x pa=%#x va=%#x size=%d\n", info.name, cpu, info.size == 4 ? (*(uint32_t *)data) : - (*(uint32_t *)data), + (*(uint64_t *)data), daddr, req->paddr, req->vaddr, req->size); prepareWrite(cpu, index); - regWrite(daddr, cpu, data); - - return NoFault; -} - -void -Device::regWrite(Addr daddr, int cpu, const uint8_t *data) -{ - Addr index = daddr >> Regs::VirtualShift; - Addr raddr = daddr & Regs::VirtualMask; - - uint32_t reg32 = *(uint32_t *)data; - uint64_t reg64 = *(uint64_t *)data; - VirtualReg &vnic = virtualRegs[index]; - switch (raddr) { case Regs::Config: changeConfig(reg32); @@ -564,6 +551,8 @@ Device::regWrite(Addr daddr, int cpu, const uint8_t *data) } break; } + + return NoFault; } void From 3a362d04b7aed0fa728af9373bad175a096a7de8 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 28 Feb 2006 06:28:09 -0500 Subject: [PATCH 127/180] Corrected some mistakes in the hand merge --HG-- extra : convert_revision : 84d852e625f754c4414403e8c3e26bda80500d4f --- dev/sinic.cc | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/dev/sinic.cc b/dev/sinic.cc index 1c0e59e0a..31d651249 100644 --- a/dev/sinic.cc +++ b/dev/sinic.cc @@ -489,18 +489,13 @@ Device::writeBar0(MemReqPtr &req, Addr daddr, const uint8_t *data) panic("invalid size for %s: cpu=%d da=%#x pa=%#x va=%#x size=%d", info.name, cpu, daddr, req->paddr, req->vaddr, req->size); - //These are commmented out because when the DPRINTF below isn't used, - //these values aren't used and gcc issues a warning. With -Werror, - //this prevents compilation. - //uint32_t reg32 = *(uint32_t *)data; - //uint64_t reg64 = *(uint64_t *)data; + uint32_t reg32 = *(uint32_t *)data; + uint64_t reg64 = *(uint64_t *)data; VirtualReg &vnic = virtualRegs[index]; DPRINTF(EthernetPIO, "write %s: cpu=%d val=%#x da=%#x pa=%#x va=%#x size=%d\n", - info.name, cpu, info.size == 4 ? - (*(uint32_t *)data) : - (*(uint64_t *)data), + info.name, cpu, info.size == 4 ? reg32 : reg64, daddr, req->paddr, req->vaddr, req->size); prepareWrite(cpu, index); From 26d7b5a4d1ee06ce314093facdbef6389ee1ec55 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Tue, 28 Feb 2006 18:41:04 -0500 Subject: [PATCH 128/180] Add quiesceNs, quiesceTime, quiesceCycles, and m5panic pseudo ops. This changeset removes a check that prevents quiescing when an interrupt is pending. *** You should only call quiesce if that isn't a problem. *** arch/alpha/isa/decoder.isa: sim/pseudo_inst.cc: sim/pseudo_inst.hh: Add quiesceNs, quiesceCycles, quisceTime and m5panic pseudo ops. These quiesce for a number of ns, cycles, report how long we were quiesced for, and panic the simulator respectively. The latter is added to the panic() function in the console and linux kernel instead of executing an infinite loop until someone notices. cpu/exec_context.cc: cpu/exec_context.hh: Add a quiesce end event to the execution contexted which upon executing wakes up a CPU for quiesceCycles/quiesceNs. util/m5/Makefile: Make the makefile more reasonable util/m5/m5.c: update the m5op executable to use the files from the linux tree util/m5/m5op.S: update m5op.S from linux tree util/m5/m5op.h: update m5op.h from linux tree --HG-- rename : util/m5/m5op.s => util/m5/m5op.S extra : convert_revision : 3be18525e811405b112e33f24a8c4e772d15462d --- arch/alpha/isa/decoder.isa | 14 ++- cpu/exec_context.cc | 47 +++++++-- cpu/exec_context.hh | 22 ++++- sim/pseudo_inst.cc | 38 ++++++- sim/pseudo_inst.hh | 5 +- util/m5/Makefile | 64 ++++++++---- util/m5/m5.c | 18 ++-- util/m5/m5op.S | 196 +++++++++++++++++++++++++++++++++++++ util/m5/m5op.h | 31 +++--- util/m5/m5op.s | 121 ----------------------- 10 files changed, 384 insertions(+), 172 deletions(-) create mode 100644 util/m5/m5op.S delete mode 100644 util/m5/m5op.s diff --git a/arch/alpha/isa/decoder.isa b/arch/alpha/isa/decoder.isa index 37b15416b..b93b6575c 100644 --- a/arch/alpha/isa/decoder.isa +++ b/arch/alpha/isa/decoder.isa @@ -1,6 +1,6 @@ // -*- mode:c++ -*- -// Copyright (c) 2003-2005 The Regents of The University of Michigan +// Copyright (c) 2003-2006 The Regents of The University of Michigan // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -758,6 +758,15 @@ decode OPCODE default Unknown::unknown() { 0x01: quiesce({{ AlphaPseudo::quiesce(xc->xcBase()); }}, IsNonSpeculative); + 0x02: quiesceNs({{ + AlphaPseudo::quiesceNs(xc->xcBase(), R16); + }}, IsNonSpeculative); + 0x03: quiesceCycles({{ + AlphaPseudo::quiesceCycles(xc->xcBase(), R16); + }}, IsNonSpeculative); + 0x04: quiesceTime({{ + R0 = AlphaPseudo::quiesceTime(xc->xcBase()); + }}, IsNonSpeculative); 0x10: ivlb({{ AlphaPseudo::ivlb(xc->xcBase()); }}, No_OpClass, IsNonSpeculative); @@ -795,6 +804,9 @@ decode OPCODE default Unknown::unknown() { 0x53: m5addsymbol({{ AlphaPseudo::addsymbol(xc->xcBase(), R16, R17); }}, IsNonSpeculative); + 0x54: m5panic({{ + panic("M5 panic instruction called."); + }}, IsNonSpeculative); } } diff --git a/cpu/exec_context.cc b/cpu/exec_context.cc index 9bed3ba47..4ff3e0952 100644 --- a/cpu/exec_context.cc +++ b/cpu/exec_context.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001-2005 The Regents of The University of Michigan + * Copyright (c) 2001-2006 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -35,6 +35,7 @@ #include "base/callback.hh" #include "base/cprintf.hh" #include "base/output.hh" +#include "base/trace.hh" #include "cpu/profile.hh" #include "kern/kernel_stats.hh" #include "sim/serialize.hh" @@ -53,10 +54,10 @@ ExecContext::ExecContext(BaseCPU *_cpu, int _thread_num, System *_sys, AlphaITB *_itb, AlphaDTB *_dtb, FunctionalMemory *_mem) : _status(ExecContext::Unallocated), cpu(_cpu), thread_num(_thread_num), - cpu_id(-1), mem(_mem), itb(_itb), dtb(_dtb), system(_sys), - memctrl(_sys->memctrl), physmem(_sys->physmem), + cpu_id(-1), lastActivate(0), lastSuspend(0), mem(_mem), itb(_itb), + dtb(_dtb), system(_sys), memctrl(_sys->memctrl), physmem(_sys->physmem), kernelBinning(system->kernelBinning), bin(kernelBinning->bin), - fnbin(kernelBinning->fnbin), profile(NULL), + fnbin(kernelBinning->fnbin), profile(NULL), quiesceEvent(this), func_exe_inst(0), storeCondFailures(0) { kernelStats = new Kernel::Statistics(this); @@ -79,8 +80,8 @@ ExecContext::ExecContext(BaseCPU *_cpu, int _thread_num, System *_sys, ExecContext::ExecContext(BaseCPU *_cpu, int _thread_num, Process *_process, int _asid) : _status(ExecContext::Unallocated), - cpu(_cpu), thread_num(_thread_num), cpu_id(-1), - process(_process), mem(process->getMemory()), asid(_asid), + cpu(_cpu), thread_num(_thread_num), cpu_id(-1), lastActivate(0), + lastSuspend(0), process(_process), mem(process->getMemory()), asid(_asid), func_exe_inst(0), storeCondFailures(0) { memset(®s, 0, sizeof(RegFile)); @@ -109,6 +110,23 @@ ExecContext::dumpFuncProfile() std::ostream *os = simout.create(csprintf("profile.%s.dat", cpu->name())); profile->dump(this, *os); } + +ExecContext::EndQuiesceEvent::EndQuiesceEvent(ExecContext *_xc) + : Event(&mainEventQueue), xc(_xc) +{ +} + +void +ExecContext::EndQuiesceEvent::process() +{ + xc->activate(); +} + +const char* +ExecContext::EndQuiesceEvent::description() +{ + return "End Quiesce Event."; +} #endif void @@ -143,7 +161,12 @@ ExecContext::serialize(ostream &os) SERIALIZE_SCALAR(inst); #if FULL_SYSTEM + Tick quiesceEndTick = 0; + if (quiesceEvent.scheduled()) + quiesceEndTick = quiesceEvent.when(); + SERIALIZE_SCALAR(quiesceEndTick); kernelStats->serialize(os); + #endif } @@ -158,6 +181,11 @@ ExecContext::unserialize(Checkpoint *cp, const std::string §ion) UNSERIALIZE_SCALAR(inst); #if FULL_SYSTEM + Tick quiesceEndTick; + UNSERIALIZE_SCALAR(quiesceEndTick); + if (quiesceEndTick) + quiesceEvent.schedule(quiesceEndTick); + kernelStats->unserialize(cp, section); #endif } @@ -169,6 +197,8 @@ ExecContext::activate(int delay) if (status() == Active) return; + lastActivate = curTick; + _status = Active; cpu->activateContext(thread_num, delay); } @@ -179,6 +209,9 @@ ExecContext::suspend() if (status() == Suspended) return; + lastActivate = curTick; + lastSuspend = curTick; +/* #if FULL_SYSTEM // Don't change the status from active if there are pending interrupts if (cpu->check_interrupts()) { @@ -186,7 +219,7 @@ ExecContext::suspend() return; } #endif - +*/ _status = Suspended; cpu->suspendContext(thread_num); } diff --git a/cpu/exec_context.hh b/cpu/exec_context.hh index 3e0d77254..ce7fe3467 100644 --- a/cpu/exec_context.hh +++ b/cpu/exec_context.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001-2005 The Regents of The University of Michigan + * Copyright (c) 2001-2006 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -32,6 +32,7 @@ #include "config/full_system.hh" #include "mem/functional/functional.hh" #include "mem/mem_req.hh" +#include "sim/eventq.hh" #include "sim/host.hh" #include "sim/serialize.hh" #include "arch/isa_traits.hh" @@ -131,6 +132,9 @@ class ExecContext // it belongs. For full-system mode, this is the system CPU ID. int cpu_id; + Tick lastActivate; + Tick lastSuspend; + #if FULL_SYSTEM FunctionalMemory *mem; AlphaITB *itb; @@ -153,6 +157,22 @@ class ExecContext Addr profilePC; void dumpFuncProfile(); + /** Event for timing out quiesce instruction */ + struct EndQuiesceEvent : public Event + { + /** A pointer to the execution context that is quiesced */ + ExecContext *xc; + + EndQuiesceEvent(ExecContext *_xc); + + /** Event process to occur at interrupt*/ + virtual void process(); + + /** Event description */ + virtual const char *description(); + }; + EndQuiesceEvent quiesceEvent; + #else Process *process; diff --git a/sim/pseudo_inst.cc b/sim/pseudo_inst.cc index 58ea8266f..fbfce64d9 100644 --- a/sim/pseudo_inst.cc +++ b/sim/pseudo_inst.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2005 The Regents of The University of Michigan + * Copyright (c) 2003-2006 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -77,6 +77,42 @@ namespace AlphaPseudo xc->kernelStats->quiesce(); } + void + quiesceNs(ExecContext *xc, uint64_t ns) + { + if (!doQuiesce || ns == 0) + return; + + if (xc->quiesceEvent.scheduled()) + xc->quiesceEvent.reschedule(curTick + Clock::Int::ns * ns); + else + xc->quiesceEvent.schedule(curTick + Clock::Int::ns * ns); + + xc->suspend(); + xc->kernelStats->quiesce(); + } + + void + quiesceCycles(ExecContext *xc, uint64_t cycles) + { + if (!doQuiesce || cycles == 0) + return; + + if (xc->quiesceEvent.scheduled()) + xc->quiesceEvent.reschedule(curTick + xc->cpu->cycles(cycles)); + else + xc->quiesceEvent.schedule(curTick + xc->cpu->cycles(cycles)); + + xc->suspend(); + xc->kernelStats->quiesce(); + } + + uint64_t + quiesceTime(ExecContext *xc) + { + return (xc->lastActivate - xc->lastSuspend) / Clock::Int::ns ; + } + void ivlb(ExecContext *xc) { diff --git a/sim/pseudo_inst.hh b/sim/pseudo_inst.hh index 3857f2050..4dd427c99 100644 --- a/sim/pseudo_inst.hh +++ b/sim/pseudo_inst.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2005 The Regents of The University of Michigan + * Copyright (c) 2003-2006 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -44,6 +44,9 @@ namespace AlphaPseudo void arm(ExecContext *xc); void quiesce(ExecContext *xc); + void quiesceNs(ExecContext *xc, uint64_t ns); + void quiesceCycles(ExecContext *xc, uint64_t cycles); + uint64_t quiesceTime(ExecContext *xc); void ivlb(ExecContext *xc); void ivle(ExecContext *xc); void m5exit(ExecContext *xc, Tick delay); diff --git a/util/m5/Makefile b/util/m5/Makefile index 6e4ad31a3..518542322 100644 --- a/util/m5/Makefile +++ b/util/m5/Makefile @@ -1,26 +1,50 @@ -AS=as -CC=cc -LD=cc +# Copyright (c) 2005-2006 The Regents of The University of Michigan +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -CCFLAGS=-O2 -#LDFLAGS=-non_shared +### If we are not compiling on an alpha, we must use cross tools ### +ifneq ($(shell uname -m), alpha) +CROSS_COMPILE?=alpha-unknown-linux-gnu- +endif +CC=$(CROSS_COMPILE)gcc +AS=$(CROSS_COMPILE)as +LD=$(CROSS_COMPILE)ld + +CFLAGS=-O2 +OBJS=m5.o m5op.o all: m5 -m5: m5op.o m5.o - $(LD) $(LDFLAGS) -o $@ $> - strip $@ +%.o: %.S + $(CC) $(CFLAGS) -o $@ -c $< + +%.o: %.c + $(CC) $(CFLAGS) -o $@ -c $< + +m5: $(OBJS) + $(CC) -o $@ $(OBJS) clean: - @rm -f m5 *.o *.d *~ .#* - -.SUFFIXES: -.SUFFIXES:.o .c .s - -# C Compilation -.c.o: - $(CC) $(CCFLAGS) -o $@ -c $< - -# Assembly -.s.o: - $(AS) $(ASFLAGS) -o $@ $< + rm -f *.o m5 diff --git a/util/m5/m5.c b/util/m5/m5.c index 942ad5ba4..6fdbc0500 100644 --- a/util/m5/m5.c +++ b/util/m5/m5.c @@ -73,7 +73,7 @@ main(int argc, char *argv[]) usage(); arg1 = strtoul(argv[2], NULL, 0); - ivlb(arg1); + m5_ivlb(arg1); return 0; } @@ -82,7 +82,7 @@ main(int argc, char *argv[]) usage(); arg1 = strtoul(argv[2], NULL, 0); - ivle(arg1); + m5_ivle(arg1); return 0; } @@ -90,7 +90,7 @@ main(int argc, char *argv[]) if (argc != 2) usage(); - printf("%ld", initparam()); + printf("%ld", m5_initparam()); return 0; } @@ -98,7 +98,7 @@ main(int argc, char *argv[]) if (argc != 2) usage(); - param = initparam(); + param = m5_initparam(); // run-time, rampup-time, rampdown-time, warmup-time, connections printf("%d %d %d %d %d", (param >> 48) & 0xfff, (param >> 36) & 0xfff, (param >> 24) & 0xfff, @@ -112,7 +112,7 @@ main(int argc, char *argv[]) case 3: arg1 = strtoul(argv[2], NULL, 0); case 2: - m5exit(arg1); + m5_exit(arg1); return 0; default: @@ -127,7 +127,7 @@ main(int argc, char *argv[]) case 3: arg1 = strtoul(argv[2], NULL, 0); case 2: - reset_stats(arg1, arg2); + m5_reset_stats(arg1, arg2); return 0; default: @@ -142,7 +142,7 @@ main(int argc, char *argv[]) case 3: arg1 = strtoul(argv[2], NULL, 0); case 2: - dump_stats(arg1, arg2); + m5_dump_stats(arg1, arg2); return 0; default: @@ -157,7 +157,7 @@ main(int argc, char *argv[]) case 3: arg1 = strtoul(argv[2], NULL, 0); case 2: - dumpreset_stats(arg1, arg2); + m5_dumpreset_stats(arg1, arg2); return 0; default: @@ -172,7 +172,7 @@ main(int argc, char *argv[]) case 3: arg1 = strtoul(argv[2], NULL, 0); case 2: - checkpoint(arg1, arg2); + m5_checkpoint(arg1, arg2); return 0; default: diff --git a/util/m5/m5op.S b/util/m5/m5op.S new file mode 100644 index 000000000..a53c45277 --- /dev/null +++ b/util/m5/m5op.S @@ -0,0 +1,196 @@ +/* + * Copyright (c) 2003-2006 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#define m5_op 0x01 + +#define arm_func 0x00 +#define quiesce_func 0x01 +#define quiescens_func 0x02 +#define quiescecycle_func 0x03 +#define quiescetime_func 0x04 +#define ivlb_func 0x10 +#define ivle_func 0x11 +#define exit_old_func 0x20 // deprectated! +#define exit_func 0x21 +#define initparam_func 0x30 +#define resetstats_func 0x40 +#define dumpstats_func 0x41 +#define dumprststats_func 0x42 +#define ckpt_func 0x43 +#define readfile_func 0x50 +#define debugbreak_func 0x51 +#define switchcpu_func 0x52 +#define addsymbol_func 0x53 +#define panic_func 0x54 + +#define INST(op, ra, rb, func) \ + .long (((op) << 26) | ((ra) << 21) | ((rb) << 16) | (func)) + +#define LEAF(func) \ + .align 3; \ + .globl func; \ + .ent func; \ +func: + +#define RET \ + ret ($26) + +#define END(func) \ + .end func + +#define ARM(reg) INST(m5_op, reg, 0, arm_func) +#define QUIESCE INST(m5_op, 0, 0, quiesce_func) +#define QUIESCENS(r1) INST(m5_op, r1, 0, quiescens_func) +#define QUIESCECYC(r1) INST(m5_op, r1, 0, quiescecycle_func) +#define QUIESCETIME INST(m5_op, 0, 0, quiescetime_func) +#define IVLB(reg) INST(m5_op, reg, 0, ivlb_func) +#define IVLE(reg) INST(m5_op, reg, 0, ivle_func) +#define M5EXIT(reg) INST(m5_op, reg, 0, exit_func) +#define INITPARAM(reg) INST(m5_op, reg, 0, initparam_func) +#define RESET_STATS(r1, r2) INST(m5_op, r1, r2, resetstats_func) +#define DUMP_STATS(r1, r2) INST(m5_op, r1, r2, dumpstats_func) +#define DUMPRST_STATS(r1, r2) INST(m5_op, r1, r2, dumprststats_func) +#define CHECKPOINT(r1, r2) INST(m5_op, r1, r2, ckpt_func) +#define READFILE INST(m5_op, 0, 0, readfile_func) +#define DEBUGBREAK INST(m5_op, 0, 0, debugbreak_func) +#define SWITCHCPU INST(m5_op, 0, 0, switchcpu_func) +#define ADDSYMBOL(r1,r2) INST(m5_op, r1, r2, addsymbol_func) +#define PANIC INST(m5_op, 0, 0, panic_func) + + .set noreorder + + .align 4 +LEAF(arm) + ARM(16) + RET +END(arm) + + .align 4 +LEAF(quiesce) + QUIESCE + RET +END(quiesce) + + .align 4 +LEAF(quiesceNs) + QUIESCENS(16) + RET +END(quiesceNs) + + .align 4 +LEAF(quiesceCycle) + QUIESCECYC(16) + RET +END(quiesceCycle) + + .align 4 +LEAF(quiesceTime) + QUIESCETIME + RET +END(quiesceTime) + + + .align 4 +LEAF(m5_ivlb) + IVLB(16) + RET +END(m5_ivlb) + + .align 4 +LEAF(m5_ivle) + IVLE(16) + RET +END(m5_ivle) + + .align 4 +LEAF(m5_exit) + M5EXIT(16) + RET +END(m5_exit) + + .align 4 +LEAF(m5_initparam) + INITPARAM(0) + RET +END(m5_initparam) + + .align 4 +LEAF(m5_reset_stats) + RESET_STATS(16, 17) + RET +END(m5_reset_stats) + + .align 4 +LEAF(m5_dump_stats) + DUMP_STATS(16, 17) + RET +END(m5_dump_stats) + + .align 4 +LEAF(m5_dumpreset_stats) + DUMPRST_STATS(16, 17) + RET +END(m5_dumpreset_stats) + + .align 4 +LEAF(m5_checkpoint) + CHECKPOINT(16, 17) + RET +END(m5_checkpoint) + + .align 4 +LEAF(m5_readfile) + READFILE + RET +END(m5_readfile) + + .align 4 +LEAF(m5_debugbreak) + DEBUGBREAK + RET +END(m5_debugbreak) + + .align 4 +LEAF(m5_switchcpu) + SWITCHCPU + RET +END(m5_switchcpu) + + .align 4 +LEAF(m5_addsymbol) + ADDSYMBOL(16, 17) + RET +END(m5_addsymbol) + + .align 4 +LEAF(m5_panic) + PANIC + RET +END(m5_panic) + + diff --git a/util/m5/m5op.h b/util/m5/m5op.h index 91dc4cc8b..34ac7760d 100644 --- a/util/m5/m5op.h +++ b/util/m5/m5op.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2005 The Regents of The University of Michigan + * Copyright (c) 2003-2006 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -29,17 +29,26 @@ #ifndef __M5OP_H__ #define __M5OP_H__ -#include +#include void arm(uint64_t address); -void quiesce(); -void ivlb(uint64_t interval); -void ivle(uint64_t interval); -void m5exit(uint64_t ns_delay); -uint64_t initparam(); -void checkpoint(uint64_t ns_delay, uint64_t ns_period); -void reset_stats(uint64_t ns_delay, uint64_t ns_period); -void dump_stats(uint64_t ns_delay, uint64_t ns_period); -void dumpreset_stats(uint64_t ns_delay, uint64_t ns_period); +void quiesce(void); +void quiesceNs(uint64_t ns); +void quiesceCycle(uint64_t cycles); +uint64_t quiesceTime(void); + +void m5_ivlb(uint64_t interval); +void m5_ivle(uint64_t interval); +void m5_exit(uint64_t ns_delay); +uint64_t m5_initparam(void); +void m5_checkpoint(uint64_t ns_delay, uint64_t ns_period); +void m5_reset_stats(uint64_t ns_delay, uint64_t ns_period); +void m5_dump_stats(uint64_t ns_delay, uint64_t ns_period); +void m5_dumpreset_stats(uint64_t ns_delay, uint64_t ns_period); +uint64_t m5_readfile(void *buffer, uint64_t len, uint64_t offset); +void m5_debugbreak(void); +void m5_switchcpu(void); +void m5_addsymbol(uint64_t addr, char *symbol); +void m5_panic(void); #endif // __M5OP_H__ diff --git a/util/m5/m5op.s b/util/m5/m5op.s deleted file mode 100644 index e779e4209..000000000 --- a/util/m5/m5op.s +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (c) 2003, 2005 The Regents of The University of Michigan - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include - -#define m5_op 0x01 - -#define arm_func 0x00 -#define quiesce_func 0x01 -#define ivlb_func 0x10 -#define ivle_func 0x11 -#define exit_old_func 0x20 // deprectated! -#define exit_func 0x21 -#define initparam_func 0x30 -#define resetstats_func 0x40 -#define dumpstats_func 0x41 -#define dumprststats_func 0x42 -#define ckpt_func 0x43 - -#define INST(op, ra, rb, func) \ - .long (((op) << 26) | ((ra) << 21) | ((rb) << 16) | (func)) - -#define ARM(reg) INST(m5_op, reg, 0, arm_func) -#define QUIESCE() INST(m5_op, 0, 0, quiesce_func) -#define IVLB(reg) INST(m5_op, reg, 0, ivlb_func) -#define IVLE(reg) INST(m5_op, reg, 0, ivle_func) -#define M5EXIT(reg) INST(m5_op, reg, 0, exit_func) -#define INITPARAM(reg) INST(m5_op, reg, 0, initparam_func) -#define RESET_STATS(r1, r2) INST(m5_op, r1, r2, resetstats_func) -#define DUMP_STATS(r1, r2) INST(m5_op, r1, r2, dumpstats_func) -#define DUMPRST_STATS(r1, r2) INST(m5_op, r1, r2, dumprststats_func) -#define CHECKPOINT(r1, r2) INST(m5_op, r1, r2, ckpt_func) - - .set noreorder - - .align 4 -LEAF(arm) - ARM(16) - RET -END(arm) - - .align 4 -LEAF(quiesce) - QUIESCE() - RET -END(quiesce) - - .align 4 -LEAF(ivlb) - IVLB(16) - RET -END(ivlb) - - .align 4 -LEAF(ivle) - IVLE(16) - RET -END(ivle) - - .align 4 -LEAF(m5exit) - M5EXIT(16) - RET -END(m5exit) - - .align 4 -LEAF(initparam) - INITPARAM(0) - RET -END(initparam) - - .align 4 -LEAF(reset_stats) - RESET_STATS(16, 17) - RET -END(reset_stats) - - .align 4 -LEAF(dump_stats) - DUMP_STATS(16, 17) - RET -END(dump_stats) - - .align 4 -LEAF(dumpreset_stats) - DUMPRST_STATS(16, 17) - RET -END(dumpreset_stats) - - .align 4 -LEAF(checkpoint) - CHECKPOINT(16, 17) - RET -END(checkpoint) - From 69e91d761765b84429dc069b8fa1cd3f25925688 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 1 Mar 2006 00:09:08 -0500 Subject: [PATCH 129/180] moved ev5_trap fully into the fault class. --HG-- extra : convert_revision : 182cdec9a4e05f55edff0c6a114844b9ad2ca8db --- arch/alpha/ev5.cc | 32 -------------------------------- arch/alpha/faults.cc | 34 +++++++++++++++++++++++++--------- arch/alpha/faults.hh | 6 ------ cpu/o3/alpha_cpu_impl.hh | 9 +++++---- 4 files changed, 30 insertions(+), 51 deletions(-) diff --git a/arch/alpha/ev5.cc b/arch/alpha/ev5.cc index 2bb005eb4..ac0e7e67e 100644 --- a/arch/alpha/ev5.cc +++ b/arch/alpha/ev5.cc @@ -163,38 +163,6 @@ AlphaISA::zeroRegisters(CPU *cpu) cpu->xc->setFloatRegDouble(ZeroReg, 0.0); } -void -ExecContext::ev5_temp_trap(Fault fault) -{ - DPRINTF(Fault, "Fault %s at PC: %#x\n", fault->name(), regs.pc); - cpu->recordEvent(csprintf("Fault %s", fault->name())); - - assert(!misspeculating()); - kernelStats->fault(fault); - - if (fault->isA()) - panic("Arithmetic traps are unimplemented!"); - - // exception restart address - if (!fault->isA() || !inPalMode()) - setMiscReg(AlphaISA::IPR_EXC_ADDR, regs.pc); - - if (fault->isA() || fault->isA() /* || - fault == InterruptFault && !inPalMode() */) { - // traps... skip faulting instruction. - setMiscReg(AlphaISA::IPR_EXC_ADDR, - readMiscReg(AlphaISA::IPR_EXC_ADDR) + 4); - } - - if (!inPalMode()) - AlphaISA::swap_palshadow(®s, true); - - regs.pc = readMiscReg(AlphaISA::IPR_PAL_BASE) + - (dynamic_cast(fault.get()))->vect(); - regs.npc = regs.pc + sizeof(MachInst); -} - - void AlphaISA::intr_post(RegFile *regs, Fault fault, Addr pc) { diff --git a/arch/alpha/faults.cc b/arch/alpha/faults.cc index 78613761d..8c7dc3194 100644 --- a/arch/alpha/faults.cc +++ b/arch/alpha/faults.cc @@ -28,6 +28,9 @@ #include "arch/alpha/faults.hh" #include "cpu/exec_context.hh" +#include "cpu/base.hh" +#include "base/trace.hh" +#include "kern/kernel_stats.hh" namespace AlphaISA { @@ -98,17 +101,30 @@ FaultStat IntegerOverflowFault::_stat; void AlphaFault::ev5_trap(ExecContext * xc) { - xc->ev5_temp_trap(this); -} + DPRINTF(Fault, "Fault %s at PC: %#x\n", name(), xc->regs.pc); + xc->cpu->recordEvent(csprintf("Fault %s", name())); -void AlphaMachineCheckFault::ev5_trap(ExecContext * xc) -{ - xc->ev5_temp_trap(this); -} + assert(!xc->misspeculating()); + xc->kernelStats->fault(this); -void AlphaAlignmentFault::ev5_trap(ExecContext * xc) -{ - xc->ev5_temp_trap(this); + if (isA()) + panic("Arithmetic traps are unimplemented!"); + + // exception restart address + if (!isA() || !xc->inPalMode()) + xc->setMiscReg(AlphaISA::IPR_EXC_ADDR, xc->regs.pc); + + if (isA() || isA()) { + // traps... skip faulting instruction. + xc->setMiscReg(AlphaISA::IPR_EXC_ADDR, + xc->readMiscReg(AlphaISA::IPR_EXC_ADDR) + 4); + } + + if (!xc->inPalMode()) + AlphaISA::swap_palshadow(&(xc->regs), true); + + xc->regs.pc = xc->readMiscReg(AlphaISA::IPR_PAL_BASE) + vect(); + xc->regs.npc = xc->regs.pc + sizeof(MachInst); } #endif diff --git a/arch/alpha/faults.hh b/arch/alpha/faults.hh index 156faa8fb..829edd490 100644 --- a/arch/alpha/faults.hh +++ b/arch/alpha/faults.hh @@ -55,9 +55,6 @@ class AlphaMachineCheckFault : static FaultVect _vect; static FaultStat _stat; public: -#if FULL_SYSTEM - void ev5_trap(ExecContext * xc); -#endif FaultVect vect() {return _vect;} FaultStat & stat() {return _stat;} }; @@ -70,9 +67,6 @@ class AlphaAlignmentFault : static FaultVect _vect; static FaultStat _stat; public: -#if FULL_SYSTEM - void ev5_trap(ExecContext * xc); -#endif FaultVect vect() {return _vect;} FaultStat & stat() {return _stat;} }; diff --git a/cpu/o3/alpha_cpu_impl.hh b/cpu/o3/alpha_cpu_impl.hh index daa61bb1c..a1c659b51 100644 --- a/cpu/o3/alpha_cpu_impl.hh +++ b/cpu/o3/alpha_cpu_impl.hh @@ -302,7 +302,7 @@ template void AlphaFullCPU::trap(Fault fault) { - // Keep in mind that a trap may be initiated by fetch if there's a TLB +/* // Keep in mind that a trap may be initiated by fetch if there's a TLB // miss uint64_t PC = this->commit.readCommitPC(); @@ -318,8 +318,9 @@ AlphaFullCPU::trap(Fault fault) if (!fault->isA() || !inPalMode(PC)) this->regFile.miscRegs.setReg(AlphaISA::IPR_EXC_ADDR, PC); - if (fault->isA() || fault->isA() /* || - fault == InterruptFault && !PC_PAL(regs.pc) */) { + if (fault->isA() || fault->isA()) + // || fault == InterruptFault && !PC_PAL(regs.pc) + { // traps... skip faulting instruction AlphaISA::MiscReg ipr_exc_addr = this->regFile.miscRegs.readReg(AlphaISA::IPR_EXC_ADDR); @@ -332,7 +333,7 @@ AlphaFullCPU::trap(Fault fault) this->regFile.setPC(this->regFile.miscRegs.readReg(AlphaISA::IPR_PAL_BASE) + (dynamic_cast(fault.get()))->vect()); - this->regFile.setNextPC(PC + sizeof(MachInst)); + this->regFile.setNextPC(PC + sizeof(MachInst));*/ } template From d6c06571169603a37321af07b4d012f05806ad26 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 1 Mar 2006 00:14:09 -0500 Subject: [PATCH 130/180] Used the Fault constructor to create Interrupt faults. Using the pointer directly prevents reference counting from working correctly. cpu/simple/cpu.cc: Used the Fault constructor to create an Interrupt fault. --HG-- extra : convert_revision : ec2ef7e3cd04ee9a44628877dc6e770fb907104b --- cpu/simple/cpu.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpu/simple/cpu.cc b/cpu/simple/cpu.cc index d826c589e..e5c2e18cf 100644 --- a/cpu/simple/cpu.cc +++ b/cpu/simple/cpu.cc @@ -687,7 +687,7 @@ SimpleCPU::tick() if (ipl && ipl > xc->readMiscReg(IPR_IPLR)) { xc->setMiscReg(IPR_ISR, summary); xc->setMiscReg(IPR_INTID, ipl); - (new InterruptFault)->ev5_trap(xc); + Fault(new InterruptFault)->ev5_trap(xc); DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n", xc->readMiscReg(IPR_IPLR), ipl, summary); From e08cf8fee0a2732aab1d4c6d0ba152282aad9714 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 1 Mar 2006 01:23:10 -0500 Subject: [PATCH 131/180] Changed the name of the fault's invocation method from ev5_trap to invoke. --HG-- extra : convert_revision : b7ab14ac644f6a38c69aaa5372b3002b21f34af0 --- arch/alpha/faults.cc | 2 +- arch/alpha/faults.hh | 2 +- cpu/exec_context.cc | 2 +- cpu/simple/cpu.cc | 4 ++-- cpu/simple/cpu.hh | 2 +- sim/faults.hh | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/arch/alpha/faults.cc b/arch/alpha/faults.cc index 8c7dc3194..bde7b3db1 100644 --- a/arch/alpha/faults.cc +++ b/arch/alpha/faults.cc @@ -99,7 +99,7 @@ FaultStat IntegerOverflowFault::_stat; #if FULL_SYSTEM -void AlphaFault::ev5_trap(ExecContext * xc) +void AlphaFault::invoke(ExecContext * xc) { DPRINTF(Fault, "Fault %s at PC: %#x\n", name(), xc->regs.pc); xc->cpu->recordEvent(csprintf("Fault %s", name())); diff --git a/arch/alpha/faults.hh b/arch/alpha/faults.hh index 829edd490..c0316288c 100644 --- a/arch/alpha/faults.hh +++ b/arch/alpha/faults.hh @@ -42,7 +42,7 @@ class AlphaFault : public virtual FaultBase { public: #if FULL_SYSTEM - void ev5_trap(ExecContext * xc); + void invoke(ExecContext * xc); #endif virtual FaultVect vect() = 0; }; diff --git a/cpu/exec_context.cc b/cpu/exec_context.cc index 7e8b81e18..0e787a547 100644 --- a/cpu/exec_context.cc +++ b/cpu/exec_context.cc @@ -227,7 +227,7 @@ ExecContext::trap(Fault fault) /** @todo: Going to hack it for now. Do a true fixup later. */ #if FULL_SYSTEM - fault->ev5_trap(this); + fault->invoke(this); #else fatal("fault (%d) detected @ PC 0x%08p", fault, readPC()); #endif diff --git a/cpu/simple/cpu.cc b/cpu/simple/cpu.cc index e5c2e18cf..85a3c19ac 100644 --- a/cpu/simple/cpu.cc +++ b/cpu/simple/cpu.cc @@ -687,7 +687,7 @@ SimpleCPU::tick() if (ipl && ipl > xc->readMiscReg(IPR_IPLR)) { xc->setMiscReg(IPR_ISR, summary); xc->setMiscReg(IPR_INTID, ipl); - Fault(new InterruptFault)->ev5_trap(xc); + Fault(new InterruptFault)->invoke(xc); DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n", xc->readMiscReg(IPR_IPLR), ipl, summary); @@ -811,7 +811,7 @@ SimpleCPU::tick() if (fault != NoFault) { #if FULL_SYSTEM - fault->ev5_trap(xc); + fault->invoke(xc); #else // !FULL_SYSTEM fatal("fault (%d) detected @ PC 0x%08p", fault, xc->regs.pc); #endif // FULL_SYSTEM diff --git a/cpu/simple/cpu.hh b/cpu/simple/cpu.hh index 243172821..8396937a8 100644 --- a/cpu/simple/cpu.hh +++ b/cpu/simple/cpu.hh @@ -347,7 +347,7 @@ class SimpleCPU : public BaseCPU int readIntrFlag() { return xc->readIntrFlag(); } void setIntrFlag(int val) { xc->setIntrFlag(val); } bool inPalMode() { return xc->inPalMode(); } - void ev5_trap(Fault fault) { fault->ev5_trap(xc); } + void ev5_trap(Fault fault) { fault->invoke(xc); } bool simPalCheck(int palFunc) { return xc->simPalCheck(palFunc); } #else void syscall() { xc->syscall(); } diff --git a/sim/faults.hh b/sim/faults.hh index 9b8c94cda..6a786fe26 100644 --- a/sim/faults.hh +++ b/sim/faults.hh @@ -53,7 +53,7 @@ class FaultBase : public RefCounted virtual FaultName name() = 0; virtual FaultStat & stat() = 0; #if FULL_SYSTEM - virtual void ev5_trap(ExecContext * xc) = 0; + virtual void invoke(ExecContext * xc) = 0; #endif template bool isA() {return dynamic_cast(this);} From d21e037fb8ad69857d3d134eb4e07cf360446736 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 1 Mar 2006 05:20:47 -0500 Subject: [PATCH 132/180] Made sparc copies of some architecture specific files. arch/sparc/linux_process.cc: arch/sparc/linux_process.hh: Formatting & doxygen. arch/sparc/linux_process.cc: Added some more ioctl commands to ignore. Set unlink and rename to the new functions. Ignore setrlimit, times and rt_sigaction. Should eventually provide a function for times. arch/sparc/linux_process.cc: Fixes for Linux emulation: - stat struct alignment - osf_{get,set}sysinfo return values - additional syscall numbers - initialize $r0 to 0 arch/sparc/linux_process.cc: arch/sparc/linux_process.hh: Updated Copyright arch/sparc/linux_process.cc: Alphabetize includes. arch/sparc/linux_process.cc: Changed all syscalls to use syscall return object arch/sparc/linux_process.cc: Removed unecessary constructor call at each return. arch/sparc/linux_process.cc: Rename sim/universe.{cc,hh} to root.{cc,hh}. arch/sparc/linux_process.cc: shuffle files around for new directory structure arch/sparc/linux_process.cc: Remove RCS Id string arch/sparc/linux_process.cc: arch/sparc/linux_process.hh: Update copyright dates and author list arch/sparc/linux_process.hh: remove $Id$ string arch/sparc/linux_process.cc: Apply patch for syscall emulation provided by Antti Miettinen (apm@brigitte.dna.fi). arch/sparc/linux_process.cc: Added the endianness namespace. This may change. arch/sparc/linux_process.cc: Replaced the namespace declaration with including arch/alpha/isa_traits.hh arch/sparc/linux_process.cc: fixup for bsd hosts. Some headers are included by default which means that more variables need TGT_ prefixes and there isn't a stat call (everything is a stat64 call) so we have to work around that a bit arch/sparc/linux_process.cc: Add endian conversions to fstat arch/sparc/linux_process.cc: fix #if. I wonder why my compiler had no issues arch/sparc/linux_process.cc: add endian conversions for fstat functions arch/sparc/linux_process.cc: move architecture independent code into kern/linux/linux.(hh|cc) arch/sparc/linux_process.hh: Add getDesc function arch/sparc/linux_process.cc: Added using directive for AlphaISA namespace arch/sparc/linux_process.cc: Add pipeFunc. arch/alpha/linux_process.cc: Renamed arch files to remove alpha prefix, and changed alpha_memory.hh and cc to a more accurate tlb.hh and cc arch/sparc/linux_process.cc: bk cp ../alpha/linux_process.cc linux_process.cc arch/sparc/linux_process.hh: bk cp ../alpha/linux_process.hh linux_process.hh --HG-- extra : convert_revision : a8eca1c5f848383263a2326b0e3cde4bcd85f14b --- arch/sparc/linux_process.cc | 613 ++++++++++++++++++++++++++++++++++++ arch/sparc/linux_process.hh | 58 ++++ 2 files changed, 671 insertions(+) create mode 100644 arch/sparc/linux_process.cc create mode 100644 arch/sparc/linux_process.hh diff --git a/arch/sparc/linux_process.cc b/arch/sparc/linux_process.cc new file mode 100644 index 000000000..0b193fb55 --- /dev/null +++ b/arch/sparc/linux_process.cc @@ -0,0 +1,613 @@ +/* + * 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/alpha/common_syscall_emul.hh" +#include "arch/alpha/linux_process.hh" +#include "arch/alpha/isa_traits.hh" + +#include "base/trace.hh" +#include "cpu/exec_context.hh" +#include "kern/linux/linux.hh" +#include "mem/functional/functional.hh" + +#include "sim/process.hh" +#include "sim/syscall_emul.hh" + +using namespace std; +using namespace AlphaISA; + +/// Target pipe() handler. Even though this is a generic Posix call, +/// the Alpha return convention is funky, so that makes it +/// Alpha-specific. +SyscallReturn +pipeFunc(SyscallDesc *desc, int callnum, Process *process, + ExecContext *xc) +{ + int fds[2], sim_fds[2]; + int pipe_retval = pipe(fds); + + if (pipe_retval < 0) { + // error + return pipe_retval; + } + + sim_fds[0] = process->alloc_fd(fds[0]); + sim_fds[1] = process->alloc_fd(fds[1]); + + // Alpha Linux convention for pipe() is that fd[0] is returned as + // the return value of the function, and fd[1] is returned in r20. + xc->regs.intRegFile[20] = sim_fds[1]; + return sim_fds[0]; +} + + +/// Target uname() handler. +static SyscallReturn +unameFunc(SyscallDesc *desc, int callnum, Process *process, + ExecContext *xc) +{ + TypedBufferArg name(xc->getSyscallArg(0)); + + strcpy(name->sysname, "Linux"); + strcpy(name->nodename, "m5.eecs.umich.edu"); + strcpy(name->release, "2.4.20"); + strcpy(name->version, "#1 Mon Aug 18 11:32:15 EDT 2003"); + strcpy(name->machine, "alpha"); + + name.copyOut(xc->mem); + return 0; +} + +/// Target osf_getsysyinfo() handler. Even though this call is +/// borrowed from Tru64, the subcases that get used appear to be +/// different in practice from those used by Tru64 processes. +static SyscallReturn +osf_getsysinfoFunc(SyscallDesc *desc, int callnum, Process *process, + ExecContext *xc) +{ + unsigned op = xc->getSyscallArg(0); + // unsigned nbytes = xc->getSyscallArg(2); + + switch (op) { + + case 45: { // GSI_IEEE_FP_CONTROL + TypedBufferArg fpcr(xc->getSyscallArg(1)); + // I don't think this exactly matches the HW FPCR + *fpcr = 0; + fpcr.copyOut(xc->mem); + return 0; + } + + default: + cerr << "osf_getsysinfo: unknown op " << op << endl; + abort(); + break; + } + + return 1; +} + +/// Target osf_setsysinfo() handler. +static SyscallReturn +osf_setsysinfoFunc(SyscallDesc *desc, int callnum, Process *process, + ExecContext *xc) +{ + unsigned op = xc->getSyscallArg(0); + // unsigned nbytes = xc->getSyscallArg(2); + + switch (op) { + + case 14: { // SSI_IEEE_FP_CONTROL + TypedBufferArg fpcr(xc->getSyscallArg(1)); + // I don't think this exactly matches the HW FPCR + fpcr.copyIn(xc->mem); + DPRINTFR(SyscallVerbose, "osf_setsysinfo(SSI_IEEE_FP_CONTROL): " + " setting FPCR to 0x%x\n", gtoh(*(uint64_t*)fpcr)); + return 0; + } + + default: + cerr << "osf_setsysinfo: unknown op " << op << endl; + abort(); + break; + } + + return 1; +} + + +SyscallDesc AlphaLinuxProcess::syscallDescs[] = { + /* 0 */ SyscallDesc("osf_syscall", unimplementedFunc), + /* 1 */ SyscallDesc("exit", exitFunc), + /* 2 */ SyscallDesc("fork", unimplementedFunc), + /* 3 */ SyscallDesc("read", readFunc), + /* 4 */ SyscallDesc("write", writeFunc), + /* 5 */ SyscallDesc("osf_old_open", unimplementedFunc), + /* 6 */ SyscallDesc("close", closeFunc), + /* 7 */ SyscallDesc("osf_wait4", unimplementedFunc), + /* 8 */ SyscallDesc("osf_old_creat", unimplementedFunc), + /* 9 */ SyscallDesc("link", unimplementedFunc), + /* 10 */ SyscallDesc("unlink", unlinkFunc), + /* 11 */ SyscallDesc("osf_execve", unimplementedFunc), + /* 12 */ SyscallDesc("chdir", unimplementedFunc), + /* 13 */ SyscallDesc("fchdir", unimplementedFunc), + /* 14 */ SyscallDesc("mknod", unimplementedFunc), + /* 15 */ SyscallDesc("chmod", chmodFunc), + /* 16 */ SyscallDesc("chown", chownFunc), + /* 17 */ SyscallDesc("brk", obreakFunc), + /* 18 */ SyscallDesc("osf_getfsstat", unimplementedFunc), + /* 19 */ SyscallDesc("lseek", lseekFunc), + /* 20 */ SyscallDesc("getxpid", getpidFunc), + /* 21 */ SyscallDesc("osf_mount", unimplementedFunc), + /* 22 */ SyscallDesc("umount", unimplementedFunc), + /* 23 */ SyscallDesc("setuid", setuidFunc), + /* 24 */ SyscallDesc("getxuid", getuidFunc), + /* 25 */ SyscallDesc("exec_with_loader", unimplementedFunc), + /* 26 */ SyscallDesc("osf_ptrace", unimplementedFunc), + /* 27 */ SyscallDesc("osf_nrecvmsg", unimplementedFunc), + /* 28 */ SyscallDesc("osf_nsendmsg", unimplementedFunc), + /* 29 */ SyscallDesc("osf_nrecvfrom", unimplementedFunc), + /* 30 */ SyscallDesc("osf_naccept", unimplementedFunc), + /* 31 */ SyscallDesc("osf_ngetpeername", unimplementedFunc), + /* 32 */ SyscallDesc("osf_ngetsockname", unimplementedFunc), + /* 33 */ SyscallDesc("access", unimplementedFunc), + /* 34 */ SyscallDesc("osf_chflags", unimplementedFunc), + /* 35 */ SyscallDesc("osf_fchflags", unimplementedFunc), + /* 36 */ SyscallDesc("sync", unimplementedFunc), + /* 37 */ SyscallDesc("kill", unimplementedFunc), + /* 38 */ SyscallDesc("osf_old_stat", unimplementedFunc), + /* 39 */ SyscallDesc("setpgid", unimplementedFunc), + /* 40 */ SyscallDesc("osf_old_lstat", unimplementedFunc), + /* 41 */ SyscallDesc("dup", unimplementedFunc), + /* 42 */ SyscallDesc("pipe", pipeFunc), + /* 43 */ SyscallDesc("osf_set_program_attributes", unimplementedFunc), + /* 44 */ SyscallDesc("osf_profil", unimplementedFunc), + /* 45 */ SyscallDesc("open", openFunc), + /* 46 */ SyscallDesc("osf_old_sigaction", unimplementedFunc), + /* 47 */ SyscallDesc("getxgid", getgidFunc), + /* 48 */ SyscallDesc("osf_sigprocmask", ignoreFunc), + /* 49 */ SyscallDesc("osf_getlogin", unimplementedFunc), + /* 50 */ SyscallDesc("osf_setlogin", unimplementedFunc), + /* 51 */ SyscallDesc("acct", unimplementedFunc), + /* 52 */ SyscallDesc("sigpending", unimplementedFunc), + /* 53 */ SyscallDesc("osf_classcntl", unimplementedFunc), + /* 54 */ SyscallDesc("ioctl", ioctlFunc), + /* 55 */ SyscallDesc("osf_reboot", unimplementedFunc), + /* 56 */ SyscallDesc("osf_revoke", unimplementedFunc), + /* 57 */ SyscallDesc("symlink", unimplementedFunc), + /* 58 */ SyscallDesc("readlink", unimplementedFunc), + /* 59 */ SyscallDesc("execve", unimplementedFunc), + /* 60 */ SyscallDesc("umask", unimplementedFunc), + /* 61 */ SyscallDesc("chroot", unimplementedFunc), + /* 62 */ SyscallDesc("osf_old_fstat", unimplementedFunc), + /* 63 */ SyscallDesc("getpgrp", unimplementedFunc), + /* 64 */ SyscallDesc("getpagesize", getpagesizeFunc), + /* 65 */ SyscallDesc("osf_mremap", unimplementedFunc), + /* 66 */ SyscallDesc("vfork", unimplementedFunc), + /* 67 */ SyscallDesc("stat", statFunc), + /* 68 */ SyscallDesc("lstat", lstatFunc), + /* 69 */ SyscallDesc("osf_sbrk", unimplementedFunc), + /* 70 */ SyscallDesc("osf_sstk", unimplementedFunc), + /* 71 */ SyscallDesc("mmap", mmapFunc), + /* 72 */ SyscallDesc("osf_old_vadvise", unimplementedFunc), + /* 73 */ SyscallDesc("munmap", munmapFunc), + /* 74 */ SyscallDesc("mprotect", ignoreFunc), + /* 75 */ SyscallDesc("madvise", unimplementedFunc), + /* 76 */ SyscallDesc("vhangup", unimplementedFunc), + /* 77 */ SyscallDesc("osf_kmodcall", unimplementedFunc), + /* 78 */ SyscallDesc("osf_mincore", unimplementedFunc), + /* 79 */ SyscallDesc("getgroups", unimplementedFunc), + /* 80 */ SyscallDesc("setgroups", unimplementedFunc), + /* 81 */ SyscallDesc("osf_old_getpgrp", unimplementedFunc), + /* 82 */ SyscallDesc("setpgrp", unimplementedFunc), + /* 83 */ SyscallDesc("osf_setitimer", unimplementedFunc), + /* 84 */ SyscallDesc("osf_old_wait", unimplementedFunc), + /* 85 */ SyscallDesc("osf_table", unimplementedFunc), + /* 86 */ SyscallDesc("osf_getitimer", unimplementedFunc), + /* 87 */ SyscallDesc("gethostname", gethostnameFunc), + /* 88 */ SyscallDesc("sethostname", unimplementedFunc), + /* 89 */ SyscallDesc("getdtablesize", unimplementedFunc), + /* 90 */ SyscallDesc("dup2", unimplementedFunc), + /* 91 */ SyscallDesc("fstat", fstatFunc), + /* 92 */ SyscallDesc("fcntl", fcntlFunc), + /* 93 */ SyscallDesc("osf_select", unimplementedFunc), + /* 94 */ SyscallDesc("poll", unimplementedFunc), + /* 95 */ SyscallDesc("fsync", unimplementedFunc), + /* 96 */ SyscallDesc("setpriority", unimplementedFunc), + /* 97 */ SyscallDesc("socket", unimplementedFunc), + /* 98 */ SyscallDesc("connect", unimplementedFunc), + /* 99 */ SyscallDesc("accept", unimplementedFunc), + /* 100 */ SyscallDesc("getpriority", unimplementedFunc), + /* 101 */ SyscallDesc("send", unimplementedFunc), + /* 102 */ SyscallDesc("recv", unimplementedFunc), + /* 103 */ SyscallDesc("sigreturn", unimplementedFunc), + /* 104 */ SyscallDesc("bind", unimplementedFunc), + /* 105 */ SyscallDesc("setsockopt", unimplementedFunc), + /* 106 */ SyscallDesc("listen", unimplementedFunc), + /* 107 */ SyscallDesc("osf_plock", unimplementedFunc), + /* 108 */ SyscallDesc("osf_old_sigvec", unimplementedFunc), + /* 109 */ SyscallDesc("osf_old_sigblock", unimplementedFunc), + /* 110 */ SyscallDesc("osf_old_sigsetmask", unimplementedFunc), + /* 111 */ SyscallDesc("sigsuspend", unimplementedFunc), + /* 112 */ SyscallDesc("osf_sigstack", ignoreFunc), + /* 113 */ SyscallDesc("recvmsg", unimplementedFunc), + /* 114 */ SyscallDesc("sendmsg", unimplementedFunc), + /* 115 */ SyscallDesc("osf_old_vtrace", unimplementedFunc), + /* 116 */ SyscallDesc("osf_gettimeofday", unimplementedFunc), + /* 117 */ SyscallDesc("osf_getrusage", unimplementedFunc), + /* 118 */ SyscallDesc("getsockopt", unimplementedFunc), + /* 119 */ SyscallDesc("numa_syscalls", unimplementedFunc), + /* 120 */ SyscallDesc("readv", unimplementedFunc), + /* 121 */ SyscallDesc("writev", writevFunc), + /* 122 */ SyscallDesc("osf_settimeofday", unimplementedFunc), + /* 123 */ SyscallDesc("fchown", fchownFunc), + /* 124 */ SyscallDesc("fchmod", fchmodFunc), + /* 125 */ SyscallDesc("recvfrom", unimplementedFunc), + /* 126 */ SyscallDesc("setreuid", unimplementedFunc), + /* 127 */ SyscallDesc("setregid", unimplementedFunc), + /* 128 */ SyscallDesc("rename", renameFunc), + /* 129 */ SyscallDesc("truncate", unimplementedFunc), + /* 130 */ SyscallDesc("ftruncate", unimplementedFunc), + /* 131 */ SyscallDesc("flock", unimplementedFunc), + /* 132 */ SyscallDesc("setgid", unimplementedFunc), + /* 133 */ SyscallDesc("sendto", unimplementedFunc), + /* 134 */ SyscallDesc("shutdown", unimplementedFunc), + /* 135 */ SyscallDesc("socketpair", unimplementedFunc), + /* 136 */ SyscallDesc("mkdir", unimplementedFunc), + /* 137 */ SyscallDesc("rmdir", unimplementedFunc), + /* 138 */ SyscallDesc("osf_utimes", unimplementedFunc), + /* 139 */ SyscallDesc("osf_old_sigreturn", unimplementedFunc), + /* 140 */ SyscallDesc("osf_adjtime", unimplementedFunc), + /* 141 */ SyscallDesc("getpeername", unimplementedFunc), + /* 142 */ SyscallDesc("osf_gethostid", unimplementedFunc), + /* 143 */ SyscallDesc("osf_sethostid", unimplementedFunc), + /* 144 */ SyscallDesc("getrlimit", getrlimitFunc), + /* 145 */ SyscallDesc("setrlimit", ignoreFunc), + /* 146 */ SyscallDesc("osf_old_killpg", unimplementedFunc), + /* 147 */ SyscallDesc("setsid", unimplementedFunc), + /* 148 */ SyscallDesc("quotactl", unimplementedFunc), + /* 149 */ SyscallDesc("osf_oldquota", unimplementedFunc), + /* 150 */ SyscallDesc("getsockname", unimplementedFunc), + /* 151 */ SyscallDesc("osf_pread", unimplementedFunc), + /* 152 */ SyscallDesc("osf_pwrite", unimplementedFunc), + /* 153 */ SyscallDesc("osf_pid_block", unimplementedFunc), + /* 154 */ SyscallDesc("osf_pid_unblock", unimplementedFunc), + /* 155 */ SyscallDesc("osf_signal_urti", unimplementedFunc), + /* 156 */ SyscallDesc("sigaction", ignoreFunc), + /* 157 */ SyscallDesc("osf_sigwaitprim", unimplementedFunc), + /* 158 */ SyscallDesc("osf_nfssvc", unimplementedFunc), + /* 159 */ SyscallDesc("osf_getdirentries", unimplementedFunc), + /* 160 */ SyscallDesc("osf_statfs", unimplementedFunc), + /* 161 */ SyscallDesc("osf_fstatfs", unimplementedFunc), + /* 162 */ SyscallDesc("unknown #162", unimplementedFunc), + /* 163 */ SyscallDesc("osf_async_daemon", unimplementedFunc), + /* 164 */ SyscallDesc("osf_getfh", unimplementedFunc), + /* 165 */ SyscallDesc("osf_getdomainname", unimplementedFunc), + /* 166 */ SyscallDesc("setdomainname", unimplementedFunc), + /* 167 */ SyscallDesc("unknown #167", unimplementedFunc), + /* 168 */ SyscallDesc("unknown #168", unimplementedFunc), + /* 169 */ SyscallDesc("osf_exportfs", unimplementedFunc), + /* 170 */ SyscallDesc("unknown #170", unimplementedFunc), + /* 171 */ SyscallDesc("unknown #171", unimplementedFunc), + /* 172 */ SyscallDesc("unknown #172", unimplementedFunc), + /* 173 */ SyscallDesc("unknown #173", unimplementedFunc), + /* 174 */ SyscallDesc("unknown #174", unimplementedFunc), + /* 175 */ SyscallDesc("unknown #175", unimplementedFunc), + /* 176 */ SyscallDesc("unknown #176", unimplementedFunc), + /* 177 */ SyscallDesc("unknown #177", unimplementedFunc), + /* 178 */ SyscallDesc("unknown #178", unimplementedFunc), + /* 179 */ SyscallDesc("unknown #179", unimplementedFunc), + /* 180 */ SyscallDesc("unknown #180", unimplementedFunc), + /* 181 */ SyscallDesc("osf_alt_plock", unimplementedFunc), + /* 182 */ SyscallDesc("unknown #182", unimplementedFunc), + /* 183 */ SyscallDesc("unknown #183", unimplementedFunc), + /* 184 */ SyscallDesc("osf_getmnt", unimplementedFunc), + /* 185 */ SyscallDesc("unknown #185", unimplementedFunc), + /* 186 */ SyscallDesc("unknown #186", unimplementedFunc), + /* 187 */ SyscallDesc("osf_alt_sigpending", unimplementedFunc), + /* 188 */ SyscallDesc("osf_alt_setsid", unimplementedFunc), + /* 189 */ SyscallDesc("unknown #189", unimplementedFunc), + /* 190 */ SyscallDesc("unknown #190", unimplementedFunc), + /* 191 */ SyscallDesc("unknown #191", unimplementedFunc), + /* 192 */ SyscallDesc("unknown #192", unimplementedFunc), + /* 193 */ SyscallDesc("unknown #193", unimplementedFunc), + /* 194 */ SyscallDesc("unknown #194", unimplementedFunc), + /* 195 */ SyscallDesc("unknown #195", unimplementedFunc), + /* 196 */ SyscallDesc("unknown #196", unimplementedFunc), + /* 197 */ SyscallDesc("unknown #197", unimplementedFunc), + /* 198 */ SyscallDesc("unknown #198", unimplementedFunc), + /* 199 */ SyscallDesc("osf_swapon", unimplementedFunc), + /* 200 */ SyscallDesc("msgctl", unimplementedFunc), + /* 201 */ SyscallDesc("msgget", unimplementedFunc), + /* 202 */ SyscallDesc("msgrcv", unimplementedFunc), + /* 203 */ SyscallDesc("msgsnd", unimplementedFunc), + /* 204 */ SyscallDesc("semctl", unimplementedFunc), + /* 205 */ SyscallDesc("semget", unimplementedFunc), + /* 206 */ SyscallDesc("semop", unimplementedFunc), + /* 207 */ SyscallDesc("osf_utsname", unimplementedFunc), + /* 208 */ SyscallDesc("lchown", unimplementedFunc), + /* 209 */ SyscallDesc("osf_shmat", unimplementedFunc), + /* 210 */ SyscallDesc("shmctl", unimplementedFunc), + /* 211 */ SyscallDesc("shmdt", unimplementedFunc), + /* 212 */ SyscallDesc("shmget", unimplementedFunc), + /* 213 */ SyscallDesc("osf_mvalid", unimplementedFunc), + /* 214 */ SyscallDesc("osf_getaddressconf", unimplementedFunc), + /* 215 */ SyscallDesc("osf_msleep", unimplementedFunc), + /* 216 */ SyscallDesc("osf_mwakeup", unimplementedFunc), + /* 217 */ SyscallDesc("msync", unimplementedFunc), + /* 218 */ SyscallDesc("osf_signal", unimplementedFunc), + /* 219 */ SyscallDesc("osf_utc_gettime", unimplementedFunc), + /* 220 */ SyscallDesc("osf_utc_adjtime", unimplementedFunc), + /* 221 */ SyscallDesc("unknown #221", unimplementedFunc), + /* 222 */ SyscallDesc("osf_security", unimplementedFunc), + /* 223 */ SyscallDesc("osf_kloadcall", unimplementedFunc), + /* 224 */ SyscallDesc("unknown #224", unimplementedFunc), + /* 225 */ SyscallDesc("unknown #225", unimplementedFunc), + /* 226 */ SyscallDesc("unknown #226", unimplementedFunc), + /* 227 */ SyscallDesc("unknown #227", unimplementedFunc), + /* 228 */ SyscallDesc("unknown #228", unimplementedFunc), + /* 229 */ SyscallDesc("unknown #229", unimplementedFunc), + /* 230 */ SyscallDesc("unknown #230", unimplementedFunc), + /* 231 */ SyscallDesc("unknown #231", unimplementedFunc), + /* 232 */ SyscallDesc("unknown #232", unimplementedFunc), + /* 233 */ SyscallDesc("getpgid", unimplementedFunc), + /* 234 */ SyscallDesc("getsid", unimplementedFunc), + /* 235 */ SyscallDesc("sigaltstack", ignoreFunc), + /* 236 */ SyscallDesc("osf_waitid", unimplementedFunc), + /* 237 */ SyscallDesc("osf_priocntlset", unimplementedFunc), + /* 238 */ SyscallDesc("osf_sigsendset", unimplementedFunc), + /* 239 */ SyscallDesc("osf_set_speculative", unimplementedFunc), + /* 240 */ SyscallDesc("osf_msfs_syscall", unimplementedFunc), + /* 241 */ SyscallDesc("osf_sysinfo", unimplementedFunc), + /* 242 */ SyscallDesc("osf_uadmin", unimplementedFunc), + /* 243 */ SyscallDesc("osf_fuser", unimplementedFunc), + /* 244 */ SyscallDesc("osf_proplist_syscall", unimplementedFunc), + /* 245 */ SyscallDesc("osf_ntp_adjtime", unimplementedFunc), + /* 246 */ SyscallDesc("osf_ntp_gettime", unimplementedFunc), + /* 247 */ SyscallDesc("osf_pathconf", unimplementedFunc), + /* 248 */ SyscallDesc("osf_fpathconf", unimplementedFunc), + /* 249 */ SyscallDesc("unknown #249", unimplementedFunc), + /* 250 */ SyscallDesc("osf_uswitch", unimplementedFunc), + /* 251 */ SyscallDesc("osf_usleep_thread", unimplementedFunc), + /* 252 */ SyscallDesc("osf_audcntl", unimplementedFunc), + /* 253 */ SyscallDesc("osf_audgen", unimplementedFunc), + /* 254 */ SyscallDesc("sysfs", unimplementedFunc), + /* 255 */ SyscallDesc("osf_subsys_info", unimplementedFunc), + /* 256 */ SyscallDesc("osf_getsysinfo", osf_getsysinfoFunc), + /* 257 */ SyscallDesc("osf_setsysinfo", osf_setsysinfoFunc), + /* 258 */ SyscallDesc("osf_afs_syscall", unimplementedFunc), + /* 259 */ SyscallDesc("osf_swapctl", unimplementedFunc), + /* 260 */ SyscallDesc("osf_memcntl", unimplementedFunc), + /* 261 */ SyscallDesc("osf_fdatasync", unimplementedFunc), + /* 262 */ SyscallDesc("unknown #262", unimplementedFunc), + /* 263 */ SyscallDesc("unknown #263", unimplementedFunc), + /* 264 */ SyscallDesc("unknown #264", unimplementedFunc), + /* 265 */ SyscallDesc("unknown #265", unimplementedFunc), + /* 266 */ SyscallDesc("unknown #266", unimplementedFunc), + /* 267 */ SyscallDesc("unknown #267", unimplementedFunc), + /* 268 */ SyscallDesc("unknown #268", unimplementedFunc), + /* 269 */ SyscallDesc("unknown #269", unimplementedFunc), + /* 270 */ SyscallDesc("unknown #270", unimplementedFunc), + /* 271 */ SyscallDesc("unknown #271", unimplementedFunc), + /* 272 */ SyscallDesc("unknown #272", unimplementedFunc), + /* 273 */ SyscallDesc("unknown #273", unimplementedFunc), + /* 274 */ SyscallDesc("unknown #274", unimplementedFunc), + /* 275 */ SyscallDesc("unknown #275", unimplementedFunc), + /* 276 */ SyscallDesc("unknown #276", unimplementedFunc), + /* 277 */ SyscallDesc("unknown #277", unimplementedFunc), + /* 278 */ SyscallDesc("unknown #278", unimplementedFunc), + /* 279 */ SyscallDesc("unknown #279", unimplementedFunc), + /* 280 */ SyscallDesc("unknown #280", unimplementedFunc), + /* 281 */ SyscallDesc("unknown #281", unimplementedFunc), + /* 282 */ SyscallDesc("unknown #282", unimplementedFunc), + /* 283 */ SyscallDesc("unknown #283", unimplementedFunc), + /* 284 */ SyscallDesc("unknown #284", unimplementedFunc), + /* 285 */ SyscallDesc("unknown #285", unimplementedFunc), + /* 286 */ SyscallDesc("unknown #286", unimplementedFunc), + /* 287 */ SyscallDesc("unknown #287", unimplementedFunc), + /* 288 */ SyscallDesc("unknown #288", unimplementedFunc), + /* 289 */ SyscallDesc("unknown #289", unimplementedFunc), + /* 290 */ SyscallDesc("unknown #290", unimplementedFunc), + /* 291 */ SyscallDesc("unknown #291", unimplementedFunc), + /* 292 */ SyscallDesc("unknown #292", unimplementedFunc), + /* 293 */ SyscallDesc("unknown #293", unimplementedFunc), + /* 294 */ SyscallDesc("unknown #294", unimplementedFunc), + /* 295 */ SyscallDesc("unknown #295", unimplementedFunc), + /* 296 */ SyscallDesc("unknown #296", unimplementedFunc), + /* 297 */ SyscallDesc("unknown #297", unimplementedFunc), + /* 298 */ SyscallDesc("unknown #298", unimplementedFunc), + /* 299 */ SyscallDesc("unknown #299", unimplementedFunc), +/* + * Linux-specific system calls begin at 300 + */ + /* 300 */ SyscallDesc("bdflush", unimplementedFunc), + /* 301 */ SyscallDesc("sethae", unimplementedFunc), + /* 302 */ SyscallDesc("mount", unimplementedFunc), + /* 303 */ SyscallDesc("old_adjtimex", unimplementedFunc), + /* 304 */ SyscallDesc("swapoff", unimplementedFunc), + /* 305 */ SyscallDesc("getdents", unimplementedFunc), + /* 306 */ SyscallDesc("create_module", unimplementedFunc), + /* 307 */ SyscallDesc("init_module", unimplementedFunc), + /* 308 */ SyscallDesc("delete_module", unimplementedFunc), + /* 309 */ SyscallDesc("get_kernel_syms", unimplementedFunc), + /* 310 */ SyscallDesc("syslog", unimplementedFunc), + /* 311 */ SyscallDesc("reboot", unimplementedFunc), + /* 312 */ SyscallDesc("clone", unimplementedFunc), + /* 313 */ SyscallDesc("uselib", unimplementedFunc), + /* 314 */ SyscallDesc("mlock", unimplementedFunc), + /* 315 */ SyscallDesc("munlock", unimplementedFunc), + /* 316 */ SyscallDesc("mlockall", unimplementedFunc), + /* 317 */ SyscallDesc("munlockall", unimplementedFunc), + /* 318 */ SyscallDesc("sysinfo", unimplementedFunc), + /* 319 */ SyscallDesc("_sysctl", unimplementedFunc), + /* 320 */ SyscallDesc("was sys_idle", unimplementedFunc), + /* 321 */ SyscallDesc("oldumount", unimplementedFunc), + /* 322 */ SyscallDesc("swapon", unimplementedFunc), + /* 323 */ SyscallDesc("times", ignoreFunc), + /* 324 */ SyscallDesc("personality", unimplementedFunc), + /* 325 */ SyscallDesc("setfsuid", unimplementedFunc), + /* 326 */ SyscallDesc("setfsgid", unimplementedFunc), + /* 327 */ SyscallDesc("ustat", unimplementedFunc), + /* 328 */ SyscallDesc("statfs", unimplementedFunc), + /* 329 */ SyscallDesc("fstatfs", unimplementedFunc), + /* 330 */ SyscallDesc("sched_setparam", unimplementedFunc), + /* 331 */ SyscallDesc("sched_getparam", unimplementedFunc), + /* 332 */ SyscallDesc("sched_setscheduler", unimplementedFunc), + /* 333 */ SyscallDesc("sched_getscheduler", unimplementedFunc), + /* 334 */ SyscallDesc("sched_yield", unimplementedFunc), + /* 335 */ SyscallDesc("sched_get_priority_max", unimplementedFunc), + /* 336 */ SyscallDesc("sched_get_priority_min", unimplementedFunc), + /* 337 */ SyscallDesc("sched_rr_get_interval", unimplementedFunc), + /* 338 */ SyscallDesc("afs_syscall", unimplementedFunc), + /* 339 */ SyscallDesc("uname", unameFunc), + /* 340 */ SyscallDesc("nanosleep", unimplementedFunc), + /* 341 */ SyscallDesc("mremap", unimplementedFunc), + /* 342 */ SyscallDesc("nfsservctl", unimplementedFunc), + /* 343 */ SyscallDesc("setresuid", unimplementedFunc), + /* 344 */ SyscallDesc("getresuid", unimplementedFunc), + /* 345 */ SyscallDesc("pciconfig_read", unimplementedFunc), + /* 346 */ SyscallDesc("pciconfig_write", unimplementedFunc), + /* 347 */ SyscallDesc("query_module", unimplementedFunc), + /* 348 */ SyscallDesc("prctl", unimplementedFunc), + /* 349 */ SyscallDesc("pread", unimplementedFunc), + /* 350 */ SyscallDesc("pwrite", unimplementedFunc), + /* 351 */ SyscallDesc("rt_sigreturn", unimplementedFunc), + /* 352 */ SyscallDesc("rt_sigaction", ignoreFunc), + /* 353 */ SyscallDesc("rt_sigprocmask", unimplementedFunc), + /* 354 */ SyscallDesc("rt_sigpending", unimplementedFunc), + /* 355 */ SyscallDesc("rt_sigtimedwait", unimplementedFunc), + /* 356 */ SyscallDesc("rt_sigqueueinfo", unimplementedFunc), + /* 357 */ SyscallDesc("rt_sigsuspend", unimplementedFunc), + /* 358 */ SyscallDesc("select", unimplementedFunc), + /* 359 */ SyscallDesc("gettimeofday", gettimeofdayFunc), + /* 360 */ SyscallDesc("settimeofday", unimplementedFunc), + /* 361 */ SyscallDesc("getitimer", unimplementedFunc), + /* 362 */ SyscallDesc("setitimer", unimplementedFunc), + /* 363 */ SyscallDesc("utimes", utimesFunc), + /* 364 */ SyscallDesc("getrusage", getrusageFunc), + /* 365 */ SyscallDesc("wait4", unimplementedFunc), + /* 366 */ SyscallDesc("adjtimex", unimplementedFunc), + /* 367 */ SyscallDesc("getcwd", unimplementedFunc), + /* 368 */ SyscallDesc("capget", unimplementedFunc), + /* 369 */ SyscallDesc("capset", unimplementedFunc), + /* 370 */ SyscallDesc("sendfile", unimplementedFunc), + /* 371 */ SyscallDesc("setresgid", unimplementedFunc), + /* 372 */ SyscallDesc("getresgid", unimplementedFunc), + /* 373 */ SyscallDesc("dipc", unimplementedFunc), + /* 374 */ SyscallDesc("pivot_root", unimplementedFunc), + /* 375 */ SyscallDesc("mincore", unimplementedFunc), + /* 376 */ SyscallDesc("pciconfig_iobase", unimplementedFunc), + /* 377 */ SyscallDesc("getdents64", unimplementedFunc), + /* 378 */ SyscallDesc("gettid", unimplementedFunc), + /* 379 */ SyscallDesc("readahead", unimplementedFunc), + /* 380 */ SyscallDesc("security", unimplementedFunc), + /* 381 */ SyscallDesc("tkill", unimplementedFunc), + /* 382 */ SyscallDesc("setxattr", unimplementedFunc), + /* 383 */ SyscallDesc("lsetxattr", unimplementedFunc), + /* 384 */ SyscallDesc("fsetxattr", unimplementedFunc), + /* 385 */ SyscallDesc("getxattr", unimplementedFunc), + /* 386 */ SyscallDesc("lgetxattr", unimplementedFunc), + /* 387 */ SyscallDesc("fgetxattr", unimplementedFunc), + /* 388 */ SyscallDesc("listxattr", unimplementedFunc), + /* 389 */ SyscallDesc("llistxattr", unimplementedFunc), + /* 390 */ SyscallDesc("flistxattr", unimplementedFunc), + /* 391 */ SyscallDesc("removexattr", unimplementedFunc), + /* 392 */ SyscallDesc("lremovexattr", unimplementedFunc), + /* 393 */ SyscallDesc("fremovexattr", unimplementedFunc), + /* 394 */ SyscallDesc("futex", unimplementedFunc), + /* 395 */ SyscallDesc("sched_setaffinity", unimplementedFunc), + /* 396 */ SyscallDesc("sched_getaffinity", unimplementedFunc), + /* 397 */ SyscallDesc("tuxcall", unimplementedFunc), + /* 398 */ SyscallDesc("io_setup", unimplementedFunc), + /* 399 */ SyscallDesc("io_destroy", unimplementedFunc), + /* 400 */ SyscallDesc("io_getevents", unimplementedFunc), + /* 401 */ SyscallDesc("io_submit", unimplementedFunc), + /* 402 */ SyscallDesc("io_cancel", unimplementedFunc), + /* 403 */ SyscallDesc("unknown #403", unimplementedFunc), + /* 404 */ SyscallDesc("unknown #404", unimplementedFunc), + /* 405 */ SyscallDesc("exit_group", exitFunc), // exit all threads... + /* 406 */ SyscallDesc("lookup_dcookie", unimplementedFunc), + /* 407 */ SyscallDesc("sys_epoll_create", unimplementedFunc), + /* 408 */ SyscallDesc("sys_epoll_ctl", unimplementedFunc), + /* 409 */ SyscallDesc("sys_epoll_wait", unimplementedFunc), + /* 410 */ SyscallDesc("remap_file_pages", unimplementedFunc), + /* 411 */ SyscallDesc("set_tid_address", unimplementedFunc), + /* 412 */ SyscallDesc("restart_syscall", unimplementedFunc), + /* 413 */ SyscallDesc("fadvise64", unimplementedFunc), + /* 414 */ SyscallDesc("timer_create", unimplementedFunc), + /* 415 */ SyscallDesc("timer_settime", unimplementedFunc), + /* 416 */ SyscallDesc("timer_gettime", unimplementedFunc), + /* 417 */ SyscallDesc("timer_getoverrun", unimplementedFunc), + /* 418 */ SyscallDesc("timer_delete", unimplementedFunc), + /* 419 */ SyscallDesc("clock_settime", unimplementedFunc), + /* 420 */ SyscallDesc("clock_gettime", unimplementedFunc), + /* 421 */ SyscallDesc("clock_getres", unimplementedFunc), + /* 422 */ SyscallDesc("clock_nanosleep", unimplementedFunc), + /* 423 */ SyscallDesc("semtimedop", unimplementedFunc), + /* 424 */ SyscallDesc("tgkill", unimplementedFunc), + /* 425 */ SyscallDesc("stat64", unimplementedFunc), + /* 426 */ SyscallDesc("lstat64", lstat64Func), + /* 427 */ SyscallDesc("fstat64", fstat64Func), + /* 428 */ SyscallDesc("vserver", unimplementedFunc), + /* 429 */ SyscallDesc("mbind", unimplementedFunc), + /* 430 */ SyscallDesc("get_mempolicy", unimplementedFunc), + /* 431 */ SyscallDesc("set_mempolicy", unimplementedFunc), + /* 432 */ SyscallDesc("mq_open", unimplementedFunc), + /* 433 */ SyscallDesc("mq_unlink", unimplementedFunc), + /* 434 */ SyscallDesc("mq_timedsend", unimplementedFunc), + /* 435 */ SyscallDesc("mq_timedreceive", unimplementedFunc), + /* 436 */ SyscallDesc("mq_notify", unimplementedFunc), + /* 437 */ SyscallDesc("mq_getsetattr", unimplementedFunc), + /* 438 */ SyscallDesc("waitid", unimplementedFunc), + /* 439 */ SyscallDesc("add_key", unimplementedFunc), + /* 440 */ SyscallDesc("request_key", unimplementedFunc), + /* 441 */ SyscallDesc("keyctl", unimplementedFunc) +}; + +AlphaLinuxProcess::AlphaLinuxProcess(const std::string &name, + ObjectFile *objFile, + int stdin_fd, + int stdout_fd, + int stderr_fd, + std::vector &argv, + std::vector &envp) + : LiveProcess(name, objFile, stdin_fd, stdout_fd, stderr_fd, argv, envp), + Num_Syscall_Descs(sizeof(syscallDescs) / sizeof(SyscallDesc)) +{ + init_regs->intRegFile[0] = 0; +} + + + +SyscallDesc* +AlphaLinuxProcess::getDesc(int callnum) +{ + if (callnum < 0 || callnum > Num_Syscall_Descs) + return NULL; + return &syscallDescs[callnum]; +} diff --git a/arch/sparc/linux_process.hh b/arch/sparc/linux_process.hh new file mode 100644 index 000000000..7de1b1ac1 --- /dev/null +++ b/arch/sparc/linux_process.hh @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2003-2004 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 __ALPHA_LINUX_PROCESS_HH__ +#define __ALPHA_LINUX_PROCESS_HH__ + +#include "sim/process.hh" + + +/// A process with emulated Alpha/Linux syscalls. +class AlphaLinuxProcess : public LiveProcess +{ + public: + /// Constructor. + AlphaLinuxProcess(const std::string &name, + ObjectFile *objFile, + int stdin_fd, int stdout_fd, int stderr_fd, + std::vector &argv, + std::vector &envp); + + virtual SyscallDesc* getDesc(int callnum); + + /// The target system's hostname. + static const char *hostname; + + /// Array of syscall descriptors, indexed by call number. + static SyscallDesc syscallDescs[]; + + const int Num_Syscall_Descs; +}; + + +#endif // __ALPHA_LINUX_PROCESS_HH__ From 1cfc27742448ab0e364d2f7ffc7460d90714a6d2 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 1 Mar 2006 05:21:16 -0500 Subject: [PATCH 133/180] Removed the targetarch code. --HG-- extra : convert_revision : ab0c8ed2e8d7359b353f34b443e84094ca40c5e6 --- SConscript | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/SConscript b/SConscript index 540876699..51836b0be 100644 --- a/SConscript +++ b/SConscript @@ -300,29 +300,6 @@ syscall_emulation_sources = Split(''' sim/syscall_emul.cc ''') -# The following stuff (targetarch code and global define of THE_ISA) -# are legacy things that assume we're only compiling one ISA at a -# time. These will have to go away if we want to build a binary that -# supports multiple ISAs. - -#targetarch_files = Split(''' -# alpha_linux_process.hh -# alpha_memory.hh -# alpha_tru64_process.hh -# aout_machdep.h -# arguments.hh -# ecoff_machdep.h -# ev5.hh -# faults.hh -# stacktrace.hh -# vtophys.hh -# ''') - -# Set up bridging headers to the architecture specific versions -#for f in targetarch_files: -# env.Command('targetarch/' + f, 'arch/%s/%s' % (env['TARGET_ISA'], f), -# '''echo '#include "arch/%s/%s"' > $TARGET''' % (env['TARGET_ISA'], f)) - # Add a flag defining what THE_ISA should be for all compilation env.Append(CPPDEFINES=[('THE_ISA','%s_ISA' % env['TARGET_ISA'].upper())]) From 2eff368dd03c93a503e13ab82cf4c4abb0c06aa9 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 1 Mar 2006 05:26:08 -0500 Subject: [PATCH 134/180] Cleaned up some of the Fault system. arch/alpha/ev5.cc: Commented out the intr_post function since it's not used. If this really -is- needed, it should be moved into the fault class. arch/alpha/faults.cc: arch/alpha/faults.hh: Moved the fault invocation code into the fault class fully, and got rid of the need for isA. cpu/exec_context.cc: cpu/exec_context.hh: Removed the trap function from the ExecContext. The faults will execute normally in full system mode, but always panic in syscall emulation mode. cpu/ozone/cpu.hh: cpu/simple/cpu.hh: Changed the execution context executing a fault to a fault executing on the execution context. sim/faults.cc: If not in full system mode, trying to invoke a fault causes a panic. sim/faults.hh: Removed the isA function. --HG-- extra : convert_revision : 894dc8f0755c8efc4b7ef5a09fb2cf7373042395 --- arch/alpha/ev5.cc | 4 ++-- arch/alpha/faults.cc | 24 +++++++++++++++++++----- arch/alpha/faults.hh | 10 ++++++++++ cpu/exec_context.cc | 12 ------------ cpu/exec_context.hh | 9 --------- cpu/ozone/cpu.hh | 2 +- cpu/simple/cpu.hh | 2 +- sim/faults.cc | 7 +++++++ sim/faults.hh | 6 ++++-- 9 files changed, 44 insertions(+), 32 deletions(-) diff --git a/arch/alpha/ev5.cc b/arch/alpha/ev5.cc index ac0e7e67e..c6da628be 100644 --- a/arch/alpha/ev5.cc +++ b/arch/alpha/ev5.cc @@ -166,7 +166,7 @@ AlphaISA::zeroRegisters(CPU *cpu) void AlphaISA::intr_post(RegFile *regs, Fault fault, Addr pc) { - bool use_pc = (fault == NoFault); +/* bool use_pc = (fault == NoFault); if (fault->isA()) panic("arithmetic faults NYI..."); @@ -186,7 +186,7 @@ AlphaISA::intr_post(RegFile *regs, Fault fault, Addr pc) (dynamic_cast(fault.get()))->vect(); else regs->npc = regs->miscRegs.readReg(IPR_PAL_BASE) + pc; - +*/ // that's it! (orders of magnitude less painful than x86) } diff --git a/arch/alpha/faults.cc b/arch/alpha/faults.cc index bde7b3db1..7cdcc9bab 100644 --- a/arch/alpha/faults.cc +++ b/arch/alpha/faults.cc @@ -107,14 +107,11 @@ void AlphaFault::invoke(ExecContext * xc) assert(!xc->misspeculating()); xc->kernelStats->fault(this); - if (isA()) - panic("Arithmetic traps are unimplemented!"); - // exception restart address - if (!isA() || !xc->inPalMode()) + if (setRestartAddress() || !xc->inPalMode()) xc->setMiscReg(AlphaISA::IPR_EXC_ADDR, xc->regs.pc); - if (isA() || isA()) { + if (skipFaultingInstruction()) { // traps... skip faulting instruction. xc->setMiscReg(AlphaISA::IPR_EXC_ADDR, xc->readMiscReg(AlphaISA::IPR_EXC_ADDR) + 4); @@ -127,6 +124,23 @@ void AlphaFault::invoke(ExecContext * xc) xc->regs.npc = xc->regs.pc + sizeof(MachInst); } +void ArithmeticFault::invoke(ExecContext * xc) +{ + DPRINTF(Fault, "Fault %s at PC: %#x\n", name(), xc->regs.pc); + xc->cpu->recordEvent(csprintf("Fault %s", name())); + + assert(!xc->misspeculating()); + xc->kernelStats->fault(this); + + panic("Arithmetic traps are unimplemented!"); +} + + +/*void ArithmeticFault::invoke(ExecContext * xc) +{ + panic("Arithmetic traps are unimplemented!"); +}*/ + #endif } // namespace AlphaISA diff --git a/arch/alpha/faults.hh b/arch/alpha/faults.hh index c0316288c..b9573905a 100644 --- a/arch/alpha/faults.hh +++ b/arch/alpha/faults.hh @@ -40,6 +40,9 @@ typedef const Addr FaultVect; class AlphaFault : public virtual FaultBase { + protected: + virtual bool skipFaultingInstruction() {return false;} + virtual bool setRestartAddress() {return true;} public: #if FULL_SYSTEM void invoke(ExecContext * xc); @@ -95,6 +98,8 @@ class ResetFault : public AlphaFault class ArithmeticFault : public AlphaFault { + protected: + bool skipFaultingInstruction() {return true;} private: static FaultName _name; static FaultVect _vect; @@ -103,10 +108,13 @@ class ArithmeticFault : public AlphaFault FaultName name() {return _name;} FaultVect vect() {return _vect;} FaultStat & stat() {return _stat;} + void invoke(ExecContext * xc); }; class InterruptFault : public AlphaFault { + protected: + bool setRestartAddress() {return false;} private: static FaultName _name; static FaultVect _vect; @@ -227,6 +235,8 @@ class FloatEnableFault : public AlphaFault class PalFault : public AlphaFault { + protected: + bool skipFaultingInstruction() {return true;} private: static FaultName _name; static FaultVect _vect; diff --git a/cpu/exec_context.cc b/cpu/exec_context.cc index 0e787a547..9b6ff427b 100644 --- a/cpu/exec_context.cc +++ b/cpu/exec_context.cc @@ -220,15 +220,3 @@ ExecContext::regStats(const string &name) #endif } -void -ExecContext::trap(Fault fault) -{ - //TheISA::trap(fault); //One possible way to do it... - - /** @todo: Going to hack it for now. Do a true fixup later. */ -#if FULL_SYSTEM - fault->invoke(this); -#else - fatal("fault (%d) detected @ PC 0x%08p", fault, readPC()); -#endif -} diff --git a/cpu/exec_context.hh b/cpu/exec_context.hh index 7ab8c589e..033d3d30a 100644 --- a/cpu/exec_context.hh +++ b/cpu/exec_context.hh @@ -427,18 +427,9 @@ class ExecContext void setIntrFlag(int val) { regs.intrflag = val; } Fault hwrei(); bool inPalMode() { return AlphaISA::PcPAL(regs.pc); } - void ev5_temp_trap(Fault fault); bool simPalCheck(int palFunc); #endif - /** Meant to be more generic trap function to be - * called when an instruction faults. - * @param fault The fault generated by executing the instruction. - * @todo How to do this properly so it's dependent upon ISA only? - */ - - void trap(Fault fault); - #if !FULL_SYSTEM TheISA::IntReg getSyscallArg(int i) { diff --git a/cpu/ozone/cpu.hh b/cpu/ozone/cpu.hh index 667e2b3f8..f5d84d656 100644 --- a/cpu/ozone/cpu.hh +++ b/cpu/ozone/cpu.hh @@ -517,7 +517,7 @@ class OoOCPU : public BaseCPU int readIntrFlag() { return xc->readIntrFlag(); } void setIntrFlag(int val) { xc->setIntrFlag(val); } bool inPalMode() { return xc->inPalMode(); } - void ev5_trap(Fault fault) { xc->ev5_trap(fault); } + void trap(Fault fault) { fault->invoke(xc); } bool simPalCheck(int palFunc) { return xc->simPalCheck(palFunc); } #else void syscall() { xc->syscall(); } diff --git a/cpu/simple/cpu.hh b/cpu/simple/cpu.hh index 8396937a8..0b8d84e53 100644 --- a/cpu/simple/cpu.hh +++ b/cpu/simple/cpu.hh @@ -347,7 +347,7 @@ class SimpleCPU : public BaseCPU int readIntrFlag() { return xc->readIntrFlag(); } void setIntrFlag(int val) { xc->setIntrFlag(val); } bool inPalMode() { return xc->inPalMode(); } - void ev5_trap(Fault fault) { fault->invoke(xc); } + void trap(Fault fault) { fault->invoke(xc); } bool simPalCheck(int palFunc) { return xc->simPalCheck(palFunc); } #else void syscall() { xc->syscall(); } diff --git a/sim/faults.cc b/sim/faults.cc index 78bfc8092..68df2b785 100644 --- a/sim/faults.cc +++ b/sim/faults.cc @@ -27,7 +27,14 @@ */ #include "sim/faults.hh" +#include "cpu/exec_context.hh" FaultName MachineCheckFault::_name = "mchk"; FaultName AlignmentFault::_name = "unalign"; +#if !FULL_SYSTEM +void FaultBase::invoke(ExecContext * xc) +{ + fatal("fault (%s) detected @ PC 0x%08p", name(), xc->readPC()); +} +#endif diff --git a/sim/faults.hh b/sim/faults.hh index 6a786fe26..1e43bfb82 100644 --- a/sim/faults.hh +++ b/sim/faults.hh @@ -54,9 +54,11 @@ class FaultBase : public RefCounted virtual FaultStat & stat() = 0; #if FULL_SYSTEM virtual void invoke(ExecContext * xc) = 0; +#else + virtual void invoke(ExecContext * xc); #endif - template - bool isA() {return dynamic_cast(this);} +// template +// bool isA() {return dynamic_cast(this);} virtual bool isMachineCheckFault() {return false;} virtual bool isAlignmentFault() {return false;} }; From b71f9c801eb869b477a1e5a6f12498862efbb886 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 1 Mar 2006 05:28:26 -0500 Subject: [PATCH 135/180] Begain setting up syscall emulation for sparc linux. arch/sparc/linux_process.cc: Began modifying this file for sparc, and replaced the alpha syscall numbers with the sparc ones. arch/sparc/linux_process.hh: Begain modifying this file for sparc. --HG-- extra : convert_revision : b1ed8ac50a35591521c5feaf1ea9c4b8ccc26dc8 --- arch/sparc/linux_process.cc | 741 ++++++++++++++---------------------- arch/sparc/linux_process.hh | 10 +- 2 files changed, 295 insertions(+), 456 deletions(-) diff --git a/arch/sparc/linux_process.cc b/arch/sparc/linux_process.cc index 0b193fb55..14b3d1505 100644 --- a/arch/sparc/linux_process.cc +++ b/arch/sparc/linux_process.cc @@ -26,9 +26,9 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "arch/alpha/common_syscall_emul.hh" -#include "arch/alpha/linux_process.hh" -#include "arch/alpha/isa_traits.hh" +#include "arch/sparc/common_syscall_emul.hh" +#include "arch/sparc/linux_process.hh" +#include "arch/sparc/isa_traits.hh" #include "base/trace.hh" #include "cpu/exec_context.hh" @@ -39,7 +39,7 @@ #include "sim/syscall_emul.hh" using namespace std; -using namespace AlphaISA; +using namespace SPARCISA; /// Target pipe() handler. Even though this is a generic Posix call, /// the Alpha return convention is funky, so that makes it @@ -141,455 +141,294 @@ osf_setsysinfoFunc(SyscallDesc *desc, int callnum, Process *process, } -SyscallDesc AlphaLinuxProcess::syscallDescs[] = { - /* 0 */ SyscallDesc("osf_syscall", unimplementedFunc), - /* 1 */ SyscallDesc("exit", exitFunc), - /* 2 */ SyscallDesc("fork", unimplementedFunc), - /* 3 */ SyscallDesc("read", readFunc), - /* 4 */ SyscallDesc("write", writeFunc), - /* 5 */ SyscallDesc("osf_old_open", unimplementedFunc), - /* 6 */ SyscallDesc("close", closeFunc), - /* 7 */ SyscallDesc("osf_wait4", unimplementedFunc), - /* 8 */ SyscallDesc("osf_old_creat", unimplementedFunc), - /* 9 */ SyscallDesc("link", unimplementedFunc), - /* 10 */ SyscallDesc("unlink", unlinkFunc), - /* 11 */ SyscallDesc("osf_execve", unimplementedFunc), - /* 12 */ SyscallDesc("chdir", unimplementedFunc), - /* 13 */ SyscallDesc("fchdir", unimplementedFunc), - /* 14 */ SyscallDesc("mknod", unimplementedFunc), - /* 15 */ SyscallDesc("chmod", chmodFunc), - /* 16 */ SyscallDesc("chown", chownFunc), - /* 17 */ SyscallDesc("brk", obreakFunc), - /* 18 */ SyscallDesc("osf_getfsstat", unimplementedFunc), - /* 19 */ SyscallDesc("lseek", lseekFunc), - /* 20 */ SyscallDesc("getxpid", getpidFunc), - /* 21 */ SyscallDesc("osf_mount", unimplementedFunc), - /* 22 */ SyscallDesc("umount", unimplementedFunc), - /* 23 */ SyscallDesc("setuid", setuidFunc), - /* 24 */ SyscallDesc("getxuid", getuidFunc), - /* 25 */ SyscallDesc("exec_with_loader", unimplementedFunc), - /* 26 */ SyscallDesc("osf_ptrace", unimplementedFunc), - /* 27 */ SyscallDesc("osf_nrecvmsg", unimplementedFunc), - /* 28 */ SyscallDesc("osf_nsendmsg", unimplementedFunc), - /* 29 */ SyscallDesc("osf_nrecvfrom", unimplementedFunc), - /* 30 */ SyscallDesc("osf_naccept", unimplementedFunc), - /* 31 */ SyscallDesc("osf_ngetpeername", unimplementedFunc), - /* 32 */ SyscallDesc("osf_ngetsockname", unimplementedFunc), - /* 33 */ SyscallDesc("access", unimplementedFunc), - /* 34 */ SyscallDesc("osf_chflags", unimplementedFunc), - /* 35 */ SyscallDesc("osf_fchflags", unimplementedFunc), - /* 36 */ SyscallDesc("sync", unimplementedFunc), - /* 37 */ SyscallDesc("kill", unimplementedFunc), - /* 38 */ SyscallDesc("osf_old_stat", unimplementedFunc), - /* 39 */ SyscallDesc("setpgid", unimplementedFunc), - /* 40 */ SyscallDesc("osf_old_lstat", unimplementedFunc), - /* 41 */ SyscallDesc("dup", unimplementedFunc), - /* 42 */ SyscallDesc("pipe", pipeFunc), - /* 43 */ SyscallDesc("osf_set_program_attributes", unimplementedFunc), - /* 44 */ SyscallDesc("osf_profil", unimplementedFunc), - /* 45 */ SyscallDesc("open", openFunc), - /* 46 */ SyscallDesc("osf_old_sigaction", unimplementedFunc), - /* 47 */ SyscallDesc("getxgid", getgidFunc), - /* 48 */ SyscallDesc("osf_sigprocmask", ignoreFunc), - /* 49 */ SyscallDesc("osf_getlogin", unimplementedFunc), - /* 50 */ SyscallDesc("osf_setlogin", unimplementedFunc), - /* 51 */ SyscallDesc("acct", unimplementedFunc), - /* 52 */ SyscallDesc("sigpending", unimplementedFunc), - /* 53 */ SyscallDesc("osf_classcntl", unimplementedFunc), - /* 54 */ SyscallDesc("ioctl", ioctlFunc), - /* 55 */ SyscallDesc("osf_reboot", unimplementedFunc), - /* 56 */ SyscallDesc("osf_revoke", unimplementedFunc), - /* 57 */ SyscallDesc("symlink", unimplementedFunc), - /* 58 */ SyscallDesc("readlink", unimplementedFunc), - /* 59 */ SyscallDesc("execve", unimplementedFunc), - /* 60 */ SyscallDesc("umask", unimplementedFunc), - /* 61 */ SyscallDesc("chroot", unimplementedFunc), - /* 62 */ SyscallDesc("osf_old_fstat", unimplementedFunc), - /* 63 */ SyscallDesc("getpgrp", unimplementedFunc), - /* 64 */ SyscallDesc("getpagesize", getpagesizeFunc), - /* 65 */ SyscallDesc("osf_mremap", unimplementedFunc), - /* 66 */ SyscallDesc("vfork", unimplementedFunc), - /* 67 */ SyscallDesc("stat", statFunc), - /* 68 */ SyscallDesc("lstat", lstatFunc), - /* 69 */ SyscallDesc("osf_sbrk", unimplementedFunc), - /* 70 */ SyscallDesc("osf_sstk", unimplementedFunc), - /* 71 */ SyscallDesc("mmap", mmapFunc), - /* 72 */ SyscallDesc("osf_old_vadvise", unimplementedFunc), - /* 73 */ SyscallDesc("munmap", munmapFunc), - /* 74 */ SyscallDesc("mprotect", ignoreFunc), - /* 75 */ SyscallDesc("madvise", unimplementedFunc), - /* 76 */ SyscallDesc("vhangup", unimplementedFunc), - /* 77 */ SyscallDesc("osf_kmodcall", unimplementedFunc), - /* 78 */ SyscallDesc("osf_mincore", unimplementedFunc), - /* 79 */ SyscallDesc("getgroups", unimplementedFunc), - /* 80 */ SyscallDesc("setgroups", unimplementedFunc), - /* 81 */ SyscallDesc("osf_old_getpgrp", unimplementedFunc), - /* 82 */ SyscallDesc("setpgrp", unimplementedFunc), - /* 83 */ SyscallDesc("osf_setitimer", unimplementedFunc), - /* 84 */ SyscallDesc("osf_old_wait", unimplementedFunc), - /* 85 */ SyscallDesc("osf_table", unimplementedFunc), - /* 86 */ SyscallDesc("osf_getitimer", unimplementedFunc), - /* 87 */ SyscallDesc("gethostname", gethostnameFunc), - /* 88 */ SyscallDesc("sethostname", unimplementedFunc), - /* 89 */ SyscallDesc("getdtablesize", unimplementedFunc), - /* 90 */ SyscallDesc("dup2", unimplementedFunc), - /* 91 */ SyscallDesc("fstat", fstatFunc), - /* 92 */ SyscallDesc("fcntl", fcntlFunc), - /* 93 */ SyscallDesc("osf_select", unimplementedFunc), - /* 94 */ SyscallDesc("poll", unimplementedFunc), - /* 95 */ SyscallDesc("fsync", unimplementedFunc), - /* 96 */ SyscallDesc("setpriority", unimplementedFunc), - /* 97 */ SyscallDesc("socket", unimplementedFunc), - /* 98 */ SyscallDesc("connect", unimplementedFunc), - /* 99 */ SyscallDesc("accept", unimplementedFunc), - /* 100 */ SyscallDesc("getpriority", unimplementedFunc), - /* 101 */ SyscallDesc("send", unimplementedFunc), - /* 102 */ SyscallDesc("recv", unimplementedFunc), - /* 103 */ SyscallDesc("sigreturn", unimplementedFunc), - /* 104 */ SyscallDesc("bind", unimplementedFunc), - /* 105 */ SyscallDesc("setsockopt", unimplementedFunc), - /* 106 */ SyscallDesc("listen", unimplementedFunc), - /* 107 */ SyscallDesc("osf_plock", unimplementedFunc), - /* 108 */ SyscallDesc("osf_old_sigvec", unimplementedFunc), - /* 109 */ SyscallDesc("osf_old_sigblock", unimplementedFunc), - /* 110 */ SyscallDesc("osf_old_sigsetmask", unimplementedFunc), - /* 111 */ SyscallDesc("sigsuspend", unimplementedFunc), - /* 112 */ SyscallDesc("osf_sigstack", ignoreFunc), - /* 113 */ SyscallDesc("recvmsg", unimplementedFunc), - /* 114 */ SyscallDesc("sendmsg", unimplementedFunc), - /* 115 */ SyscallDesc("osf_old_vtrace", unimplementedFunc), - /* 116 */ SyscallDesc("osf_gettimeofday", unimplementedFunc), - /* 117 */ SyscallDesc("osf_getrusage", unimplementedFunc), - /* 118 */ SyscallDesc("getsockopt", unimplementedFunc), - /* 119 */ SyscallDesc("numa_syscalls", unimplementedFunc), - /* 120 */ SyscallDesc("readv", unimplementedFunc), - /* 121 */ SyscallDesc("writev", writevFunc), - /* 122 */ SyscallDesc("osf_settimeofday", unimplementedFunc), - /* 123 */ SyscallDesc("fchown", fchownFunc), - /* 124 */ SyscallDesc("fchmod", fchmodFunc), - /* 125 */ SyscallDesc("recvfrom", unimplementedFunc), - /* 126 */ SyscallDesc("setreuid", unimplementedFunc), - /* 127 */ SyscallDesc("setregid", unimplementedFunc), - /* 128 */ SyscallDesc("rename", renameFunc), - /* 129 */ SyscallDesc("truncate", unimplementedFunc), - /* 130 */ SyscallDesc("ftruncate", unimplementedFunc), - /* 131 */ SyscallDesc("flock", unimplementedFunc), - /* 132 */ SyscallDesc("setgid", unimplementedFunc), - /* 133 */ SyscallDesc("sendto", unimplementedFunc), - /* 134 */ SyscallDesc("shutdown", unimplementedFunc), - /* 135 */ SyscallDesc("socketpair", unimplementedFunc), - /* 136 */ SyscallDesc("mkdir", unimplementedFunc), - /* 137 */ SyscallDesc("rmdir", unimplementedFunc), - /* 138 */ SyscallDesc("osf_utimes", unimplementedFunc), - /* 139 */ SyscallDesc("osf_old_sigreturn", unimplementedFunc), - /* 140 */ SyscallDesc("osf_adjtime", unimplementedFunc), - /* 141 */ SyscallDesc("getpeername", unimplementedFunc), - /* 142 */ SyscallDesc("osf_gethostid", unimplementedFunc), - /* 143 */ SyscallDesc("osf_sethostid", unimplementedFunc), - /* 144 */ SyscallDesc("getrlimit", getrlimitFunc), - /* 145 */ SyscallDesc("setrlimit", ignoreFunc), - /* 146 */ SyscallDesc("osf_old_killpg", unimplementedFunc), - /* 147 */ SyscallDesc("setsid", unimplementedFunc), - /* 148 */ SyscallDesc("quotactl", unimplementedFunc), - /* 149 */ SyscallDesc("osf_oldquota", unimplementedFunc), - /* 150 */ SyscallDesc("getsockname", unimplementedFunc), - /* 151 */ SyscallDesc("osf_pread", unimplementedFunc), - /* 152 */ SyscallDesc("osf_pwrite", unimplementedFunc), - /* 153 */ SyscallDesc("osf_pid_block", unimplementedFunc), - /* 154 */ SyscallDesc("osf_pid_unblock", unimplementedFunc), - /* 155 */ SyscallDesc("osf_signal_urti", unimplementedFunc), - /* 156 */ SyscallDesc("sigaction", ignoreFunc), - /* 157 */ SyscallDesc("osf_sigwaitprim", unimplementedFunc), - /* 158 */ SyscallDesc("osf_nfssvc", unimplementedFunc), - /* 159 */ SyscallDesc("osf_getdirentries", unimplementedFunc), - /* 160 */ SyscallDesc("osf_statfs", unimplementedFunc), - /* 161 */ SyscallDesc("osf_fstatfs", unimplementedFunc), - /* 162 */ SyscallDesc("unknown #162", unimplementedFunc), - /* 163 */ SyscallDesc("osf_async_daemon", unimplementedFunc), - /* 164 */ SyscallDesc("osf_getfh", unimplementedFunc), - /* 165 */ SyscallDesc("osf_getdomainname", unimplementedFunc), - /* 166 */ SyscallDesc("setdomainname", unimplementedFunc), - /* 167 */ SyscallDesc("unknown #167", unimplementedFunc), - /* 168 */ SyscallDesc("unknown #168", unimplementedFunc), - /* 169 */ SyscallDesc("osf_exportfs", unimplementedFunc), - /* 170 */ SyscallDesc("unknown #170", unimplementedFunc), - /* 171 */ SyscallDesc("unknown #171", unimplementedFunc), - /* 172 */ SyscallDesc("unknown #172", unimplementedFunc), - /* 173 */ SyscallDesc("unknown #173", unimplementedFunc), - /* 174 */ SyscallDesc("unknown #174", unimplementedFunc), - /* 175 */ SyscallDesc("unknown #175", unimplementedFunc), - /* 176 */ SyscallDesc("unknown #176", unimplementedFunc), - /* 177 */ SyscallDesc("unknown #177", unimplementedFunc), - /* 178 */ SyscallDesc("unknown #178", unimplementedFunc), - /* 179 */ SyscallDesc("unknown #179", unimplementedFunc), - /* 180 */ SyscallDesc("unknown #180", unimplementedFunc), - /* 181 */ SyscallDesc("osf_alt_plock", unimplementedFunc), - /* 182 */ SyscallDesc("unknown #182", unimplementedFunc), - /* 183 */ SyscallDesc("unknown #183", unimplementedFunc), - /* 184 */ SyscallDesc("osf_getmnt", unimplementedFunc), - /* 185 */ SyscallDesc("unknown #185", unimplementedFunc), - /* 186 */ SyscallDesc("unknown #186", unimplementedFunc), - /* 187 */ SyscallDesc("osf_alt_sigpending", unimplementedFunc), - /* 188 */ SyscallDesc("osf_alt_setsid", unimplementedFunc), - /* 189 */ SyscallDesc("unknown #189", unimplementedFunc), - /* 190 */ SyscallDesc("unknown #190", unimplementedFunc), - /* 191 */ SyscallDesc("unknown #191", unimplementedFunc), - /* 192 */ SyscallDesc("unknown #192", unimplementedFunc), - /* 193 */ SyscallDesc("unknown #193", unimplementedFunc), - /* 194 */ SyscallDesc("unknown #194", unimplementedFunc), - /* 195 */ SyscallDesc("unknown #195", unimplementedFunc), - /* 196 */ SyscallDesc("unknown #196", unimplementedFunc), - /* 197 */ SyscallDesc("unknown #197", unimplementedFunc), - /* 198 */ SyscallDesc("unknown #198", unimplementedFunc), - /* 199 */ SyscallDesc("osf_swapon", unimplementedFunc), - /* 200 */ SyscallDesc("msgctl", unimplementedFunc), - /* 201 */ SyscallDesc("msgget", unimplementedFunc), - /* 202 */ SyscallDesc("msgrcv", unimplementedFunc), - /* 203 */ SyscallDesc("msgsnd", unimplementedFunc), - /* 204 */ SyscallDesc("semctl", unimplementedFunc), - /* 205 */ SyscallDesc("semget", unimplementedFunc), - /* 206 */ SyscallDesc("semop", unimplementedFunc), - /* 207 */ SyscallDesc("osf_utsname", unimplementedFunc), - /* 208 */ SyscallDesc("lchown", unimplementedFunc), - /* 209 */ SyscallDesc("osf_shmat", unimplementedFunc), - /* 210 */ SyscallDesc("shmctl", unimplementedFunc), - /* 211 */ SyscallDesc("shmdt", unimplementedFunc), - /* 212 */ SyscallDesc("shmget", unimplementedFunc), - /* 213 */ SyscallDesc("osf_mvalid", unimplementedFunc), - /* 214 */ SyscallDesc("osf_getaddressconf", unimplementedFunc), - /* 215 */ SyscallDesc("osf_msleep", unimplementedFunc), - /* 216 */ SyscallDesc("osf_mwakeup", unimplementedFunc), - /* 217 */ SyscallDesc("msync", unimplementedFunc), - /* 218 */ SyscallDesc("osf_signal", unimplementedFunc), - /* 219 */ SyscallDesc("osf_utc_gettime", unimplementedFunc), - /* 220 */ SyscallDesc("osf_utc_adjtime", unimplementedFunc), - /* 221 */ SyscallDesc("unknown #221", unimplementedFunc), - /* 222 */ SyscallDesc("osf_security", unimplementedFunc), - /* 223 */ SyscallDesc("osf_kloadcall", unimplementedFunc), - /* 224 */ SyscallDesc("unknown #224", unimplementedFunc), - /* 225 */ SyscallDesc("unknown #225", unimplementedFunc), - /* 226 */ SyscallDesc("unknown #226", unimplementedFunc), - /* 227 */ SyscallDesc("unknown #227", unimplementedFunc), - /* 228 */ SyscallDesc("unknown #228", unimplementedFunc), - /* 229 */ SyscallDesc("unknown #229", unimplementedFunc), - /* 230 */ SyscallDesc("unknown #230", unimplementedFunc), - /* 231 */ SyscallDesc("unknown #231", unimplementedFunc), - /* 232 */ SyscallDesc("unknown #232", unimplementedFunc), - /* 233 */ SyscallDesc("getpgid", unimplementedFunc), - /* 234 */ SyscallDesc("getsid", unimplementedFunc), - /* 235 */ SyscallDesc("sigaltstack", ignoreFunc), - /* 236 */ SyscallDesc("osf_waitid", unimplementedFunc), - /* 237 */ SyscallDesc("osf_priocntlset", unimplementedFunc), - /* 238 */ SyscallDesc("osf_sigsendset", unimplementedFunc), - /* 239 */ SyscallDesc("osf_set_speculative", unimplementedFunc), - /* 240 */ SyscallDesc("osf_msfs_syscall", unimplementedFunc), - /* 241 */ SyscallDesc("osf_sysinfo", unimplementedFunc), - /* 242 */ SyscallDesc("osf_uadmin", unimplementedFunc), - /* 243 */ SyscallDesc("osf_fuser", unimplementedFunc), - /* 244 */ SyscallDesc("osf_proplist_syscall", unimplementedFunc), - /* 245 */ SyscallDesc("osf_ntp_adjtime", unimplementedFunc), - /* 246 */ SyscallDesc("osf_ntp_gettime", unimplementedFunc), - /* 247 */ SyscallDesc("osf_pathconf", unimplementedFunc), - /* 248 */ SyscallDesc("osf_fpathconf", unimplementedFunc), - /* 249 */ SyscallDesc("unknown #249", unimplementedFunc), - /* 250 */ SyscallDesc("osf_uswitch", unimplementedFunc), - /* 251 */ SyscallDesc("osf_usleep_thread", unimplementedFunc), - /* 252 */ SyscallDesc("osf_audcntl", unimplementedFunc), - /* 253 */ SyscallDesc("osf_audgen", unimplementedFunc), - /* 254 */ SyscallDesc("sysfs", unimplementedFunc), - /* 255 */ SyscallDesc("osf_subsys_info", unimplementedFunc), - /* 256 */ SyscallDesc("osf_getsysinfo", osf_getsysinfoFunc), - /* 257 */ SyscallDesc("osf_setsysinfo", osf_setsysinfoFunc), - /* 258 */ SyscallDesc("osf_afs_syscall", unimplementedFunc), - /* 259 */ SyscallDesc("osf_swapctl", unimplementedFunc), - /* 260 */ SyscallDesc("osf_memcntl", unimplementedFunc), - /* 261 */ SyscallDesc("osf_fdatasync", unimplementedFunc), - /* 262 */ SyscallDesc("unknown #262", unimplementedFunc), - /* 263 */ SyscallDesc("unknown #263", unimplementedFunc), - /* 264 */ SyscallDesc("unknown #264", unimplementedFunc), - /* 265 */ SyscallDesc("unknown #265", unimplementedFunc), - /* 266 */ SyscallDesc("unknown #266", unimplementedFunc), - /* 267 */ SyscallDesc("unknown #267", unimplementedFunc), - /* 268 */ SyscallDesc("unknown #268", unimplementedFunc), - /* 269 */ SyscallDesc("unknown #269", unimplementedFunc), - /* 270 */ SyscallDesc("unknown #270", unimplementedFunc), - /* 271 */ SyscallDesc("unknown #271", unimplementedFunc), - /* 272 */ SyscallDesc("unknown #272", unimplementedFunc), - /* 273 */ SyscallDesc("unknown #273", unimplementedFunc), - /* 274 */ SyscallDesc("unknown #274", unimplementedFunc), - /* 275 */ SyscallDesc("unknown #275", unimplementedFunc), - /* 276 */ SyscallDesc("unknown #276", unimplementedFunc), - /* 277 */ SyscallDesc("unknown #277", unimplementedFunc), - /* 278 */ SyscallDesc("unknown #278", unimplementedFunc), - /* 279 */ SyscallDesc("unknown #279", unimplementedFunc), - /* 280 */ SyscallDesc("unknown #280", unimplementedFunc), - /* 281 */ SyscallDesc("unknown #281", unimplementedFunc), - /* 282 */ SyscallDesc("unknown #282", unimplementedFunc), - /* 283 */ SyscallDesc("unknown #283", unimplementedFunc), - /* 284 */ SyscallDesc("unknown #284", unimplementedFunc), - /* 285 */ SyscallDesc("unknown #285", unimplementedFunc), - /* 286 */ SyscallDesc("unknown #286", unimplementedFunc), - /* 287 */ SyscallDesc("unknown #287", unimplementedFunc), - /* 288 */ SyscallDesc("unknown #288", unimplementedFunc), - /* 289 */ SyscallDesc("unknown #289", unimplementedFunc), - /* 290 */ SyscallDesc("unknown #290", unimplementedFunc), - /* 291 */ SyscallDesc("unknown #291", unimplementedFunc), - /* 292 */ SyscallDesc("unknown #292", unimplementedFunc), - /* 293 */ SyscallDesc("unknown #293", unimplementedFunc), - /* 294 */ SyscallDesc("unknown #294", unimplementedFunc), - /* 295 */ SyscallDesc("unknown #295", unimplementedFunc), - /* 296 */ SyscallDesc("unknown #296", unimplementedFunc), - /* 297 */ SyscallDesc("unknown #297", unimplementedFunc), - /* 298 */ SyscallDesc("unknown #298", unimplementedFunc), - /* 299 */ SyscallDesc("unknown #299", unimplementedFunc), -/* - * Linux-specific system calls begin at 300 - */ - /* 300 */ SyscallDesc("bdflush", unimplementedFunc), - /* 301 */ SyscallDesc("sethae", unimplementedFunc), - /* 302 */ SyscallDesc("mount", unimplementedFunc), - /* 303 */ SyscallDesc("old_adjtimex", unimplementedFunc), - /* 304 */ SyscallDesc("swapoff", unimplementedFunc), - /* 305 */ SyscallDesc("getdents", unimplementedFunc), - /* 306 */ SyscallDesc("create_module", unimplementedFunc), - /* 307 */ SyscallDesc("init_module", unimplementedFunc), - /* 308 */ SyscallDesc("delete_module", unimplementedFunc), - /* 309 */ SyscallDesc("get_kernel_syms", unimplementedFunc), - /* 310 */ SyscallDesc("syslog", unimplementedFunc), - /* 311 */ SyscallDesc("reboot", unimplementedFunc), - /* 312 */ SyscallDesc("clone", unimplementedFunc), - /* 313 */ SyscallDesc("uselib", unimplementedFunc), - /* 314 */ SyscallDesc("mlock", unimplementedFunc), - /* 315 */ SyscallDesc("munlock", unimplementedFunc), - /* 316 */ SyscallDesc("mlockall", unimplementedFunc), - /* 317 */ SyscallDesc("munlockall", unimplementedFunc), - /* 318 */ SyscallDesc("sysinfo", unimplementedFunc), - /* 319 */ SyscallDesc("_sysctl", unimplementedFunc), - /* 320 */ SyscallDesc("was sys_idle", unimplementedFunc), - /* 321 */ SyscallDesc("oldumount", unimplementedFunc), - /* 322 */ SyscallDesc("swapon", unimplementedFunc), - /* 323 */ SyscallDesc("times", ignoreFunc), - /* 324 */ SyscallDesc("personality", unimplementedFunc), - /* 325 */ SyscallDesc("setfsuid", unimplementedFunc), - /* 326 */ SyscallDesc("setfsgid", unimplementedFunc), - /* 327 */ SyscallDesc("ustat", unimplementedFunc), - /* 328 */ SyscallDesc("statfs", unimplementedFunc), - /* 329 */ SyscallDesc("fstatfs", unimplementedFunc), - /* 330 */ SyscallDesc("sched_setparam", unimplementedFunc), - /* 331 */ SyscallDesc("sched_getparam", unimplementedFunc), - /* 332 */ SyscallDesc("sched_setscheduler", unimplementedFunc), - /* 333 */ SyscallDesc("sched_getscheduler", unimplementedFunc), - /* 334 */ SyscallDesc("sched_yield", unimplementedFunc), - /* 335 */ SyscallDesc("sched_get_priority_max", unimplementedFunc), - /* 336 */ SyscallDesc("sched_get_priority_min", unimplementedFunc), - /* 337 */ SyscallDesc("sched_rr_get_interval", unimplementedFunc), - /* 338 */ SyscallDesc("afs_syscall", unimplementedFunc), - /* 339 */ SyscallDesc("uname", unameFunc), - /* 340 */ SyscallDesc("nanosleep", unimplementedFunc), - /* 341 */ SyscallDesc("mremap", unimplementedFunc), - /* 342 */ SyscallDesc("nfsservctl", unimplementedFunc), - /* 343 */ SyscallDesc("setresuid", unimplementedFunc), - /* 344 */ SyscallDesc("getresuid", unimplementedFunc), - /* 345 */ SyscallDesc("pciconfig_read", unimplementedFunc), - /* 346 */ SyscallDesc("pciconfig_write", unimplementedFunc), - /* 347 */ SyscallDesc("query_module", unimplementedFunc), - /* 348 */ SyscallDesc("prctl", unimplementedFunc), - /* 349 */ SyscallDesc("pread", unimplementedFunc), - /* 350 */ SyscallDesc("pwrite", unimplementedFunc), - /* 351 */ SyscallDesc("rt_sigreturn", unimplementedFunc), - /* 352 */ SyscallDesc("rt_sigaction", ignoreFunc), - /* 353 */ SyscallDesc("rt_sigprocmask", unimplementedFunc), - /* 354 */ SyscallDesc("rt_sigpending", unimplementedFunc), - /* 355 */ SyscallDesc("rt_sigtimedwait", unimplementedFunc), - /* 356 */ SyscallDesc("rt_sigqueueinfo", unimplementedFunc), - /* 357 */ SyscallDesc("rt_sigsuspend", unimplementedFunc), - /* 358 */ SyscallDesc("select", unimplementedFunc), - /* 359 */ SyscallDesc("gettimeofday", gettimeofdayFunc), - /* 360 */ SyscallDesc("settimeofday", unimplementedFunc), - /* 361 */ SyscallDesc("getitimer", unimplementedFunc), - /* 362 */ SyscallDesc("setitimer", unimplementedFunc), - /* 363 */ SyscallDesc("utimes", utimesFunc), - /* 364 */ SyscallDesc("getrusage", getrusageFunc), - /* 365 */ SyscallDesc("wait4", unimplementedFunc), - /* 366 */ SyscallDesc("adjtimex", unimplementedFunc), - /* 367 */ SyscallDesc("getcwd", unimplementedFunc), - /* 368 */ SyscallDesc("capget", unimplementedFunc), - /* 369 */ SyscallDesc("capset", unimplementedFunc), - /* 370 */ SyscallDesc("sendfile", unimplementedFunc), - /* 371 */ SyscallDesc("setresgid", unimplementedFunc), - /* 372 */ SyscallDesc("getresgid", unimplementedFunc), - /* 373 */ SyscallDesc("dipc", unimplementedFunc), - /* 374 */ SyscallDesc("pivot_root", unimplementedFunc), - /* 375 */ SyscallDesc("mincore", unimplementedFunc), - /* 376 */ SyscallDesc("pciconfig_iobase", unimplementedFunc), - /* 377 */ SyscallDesc("getdents64", unimplementedFunc), - /* 378 */ SyscallDesc("gettid", unimplementedFunc), - /* 379 */ SyscallDesc("readahead", unimplementedFunc), - /* 380 */ SyscallDesc("security", unimplementedFunc), - /* 381 */ SyscallDesc("tkill", unimplementedFunc), - /* 382 */ SyscallDesc("setxattr", unimplementedFunc), - /* 383 */ SyscallDesc("lsetxattr", unimplementedFunc), - /* 384 */ SyscallDesc("fsetxattr", unimplementedFunc), - /* 385 */ SyscallDesc("getxattr", unimplementedFunc), - /* 386 */ SyscallDesc("lgetxattr", unimplementedFunc), - /* 387 */ SyscallDesc("fgetxattr", unimplementedFunc), - /* 388 */ SyscallDesc("listxattr", unimplementedFunc), - /* 389 */ SyscallDesc("llistxattr", unimplementedFunc), - /* 390 */ SyscallDesc("flistxattr", unimplementedFunc), - /* 391 */ SyscallDesc("removexattr", unimplementedFunc), - /* 392 */ SyscallDesc("lremovexattr", unimplementedFunc), - /* 393 */ SyscallDesc("fremovexattr", unimplementedFunc), - /* 394 */ SyscallDesc("futex", unimplementedFunc), - /* 395 */ SyscallDesc("sched_setaffinity", unimplementedFunc), - /* 396 */ SyscallDesc("sched_getaffinity", unimplementedFunc), - /* 397 */ SyscallDesc("tuxcall", unimplementedFunc), - /* 398 */ SyscallDesc("io_setup", unimplementedFunc), - /* 399 */ SyscallDesc("io_destroy", unimplementedFunc), - /* 400 */ SyscallDesc("io_getevents", unimplementedFunc), - /* 401 */ SyscallDesc("io_submit", unimplementedFunc), - /* 402 */ SyscallDesc("io_cancel", unimplementedFunc), - /* 403 */ SyscallDesc("unknown #403", unimplementedFunc), - /* 404 */ SyscallDesc("unknown #404", unimplementedFunc), - /* 405 */ SyscallDesc("exit_group", exitFunc), // exit all threads... - /* 406 */ SyscallDesc("lookup_dcookie", unimplementedFunc), - /* 407 */ SyscallDesc("sys_epoll_create", unimplementedFunc), - /* 408 */ SyscallDesc("sys_epoll_ctl", unimplementedFunc), - /* 409 */ SyscallDesc("sys_epoll_wait", unimplementedFunc), - /* 410 */ SyscallDesc("remap_file_pages", unimplementedFunc), - /* 411 */ SyscallDesc("set_tid_address", unimplementedFunc), - /* 412 */ SyscallDesc("restart_syscall", unimplementedFunc), - /* 413 */ SyscallDesc("fadvise64", unimplementedFunc), - /* 414 */ SyscallDesc("timer_create", unimplementedFunc), - /* 415 */ SyscallDesc("timer_settime", unimplementedFunc), - /* 416 */ SyscallDesc("timer_gettime", unimplementedFunc), - /* 417 */ SyscallDesc("timer_getoverrun", unimplementedFunc), - /* 418 */ SyscallDesc("timer_delete", unimplementedFunc), - /* 419 */ SyscallDesc("clock_settime", unimplementedFunc), - /* 420 */ SyscallDesc("clock_gettime", unimplementedFunc), - /* 421 */ SyscallDesc("clock_getres", unimplementedFunc), - /* 422 */ SyscallDesc("clock_nanosleep", unimplementedFunc), - /* 423 */ SyscallDesc("semtimedop", unimplementedFunc), - /* 424 */ SyscallDesc("tgkill", unimplementedFunc), - /* 425 */ SyscallDesc("stat64", unimplementedFunc), - /* 426 */ SyscallDesc("lstat64", lstat64Func), - /* 427 */ SyscallDesc("fstat64", fstat64Func), - /* 428 */ SyscallDesc("vserver", unimplementedFunc), - /* 429 */ SyscallDesc("mbind", unimplementedFunc), - /* 430 */ SyscallDesc("get_mempolicy", unimplementedFunc), - /* 431 */ SyscallDesc("set_mempolicy", unimplementedFunc), - /* 432 */ SyscallDesc("mq_open", unimplementedFunc), - /* 433 */ SyscallDesc("mq_unlink", unimplementedFunc), - /* 434 */ SyscallDesc("mq_timedsend", unimplementedFunc), - /* 435 */ SyscallDesc("mq_timedreceive", unimplementedFunc), - /* 436 */ SyscallDesc("mq_notify", unimplementedFunc), - /* 437 */ SyscallDesc("mq_getsetattr", unimplementedFunc), - /* 438 */ SyscallDesc("waitid", unimplementedFunc), - /* 439 */ SyscallDesc("add_key", unimplementedFunc), - /* 440 */ SyscallDesc("request_key", unimplementedFunc), - /* 441 */ SyscallDesc("keyctl", unimplementedFunc) +SyscallDesc SparcLinuxProcess::syscallDescs[] = { + /* 0 */ SyscallDesc("restart_syscall", unimplimentedFunc); + /* 1 */ SyscallDesc("exit", unimplimentedFunc); + /* 2 */ SyscallDesc("fork", unimplimentedFunc); + /* 3 */ SyscallDesc("read", unimplimentedFunc); + /* 4 */ SyscallDesc("write", unimplimentedFunc); + /* 5 */ SyscallDesc("open", unimplimentedFunc); + /* 6 */ SyscallDesc("close", unimplimentedFunc); + /* 7 */ SyscallDesc("wait4", unimplimentedFunc); + /* 8 */ SyscallDesc("creat", unimplimentedFunc); + /* 9 */ SyscallDesc("link", unimplimentedFunc); + /* 10 */ SyscallDesc("unlink", unimplimentedFunc); + /* 11 */ SyscallDesc("execv", unimplimentedFunc); + /* 12 */ SyscallDesc("chdir", unimplimentedFunc); + /* 13 */ SyscallDesc("chown", unimplimentedFunc); + /* 14 */ SyscallDesc("mknod", unimplimentedFunc); + /* 15 */ SyscallDesc("chmod", unimplimentedFunc); + /* 16 */ SyscallDesc("lchown", unimplimentedFunc); + /* 17 */ SyscallDesc("brk", unimplimentedFunc); + /* 18 */ SyscallDesc("perfctr", unimplimentedFunc); + /* 19 */ SyscallDesc("lseek", unimplimentedFunc); + /* 20 */ SyscallDesc("getpid", unimplimentedFunc); + /* 21 */ SyscallDesc("capget", unimplimentedFunc); + /* 22 */ SyscallDesc("capset", unimplimentedFunc); + /* 23 */ SyscallDesc("setuid", unimplimentedFunc); + /* 24 */ SyscallDesc("getuid", unimplimentedFunc); + /* 25 */ SyscallDesc("time", unimplimentedFunc); + /* 26 */ SyscallDesc("ptrace", unimplimentedFunc); + /* 27 */ SyscallDesc("alarm", unimplimentedFunc); + /* 28 */ SyscallDesc("sigaltstack", unimplimentedFunc); + /* 29 */ SyscallDesc("pause", unimplimentedFunc); + /* 30 */ SyscallDesc("utime", unimplimentedFunc); + /* 31 */ SyscallDesc("lchown32", unimplimentedFunc); + /* 32 */ SyscallDesc("fchown32", unimplimentedFunc); + /* 33 */ SyscallDesc("access", unimplimentedFunc); + /* 34 */ SyscallDesc("nice", unimplimentedFunc); + /* 35 */ SyscallDesc("chown32", unimplimentedFunc); + /* 36 */ SyscallDesc("sync", unimplimentedFunc); + /* 37 */ SyscallDesc("kill", unimplimentedFunc); + /* 38 */ SyscallDesc("stat", unimplimentedFunc); + /* 39 */ SyscallDesc("sendfile", unimplimentedFunc); + /* 40 */ SyscallDesc("lstat", unimplimentedFunc); + /* 41 */ SyscallDesc("dup", unimplimentedFunc); + /* 42 */ SyscallDesc("pipe", unimplimentedFunc); + /* 43 */ SyscallDesc("times", unimplimentedFunc); + /* 44 */ SyscallDesc("getuid32", unimplimentedFunc); + /* 45 */ SyscallDesc("umount2", unimplimentedFunc); + /* 46 */ SyscallDesc("setgid", unimplimentedFunc); + /* 47 */ SyscallDesc("getgid", unimplimentedFunc); + /* 48 */ SyscallDesc("signal", unimplimentedFunc); + /* 49 */ SyscallDesc("geteuid", unimplimentedFunc); + /* 50 */ SyscallDesc("getegid", unimplimentedFunc); + /* 51 */ SyscallDesc("acct", unimplimentedFunc); + /* 52 */ SyscallDesc("memory_ordering", unimplimentedFunc); + /* 53 */ SyscallDesc("getgid32", unimplimentedFunc); + /* 54 */ SyscallDesc("ioctl", unimplimentedFunc); + /* 55 */ SyscallDesc("reboot", unimplimentedFunc); + /* 56 */ SyscallDesc("mmap2", unimplimentedFunc); + /* 57 */ SyscallDesc("symlink", unimplimentedFunc); + /* 58 */ SyscallDesc("readlink", unimplimentedFunc); + /* 59 */ SyscallDesc("execve", unimplimentedFunc); + /* 60 */ SyscallDesc("umask", unimplimentedFunc); + /* 61 */ SyscallDesc("chroot", unimplimentedFunc); + /* 62 */ SyscallDesc("fstat", unimplimentedFunc); + /* 63 */ SyscallDesc("fstat64", unimplimentedFunc); + /* 64 */ SyscallDesc("getpagesize", unimplimentedFunc); + /* 65 */ SyscallDesc("msync", unimplimentedFunc); + /* 66 */ SyscallDesc("vfork", unimplimentedFunc); + /* 67 */ SyscallDesc("pread64", unimplimentedFunc); + /* 68 */ SyscallDesc("pwrite64", unimplimentedFunc); + /* 69 */ SyscallDesc("geteuid32", unimplimentedFunc); + /* 70 */ SyscallDesc("getdgid32", unimplimentedFunc); + /* 71 */ SyscallDesc("mmap", unimplimentedFunc); + /* 72 */ SyscallDesc("setreuid32", unimplimentedFunc); + /* 73 */ SyscallDesc("munmap", unimplimentedFunc); + /* 74 */ SyscallDesc("mprotect", unimplimentedFunc); + /* 75 */ SyscallDesc("madvise", unimplimentedFunc); + /* 76 */ SyscallDesc("vhangup", unimplimentedFunc); + /* 77 */ SyscallDesc("truncate64", unimplimentedFunc); + /* 78 */ SyscallDesc("mincore", unimplimentedFunc); + /* 79 */ SyscallDesc("getgroups", unimplimentedFunc); + /* 80 */ SyscallDesc("setgroups", unimplimentedFunc); + /* 81 */ SyscallDesc("getpgrp", unimplimentedFunc); + /* 82 */ SyscallDesc("setgroups32", unimplimentedFunc); + /* 83 */ SyscallDesc("setitimer", unimplimentedFunc); + /* 84 */ SyscallDesc("ftruncate64", unimplimentedFunc); + /* 85 */ SyscallDesc("swapon", unimplimentedFunc); + /* 86 */ SyscallDesc("getitimer", unimplimentedFunc); + /* 87 */ SyscallDesc("setuid32", unimplimentedFunc); + /* 88 */ SyscallDesc("sethostname", unimplimentedFunc); + /* 89 */ SyscallDesc("setgid32", unimplimentedFunc); + /* 90 */ SyscallDesc("dup2", unimplimentedFunc); + /* 91 */ SyscallDesc("setfsuid32", unimplimentedFunc); + /* 92 */ SyscallDesc("fcntl", unimplimentedFunc); + /* 93 */ SyscallDesc("select", unimplimentedFunc); + /* 94 */ SyscallDesc("setfsgid32", unimplimentedFunc); + /* 95 */ SyscallDesc("fsync", unimplimentedFunc); + /* 96 */ SyscallDesc("setpriority", unimplimentedFunc); + /* 97 */ SyscallDesc("socket", unimplimentedFunc); + /* 98 */ SyscallDesc("connect", unimplimentedFunc); + /* 99 */ SyscallDesc("accept", unimplimentedFunc); + /* 100 */ SyscallDesc("getpriority", unimplimentedFunc); + /* 101 */ SyscallDesc("rt_sigreturn", unimplimentedFunc); + /* 102 */ SyscallDesc("rt_sigaction", unimplimentedFunc); + /* 103 */ SyscallDesc("rt_sigprocmask", unimplimentedFunc); + /* 104 */ SyscallDesc("rt_sigpending", unimplimentedFunc); + /* 105 */ SyscallDesc("rt_sigtimedwait", unimplimentedFunc); + /* 106 */ SyscallDesc("rt_sigqueueinfo", unimplimentedFunc); + /* 107 */ SyscallDesc("rt_sigsuspend", unimplimentedFunc); + /* 108 */ SyscallDesc("setresuid", unimplimentedFunc); + /* 109 */ SyscallDesc("getresuid", unimplimentedFunc); + /* 110 */ SyscallDesc("setresgid", unimplimentedFunc); + /* 111 */ SyscallDesc("getresgid", unimplimentedFunc); + /* 112 */ SyscallDesc("setregid32", unimplimentedFunc); + /* 113 */ SyscallDesc("recvmsg", unimplimentedFunc); + /* 114 */ SyscallDesc("sendmsg", unimplimentedFunc); + /* 115 */ SyscallDesc("getgroups32", unimplimentedFunc); + /* 116 */ SyscallDesc("gettimeofday", unimplimentedFunc); + /* 117 */ SyscallDesc("getrusage", unimplimentedFunc); + /* 118 */ SyscallDesc("getsockopt", unimplimentedFunc); + /* 119 */ SyscallDesc("getcwd", unimplimentedFunc); + /* 120 */ SyscallDesc("readv", unimplimentedFunc); + /* 121 */ SyscallDesc("writev", unimplimentedFunc); + /* 122 */ SyscallDesc("settimeofday", unimplimentedFunc); + /* 123 */ SyscallDesc("fchown", unimplimentedFunc); + /* 124 */ SyscallDesc("fchmod", unimplimentedFunc); + /* 125 */ SyscallDesc("recvfrom", unimplimentedFunc); + /* 126 */ SyscallDesc("setreuid", unimplimentedFunc); + /* 127 */ SyscallDesc("setregid", unimplimentedFunc); + /* 128 */ SyscallDesc("rename", unimplimentedFunc); + /* 129 */ SyscallDesc("truncate", unimplimentedFunc); + /* 130 */ SyscallDesc("ftruncate", unimplimentedFunc); + /* 131 */ SyscallDesc("flock", unimplimentedFunc); + /* 132 */ SyscallDesc("lstat64", unimplimentedFunc); + /* 133 */ SyscallDesc("sendto", unimplimentedFunc); + /* 134 */ SyscallDesc("shutdown", unimplimentedFunc); + /* 135 */ SyscallDesc("socketpair", unimplimentedFunc); + /* 136 */ SyscallDesc("mkdir", unimplimentedFunc); + /* 137 */ SyscallDesc("rmdir", unimplimentedFunc); + /* 138 */ SyscallDesc("utimes", unimplimentedFunc); + /* 139 */ SyscallDesc("stat64", unimplimentedFunc); + /* 140 */ SyscallDesc("sendfile64", unimplimentedFunc); + /* 141 */ SyscallDesc("getpeername", unimplimentedFunc); + /* 142 */ SyscallDesc("futex", unimplimentedFunc); + /* 143 */ SyscallDesc("gettid", unimplimentedFunc); + /* 144 */ SyscallDesc("getrlimit", unimplimentedFunc); + /* 145 */ SyscallDesc("setrlimit", unimplimentedFunc); + /* 146 */ SyscallDesc("pivot_root", unimplimentedFunc); + /* 147 */ SyscallDesc("prctl", unimplimentedFunc); + /* 148 */ SyscallDesc("pciconfig_read", unimplimentedFunc); + /* 149 */ SyscallDesc("pciconfig_write", unimplimentedFunc); + /* 150 */ SyscallDesc("getsockname", unimplimentedFunc); + /* 151 */ SyscallDesc("inotify_init", unimplimentedFunc); + /* 152 */ SyscallDesc("inotify_add_watch", unimplimentedFunc); + /* 153 */ SyscallDesc("poll", unimplimentedFunc); + /* 154 */ SyscallDesc("getdents64", unimplimentedFunc); + /* 155 */ SyscallDesc("fcntl64", unimplimentedFunc); + /* 156 */ SyscallDesc("inotify_rm_watch", unimplimentedFunc); + /* 157 */ SyscallDesc("statfs", unimplimentedFunc); + /* 158 */ SyscallDesc("fstatfs", unimplimentedFunc); + /* 159 */ SyscallDesc("umount", unimplimentedFunc); + /* 160 */ SyscallDesc("sched_set_affinity", unimplimentedFunc); + /* 161 */ SyscallDesc("sched_get_affinity", unimplimentedFunc); + /* 162 */ SyscallDesc("getdomainname", unimplimentedFunc); + /* 163 */ SyscallDesc("setdomainname", unimplimentedFunc); + /* 164 */ SyscallDesc("utrap_install", unimplimentedFunc); + /* 165 */ SyscallDesc("quotactl", unimplimentedFunc); + /* 166 */ SyscallDesc("set_tid_address", unimplimentedFunc); + /* 167 */ SyscallDesc("mount", unimplimentedFunc); + /* 168 */ SyscallDesc("ustat", unimplimentedFunc); + /* 169 */ SyscallDesc("setxattr", unimplimentedFunc); + /* 170 */ SyscallDesc("lsetxattr", unimplimentedFunc); + /* 171 */ SyscallDesc("fsetxattr", unimplimentedFunc); + /* 172 */ SyscallDesc("getxattr", unimplimentedFunc); + /* 173 */ SyscallDesc("lgetxattr", unimplimentedFunc); + /* 174 */ SyscallDesc("getdents", unimplimentedFunc); + /* 175 */ SyscallDesc("setsid", unimplimentedFunc); + /* 176 */ SyscallDesc("fchdir", unimplimentedFunc); + /* 177 */ SyscallDesc("fgetxattr", unimplimentedFunc); + /* 178 */ SyscallDesc("listxattr", unimplimentedFunc); + /* 179 */ SyscallDesc("llistxattr", unimplimentedFunc); + /* 180 */ SyscallDesc("flistxattr", unimplimentedFunc); + /* 181 */ SyscallDesc("removexattr", unimplimentedFunc); + /* 182 */ SyscallDesc("lremovexattr", unimplimentedFunc); + /* 183 */ SyscallDesc("sigpending", unimplimentedFunc); + /* 184 */ SyscallDesc("query_module", unimplimentedFunc); + /* 185 */ SyscallDesc("setpgid", unimplimentedFunc); + /* 186 */ SyscallDesc("fremovexattr", unimplimentedFunc); + /* 187 */ SyscallDesc("tkill", unimplimentedFunc); + /* 188 */ SyscallDesc("exit_group", unimplimentedFunc); + /* 189 */ SyscallDesc("uname", unimplimentedFunc); + /* 190 */ SyscallDesc("init_module", unimplimentedFunc); + /* 191 */ SyscallDesc("personality", unimplimentedFunc); + /* 192 */ SyscallDesc("remap_file_pages", unimplimentedFunc); + /* 193 */ SyscallDesc("epoll_create", unimplimentedFunc); + /* 194 */ SyscallDesc("epoll_ctl", unimplimentedFunc); + /* 195 */ SyscallDesc("epoll_wait", unimplimentedFunc); + /* 196 */ SyscallDesc("ioprio_set", unimplimentedFunc); + /* 197 */ SyscallDesc("getppid", unimplimentedFunc); + /* 198 */ SyscallDesc("sigaction", unimplimentedFunc); + /* 199 */ SyscallDesc("sgetmask", unimplimentedFunc); + /* 200 */ SyscallDesc("ssetmask", unimplimentedFunc); + /* 201 */ SyscallDesc("sigsuspend", unimplimentedFunc); + /* 202 */ SyscallDesc("oldlstat", unimplimentedFunc); + /* 203 */ SyscallDesc("uselib", unimplimentedFunc); + /* 204 */ SyscallDesc("readdir", unimplimentedFunc); + /* 205 */ SyscallDesc("readahead", unimplimentedFunc); + /* 206 */ SyscallDesc("socketcall", unimplimentedFunc); + /* 207 */ SyscallDesc("syslog", unimplimentedFunc); + /* 208 */ SyscallDesc("lookup_dcookie", unimplimentedFunc); + /* 209 */ SyscallDesc("fadvise64", unimplimentedFunc); + /* 210 */ SyscallDesc("fadvise64_64", unimplimentedFunc); + /* 211 */ SyscallDesc("tgkill", unimplimentedFunc); + /* 212 */ SyscallDesc("waitpid", unimplimentedFunc); + /* 213 */ SyscallDesc("swapoff", unimplimentedFunc); + /* 214 */ SyscallDesc("sysinfo", unimplimentedFunc); + /* 215 */ SyscallDesc("ipc", unimplimentedFunc); + /* 216 */ SyscallDesc("sigreturn", unimplimentedFunc); + /* 217 */ SyscallDesc("clone", unimplimentedFunc); + /* 218 */ SyscallDesc("ioprio_get", unimplimentedFunc); + /* 219 */ SyscallDesc("adjtimex", unimplimentedFunc); + /* 220 */ SyscallDesc("sigprocmask", unimplimentedFunc); + /* 221 */ SyscallDesc("create_module", unimplimentedFunc); + /* 222 */ SyscallDesc("delete_module", unimplimentedFunc); + /* 223 */ SyscallDesc("get_kernel_syms", unimplimentedFunc); + /* 224 */ SyscallDesc("getpgid", unimplimentedFunc); + /* 225 */ SyscallDesc("bdflush", unimplimentedFunc); + /* 226 */ SyscallDesc("sysfs", unimplimentedFunc); + /* 227 */ SyscallDesc("afs_syscall", unimplimentedFunc); + /* 228 */ SyscallDesc("setfsuid", unimplimentedFunc); + /* 229 */ SyscallDesc("setfsgid", unimplimentedFunc); + /* 230 */ SyscallDesc("_newselect", unimplimentedFunc); + /* 231 */ SyscallDesc("time", unimplimentedFunc); + /* 232 */ SyscallDesc("oldstat", unimplimentedFunc); + /* 233 */ SyscallDesc("stime", unimplimentedFunc); + /* 234 */ SyscallDesc("statfs64", unimplimentedFunc); + /* 235 */ SyscallDesc("fstatfs64", unimplimentedFunc); + /* 236 */ SyscallDesc("_llseek", unimplimentedFunc); + /* 237 */ SyscallDesc("mlock", unimplimentedFunc); + /* 238 */ SyscallDesc("munlock", unimplimentedFunc); + /* 239 */ SyscallDesc("mlockall", unimplimentedFunc); + /* 240 */ SyscallDesc("munlockall", unimplimentedFunc); + /* 241 */ SyscallDesc("sched_setparam", unimplimentedFunc); + /* 242 */ SyscallDesc("sched_getparam", unimplimentedFunc); + /* 243 */ SyscallDesc("sched_setscheduler", unimplimentedFunc); + /* 244 */ SyscallDesc("sched_getscheduler", unimplimentedFunc); + /* 245 */ SyscallDesc("sched_yield", unimplimentedFunc); + /* 246 */ SyscallDesc("sched_get_priority_max", unimplimented); + /* 247 */ SyscallDesc("sched_get_priority_min", unimplimented); + /* 248 */ SyscallDesc("sched_rr_get_interval", unimplimented); + /* 249 */ SyscallDesc("nanosleep", unimplimentedFunc); + /* 250 */ SyscallDesc("mremap", unimplimentedFunc); + /* 251 */ SyscallDesc("_sysctl", unimplimentedFunc); + /* 252 */ SyscallDesc("getsid", unimplimentedFunc); + /* 253 */ SyscallDesc("fdatasync", unimplimentedFunc); + /* 254 */ SyscallDesc("nfsservctl", unimplimentedFunc); + /* 255 */ SyscallDesc("aplib", unimplimentedFunc); + /* 256 */ SyscallDesc("clock_settime", unimplimentedFunc); + /* 257 */ SyscallDesc("clock_gettime", unimplimentedFunc); + /* 258 */ SyscallDesc("clock_getres", unimplimentedFunc); + /* 259 */ SyscallDesc("clock_nanosleep", unimplimentedFunc); + /* 260 */ SyscallDesc("sched_getaffinity", unimplimentedFunc); + /* 261 */ SyscallDesc("sched_setaffinity", unimplimentedFunc); + /* 262 */ SyscallDesc("timer_settime", unimplimentedFunc); + /* 263 */ SyscallDesc("timer_gettime", unimplimentedFunc); + /* 264 */ SyscallDesc("timer_getoverrun", unimplimentedFunc); + /* 265 */ SyscallDesc("timer_delete", unimplimentedFunc); + /* 266 */ SyscallDesc("timer_create", unimplimentedFunc); + /* 267 */ SyscallDesc("vserver", unimplimentedFunc); + /* 268 */ SyscallDesc("io_setup", unimplimentedFunc); + /* 269 */ SyscallDesc("io_destroy", unimplimentedFunc); + /* 270 */ SyscallDesc("io_submit", unimplimentedFunc); + /* 271 */ SyscallDesc("io_cancel", unimplimentedFunc); + /* 272 */ SyscallDesc("io_getevents", unimplimentedFunc); + /* 273 */ SyscallDesc("mq_open", unimplimentedFunc); + /* 274 */ SyscallDesc("mq_unlink", unimplimentedFunc); + /* 275 */ SyscallDesc("mq_timedsend", unimplimentedFunc); + /* 276 */ SyscallDesc("mq_timedreceive", unimplimentedFunc); + /* 277 */ SyscallDesc("mq_notify", unimplimentedFunc); + /* 278 */ SyscallDesc("mq_getsetattr", unimplimentedFunc); + /* 279 */ SyscallDesc("waitid", unimplimentedFunc); + /* 280 */ SyscallDesc("sys_setaltroot", unimplimentedFunc); + /* 281 */ SyscallDesc("add_key", unimplimentedFunc); + /* 282 */ SyscallDesc("request_key", unimplimentedFunc); + /* 283 */ SyscallDesc("keyctl", unimplimentedFunc); }; -AlphaLinuxProcess::AlphaLinuxProcess(const std::string &name, +SparcLinuxProcess::SparcLinuxProcess(const std::string &name, ObjectFile *objFile, int stdin_fd, int stdout_fd, diff --git a/arch/sparc/linux_process.hh b/arch/sparc/linux_process.hh index 7de1b1ac1..c41406b4b 100644 --- a/arch/sparc/linux_process.hh +++ b/arch/sparc/linux_process.hh @@ -26,18 +26,18 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef __ALPHA_LINUX_PROCESS_HH__ -#define __ALPHA_LINUX_PROCESS_HH__ +#ifndef __SPARC_LINUX_PROCESS_HH__ +#define __SPARC_LINUX_PROCESS_HH__ #include "sim/process.hh" -/// A process with emulated Alpha/Linux syscalls. -class AlphaLinuxProcess : public LiveProcess +/// A process with emulated SPARC/Linux syscalls. +class SparcLinuxProcess : public LiveProcess { public: /// Constructor. - AlphaLinuxProcess(const std::string &name, + SparcLinuxProcess(const std::string &name, ObjectFile *objFile, int stdin_fd, int stdout_fd, int stderr_fd, std::vector &argv, From 6b7d62790399f3ff675e5d37a25c320aa068897a Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 1 Mar 2006 19:03:42 -0500 Subject: [PATCH 136/180] Got rid of the multiple inheritance in the Fault classes, and the base MachineCheck and Alignment faults. --HG-- extra : convert_revision : 4b1429ef5c7a11c25e28f2bc868cc1481a08c5d1 --- arch/alpha/faults.cc | 10 ++++++---- arch/alpha/faults.hh | 20 ++++++++++++-------- sim/faults.cc | 3 --- sim/faults.hh | 25 ------------------------- 4 files changed, 18 insertions(+), 40 deletions(-) diff --git a/arch/alpha/faults.cc b/arch/alpha/faults.cc index 7cdcc9bab..0a836363c 100644 --- a/arch/alpha/faults.cc +++ b/arch/alpha/faults.cc @@ -35,11 +35,13 @@ namespace AlphaISA { -FaultVect AlphaMachineCheckFault::_vect = 0x0401; -FaultStat AlphaMachineCheckFault::_stat; +FaultName MachineCheckFault::_name = "mchk"; +FaultVect MachineCheckFault::_vect = 0x0401; +FaultStat MachineCheckFault::_stat; -FaultVect AlphaAlignmentFault::_vect = 0x0301; -FaultStat AlphaAlignmentFault::_stat; +FaultName AlignmentFault::_name = "unalign"; +FaultVect AlignmentFault::_vect = 0x0301; +FaultStat AlignmentFault::_stat; FaultName ResetFault::_name = "reset"; FaultVect ResetFault::_vect = 0x0001; diff --git a/arch/alpha/faults.hh b/arch/alpha/faults.hh index b9573905a..c4a72e07c 100644 --- a/arch/alpha/faults.hh +++ b/arch/alpha/faults.hh @@ -50,38 +50,40 @@ class AlphaFault : public virtual FaultBase virtual FaultVect vect() = 0; }; -class AlphaMachineCheckFault : - public MachineCheckFault, - public AlphaFault +class MachineCheckFault : public AlphaFault { private: + static FaultName _name; static FaultVect _vect; static FaultStat _stat; public: + FaultName name() {return _name;} FaultVect vect() {return _vect;} FaultStat & stat() {return _stat;} + bool isMachineCheckFault() {return true;} }; -class AlphaAlignmentFault : - public AlignmentFault, - public AlphaFault +class AlignmentFault : public AlphaFault { private: + static FaultName _name; static FaultVect _vect; static FaultStat _stat; public: + FaultName name() {return _name;} FaultVect vect() {return _vect;} FaultStat & stat() {return _stat;} + bool isAlignmentFault() {return true;} }; static inline Fault genMachineCheckFault() { - return new AlphaMachineCheckFault; + return new MachineCheckFault; } static inline Fault genAlignmentFault() { - return new AlphaAlignmentFault; + return new AlignmentFault; } class ResetFault : public AlphaFault @@ -108,7 +110,9 @@ class ArithmeticFault : public AlphaFault FaultName name() {return _name;} FaultVect vect() {return _vect;} FaultStat & stat() {return _stat;} +#if FULL_SYSTEM void invoke(ExecContext * xc); +#endif }; class InterruptFault : public AlphaFault diff --git a/sim/faults.cc b/sim/faults.cc index 68df2b785..9b4a0ea7f 100644 --- a/sim/faults.cc +++ b/sim/faults.cc @@ -29,9 +29,6 @@ #include "sim/faults.hh" #include "cpu/exec_context.hh" -FaultName MachineCheckFault::_name = "mchk"; -FaultName AlignmentFault::_name = "unalign"; - #if !FULL_SYSTEM void FaultBase::invoke(ExecContext * xc) { diff --git a/sim/faults.hh b/sim/faults.hh index 1e43bfb82..9e8d224cd 100644 --- a/sim/faults.hh +++ b/sim/faults.hh @@ -65,29 +65,4 @@ class FaultBase : public RefCounted FaultBase * const NoFault = 0; -//The ISAs are each responsible for providing a genMachineCheckFault and a -//genAlignmentFault functions, which return faults to use in the case of a -//machine check fault or an alignment fault, respectively. Base classes which -//provide the name() function, and the isMachineCheckFault and isAlignmentFault -//functions are provided below. - -class MachineCheckFault : public virtual FaultBase -{ - private: - static FaultName _name; - public: - FaultName name() {return _name;} - bool isMachineCheckFault() {return true;} -}; - -class AlignmentFault : public virtual FaultBase -{ - private: - static FaultName _name; - public: - FaultName name() {return _name;} - bool isAlignmentFault() {return true;} -}; - - #endif // __FAULTS_HH__ From 0fed64a6a47a62a94a53c5f41ac89b34a2fd6786 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Thu, 2 Mar 2006 17:49:12 -0500 Subject: [PATCH 137/180] Fix fault handling, dereferincing a null pointer is bad. --HG-- extra : convert_revision : a4f658bfd39b7f1d219ad8929b8f45457f49299f --- cpu/simple/cpu.cc | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/cpu/simple/cpu.cc b/cpu/simple/cpu.cc index d826c589e..ca5d54694 100644 --- a/cpu/simple/cpu.cc +++ b/cpu/simple/cpu.cc @@ -347,12 +347,12 @@ SimpleCPU::copySrcTranslate(Addr src) // translate to physical address Fault fault = xc->translateDataReadReq(memReq); - assert(!fault->isAlignmentFault()); - if (fault == NoFault) { xc->copySrcAddr = src; xc->copySrcPhysAddr = memReq->paddr + offset; } else { + assert(!fault->isAlignmentFault()); + xc->copySrcAddr = 0; xc->copySrcPhysAddr = 0; } @@ -382,8 +382,6 @@ SimpleCPU::copy(Addr dest) // translate to physical address Fault fault = xc->translateDataWriteReq(memReq); - assert(!fault->isAlignmentFault()); - if (fault == NoFault) { Addr dest_addr = memReq->paddr + offset; // Need to read straight from memory since we have more than 8 bytes. @@ -402,6 +400,9 @@ SimpleCPU::copy(Addr dest) dcacheInterface->access(memReq); } } + else + assert(!fault->isAlignmentFault()); + return fault; } From 7546fabe68a1dc6ec9b9e020f5e2b1cc0aa31c21 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Fri, 3 Mar 2006 14:17:48 -0500 Subject: [PATCH 138/180] Ethernet devices have an RSS option to tell the driver to use Receive side scaling dev/ns_gige.cc: dev/ns_gige.hh: dev/ns_gige_reg.h: dev/sinic.cc: dev/sinic.hh: dev/sinicreg.hh: add support for setting the RSS flag to notify the driver to use RSS --HG-- extra : convert_revision : 5f0c11668ae976634b3bf0caad669a9464a4c041 --- dev/ns_gige.cc | 7 ++++++- dev/ns_gige.hh | 1 + dev/ns_gige_reg.h | 1 + dev/sinic.cc | 7 ++++++- dev/sinic.hh | 1 + dev/sinicreg.hh | 1 + python/m5/objects/Ethernet.py | 1 + 7 files changed, 17 insertions(+), 2 deletions(-) diff --git a/dev/ns_gige.cc b/dev/ns_gige.cc index d6df347bc..ed8c794f9 100644 --- a/dev/ns_gige.cc +++ b/dev/ns_gige.cc @@ -767,6 +767,8 @@ NSGigE::read(MemReqPtr &req, uint8_t *data) reg |= M5REG_RX_THREAD; if (params()->tx_thread) reg |= M5REG_TX_THREAD; + if (params()->rss) + reg |= M5REG_RSS; break; default: @@ -3009,6 +3011,7 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(NSGigE) Param hardware_address; Param rx_thread; Param tx_thread; + Param rss; END_DECLARE_SIM_OBJECT_PARAMS(NSGigE) @@ -3048,7 +3051,8 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(NSGigE) INIT_PARAM(rx_filter, "Enable Receive Filter"), INIT_PARAM(hardware_address, "Ethernet Hardware Address"), INIT_PARAM(rx_thread, ""), - INIT_PARAM(tx_thread, "") + INIT_PARAM(tx_thread, ""), + INIT_PARAM(rss, "") END_INIT_SIM_OBJECT_PARAMS(NSGigE) @@ -3093,6 +3097,7 @@ CREATE_SIM_OBJECT(NSGigE) params->eaddr = hardware_address; params->rx_thread = rx_thread; params->tx_thread = tx_thread; + params->rss = rss; return new NSGigE(params); } diff --git a/dev/ns_gige.hh b/dev/ns_gige.hh index cdd8e4b9e..59c55056e 100644 --- a/dev/ns_gige.hh +++ b/dev/ns_gige.hh @@ -385,6 +385,7 @@ class NSGigE : public PciDev uint32_t rx_fifo_size; bool rx_thread; bool tx_thread; + bool rss; bool dma_no_allocate; }; diff --git a/dev/ns_gige_reg.h b/dev/ns_gige_reg.h index eadc60d03..5f6fa2cc5 100644 --- a/dev/ns_gige_reg.h +++ b/dev/ns_gige_reg.h @@ -306,6 +306,7 @@ /* M5 control register */ #define M5REG_RESERVED 0xfffffffc +#define M5REG_RSS 0x00000004 #define M5REG_RX_THREAD 0x00000002 #define M5REG_TX_THREAD 0x00000001 diff --git a/dev/sinic.cc b/dev/sinic.cc index 34b4213e0..363994919 100644 --- a/dev/sinic.cc +++ b/dev/sinic.cc @@ -761,6 +761,8 @@ Device::reset() regs.Config |= Config_RxThread; if (params()->tx_thread) regs.Config |= Config_TxThread; + if (params()->rss) + regs.Config |= Config_RSS; regs.IntrMask = Intr_Soft | Intr_RxHigh | Intr_RxPacket | Intr_TxLow; regs.RxMaxCopy = params()->rx_max_copy; regs.TxMaxCopy = params()->tx_max_copy; @@ -1624,6 +1626,7 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(Device) Param hardware_address; Param rx_thread; Param tx_thread; + Param rss; END_DECLARE_SIM_OBJECT_PARAMS(Device) @@ -1666,7 +1669,8 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(Device) INIT_PARAM(rx_filter, "Enable Receive Filter"), INIT_PARAM(hardware_address, "Ethernet Hardware Address"), INIT_PARAM(rx_thread, ""), - INIT_PARAM(tx_thread, "") + INIT_PARAM(tx_thread, ""), + INIT_PARAM(rss, "") END_INIT_SIM_OBJECT_PARAMS(Device) @@ -1714,6 +1718,7 @@ CREATE_SIM_OBJECT(Device) params->eaddr = hardware_address; params->rx_thread = rx_thread; params->tx_thread = tx_thread; + params->rss = rss; return new Device(params); } diff --git a/dev/sinic.hh b/dev/sinic.hh index c4027be86..25172fa45 100644 --- a/dev/sinic.hh +++ b/dev/sinic.hh @@ -355,6 +355,7 @@ class Device : public Base bool dma_no_allocate; bool rx_thread; bool tx_thread; + bool rss; }; protected: diff --git a/dev/sinicreg.hh b/dev/sinicreg.hh index fc1f4c06b..f90432398 100644 --- a/dev/sinicreg.hh +++ b/dev/sinicreg.hh @@ -81,6 +81,7 @@ __SINIC_REG32(HwAddr, 0x60); // 64: mac address __SINIC_REG32(Size, 0x68); // register addres space size // Config register bits +__SINIC_VAL32(Config_RSS, 10, 1); // enable receive side scaling __SINIC_VAL32(Config_RxThread, 9, 1); // enable receive threads __SINIC_VAL32(Config_TxThread, 8, 1); // enable transmit thread __SINIC_VAL32(Config_Filter, 7, 1); // enable receive filter diff --git a/python/m5/objects/Ethernet.py b/python/m5/objects/Ethernet.py index 3a7f88d04..6113e656f 100644 --- a/python/m5/objects/Ethernet.py +++ b/python/m5/objects/Ethernet.py @@ -86,6 +86,7 @@ class EtherDevBase(PciDevice): intr_delay = Param.Latency('10us', "Interrupt propagation delay") rx_thread = Param.Bool(False, "dedicated kernel thread for transmit") tx_thread = Param.Bool(False, "dedicated kernel threads for receive") + rss = Param.Bool(False, "Receive Side Scaling") class NSGigE(EtherDevBase): type = 'NSGigE' From 0bf25c595364f7ca9b5e632c84fcf0d35dc3490a Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Fri, 3 Mar 2006 14:24:15 -0500 Subject: [PATCH 139/180] First cut at moving alpha specefic stuff out of /sim/system* into arch/alpha/system*. SConscript: dev/alpha_console.cc: dev/alpha_console.hh: kern/freebsd/freebsd_system.cc: kern/freebsd/freebsd_system.hh: kern/kernel_stats.cc: kern/linux/linux_system.cc: kern/linux/linux_system.hh: kern/tru64/tru64_system.cc: kern/tru64/tru64_system.hh: sim/pseudo_inst.cc: sim/system.cc: sim/system.hh: First cut at moving alpha specefic stuff out of /sim/system* --HG-- extra : convert_revision : eba58f537fc04e605af4fc216e184b074a44c8a0 --- SConscript | 2 + arch/alpha/system.cc | 298 +++++++++++++++++++++++++++++++++ arch/alpha/system.hh | 109 ++++++++++++ dev/alpha_console.cc | 6 +- dev/alpha_console.hh | 6 +- kern/freebsd/freebsd_system.cc | 5 +- kern/freebsd/freebsd_system.hh | 2 +- kern/kernel_stats.cc | 2 +- kern/linux/linux_system.cc | 9 +- kern/linux/linux_system.hh | 2 +- kern/tru64/tru64_system.cc | 4 +- kern/tru64/tru64_system.hh | 5 +- sim/pseudo_inst.cc | 2 +- sim/system.cc | 262 +---------------------------- sim/system.hh | 55 ++---- 15 files changed, 447 insertions(+), 322 deletions(-) create mode 100644 arch/alpha/system.cc create mode 100644 arch/alpha/system.hh diff --git a/SConscript b/SConscript index 966cb6d3e..d81baedad 100644 --- a/SConscript +++ b/SConscript @@ -212,6 +212,8 @@ mysql_sources = Split(''' # Full-system sources full_system_sources = Split(''' + arch/alpha/system.cc + base/crc.cc base/inet.cc base/remote_gdb.cc diff --git a/arch/alpha/system.cc b/arch/alpha/system.cc new file mode 100644 index 000000000..b841a6d53 --- /dev/null +++ b/arch/alpha/system.cc @@ -0,0 +1,298 @@ +/* + * Copyright (c) 2002-2005 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "arch/alpha/system.hh" +#include "base/remote_gdb.hh" +#include "base/loader/object_file.hh" +#include "base/loader/symtab.hh" +#include "base/trace.hh" +#include "mem/functional/memory_control.hh" +#include "mem/functional/physical.hh" +#include "sim/byteswap.hh" +#include "sim/builder.hh" +#include "targetarch/vtophys.hh" + +using namespace LittleEndianGuest; + +AlphaSystem::AlphaSystem(Params *p) + : System(p) +{ + consoleSymtab = new SymbolTable; + palSymtab = new SymbolTable; + + + /** + * Load the pal, and console code into memory + */ + // Load Console Code + console = createObjectFile(params()->console_path); + if (console == NULL) + fatal("Could not load console file %s", params()->console_path); + + // Load pal file + pal = createObjectFile(params()->palcode); + if (pal == NULL) + fatal("Could not load PALcode file %s", params()->palcode); + + + // Load program sections into memory + pal->loadSections(physmem, true); + console->loadSections(physmem, true); + + // load symbols + if (!console->loadGlobalSymbols(consoleSymtab)) + panic("could not load console symbols\n"); + + if (!pal->loadGlobalSymbols(palSymtab)) + panic("could not load pal symbols\n"); + + if (!pal->loadLocalSymbols(palSymtab)) + panic("could not load pal symbols\n"); + + if (!console->loadGlobalSymbols(debugSymbolTable)) + panic("could not load console symbols\n"); + + if (!pal->loadGlobalSymbols(debugSymbolTable)) + panic("could not load pal symbols\n"); + + if (!pal->loadLocalSymbols(debugSymbolTable)) + panic("could not load pal symbols\n"); + + Addr addr = 0; +#ifndef NDEBUG + consolePanicEvent = addConsoleFuncEvent("panic"); +#endif + + /** + * Copy the osflags (kernel arguments) into the consoles + * memory. (Presently Linux does not use the console service + * routine to get these command line arguments, but Tru64 and + * others do.) + */ + if (consoleSymtab->findAddress("env_booted_osflags", addr)) { + Addr paddr = vtophys(physmem, addr); + char *osflags = (char *)physmem->dma_addr(paddr, sizeof(uint32_t)); + + if (osflags) + strcpy(osflags, params()->boot_osflags.c_str()); + } + + /** + * Set the hardware reset parameter block system type and revision + * information to Tsunami. + */ + if (consoleSymtab->findAddress("m5_rpb", addr)) { + Addr paddr = vtophys(physmem, addr); + char *hwrpb = (char *)physmem->dma_addr(paddr, sizeof(uint64_t)); + + if (!hwrpb) + panic("could not translate hwrpb addr\n"); + + *(uint64_t*)(hwrpb+0x50) = htog(params()->system_type); + *(uint64_t*)(hwrpb+0x58) = htog(params()->system_rev); + } else + panic("could not find hwrpb\n"); + +} + +AlphaSystem::~AlphaSystem() +{ + delete consoleSymtab; + delete console; + delete pal; +#ifdef DEBUG + delete consolePanicEvent; +#endif +} + +/** + * This function fixes up addresses that are used to match PCs for + * hooking simulator events on to target function executions. + * + * Alpha binaries may have multiple global offset table (GOT) + * sections. A function that uses the GOT starts with a + * two-instruction prolog which sets the global pointer (gp == r29) to + * the appropriate GOT section. The proper gp value is calculated + * based on the function address, which must be passed by the caller + * in the procedure value register (pv aka t12 == r27). This sequence + * looks like the following: + * + * opcode Ra Rb offset + * ldah gp,X(pv) 09 29 27 X + * lda gp,Y(gp) 08 29 29 Y + * + * for some constant offsets X and Y. The catch is that the linker + * (or maybe even the compiler, I'm not sure) may recognize that the + * caller and callee are using the same GOT section, making this + * prolog redundant, and modify the call target to skip these + * instructions. If we check for execution of the first instruction + * of a function (the one the symbol points to) to detect when to skip + * it, we'll miss all these modified calls. It might work to + * unconditionally check for the third instruction, but not all + * functions have this prolog, and there's some chance that those + * first two instructions could have undesired consequences. So we do + * the Right Thing and pattern-match the first two instructions of the + * function to decide where to patch. + * + * Eventually this code should be moved into an ISA-specific file. + */ +Addr +AlphaSystem::fixFuncEventAddr(Addr addr) +{ + // mask for just the opcode, Ra, and Rb fields (not the offset) + const uint32_t inst_mask = 0xffff0000; + // ldah gp,X(pv): opcode 9, Ra = 29, Rb = 27 + const uint32_t gp_ldah_pattern = (9 << 26) | (29 << 21) | (27 << 16); + // lda gp,Y(gp): opcode 8, Ra = 29, rb = 29 + const uint32_t gp_lda_pattern = (8 << 26) | (29 << 21) | (29 << 16); + // instruction size + const int sz = sizeof(uint32_t); + + Addr paddr = vtophys(physmem, addr); + uint32_t i1 = *(uint32_t *)physmem->dma_addr(paddr, sz); + uint32_t i2 = *(uint32_t *)physmem->dma_addr(paddr+sz, sz); + + if ((i1 & inst_mask) == gp_ldah_pattern && + (i2 & inst_mask) == gp_lda_pattern) { + Addr new_addr = addr + 2*sz; + DPRINTF(Loader, "fixFuncEventAddr: %p -> %p", addr, new_addr); + return new_addr; + } else { + return addr; + } +} + + +void +AlphaSystem::setAlphaAccess(Addr access) +{ + Addr addr = 0; + if (consoleSymtab->findAddress("m5AlphaAccess", addr)) { + Addr paddr = vtophys(physmem, addr); + uint64_t *m5AlphaAccess = + (uint64_t *)physmem->dma_addr(paddr, sizeof(uint64_t)); + + if (!m5AlphaAccess) + panic("could not translate m5AlphaAccess addr\n"); + + *m5AlphaAccess = htog(EV5::Phys2K0Seg(access)); + } else + panic("could not find m5AlphaAccess\n"); +} + +bool +AlphaSystem::breakpoint() +{ + return remoteGDB[0]->trap(ALPHA_KENTRY_INT); +} + +void +AlphaSystem::serialize(std::ostream &os) +{ + System::serialize(os); + consoleSymtab->serialize("console_symtab", os); + palSymtab->serialize("pal_symtab", os); +} + + +void +AlphaSystem::unserialize(Checkpoint *cp, const std::string §ion) +{ + System::unserialize(cp,section); + consoleSymtab->unserialize("console_symtab", cp, section); + palSymtab->unserialize("pal_symtab", cp, section); +} + + +BEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaSystem) + + Param boot_cpu_frequency; + SimObjectParam memctrl; + SimObjectParam physmem; + + Param kernel; + Param console; + Param pal; + + Param boot_osflags; + Param readfile; + Param init_param; + + Param system_type; + Param system_rev; + + Param bin; + VectorParam binned_fns; + Param bin_int; + +END_DECLARE_SIM_OBJECT_PARAMS(AlphaSystem) + +BEGIN_INIT_SIM_OBJECT_PARAMS(AlphaSystem) + + INIT_PARAM(boot_cpu_frequency, "Frequency of the boot CPU"), + INIT_PARAM(memctrl, "memory controller"), + INIT_PARAM(physmem, "phsyical memory"), + INIT_PARAM(kernel, "file that contains the kernel code"), + INIT_PARAM(console, "file that contains the console code"), + INIT_PARAM(pal, "file that contains palcode"), + INIT_PARAM_DFLT(boot_osflags, "flags to pass to the kernel during boot", + "a"), + INIT_PARAM_DFLT(readfile, "file to read startup script from", ""), + INIT_PARAM_DFLT(init_param, "numerical value to pass into simulator", 0), + INIT_PARAM_DFLT(system_type, "Type of system we are emulating", 34), + INIT_PARAM_DFLT(system_rev, "Revision of system we are emulating", 1<<10), + INIT_PARAM_DFLT(bin, "is this system to be binned", false), + INIT_PARAM(binned_fns, "functions to be broken down and binned"), + INIT_PARAM_DFLT(bin_int, "is interrupt code binned seperately?", true) + +END_INIT_SIM_OBJECT_PARAMS(AlphaSystem) + +CREATE_SIM_OBJECT(AlphaSystem) +{ + AlphaSystem::Params *p = new AlphaSystem::Params; + p->name = getInstanceName(); + p->boot_cpu_frequency = boot_cpu_frequency; + p->memctrl = memctrl; + p->physmem = physmem; + p->kernel_path = kernel; + p->console_path = console; + p->palcode = pal; + p->boot_osflags = boot_osflags; + p->init_param = init_param; + p->readfile = readfile; + p->system_type = system_type; + p->system_rev = system_rev; + p->bin = bin; + p->binned_fns = binned_fns; + p->bin_int = bin_int; + return new AlphaSystem(p); +} + +REGISTER_SIM_OBJECT("AlphaSystem", AlphaSystem) + + diff --git a/arch/alpha/system.hh b/arch/alpha/system.hh new file mode 100644 index 000000000..fe1307ac3 --- /dev/null +++ b/arch/alpha/system.hh @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2002-2005 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __ARCH_ALPHA_SYSTEM_HH__ +#define __ARCH_ALPHA_SYSTEM_HH__ + +#include +#include + +#include "sim/system.hh" +#include "base/loader/symtab.hh" +#include "cpu/pc_event.hh" +#include "kern/system_events.hh" +#include "sim/sim_object.hh" + +class AlphaSystem : public System +{ + public: + struct Params : public System::Params + { + std::string console_path; + std::string palcode; + std::string boot_osflags; + uint64_t system_type; + uint64_t system_rev; + }; + + AlphaSystem(Params *p); + + ~AlphaSystem(); + + virtual bool breakpoint(); + +/** + * Serialization stuff + */ + public: + virtual void serialize(std::ostream &os); + virtual void unserialize(Checkpoint *cp, const std::string §ion); + + /** + * Set the m5AlphaAccess pointer in the console + */ + void setAlphaAccess(Addr access); + + /** console symbol table */ + SymbolTable *consoleSymtab; + + /** pal symbol table */ + SymbolTable *palSymtab; + + /** Object pointer for the console code */ + ObjectFile *console; + + /** Object pointer for the PAL code */ + ObjectFile *pal; + +#ifndef NDEBUG + /** Event to halt the simulator if the console calls panic() */ + BreakPCEvent *consolePanicEvent; +#endif + protected: + const Params *params() const { return (const Params *)_params; } + + /** Add a function-based event to PALcode. */ + template + T *AlphaSystem::addPalFuncEvent(const char *lbl) + { + return addFuncEvent(palSymtab, lbl); + } + + /** Add a function-based event to the console code. */ + template + T *AlphaSystem::addConsoleFuncEvent(const char *lbl) + { + return addFuncEvent(consoleSymtab, lbl); + } + + virtual Addr fixFuncEventAddr(Addr addr); + +}; + +#endif + diff --git a/dev/alpha_console.cc b/dev/alpha_console.cc index 2e8bbd1dd..94f834b4f 100644 --- a/dev/alpha_console.cc +++ b/dev/alpha_console.cc @@ -34,6 +34,7 @@ #include #include +#include "arch/alpha/system.hh" #include "base/inifile.hh" #include "base/str.hh" #include "base/trace.hh" @@ -50,13 +51,12 @@ #include "mem/functional/physical.hh" #include "sim/builder.hh" #include "sim/sim_object.hh" -#include "sim/system.hh" using namespace std; using namespace AlphaISA; AlphaConsole::AlphaConsole(const string &name, SimConsole *cons, SimpleDisk *d, - System *s, BaseCPU *c, Platform *p, + AlphaSystem *s, BaseCPU *c, Platform *p, MemoryController *mmu, Addr a, HierParams *hier, Bus *pio_bus) : PioDevice(name, p), disk(d), console(cons), system(s), cpu(c), addr(a) @@ -323,7 +323,7 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaConsole) SimObjectParam disk; SimObjectParam mmu; Param addr; - SimObjectParam system; + SimObjectParam system; SimObjectParam cpu; SimObjectParam platform; SimObjectParam pio_bus; diff --git a/dev/alpha_console.hh b/dev/alpha_console.hh index 2d1c1e634..86ef021e9 100644 --- a/dev/alpha_console.hh +++ b/dev/alpha_console.hh @@ -41,7 +41,7 @@ class BaseCPU; class SimConsole; -class System; +class AlphaSystem; class SimpleDisk; /** @@ -90,7 +90,7 @@ class AlphaConsole : public PioDevice SimConsole *console; /** a pointer to the system we are running in */ - System *system; + AlphaSystem *system; /** a pointer to the CPU boot cpu */ BaseCPU *cpu; @@ -101,7 +101,7 @@ class AlphaConsole : public PioDevice public: /** Standard Constructor */ AlphaConsole(const std::string &name, SimConsole *cons, SimpleDisk *d, - System *s, BaseCPU *c, Platform *platform, + AlphaSystem *s, BaseCPU *c, Platform *platform, MemoryController *mmu, Addr addr, HierParams *hier, Bus *pio_bus); diff --git a/kern/freebsd/freebsd_system.cc b/kern/freebsd/freebsd_system.cc index cead8caaf..a9052081a 100644 --- a/kern/freebsd/freebsd_system.cc +++ b/kern/freebsd/freebsd_system.cc @@ -33,6 +33,7 @@ * */ +#include "arch/alpha/system.hh" #include "base/loader/symtab.hh" #include "cpu/exec_context.hh" #include "kern/freebsd/freebsd_system.hh" @@ -49,7 +50,7 @@ using namespace std; using namespace TheISA; FreebsdSystem::FreebsdSystem(Params *p) - : System(p) + : AlphaSystem(p) { /** * Any time DELAY is called just skip the function. @@ -143,7 +144,7 @@ END_INIT_SIM_OBJECT_PARAMS(FreebsdSystem) CREATE_SIM_OBJECT(FreebsdSystem) { - System::Params *p = new System::Params; + AlphaSystem::Params *p = new AlphaSystem::Params; p->name = getInstanceName(); p->boot_cpu_frequency = boot_cpu_frequency; p->memctrl = memctrl; diff --git a/kern/freebsd/freebsd_system.hh b/kern/freebsd/freebsd_system.hh index ecb842ec6..f87fb03ef 100644 --- a/kern/freebsd/freebsd_system.hh +++ b/kern/freebsd/freebsd_system.hh @@ -31,7 +31,7 @@ #include "kern/system_events.hh" -class FreebsdSystem : public System +class FreebsdSystem : public AlphaSystem { private: class SkipCalibrateClocksEvent : public SkipFuncEvent diff --git a/kern/kernel_stats.cc b/kern/kernel_stats.cc index 50bbaee00..6d2f2a774 100644 --- a/kern/kernel_stats.cc +++ b/kern/kernel_stats.cc @@ -47,7 +47,7 @@ Statistics::Statistics(ExecContext *context) : xc(context), idleProcess((Addr)-1), themode(kernel), lastModeTick(0), iplLast(0), iplLastTick(0) { - bin_int = xc->system->params->bin_int; + bin_int = xc->system->params()->bin_int; } void diff --git a/kern/linux/linux_system.cc b/kern/linux/linux_system.cc index c5a9e184a..db13da0ec 100644 --- a/kern/linux/linux_system.cc +++ b/kern/linux/linux_system.cc @@ -35,6 +35,7 @@ * up boot time. */ +#include "arch/alpha/system.hh" #include "base/loader/symtab.hh" #include "cpu/exec_context.hh" #include "cpu/base.hh" @@ -53,7 +54,7 @@ using namespace std; using namespace TheISA; LinuxSystem::LinuxSystem(Params *p) - : System(p) + : AlphaSystem(p) { Addr addr = 0; Addr paddr = 0; @@ -73,7 +74,7 @@ LinuxSystem::LinuxSystem(Params *p) paddr = vtophys(physmem, CommandLine()); char *commandline = (char *)physmem->dma_addr(paddr, sizeof(uint64_t)); if (commandline) - strncpy(commandline, params->boot_osflags.c_str(), CommandLineSize); + strncpy(commandline, params()->boot_osflags.c_str(), CommandLineSize); /** * find the address of the est_cycle_freq variable and insert it @@ -146,7 +147,7 @@ LinuxSystem::LinuxSystem(Params *p) printThreadEvent = NULL; } - if (params->bin_int) { + if (params()->bin_int) { intStartEvent = addPalFuncEvent("sys_int_21"); if (!intStartEvent) panic("could not find symbol: sys_int_21\n"); @@ -277,7 +278,7 @@ END_INIT_SIM_OBJECT_PARAMS(LinuxSystem) CREATE_SIM_OBJECT(LinuxSystem) { - System::Params *p = new System::Params; + AlphaSystem::Params *p = new AlphaSystem::Params; p->name = getInstanceName(); p->boot_cpu_frequency = boot_cpu_frequency; p->memctrl = memctrl; diff --git a/kern/linux/linux_system.hh b/kern/linux/linux_system.hh index f883bef93..9fecb7290 100644 --- a/kern/linux/linux_system.hh +++ b/kern/linux/linux_system.hh @@ -40,7 +40,7 @@ class PrintThreadInfo; * It points to objects that are the system binaries to load and patches them * appropriately to work in simulator. */ -class LinuxSystem : public System +class LinuxSystem : public AlphaSystem { private: class SkipDelayLoopEvent : public SkipFuncEvent diff --git a/kern/tru64/tru64_system.cc b/kern/tru64/tru64_system.cc index ebcdc1553..8337d38db 100644 --- a/kern/tru64/tru64_system.cc +++ b/kern/tru64/tru64_system.cc @@ -42,7 +42,7 @@ using namespace std; Tru64System::Tru64System(Tru64System::Params *p) - : System(p) + : AlphaSystem(p) { Addr addr = 0; if (kernelSymtab->findAddress("enable_async_printf", addr)) { @@ -136,7 +136,7 @@ END_INIT_SIM_OBJECT_PARAMS(Tru64System) CREATE_SIM_OBJECT(Tru64System) { - System::Params *p = new System::Params; + AlphaSystem::Params *p = new AlphaSystem::Params; p->name = getInstanceName(); p->boot_cpu_frequency = boot_cpu_frequency; p->memctrl = memctrl; diff --git a/kern/tru64/tru64_system.hh b/kern/tru64/tru64_system.hh index d4eb5a59a..38e6d9dd7 100644 --- a/kern/tru64/tru64_system.hh +++ b/kern/tru64/tru64_system.hh @@ -29,8 +29,9 @@ #ifndef __KERN_TRU64_TRU64_SYSTEM_HH__ #define __KERN_TRU64_TRU64_SYSTEM_HH__ -#include "sim/system.hh" +#include "arch/alpha/system.hh" #include "arch/isa_traits.hh" +#include "sim/system.hh" class ExecContext; @@ -42,7 +43,7 @@ class DebugPrintfEvent; class DumpMbufEvent; class AlphaArguments; -class Tru64System : public System +class Tru64System : public AlphaSystem { private: #ifdef DEBUG diff --git a/sim/pseudo_inst.cc b/sim/pseudo_inst.cc index 58ea8266f..0250352f4 100644 --- a/sim/pseudo_inst.cc +++ b/sim/pseudo_inst.cc @@ -171,7 +171,7 @@ namespace AlphaPseudo uint64_t readfile(ExecContext *xc, Addr vaddr, uint64_t len, uint64_t offset) { - const string &file = xc->cpu->system->params->readfile; + const string &file = xc->cpu->system->params()->readfile; if (file.empty()) { return ULL(0); } diff --git a/sim/system.cc b/sim/system.cc index 41de8cee4..e138a6c22 100644 --- a/sim/system.cc +++ b/sim/system.cc @@ -1,31 +1,3 @@ -/* - * Copyright (c) 2002-2005 The Regents of The University of Michigan - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - #include "base/loader/object_file.hh" #include "base/loader/symtab.hh" #include "base/remote_gdb.hh" @@ -49,38 +21,23 @@ int System::numSystemsRunning = 0; System::System(Params *p) : SimObject(p->name), memctrl(p->memctrl), physmem(p->physmem), - init_param(p->init_param), numcpus(0), params(p) + init_param(p->init_param), numcpus(0), _params(p) { // add self to global system list systemList.push_back(this); kernelSymtab = new SymbolTable; - consoleSymtab = new SymbolTable; - palSymtab = new SymbolTable; debugSymbolTable = new SymbolTable; /** - * Load the kernel, pal, and console code into memory + * Load the kernel code into memory */ // Load kernel code - kernel = createObjectFile(params->kernel_path); + kernel = createObjectFile(params()->kernel_path); if (kernel == NULL) - fatal("Could not load kernel file %s", params->kernel_path); - - // Load Console Code - console = createObjectFile(params->console_path); - if (console == NULL) - fatal("Could not load console file %s", params->console_path); - - // Load pal file - pal = createObjectFile(params->palcode); - if (pal == NULL) - fatal("Could not load PALcode file %s", params->palcode); - + fatal("Could not load kernel file %s", params()->kernel_path); // Load program sections into memory - pal->loadSections(physmem, true); - console->loadSections(physmem, true); kernel->loadSections(physmem, true); // setup entry points @@ -95,71 +52,17 @@ System::System(Params *p) if (!kernel->loadLocalSymbols(kernelSymtab)) panic("could not load kernel local symbols\n"); - if (!console->loadGlobalSymbols(consoleSymtab)) - panic("could not load console symbols\n"); - - if (!pal->loadGlobalSymbols(palSymtab)) - panic("could not load pal symbols\n"); - - if (!pal->loadLocalSymbols(palSymtab)) - panic("could not load pal symbols\n"); - if (!kernel->loadGlobalSymbols(debugSymbolTable)) panic("could not load kernel symbols\n"); if (!kernel->loadLocalSymbols(debugSymbolTable)) panic("could not load kernel local symbols\n"); - if (!console->loadGlobalSymbols(debugSymbolTable)) - panic("could not load console symbols\n"); - - if (!pal->loadGlobalSymbols(debugSymbolTable)) - panic("could not load pal symbols\n"); - - if (!pal->loadLocalSymbols(debugSymbolTable)) - panic("could not load pal symbols\n"); - - DPRINTF(Loader, "Kernel start = %#x\n", kernelStart); DPRINTF(Loader, "Kernel end = %#x\n", kernelEnd); DPRINTF(Loader, "Kernel entry = %#x\n", kernelEntry); DPRINTF(Loader, "Kernel loaded...\n"); - Addr addr = 0; -#ifndef NDEBUG - consolePanicEvent = addConsoleFuncEvent("panic"); -#endif - - /** - * Copy the osflags (kernel arguments) into the consoles - * memory. (Presently Linux does not use the console service - * routine to get these command line arguments, but Tru64 and - * others do.) - */ - if (consoleSymtab->findAddress("env_booted_osflags", addr)) { - Addr paddr = vtophys(physmem, addr); - char *osflags = (char *)physmem->dma_addr(paddr, sizeof(uint32_t)); - - if (osflags) - strcpy(osflags, params->boot_osflags.c_str()); - } - - /** - * Set the hardware reset parameter block system type and revision - * information to Tsunami. - */ - if (consoleSymtab->findAddress("m5_rpb", addr)) { - Addr paddr = vtophys(physmem, addr); - char *hwrpb = (char *)physmem->dma_addr(paddr, sizeof(uint64_t)); - - if (!hwrpb) - panic("could not translate hwrpb addr\n"); - - *(uint64_t*)(hwrpb+0x50) = htog(params->system_type); - *(uint64_t*)(hwrpb+0x58) = htog(params->system_rev); - } else - panic("could not find hwrpb\n"); - // increment the number of running systms numSystemsRunning++; @@ -169,100 +72,13 @@ System::System(Params *p) System::~System() { delete kernelSymtab; - delete consoleSymtab; delete kernel; - delete console; - delete pal; delete kernelBinning; - -#ifdef DEBUG - delete consolePanicEvent; -#endif } -/** - * This function fixes up addresses that are used to match PCs for - * hooking simulator events on to target function executions. - * - * Alpha binaries may have multiple global offset table (GOT) - * sections. A function that uses the GOT starts with a - * two-instruction prolog which sets the global pointer (gp == r29) to - * the appropriate GOT section. The proper gp value is calculated - * based on the function address, which must be passed by the caller - * in the procedure value register (pv aka t12 == r27). This sequence - * looks like the following: - * - * opcode Ra Rb offset - * ldah gp,X(pv) 09 29 27 X - * lda gp,Y(gp) 08 29 29 Y - * - * for some constant offsets X and Y. The catch is that the linker - * (or maybe even the compiler, I'm not sure) may recognize that the - * caller and callee are using the same GOT section, making this - * prolog redundant, and modify the call target to skip these - * instructions. If we check for execution of the first instruction - * of a function (the one the symbol points to) to detect when to skip - * it, we'll miss all these modified calls. It might work to - * unconditionally check for the third instruction, but not all - * functions have this prolog, and there's some chance that those - * first two instructions could have undesired consequences. So we do - * the Right Thing and pattern-match the first two instructions of the - * function to decide where to patch. - * - * Eventually this code should be moved into an ISA-specific file. - */ -Addr -System::fixFuncEventAddr(Addr addr) -{ - // mask for just the opcode, Ra, and Rb fields (not the offset) - const uint32_t inst_mask = 0xffff0000; - // ldah gp,X(pv): opcode 9, Ra = 29, Rb = 27 - const uint32_t gp_ldah_pattern = (9 << 26) | (29 << 21) | (27 << 16); - // lda gp,Y(gp): opcode 8, Ra = 29, rb = 29 - const uint32_t gp_lda_pattern = (8 << 26) | (29 << 21) | (29 << 16); - // instruction size - const int sz = sizeof(uint32_t); - Addr paddr = vtophys(physmem, addr); - uint32_t i1 = *(uint32_t *)physmem->dma_addr(paddr, sz); - uint32_t i2 = *(uint32_t *)physmem->dma_addr(paddr+sz, sz); - - if ((i1 & inst_mask) == gp_ldah_pattern && - (i2 & inst_mask) == gp_lda_pattern) { - Addr new_addr = addr + 2*sz; - DPRINTF(Loader, "fixFuncEventAddr: %p -> %p", addr, new_addr); - return new_addr; - } else { - return addr; - } -} - - -void -System::setAlphaAccess(Addr access) -{ - Addr addr = 0; - if (consoleSymtab->findAddress("m5AlphaAccess", addr)) { - Addr paddr = vtophys(physmem, addr); - uint64_t *m5AlphaAccess = - (uint64_t *)physmem->dma_addr(paddr, sizeof(uint64_t)); - - if (!m5AlphaAccess) - panic("could not translate m5AlphaAccess addr\n"); - - *m5AlphaAccess = htog(EV5::Phys2K0Seg(access)); - } else - panic("could not find m5AlphaAccess\n"); -} - - -bool -System::breakpoint() -{ - return remoteGDB[0]->trap(ALPHA_KENTRY_INT); -} int rgdb_wait = -1; @@ -336,8 +152,6 @@ System::serialize(ostream &os) kernelBinning->serialize(os); kernelSymtab->serialize("kernel_symtab", os); - consoleSymtab->serialize("console_symtab", os); - palSymtab->serialize("pal_symtab", os); } @@ -347,8 +161,6 @@ System::unserialize(Checkpoint *cp, const string §ion) kernelBinning->unserialize(cp, section); kernelSymtab->unserialize("kernel_symtab", cp, section); - consoleSymtab->unserialize("console_symtab", cp, section); - palSymtab->unserialize("pal_symtab", cp, section); } void @@ -369,69 +181,5 @@ printSystems() System::printSystems(); } -BEGIN_DECLARE_SIM_OBJECT_PARAMS(System) - - Param boot_cpu_frequency; - SimObjectParam memctrl; - SimObjectParam physmem; - - Param kernel; - Param console; - Param pal; - - Param boot_osflags; - Param readfile; - Param init_param; - - Param system_type; - Param system_rev; - - Param bin; - VectorParam binned_fns; - Param bin_int; - -END_DECLARE_SIM_OBJECT_PARAMS(System) - -BEGIN_INIT_SIM_OBJECT_PARAMS(System) - - INIT_PARAM(boot_cpu_frequency, "Frequency of the boot CPU"), - INIT_PARAM(memctrl, "memory controller"), - INIT_PARAM(physmem, "phsyical memory"), - INIT_PARAM(kernel, "file that contains the kernel code"), - INIT_PARAM(console, "file that contains the console code"), - INIT_PARAM(pal, "file that contains palcode"), - INIT_PARAM_DFLT(boot_osflags, "flags to pass to the kernel during boot", - "a"), - INIT_PARAM_DFLT(readfile, "file to read startup script from", ""), - INIT_PARAM_DFLT(init_param, "numerical value to pass into simulator", 0), - INIT_PARAM_DFLT(system_type, "Type of system we are emulating", 34), - INIT_PARAM_DFLT(system_rev, "Revision of system we are emulating", 1<<10), - INIT_PARAM_DFLT(bin, "is this system to be binned", false), - INIT_PARAM(binned_fns, "functions to be broken down and binned"), - INIT_PARAM_DFLT(bin_int, "is interrupt code binned seperately?", true) - -END_INIT_SIM_OBJECT_PARAMS(System) - -CREATE_SIM_OBJECT(System) -{ - System::Params *p = new System::Params; - p->name = getInstanceName(); - p->boot_cpu_frequency = boot_cpu_frequency; - p->memctrl = memctrl; - p->physmem = physmem; - p->kernel_path = kernel; - p->console_path = console; - p->palcode = pal; - p->boot_osflags = boot_osflags; - p->init_param = init_param; - p->readfile = readfile; - p->system_type = system_type; - p->system_rev = system_rev; - p->bin = bin; - p->binned_fns = binned_fns; - p->bin_int = bin_int; - return new System(p); -} - -REGISTER_SIM_OBJECT("System", System) +DEFINE_SIM_OBJECT_CLASS_NAME("System", System) diff --git a/sim/system.hh b/sim/system.hh index aa697c040..ea482a102 100644 --- a/sim/system.hh +++ b/sim/system.hh @@ -71,21 +71,9 @@ class System : public SimObject /** kernel symbol table */ SymbolTable *kernelSymtab; - /** console symbol table */ - SymbolTable *consoleSymtab; - - /** pal symbol table */ - SymbolTable *palSymtab; - /** Object pointer for the kernel code */ ObjectFile *kernel; - /** Object pointer for the console code */ - ObjectFile *console; - - /** Object pointer for the PAL code */ - ObjectFile *pal; - /** Begining of kernel code */ Addr kernelStart; @@ -97,11 +85,6 @@ class System : public SimObject Kernel::Binning *kernelBinning; -#ifndef NDEBUG - /** Event to halt the simulator if the console calls panic() */ - BreakPCEvent *consolePanicEvent; -#endif - protected: /** @@ -109,7 +92,7 @@ class System : public SimObject * events on to target function executions. See comment in * system.cc for details. */ - Addr fixFuncEventAddr(Addr addr); + virtual Addr fixFuncEventAddr(Addr addr) = 0; /** * Add a function-based event to the given function, to be looked @@ -135,24 +118,10 @@ class System : public SimObject return addFuncEvent(kernelSymtab, lbl); } - /** Add a function-based event to PALcode. */ - template - T *System::addPalFuncEvent(const char *lbl) - { - return addFuncEvent(palSymtab, lbl); - } - - /** Add a function-based event to the console code. */ - template - T *System::addConsoleFuncEvent(const char *lbl) - { - return addFuncEvent(consoleSymtab, lbl); - } - public: std::vector remoteGDB; std::vector gdbListen; - bool breakpoint(); + virtual bool breakpoint() = 0; public: struct Params @@ -167,27 +136,21 @@ class System : public SimObject bool bin_int; std::string kernel_path; - std::string console_path; - std::string palcode; - std::string boot_osflags; - std::string readfile; - uint64_t system_type; - uint64_t system_rev; }; - Params *params; + protected: + Params *_params; + + public: System(Params *p); ~System(); void startup(); - public: - /** - * Set the m5AlphaAccess pointer in the console - */ - void setAlphaAccess(Addr access); + const Params *params() const { return (const Params *)_params; } + public: /** * Returns the addess the kernel starts at. * @return address the kernel starts at @@ -224,6 +187,8 @@ class System : public SimObject static int numSystemsRunning; static void printSystems(); + + }; #endif // __SYSTEM_HH__ From e7825aab59e03b9691d361338fba222f56446f77 Mon Sep 17 00:00:00 2001 From: Kevin Lim Date: Fri, 3 Mar 2006 15:28:25 -0500 Subject: [PATCH 140/180] Changes to support automatic renaming of the shadow registers at decode time. This requires using an ExtMachInst (uint64_t) instead of the normal MachInst; the ExtMachInst is packed with extra decode context information. In the case of Alpha, the PAL mode is included. The shadow registers are folded into the normal integer registers to ease renaming indexing. Include the removed Opcdec class of instructions for faulting when a pal mode only instruction is decoded in non-pal mode. arch/alpha/ev5.cc: Changes to automatically map the shadow registers if the instruction is in PAL mode. arch/alpha/isa/branch.isa: arch/alpha/isa/decoder.isa: arch/alpha/isa/fp.isa: arch/alpha/isa/int.isa: arch/alpha/isa/mem.isa: arch/alpha/isa/pal.isa: arch/alpha/isa/unimp.isa: Changes for automatically using the shadow registers. Now instructions must decode based on an ExtMachInst, which is a MachInst with any decode context information concatenated onto the higher order bits. arch/alpha/isa/main.isa: Changes for automatically using the shadow registers. Now instructions must decode based on an ExtMachInst, which is a MachInst with any decode context information concatenated onto the higher order bits. The decoder (for Alpha) uses the 32nd bit in order to determine if the machine is in PAL mode. If it is, then it refers to the reg_redir table to determine the true index of the register it is using. Also include the opcdec instruction definition. arch/alpha/isa_traits.hh: Define ExtMachInst type that is used by the static inst in order to decode the instruction, given the context of being in pal mode or not. Redefine the number of Int registers, splitting it into NumIntArchRegs (32) and NumIntRegs (32 + 8 shadow registers). Change the dependence tags to reflect the integer registers include the 8 shadow registers. Define function to make an ExtMachInst. Currently it is somewhat specific to Alpha; in the future it must be decided to make this more generic and possibly slower, or leave it specific to each architecture and ifdef it within the CPU. arch/isa_parser.py: Have static insts decode on the ExtMachInst. base/remote_gdb.cc: Support the automatic remapping of shadow registers. Remote GDB must now look at the PC being read in order to tell if it should use the normal register indices or the shadow register indices. cpu/o3/regfile.hh: Comment out the pal registers; they are now a part of the integer registers. cpu/simple/cpu.cc: Create an ExtMachInst to decode on, based on the normal MachInst and the PC of the instructoin. cpu/static_inst.hh: Change from MachInst to ExtMachInst to support shadow register renaming. --HG-- extra : convert_revision : 1d23eabf735e297068e1917445a6348e9f8c88d5 --- arch/alpha/ev5.cc | 35 ------------------ arch/alpha/isa/branch.isa | 6 ++-- arch/alpha/isa/decoder.isa | 69 +++++++++++++++++++----------------- arch/alpha/isa/fp.isa | 2 +- arch/alpha/isa/int.isa | 2 +- arch/alpha/isa/main.isa | 21 +++++++---- arch/alpha/isa/mem.isa | 18 +++++----- arch/alpha/isa/opcdec.isa | 72 ++++++++++++++++++++++++++++++++++++++ arch/alpha/isa/pal.isa | 12 +++---- arch/alpha/isa/unimp.isa | 6 ++-- arch/alpha/isa_traits.hh | 51 +++++++++++++++++++-------- arch/isa_parser.py | 2 +- base/remote_gdb.cc | 39 ++++++++++++++++----- cpu/o3/regfile.hh | 2 +- cpu/simple/cpu.cc | 2 +- cpu/static_inst.hh | 14 ++++---- 16 files changed, 225 insertions(+), 128 deletions(-) create mode 100644 arch/alpha/isa/opcdec.isa diff --git a/arch/alpha/ev5.cc b/arch/alpha/ev5.cc index 2bb005eb4..9193e40f0 100644 --- a/arch/alpha/ev5.cc +++ b/arch/alpha/ev5.cc @@ -44,27 +44,6 @@ using namespace EV5; -//////////////////////////////////////////////////////////////////////// -// -// -// -void -AlphaISA::swap_palshadow(RegFile *regs, bool use_shadow) -{ - if (regs->pal_shadow == use_shadow) - panic("swap_palshadow: wrong PAL shadow state"); - - regs->pal_shadow = use_shadow; - - for (int i = 0; i < NumIntRegs; i++) { - if (reg_redir[i]) { - IntReg temp = regs->intRegFile[i]; - regs->intRegFile[i] = regs->palregs[i]; - regs->palregs[i] = temp; - } - } -} - //////////////////////////////////////////////////////////////////////// // // Machine dependent functions @@ -73,8 +52,6 @@ void AlphaISA::initCPU(RegFile *regs, int cpuId) { initIPRs(®s->miscRegs, cpuId); - // CPU comes up with PAL regs enabled - swap_palshadow(regs, true); regs->intRegFile[16] = cpuId; regs->intRegFile[0] = cpuId; @@ -83,12 +60,6 @@ AlphaISA::initCPU(RegFile *regs, int cpuId) regs->npc = regs->pc + sizeof(MachInst); } -const int AlphaISA::reg_redir[AlphaISA::NumIntRegs] = { - /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, - /* 8 */ 1, 1, 1, 1, 1, 1, 1, 0, - /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0, - /* 24 */ 0, 1, 0, 0, 0, 0, 0, 0 }; - //////////////////////////////////////////////////////////////////////// // // @@ -186,9 +157,6 @@ ExecContext::ev5_temp_trap(Fault fault) readMiscReg(AlphaISA::IPR_EXC_ADDR) + 4); } - if (!inPalMode()) - AlphaISA::swap_palshadow(®s, true); - regs.pc = readMiscReg(AlphaISA::IPR_PAL_BASE) + (dynamic_cast(fault.get()))->vect(); regs.npc = regs.pc + sizeof(MachInst); @@ -233,9 +201,6 @@ ExecContext::hwrei() if (!misspeculating()) { kernelStats->hwrei(); - if ((readMiscReg(AlphaISA::IPR_EXC_ADDR) & 1) == 0) - AlphaISA::swap_palshadow(®s, false); - cpu->checkInterrupts = true; } diff --git a/arch/alpha/isa/branch.isa b/arch/alpha/isa/branch.isa index 9a7fb9d79..b528df938 100644 --- a/arch/alpha/isa/branch.isa +++ b/arch/alpha/isa/branch.isa @@ -46,7 +46,7 @@ output header {{ mutable const SymbolTable *cachedSymtab; /// Constructor - PCDependentDisassembly(const char *mnem, MachInst _machInst, + PCDependentDisassembly(const char *mnem, ExtMachInst _machInst, OpClass __opClass) : AlphaStaticInst(mnem, _machInst, __opClass), cachedPC(0), cachedSymtab(0) @@ -68,7 +68,7 @@ output header {{ int32_t disp; /// Constructor. - Branch(const char *mnem, MachInst _machInst, OpClass __opClass) + Branch(const char *mnem, ExtMachInst _machInst, OpClass __opClass) : PCDependentDisassembly(mnem, _machInst, __opClass), disp(BRDISP << 2) { @@ -93,7 +93,7 @@ output header {{ public: /// Constructor - Jump(const char *mnem, MachInst _machInst, OpClass __opClass) + Jump(const char *mnem, ExtMachInst _machInst, OpClass __opClass) : PCDependentDisassembly(mnem, _machInst, __opClass), disp(BRDISP) { diff --git a/arch/alpha/isa/decoder.isa b/arch/alpha/isa/decoder.isa index ca38dca92..ea858dd7d 100644 --- a/arch/alpha/isa/decoder.isa +++ b/arch/alpha/isa/decoder.isa @@ -681,7 +681,6 @@ decode OPCODE default Unknown::unknown() { bool dopal = xc->simPalCheck(palFunc); if (dopal) { - AlphaISA::swap_palshadow(&xc->xcBase()->regs, true); xc->setMiscRegWithEffect(AlphaISA::IPR_EXC_ADDR, NPC); NPC = xc->readMiscRegWithEffect(AlphaISA::IPR_PAL_BASE, fault) + palOffset; } @@ -705,50 +704,56 @@ decode OPCODE default Unknown::unknown() { #endif #if FULL_SYSTEM - format HwLoad { - 0x1b: decode HW_LDST_QUAD { - 0: hw_ld({{ EA = (Rb + disp) & ~3; }}, {{ Ra = Mem.ul; }}, L); - 1: hw_ld({{ EA = (Rb + disp) & ~7; }}, {{ Ra = Mem.uq; }}, Q); + 0x1b: decode PALMODE { + 0: OpcdecFault::hw_st_quad(); + 1: decode HW_LDST_QUAD { + format HwLoad { + 0: hw_ld({{ EA = (Rb + disp) & ~3; }}, {{ Ra = Mem.ul; }}, L); + 1: hw_ld({{ EA = (Rb + disp) & ~7; }}, {{ Ra = Mem.uq; }}, Q); + } } } - format HwStore { - 0x1f: decode HW_LDST_COND { - 0: decode HW_LDST_QUAD { - 0: hw_st({{ EA = (Rb + disp) & ~3; }}, - {{ Mem.ul = Ra<31:0>; }}, L); - 1: hw_st({{ EA = (Rb + disp) & ~7; }}, - {{ Mem.uq = Ra.uq; }}, Q); - } + 0x1f: decode PALMODE { + 0: OpcdecFault::hw_st_cond(); + format HwStore { + 1: decode HW_LDST_COND { + 0: decode HW_LDST_QUAD { + 0: hw_st({{ EA = (Rb + disp) & ~3; }}, + {{ Mem.ul = Ra<31:0>; }}, L); + 1: hw_st({{ EA = (Rb + disp) & ~7; }}, + {{ Mem.uq = Ra.uq; }}, Q); + } - 1: FailUnimpl::hw_st_cond(); + 1: FailUnimpl::hw_st_cond(); + } } } - format HwMoveIPR { - 0x19: hw_mfpr({{ - // this instruction is only valid in PAL mode - if (!xc->inPalMode()) { - fault = new UnimplementedOpcodeFault; - } - else { + 0x19: decode PALMODE { + 0: OpcdecFault::hw_mfpr(); + format HwMoveIPR { + 1: hw_mfpr({{ Ra = xc->readMiscRegWithEffect(ipr_index, fault); - } - }}); - 0x1d: hw_mtpr({{ - // this instruction is only valid in PAL mode - if (!xc->inPalMode()) { - fault = new UnimplementedOpcodeFault; - } - else { + }}); + } + } + + 0x1d: decode PALMODE { + 0: OpcdecFault::hw_mtpr(); + format HwMoveIPR { + 1: hw_mtpr({{ xc->setMiscRegWithEffect(ipr_index, Ra); if (traceData) { traceData->setData(Ra); } - } - }}); + }}); + } } format BasicOperate { - 0x1e: hw_rei({{ xc->hwrei(); }}, IsSerializing); + 0x1e: decode PALMODE { + 0: OpcdecFault::hw_rei(); + 1:hw_rei({{ xc->hwrei(); }}, IsSerializing); + } // M5 special opcodes use the reserved 0x01 opcode space 0x01: decode M5FUNC { diff --git a/arch/alpha/isa/fp.isa b/arch/alpha/isa/fp.isa index 13656359f..f34c13c42 100644 --- a/arch/alpha/isa/fp.isa +++ b/arch/alpha/isa/fp.isa @@ -106,7 +106,7 @@ output header {{ mutable bool warnedOnTrapping; /// Constructor - AlphaFP(const char *mnem, MachInst _machInst, OpClass __opClass) + AlphaFP(const char *mnem, ExtMachInst _machInst, OpClass __opClass) : AlphaStaticInst(mnem, _machInst, __opClass), roundingMode((enum RoundingMode)FP_ROUNDMODE), trappingMode((enum TrappingMode)FP_TRAPMODE), diff --git a/arch/alpha/isa/int.isa b/arch/alpha/isa/int.isa index 049437f8c..17ecc1a51 100644 --- a/arch/alpha/isa/int.isa +++ b/arch/alpha/isa/int.isa @@ -37,7 +37,7 @@ output header {{ uint8_t imm; /// Constructor - IntegerImm(const char *mnem, MachInst _machInst, OpClass __opClass) + IntegerImm(const char *mnem, ExtMachInst _machInst, OpClass __opClass) : AlphaStaticInst(mnem, _machInst, __opClass), imm(INTIMM) { } diff --git a/arch/alpha/isa/main.isa b/arch/alpha/isa/main.isa index ad9c2a55e..17c9989ab 100644 --- a/arch/alpha/isa/main.isa +++ b/arch/alpha/isa/main.isa @@ -79,6 +79,7 @@ namespace AlphaISA; // // Universal (format-independent) fields +def bitfield PALMODE <32:32>; def bitfield OPCODE <31:26>; def bitfield RA <25:21>; def bitfield RB <20:16>; @@ -153,9 +154,12 @@ def operands {{ # Int regs default to unsigned, but code should not count on this. # For clarity, descriptions that depend on unsigned behavior should # explicitly specify '.uq'. - 'Ra': ('IntReg', 'uq', 'RA', 'IsInteger', 1), - 'Rb': ('IntReg', 'uq', 'RB', 'IsInteger', 2), - 'Rc': ('IntReg', 'uq', 'RC', 'IsInteger', 3), + 'Ra': ('IntReg', 'uq', 'PALMODE ? AlphaISA::reg_redir[RA] : RA', + 'IsInteger', 1), + 'Rb': ('IntReg', 'uq', 'PALMODE ? AlphaISA::reg_redir[RB] : RB', + 'IsInteger', 2), + 'Rc': ('IntReg', 'uq', 'PALMODE ? AlphaISA::reg_redir[RC] : RC', + 'IsInteger', 3), 'Fa': ('FloatReg', 'df', 'FA', 'IsFloating', 1), 'Fb': ('FloatReg', 'df', 'FB', 'IsFloating', 2), 'Fc': ('FloatReg', 'df', 'FC', 'IsFloating', 3), @@ -200,7 +204,7 @@ output header {{ }; /// Constructor. - AlphaStaticInst(const char *mnem, MachInst _machInst, + AlphaStaticInst(const char *mnem, ExtMachInst _machInst, OpClass __opClass) : StaticInst(mnem, _machInst, __opClass) { @@ -272,7 +276,7 @@ def template BasicDeclare {{ { public: /// Constructor. - %(class_name)s(MachInst machInst); + %(class_name)s(ExtMachInst machInst); %(BasicExecDeclare)s }; @@ -280,7 +284,7 @@ def template BasicDeclare {{ // Basic instruction class constructor template. def template BasicConstructor {{ - inline %(class_name)s::%(class_name)s(MachInst machInst) + inline %(class_name)s::%(class_name)s(ExtMachInst machInst) : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s) { %(constructor)s; @@ -344,7 +348,7 @@ output header {{ public: /// Constructor - Nop(const std::string _originalDisassembly, MachInst _machInst) + Nop(const std::string _originalDisassembly, ExtMachInst _machInst) : AlphaStaticInst("nop", _machInst, No_OpClass), originalDisassembly(_originalDisassembly) { @@ -428,6 +432,9 @@ def format BasicOperateWithNopCheck(code, *opt_args) {{ // PAL instruction templates, formats, etc. ##include "m5/arch/alpha/isa/pal.isa" +// Opcdec fault instruction templates, formats, etc. +##include "m5/arch/alpha/isa/opcdec.isa" + // Unimplemented instruction templates, formats, etc. ##include "m5/arch/alpha/isa/unimp.isa" diff --git a/arch/alpha/isa/mem.isa b/arch/alpha/isa/mem.isa index 61d6ea8fa..3c8b4f755 100644 --- a/arch/alpha/isa/mem.isa +++ b/arch/alpha/isa/mem.isa @@ -42,7 +42,7 @@ output header {{ const StaticInstPtr memAccPtr; /// Constructor - Memory(const char *mnem, MachInst _machInst, OpClass __opClass, + Memory(const char *mnem, ExtMachInst _machInst, OpClass __opClass, StaticInstPtr _eaCompPtr = nullStaticInstPtr, StaticInstPtr _memAccPtr = nullStaticInstPtr) : AlphaStaticInst(mnem, _machInst, __opClass), @@ -70,7 +70,7 @@ output header {{ int32_t disp; /// Constructor. - MemoryDisp32(const char *mnem, MachInst _machInst, OpClass __opClass, + MemoryDisp32(const char *mnem, ExtMachInst _machInst, OpClass __opClass, StaticInstPtr _eaCompPtr = nullStaticInstPtr, StaticInstPtr _memAccPtr = nullStaticInstPtr) : Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr), @@ -89,7 +89,7 @@ output header {{ { protected: /// Constructor - MemoryNoDisp(const char *mnem, MachInst _machInst, OpClass __opClass, + MemoryNoDisp(const char *mnem, ExtMachInst _machInst, OpClass __opClass, StaticInstPtr _eaCompPtr = nullStaticInstPtr, StaticInstPtr _memAccPtr = nullStaticInstPtr) : Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr) @@ -141,7 +141,7 @@ def template LoadStoreDeclare {{ { public: /// Constructor - EAComp(MachInst machInst); + EAComp(ExtMachInst machInst); %(BasicExecDeclare)s }; @@ -153,7 +153,7 @@ def template LoadStoreDeclare {{ { public: /// Constructor - MemAcc(MachInst machInst); + MemAcc(ExtMachInst machInst); %(BasicExecDeclare)s }; @@ -161,7 +161,7 @@ def template LoadStoreDeclare {{ public: /// Constructor. - %(class_name)s(MachInst machInst); + %(class_name)s(ExtMachInst machInst); %(BasicExecDeclare)s @@ -186,19 +186,19 @@ def template LoadStoreConstructor {{ /** TODO: change op_class to AddrGenOp or something (requires * creating new member of OpClass enum in op_class.hh, updating * config files, etc.). */ - inline %(class_name)s::EAComp::EAComp(MachInst machInst) + inline %(class_name)s::EAComp::EAComp(ExtMachInst machInst) : %(base_class)s("%(mnemonic)s (EAComp)", machInst, IntAluOp) { %(ea_constructor)s; } - inline %(class_name)s::MemAcc::MemAcc(MachInst machInst) + inline %(class_name)s::MemAcc::MemAcc(ExtMachInst machInst) : %(base_class)s("%(mnemonic)s (MemAcc)", machInst, %(op_class)s) { %(memacc_constructor)s; } - inline %(class_name)s::%(class_name)s(MachInst machInst) + inline %(class_name)s::%(class_name)s(ExtMachInst machInst) : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s, new EAComp(machInst), new MemAcc(machInst)) { diff --git a/arch/alpha/isa/opcdec.isa b/arch/alpha/isa/opcdec.isa new file mode 100644 index 000000000..bb2f91e5c --- /dev/null +++ b/arch/alpha/isa/opcdec.isa @@ -0,0 +1,72 @@ +// -*- mode:c++ -*- + +// 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. + +output header {{ + /** + * Static instruction class for instructions that cause an OPCDEC fault + * when executed. This is currently only for PAL mode instructions + * executed in non-PAL mode. + */ + class OpcdecFault : public AlphaStaticInst + { + public: + /// Constructor + OpcdecFault(ExtMachInst _machInst) + : AlphaStaticInst("opcdec fault", _machInst, No_OpClass) + { + } + + %(BasicExecDeclare)s + + std::string + generateDisassembly(Addr pc, const SymbolTable *symtab) const; + }; +}}; + +output decoder {{ + std::string + OpcdecFault::generateDisassembly(Addr pc, const SymbolTable *symtab) const + { + return csprintf("%-10s (inst 0x%x, opcode 0x%x)", + " OPCDEC fault", machInst, OPCODE); + } +}}; + +output exec {{ + Fault + OpcdecFault::execute(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + return new UnimplementedOpcodeFault; + } +}}; + +def format OpcdecFault() {{ + decode_block = 'return new OpcdecFault(machInst);\n' +}}; + diff --git a/arch/alpha/isa/pal.isa b/arch/alpha/isa/pal.isa index 49e5bff12..e07bea5a8 100644 --- a/arch/alpha/isa/pal.isa +++ b/arch/alpha/isa/pal.isa @@ -36,7 +36,7 @@ output header {{ protected: /// Constructor. - EmulatedCallPal(const char *mnem, MachInst _machInst, + EmulatedCallPal(const char *mnem, ExtMachInst _machInst, OpClass __opClass) : AlphaStaticInst(mnem, _machInst, __opClass) { @@ -83,7 +83,7 @@ output header {{ bool palPriv; ///< is this call privileged? /// Constructor. - CallPalBase(const char *mnem, MachInst _machInst, + CallPalBase(const char *mnem, ExtMachInst _machInst, OpClass __opClass); std::string @@ -93,7 +93,7 @@ output header {{ output decoder {{ inline - CallPalBase::CallPalBase(const char *mnem, MachInst _machInst, + CallPalBase::CallPalBase(const char *mnem, ExtMachInst _machInst, OpClass __opClass) : AlphaStaticInst(mnem, _machInst, __opClass), palFunc(PALFUNC) @@ -148,7 +148,7 @@ output header {{ int16_t disp; /// Constructor - HwLoadStore(const char *mnem, MachInst _machInst, OpClass __opClass, + HwLoadStore(const char *mnem, ExtMachInst _machInst, OpClass __opClass, StaticInstPtr _eaCompPtr = nullStaticInstPtr, StaticInstPtr _memAccPtr = nullStaticInstPtr); @@ -160,7 +160,7 @@ output header {{ output decoder {{ inline - HwLoadStore::HwLoadStore(const char *mnem, MachInst _machInst, + HwLoadStore::HwLoadStore(const char *mnem, ExtMachInst _machInst, OpClass __opClass, StaticInstPtr _eaCompPtr, StaticInstPtr _memAccPtr) @@ -231,7 +231,7 @@ output header {{ int ipr_index; /// Constructor - HwMoveIPR(const char *mnem, MachInst _machInst, OpClass __opClass) + HwMoveIPR(const char *mnem, ExtMachInst _machInst, OpClass __opClass) : AlphaStaticInst(mnem, _machInst, __opClass), ipr_index(HW_IPR_IDX) { diff --git a/arch/alpha/isa/unimp.isa b/arch/alpha/isa/unimp.isa index 09df39706..392522801 100644 --- a/arch/alpha/isa/unimp.isa +++ b/arch/alpha/isa/unimp.isa @@ -38,7 +38,7 @@ output header {{ { public: /// Constructor - FailUnimplemented(const char *_mnemonic, MachInst _machInst) + FailUnimplemented(const char *_mnemonic, ExtMachInst _machInst) : AlphaStaticInst(_mnemonic, _machInst, No_OpClass) { // don't call execute() (which panics) if we're on a @@ -69,7 +69,7 @@ output header {{ public: /// Constructor - WarnUnimplemented(const char *_mnemonic, MachInst _machInst) + WarnUnimplemented(const char *_mnemonic, ExtMachInst _machInst) : AlphaStaticInst(_mnemonic, _machInst, No_OpClass), warned(false) { // don't call execute() (which panics) if we're on a @@ -148,7 +148,7 @@ output header {{ { public: /// Constructor - Unknown(MachInst _machInst) + Unknown(ExtMachInst _machInst) : AlphaStaticInst("unknown", _machInst, No_OpClass) { // don't call execute() (which panics) if we're on a diff --git a/arch/alpha/isa_traits.hh b/arch/alpha/isa_traits.hh index 938ba696e..b1980b4b6 100644 --- a/arch/alpha/isa_traits.hh +++ b/arch/alpha/isa_traits.hh @@ -57,16 +57,18 @@ namespace AlphaISA { typedef uint32_t MachInst; + typedef uint64_t ExtMachInst; // typedef uint64_t Addr; typedef uint8_t RegIndex; enum { MemoryEnd = 0xffffffffffffffffULL, - NumIntRegs = 32, - NumFloatRegs = 32, + NumIntArchRegs = 32, + NumPALShadowRegs = 8, + NumFloatArchRegs = 32, // @todo: Figure out what this number really should be. - NumMiscRegs = 32, + NumMiscArchRegs = 32, MaxRegsOfAnyType = 32, // Static instruction parameters @@ -100,17 +102,23 @@ namespace AlphaISA DepNA = 0, }; + enum { + NumIntRegs = NumIntArchRegs + NumPALShadowRegs, + NumFloatRegs = NumFloatArchRegs, + NumMiscRegs = NumMiscArchRegs + }; + // These enumerate all the registers for dependence tracking. enum DependenceTags { // 0..31 are the integer regs 0..31 // 32..63 are the FP regs 0..31, i.e. use (reg + FP_Base_DepTag) - FP_Base_DepTag = 32, - Ctrl_Base_DepTag = 64, - Fpcr_DepTag = 64, // floating point control register - Uniq_DepTag = 65, - Lock_Flag_DepTag = 66, - Lock_Addr_DepTag = 67, - IPR_Base_DepTag = 68 + FP_Base_DepTag = 40, + Ctrl_Base_DepTag = 72, + Fpcr_DepTag = 72, // floating point control register + Uniq_DepTag = 73, + Lock_Flag_DepTag = 74, + Lock_Addr_DepTag = 75, + IPR_Base_DepTag = 76 }; typedef uint64_t IntReg; @@ -132,6 +140,9 @@ extern const Addr PageBytes; extern const Addr PageMask; extern const Addr PageOffset; +// redirected register map, really only used for the full system case. +extern const int reg_redir[NumIntRegs]; + #if FULL_SYSTEM typedef uint64_t InternalProcReg; @@ -199,9 +210,7 @@ extern const Addr PageOffset; Addr pc; // program counter Addr npc; // next-cycle program counter #if FULL_SYSTEM - IntReg palregs[NumIntRegs]; // PAL shadow registers int intrflag; // interrupt flag - bool pal_shadow; // using pal_shadow registers inline int instAsid() { return EV5::ITB_ASN_ASN(miscRegs.ipr[IPR_ITB_ASN]); } inline int dataAsid() @@ -212,10 +221,12 @@ extern const Addr PageOffset; void unserialize(Checkpoint *cp, const std::string §ion); }; - StaticInstPtr decodeInst(MachInst); + static inline ExtMachInst makeExtMI(MachInst inst, const uint64_t &pc); + + StaticInstPtr decodeInst(ExtMachInst); // return a no-op instruction... used for instruction fetch faults - extern const MachInst NoopMachInst; + extern const ExtMachInst NoopMachInst; enum annotes { ANNOTE_NONE = 0, @@ -362,6 +373,18 @@ class SyscallReturn { #endif +static inline AlphaISA::ExtMachInst +AlphaISA::makeExtMI(AlphaISA::MachInst inst, const uint64_t &pc) { +#if FULL_SYSTEM + AlphaISA::ExtMachInst ext_inst = inst; + if (pc && 0x1) + return ext_inst|=(static_cast(pc & 0x1) << 32); + else + return ext_inst; +#else + return AlphaISA::ExtMachInst(inst); +#endif +} #if FULL_SYSTEM //typedef TheISA::InternalProcReg InternalProcReg; diff --git a/arch/isa_parser.py b/arch/isa_parser.py index 5185ed573..570110d84 100755 --- a/arch/isa_parser.py +++ b/arch/isa_parser.py @@ -225,7 +225,7 @@ def p_specification(t): # wrap the decode block as a function definition t[4].wrap_decode_block(''' StaticInstPtr -%(isa_name)s::decodeInst(%(isa_name)s::MachInst machInst) +%(isa_name)s::decodeInst(%(isa_name)s::ExtMachInst machInst) { using namespace %(namespace)s; ''' % vars(), '}') diff --git a/base/remote_gdb.cc b/base/remote_gdb.cc index f56ddf7cf..57a179719 100644 --- a/base/remote_gdb.cc +++ b/base/remote_gdb.cc @@ -424,12 +424,25 @@ void RemoteGDB::getregs() { memset(gdbregs, 0, sizeof(gdbregs)); - memcpy(&gdbregs[KGDB_REG_V0], context->regs.intRegFile, 32 * sizeof(uint64_t)); + + gdbregs[KGDB_REG_PC] = context->readPC(); + + // @todo: Currently this is very Alpha specific. + if (AlphaISA::PcPAL(gdbregs[KGDB_REG_PC])) { + for (int i = 0; i < TheISA::NumIntArchRegs; ++i) { + gdbregs[i] = context->readIntReg(AlphaISA::reg_redir[i]); + } + } else { + for (int i = 0; i < TheISA::NumIntArchRegs; ++i) { + gdbregs[i] = context->readIntReg(i); + } + } + #ifdef KGDB_FP_REGS - memcpy(&gdbregs[KGDB_REG_F0], context->regs.floatRegFile.q, - 32 * sizeof(uint64_t)); + for (int i = 0; i < TheISA::NumFloatArchRegs; ++i) { + gdbregs[i + KGDB_REG_F0] = context->readFloatRegInt(i); + } #endif - gdbregs[KGDB_REG_PC] = context->regs.pc; } /////////////////////////////////////////////////////////// @@ -441,11 +454,21 @@ RemoteGDB::getregs() void RemoteGDB::setregs() { - memcpy(context->regs.intRegFile, &gdbregs[KGDB_REG_V0], - 32 * sizeof(uint64_t)); + // @todo: Currently this is very Alpha specific. + if (AlphaISA::PcPAL(gdbregs[KGDB_REG_PC])) { + for (int i = 0; i < TheISA::NumIntArchRegs; ++i) { + context->setIntReg(AlphaISA::reg_redir[i], gdbregs[i]); + } + } else { + for (int i = 0; i < TheISA::NumIntArchRegs; ++i) { + context->setIntReg(i, gdbregs[i]); + } + } + #ifdef KGDB_FP_REGS - memcpy(context->regs.floatRegFile.q, &gdbregs[KGDB_REG_F0], - 32 * sizeof(uint64_t)); + for (int i = 0; i < TheISA::NumFloatArchRegs; ++i) { + context->setFloatRegInt(i, gdbregs[i + KGDB_REG_F0]); + } #endif context->regs.pc = gdbregs[KGDB_REG_PC]; } diff --git a/cpu/o3/regfile.hh b/cpu/o3/regfile.hh index 691a75382..03ad2da46 100644 --- a/cpu/o3/regfile.hh +++ b/cpu/o3/regfile.hh @@ -236,7 +236,7 @@ class PhysRegFile #if FULL_SYSTEM private: // This is ISA specifc stuff; remove it eventually once ISAImpl is used - IntReg palregs[NumIntRegs]; // PAL shadow registers +// IntReg palregs[NumIntRegs]; // PAL shadow registers InternalProcReg ipr[NumInternalProcRegs]; // internal processor regs int intrflag; // interrupt flag bool pal_shadow; // using pal_shadow registers diff --git a/cpu/simple/cpu.cc b/cpu/simple/cpu.cc index d826c589e..2006f4fe8 100644 --- a/cpu/simple/cpu.cc +++ b/cpu/simple/cpu.cc @@ -761,7 +761,7 @@ SimpleCPU::tick() // decode the instruction inst = gtoh(inst); - curStaticInst = StaticInst::decode(inst); + curStaticInst = StaticInst::decode(makeExtMI(inst, xc->readPC())); traceData = Trace::getInstRecord(curTick, xc, this, curStaticInst, xc->regs.pc); diff --git a/cpu/static_inst.hh b/cpu/static_inst.hh index 5566f2f6d..20116554e 100644 --- a/cpu/static_inst.hh +++ b/cpu/static_inst.hh @@ -231,6 +231,8 @@ class StaticInst : public StaticInstBase /// Binary machine instruction type. typedef TheISA::MachInst MachInst; + /// Binary extended machine instruction type. + typedef TheISA::ExtMachInst ExtMachInst; /// Logical register index type. typedef TheISA::RegIndex RegIndex; @@ -272,7 +274,7 @@ class StaticInst : public StaticInstBase StaticInstPtr &memAccInst() const { return nullStaticInstPtr; } /// The binary machine instruction. - const MachInst machInst; + const ExtMachInst machInst; protected: @@ -302,7 +304,7 @@ class StaticInst : public StaticInstBase generateDisassembly(Addr pc, const SymbolTable *symtab) const = 0; /// Constructor. - StaticInst(const char *_mnemonic, MachInst _machInst, OpClass __opClass) + StaticInst(const char *_mnemonic, ExtMachInst _machInst, OpClass __opClass) : StaticInstBase(__opClass), machInst(_machInst), mnemonic(_mnemonic), cachedDisassembly(0) { @@ -372,7 +374,7 @@ class StaticInst : public StaticInstBase /// Decoded instruction cache type. /// For now we're using a generic hash_map; this seems to work /// pretty well. - typedef m5::hash_map DecodeCache; + typedef m5::hash_map DecodeCache; /// A cache of decoded instruction objects. static DecodeCache decodeCache; @@ -387,7 +389,7 @@ class StaticInst : public StaticInstBase /// @param mach_inst The binary instruction to decode. /// @retval A pointer to the corresponding StaticInst object. //This is defined as inline below. - static StaticInstPtr decode(MachInst mach_inst); + static StaticInstPtr decode(ExtMachInst mach_inst); }; typedef RefCountingPtr StaticInstBasePtr; @@ -418,7 +420,7 @@ class StaticInstPtr : public RefCountingPtr /// Construct directly from machine instruction. /// Calls StaticInst::decode(). - StaticInstPtr(TheISA::MachInst mach_inst) + StaticInstPtr(TheISA::ExtMachInst mach_inst) : RefCountingPtr(StaticInst::decode(mach_inst)) { } @@ -431,7 +433,7 @@ class StaticInstPtr : public RefCountingPtr }; inline StaticInstPtr -StaticInst::decode(StaticInst::MachInst mach_inst) +StaticInst::decode(StaticInst::ExtMachInst mach_inst) { #ifdef DECODE_CACHE_HASH_STATS // Simple stats on decode hash_map. Turns out the default From 14b6cd39aadcac72e8fce47e24445037bae70309 Mon Sep 17 00:00:00 2001 From: Kevin Lim Date: Fri, 3 Mar 2006 15:41:57 -0500 Subject: [PATCH 141/180] Remove intr_post function. No longer being used. --HG-- extra : convert_revision : 1dc1d691244fd2edbd21d5cbf0764622d8f95fbb --- arch/alpha/ev5.cc | 27 --------------------------- 1 file changed, 27 deletions(-) diff --git a/arch/alpha/ev5.cc b/arch/alpha/ev5.cc index 9193e40f0..2cbfe7fd6 100644 --- a/arch/alpha/ev5.cc +++ b/arch/alpha/ev5.cc @@ -163,33 +163,6 @@ ExecContext::ev5_temp_trap(Fault fault) } -void -AlphaISA::intr_post(RegFile *regs, Fault fault, Addr pc) -{ - bool use_pc = (fault == NoFault); - - if (fault->isA()) - panic("arithmetic faults NYI..."); - - // compute exception restart address - if (use_pc || fault->isA() || fault->isA()) { - // traps... skip faulting instruction - regs->miscRegs.setReg(IPR_EXC_ADDR, regs->pc + 4); - } else { - // fault, post fault at excepting instruction - regs->miscRegs.setReg(IPR_EXC_ADDR, regs->pc); - } - - // jump to expection address (PAL PC bit set here as well...) - if (!use_pc) - regs->npc = regs->miscRegs.readReg(IPR_PAL_BASE) + - (dynamic_cast(fault.get()))->vect(); - else - regs->npc = regs->miscRegs.readReg(IPR_PAL_BASE) + pc; - - // that's it! (orders of magnitude less painful than x86) -} - Fault ExecContext::hwrei() { From 7c4c623302dca7da95b1c95d4968f4ef76de391d Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sat, 4 Mar 2006 03:09:23 -0500 Subject: [PATCH 142/180] Filled out the object file loader so it can load object files for several OSs and architectures. SConscript: Added ./libelf as an include search directory. There might be a better spot for this than where I put it. arch/SConscript: Combined the linux_process.h and tru64_process.h into process.h. This allows each ISA to support processes from arbitrary OSs. arch/alpha/SConscript: Added process.cc as a source file. It provides an implementation of createProcess, which takes an object_file object and creates the appropriate process object, or dies. base/loader/elf_object.cc: Actually extract the OS and architecture from the elf file, rather than always guessing Alpha and Linux. base/loader/object_file.hh: Added constants for SPARC, MIPS, and Solaris, and changed the include for the Addr type. sim/process.cc: Pushed creation of specific process objects into the ISA specific code. --HG-- extra : convert_revision : b4754e7ca8328672d07e1394c4d162e199606b53 --- SConscript | 1 + arch/SConscript | 3 +- arch/alpha/SConscript | 1 + arch/alpha/process.cc | 61 ++++++++++++++++++++++++++++++++++++++ arch/alpha/process.hh | 48 ++++++++++++++++++++++++++++++ arch/mips/process.cc | 56 ++++++++++++++++++++++++++++++++++ arch/mips/process.hh | 45 ++++++++++++++++++++++++++++ arch/sparc/process.cc | 56 ++++++++++++++++++++++++++++++++++ arch/sparc/process.hh | 45 ++++++++++++++++++++++++++++ base/loader/elf_object.cc | 45 +++++++++++++++++++++++++--- base/loader/object_file.hh | 11 +++++-- sim/process.cc | 28 ++++------------- 12 files changed, 368 insertions(+), 32 deletions(-) create mode 100644 arch/alpha/process.cc create mode 100644 arch/alpha/process.hh create mode 100644 arch/mips/process.cc create mode 100644 arch/mips/process.hh create mode 100644 arch/sparc/process.cc create mode 100644 arch/sparc/process.hh diff --git a/SConscript b/SConscript index 51836b0be..1f68011b6 100644 --- a/SConscript +++ b/SConscript @@ -374,6 +374,7 @@ def make_objs(sources, env): # the corresponding build directory to pick up generated include # files. env.Append(CPPPATH='.') +env.Append(CPPPATH='./libelf') # Debug binary debugEnv = env.Copy(OBJSUFFIX='.do') diff --git a/arch/SConscript b/arch/SConscript index 5783b39dd..b4b7a1ddb 100644 --- a/arch/SConscript +++ b/arch/SConscript @@ -46,9 +46,8 @@ sources = [] # List of headers to generate isa_switch_hdrs = Split(''' isa_traits.hh - linux_process.hh - tru64_process.hh tlb.hh + process.hh aout_machdep.h ecoff_machdep.h arguments.hh diff --git a/arch/alpha/SConscript b/arch/alpha/SConscript index 3b0e69b7a..03d73eef7 100644 --- a/arch/alpha/SConscript +++ b/arch/alpha/SConscript @@ -64,6 +64,7 @@ syscall_emulation_sources = Split(''' common_syscall_emul.cc linux_process.cc tru64_process.cc + process.cc ''') # Set up complete list of sources based on configuration. diff --git a/arch/alpha/process.cc b/arch/alpha/process.cc new file mode 100644 index 000000000..b2dbe7ad1 --- /dev/null +++ b/arch/alpha/process.cc @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2003-2004 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/alpha/process.hh" + +namespace AlphaISA +{ + +LiveProcess * +createProcess(const std::string &nm, ObjectFile * objFile, + int stdin_fd, int stdout_fd, int stderr_fd, + std::vector &argv, std::vector &envp) +{ + LiveProcess * process = NULL; + if (objFile->getArch() != ObjectFile::Alpha) + fatal("Object file does not match architecture."); + switch (objFile->getOpSys()) { + case ObjectFile::Tru64: + process = new AlphaTru64Process(nm, objFile, + stdin_fd, stdout_fd, stderr_fd, + argv, envp); + break; + + case ObjectFile::Linux: + process = new AlphaLinuxProcess(nm, objFile, + stdin_fd, stdout_fd, stderr_fd, + argv, envp); + break; + + default: + fatal("Unknown/unsupported operating system."); + } + return process; +} + +} // namespace AlphaISA diff --git a/arch/alpha/process.hh b/arch/alpha/process.hh new file mode 100644 index 000000000..7b660ddd0 --- /dev/null +++ b/arch/alpha/process.hh @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2003-2004 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 __ALPHA_PROCESS_HH__ +#define __ALPHA_PROCESS_HH__ + +#include + +#include "arch/alpha/linux_process.hh" +#include "arch/alpha/tru64_process.hh" +#include "base/loader/object_file.hh" + +namespace AlphaISA +{ + +LiveProcess * +createProcess(const std::string &nm, ObjectFile * objFile, + int stdin_fd, int stdout_fd, int stderr_fd, + std::vector &argv, std::vector &envp); + +} // namespace AlphaISA + +#endif // __ALPHA_PROCESS_HH__ diff --git a/arch/mips/process.cc b/arch/mips/process.cc new file mode 100644 index 000000000..6de44fe9f --- /dev/null +++ b/arch/mips/process.cc @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2003-2004 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/mips/process.hh" + +namespace MipsISA +{ + +LiveProcess * +createProcess(const string &nm, ObjectFile * objFile, + int stdin_fd, int stdout_fd, int stderr_fd, + vector &argv, vector &envp) +{ + LiveProcess * process = NULL; + if (objFile->getArch() != ObjectFile::MIPS) + fatal("Object file does not match architecture."); + switch (objFile->getOpSys()) { + case ObjectFile::Linux: + process = new MipsLinuxProcess(nm, objFile, + stdin_fd, stdout_fd, stderr_fd, + argv, envp); + break; + + default: + fatal("Unknown/unsupported operating system."); + } + return process; +} + +} // namespace MipsISA + diff --git a/arch/mips/process.hh b/arch/mips/process.hh new file mode 100644 index 000000000..ab4323107 --- /dev/null +++ b/arch/mips/process.hh @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2003-2004 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_PROCESS_HH__ +#define __MIPS_PROCESS_HH__ + +#include "arch/mips/linux_process.hh" +#include "base/loader/object_file.hh" + +namespace MipsISA +{ + +LiveProcess * +createProcess(const string &nm, ObjectFile * objFile, + int stdin_fd, int stdout_fd, int stderr_fd, + vector &argv, vector &envp); + +} // namespace MipsISA + +#endif // __MIPS_PROCESS_HH__ diff --git a/arch/sparc/process.cc b/arch/sparc/process.cc new file mode 100644 index 000000000..53a215379 --- /dev/null +++ b/arch/sparc/process.cc @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2003-2004 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/process.hh" + +namespace SparcISA +{ + +LiveProcess * +createProcess(const string &nm, ObjectFile * objFile, + int stdin_fd, int stdout_fd, int stderr_fd, + vector &argv, vector &envp) +{ + LiveProcess * process = NULL; + if (objFile->getArch() != ObjectFile::SPARC) + fatal("Object file does not match architecture."); + switch (objFile->getOpSys()) { + case ObjectFile::Linux: + process = new SparcLinuxProcess(nm, objFile, + stdin_fd, stdout_fd, stderr_fd, + argv, envp); + break; + + case ObjectFile::Solaris: + default: + fatal("Unknown/unsupported operating system."); + } + return process; +} + +} // namespace SparcISA diff --git a/arch/sparc/process.hh b/arch/sparc/process.hh new file mode 100644 index 000000000..387649d47 --- /dev/null +++ b/arch/sparc/process.hh @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2003-2004 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 __SPARC_PROCESS_HH__ +#define __SPARC_PROCESS_HH__ + +#include "arch/sparc/linux_process.hh" +#include "base/loader/object_file.hh" + +namespace SparcISA +{ + +LiveProcess * +createProcess(const string &nm, ObjectFile * objFile, + int stdin_fd, int stdout_fd, int stderr_fd, + vector &argv, vector &envp); + +} // namespace SparcISA + +#endif // __SPARC_PROCESS_HH__ diff --git a/base/loader/elf_object.cc b/base/loader/elf_object.cc index b74d537af..9dd9f9d00 100644 --- a/base/loader/elf_object.cc +++ b/base/loader/elf_object.cc @@ -56,6 +56,8 @@ ElfObject::tryFile(const string &fname, int fd, size_t len, uint8_t *data) { Elf *elf; GElf_Ehdr ehdr; + Arch arch = UnknownArch; + OpSys opSys = UnknownOpSys; // check that header matches library version if (elf_version(EV_CURRENT) == EV_NONE) @@ -73,8 +75,8 @@ ElfObject::tryFile(const string &fname, int fd, size_t len, uint8_t *data) return NULL; } else { - if (ehdr.e_ident[EI_CLASS] == ELFCLASS32) - panic("32 bit ELF Binary, Not Supported"); +// if (ehdr.e_ident[EI_CLASS] == ELFCLASS32) +// panic("32 bit ELF Binary, Not Supported"); /* @todo this emachine value isn't offical yet. * so we probably shouldn't check it. */ // if (ehdr.e_machine != EM_ALPHA) @@ -82,8 +84,43 @@ ElfObject::tryFile(const string &fname, int fd, size_t len, uint8_t *data) elf_end(elf); - return new ElfObject(fname, fd, len, data, - ObjectFile::Alpha, ObjectFile::Linux); + //Detect the architecture + //Versioning issues in libelf need to be resolved to get the correct + //SPARC constants. + //If MIPS supports 32 bit executables, this may need to be changed. + //Also, there are other MIPS constants which may be used, like + //EM_MIPS_RS3_LE and EM_MIPS_X + //Since we don't know how to check for alpha right now, we'll + //just assume if it wasn't something else and it's 64 bit, that's + //what it must be. + if (ehdr.e_machine == EM_SPARC64 || + ehdr.e_machine == EM_SPARC || + ehdr.e_machine == EM_SPARCV9) { + arch = ObjectFile::SPARC; + } else if (ehdr.e_machine == EM_MIPS + && ehdr.e_ident[EI_CLASS] == ELFCLASS32) { + arch = ObjectFile::MIPS; + } else if (ehdr.e_ident[EI_CLASS] == ELFCLASS64) { + arch = ObjectFile::Alpha; + } else { + arch = ObjectFile::UnknownArch; + } + + //Detect the operating system + switch (ehdr.e_ident[EI_OSABI]) + { + case ELFOSABI_LINUX: + opSys = ObjectFile::Linux; + break; + case ELFOSABI_SOLARIS: + opSys = ObjectFile::Solaris; + case ELFOSABI_TRU64: + opSys = ObjectFile::Tru64; + default: + opSys = ObjectFile::UnknownOpSys; + } + + return new ElfObject(fname, fd, len, data, arch, opSys); } } diff --git a/base/loader/object_file.hh b/base/loader/object_file.hh index 3c8659e18..1b44ae14f 100644 --- a/base/loader/object_file.hh +++ b/base/loader/object_file.hh @@ -29,7 +29,9 @@ #ifndef __OBJECT_FILE_HH__ #define __OBJECT_FILE_HH__ -#include "arch/isa_traits.hh" // for Addr +#include + +#include "sim/host.hh" // for Addr class FunctionalMemory; class SymbolTable; @@ -40,13 +42,16 @@ class ObjectFile enum Arch { UnknownArch, - Alpha + Alpha, + SPARC, + MIPS }; enum OpSys { UnknownOpSys, Tru64, - Linux + Linux, + Solaris }; protected: diff --git a/sim/process.cc b/sim/process.cc index e3cae2855..fddd9a0b9 100644 --- a/sim/process.cc +++ b/sim/process.cc @@ -48,8 +48,7 @@ #include "sim/stats.hh" #include "sim/syscall_emul.hh" -#include "arch/tru64_process.hh" -#include "arch/linux_process.hh" +#include "arch/process.hh" using namespace std; using namespace TheISA; @@ -376,27 +375,10 @@ LiveProcess::create(const string &nm, fatal("Can't load object file %s", executable); } - // check object type & set up syscall emulation pointer - if (objFile->getArch() == ObjectFile::Alpha) { - switch (objFile->getOpSys()) { - case ObjectFile::Tru64: - process = new AlphaTru64Process(nm, objFile, - stdin_fd, stdout_fd, stderr_fd, - argv, envp); - break; - - case ObjectFile::Linux: - process = new AlphaLinuxProcess(nm, objFile, - stdin_fd, stdout_fd, stderr_fd, - argv, envp); - break; - - default: - fatal("Unknown/unsupported operating system."); - } - } else { - fatal("Unknown object file architecture."); - } + // set up syscall emulation pointer for the current ISA + process = createProcess(nm, objFile, + stdin_fd, stdout_fd, stderr_fd, + argv, envp); delete objFile; From 890eb2432d3535727cd2f5f08ccdaec918774022 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sat, 4 Mar 2006 03:10:34 -0500 Subject: [PATCH 143/180] Removed the commented out declaration of the Addr type. --HG-- extra : convert_revision : 70612a3efc877febbff0c8fb9065dea7e1d12cd8 --- arch/alpha/isa_traits.hh | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/alpha/isa_traits.hh b/arch/alpha/isa_traits.hh index 938ba696e..b8aeffdde 100644 --- a/arch/alpha/isa_traits.hh +++ b/arch/alpha/isa_traits.hh @@ -57,7 +57,6 @@ namespace AlphaISA { typedef uint32_t MachInst; -// typedef uint64_t Addr; typedef uint8_t RegIndex; enum { From 62d149d9be9627593dc3e89505daa20b349ec116 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sat, 4 Mar 2006 03:16:16 -0500 Subject: [PATCH 144/180] General small SPARC fixups arch/sparc/SConscript: Fixed up the SPARC SConscript to use the name of the SPARC source files. arch/sparc/linux_process.cc: Changed the namespace name from SPARCISA to SparcISA. --HG-- extra : convert_revision : c340fbf78200bf7d962e7578a3f2998860224c53 --- arch/sparc/SConscript | 8 ++++---- arch/sparc/linux_process.cc | 3 +-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/arch/sparc/SConscript b/arch/sparc/SConscript index fea31fd5d..edff5821e 100644 --- a/arch/sparc/SConscript +++ b/arch/sparc/SConscript @@ -47,7 +47,7 @@ base_sources = Split(''' # Full-system sources full_system_sources = Split(''' - alpha_memory.cc + tlb.cc arguments.cc ev5.cc osfpal.cc @@ -57,9 +57,9 @@ full_system_sources = Split(''' # Syscall emulation (non-full-system) sources syscall_emulation_sources = Split(''' - alpha_common_syscall_emul.cc - alpha_linux_process.cc - alpha_tru64_process.cc + common_syscall_emul.cc + linux_process.cc + process.cc ''') sources = base_sources diff --git a/arch/sparc/linux_process.cc b/arch/sparc/linux_process.cc index 14b3d1505..d1c439d72 100644 --- a/arch/sparc/linux_process.cc +++ b/arch/sparc/linux_process.cc @@ -39,7 +39,7 @@ #include "sim/syscall_emul.hh" using namespace std; -using namespace SPARCISA; +using namespace SparcISA; /// Target pipe() handler. Even though this is a generic Posix call, /// the Alpha return convention is funky, so that makes it @@ -140,7 +140,6 @@ osf_setsysinfoFunc(SyscallDesc *desc, int callnum, Process *process, return 1; } - SyscallDesc SparcLinuxProcess::syscallDescs[] = { /* 0 */ SyscallDesc("restart_syscall", unimplimentedFunc); /* 1 */ SyscallDesc("exit", unimplimentedFunc); From 1e071c9f5fd5258ff92dc496aecc175db94a5ad7 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Sat, 4 Mar 2006 12:35:13 -0500 Subject: [PATCH 145/180] we REALLY don't want to use system headers for libelf... use "" not <> targetarch->arch arch/alpha/system.cc: targetarch -> arch base/loader/elf_object.cc: we REALLY don't want to use system headers for libelf... use "" not <> --HG-- extra : convert_revision : d0e1672dc655dca3081e36b2158e7b19ef54af40 --- arch/alpha/system.cc | 2 +- base/loader/elf_object.cc | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/alpha/system.cc b/arch/alpha/system.cc index b841a6d53..1e80c7768 100644 --- a/arch/alpha/system.cc +++ b/arch/alpha/system.cc @@ -27,6 +27,7 @@ */ #include "arch/alpha/system.hh" +#include "arch/vtophys.hh" #include "base/remote_gdb.hh" #include "base/loader/object_file.hh" #include "base/loader/symtab.hh" @@ -35,7 +36,6 @@ #include "mem/functional/physical.hh" #include "sim/byteswap.hh" #include "sim/builder.hh" -#include "targetarch/vtophys.hh" using namespace LittleEndianGuest; diff --git a/base/loader/elf_object.cc b/base/loader/elf_object.cc index 9dd9f9d00..fd69c9e56 100644 --- a/base/loader/elf_object.cc +++ b/base/loader/elf_object.cc @@ -38,8 +38,8 @@ #define __LIBELF_NEED_LINK_H 0 #define __LIBELF_SYMBOL_VERSIONS 0 -#include -#include +#include "libelf/libelf.h" +#include "libelf/gelf.h" #include "base/loader/elf_object.hh" From 41b8b41b9cdc12ff3939ca1e4b7a6fe99e60b6dc Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Sat, 4 Mar 2006 15:15:47 -0500 Subject: [PATCH 146/180] properly align the uid and size fields in the pre_F54_stat structure. Patch from Jos Delbar, modified to use variable attributes. --HG-- extra : convert_revision : 12c9ebbb109a789dd4230b7606b1f8ded00c21fc --- kern/tru64/tru64.hh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/kern/tru64/tru64.hh b/kern/tru64/tru64.hh index ad568cb0c..9c541ae1a 100644 --- a/kern/tru64/tru64.hh +++ b/kern/tru64/tru64.hh @@ -155,15 +155,16 @@ class Tru64 { /// implementing another set of stat functions using the old /// structure definition and binding them to the old syscall /// numbers. + struct pre_F64_stat { dev_t st_dev; ino_t st_ino; mode_t st_mode; nlink_t st_nlink; - uid_t st_uid; + uid_t st_uid __attribute__ ((aligned(sizeof(uid_t)))); gid_t st_gid; dev_t st_rdev; - off_t st_size; + off_t st_size __attribute__ ((aligned(sizeof(off_t)))); time_t st_atimeX; int32_t st_uatime; time_t st_mtimeX; From f15e492375e8ecd42a1f0ba7ead68cfeb2b4b673 Mon Sep 17 00:00:00 2001 From: Kevin Lim Date: Sat, 4 Mar 2006 15:18:40 -0500 Subject: [PATCH 147/180] Steps towards setting up the infrastructure to allow the new CPU model to work in full system mode. The major change is renaming the old ExecContext to CPUExecContext, and creating two new classes, ExecContext (an abstract class), and ProxyExecContext (a templated class that derives from ExecContext). Code outside of the CPU continues to use ExecContext as normal (other than not being able to access variables within the XC). The CPU uses the CPUExecContext, or however else it stores its own state. It then creates a ProxyExecContext, templated on the class used to hold its state. This proxy is passed to any code outside of the CPU that needs to access the XC. This allows code outside of the CPU to use the ExecContext interface to access any state needed, without knowledge of how that state is laid out. Note that these changes will not compile without the accompanying revision to automatically rename the shadow registers. SConscript: Include new file, cpu_exec_context.cc. arch/alpha/alpha_linux_process.cc: arch/alpha/alpha_memory.cc: arch/alpha/alpha_tru64_process.cc: arch/alpha/arguments.cc: arch/alpha/isa/decoder.isa: arch/alpha/stacktrace.cc: arch/alpha/vtophys.cc: base/remote_gdb.cc: cpu/intr_control.cc: Avoid directly accessing objects within the XC. arch/alpha/ev5.cc: Avoid directly accessing objects within the XC. KernelStats have been moved to the BaseCPU instead of the XC. arch/alpha/isa_traits.hh: Remove clearIprs(). It wasn't used very often and it did not work well with the proxy ExecContext. cpu/base.cc: Place kernel stats within the BaseCPU instead of the ExecContext. For now comment out the profiling code sampling until its exact location is decided upon. cpu/base.hh: Kernel stats are now in the BaseCPU instead of the ExecContext. cpu/base_dyn_inst.cc: cpu/base_dyn_inst.hh: cpu/memtest/memtest.cc: cpu/memtest/memtest.hh: Changes to support rename of old ExecContext to CPUExecContext. See changeset for more details. cpu/exetrace.cc: Remove unneeded include of exec_context.hh. cpu/intr_control.hh: cpu/o3/alpha_cpu_builder.cc: Remove unneeded include of exec_context.hh cpu/o3/alpha_cpu.hh: cpu/o3/alpha_cpu_impl.hh: cpu/o3/cpu.cc: cpu/o3/cpu.hh: cpu/simple/cpu.cc: cpu/simple/cpu.hh: Changes to support rename of old ExecContext to CPUExecContext. See changeset for more details. Also avoid accessing anything directly from the XC. cpu/pc_event.cc: Avoid accessing objects directly from the XC. dev/tsunami_cchip.cc: Avoid accessing objects directly within the XC> kern/freebsd/freebsd_system.cc: kern/linux/linux_system.cc: kern/linux/linux_threadinfo.hh: kern/tru64/dump_mbuf.cc: kern/tru64/tru64.hh: kern/tru64/tru64_events.cc: sim/syscall_emul.cc: sim/syscall_emul.hh: Avoid accessing objects directly within the XC. kern/kernel_stats.cc: kern/kernel_stats.hh: Kernel stats no longer exist within the XC. kern/system_events.cc: Avoid accessing objects directly within the XC. Also kernel stats are now in the BaseCPU. sim/process.cc: sim/process.hh: Avoid accessing regs directly within an ExecContext. Instead use a CPUExecContext to initialize the registers and copy them over. cpu/cpu_exec_context.cc: Rename old ExecContext to CPUExecContext. This is used by the old CPU models to store any necessary architectural state. Also include the ProxyExecContext, which is used to access the CPUExecContext's state in code outside of the CPU. cpu/cpu_exec_context.hh: Rename old ExecContext to CPUExecContext. This is used by the old CPU models to store any necessary architectural state. Also include the ProxyExecContext, which is used to access the CPUExecContext's state in code outside of the CPU. Remove kernel stats from the ExecContext. sim/pseudo_inst.cc: Kernel stats now live within the CPU. Avoid accessing objects directly within the XC. --HG-- rename : cpu/exec_context.cc => cpu/cpu_exec_context.cc rename : cpu/exec_context.hh => cpu/cpu_exec_context.hh extra : convert_revision : a75393a8945c80cca225b5e9d9c22a16609efb85 --- SConscript | 2 +- arch/alpha/alpha_linux_process.cc | 8 +- arch/alpha/alpha_memory.cc | 3 +- arch/alpha/alpha_tru64_process.cc | 16 +- arch/alpha/arguments.cc | 8 +- arch/alpha/ev5.cc | 77 ++- arch/alpha/isa/decoder.isa | 2 +- arch/alpha/isa_traits.hh | 2 - arch/alpha/stacktrace.cc | 29 +- arch/alpha/vtophys.cc | 27 +- base/remote_gdb.cc | 24 +- cpu/base.cc | 49 +- cpu/base.hh | 5 + cpu/base_dyn_inst.cc | 32 +- cpu/base_dyn_inst.hh | 8 +- cpu/{exec_context.cc => cpu_exec_context.cc} | 116 ++-- cpu/cpu_exec_context.hh | 510 +++++++++++++++ cpu/exec_context.hh | 625 ++++++++----------- cpu/exetrace.cc | 1 - cpu/intr_control.cc | 8 +- cpu/intr_control.hh | 1 - cpu/memtest/memtest.cc | 6 +- cpu/memtest/memtest.hh | 2 +- cpu/o3/alpha_cpu.hh | 45 +- cpu/o3/alpha_cpu_builder.cc | 1 - cpu/o3/alpha_cpu_impl.hh | 51 +- cpu/o3/cpu.cc | 33 +- cpu/o3/cpu.hh | 21 +- cpu/pc_event.cc | 7 +- cpu/simple/cpu.cc | 136 ++-- cpu/simple/cpu.hh | 53 +- dev/tsunami_cchip.cc | 2 +- kern/freebsd/freebsd_system.cc | 8 +- kern/kernel_stats.cc | 30 +- kern/kernel_stats.hh | 13 +- kern/linux/linux_system.cc | 6 +- kern/linux/linux_threadinfo.hh | 2 +- kern/system_events.cc | 21 +- kern/tru64/dump_mbuf.cc | 2 +- kern/tru64/tru64.hh | 79 ++- kern/tru64/tru64_events.cc | 11 +- sim/process.cc | 7 +- sim/process.hh | 2 + sim/pseudo_inst.cc | 10 +- sim/syscall_emul.cc | 20 +- sim/syscall_emul.hh | 40 +- 46 files changed, 1330 insertions(+), 831 deletions(-) rename cpu/{exec_context.cc => cpu_exec_context.cc} (64%) create mode 100644 cpu/cpu_exec_context.hh diff --git a/SConscript b/SConscript index 966cb6d3e..bd94ec430 100644 --- a/SConscript +++ b/SConscript @@ -82,7 +82,7 @@ base_sources = Split(''' cpu/base.cc cpu/base_dyn_inst.cc - cpu/exec_context.cc + cpu/cpu_exec_context.cc cpu/exetrace.cc cpu/pc_event.cc cpu/static_inst.cc diff --git a/arch/alpha/alpha_linux_process.cc b/arch/alpha/alpha_linux_process.cc index 16ebcca7b..63913d68e 100644 --- a/arch/alpha/alpha_linux_process.cc +++ b/arch/alpha/alpha_linux_process.cc @@ -61,7 +61,7 @@ pipeFunc(SyscallDesc *desc, int callnum, Process *process, // Alpha Linux convention for pipe() is that fd[0] is returned as // the return value of the function, and fd[1] is returned in r20. - xc->regs.intRegFile[20] = sim_fds[1]; + xc->setIntReg(20, sim_fds[1]); return sim_fds[0]; } @@ -79,7 +79,7 @@ unameFunc(SyscallDesc *desc, int callnum, Process *process, strcpy(name->version, "#1 Mon Aug 18 11:32:15 EDT 2003"); strcpy(name->machine, "alpha"); - name.copyOut(xc->mem); + name.copyOut(xc->getMemPtr()); return 0; } @@ -99,7 +99,7 @@ osf_getsysinfoFunc(SyscallDesc *desc, int callnum, Process *process, TypedBufferArg fpcr(xc->getSyscallArg(1)); // I don't think this exactly matches the HW FPCR *fpcr = 0; - fpcr.copyOut(xc->mem); + fpcr.copyOut(xc->getMemPtr()); return 0; } @@ -125,7 +125,7 @@ osf_setsysinfoFunc(SyscallDesc *desc, int callnum, Process *process, case 14: { // SSI_IEEE_FP_CONTROL TypedBufferArg fpcr(xc->getSyscallArg(1)); // I don't think this exactly matches the HW FPCR - fpcr.copyIn(xc->mem); + fpcr.copyIn(xc->getMemPtr()); DPRINTFR(SyscallVerbose, "osf_setsysinfo(SSI_IEEE_FP_CONTROL): " " setting FPCR to 0x%x\n", gtoh(*(uint64_t*)fpcr)); return 0; diff --git a/arch/alpha/alpha_memory.cc b/arch/alpha/alpha_memory.cc index fb619d8b3..9b43ad39e 100644 --- a/arch/alpha/alpha_memory.cc +++ b/arch/alpha/alpha_memory.cc @@ -496,9 +496,8 @@ AlphaDTB::fault(MemReqPtr &req, uint64_t flags) const Fault AlphaDTB::translate(MemReqPtr &req, bool write) const { - RegFile *regs = &req->xc->regs; ExecContext *xc = req->xc; - Addr pc = regs->pc; + Addr pc = xc->readPC(); AlphaISA::mode_type mode = (AlphaISA::mode_type)DTB_CM_CM(xc->readMiscReg(AlphaISA::IPR_DTB_CM)); diff --git a/arch/alpha/alpha_tru64_process.cc b/arch/alpha/alpha_tru64_process.cc index 8121d3452..7c0bc49e9 100644 --- a/arch/alpha/alpha_tru64_process.cc +++ b/arch/alpha/alpha_tru64_process.cc @@ -52,7 +52,7 @@ unameFunc(SyscallDesc *desc, int callnum, Process *process, strcpy(name->version, "732"); strcpy(name->machine, "alpha"); - name.copyOut(xc->mem); + name.copyOut(xc->getMemPtr()); return 0; } @@ -69,21 +69,21 @@ getsysinfoFunc(SyscallDesc *desc, int callnum, Process *process, case Tru64::GSI_MAX_CPU: { TypedBufferArg max_cpu(xc->getSyscallArg(1)); *max_cpu = htog((uint32_t)process->numCpus()); - max_cpu.copyOut(xc->mem); + max_cpu.copyOut(xc->getMemPtr()); return 1; } case Tru64::GSI_CPUS_IN_BOX: { TypedBufferArg cpus_in_box(xc->getSyscallArg(1)); *cpus_in_box = htog((uint32_t)process->numCpus()); - cpus_in_box.copyOut(xc->mem); + cpus_in_box.copyOut(xc->getMemPtr()); return 1; } case Tru64::GSI_PHYSMEM: { TypedBufferArg physmem(xc->getSyscallArg(1)); *physmem = htog((uint64_t)1024 * 1024); // physical memory in KB - physmem.copyOut(xc->mem); + physmem.copyOut(xc->getMemPtr()); return 1; } @@ -100,14 +100,14 @@ getsysinfoFunc(SyscallDesc *desc, int callnum, Process *process, infop->cpu_ex_binding = htog(0); infop->mhz = htog(667); - infop.copyOut(xc->mem); + infop.copyOut(xc->getMemPtr()); return 1; } case Tru64::GSI_PROC_TYPE: { TypedBufferArg proc_type(xc->getSyscallArg(1)); *proc_type = htog((uint64_t)11); - proc_type.copyOut(xc->mem); + proc_type.copyOut(xc->getMemPtr()); return 1; } @@ -116,14 +116,14 @@ getsysinfoFunc(SyscallDesc *desc, int callnum, Process *process, strncpy((char *)bufArg.bufferPtr(), "COMPAQ Professional Workstation XP1000", nbytes); - bufArg.copyOut(xc->mem); + bufArg.copyOut(xc->getMemPtr()); return 1; } case Tru64::GSI_CLK_TCK: { TypedBufferArg clk_hz(xc->getSyscallArg(1)); *clk_hz = htog((uint64_t)1024); - clk_hz.copyOut(xc->mem); + clk_hz.copyOut(xc->getMemPtr()); return 1; } diff --git a/arch/alpha/arguments.cc b/arch/alpha/arguments.cc index 4e8190cbc..019390aeb 100644 --- a/arch/alpha/arguments.cc +++ b/arch/alpha/arguments.cc @@ -54,13 +54,13 @@ AlphaArguments::getArg(bool fp) { if (number < 6) { if (fp) - return xc->regs.floatRegFile.q[16 + number]; + return xc->readFloatRegInt(16 + number); else - return xc->regs.intRegFile[16 + number]; + return xc->readIntReg(16 + number); } else { - Addr sp = xc->regs.intRegFile[30]; + Addr sp = xc->readIntReg(30); Addr paddr = vtophys(xc, sp + (number-6) * sizeof(uint64_t)); - return xc->physmem->phys_read_qword(paddr); + return xc->getPhysMemPtr()->phys_read_qword(paddr); } } diff --git a/arch/alpha/ev5.cc b/arch/alpha/ev5.cc index f292c6c46..9d2ff4db7 100644 --- a/arch/alpha/ev5.cc +++ b/arch/alpha/ev5.cc @@ -34,6 +34,7 @@ #include "base/stats/events.hh" #include "config/full_system.hh" #include "cpu/base.hh" +#include "cpu/cpu_exec_context.hh" #include "cpu/exec_context.hh" #include "cpu/fast/cpu.hh" #include "kern/kernel_stats.hh" @@ -70,17 +71,17 @@ AlphaISA::swap_palshadow(RegFile *regs, bool use_shadow) // Machine dependent functions // void -AlphaISA::initCPU(RegFile *regs, int cpuId) +AlphaISA::initCPU(ExecContext *xc, int cpuId) { - initIPRs(®s->miscRegs, cpuId); + initIPRs(xc, cpuId); // CPU comes up with PAL regs enabled swap_palshadow(regs, true); - regs->intRegFile[16] = cpuId; - regs->intRegFile[0] = cpuId; + xc->setIntReg(16, cpuId); + xc->setIntReg(0, cpuId); - regs->pc = regs->miscRegs.readReg(IPR_PAL_BASE) + fault_addr(ResetFault); - regs->npc = regs->pc + sizeof(MachInst); + xc->setPC(xc->readMiscReg(IPR_PAL_BASE) + fault_addr(ResetFault)); + xc->setNextPC(xc->readPC() + sizeof(MachInst)); } //////////////////////////////////////////////////////////////////////// @@ -109,13 +110,15 @@ const int AlphaISA::reg_redir[AlphaISA::NumIntRegs] = { // // void -AlphaISA::initIPRs(MiscRegFile *miscRegs, int cpuId) +AlphaISA::initIPRs(ExecContext *xc, int cpuId) { - miscRegs->clearIprs(); + for (int i = 0; i < NumInternalProcRegs; ++i) { + xc->setMiscReg(i, 0); + } - miscRegs->setReg(IPR_PAL_BASE, PalBase); - miscRegs->setReg(IPR_MCSR, 0x6); - miscRegs->setReg(IPR_PALtemp16, cpuId); + xc->setMiscReg(IPR_PAL_BASE, PalBase); + xc->setMiscReg(IPR_MCSR, 0x6); + xc->setMiscReg(IPR_PALtemp16, cpuId); } @@ -174,18 +177,18 @@ AlphaISA::zeroRegisters(CPU *cpu) // Insure ISA semantics // (no longer very clean due to the change in setIntReg() in the // cpu model. Consider changing later.) - cpu->xc->setIntReg(ZeroReg, 0); - cpu->xc->setFloatRegDouble(ZeroReg, 0.0); + cpu->cpuXC->setIntReg(ZeroReg, 0); + cpu->cpuXC->setFloatRegDouble(ZeroReg, 0.0); } void -ExecContext::ev5_trap(Fault fault) +CPUExecContext::ev5_trap(Fault fault) { DPRINTF(Fault, "Fault %s at PC: %#x\n", fault->name, regs.pc); cpu->recordEvent(csprintf("Fault %s", fault->name)); assert(!misspeculating()); - kernelStats->fault(fault); + cpu->kernelStats->fault(fault); if (fault == ArithmeticFault) panic("Arithmetic traps are unimplemented!"); @@ -237,7 +240,7 @@ AlphaISA::intr_post(RegFile *regs, Fault fault, Addr pc) } Fault -ExecContext::hwrei() +CPUExecContext::hwrei() { if (!inPalMode()) return UnimplementedOpcodeFault; @@ -245,7 +248,7 @@ ExecContext::hwrei() setNextPC(readMiscReg(AlphaISA::IPR_EXC_ADDR)); if (!misspeculating()) { - kernelStats->hwrei(); + cpu->kernelStats->hwrei(); if ((readMiscReg(AlphaISA::IPR_EXC_ADDR) & 1) == 0) AlphaISA::swap_palshadow(®s, false); @@ -257,12 +260,6 @@ ExecContext::hwrei() return NoFault; } -void -AlphaISA::MiscRegFile::clearIprs() -{ - bzero((char *)ipr, NumInternalProcRegs * sizeof(InternalProcReg)); -} - AlphaISA::MiscReg AlphaISA::MiscRegFile::readIpr(int idx, Fault &fault, ExecContext *xc) { @@ -318,7 +315,7 @@ AlphaISA::MiscRegFile::readIpr(int idx, Fault &fault, ExecContext *xc) case AlphaISA::IPR_CC: retval |= ipr[idx] & ULL(0xffffffff00000000); - retval |= xc->cpu->curCycle() & ULL(0x00000000ffffffff); + retval |= xc->getCpuPtr()->curCycle() & ULL(0x00000000ffffffff); break; case AlphaISA::IPR_VA: @@ -335,7 +332,7 @@ AlphaISA::MiscRegFile::readIpr(int idx, Fault &fault, ExecContext *xc) case AlphaISA::IPR_DTB_PTE: { - AlphaISA::PTE &pte = xc->dtb->index(!xc->misspeculating()); + AlphaISA::PTE &pte = xc->getDTBPtr()->index(!xc->misspeculating()); retval |= ((u_int64_t)pte.ppn & ULL(0x7ffffff)) << 32; retval |= ((u_int64_t)pte.xre & ULL(0xf)) << 8; @@ -432,7 +429,7 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ExecContext *xc) // write entire quad w/ no side-effect old = ipr[idx]; ipr[idx] = val; - xc->kernelStats->context(old, val); + xc->getCpuPtr()->kernelStats->context(old, val, xc); break; case AlphaISA::IPR_DTB_PTE: @@ -459,14 +456,14 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ExecContext *xc) // only write least significant five bits - interrupt level ipr[idx] = val & 0x1f; - xc->kernelStats->swpipl(ipr[idx]); + xc->getCpuPtr()->kernelStats->swpipl(ipr[idx]); break; case AlphaISA::IPR_DTB_CM: if (val & 0x18) - xc->kernelStats->mode(Kernel::user); + xc->getCpuPtr()->kernelStats->mode(Kernel::user, xc); else - xc->kernelStats->mode(Kernel::kernel); + xc->getCpuPtr()->kernelStats->mode(Kernel::kernel, xc); case AlphaISA::IPR_ICM: // only write two mode bits - processor mode @@ -540,21 +537,22 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ExecContext *xc) // really a control write ipr[idx] = 0; - xc->dtb->flushAll(); + xc->getDTBPtr()->flushAll(); break; case AlphaISA::IPR_DTB_IAP: // really a control write ipr[idx] = 0; - xc->dtb->flushProcesses(); + xc->getDTBPtr()->flushProcesses(); break; case AlphaISA::IPR_DTB_IS: // really a control write ipr[idx] = val; - xc->dtb->flushAddr(val, DTB_ASN_ASN(ipr[AlphaISA::IPR_DTB_ASN])); + xc->getDTBPtr()->flushAddr(val, + DTB_ASN_ASN(ipr[AlphaISA::IPR_DTB_ASN])); break; case AlphaISA::IPR_DTB_TAG: { @@ -577,7 +575,7 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ExecContext *xc) pte.asn = DTB_ASN_ASN(ipr[AlphaISA::IPR_DTB_ASN]); // insert new TAG/PTE value into data TLB - xc->dtb->insert(val, pte); + xc->getDTBPtr()->insert(val, pte); } break; @@ -601,7 +599,7 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ExecContext *xc) pte.asn = ITB_ASN_ASN(ipr[AlphaISA::IPR_ITB_ASN]); // insert new TAG/PTE value into data TLB - xc->itb->insert(ipr[AlphaISA::IPR_ITB_TAG], pte); + xc->getITBPtr()->insert(ipr[AlphaISA::IPR_ITB_TAG], pte); } break; @@ -609,21 +607,22 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ExecContext *xc) // really a control write ipr[idx] = 0; - xc->itb->flushAll(); + xc->getITBPtr()->flushAll(); break; case AlphaISA::IPR_ITB_IAP: // really a control write ipr[idx] = 0; - xc->itb->flushProcesses(); + xc->getITBPtr()->flushProcesses(); break; case AlphaISA::IPR_ITB_IS: // really a control write ipr[idx] = val; - xc->itb->flushAddr(val, ITB_ASN_ASN(ipr[AlphaISA::IPR_ITB_ASN])); + xc->getITBPtr()->flushAddr(val, + ITB_ASN_ASN(ipr[AlphaISA::IPR_ITB_ASN])); break; default: @@ -640,9 +639,9 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ExecContext *xc) * If return value is false, actual PAL call will be suppressed. */ bool -ExecContext::simPalCheck(int palFunc) +CPUExecContext::simPalCheck(int palFunc) { - kernelStats->callpal(palFunc); + cpu->kernelStats->callpal(palFunc, proxy); switch (palFunc) { case PAL::halt: diff --git a/arch/alpha/isa/decoder.isa b/arch/alpha/isa/decoder.isa index c72f14a71..1817f65f2 100644 --- a/arch/alpha/isa/decoder.isa +++ b/arch/alpha/isa/decoder.isa @@ -770,7 +770,7 @@ decode OPCODE default Unknown::unknown() { 0x21: m5exit({{ AlphaPseudo::m5exit(xc->xcBase(), R16); }}, No_OpClass, IsNonSpeculative); - 0x30: initparam({{ Ra = xc->xcBase()->cpu->system->init_param; }}); + 0x30: initparam({{ Ra = xc->xcBase()->getCpuPtr()->system->init_param; }}); 0x40: resetstats({{ AlphaPseudo::resetstats(xc->xcBase(), R16, R17); }}, IsNonSpeculative); diff --git a/arch/alpha/isa_traits.hh b/arch/alpha/isa_traits.hh index 938ba696e..a94777bee 100644 --- a/arch/alpha/isa_traits.hh +++ b/arch/alpha/isa_traits.hh @@ -164,8 +164,6 @@ extern const Addr PageOffset; ExecContext *xc); #if FULL_SYSTEM - void clearIprs(); - protected: InternalProcReg ipr[NumInternalProcRegs]; // Internal processor regs diff --git a/arch/alpha/stacktrace.cc b/arch/alpha/stacktrace.cc index 89b6b73a9..50f2e4d21 100644 --- a/arch/alpha/stacktrace.cc +++ b/arch/alpha/stacktrace.cc @@ -44,23 +44,23 @@ ProcessInfo::ProcessInfo(ExecContext *_xc) { Addr addr = 0; - if (!xc->system->kernelSymtab->findAddress("thread_info_size", addr)) + if (!xc->getSystemPtr()->kernelSymtab->findAddress("thread_info_size", addr)) panic("thread info not compiled into kernel\n"); thread_info_size = *(int32_t *)vtomem(xc, addr, sizeof(int32_t)); - if (!xc->system->kernelSymtab->findAddress("task_struct_size", addr)) + if (!xc->getSystemPtr()->kernelSymtab->findAddress("task_struct_size", addr)) panic("thread info not compiled into kernel\n"); task_struct_size = *(int32_t *)vtomem(xc, addr, sizeof(int32_t)); - if (!xc->system->kernelSymtab->findAddress("thread_info_task", addr)) + if (!xc->getSystemPtr()->kernelSymtab->findAddress("thread_info_task", addr)) panic("thread info not compiled into kernel\n"); task_off = *(int32_t *)vtomem(xc, addr, sizeof(int32_t)); - if (!xc->system->kernelSymtab->findAddress("task_struct_pid", addr)) + if (!xc->getSystemPtr()->kernelSymtab->findAddress("task_struct_pid", addr)) panic("thread info not compiled into kernel\n"); pid_off = *(int32_t *)vtomem(xc, addr, sizeof(int32_t)); - if (!xc->system->kernelSymtab->findAddress("task_struct_comm", addr)) + if (!xc->getSystemPtr()->kernelSymtab->findAddress("task_struct_comm", addr)) panic("thread info not compiled into kernel\n"); name_off = *(int32_t *)vtomem(xc, addr, sizeof(int32_t)); } @@ -126,8 +126,9 @@ StackTrace::trace(ExecContext *_xc, bool is_call) bool usermode = (xc->readMiscReg(AlphaISA::IPR_DTB_CM) & 0x18) != 0; - Addr pc = xc->regs.npc; - bool kernel = xc->system->kernelStart <= pc && pc <= xc->system->kernelEnd; + Addr pc = xc->readNextPC(); + bool kernel = xc->getSystemPtr()->kernelStart <= pc && + pc <= xc->getSystemPtr()->kernelEnd; if (usermode) { stack.push_back(user); @@ -139,8 +140,8 @@ StackTrace::trace(ExecContext *_xc, bool is_call) return; } - SymbolTable *symtab = xc->system->kernelSymtab; - Addr ksp = xc->regs.intRegFile[TheISA::StackPointerReg]; + SymbolTable *symtab = xc->getSystemPtr()->kernelSymtab; + Addr ksp = xc->readIntReg(TheISA::StackPointerReg); Addr bottom = ksp & ~0x3fff; Addr addr; @@ -149,7 +150,7 @@ StackTrace::trace(ExecContext *_xc, bool is_call) panic("could not find address %#x", pc); stack.push_back(addr); - pc = xc->regs.pc; + pc = xc->readPC(); } Addr ra; @@ -181,8 +182,8 @@ StackTrace::trace(ExecContext *_xc, bool is_call) return; } - bool kernel = xc->system->kernelStart <= pc && - pc <= xc->system->kernelEnd; + bool kernel = xc->getSystemPtr()->kernelStart <= pc && + pc <= xc->getSystemPtr()->kernelEnd; if (!kernel) return; @@ -323,8 +324,8 @@ StackTrace::decodePrologue(Addr sp, Addr callpc, Addr func, void StackTrace::dump() { - StringWrap name(xc->cpu->name()); - SymbolTable *symtab = xc->system->kernelSymtab; + StringWrap name(xc->getCpuPtr()->name()); + SymbolTable *symtab = xc->getSystemPtr()->kernelSymtab; DPRINTFN("------ Stack ------\n"); diff --git a/arch/alpha/vtophys.cc b/arch/alpha/vtophys.cc index 1d70196c5..40261426d 100644 --- a/arch/alpha/vtophys.cc +++ b/arch/alpha/vtophys.cc @@ -95,7 +95,7 @@ vtophys(ExecContext *xc, Addr addr) paddr = vaddr; } else { AlphaISA::PageTableEntry pte = - kernel_pte_lookup(xc->physmem, ptbr, vaddr); + kernel_pte_lookup(xc->getPhysMemPtr(), ptbr, vaddr); if (pte.valid()) paddr = pte.paddr() | vaddr.offset(); } @@ -110,14 +110,14 @@ vtophys(ExecContext *xc, Addr addr) uint8_t * ptomem(ExecContext *xc, Addr paddr, size_t len) { - return xc->physmem->dma_addr(paddr, len); + return xc->getPhysMemPtr()->dma_addr(paddr, len); } uint8_t * vtomem(ExecContext *xc, Addr vaddr, size_t len) { Addr paddr = vtophys(xc, vaddr); - return xc->physmem->dma_addr(paddr, len); + return xc->getPhysMemPtr()->dma_addr(paddr, len); } void @@ -131,7 +131,7 @@ CopyOut(ExecContext *xc, void *dest, Addr src, size_t cplen) paddr = vtophys(xc, src); len = min((int)(AlphaISA::PageBytes - (paddr & AlphaISA::PageOffset)), (int)cplen); - dmaaddr = (char *)xc->physmem->dma_addr(paddr, len); + dmaaddr = (char *)xc->getPhysMemPtr()->dma_addr(paddr, len); assert(dmaaddr); memcpy(dst, dmaaddr, len); @@ -144,7 +144,8 @@ CopyOut(ExecContext *xc, void *dest, Addr src, size_t cplen) while (cplen > AlphaISA::PageBytes) { paddr = vtophys(xc, src); - dmaaddr = (char *)xc->physmem->dma_addr(paddr, AlphaISA::PageBytes); + dmaaddr = (char *)xc->getPhysMemPtr()->dma_addr(paddr, + AlphaISA::PageBytes); assert(dmaaddr); memcpy(dst, dmaaddr, AlphaISA::PageBytes); @@ -155,7 +156,7 @@ CopyOut(ExecContext *xc, void *dest, Addr src, size_t cplen) if (cplen > 0) { paddr = vtophys(xc, src); - dmaaddr = (char *)xc->physmem->dma_addr(paddr, cplen); + dmaaddr = (char *)xc->getPhysMemPtr()->dma_addr(paddr, cplen); assert(dmaaddr); memcpy(dst, dmaaddr, cplen); @@ -173,7 +174,7 @@ CopyIn(ExecContext *xc, Addr dest, void *source, size_t cplen) paddr = vtophys(xc, dest); len = min((int)(AlphaISA::PageBytes - (paddr & AlphaISA::PageOffset)), (int)cplen); - dmaaddr = (char *)xc->physmem->dma_addr(paddr, len); + dmaaddr = (char *)xc->getPhysMemPtr()->dma_addr(paddr, len); assert(dmaaddr); memcpy(dmaaddr, src, len); @@ -186,7 +187,8 @@ CopyIn(ExecContext *xc, Addr dest, void *source, size_t cplen) while (cplen > AlphaISA::PageBytes) { paddr = vtophys(xc, dest); - dmaaddr = (char *)xc->physmem->dma_addr(paddr, AlphaISA::PageBytes); + dmaaddr = (char *)xc->getPhysMemPtr()->dma_addr(paddr, + AlphaISA::PageBytes); assert(dmaaddr); memcpy(dmaaddr, src, AlphaISA::PageBytes); @@ -197,7 +199,7 @@ CopyIn(ExecContext *xc, Addr dest, void *source, size_t cplen) if (cplen > 0) { paddr = vtophys(xc, dest); - dmaaddr = (char *)xc->physmem->dma_addr(paddr, cplen); + dmaaddr = (char *)xc->getPhysMemPtr()->dma_addr(paddr, cplen); assert(dmaaddr); memcpy(dmaaddr, src, cplen); @@ -214,7 +216,7 @@ CopyString(ExecContext *xc, char *dst, Addr vaddr, size_t maxlen) paddr = vtophys(xc, vaddr); len = min((int)(AlphaISA::PageBytes - (paddr & AlphaISA::PageOffset)), (int)maxlen); - dmaaddr = (char *)xc->physmem->dma_addr(paddr, len); + dmaaddr = (char *)xc->getPhysMemPtr()->dma_addr(paddr, len); assert(dmaaddr); char *term = (char *)memchr(dmaaddr, 0, len); @@ -232,7 +234,8 @@ CopyString(ExecContext *xc, char *dst, Addr vaddr, size_t maxlen) while (maxlen > AlphaISA::PageBytes) { paddr = vtophys(xc, vaddr); - dmaaddr = (char *)xc->physmem->dma_addr(paddr, AlphaISA::PageBytes); + dmaaddr = (char *)xc->getPhysMemPtr()->dma_addr(paddr, + AlphaISA::PageBytes); assert(dmaaddr); char *term = (char *)memchr(dmaaddr, 0, AlphaISA::PageBytes); @@ -249,7 +252,7 @@ CopyString(ExecContext *xc, char *dst, Addr vaddr, size_t maxlen) if (maxlen > 0) { paddr = vtophys(xc, vaddr); - dmaaddr = (char *)xc->physmem->dma_addr(paddr, maxlen); + dmaaddr = (char *)xc->getPhysMemPtr()->dma_addr(paddr, maxlen); assert(dmaaddr); char *term = (char *)memchr(dmaaddr, 0, maxlen); diff --git a/base/remote_gdb.cc b/base/remote_gdb.cc index 5f1a2db2c..50c4798c4 100644 --- a/base/remote_gdb.cc +++ b/base/remote_gdb.cc @@ -429,7 +429,7 @@ RemoteGDB::getregs() memcpy(&gdbregs[KGDB_REG_F0], context->regs.floatRegFile.q, 32 * sizeof(uint64_t)); #endif - gdbregs[KGDB_REG_PC] = context->regs.pc; + gdbregs[KGDB_REG_PC] = context->readPC(); } /////////////////////////////////////////////////////////// @@ -447,7 +447,7 @@ RemoteGDB::setregs() memcpy(context->regs.floatRegFile.q, &gdbregs[KGDB_REG_F0], 32 * sizeof(uint64_t)); #endif - context->regs.pc = gdbregs[KGDB_REG_PC]; + context->setPC(gdbregs[KGDB_REG_PC]); } void @@ -486,7 +486,7 @@ RemoteGDB::clearSingleStep() void RemoteGDB::setSingleStep() { - Addr pc = context->regs.pc; + Addr pc = context->readPC(); Addr npc, bpc; bool set_bt = false; @@ -835,7 +835,7 @@ RemoteGDB::trap(int type) return false; DPRINTF(GDBMisc, "trap: PC=%#x NPC=%#x\n", - context->regs.pc, context->regs.npc); + context->readPC(), context->readNextPC()); clearSingleStep(); @@ -990,8 +990,8 @@ RemoteGDB::trap(int type) subcmd = hex2i(&p); if (*p++ == ';') { val = hex2i(&p); - context->regs.pc = val; - context->regs.npc = val + sizeof(MachInst); + context->setPC(val); + context->setNextPC(val + sizeof(MachInst)); } clearSingleStep(); goto out; @@ -999,8 +999,8 @@ RemoteGDB::trap(int type) case KGDB_CONT: if (p - data < datalen) { val = hex2i(&p); - context->regs.pc = val; - context->regs.npc = val + sizeof(MachInst); + context->setPC(val); + context->setNextPC(val + sizeof(MachInst)); } clearSingleStep(); goto out; @@ -1009,8 +1009,8 @@ RemoteGDB::trap(int type) subcmd = hex2i(&p); if (*p++ == ';') { val = hex2i(&p); - context->regs.pc = val; - context->regs.npc = val + sizeof(MachInst); + context->setPC(val); + context->setNextPC(val + sizeof(MachInst)); } setSingleStep(); goto out; @@ -1018,8 +1018,8 @@ RemoteGDB::trap(int type) case KGDB_STEP: if (p - data < datalen) { val = hex2i(&p); - context->regs.pc = val; - context->regs.npc = val + sizeof(MachInst); + context->setPC(val); + context->setNextPC(val + sizeof(MachInst)); } setSingleStep(); goto out; diff --git a/cpu/base.cc b/cpu/base.cc index 5a7ecf152..e2a4c214a 100644 --- a/cpu/base.cc +++ b/cpu/base.cc @@ -39,10 +39,16 @@ #include "cpu/profile.hh" #include "cpu/sampler/sampler.hh" #include "sim/param.hh" +#include "sim/process.hh" #include "sim/sim_events.hh" +#include "sim/system.hh" #include "base/trace.hh" +#if FULL_SYSTEM +#include "kern/kernel_stats.hh" +#endif + using namespace std; vector BaseCPU::cpuList; @@ -147,7 +153,10 @@ BaseCPU::BaseCPU(Params *p) profileEvent = NULL; if (params->profile) profileEvent = new ProfileEvent(this, params->profile); + + kernelStats = new Kernel::Statistics(system); #endif + } BaseCPU::Params::Params() @@ -165,6 +174,10 @@ BaseCPU::enableFunctionTrace() BaseCPU::~BaseCPU() { +#if FULL_SYSTEM + if (kernelStats) + delete kernelStats; +#endif } void @@ -203,6 +216,11 @@ BaseCPU::regStats() } } else if (size == 1) execContexts[0]->regStats(name()); + +#if FULL_SYSTEM + if (kernelStats) + kernelStats->regStats(name() + ".kern"); +#endif } @@ -216,9 +234,9 @@ BaseCPU::registerExecContexts() if (id != -1) id += i; - xc->cpu_id = system->registerExecContext(xc, id); + xc->setCpuId(system->registerExecContext(xc, id)); #else - xc->cpu_id = xc->process->registerExecContext(xc); + xc->setCpuId(xc->getProcessPtr()->registerExecContext(xc)); #endif } } @@ -240,12 +258,12 @@ BaseCPU::takeOverFrom(BaseCPU *oldCPU) ExecContext *oldXC = oldCPU->execContexts[i]; newXC->takeOverFrom(oldXC); - assert(newXC->cpu_id == oldXC->cpu_id); + assert(newXC->readCpuId() == oldXC->readCpuId()); #if FULL_SYSTEM - system->replaceExecContext(newXC, newXC->cpu_id); + system->replaceExecContext(newXC, newXC->readCpuId()); #else - assert(newXC->process == oldXC->process); - newXC->process->replaceExecContext(newXC, newXC->cpu_id); + assert(newXC->getProcessPtr() == oldXC->getProcessPtr()); + newXC->getProcessPtr()->replaceExecContext(newXC, newXC->readCpuId()); #endif } @@ -253,11 +271,11 @@ BaseCPU::takeOverFrom(BaseCPU *oldCPU) for (int i = 0; i < TheISA::NumInterruptLevels; ++i) interrupts[i] = oldCPU->interrupts[i]; intstatus = oldCPU->intstatus; - +/* for (int i = 0; i < execContexts.size(); ++i) if (execContexts[i]->profile) execContexts[i]->profile->clear(); - +*/ if (profileEvent) profileEvent->schedule(curTick); #endif @@ -272,11 +290,11 @@ BaseCPU::ProfileEvent::ProfileEvent(BaseCPU *_cpu, int _interval) void BaseCPU::ProfileEvent::process() { - for (int i = 0, size = cpu->execContexts.size(); i < size; ++i) { +/* for (int i = 0, size = cpu->execContexts.size(); i < size; ++i) { ExecContext *xc = cpu->execContexts[i]; xc->profile->sample(xc->profileNode, xc->profilePC); } - +*/ schedule(curTick + interval); } @@ -327,6 +345,12 @@ BaseCPU::serialize(std::ostream &os) { SERIALIZE_ARRAY(interrupts, TheISA::NumInterruptLevels); SERIALIZE_SCALAR(intstatus); + +#if FULL_SYSTEM + if (kernelStats) + kernelStats->serialize(os); +#endif + } void @@ -334,6 +358,11 @@ BaseCPU::unserialize(Checkpoint *cp, const std::string §ion) { UNSERIALIZE_ARRAY(interrupts, TheISA::NumInterruptLevels); UNSERIALIZE_SCALAR(intstatus); + +#if FULL_SYSTEM + if (kernelStats) + kernelStats->unserialize(cp, section); +#endif } #endif // FULL_SYSTEM diff --git a/cpu/base.hh b/cpu/base.hh index d5764d495..d9d5d2b88 100644 --- a/cpu/base.hh +++ b/cpu/base.hh @@ -40,6 +40,7 @@ #if FULL_SYSTEM class System; +namespace Kernel { class Statistics; } #endif class BranchPred; @@ -234,6 +235,10 @@ class BaseCPU : public SimObject public: // Number of CPU cycles simulated Stats::Scalar<> numCycles; + +#if FULL_SYSTEM + Kernel::Statistics *kernelStats; +#endif }; #endif // __CPU_BASE_HH__ diff --git a/cpu/base_dyn_inst.cc b/cpu/base_dyn_inst.cc index 86314bef1..a40b4a1dd 100644 --- a/cpu/base_dyn_inst.cc +++ b/cpu/base_dyn_inst.cc @@ -67,7 +67,7 @@ template BaseDynInst::BaseDynInst(MachInst machInst, Addr inst_PC, Addr pred_PC, InstSeqNum seq_num, FullCPU *cpu) - : staticInst(machInst), traceData(NULL), cpu(cpu), xc(cpu->xcBase()) + : staticInst(machInst), traceData(NULL), cpu(cpu), cpuXC(cpu->cpuXCBase()) { seqNum = seq_num; @@ -138,14 +138,14 @@ BaseDynInst::prefetch(Addr addr, unsigned flags) // state. // Generate a MemReq so we can translate the effective address. - MemReqPtr req = new MemReq(addr, xc, 1, flags); + MemReqPtr req = new MemReq(addr, cpuXC->getProxy(), 1, flags); req->asid = asid; // Prefetches never cause faults. fault = NoFault; // note this is a local, not BaseDynInst::fault - Fault trans_fault = xc->translateDataReadReq(req); + Fault trans_fault = cpuXC->translateDataReadReq(req); if (trans_fault == NoFault && !(req->flags & UNCACHEABLE)) { // It's a valid address to cacheable space. Record key MemReq @@ -183,10 +183,10 @@ BaseDynInst::writeHint(Addr addr, int size, unsigned flags) // will casue a TLB miss trap if necessary... not sure whether // that's the best thing to do or not. We don't really need the // MemReq otherwise, since wh64 has no functional effect. - MemReqPtr req = new MemReq(addr, xc, size, flags); + MemReqPtr req = new MemReq(addr, cpuXC->getProxy(), size, flags); req->asid = asid; - fault = xc->translateDataWriteReq(req); + fault = cpuXC->translateDataWriteReq(req); if (fault == NoFault && !(req->flags & UNCACHEABLE)) { // Record key MemReq parameters so we can generate another one @@ -211,18 +211,18 @@ template Fault BaseDynInst::copySrcTranslate(Addr src) { - MemReqPtr req = new MemReq(src, xc, 64); + MemReqPtr req = new MemReq(src, cpuXC->getProxy(), 64); req->asid = asid; // translate to physical address - Fault fault = xc->translateDataReadReq(req); + Fault fault = cpuXC->translateDataReadReq(req); if (fault == NoFault) { - xc->copySrcAddr = src; - xc->copySrcPhysAddr = req->paddr; + cpuXC->copySrcAddr = src; + cpuXC->copySrcPhysAddr = req->paddr; } else { - xc->copySrcAddr = 0; - xc->copySrcPhysAddr = 0; + cpuXC->copySrcAddr = 0; + cpuXC->copySrcPhysAddr = 0; } return fault; } @@ -235,18 +235,18 @@ Fault BaseDynInst::copy(Addr dest) { uint8_t data[64]; - FunctionalMemory *mem = xc->mem; - assert(xc->copySrcPhysAddr || xc->misspeculating()); - MemReqPtr req = new MemReq(dest, xc, 64); + FunctionalMemory *mem = cpuXC->mem; + assert(cpuXC->copySrcPhysAddr || cpuXC->misspeculating()); + MemReqPtr req = new MemReq(dest, cpuXC->getProxy(), 64); req->asid = asid; // translate to physical address - Fault fault = xc->translateDataWriteReq(req); + Fault fault = cpuXC->translateDataWriteReq(req); if (fault == NoFault) { Addr dest_addr = req->paddr; // Need to read straight from memory since we have more than 8 bytes. - req->paddr = xc->copySrcPhysAddr; + req->paddr = cpuXC->copySrcPhysAddr; mem->read(req, data); req->paddr = dest_addr; mem->write(req, data); diff --git a/cpu/base_dyn_inst.hh b/cpu/base_dyn_inst.hh index e94c44151..3a7852f79 100644 --- a/cpu/base_dyn_inst.hh +++ b/cpu/base_dyn_inst.hh @@ -145,7 +145,7 @@ class BaseDynInst : public FastAlloc, public RefCounted FullCPU *cpu; /** Pointer to the exec context. Will not exist in the final version. */ - ExecContext *xc; + CPUExecContext *cpuXC; /** The kind of fault this instruction has generated. */ Fault fault; @@ -406,7 +406,7 @@ class BaseDynInst : public FastAlloc, public RefCounted /** Returns the exec context. * @todo: Remove this once the ExecContext is no longer used. */ - ExecContext *xcBase() { return xc; } + ExecContext *xcBase() { return cpuXC->getProxy(); } private: /** Instruction effective address. @@ -444,7 +444,7 @@ template inline Fault BaseDynInst::read(Addr addr, T &data, unsigned flags) { - MemReqPtr req = new MemReq(addr, xc, sizeof(T), flags); + MemReqPtr req = new MemReq(addr, cpuXC->getProxy(), sizeof(T), flags); req->asid = asid; fault = cpu->translateDataReadReq(req); @@ -492,7 +492,7 @@ BaseDynInst::write(T data, Addr addr, unsigned flags, uint64_t *res) traceData->setData(data); } - MemReqPtr req = new MemReq(addr, xc, sizeof(T), flags); + MemReqPtr req = new MemReq(addr, cpuXC->getProxy(), sizeof(T), flags); req->asid = asid; diff --git a/cpu/exec_context.cc b/cpu/cpu_exec_context.cc similarity index 64% rename from cpu/exec_context.cc rename to cpu/cpu_exec_context.cc index 9bed3ba47..2fb3d5d53 100644 --- a/cpu/exec_context.cc +++ b/cpu/cpu_exec_context.cc @@ -29,6 +29,7 @@ #include #include "cpu/base.hh" +#include "cpu/cpu_exec_context.hh" #include "cpu/exec_context.hh" #if FULL_SYSTEM @@ -49,23 +50,23 @@ using namespace std; // constructor #if FULL_SYSTEM -ExecContext::ExecContext(BaseCPU *_cpu, int _thread_num, System *_sys, +CPUExecContext::CPUExecContext(BaseCPU *_cpu, int _thread_num, System *_sys, AlphaITB *_itb, AlphaDTB *_dtb, FunctionalMemory *_mem) : _status(ExecContext::Unallocated), cpu(_cpu), thread_num(_thread_num), cpu_id(-1), mem(_mem), itb(_itb), dtb(_dtb), system(_sys), - memctrl(_sys->memctrl), physmem(_sys->physmem), - kernelBinning(system->kernelBinning), bin(kernelBinning->bin), - fnbin(kernelBinning->fnbin), profile(NULL), + memctrl(_sys->memctrl), physmem(_sys->physmem), profile(NULL), func_exe_inst(0), storeCondFailures(0) { - kernelStats = new Kernel::Statistics(this); + proxy = new ProxyExecContext(this); + memset(®s, 0, sizeof(RegFile)); if (cpu->params->profile) { profile = new FunctionProfile(system->kernelSymtab); Callback *cb = - new MakeCallback(this); + new MakeCallback(this); registerExitCallback(cb); } @@ -76,7 +77,7 @@ ExecContext::ExecContext(BaseCPU *_cpu, int _thread_num, System *_sys, profilePC = 3; } #else -ExecContext::ExecContext(BaseCPU *_cpu, int _thread_num, +CPUExecContext::CPUExecContext(BaseCPU *_cpu, int _thread_num, Process *_process, int _asid) : _status(ExecContext::Unallocated), cpu(_cpu), thread_num(_thread_num), cpu_id(-1), @@ -84,36 +85,46 @@ ExecContext::ExecContext(BaseCPU *_cpu, int _thread_num, func_exe_inst(0), storeCondFailures(0) { memset(®s, 0, sizeof(RegFile)); + proxy = new ProxyExecContext(this); } -ExecContext::ExecContext(BaseCPU *_cpu, int _thread_num, +CPUExecContext::CPUExecContext(BaseCPU *_cpu, int _thread_num, FunctionalMemory *_mem, int _asid) : cpu(_cpu), thread_num(_thread_num), process(0), mem(_mem), asid(_asid), func_exe_inst(0), storeCondFailures(0) { memset(®s, 0, sizeof(RegFile)); + proxy = new ProxyExecContext(this); } + +CPUExecContext::CPUExecContext(RegFile *regFile) + : cpu(NULL), thread_num(-1), process(NULL), mem(NULL), asid(-1), + func_exe_inst(0), storeCondFailures(0) +{ + regs = *regFile; + proxy = new ProxyExecContext(this); +} + #endif -ExecContext::~ExecContext() +CPUExecContext::~CPUExecContext() { -#if FULL_SYSTEM - delete kernelStats; -#endif + delete proxy; } #if FULL_SYSTEM void -ExecContext::dumpFuncProfile() +CPUExecContext::dumpFuncProfile() { std::ostream *os = simout.create(csprintf("profile.%s.dat", cpu->name())); - profile->dump(this, *os); + profile->dump(proxy, *os); } #endif void -ExecContext::takeOverFrom(ExecContext *oldContext) +CPUExecContext::takeOverFrom(ExecContext *oldContext) { +/* // some things should already be set up assert(mem == oldContext->mem); #if FULL_SYSTEM @@ -130,98 +141,115 @@ ExecContext::takeOverFrom(ExecContext *oldContext) storeCondFailures = 0; - oldContext->_status = ExecContext::Unallocated; + oldContext->_status = CPUExecContext::Unallocated; +*/ } void -ExecContext::serialize(ostream &os) +CPUExecContext::serialize(ostream &os) { SERIALIZE_ENUM(_status); regs.serialize(os); // thread_num and cpu_id are deterministic from the config SERIALIZE_SCALAR(func_exe_inst); SERIALIZE_SCALAR(inst); - -#if FULL_SYSTEM - kernelStats->serialize(os); -#endif } void -ExecContext::unserialize(Checkpoint *cp, const std::string §ion) +CPUExecContext::unserialize(Checkpoint *cp, const std::string §ion) { UNSERIALIZE_ENUM(_status); regs.unserialize(cp, section); // thread_num and cpu_id are deterministic from the config UNSERIALIZE_SCALAR(func_exe_inst); UNSERIALIZE_SCALAR(inst); - -#if FULL_SYSTEM - kernelStats->unserialize(cp, section); -#endif } void -ExecContext::activate(int delay) +CPUExecContext::activate(int delay) { - if (status() == Active) + if (status() == ExecContext::Active) return; - _status = Active; + _status = ExecContext::Active; cpu->activateContext(thread_num, delay); } void -ExecContext::suspend() +CPUExecContext::suspend() { - if (status() == Suspended) + if (status() == ExecContext::Suspended) return; #if FULL_SYSTEM // Don't change the status from active if there are pending interrupts if (cpu->check_interrupts()) { - assert(status() == Active); + assert(status() == ExecContext::Active); return; } #endif - _status = Suspended; + _status = ExecContext::Suspended; cpu->suspendContext(thread_num); } void -ExecContext::deallocate() +CPUExecContext::deallocate() { - if (status() == Unallocated) + if (status() == ExecContext::Unallocated) return; - _status = Unallocated; + _status = ExecContext::Unallocated; cpu->deallocateContext(thread_num); } void -ExecContext::halt() +CPUExecContext::halt() { - if (status() == Halted) + if (status() == ExecContext::Halted) return; - _status = Halted; + _status = ExecContext::Halted; cpu->haltContext(thread_num); } void -ExecContext::regStats(const string &name) +CPUExecContext::regStats(const string &name) { -#if FULL_SYSTEM - kernelStats->regStats(name + ".kern"); -#endif } void -ExecContext::trap(Fault fault) +CPUExecContext::copyArchRegs(ExecContext *xc) +{ + // First loop through the integer registers. + for (int i = 0; i < AlphaISA::NumIntRegs; ++i) { + setIntReg(i, xc->readIntReg(i)); + } + + // Then loop through the floating point registers. + for (int i = 0; i < AlphaISA::NumFloatRegs; ++i) { + setFloatRegDouble(i, xc->readFloatRegDouble(i)); + setFloatRegInt(i, xc->readFloatRegInt(i)); + } + + // Copy misc. registers + setMiscReg(AlphaISA::Fpcr_DepTag, xc->readMiscReg(AlphaISA::Fpcr_DepTag)); + setMiscReg(AlphaISA::Uniq_DepTag, xc->readMiscReg(AlphaISA::Uniq_DepTag)); + setMiscReg(AlphaISA::Lock_Flag_DepTag, + xc->readMiscReg(AlphaISA::Lock_Flag_DepTag)); + setMiscReg(AlphaISA::Lock_Addr_DepTag, + xc->readMiscReg(AlphaISA::Lock_Addr_DepTag)); + + // Lastly copy PC/NPC + setPC(xc->readPC()); + setNextPC(xc->readNextPC()); +} + +void +CPUExecContext::trap(Fault fault) { //TheISA::trap(fault); //One possible way to do it... diff --git a/cpu/cpu_exec_context.hh b/cpu/cpu_exec_context.hh new file mode 100644 index 000000000..1ae24582d --- /dev/null +++ b/cpu/cpu_exec_context.hh @@ -0,0 +1,510 @@ +/* + * Copyright (c) 2001-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 __CPU_CPU_EXEC_CONTEXT_HH__ +#define __CPU_CPU_EXEC_CONTEXT_HH__ + +#include "arch/isa_traits.hh" +#include "config/full_system.hh" +#include "cpu/exec_context.hh" +#include "mem/functional/functional.hh" +#include "mem/mem_req.hh" +#include "sim/byteswap.hh" +#include "sim/host.hh" +#include "sim/serialize.hh" + +// forward declaration: see functional_memory.hh +class FunctionalMemory; +class PhysicalMemory; +class BaseCPU; + +#if FULL_SYSTEM + +#include "sim/system.hh" +#include "targetarch/alpha_memory.hh" + +class FunctionProfile; +class ProfileNode; +class MemoryController; + +#else // !FULL_SYSTEM + +#include "sim/process.hh" + +#endif // FULL_SYSTEM + +// +// The CPUExecContext object represents a functional context for +// instruction execution. It incorporates everything required for +// architecture-level functional simulation of a single thread. +// + +class CPUExecContext +{ + protected: + typedef TheISA::RegFile RegFile; + typedef TheISA::MachInst MachInst; + typedef TheISA::MiscRegFile MiscRegFile; + typedef TheISA::MiscReg MiscReg; + public: + typedef ExecContext::Status Status; + + private: + Status _status; + + public: + Status status() const { return _status; } + + void setStatus(Status newStatus) { _status = newStatus; } + + /// Set the status to Active. Optional delay indicates number of + /// cycles to wait before beginning execution. + void activate(int delay = 1); + + /// Set the status to Suspended. + void suspend(); + + /// Set the status to Unallocated. + void deallocate(); + + /// Set the status to Halted. + void halt(); + + protected: + RegFile regs; // correct-path register context + + public: + // pointer to CPU associated with this context + BaseCPU *cpu; + + ProxyExecContext *proxy; + + // Current instruction + MachInst inst; + + // Index of hardware thread context on the CPU that this represents. + int thread_num; + + // ID of this context w.r.t. the System or Process object to which + // it belongs. For full-system mode, this is the system CPU ID. + int cpu_id; + +#if FULL_SYSTEM + FunctionalMemory *mem; + AlphaITB *itb; + AlphaDTB *dtb; + System *system; + + // the following two fields are redundant, since we can always + // look them up through the system pointer, but we'll leave them + // here for now for convenience + MemoryController *memctrl; + PhysicalMemory *physmem; + + FunctionProfile *profile; + ProfileNode *profileNode; + Addr profilePC; + void dumpFuncProfile(); + +#else + Process *process; + + FunctionalMemory *mem; // functional storage for process address space + + // Address space ID. Note that this is used for TIMING cache + // simulation only; all functional memory accesses should use + // one of the FunctionalMemory pointers above. + short asid; + +#endif + + /** + * Temporary storage to pass the source address from copy_load to + * copy_store. + * @todo Remove this temporary when we have a better way to do it. + */ + Addr copySrcAddr; + /** + * Temp storage for the physical source address of a copy. + * @todo Remove this temporary when we have a better way to do it. + */ + Addr copySrcPhysAddr; + + + /* + * number of executed instructions, for matching with syscall trace + * points in EIO files. + */ + Counter func_exe_inst; + + // + // Count failed store conditionals so we can warn of apparent + // application deadlock situations. + unsigned storeCondFailures; + + // constructor: initialize context from given process structure +#if FULL_SYSTEM + CPUExecContext(BaseCPU *_cpu, int _thread_num, System *_system, + AlphaITB *_itb, AlphaDTB *_dtb, FunctionalMemory *_dem); +#else + CPUExecContext(BaseCPU *_cpu, int _thread_num, Process *_process, int _asid); + CPUExecContext(BaseCPU *_cpu, int _thread_num, FunctionalMemory *_mem, + int _asid); + // Constructor to use XC to pass reg file around. Not used for anything + // else. + CPUExecContext(RegFile *regFile); +#endif + virtual ~CPUExecContext(); + + virtual void takeOverFrom(ExecContext *oldContext); + + void regStats(const std::string &name); + + void serialize(std::ostream &os); + void unserialize(Checkpoint *cp, const std::string §ion); + + BaseCPU *getCpuPtr() { return cpu; } + + ExecContext *getProxy() { return proxy; } + + int getThreadNum() { return thread_num; } + +#if FULL_SYSTEM + System *getSystemPtr() { return system; } + + PhysicalMemory *getPhysMemPtr() { return physmem; } + + AlphaITB *getITBPtr() { return itb; } + + AlphaDTB *getDTBPtr() { return dtb; } + + bool validInstAddr(Addr addr) { return true; } + bool validDataAddr(Addr addr) { return true; } + int getInstAsid() { return regs.instAsid(); } + int getDataAsid() { return regs.dataAsid(); } + + Fault translateInstReq(MemReqPtr &req) + { + return itb->translate(req); + } + + Fault translateDataReadReq(MemReqPtr &req) + { + return dtb->translate(req, false); + } + + Fault translateDataWriteReq(MemReqPtr &req) + { + return dtb->translate(req, true); + } + +#else + Process *getProcessPtr() { return process; } + + bool validInstAddr(Addr addr) + { return process->validInstAddr(addr); } + + bool validDataAddr(Addr addr) + { return process->validDataAddr(addr); } + + int getInstAsid() { return asid; } + int getDataAsid() { return asid; } + + Fault dummyTranslation(MemReqPtr &req) + { +#if 0 + assert((req->vaddr >> 48 & 0xffff) == 0); +#endif + + // put the asid in the upper 16 bits of the paddr + req->paddr = req->vaddr & ~((Addr)0xffff << sizeof(Addr) * 8 - 16); + req->paddr = req->paddr | (Addr)req->asid << sizeof(Addr) * 8 - 16; + return NoFault; + } + Fault translateInstReq(MemReqPtr &req) + { + return dummyTranslation(req); + } + Fault translateDataReadReq(MemReqPtr &req) + { + return dummyTranslation(req); + } + Fault translateDataWriteReq(MemReqPtr &req) + { + return dummyTranslation(req); + } + +#endif + + template + Fault read(MemReqPtr &req, T &data) + { +#if FULL_SYSTEM && defined(TARGET_ALPHA) + if (req->flags & LOCKED) { + req->xc->setMiscReg(TheISA::Lock_Addr_DepTag, req->paddr); + req->xc->setMiscReg(TheISA::Lock_Flag_DepTag, true); + } +#endif + + Fault error; + error = mem->read(req, data); + data = LittleEndianGuest::gtoh(data); + return error; + } + + template + Fault write(MemReqPtr &req, T &data) + { +#if FULL_SYSTEM && defined(TARGET_ALPHA) + ExecContext *xc; + + // If this is a store conditional, act appropriately + if (req->flags & LOCKED) { + xc = req->xc; + + if (req->flags & UNCACHEABLE) { + // Don't update result register (see stq_c in isa_desc) + req->result = 2; + xc->setStCondFailures(0);//Needed? [RGD] + } else { + bool lock_flag = xc->readMiscReg(TheISA::Lock_Flag_DepTag); + Addr lock_addr = xc->readMiscReg(TheISA::Lock_Addr_DepTag); + req->result = lock_flag; + if (!lock_flag || + ((lock_addr & ~0xf) != (req->paddr & ~0xf))) { + xc->setMiscReg(TheISA::Lock_Flag_DepTag, false); + xc->setStCondFailures(xc->readStCondFailures() + 1); + if (((xc->readStCondFailures()) % 100000) == 0) { + std::cerr << "Warning: " + << xc->readStCondFailures() + << " consecutive store conditional failures " + << "on cpu " << req->xc->readCpuId() + << std::endl; + } + return NoFault; + } + else xc->setStCondFailures(0); + } + } + + // Need to clear any locked flags on other proccessors for + // this address. Only do this for succsful Store Conditionals + // and all other stores (WH64?). Unsuccessful Store + // Conditionals would have returned above, and wouldn't fall + // through. + for (int i = 0; i < system->execContexts.size(); i++){ + xc = system->execContexts[i]; + if ((xc->readMiscReg(TheISA::Lock_Addr_DepTag) & ~0xf) == + (req->paddr & ~0xf)) { + xc->setMiscReg(TheISA::Lock_Flag_DepTag, false); + } + } + +#endif + return mem->write(req, (T)LittleEndianGuest::htog(data)); + } + + virtual bool misspeculating(); + + + MachInst getInst() { return inst; } + + void setInst(MachInst new_inst) + { + inst = new_inst; + } + + Fault instRead(MemReqPtr &req) + { + return mem->read(req, inst); + } + + void setCpuId(int id) { cpu_id = id; } + + int readCpuId() { return cpu_id; } + + FunctionalMemory *getMemPtr() { return mem; } + + void copyArchRegs(ExecContext *xc); + + // + // New accessors for new decoder. + // + uint64_t readIntReg(int reg_idx) + { + return regs.intRegFile[reg_idx]; + } + + float readFloatRegSingle(int reg_idx) + { + return (float)regs.floatRegFile.d[reg_idx]; + } + + double readFloatRegDouble(int reg_idx) + { + return regs.floatRegFile.d[reg_idx]; + } + + uint64_t readFloatRegInt(int reg_idx) + { + return regs.floatRegFile.q[reg_idx]; + } + + void setIntReg(int reg_idx, uint64_t val) + { + regs.intRegFile[reg_idx] = val; + } + + void setFloatRegSingle(int reg_idx, float val) + { + regs.floatRegFile.d[reg_idx] = (double)val; + } + + void setFloatRegDouble(int reg_idx, double val) + { + regs.floatRegFile.d[reg_idx] = val; + } + + void setFloatRegInt(int reg_idx, uint64_t val) + { + regs.floatRegFile.q[reg_idx] = val; + } + + uint64_t readPC() + { + return regs.pc; + } + + void setPC(uint64_t val) + { + regs.pc = val; + } + + uint64_t readNextPC() + { + return regs.npc; + } + + void setNextPC(uint64_t val) + { + regs.npc = val; + } + + MiscReg readMiscReg(int misc_reg) + { + return regs.miscRegs.readReg(misc_reg); + } + + MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault) + { + return regs.miscRegs.readRegWithEffect(misc_reg, fault, proxy); + } + + Fault setMiscReg(int misc_reg, const MiscReg &val) + { + return regs.miscRegs.setReg(misc_reg, val); + } + + Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val) + { + return regs.miscRegs.setRegWithEffect(misc_reg, val, proxy); + } + + unsigned readStCondFailures() { return storeCondFailures; } + + void setStCondFailures(unsigned sc_failures) + { storeCondFailures = sc_failures; } + + void clearArchRegs() { memset(®s, 0, sizeof(regs)); } + +#if FULL_SYSTEM + int readIntrFlag() { return regs.intrflag; } + void setIntrFlag(int val) { regs.intrflag = val; } + Fault hwrei(); + bool inPalMode() { return AlphaISA::PcPAL(regs.pc); } + void ev5_trap(Fault fault); + bool simPalCheck(int palFunc); +#endif + + /** Meant to be more generic trap function to be + * called when an instruction faults. + * @param fault The fault generated by executing the instruction. + * @todo How to do this properly so it's dependent upon ISA only? + */ + + void trap(Fault fault); + +#if !FULL_SYSTEM + TheISA::IntReg getSyscallArg(int i) + { + return regs.intRegFile[TheISA::ArgumentReg0 + i]; + } + + // used to shift args for indirect syscall + void setSyscallArg(int i, TheISA::IntReg val) + { + regs.intRegFile[TheISA::ArgumentReg0 + i] = val; + } + + void setSyscallReturn(SyscallReturn return_value) + { + // check for error condition. Alpha syscall convention is to + // indicate success/failure in reg a3 (r19) and put the + // return value itself in the standard return value reg (v0). + const int RegA3 = 19; // only place this is used + if (return_value.successful()) { + // no error + regs.intRegFile[RegA3] = 0; + regs.intRegFile[TheISA::ReturnValueReg] = return_value.value(); + } else { + // got an error, return details + regs.intRegFile[RegA3] = (TheISA::IntReg) -1; + regs.intRegFile[TheISA::ReturnValueReg] = -return_value.value(); + } + } + + void syscall() + { + process->syscall(proxy); + } + + Counter readFuncExeInst() { return func_exe_inst; } + + void setFuncExeInst(Counter new_val) { func_exe_inst = new_val; } +#endif +}; + + +// for non-speculative execution context, spec_mode is always false +inline bool +CPUExecContext::misspeculating() +{ + return false; +} + +#endif // __CPU_CPU_EXEC_CONTEXT_HH__ diff --git a/cpu/exec_context.hh b/cpu/exec_context.hh index 88b12c301..9c96b5c42 100644 --- a/cpu/exec_context.hh +++ b/cpu/exec_context.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001-2005 The Regents of The University of Michigan + * Copyright (c) 2006 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -30,46 +30,29 @@ #define __CPU_EXEC_CONTEXT_HH__ #include "config/full_system.hh" -#include "mem/functional/functional.hh" #include "mem/mem_req.hh" +#include "sim/faults.hh" #include "sim/host.hh" #include "sim/serialize.hh" -#include "arch/isa_traits.hh" -//#include "arch/isa_registers.hh" #include "sim/byteswap.hh" // forward declaration: see functional_memory.hh +// @todo: Figure out a more architecture independent way to obtain the ITB and +// DTB pointers. +class AlphaDTB; +class AlphaITB; +class BaseCPU; class FunctionalMemory; class PhysicalMemory; -class BaseCPU; - -#if FULL_SYSTEM - -#include "sim/system.hh" -#include "targetarch/alpha_memory.hh" - -class FunctionProfile; -class ProfileNode; -class MemoryController; -namespace Kernel { class Binning; class Statistics; } - -#else // !FULL_SYSTEM - -#include "sim/process.hh" - -#endif // FULL_SYSTEM - -// -// The ExecContext object represents a functional context for -// instruction execution. It incorporates everything required for -// architecture-level functional simulation of a single thread. -// +class Process; +class System; class ExecContext { protected: typedef TheISA::RegFile RegFile; typedef TheISA::MachInst MachInst; + typedef TheISA::IntReg IntReg; typedef TheISA::MiscRegFile MiscRegFile; typedef TheISA::MiscReg MiscReg; public: @@ -86,7 +69,7 @@ class ExecContext Active, /// Temporarily inactive. Entered while waiting for - /// initialization,synchronization, etc. + /// synchronization, etc. Suspended, /// Permanently shut down. Entered when target executes @@ -95,392 +78,326 @@ class ExecContext Halted }; - private: - Status _status; + virtual ~ExecContext() { }; - public: - Status status() const { return _status; } + virtual BaseCPU *getCpuPtr() = 0; - void setStatus(Status newStatus) { _status = newStatus; } + virtual void setCpuId(int id) = 0; + + virtual int readCpuId() = 0; + + virtual FunctionalMemory *getMemPtr() = 0; + +#if FULL_SYSTEM + virtual System *getSystemPtr() = 0; + + virtual PhysicalMemory *getPhysMemPtr() = 0; + + virtual AlphaITB *getITBPtr() = 0; + + virtual AlphaDTB * getDTBPtr() = 0; +#else + virtual Process *getProcessPtr() = 0; +#endif + + virtual Status status() const = 0; /// Set the status to Active. Optional delay indicates number of /// cycles to wait before beginning execution. - void activate(int delay = 1); + virtual void activate(int delay = 1) = 0; /// Set the status to Suspended. - void suspend(); + virtual void suspend() = 0; /// Set the status to Unallocated. - void deallocate(); + virtual void deallocate() = 0; /// Set the status to Halted. - void halt(); - - public: - RegFile regs; // correct-path register context - - // pointer to CPU associated with this context - BaseCPU *cpu; - - // Current instruction - MachInst inst; - - // Index of hardware thread context on the CPU that this represents. - int thread_num; - - // ID of this context w.r.t. the System or Process object to which - // it belongs. For full-system mode, this is the system CPU ID. - int cpu_id; + virtual void halt() = 0; #if FULL_SYSTEM - FunctionalMemory *mem; - AlphaITB *itb; - AlphaDTB *dtb; - System *system; - - // the following two fields are redundant, since we can always - // look them up through the system pointer, but we'll leave them - // here for now for convenience - MemoryController *memctrl; - PhysicalMemory *physmem; - - Kernel::Binning *kernelBinning; - Kernel::Statistics *kernelStats; - bool bin; - bool fnbin; - - FunctionProfile *profile; - ProfileNode *profileNode; - Addr profilePC; - void dumpFuncProfile(); - -#else - Process *process; - - FunctionalMemory *mem; // functional storage for process address space - - // Address space ID. Note that this is used for TIMING cache - // simulation only; all functional memory accesses should use - // one of the FunctionalMemory pointers above. - short asid; - + virtual void dumpFuncProfile() = 0; #endif - /** - * Temporary storage to pass the source address from copy_load to - * copy_store. - * @todo Remove this temporary when we have a better way to do it. - */ - Addr copySrcAddr; - /** - * Temp storage for the physical source address of a copy. - * @todo Remove this temporary when we have a better way to do it. - */ - Addr copySrcPhysAddr; + virtual void takeOverFrom(ExecContext *oldContext) = 0; + virtual void regStats(const std::string &name) = 0; - /* - * number of executed instructions, for matching with syscall trace - * points in EIO files. - */ - Counter func_exe_inst; + virtual void serialize(std::ostream &os) = 0; + virtual void unserialize(Checkpoint *cp, const std::string §ion) = 0; - // - // Count failed store conditionals so we can warn of apparent - // application deadlock situations. - unsigned storeCondFailures; + virtual int getThreadNum() = 0; - // constructor: initialize context from given process structure -#if FULL_SYSTEM - ExecContext(BaseCPU *_cpu, int _thread_num, System *_system, - AlphaITB *_itb, AlphaDTB *_dtb, FunctionalMemory *_dem); -#else - ExecContext(BaseCPU *_cpu, int _thread_num, Process *_process, int _asid); - ExecContext(BaseCPU *_cpu, int _thread_num, FunctionalMemory *_mem, - int _asid); -#endif - virtual ~ExecContext(); + virtual bool validInstAddr(Addr addr) = 0; + virtual bool validDataAddr(Addr addr) = 0; + virtual int getInstAsid() = 0; + virtual int getDataAsid() = 0; - virtual void takeOverFrom(ExecContext *oldContext); + virtual Fault translateInstReq(MemReqPtr &req) = 0; - void regStats(const std::string &name); + virtual Fault translateDataReadReq(MemReqPtr &req) = 0; - void serialize(std::ostream &os); - void unserialize(Checkpoint *cp, const std::string §ion); + virtual Fault translateDataWriteReq(MemReqPtr &req) = 0; -#if FULL_SYSTEM - bool validInstAddr(Addr addr) { return true; } - bool validDataAddr(Addr addr) { return true; } - int getInstAsid() { return regs.instAsid(); } - int getDataAsid() { return regs.dataAsid(); } + virtual TheISA::MachInst getInst() = 0; - Fault translateInstReq(MemReqPtr &req) - { - return itb->translate(req); - } + virtual void copyArchRegs(ExecContext *xc) = 0; - Fault translateDataReadReq(MemReqPtr &req) - { - return dtb->translate(req, false); - } - - Fault translateDataWriteReq(MemReqPtr &req) - { - return dtb->translate(req, true); - } - -#else - bool validInstAddr(Addr addr) - { return process->validInstAddr(addr); } - - bool validDataAddr(Addr addr) - { return process->validDataAddr(addr); } - - int getInstAsid() { return asid; } - int getDataAsid() { return asid; } - - Fault dummyTranslation(MemReqPtr &req) - { -#if 0 - assert((req->vaddr >> 48 & 0xffff) == 0); -#endif - - // put the asid in the upper 16 bits of the paddr - req->paddr = req->vaddr & ~((Addr)0xffff << sizeof(Addr) * 8 - 16); - req->paddr = req->paddr | (Addr)req->asid << sizeof(Addr) * 8 - 16; - return NoFault; - } - Fault translateInstReq(MemReqPtr &req) - { - return dummyTranslation(req); - } - Fault translateDataReadReq(MemReqPtr &req) - { - return dummyTranslation(req); - } - Fault translateDataWriteReq(MemReqPtr &req) - { - return dummyTranslation(req); - } - -#endif - - template - Fault read(MemReqPtr &req, T &data) - { -#if FULL_SYSTEM && defined(TARGET_ALPHA) - if (req->flags & LOCKED) { - MiscRegFile *cregs = &req->xc->regs.miscRegs; - cregs->setReg(TheISA::Lock_Addr_DepTag, req->paddr); - cregs->setReg(TheISA::Lock_Flag_DepTag, true); - } -#endif - - Fault error; - error = mem->read(req, data); - data = LittleEndianGuest::gtoh(data); - return error; - } - - template - Fault write(MemReqPtr &req, T &data) - { -#if FULL_SYSTEM && defined(TARGET_ALPHA) - - MiscRegFile *cregs; - - // If this is a store conditional, act appropriately - if (req->flags & LOCKED) { - cregs = &req->xc->regs.miscRegs; - - if (req->flags & UNCACHEABLE) { - // Don't update result register (see stq_c in isa_desc) - req->result = 2; - req->xc->storeCondFailures = 0;//Needed? [RGD] - } else { - bool lock_flag = cregs->readReg(TheISA::Lock_Flag_DepTag); - Addr lock_addr = cregs->readReg(TheISA::Lock_Addr_DepTag); - req->result = lock_flag; - if (!lock_flag || - ((lock_addr & ~0xf) != (req->paddr & ~0xf))) { - cregs->setReg(TheISA::Lock_Flag_DepTag, false); - if (((++req->xc->storeCondFailures) % 100000) == 0) { - std::cerr << "Warning: " - << req->xc->storeCondFailures - << " consecutive store conditional failures " - << "on cpu " << req->xc->cpu_id - << std::endl; - } - return NoFault; - } - else req->xc->storeCondFailures = 0; - } - } - - // Need to clear any locked flags on other proccessors for - // this address. Only do this for succsful Store Conditionals - // and all other stores (WH64?). Unsuccessful Store - // Conditionals would have returned above, and wouldn't fall - // through. - for (int i = 0; i < system->execContexts.size(); i++){ - cregs = &system->execContexts[i]->regs.miscRegs; - if ((cregs->readReg(TheISA::Lock_Addr_DepTag) & ~0xf) == - (req->paddr & ~0xf)) { - cregs->setReg(TheISA::Lock_Flag_DepTag, false); - } - } - -#endif - return mem->write(req, (T)LittleEndianGuest::htog(data)); - } - - virtual bool misspeculating(); - - - MachInst getInst() { return inst; } - - void setInst(MachInst new_inst) - { - inst = new_inst; - } - - Fault instRead(MemReqPtr &req) - { - return mem->read(req, inst); - } + virtual void clearArchRegs() = 0; // // New accessors for new decoder. // - uint64_t readIntReg(int reg_idx) - { - return regs.intRegFile[reg_idx]; - } + virtual uint64_t readIntReg(int reg_idx) = 0; - float readFloatRegSingle(int reg_idx) - { - return (float)regs.floatRegFile.d[reg_idx]; - } + virtual float readFloatRegSingle(int reg_idx) = 0; - double readFloatRegDouble(int reg_idx) - { - return regs.floatRegFile.d[reg_idx]; - } + virtual double readFloatRegDouble(int reg_idx) = 0; - uint64_t readFloatRegInt(int reg_idx) - { - return regs.floatRegFile.q[reg_idx]; - } + virtual uint64_t readFloatRegInt(int reg_idx) = 0; - void setIntReg(int reg_idx, uint64_t val) - { - regs.intRegFile[reg_idx] = val; - } + virtual void setIntReg(int reg_idx, uint64_t val) = 0; - void setFloatRegSingle(int reg_idx, float val) - { - regs.floatRegFile.d[reg_idx] = (double)val; - } + virtual void setFloatRegSingle(int reg_idx, float val) = 0; - void setFloatRegDouble(int reg_idx, double val) - { - regs.floatRegFile.d[reg_idx] = val; - } + virtual void setFloatRegDouble(int reg_idx, double val) = 0; - void setFloatRegInt(int reg_idx, uint64_t val) - { - regs.floatRegFile.q[reg_idx] = val; - } + virtual void setFloatRegInt(int reg_idx, uint64_t val) = 0; - uint64_t readPC() - { - return regs.pc; - } + virtual uint64_t readPC() = 0; - void setNextPC(uint64_t val) - { - regs.npc = val; - } + virtual void setPC(uint64_t val) = 0; - MiscReg readMiscReg(int misc_reg) - { - return regs.miscRegs.readReg(misc_reg); - } + virtual uint64_t readNextPC() = 0; - MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault) - { - return regs.miscRegs.readRegWithEffect(misc_reg, fault, this); - } + virtual void setNextPC(uint64_t val) = 0; - Fault setMiscReg(int misc_reg, const MiscReg &val) - { - return regs.miscRegs.setReg(misc_reg, val); - } + virtual MiscReg readMiscReg(int misc_reg) = 0; - Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val) - { - return regs.miscRegs.setRegWithEffect(misc_reg, val, this); - } + virtual MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault) = 0; + + virtual Fault setMiscReg(int misc_reg, const MiscReg &val) = 0; + + virtual Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val) = 0; + + virtual unsigned readStCondFailures() = 0; + + virtual void setStCondFailures(unsigned sc_failures) = 0; #if FULL_SYSTEM - int readIntrFlag() { return regs.intrflag; } - void setIntrFlag(int val) { regs.intrflag = val; } - Fault hwrei(); - bool inPalMode() { return AlphaISA::PcPAL(regs.pc); } - void ev5_trap(Fault fault); - bool simPalCheck(int palFunc); + virtual int readIntrFlag() = 0; + virtual void setIntrFlag(int val) = 0; + virtual Fault hwrei() = 0; + virtual bool inPalMode() = 0; + virtual void ev5_trap(Fault fault) = 0; + virtual bool simPalCheck(int palFunc) = 0; #endif + virtual bool misspeculating() = 0; + /** Meant to be more generic trap function to be * called when an instruction faults. * @param fault The fault generated by executing the instruction. * @todo How to do this properly so it's dependent upon ISA only? */ - void trap(Fault fault); + virtual void trap(Fault fault) = 0; #if !FULL_SYSTEM - TheISA::IntReg getSyscallArg(int i) - { - return regs.intRegFile[TheISA::ArgumentReg0 + i]; - } + virtual IntReg getSyscallArg(int i) = 0; // used to shift args for indirect syscall - void setSyscallArg(int i, TheISA::IntReg val) - { - regs.intRegFile[TheISA::ArgumentReg0 + i] = val; - } + virtual void setSyscallArg(int i, IntReg val) = 0; - void setSyscallReturn(SyscallReturn return_value) - { - // check for error condition. Alpha syscall convention is to - // indicate success/failure in reg a3 (r19) and put the - // return value itself in the standard return value reg (v0). - const int RegA3 = 19; // only place this is used - if (return_value.successful()) { - // no error - regs.intRegFile[RegA3] = 0; - regs.intRegFile[TheISA::ReturnValueReg] = return_value.value(); - } else { - // got an error, return details - regs.intRegFile[RegA3] = (TheISA::IntReg) -1; - regs.intRegFile[TheISA::ReturnValueReg] = -return_value.value(); - } - } + virtual void setSyscallReturn(SyscallReturn return_value) = 0; - void syscall() - { - process->syscall(this); - } + virtual void syscall() = 0; + + virtual Counter readFuncExeInst() = 0; + + virtual void setFuncExeInst(Counter new_val) = 0; #endif }; - -// for non-speculative execution context, spec_mode is always false -inline bool -ExecContext::misspeculating() +template +class ProxyExecContext : public ExecContext { - return false; -} + public: + ProxyExecContext(XC *actual_xc) + { actualXC = actual_xc; } -#endif // __CPU_EXEC_CONTEXT_HH__ + private: + XC *actualXC; + + public: + + BaseCPU *getCpuPtr() { return actualXC->getCpuPtr(); } + + void setCpuId(int id) { actualXC->setCpuId(id); } + + int readCpuId() { return actualXC->readCpuId(); } + + FunctionalMemory *getMemPtr() { return actualXC->getMemPtr(); } + +#if FULL_SYSTEM + System *getSystemPtr() { return actualXC->getSystemPtr(); } + + PhysicalMemory *getPhysMemPtr() { return actualXC->getPhysMemPtr(); } + + AlphaITB *getITBPtr() { return actualXC->getITBPtr(); } + + AlphaDTB *getDTBPtr() { return actualXC->getDTBPtr(); } +#else + Process *getProcessPtr() { return actualXC->getProcessPtr(); } +#endif + + Status status() const { return actualXC->status(); } + + /// Set the status to Active. Optional delay indicates number of + /// cycles to wait before beginning execution. + void activate(int delay = 1) { actualXC->activate(delay); } + + /// Set the status to Suspended. + void suspend() { actualXC->suspend(); } + + /// Set the status to Unallocated. + void deallocate() { actualXC->deallocate(); } + + /// Set the status to Halted. + void halt() { actualXC->halt(); } + +#if FULL_SYSTEM + void dumpFuncProfile() { actualXC->dumpFuncProfile(); } +#endif + + void takeOverFrom(ExecContext *oldContext) + { actualXC->takeOverFrom(oldContext); } + + void regStats(const std::string &name) { actualXC->regStats(name); } + + void serialize(std::ostream &os) { actualXC->serialize(os); } + void unserialize(Checkpoint *cp, const std::string §ion) + { actualXC->unserialize(cp, section); } + + int getThreadNum() { return actualXC->getThreadNum(); } + + bool validInstAddr(Addr addr) { return actualXC->validInstAddr(addr); } + bool validDataAddr(Addr addr) { return actualXC->validDataAddr(addr); } + int getInstAsid() { return actualXC->getInstAsid(); } + int getDataAsid() { return actualXC->getDataAsid(); } + + Fault translateInstReq(MemReqPtr &req) + { return actualXC->translateInstReq(req); } + + Fault translateDataReadReq(MemReqPtr &req) + { return actualXC->translateDataReadReq(req); } + + Fault translateDataWriteReq(MemReqPtr &req) + { return actualXC->translateDataWriteReq(req); } + + // @todo: Do I need this? + MachInst getInst() { return actualXC->getInst(); } + + // @todo: Do I need this? + void copyArchRegs(ExecContext *xc) { actualXC->copyArchRegs(xc); } + + void clearArchRegs() { actualXC->clearArchRegs(); } + + // + // New accessors for new decoder. + // + uint64_t readIntReg(int reg_idx) + { return actualXC->readIntReg(reg_idx); } + + float readFloatRegSingle(int reg_idx) + { return actualXC->readFloatRegSingle(reg_idx); } + + double readFloatRegDouble(int reg_idx) + { return actualXC->readFloatRegDouble(reg_idx); } + + uint64_t readFloatRegInt(int reg_idx) + { return actualXC->readFloatRegInt(reg_idx); } + + void setIntReg(int reg_idx, uint64_t val) + { actualXC->setIntReg(reg_idx, val); } + + void setFloatRegSingle(int reg_idx, float val) + { actualXC->setFloatRegSingle(reg_idx, val); } + + void setFloatRegDouble(int reg_idx, double val) + { actualXC->setFloatRegDouble(reg_idx, val); } + + void setFloatRegInt(int reg_idx, uint64_t val) + { actualXC->setFloatRegInt(reg_idx, val); } + + uint64_t readPC() { return actualXC->readPC(); } + + void setPC(uint64_t val) { actualXC->setPC(val); } + + uint64_t readNextPC() { return actualXC->readNextPC(); } + + void setNextPC(uint64_t val) { actualXC->setNextPC(val); } + + MiscReg readMiscReg(int misc_reg) + { return actualXC->readMiscReg(misc_reg); } + + MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault) + { return actualXC->readMiscRegWithEffect(misc_reg, fault); } + + Fault setMiscReg(int misc_reg, const MiscReg &val) + { return actualXC->setMiscReg(misc_reg, val); } + + Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val) + { return actualXC->setMiscRegWithEffect(misc_reg, val); } + + unsigned readStCondFailures() + { return actualXC->readStCondFailures(); } + + void setStCondFailures(unsigned sc_failures) + { actualXC->setStCondFailures(sc_failures); } + +#if FULL_SYSTEM + int readIntrFlag() { return actualXC->readIntrFlag(); } + + void setIntrFlag(int val) { actualXC->setIntrFlag(val); } + + Fault hwrei() { return actualXC->hwrei(); } + + bool inPalMode() { return actualXC->inPalMode(); } + + void ev5_trap(Fault fault) { actualXC->ev5_trap(fault); } + + bool simPalCheck(int palFunc) { return actualXC->simPalCheck(palFunc); } +#endif + + // @todo: Fix this! + bool misspeculating() { return false; } + + /** Meant to be more generic trap function to be + * called when an instruction faults. + * @param fault The fault generated by executing the instruction. + * @todo How to do this properly so it's dependent upon ISA only? + */ + + void trap(Fault fault) { actualXC->trap(fault); } + +#if !FULL_SYSTEM + IntReg getSyscallArg(int i) { return actualXC->getSyscallArg(i); } + + // used to shift args for indirect syscall + void setSyscallArg(int i, IntReg val) + { actualXC->setSyscallArg(i, val); } + + void setSyscallReturn(SyscallReturn return_value) + { actualXC->setSyscallReturn(return_value); } + + void syscall() { actualXC->syscall(); } + + Counter readFuncExeInst() { return actualXC->readFuncExeInst(); } + + void setFuncExeInst(Counter new_val) + { return actualXC->setFuncExeInst(new_val); } +#endif +}; + +#endif diff --git a/cpu/exetrace.cc b/cpu/exetrace.cc index 8393a1b85..84b5eacf7 100644 --- a/cpu/exetrace.cc +++ b/cpu/exetrace.cc @@ -34,7 +34,6 @@ #include "encumbered/cpu/full/spec_state.hh" #include "encumbered/cpu/full/issue.hh" #include "cpu/exetrace.hh" -#include "cpu/exec_context.hh" #include "base/loader/symtab.hh" #include "cpu/base.hh" #include "cpu/static_inst.hh" diff --git a/cpu/intr_control.cc b/cpu/intr_control.cc index 5f17c7212..d1866a0c4 100644 --- a/cpu/intr_control.cc +++ b/cpu/intr_control.cc @@ -48,7 +48,7 @@ void IntrControl::post(int int_num, int index) { std::vector &xcvec = cpu->system->execContexts; - BaseCPU *temp = xcvec[0]->cpu; + BaseCPU *temp = xcvec[0]->getCpuPtr(); temp->post_interrupt(int_num, index); } @@ -56,7 +56,7 @@ void IntrControl::post(int cpu_id, int int_num, int index) { std::vector &xcvec = cpu->system->execContexts; - BaseCPU *temp = xcvec[cpu_id]->cpu; + BaseCPU *temp = xcvec[cpu_id]->getCpuPtr(); temp->post_interrupt(int_num, index); } @@ -64,7 +64,7 @@ void IntrControl::clear(int int_num, int index) { std::vector &xcvec = cpu->system->execContexts; - BaseCPU *temp = xcvec[0]->cpu; + BaseCPU *temp = xcvec[0]->getCpuPtr(); temp->clear_interrupt(int_num, index); } @@ -72,7 +72,7 @@ void IntrControl::clear(int cpu_id, int int_num, int index) { std::vector &xcvec = cpu->system->execContexts; - BaseCPU *temp = xcvec[cpu_id]->cpu; + BaseCPU *temp = xcvec[cpu_id]->getCpuPtr(); temp->clear_interrupt(int_num, index); } diff --git a/cpu/intr_control.hh b/cpu/intr_control.hh index 2a57a8dfc..5ec4e14cb 100644 --- a/cpu/intr_control.hh +++ b/cpu/intr_control.hh @@ -34,7 +34,6 @@ #include "cpu/base.hh" #include "sim/sim_object.hh" #include "sim/system.hh" -#include "cpu/exec_context.hh" class IntrControl : public SimObject diff --git a/cpu/memtest/memtest.cc b/cpu/memtest/memtest.cc index 5a4024587..94b66b70b 100644 --- a/cpu/memtest/memtest.cc +++ b/cpu/memtest/memtest.cc @@ -36,7 +36,7 @@ #include "base/misc.hh" #include "base/statistics.hh" -#include "cpu/exec_context.hh" +#include "cpu/cpu_exec_context.hh" #include "cpu/memtest/memtest.hh" #include "mem/cache/base_cache.hh" #include "sim/builder.hh" @@ -79,7 +79,7 @@ MemTest::MemTest(const string &name, vector cmd; cmd.push_back("/bin/ls"); vector null_vec; - xc = new ExecContext(NULL, 0, mainMem, 0); + cpuXC = new CPUExecContext(NULL, 0, mainMem, 0); blockSize = cacheInterface->getBlockSize(); blockAddrMask = blockSize - 1; @@ -269,7 +269,7 @@ MemTest::tick() req->data = new uint8_t[req->size]; req->paddr &= ~(req->size - 1); req->time = curTick; - req->xc = xc; + req->xc = cpuXC->getProxy(); if (cmd < percentReads) { // read diff --git a/cpu/memtest/memtest.hh b/cpu/memtest/memtest.hh index 7abcf017a..cdb40a26a 100644 --- a/cpu/memtest/memtest.hh +++ b/cpu/memtest/memtest.hh @@ -83,7 +83,7 @@ class MemTest : public SimObject MemInterface *cacheInterface; FunctionalMemory *mainMem; FunctionalMemory *checkMem; - ExecContext *xc; + CPUExecContext *cpuXC; unsigned size; // size of testing memory region diff --git a/cpu/o3/alpha_cpu.hh b/cpu/o3/alpha_cpu.hh index 47ea532a6..75a4d72c2 100644 --- a/cpu/o3/alpha_cpu.hh +++ b/cpu/o3/alpha_cpu.hh @@ -152,13 +152,13 @@ class AlphaFullCPU : public FullO3CPU // set the register. IntReg getSyscallArg(int i) { - return this->xc->regs.intRegFile[AlphaISA::ArgumentReg0 + i]; + return this->cpuXC->readIntReg(AlphaISA::ArgumentReg0 + i); } // used to shift args for indirect syscall void setSyscallArg(int i, IntReg val) { - this->xc->regs.intRegFile[AlphaISA::ArgumentReg0 + i] = val; + this->cpuXC->setIntReg(AlphaISA::ArgumentReg0 + i, val); } void setSyscallReturn(int64_t return_value) @@ -169,12 +169,12 @@ class AlphaFullCPU : public FullO3CPU const int RegA3 = 19; // only place this is used if (return_value >= 0) { // no error - this->xc->regs.intRegFile[RegA3] = 0; - this->xc->regs.intRegFile[AlphaISA::ReturnValueReg] = return_value; + this->cpuXC->setIntReg(RegA3, 0); + this->cpuXC->setIntReg(AlphaISA::ReturnValueReg, return_value); } else { // got an error, return details - this->xc->regs.intRegFile[RegA3] = (IntReg) -1; - this->xc->regs.intRegFile[AlphaISA::ReturnValueReg] = -return_value; + this->cpuXC->setIntReg(RegA3, (IntReg) -1); + this->cpuXC->setIntReg(AlphaISA::ReturnValueReg, -return_value); } } @@ -208,9 +208,8 @@ class AlphaFullCPU : public FullO3CPU { #if FULL_SYSTEM && defined(TARGET_ALPHA) if (req->flags & LOCKED) { - MiscRegFile *cregs = &req->xc->regs.miscRegs; - cregs->setReg(TheISA::Lock_Addr_DepTag, req->paddr); - cregs->setReg(TheISA::Lock_Flag_DepTag, true); + req->xc->setMiscReg(TheISA::Lock_Addr_DepTag, req->paddr); + req->xc->setMiscReg(TheISA::Lock_Flag_DepTag, true); } #endif @@ -230,34 +229,34 @@ class AlphaFullCPU : public FullO3CPU Fault write(MemReqPtr &req, T &data) { #if FULL_SYSTEM && defined(TARGET_ALPHA) - - MiscRegFile *cregs; + ExecContext *xc; // If this is a store conditional, act appropriately if (req->flags & LOCKED) { - cregs = &req->xc->regs.miscRegs; + xc = req->xc; if (req->flags & UNCACHEABLE) { // Don't update result register (see stq_c in isa_desc) req->result = 2; - req->xc->storeCondFailures = 0;//Needed? [RGD] + xc->setStCondFailures(0);//Needed? [RGD] } else { - bool lock_flag = cregs->readReg(TheISA::Lock_Flag_DepTag); - Addr lock_addr = cregs->readReg(TheISA::Lock_Addr_DepTag); + bool lock_flag = xc->readMiscReg(TheISA::Lock_Flag_DepTag); + Addr lock_addr = xc->readMiscReg(TheISA::Lock_Addr_DepTag); req->result = lock_flag; if (!lock_flag || ((lock_addr & ~0xf) != (req->paddr & ~0xf))) { - cregs->setReg(TheISA::Lock_Flag_DepTag, false); - if (((++req->xc->storeCondFailures) % 100000) == 0) { + xc->setMiscReg(TheISA::Lock_Flag_DepTag, false); + xc->setStCondFailures(xc->readStCondFailures() + 1); + if (((xc->readStCondFailures()) % 100000) == 0) { std::cerr << "Warning: " - << req->xc->storeCondFailures + << xc->readStCondFailures() << " consecutive store conditional failures " - << "on cpu " << req->xc->cpu_id + << "on cpu " << req->xc->readCpuId() << std::endl; } return NoFault; } - else req->xc->storeCondFailures = 0; + else xc->setStCondFailures(0); } } @@ -267,10 +266,10 @@ class AlphaFullCPU : public FullO3CPU // Conditionals would have returned above, and wouldn't fall // through. for (int i = 0; i < this->system->execContexts.size(); i++){ - cregs = &this->system->execContexts[i]->regs.miscRegs; - if ((cregs->readReg(TheISA::Lock_Addr_DepTag) & ~0xf) == + xc = this->system->execContexts[i]; + if ((xc->readMiscReg(TheISA::Lock_Addr_DepTag) & ~0xf) == (req->paddr & ~0xf)) { - cregs->setReg(TheISA::Lock_Flag_DepTag, false); + xc->setMiscReg(TheISA::Lock_Flag_DepTag, false); } } diff --git a/cpu/o3/alpha_cpu_builder.cc b/cpu/o3/alpha_cpu_builder.cc index 3547fb1b5..7e687ad2b 100644 --- a/cpu/o3/alpha_cpu_builder.cc +++ b/cpu/o3/alpha_cpu_builder.cc @@ -30,7 +30,6 @@ #include "base/loader/symtab.hh" #include "base/misc.hh" #include "cpu/base.hh" -#include "cpu/exec_context.hh" #include "cpu/exetrace.hh" #include "cpu/o3/alpha_cpu.hh" #include "cpu/o3/alpha_impl.hh" diff --git a/cpu/o3/alpha_cpu_impl.hh b/cpu/o3/alpha_cpu_impl.hh index bd4e34914..271b542ab 100644 --- a/cpu/o3/alpha_cpu_impl.hh +++ b/cpu/o3/alpha_cpu_impl.hh @@ -165,7 +165,7 @@ AlphaFullCPU::copyToXC() for (int i = 0; i < AlphaISA::NumIntRegs; ++i) { renamed_reg = this->renameMap.lookup(i); - this->xc->regs.intRegFile[i] = this->regFile.readIntReg(renamed_reg); + this->cpuXC->setIntReg(i, this->regFile.readIntReg(renamed_reg)); DPRINTF(FullCPU, "FullCPU: Copying register %i, has data %lli.\n", renamed_reg, this->regFile.intRegFile[renamed_reg]); } @@ -174,21 +174,23 @@ AlphaFullCPU::copyToXC() for (int i = 0; i < AlphaISA::NumFloatRegs; ++i) { renamed_reg = this->renameMap.lookup(i + AlphaISA::FP_Base_DepTag); - this->xc->regs.floatRegFile.d[i] = - this->regFile.readFloatRegDouble(renamed_reg); - this->xc->regs.floatRegFile.q[i] = - this->regFile.readFloatRegInt(renamed_reg); + this->cpuXC->setFloatRegDouble(i, + this->regFile.readFloatRegDouble(renamed_reg)); + this->cpuXC->setFloatRegInt(i, + this->regFile.readFloatRegInt(renamed_reg)); } /* - this->xc->regs.miscRegs.fpcr = this->regFile.miscRegs.fpcr; - this->xc->regs.miscRegs.uniq = this->regFile.miscRegs.uniq; - this->xc->regs.miscRegs.lock_flag = this->regFile.miscRegs.lock_flag; - this->xc->regs.miscRegs.lock_addr = this->regFile.miscRegs.lock_addr; + this->cpuXC->regs.miscRegs.fpcr = this->regFile.miscRegs.fpcr; + this->cpuXC->regs.miscRegs.uniq = this->regFile.miscRegs.uniq; + this->cpuXC->regs.miscRegs.lock_flag = this->regFile.miscRegs.lock_flag; + this->cpuXC->regs.miscRegs.lock_addr = this->regFile.miscRegs.lock_addr; */ - this->xc->regs.pc = this->rob.readHeadPC(); - this->xc->regs.npc = this->xc->regs.pc+4; + this->cpuXC->setPC(this->rob.readHeadPC()); + this->cpuXC->setNextPC(this->cpuXC->readPC()+4); - this->xc->func_exe_inst = this->funcExeInst; +#if !FULL_SYSTEM + this->cpuXC->setFuncExeInst(this->funcExeInst); +#endif } // This function will probably mess things up unless the ROB is empty and @@ -207,9 +209,9 @@ AlphaFullCPU::copyFromXC() DPRINTF(FullCPU, "FullCPU: Copying over register %i, had data %lli, " "now has data %lli.\n", renamed_reg, this->regFile.intRegFile[renamed_reg], - this->xc->regs.intRegFile[i]); + this->cpuXC->readIntReg(i)); - this->regFile.setIntReg(renamed_reg, this->xc->regs.intRegFile[i]); + this->regFile.setIntReg(renamed_reg, this->cpuXC->readIntReg(i)); } // Then loop through the floating point registers. @@ -217,22 +219,23 @@ AlphaFullCPU::copyFromXC() { renamed_reg = this->renameMap.lookup(i + AlphaISA::FP_Base_DepTag); this->regFile.setFloatRegDouble(renamed_reg, - this->xc->regs.floatRegFile.d[i]); + this->cpuXC->readFloatRegDouble(i)); this->regFile.setFloatRegInt(renamed_reg, - this->xc->regs.floatRegFile.q[i]); + this->cpuXC->readFloatRegInt(i)); } /* // Then loop through the misc registers. - this->regFile.miscRegs.fpcr = this->xc->regs.miscRegs.fpcr; - this->regFile.miscRegs.uniq = this->xc->regs.miscRegs.uniq; - this->regFile.miscRegs.lock_flag = this->xc->regs.miscRegs.lock_flag; - this->regFile.miscRegs.lock_addr = this->xc->regs.miscRegs.lock_addr; + this->regFile.miscRegs.fpcr = this->cpuXC->regs.miscRegs.fpcr; + this->regFile.miscRegs.uniq = this->cpuXC->regs.miscRegs.uniq; + this->regFile.miscRegs.lock_flag = this->cpuXC->regs.miscRegs.lock_flag; + this->regFile.miscRegs.lock_addr = this->cpuXC->regs.miscRegs.lock_addr; */ // Then finally set the PC and the next PC. -// regFile.pc = xc->regs.pc; -// regFile.npc = xc->regs.npc; - - this->funcExeInst = this->xc->func_exe_inst; +// regFile.pc = cpuXC->regs.pc; +// regFile.npc = cpuXC->regs.npc; +#if !FULL_SYSTEM + this->funcExeInst = this->cpuXC->readFuncExeInst(); +#endif } #if FULL_SYSTEM diff --git a/cpu/o3/cpu.cc b/cpu/o3/cpu.cc index a8c620028..62d68bb33 100644 --- a/cpu/o3/cpu.cc +++ b/cpu/o3/cpu.cc @@ -35,10 +35,11 @@ #endif #include "sim/root.hh" +#include "cpu/cpu_exec_context.hh" +#include "cpu/exec_context.hh" #include "cpu/o3/alpha_dyn_inst.hh" #include "cpu/o3/alpha_impl.hh" #include "cpu/o3/cpu.hh" -#include "cpu/exec_context.hh" using namespace std; @@ -103,7 +104,7 @@ FullO3CPU::FullO3CPU(Params ¶ms) renameQueue(5, 5), iewQueue(5, 5), - xc(NULL), + cpuXC(NULL), globalSeqNum(1), @@ -134,8 +135,8 @@ FullO3CPU::FullO3CPU(Params ¶ms) for (int i = 0; i < this->number_of_threads; ++i) { #if FULL_SYSTEM assert(i == 0); - system->execContexts[i] = - new ExecContext(this, i, system, itb, dtb, mem); + thread[i] = new CPUExecContext(this, 0, system, itb, dtb, mem); + system->execContexts[i] = thread[i]->getProxy(); execContexts.push_back(system->execContexts[i]); #else @@ -143,21 +144,17 @@ FullO3CPU::FullO3CPU(Params ¶ms) DPRINTF(FullCPU, "FullCPU: Workload[%i]'s starting PC is %#x, " "process is %#x", i, params.workload[i]->prog_entry, thread[i]); - thread[i] = new ExecContext(this, i, params.workload[i], i); + thread[i] = new CPUExecContext(this, i, params.workload[i], i); } assert(params.workload[i]->getMemory() != NULL); assert(mem != NULL); - execContexts.push_back(thread[i]); + execContexts.push_back(thread[i]->getProxy()); #endif // !FULL_SYSTEM } // Note that this is a hack so that my code which still uses xc-> will // still work. I should remove this eventually -#if FULL_SYSTEM - xc = system->execContexts[0]; -#else - xc = thread[0]; -#endif + cpuXC = thread[0]; // The stages also need their CPU pointer setup. However this must be // done at the upper level CPU because they have pointers to the upper @@ -248,21 +245,21 @@ FullO3CPU::init() // that it can start properly. #if FULL_SYSTEM ExecContext *src_xc = system->execContexts[0]; - TheISA::initCPU(&src_xc->regs, src_xc->cpu_id); + TheISA::initCPU(src_xc, src_xc->readCpuId()); #else - ExecContext *src_xc = thread[0]; + ExecContext *src_xc = thread[0]->getProxy(); #endif // First loop through the integer registers. for (int i = 0; i < TheISA::NumIntRegs; ++i) { - regFile.intRegFile[i] = src_xc->regs.intRegFile[i]; + regFile.intRegFile[i] = src_xc->readIntReg(i); } // Then loop through the floating point registers. for (int i = 0; i < TheISA::NumFloatRegs; ++i) { - regFile.floatRegFile[i].d = src_xc->regs.floatRegFile.d[i]; - regFile.floatRegFile[i].q = src_xc->regs.floatRegFile.q[i]; + regFile.floatRegFile[i].d = src_xc->readFloatRegDouble(i); + regFile.floatRegFile[i].q = src_xc->readFloatRegInt(i); } /* // Then loop through the misc registers. @@ -272,8 +269,8 @@ FullO3CPU::init() regFile.miscRegs.lock_addr = src_xc->regs.miscRegs.lock_addr; */ // Then finally set the PC and the next PC. - regFile.pc = src_xc->regs.pc; - regFile.npc = src_xc->regs.npc; + regFile.pc = src_xc->readPC(); + regFile.npc = src_xc->readNextPC(); } } diff --git a/cpu/o3/cpu.hh b/cpu/o3/cpu.hh index 09d9c3d66..45e21db7f 100644 --- a/cpu/o3/cpu.hh +++ b/cpu/o3/cpu.hh @@ -44,9 +44,9 @@ #include "base/timebuf.hh" #include "config/full_system.hh" #include "cpu/base.hh" +#include "cpu/cpu_exec_context.hh" #include "cpu/o3/comm.hh" #include "cpu/o3/cpu_policy.hh" -#include "cpu/exec_context.hh" #include "sim/process.hh" #if FULL_SYSTEM @@ -54,6 +54,7 @@ using namespace EV5; #endif +class ExecContext; class FunctionalMemory; class Process; @@ -164,8 +165,8 @@ class FullO3CPU : public BaseFullCPU bool validDataAddr(Addr addr) { return thread[0]->validDataAddr(addr); } - int getInstAsid() { return thread[0]->asid; } - int getDataAsid() { return thread[0]->asid; } + int getInstAsid() { return thread[0]->getInstAsid(); } + int getDataAsid() { return thread[0]->getDataAsid(); } #endif @@ -320,16 +321,17 @@ class FullO3CPU : public BaseFullCPU public: /** The temporary exec context to support older accessors. */ - ExecContext *xc; + CPUExecContext *cpuXC; /** Temporary function to get pointer to exec context. */ ExecContext *xcBase() { -#if FULL_SYSTEM - return system->execContexts[0]; -#else + return thread[0]->getProxy(); + } + + CPUExecContext *cpuXCBase() + { return thread[0]; -#endif } InstSeqNum globalSeqNum; @@ -344,9 +346,8 @@ class FullO3CPU : public BaseFullCPU AlphaDTB *dtb; // SWContext *swCtx; -#else - std::vector thread; #endif + std::vector thread; FunctionalMemory *mem; diff --git a/cpu/pc_event.cc b/cpu/pc_event.cc index 83fbc3e2d..050bf1a88 100644 --- a/cpu/pc_event.cc +++ b/cpu/pc_event.cc @@ -38,6 +38,7 @@ #include "cpu/pc_event.hh" #include "sim/debug.hh" #include "sim/root.hh" +#include "sim/system.hh" using namespace std; @@ -79,7 +80,7 @@ PCEventQueue::schedule(PCEvent *event) bool PCEventQueue::doService(ExecContext *xc) { - Addr pc = xc->regs.pc & ~0x3; + Addr pc = xc->readPC() & ~0x3; int serviced = 0; range_t range = equal_range(pc); for (iterator i = range.first; i != range.second; ++i) { @@ -87,7 +88,7 @@ PCEventQueue::doService(ExecContext *xc) // another event. This for example, prevents two invocations // of the SkipFuncEvent. Maybe we should have separate PC // event queues for each processor? - if (pc != (xc->regs.pc & ~0x3)) + if (pc != (xc->readPC() & ~0x3)) continue; DPRINTF(PCEvent, "PC based event serviced at %#x: %s\n", @@ -126,7 +127,7 @@ BreakPCEvent::BreakPCEvent(PCEventQueue *q, const std::string &desc, Addr addr, void BreakPCEvent::process(ExecContext *xc) { - StringWrap name(xc->cpu->name() + ".break_event"); + StringWrap name(xc->getCpuPtr()->name() + ".break_event"); DPRINTFN("break event %s triggered\n", descr()); debug_break(); if (remove) diff --git a/cpu/simple/cpu.cc b/cpu/simple/cpu.cc index dd2d53c17..7c60b242f 100644 --- a/cpu/simple/cpu.cc +++ b/cpu/simple/cpu.cc @@ -44,6 +44,7 @@ #include "base/stats/events.hh" #include "base/trace.hh" #include "cpu/base.hh" +#include "cpu/cpu_exec_context.hh" #include "cpu/exec_context.hh" #include "cpu/exetrace.hh" #include "cpu/profile.hh" @@ -94,7 +95,7 @@ SimpleCPU::init() ExecContext *xc = execContexts[i]; // initialize CPU, including PC - TheISA::initCPU(&xc->regs, xc->cpu_id); + TheISA::initCPU(xc, xc->readCpuId()); } #endif } @@ -132,22 +133,24 @@ SimpleCPU::CacheCompletionEvent::description() } SimpleCPU::SimpleCPU(Params *p) - : BaseCPU(p), tickEvent(this, p->width), xc(NULL), + : BaseCPU(p), tickEvent(this, p->width), cpuXC(NULL), cacheCompletionEvent(this) { _status = Idle; #if FULL_SYSTEM - xc = new ExecContext(this, 0, p->system, p->itb, p->dtb, p->mem); + cpuXC = new CPUExecContext(this, 0, p->system, p->itb, p->dtb, p->mem); #else - xc = new ExecContext(this, /* thread_num */ 0, p->process, /* asid */ 0); + cpuXC = new CPUExecContext(this, /* thread_num */ 0, p->process, + /* asid */ 0); #endif // !FULL_SYSTEM + xcProxy = cpuXC->getProxy(); icacheInterface = p->icache_interface; dcacheInterface = p->dcache_interface; memReq = new MemReq(); - memReq->xc = xc; + memReq->xc = xcProxy; memReq->asid = 0; memReq->data = new uint8_t[64]; @@ -158,7 +161,7 @@ SimpleCPU::SimpleCPU(Params *p) lastIcacheStall = 0; lastDcacheStall = 0; - execContexts.push_back(xc); + execContexts.push_back(xcProxy); } SimpleCPU::~SimpleCPU() @@ -207,7 +210,7 @@ void SimpleCPU::activateContext(int thread_num, int delay) { assert(thread_num == 0); - assert(xc); + assert(cpuXC); assert(_status == Idle); notIdleFraction++; @@ -220,7 +223,7 @@ void SimpleCPU::suspendContext(int thread_num) { assert(thread_num == 0); - assert(xc); + assert(cpuXC); assert(_status == Running); notIdleFraction--; @@ -301,7 +304,7 @@ SimpleCPU::serialize(ostream &os) SERIALIZE_ENUM(_status); SERIALIZE_SCALAR(inst); nameOut(os, csprintf("%s.xc", name())); - xc->serialize(os); + cpuXC->serialize(os); nameOut(os, csprintf("%s.tickEvent", name())); tickEvent.serialize(os); nameOut(os, csprintf("%s.cacheCompletionEvent", name())); @@ -314,7 +317,7 @@ SimpleCPU::unserialize(Checkpoint *cp, const string §ion) BaseCPU::unserialize(cp, section); UNSERIALIZE_ENUM(_status); UNSERIALIZE_SCALAR(inst); - xc->unserialize(cp, csprintf("%s.xc", section)); + cpuXC->unserialize(cp, csprintf("%s.xc", section)); tickEvent.unserialize(cp, csprintf("%s.tickEvent", section)); cacheCompletionEvent .unserialize(cp, csprintf("%s.cacheCompletionEvent", section)); @@ -345,16 +348,16 @@ SimpleCPU::copySrcTranslate(Addr src) memReq->reset(src & ~(blk_size - 1), blk_size); // translate to physical address - Fault fault = xc->translateDataReadReq(memReq); + Fault fault = cpuXC->translateDataReadReq(memReq); assert(fault != AlignmentFault); if (fault == NoFault) { - xc->copySrcAddr = src; - xc->copySrcPhysAddr = memReq->paddr + offset; + cpuXC->copySrcAddr = src; + cpuXC->copySrcPhysAddr = memReq->paddr + offset; } else { - xc->copySrcAddr = 0; - xc->copySrcPhysAddr = 0; + cpuXC->copySrcAddr = 0; + cpuXC->copySrcPhysAddr = 0; } return fault; } @@ -367,7 +370,7 @@ SimpleCPU::copy(Addr dest) // Only support block sizes of 64 atm. assert(blk_size == 64); uint8_t data[blk_size]; - //assert(xc->copySrcAddr); + //assert(cpuXC->copySrcAddr); int offset = dest & (blk_size - 1); // Make sure block doesn't span page @@ -380,21 +383,21 @@ SimpleCPU::copy(Addr dest) memReq->reset(dest & ~(blk_size -1), blk_size); // translate to physical address - Fault fault = xc->translateDataWriteReq(memReq); + Fault fault = cpuXC->translateDataWriteReq(memReq); assert(fault != AlignmentFault); if (fault == NoFault) { Addr dest_addr = memReq->paddr + offset; // Need to read straight from memory since we have more than 8 bytes. - memReq->paddr = xc->copySrcPhysAddr; - xc->mem->read(memReq, data); + memReq->paddr = cpuXC->copySrcPhysAddr; + cpuXC->mem->read(memReq, data); memReq->paddr = dest_addr; - xc->mem->write(memReq, data); + cpuXC->mem->write(memReq, data); if (dcacheInterface) { memReq->cmd = Copy; memReq->completionEvent = NULL; - memReq->paddr = xc->copySrcPhysAddr; + memReq->paddr = cpuXC->copySrcPhysAddr; memReq->dest = dest_addr; memReq->size = 64; memReq->time = curTick; @@ -411,7 +414,7 @@ Fault SimpleCPU::read(Addr addr, T &data, unsigned flags) { if (status() == DcacheMissStall || status() == DcacheMissSwitch) { - Fault fault = xc->read(memReq,data); + Fault fault = cpuXC->read(memReq,data); if (traceData) { traceData->setAddr(addr); @@ -422,7 +425,7 @@ SimpleCPU::read(Addr addr, T &data, unsigned flags) memReq->reset(addr, sizeof(T), flags); // translate to physical address - Fault fault = xc->translateDataReadReq(memReq); + Fault fault = cpuXC->translateDataReadReq(memReq); // if we have a cache, do cache access too if (fault == NoFault && dcacheInterface) { @@ -442,12 +445,12 @@ SimpleCPU::read(Addr addr, T &data, unsigned flags) _status = DcacheMissStall; } else { // do functional access - fault = xc->read(memReq, data); + fault = cpuXC->read(memReq, data); } } else if(fault == NoFault) { // do functional access - fault = xc->read(memReq, data); + fault = cpuXC->read(memReq, data); } @@ -507,11 +510,11 @@ SimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res) memReq->reset(addr, sizeof(T), flags); // translate to physical address - Fault fault = xc->translateDataWriteReq(memReq); + Fault fault = cpuXC->translateDataWriteReq(memReq); // do functional access if (fault == NoFault) - fault = xc->write(memReq, data); + fault = cpuXC->write(memReq, data); if (fault == NoFault && dcacheInterface) { memReq->cmd = Write; @@ -588,7 +591,7 @@ SimpleCPU::write(int32_t data, Addr addr, unsigned flags, uint64_t *res) Addr SimpleCPU::dbg_vtophys(Addr addr) { - return vtophys(xc, addr); + return vtophys(xcProxy, addr); } #endif // FULL_SYSTEM @@ -636,9 +639,9 @@ SimpleCPU::post_interrupt(int int_num, int index) { BaseCPU::post_interrupt(int_num, index); - if (xc->status() == ExecContext::Suspended) { + if (cpuXC->status() == ExecContext::Suspended) { DPRINTF(IPI,"Suspended Processor awoke\n"); - xc->activate(); + cpuXC->activate(); } } #endif // FULL_SYSTEM @@ -654,16 +657,16 @@ SimpleCPU::tick() Fault fault = NoFault; #if FULL_SYSTEM - if (checkInterrupts && check_interrupts() && !xc->inPalMode() && + if (checkInterrupts && check_interrupts() && !cpuXC->inPalMode() && status() != IcacheMissComplete) { int ipl = 0; int summary = 0; checkInterrupts = false; - if (xc->readMiscReg(IPR_SIRR)) { + if (cpuXC->readMiscReg(IPR_SIRR)) { for (int i = INTLEVEL_SOFTWARE_MIN; i < INTLEVEL_SOFTWARE_MAX; i++) { - if (xc->readMiscReg(IPR_SIRR) & (ULL(1) << i)) { + if (cpuXC->readMiscReg(IPR_SIRR) & (ULL(1) << i)) { // See table 4-19 of 21164 hardware reference ipl = (i - INTLEVEL_SOFTWARE_MIN) + 1; summary |= (ULL(1) << i); @@ -671,7 +674,7 @@ SimpleCPU::tick() } } - uint64_t interrupts = xc->cpu->intr_status(); + uint64_t interrupts = cpuXC->cpu->intr_status(); for (int i = INTLEVEL_EXTERNAL_MIN; i < INTLEVEL_EXTERNAL_MAX; i++) { if (interrupts & (ULL(1) << i)) { @@ -681,24 +684,24 @@ SimpleCPU::tick() } } - if (xc->readMiscReg(IPR_ASTRR)) + if (cpuXC->readMiscReg(IPR_ASTRR)) panic("asynchronous traps not implemented\n"); - if (ipl && ipl > xc->readMiscReg(IPR_IPLR)) { - xc->setMiscReg(IPR_ISR, summary); - xc->setMiscReg(IPR_INTID, ipl); - xc->ev5_trap(InterruptFault); + if (ipl && ipl > cpuXC->readMiscReg(IPR_IPLR)) { + cpuXC->setMiscReg(IPR_ISR, summary); + cpuXC->setMiscReg(IPR_INTID, ipl); + cpuXC->ev5_trap(InterruptFault); DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n", - xc->readMiscReg(IPR_IPLR), ipl, summary); + cpuXC->readMiscReg(IPR_IPLR), ipl, summary); } } #endif // maintain $r0 semantics - xc->regs.intRegFile[ZeroReg] = 0; + cpuXC->setIntReg(ZeroReg, 0); #ifdef TARGET_ALPHA - xc->regs.floatRegFile.d[ZeroReg] = 0.0; + cpuXC->setFloatRegDouble(ZeroReg, 0.0); #endif // TARGET_ALPHA if (status() == IcacheMissComplete) { @@ -720,13 +723,13 @@ SimpleCPU::tick() #endif memReq->cmd = Read; - memReq->reset(xc->regs.pc & ~3, sizeof(uint32_t), - IFETCH_FLAGS(xc->regs.pc)); + memReq->reset(cpuXC->readPC() & ~3, sizeof(uint32_t), + IFETCH_FLAGS(cpuXC->readPC())); - fault = xc->translateInstReq(memReq); + fault = cpuXC->translateInstReq(memReq); if (fault == NoFault) - fault = xc->mem->read(memReq, inst); + fault = cpuXC->mem->read(memReq, inst); if (icacheInterface && fault == NoFault) { memReq->completionEvent = NULL; @@ -763,29 +766,30 @@ SimpleCPU::tick() inst = gtoh(inst); curStaticInst = StaticInst::decode(inst); - traceData = Trace::getInstRecord(curTick, xc, this, curStaticInst, - xc->regs.pc); + traceData = Trace::getInstRecord(curTick, xcProxy, this, curStaticInst, + cpuXC->readPC()); #if FULL_SYSTEM - xc->setInst(inst); + cpuXC->setInst(inst); #endif // FULL_SYSTEM - xc->func_exe_inst++; + cpuXC->func_exe_inst++; fault = curStaticInst->execute(this, traceData); #if FULL_SYSTEM - if (xc->fnbin) { - assert(xc->kernelStats); - system->kernelBinning->execute(xc, inst); + if (system->kernelBinning->fnbin) { + assert(kernelStats); + system->kernelBinning->execute(xcProxy, inst); } - if (xc->profile) { - bool usermode = (xc->readMiscReg(AlphaISA::IPR_DTB_CM) & 0x18) != 0; - xc->profilePC = usermode ? 1 : xc->regs.pc; - ProfileNode *node = xc->profile->consume(xc, inst); + if (cpuXC->profile) { + bool usermode = + (cpuXC->readMiscReg(AlphaISA::IPR_DTB_CM) & 0x18) != 0; + cpuXC->profilePC = usermode ? 1 : cpuXC->readPC(); + ProfileNode *node = cpuXC->profile->consume(xcProxy, inst); if (node) - xc->profileNode = node; + cpuXC->profileNode = node; } #endif @@ -805,29 +809,29 @@ SimpleCPU::tick() traceData->finalize(); } - traceFunctions(xc->regs.pc); + traceFunctions(cpuXC->readPC()); } // if (fault == NoFault) if (fault != NoFault) { #if FULL_SYSTEM - xc->ev5_trap(fault); + cpuXC->ev5_trap(fault); #else // !FULL_SYSTEM - fatal("fault (%d) detected @ PC 0x%08p", fault, xc->regs.pc); + fatal("fault (%d) detected @ PC 0x%08p", fault, cpuXC->readPC()); #endif // FULL_SYSTEM } else { // go to the next instruction - xc->regs.pc = xc->regs.npc; - xc->regs.npc += sizeof(MachInst); + cpuXC->setPC(cpuXC->readNextPC()); + cpuXC->setNextPC(cpuXC->readNextPC() + sizeof(MachInst)); } #if FULL_SYSTEM Addr oldpc; do { - oldpc = xc->regs.pc; - system->pcEventQueue.service(xc); - } while (oldpc != xc->regs.pc); + oldpc = cpuXC->readPC(); + system->pcEventQueue.service(xcProxy); + } while (oldpc != cpuXC->readPC()); #endif assert(status() == Running || diff --git a/cpu/simple/cpu.hh b/cpu/simple/cpu.hh index 3bc905be1..1441a8fcd 100644 --- a/cpu/simple/cpu.hh +++ b/cpu/simple/cpu.hh @@ -32,7 +32,7 @@ #include "base/statistics.hh" #include "config/full_system.hh" #include "cpu/base.hh" -#include "cpu/exec_context.hh" +#include "cpu/cpu_exec_context.hh" #include "cpu/pc_event.hh" #include "cpu/sampler/sampler.hh" #include "cpu/static_inst.hh" @@ -54,6 +54,7 @@ class Process; #endif // FULL_SYSTEM +class ExecContext; class MemInterface; class Checkpoint; @@ -148,7 +149,9 @@ class SimpleCPU : public BaseCPU public: // execution context - ExecContext *xc; + CPUExecContext *cpuXC; + + ExecContext *xcProxy; void switchOut(Sampler *s); void takeOverFrom(BaseCPU *oldCPU); @@ -275,86 +278,86 @@ class SimpleCPU : public BaseCPU uint64_t readIntReg(const StaticInst *si, int idx) { - return xc->readIntReg(si->srcRegIdx(idx)); + return cpuXC->readIntReg(si->srcRegIdx(idx)); } float readFloatRegSingle(const StaticInst *si, int idx) { int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; - return xc->readFloatRegSingle(reg_idx); + return cpuXC->readFloatRegSingle(reg_idx); } double readFloatRegDouble(const StaticInst *si, int idx) { int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; - return xc->readFloatRegDouble(reg_idx); + return cpuXC->readFloatRegDouble(reg_idx); } uint64_t readFloatRegInt(const StaticInst *si, int idx) { int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; - return xc->readFloatRegInt(reg_idx); + return cpuXC->readFloatRegInt(reg_idx); } void setIntReg(const StaticInst *si, int idx, uint64_t val) { - xc->setIntReg(si->destRegIdx(idx), val); + cpuXC->setIntReg(si->destRegIdx(idx), val); } void setFloatRegSingle(const StaticInst *si, int idx, float val) { int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; - xc->setFloatRegSingle(reg_idx, val); + cpuXC->setFloatRegSingle(reg_idx, val); } void setFloatRegDouble(const StaticInst *si, int idx, double val) { int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; - xc->setFloatRegDouble(reg_idx, val); + cpuXC->setFloatRegDouble(reg_idx, val); } void setFloatRegInt(const StaticInst *si, int idx, uint64_t val) { int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; - xc->setFloatRegInt(reg_idx, val); + cpuXC->setFloatRegInt(reg_idx, val); } - uint64_t readPC() { return xc->readPC(); } - void setNextPC(uint64_t val) { xc->setNextPC(val); } + uint64_t readPC() { return cpuXC->readPC(); } + void setNextPC(uint64_t val) { cpuXC->setNextPC(val); } MiscReg readMiscReg(int misc_reg) { - return xc->readMiscReg(misc_reg); + return cpuXC->readMiscReg(misc_reg); } MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault) { - return xc->readMiscRegWithEffect(misc_reg, fault); + return cpuXC->readMiscRegWithEffect(misc_reg, fault); } Fault setMiscReg(int misc_reg, const MiscReg &val) { - return xc->setMiscReg(misc_reg, val); + return cpuXC->setMiscReg(misc_reg, val); } Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val) { - return xc->setMiscRegWithEffect(misc_reg, val); + return cpuXC->setMiscRegWithEffect(misc_reg, val); } #if FULL_SYSTEM - Fault hwrei() { return xc->hwrei(); } - int readIntrFlag() { return xc->readIntrFlag(); } - void setIntrFlag(int val) { xc->setIntrFlag(val); } - bool inPalMode() { return xc->inPalMode(); } - void ev5_trap(Fault fault) { xc->ev5_trap(fault); } - bool simPalCheck(int palFunc) { return xc->simPalCheck(palFunc); } + Fault hwrei() { return cpuXC->hwrei(); } + int readIntrFlag() { return cpuXC->readIntrFlag(); } + void setIntrFlag(int val) { cpuXC->setIntrFlag(val); } + bool inPalMode() { return cpuXC->inPalMode(); } + void ev5_trap(Fault fault) { cpuXC->ev5_trap(fault); } + bool simPalCheck(int palFunc) { return cpuXC->simPalCheck(palFunc); } #else - void syscall() { xc->syscall(); } + void syscall() { cpuXC->syscall(); } #endif - bool misspeculating() { return xc->misspeculating(); } - ExecContext *xcBase() { return xc; } + bool misspeculating() { return cpuXC->misspeculating(); } + ExecContext *xcBase() { return xcProxy; } }; #endif // __CPU_SIMPLE_CPU_SIMPLE_CPU_HH__ diff --git a/dev/tsunami_cchip.cc b/dev/tsunami_cchip.cc index 4dc4413a1..d311df4f5 100644 --- a/dev/tsunami_cchip.cc +++ b/dev/tsunami_cchip.cc @@ -113,7 +113,7 @@ TsunamiCChip::read(MemReqPtr &req, uint8_t *data) case TSDEV_CC_MISC: *(uint64_t*)data = (ipint << 8) & 0xF | (itint << 4) & 0xF | - (xc->cpu_id & 0x3); + (xc->readCpuId() & 0x3); return NoFault; case TSDEV_CC_AAR0: case TSDEV_CC_AAR1: diff --git a/kern/freebsd/freebsd_system.cc b/kern/freebsd/freebsd_system.cc index cead8caaf..3db70a368 100644 --- a/kern/freebsd/freebsd_system.cc +++ b/kern/freebsd/freebsd_system.cc @@ -33,13 +33,13 @@ * */ +#include "arch/isa_traits.hh" #include "base/loader/symtab.hh" #include "cpu/exec_context.hh" #include "kern/freebsd/freebsd_system.hh" #include "mem/functional/memory_control.hh" #include "mem/functional/physical.hh" #include "sim/builder.hh" -#include "arch/isa_traits.hh" #include "sim/byteswap.hh" #include "targetarch/vtophys.hh" @@ -76,8 +76,8 @@ FreebsdSystem::doCalibrateClocks(ExecContext *xc) Addr ppc_paddr = 0; Addr timer_paddr = 0; - ppc_vaddr = (Addr)xc->regs.intRegFile[ArgumentReg1]; - timer_vaddr = (Addr)xc->regs.intRegFile[ArgumentReg2]; + ppc_vaddr = (Addr)xc->readIntReg(ArgumentReg1); + timer_vaddr = (Addr)xc->readIntReg(ArgumentReg2); ppc_paddr = vtophys(physmem, ppc_vaddr); timer_paddr = vtophys(physmem, timer_vaddr); @@ -94,7 +94,7 @@ void FreebsdSystem::SkipCalibrateClocksEvent::process(ExecContext *xc) { SkipFuncEvent::process(xc); - ((FreebsdSystem *)xc->system)->doCalibrateClocks(xc); + ((FreebsdSystem *)xc->getSystemPtr())->doCalibrateClocks(xc); } diff --git a/kern/kernel_stats.cc b/kern/kernel_stats.cc index 3beeaa14a..ddf1058e6 100644 --- a/kern/kernel_stats.cc +++ b/kern/kernel_stats.cc @@ -43,11 +43,11 @@ namespace Kernel { const char *modestr[] = { "kernel", "user", "idle", "interrupt" }; -Statistics::Statistics(ExecContext *context) - : xc(context), idleProcess((Addr)-1), themode(kernel), lastModeTick(0), +Statistics::Statistics(System *system) + : idleProcess((Addr)-1), themode(kernel), lastModeTick(0), iplLast(0), iplLastTick(0) { - bin_int = xc->system->params->bin_int; + bin_int = system->params->bin_int; } void @@ -193,16 +193,16 @@ Statistics::regStats(const string &_name) } void -Statistics::setIdleProcess(Addr idlepcbb) +Statistics::setIdleProcess(Addr idlepcbb, ExecContext *xc) { assert(themode == kernel || themode == interrupt); idleProcess = idlepcbb; themode = idle; - changeMode(themode); + changeMode(themode, xc); } void -Statistics::changeMode(cpu_mode newmode) +Statistics::changeMode(cpu_mode newmode, ExecContext *xc) { _mode[newmode]++; @@ -215,7 +215,7 @@ Statistics::changeMode(cpu_mode newmode) _modeGood[newmode]++; _modeTicks[themode] += curTick - lastModeTick; - xc->system->kernelBinning->changeMode(newmode); + xc->getSystemPtr()->kernelBinning->changeMode(newmode); lastModeTick = curTick; themode = newmode; @@ -238,7 +238,7 @@ Statistics::swpipl(int ipl) } void -Statistics::mode(cpu_mode newmode) +Statistics::mode(cpu_mode newmode, ExecContext *xc) { Addr pcbb = xc->readMiscReg(AlphaISA::IPR_PALtemp23); @@ -249,20 +249,20 @@ Statistics::mode(cpu_mode newmode) if (bin_int == false && newmode == interrupt) newmode = kernel; - changeMode(newmode); + changeMode(newmode, xc); } void -Statistics::context(Addr oldpcbb, Addr newpcbb) +Statistics::context(Addr oldpcbb, Addr newpcbb, ExecContext *xc) { assert(themode != user); _swap_context++; - changeMode(newpcbb == idleProcess ? idle : kernel); + changeMode(newpcbb == idleProcess ? idle : kernel, xc); } void -Statistics::callpal(int code) +Statistics::callpal(int code, ExecContext *xc) { if (!PAL::name(code)) return; @@ -271,7 +271,7 @@ Statistics::callpal(int code) switch (code) { case PAL::callsys: { - int number = xc->regs.intRegFile[0]; + int number = xc->readIntReg(0); if (SystemCalls::validSyscallNumber(number)) { int cvtnum = SystemCalls::convert(number); _syscall[cvtnum]++; @@ -279,8 +279,8 @@ Statistics::callpal(int code) } break; case PAL::swpctx: - if (xc->system->kernelBinning) - xc->system->kernelBinning->palSwapContext(xc); + if (xc->getSystemPtr()->kernelBinning) + xc->getSystemPtr()->kernelBinning->palSwapContext(xc); break; } } diff --git a/kern/kernel_stats.hh b/kern/kernel_stats.hh index 02d78e4d9..6689dad01 100644 --- a/kern/kernel_stats.hh +++ b/kern/kernel_stats.hh @@ -128,14 +128,13 @@ class Statistics : public Serializable private: std::string myname; - ExecContext *xc; Addr idleProcess; cpu_mode themode; Tick lastModeTick; bool bin_int; - void changeMode(cpu_mode newmode); + void changeMode(cpu_mode newmode, ExecContext *xc); private: Stats::Scalar<> _arm; @@ -165,7 +164,7 @@ class Statistics : public Serializable Tick iplLastTick; public: - Statistics(ExecContext *context); + Statistics(System *system); const std::string name() const { return myname; } void regStats(const std::string &name); @@ -184,11 +183,11 @@ class Statistics : public Serializable else _faults[fault->id]++; }// FIXME: When there are no generic system fault objects, this will go back to _faults[fault]++; } void swpipl(int ipl); - void mode(cpu_mode newmode); - void context(Addr oldpcbb, Addr newpcbb); - void callpal(int code); + void mode(cpu_mode newmode, ExecContext *xc); + void context(Addr oldpcbb, Addr newpcbb, ExecContext *xc); + void callpal(int code, ExecContext *xc); - void setIdleProcess(Addr idle); + void setIdleProcess(Addr idle, ExecContext *xc); public: virtual void serialize(std::ostream &os); diff --git a/kern/linux/linux_system.cc b/kern/linux/linux_system.cc index c5a9e184a..a0da732f0 100644 --- a/kern/linux/linux_system.cc +++ b/kern/linux/linux_system.cc @@ -192,7 +192,7 @@ LinuxSystem::setDelayLoop(ExecContext *xc) uint8_t *loops_per_jiffy = physmem->dma_addr(paddr, sizeof(uint32_t)); - Tick cpuFreq = xc->cpu->frequency(); + Tick cpuFreq = xc->getCpuPtr()->frequency(); Tick intrFreq = platform->intrFrequency(); *(uint32_t *)loops_per_jiffy = (uint32_t)((cpuFreq / intrFreq) * 0.9988); @@ -204,7 +204,7 @@ LinuxSystem::SkipDelayLoopEvent::process(ExecContext *xc) { SkipFuncEvent::process(xc); // calculate and set loops_per_jiffy - ((LinuxSystem *)xc->system)->setDelayLoop(xc); + ((LinuxSystem *)xc->getSystemPtr())->setDelayLoop(xc); } void @@ -212,7 +212,7 @@ LinuxSystem::DebugPrintkEvent::process(ExecContext *xc) { if (DTRACE(DebugPrintf)) { if (!raw) { - StringWrap name(xc->system->name() + ".dprintk"); + StringWrap name(xc->getSystemPtr()->name() + ".dprintk"); DPRINTFN(""); } diff --git a/kern/linux/linux_threadinfo.hh b/kern/linux/linux_threadinfo.hh index a1c378d6a..f2fb10483 100644 --- a/kern/linux/linux_threadinfo.hh +++ b/kern/linux/linux_threadinfo.hh @@ -53,7 +53,7 @@ class ThreadInfo * thread_info struct. So we can get the address by masking off * the lower 14 bits. */ - current = xc->regs.intRegFile[TheISA::StackPointerReg] & ~0x3fff; + current = xc->readIntReg(TheISA::StackPointerReg) & ~0x3fff; return VPtr(xc, current); } diff --git a/kern/system_events.cc b/kern/system_events.cc index 91625e60a..9b9861497 100644 --- a/kern/system_events.cc +++ b/kern/system_events.cc @@ -34,17 +34,17 @@ using namespace TheISA; void SkipFuncEvent::process(ExecContext *xc) { - Addr newpc = xc->regs.intRegFile[ReturnAddressReg]; + Addr newpc = xc->readIntReg(ReturnAddressReg); DPRINTF(PCEvent, "skipping %s: pc=%x, newpc=%x\n", description, - xc->regs.pc, newpc); + xc->readPC(), newpc); - xc->regs.pc = newpc; - xc->regs.npc = xc->regs.pc + sizeof(MachInst); + xc->setPC(newpc); + xc->setNextPC(xc->readPC() + sizeof(TheISA::MachInst)); - BranchPred *bp = xc->cpu->getBranchPred(); + BranchPred *bp = xc->getCpuPtr()->getBranchPred(); if (bp != NULL) { - bp->popRAS(xc->thread_num); + bp->popRAS(xc->getThreadNum()); } } @@ -61,20 +61,21 @@ FnEvent::process(ExecContext *xc) if (xc->misspeculating()) return; - xc->system->kernelBinning->call(xc, mybin); + xc->getSystemPtr()->kernelBinning->call(xc, mybin); } void IdleStartEvent::process(ExecContext *xc) { - xc->kernelStats->setIdleProcess(xc->readMiscReg(AlphaISA::IPR_PALtemp23)); + xc->getCpuPtr()->kernelStats->setIdleProcess( + xc->readMiscReg(AlphaISA::IPR_PALtemp23), xc); remove(); } void InterruptStartEvent::process(ExecContext *xc) { - xc->kernelStats->mode(Kernel::interrupt); + xc->getCpuPtr()->kernelStats->mode(Kernel::interrupt, xc); } void @@ -82,5 +83,5 @@ InterruptEndEvent::process(ExecContext *xc) { // We go back to kernel, if we are user, inside the rti // pal code we will get switched to user because of the ICM write - xc->kernelStats->mode(Kernel::kernel); + xc->getCpuPtr()->kernelStats->mode(Kernel::kernel, xc); } diff --git a/kern/tru64/dump_mbuf.cc b/kern/tru64/dump_mbuf.cc index efdaed62d..5ce7570ca 100644 --- a/kern/tru64/dump_mbuf.cc +++ b/kern/tru64/dump_mbuf.cc @@ -61,7 +61,7 @@ DumpMbuf(AlphaArguments args) addr, m.m_data, m.m_len); char *buffer = new char[m.m_len]; CopyOut(xc, buffer, m.m_data, m.m_len); - Trace::dataDump(curTick, xc->system->name(), (uint8_t *)buffer, + Trace::dataDump(curTick, xc->getSystemPtr()->name(), (uint8_t *)buffer, m.m_len); delete [] buffer; diff --git a/kern/tru64/tru64.hh b/kern/tru64/tru64.hh index ad568cb0c..70abfaf6b 100644 --- a/kern/tru64/tru64.hh +++ b/kern/tru64/tru64.hh @@ -665,7 +665,7 @@ class Tru64 { // just pass basep through uninterpreted. TypedBufferArg basep(tgt_basep); - basep.copyIn(xc->mem); + basep.copyIn(xc->getMemPtr()); long host_basep = (off_t)htog((int64_t)*basep); int host_result = getdirentries(fd, host_buf, tgt_nbytes, &host_basep); @@ -692,7 +692,7 @@ class Tru64 { tgt_dp->d_reclen = tgt_bufsize; tgt_dp->d_namlen = namelen; strcpy(tgt_dp->d_name, host_dp->d_name); - tgt_dp.copyOut(xc->mem); + tgt_dp.copyOut(xc->getMemPtr()); tgt_buf_ptr += tgt_bufsize; host_buf_ptr += host_dp->d_reclen; @@ -701,7 +701,7 @@ class Tru64 { delete [] host_buf; *basep = htog((int64_t)host_basep); - basep.copyOut(xc->mem); + basep.copyOut(xc->getMemPtr()); return tgt_buf_ptr - tgt_buf; #endif @@ -713,20 +713,19 @@ class Tru64 { ExecContext *xc) { using TheISA::RegFile; - RegFile *regs = &xc->regs; TypedBufferArg sc(xc->getSyscallArg(0)); - sc.copyIn(xc->mem); + sc.copyIn(xc->getMemPtr()); // Restore state from sigcontext structure. // Note that we'll advance PC <- NPC before the end of the cycle, // so we need to restore the desired PC into NPC. // The current regs->pc will get clobbered. - regs->npc = htog(sc->sc_pc); + xc->setNextPC(htog(sc->sc_pc)); for (int i = 0; i < 31; ++i) { - regs->intRegFile[i] = htog(sc->sc_regs[i]); - regs->floatRegFile.q[i] = htog(sc->sc_fpregs[i]); + xc->setIntReg(i, htog(sc->sc_regs[i])); + xc->setFloatRegInt(i, htog(sc->sc_fpregs[i])); } xc->setMiscReg(TheISA::Fpcr_DepTag, htog(sc->sc_fpcr)); @@ -761,7 +760,7 @@ class Tru64 { elp->si_phz = htog(clk_hz); elp->si_boottime = htog(seconds_since_epoch); // seconds since epoch? elp->si_max_procs = htog(process->numCpus()); - elp.copyOut(xc->mem); + elp.copyOut(xc->getMemPtr()); return 0; } @@ -782,7 +781,7 @@ class Tru64 { { TypedBufferArg argp(xc->getSyscallArg(0)); - argp.copyIn(xc->mem); + argp.copyIn(xc->getMemPtr()); // if the user chose an address, just let them have it. Otherwise // pick one for them. @@ -791,7 +790,7 @@ class Tru64 { int stack_size = (htog(argp->rsize) + htog(argp->ysize) + htog(argp->gsize)); process->next_thread_stack_base -= stack_size; - argp.copyOut(xc->mem); + argp.copyOut(xc->getMemPtr()); } return 0; @@ -811,7 +810,7 @@ class Tru64 { TypedBufferArg attrp(xc->getSyscallArg(0)); TypedBufferArg configptr_ptr(xc->getSyscallArg(1)); - attrp.copyIn(xc->mem); + attrp.copyIn(xc->getMemPtr()); if (gtoh(attrp->nxm_version) != NXM_LIB_VERSION) { cerr << "nxm_task_init: thread library version mismatch! " @@ -852,7 +851,7 @@ class Tru64 { config->nxm_slot_state = htog(slot_state_addr); config->nxm_rad[0] = htog(rad_state_addr); - config.copyOut(xc->mem); + config.copyOut(xc->getMemPtr()); // initialize the slot_state array and copy it out TypedBufferArg slot_state(slot_state_addr, @@ -865,7 +864,7 @@ class Tru64 { (i == 0) ? Tru64::NXM_SLOT_BOUND : Tru64::NXM_SLOT_AVAIL; } - slot_state.copyOut(xc->mem); + slot_state.copyOut(xc->getMemPtr()); // same for the per-RAD "shared" struct. Note that we need to // allocate extra bytes for the per-VP array which is embedded at @@ -899,13 +898,13 @@ class Tru64 { } } - rad_state.copyOut(xc->mem); + rad_state.copyOut(xc->getMemPtr()); // // copy pointer to shared config area out to user // *configptr_ptr = htog(config_addr); - configptr_ptr.copyOut(xc->mem); + configptr_ptr.copyOut(xc->getMemPtr()); // Register this as a valid address range with the process process->nxm_start = base_addr; @@ -919,15 +918,15 @@ class Tru64 { init_exec_context(ExecContext *ec, Tru64::nxm_thread_attr *attrp, uint64_t uniq_val) { - memset(&ec->regs, 0, sizeof(ec->regs)); + ec->clearArchRegs(); - ec->regs.intRegFile[TheISA::ArgumentReg0] = gtoh(attrp->registers.a0); - ec->regs.intRegFile[27/*t12*/] = gtoh(attrp->registers.pc); - ec->regs.intRegFile[TheISA::StackPointerReg] = gtoh(attrp->registers.sp); + ec->setIntReg(TheISA::ArgumentReg0, gtoh(attrp->registers.a0)); + ec->setIntReg(27/*t12*/, gtoh(attrp->registers.pc)); + ec->setIntReg(TheISA::StackPointerReg, gtoh(attrp->registers.sp)); ec->setMiscReg(TheISA::Uniq_DepTag, uniq_val); - ec->regs.pc = gtoh(attrp->registers.pc); - ec->regs.npc = gtoh(attrp->registers.pc) + sizeof(TheISA::MachInst); + ec->setPC(gtoh(attrp->registers.pc)); + ec->setNextPC(gtoh(attrp->registers.pc) + sizeof(TheISA::MachInst)); ec->activate(); } @@ -942,7 +941,7 @@ class Tru64 { int thread_index = xc->getSyscallArg(2); // get attribute args - attrp.copyIn(xc->mem); + attrp.copyIn(xc->getMemPtr()); if (gtoh(attrp->version) != NXM_LIB_VERSION) { cerr << "nxm_thread_create: thread library version mismatch! " @@ -967,7 +966,7 @@ class Tru64 { TypedBufferArg rad_state(0x14000, rad_state_size); - rad_state.copyIn(xc->mem); + rad_state.copyIn(xc->getMemPtr()); uint64_t uniq_val = gtoh(attrp->pthid) - gtoh(rad_state->nxm_uniq_offset); @@ -978,7 +977,7 @@ class Tru64 { // This is supposed to be a port number. Make something up. *kidp = htog(99); - kidp.copyOut(xc->mem); + kidp.copyOut(xc->getMemPtr()); return 0; } else if (gtoh(attrp->type) == Tru64::NXM_TYPE_VP) { @@ -992,7 +991,7 @@ class Tru64 { ssp->nxm_u.pth_id = attrp->pthid; ssp->nxm_u.nxm_active = htog(uniq_val | 1); - rad_state.copyOut(xc->mem); + rad_state.copyOut(xc->getMemPtr()); Addr slot_state_addr = 0x12000 + sizeof(Tru64::nxm_config_info); int slot_state_size = @@ -1002,7 +1001,7 @@ class Tru64 { slot_state(slot_state_addr, slot_state_size); - slot_state.copyIn(xc->mem); + slot_state.copyIn(xc->getMemPtr()); if (slot_state[thread_index] != Tru64::NXM_SLOT_AVAIL) { cerr << "nxm_thread_createFunc: requested VP slot " @@ -1014,7 +1013,7 @@ class Tru64 { // doesn't work anyway slot_state[thread_index] = Tru64::NXM_SLOT_BOUND; - slot_state.copyOut(xc->mem); + slot_state.copyOut(xc->getMemPtr()); // Find a free simulator execution context. for (int i = 0; i < process->numCpus(); ++i) { @@ -1028,7 +1027,7 @@ class Tru64 { // and get away with just sticking the thread index // here. *kidp = htog(thread_index); - kidp.copyOut(xc->mem); + kidp.copyOut(xc->getMemPtr()); return 0; } @@ -1065,8 +1064,8 @@ class Tru64 { uint64_t action = xc->getSyscallArg(3); uint64_t usecs = xc->getSyscallArg(4); - cout << xc->cpu->name() << ": nxm_thread_block " << tid << " " << secs - << " " << flags << " " << action << " " << usecs << endl; + cout << xc->getCpuPtr()->name() << ": nxm_thread_block " << tid << " " + << secs << " " << flags << " " << action << " " << usecs << endl; return 0; } @@ -1082,7 +1081,7 @@ class Tru64 { uint64_t usecs = xc->getSyscallArg(3); uint64_t flags = xc->getSyscallArg(4); - BaseCPU *cpu = xc->cpu; + BaseCPU *cpu = xc->getCpuPtr(); cout << cpu->name() << ": nxm_block " << hex << uaddr << dec << " " << val @@ -1099,7 +1098,7 @@ class Tru64 { { Addr uaddr = xc->getSyscallArg(0); - cout << xc->cpu->name() << ": nxm_unblock " + cout << xc->getCpuPtr()->name() << ": nxm_unblock " << hex << uaddr << dec << endl; return 0; @@ -1157,12 +1156,12 @@ class Tru64 { { TypedBufferArg lockp(uaddr); - lockp.copyIn(xc->mem); + lockp.copyIn(xc->getMemPtr()); if (gtoh(*lockp) == 0) { // lock is free: grab it *lockp = htog(1); - lockp.copyOut(xc->mem); + lockp.copyOut(xc->getMemPtr()); } else { // lock is busy: disable until free process->waitList.push_back(Process::WaitRec(uaddr, xc)); @@ -1176,7 +1175,7 @@ class Tru64 { { TypedBufferArg lockp(uaddr); - lockp.copyIn(xc->mem); + lockp.copyIn(xc->getMemPtr()); assert(*lockp != 0); // Check for a process waiting on the lock. @@ -1185,7 +1184,7 @@ class Tru64 { // clear lock field if no waiting context is taking over the lock if (num_waiting == 0) { *lockp = 0; - lockp.copyOut(xc->mem); + lockp.copyOut(xc->getMemPtr()); } } @@ -1212,12 +1211,12 @@ class Tru64 { Addr uaddr = xc->getSyscallArg(0); TypedBufferArg lockp(uaddr); - lockp.copyIn(xc->mem); + lockp.copyIn(xc->getMemPtr()); if (gtoh(*lockp) == 0) { // lock is free: grab it *lockp = htog(1); - lockp.copyOut(xc->mem); + lockp.copyOut(xc->getMemPtr()); return 0; } else { return 1; @@ -1272,7 +1271,7 @@ class Tru64 { TypedBufferArg lockp(lock_addr); // user is supposed to acquire lock before entering - lockp.copyIn(xc->mem); + lockp.copyIn(xc->getMemPtr()); assert(gtoh(*lockp) != 0); m5_unlock_mutex(lock_addr, process, xc); diff --git a/kern/tru64/tru64_events.cc b/kern/tru64/tru64_events.cc index 2fe6a2dc4..d41aa5f61 100644 --- a/kern/tru64/tru64_events.cc +++ b/kern/tru64/tru64_events.cc @@ -47,13 +47,14 @@ BadAddrEvent::process(ExecContext *xc) // annotation for vmunix::badaddr in: // simos/simulation/apps/tcl/osf/tlaser.tcl - uint64_t a0 = xc->regs.intRegFile[ArgumentReg0]; + uint64_t a0 = xc->readIntReg(ArgumentReg0); if (!TheISA::IsK0Seg(a0) || - xc->memctrl->badaddr(TheISA::K0Seg2Phys(a0) & EV5::PAddrImplMask)) { + xc->getSystemPtr()->memctrl->badaddr( + TheISA::K0Seg2Phys(a0) & EV5::PAddrImplMask)) { DPRINTF(BADADDR, "badaddr arg=%#x bad\n", a0); - xc->regs.intRegFile[ReturnValueReg] = 0x1; + xc->setIntReg(ReturnValueReg, 0x1); SkipFuncEvent::process(xc); } else @@ -64,7 +65,7 @@ void PrintfEvent::process(ExecContext *xc) { if (DTRACE(Printf)) { - DebugOut() << curTick << ": " << xc->cpu->name() << ": "; + DebugOut() << curTick << ": " << xc->getCpuPtr()->name() << ": "; AlphaArguments args(xc); tru64::Printf(args); @@ -76,7 +77,7 @@ DebugPrintfEvent::process(ExecContext *xc) { if (DTRACE(DebugPrintf)) { if (!raw) - DebugOut() << curTick << ": " << xc->cpu->name() << ": "; + DebugOut() << curTick << ": " << xc->getCpuPtr()->name() << ": "; AlphaArguments args(xc); tru64::Printf(args); diff --git a/sim/process.cc b/sim/process.cc index 0a7e46082..9da93488e 100644 --- a/sim/process.cc +++ b/sim/process.cc @@ -37,6 +37,7 @@ #include "base/loader/symtab.hh" #include "base/statistics.hh" #include "config/full_system.hh" +#include "cpu/cpu_exec_context.hh" #include "cpu/exec_context.hh" #include "cpu/smt.hh" #include "encumbered/cpu/full/thread.hh" @@ -81,6 +82,8 @@ Process::Process(const string &nm, init_regs = new RegFile; memset(init_regs, 0, sizeof(RegFile)); + cpuXC = new CPUExecContext(init_regs); + // initialize first 3 fds (stdin, stdout, stderr) fd_map[STDIN_FILENO] = stdin_fd; fd_map[STDOUT_FILENO] = stdout_fd; @@ -149,7 +152,7 @@ Process::registerExecContext(ExecContext *xc) if (myIndex == 0) { // copy process's initial regs struct - xc->regs = *init_regs; + xc->copyArchRegs(cpuXC->getProxy()); } // return CPU number to caller and increment available CPU count @@ -357,7 +360,7 @@ LiveProcess::syscall(ExecContext *xc) { num_syscalls++; - int64_t callnum = xc->regs.intRegFile[ReturnValueReg]; + int64_t callnum = xc->readIntReg(ReturnValueReg); SyscallDesc *desc = getDesc(callnum); if (desc == NULL) diff --git a/sim/process.hh b/sim/process.hh index 71b7d02b3..3a48f128c 100644 --- a/sim/process.hh +++ b/sim/process.hh @@ -46,6 +46,7 @@ #include "base/statistics.hh" #include "base/trace.hh" +class CPUExecContext; class ExecContext; class FunctionalMemory; class SyscallDesc; @@ -83,6 +84,7 @@ class Process : public SimObject std::list waitList; RegFile *init_regs; // initial register contents + CPUExecContext *cpuXC; // XC to hold the init_regs Addr text_base; // text (code) segment base unsigned text_size; // text (code) size in bytes diff --git a/sim/pseudo_inst.cc b/sim/pseudo_inst.cc index 58ea8266f..f46f6acf4 100644 --- a/sim/pseudo_inst.cc +++ b/sim/pseudo_inst.cc @@ -64,7 +64,7 @@ namespace AlphaPseudo void arm(ExecContext *xc) { - xc->kernelStats->arm(); + xc->getCpuPtr()->kernelStats->arm(); } void @@ -74,13 +74,13 @@ namespace AlphaPseudo return; xc->suspend(); - xc->kernelStats->quiesce(); + xc->getCpuPtr()->kernelStats->quiesce(); } void ivlb(ExecContext *xc) { - xc->kernelStats->ivlb(); + xc->getCpuPtr()->kernelStats->ivlb(); } void @@ -138,7 +138,7 @@ namespace AlphaPseudo DPRINTF(Loader, "Loaded symbol: %s @ %#llx\n", symbol, addr); - xc->system->kernelSymtab->insert(addr,symbol); + xc->getSystemPtr()->kernelSymtab->insert(addr,symbol); } void @@ -171,7 +171,7 @@ namespace AlphaPseudo uint64_t readfile(ExecContext *xc, Addr vaddr, uint64_t len, uint64_t offset) { - const string &file = xc->cpu->system->params->readfile; + const string &file = xc->getCpuPtr()->system->params->readfile; if (file.empty()) { return ULL(0); } diff --git a/sim/syscall_emul.cc b/sim/syscall_emul.cc index d22dde3b8..2f6ed128d 100644 --- a/sim/syscall_emul.cc +++ b/sim/syscall_emul.cc @@ -47,12 +47,12 @@ void SyscallDesc::doSyscall(int callnum, Process *process, ExecContext *xc) { DPRINTFR(SyscallVerbose, "%s: syscall %s called\n", - xc->cpu->name(), name); + xc->getCpuPtr()->name(), name); SyscallReturn retval = (*funcPtr)(this, callnum, process, xc); DPRINTFR(SyscallVerbose, "%s: syscall %s returns %d\n", - xc->cpu->name(), name, retval.value()); + xc->getCpuPtr()->name(), name, retval.value()); if (!(flags & SyscallDesc::SuppressReturnValue)) xc->setSyscallReturn(retval); @@ -130,7 +130,7 @@ readFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) int bytes_read = read(fd, bufArg.bufferPtr(), nbytes); if (bytes_read != -1) - bufArg.copyOut(xc->mem); + bufArg.copyOut(xc->getMemPtr()); return bytes_read; } @@ -142,7 +142,7 @@ writeFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) int nbytes = xc->getSyscallArg(2); BufferArg bufArg(xc->getSyscallArg(1), nbytes); - bufArg.copyIn(xc->mem); + bufArg.copyIn(xc->getMemPtr()); int bytes_written = write(fd, bufArg.bufferPtr(), nbytes); @@ -183,7 +183,7 @@ gethostnameFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) strncpy((char *)name.bufferPtr(), hostname, name_len); - name.copyOut(xc->mem); + name.copyOut(xc->getMemPtr()); return 0; } @@ -193,7 +193,7 @@ unlinkFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) { string path; - if (xc->mem->readString(path, xc->getSyscallArg(0)) != NoFault) + if (xc->getMemPtr()->readString(path, xc->getSyscallArg(0)) != NoFault) return (TheISA::IntReg)-EFAULT; int result = unlink(path.c_str()); @@ -205,12 +205,12 @@ renameFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) { string old_name; - if (xc->mem->readString(old_name, xc->getSyscallArg(0)) != NoFault) + if (xc->getMemPtr()->readString(old_name, xc->getSyscallArg(0)) != NoFault) return -EFAULT; string new_name; - if (xc->mem->readString(new_name, xc->getSyscallArg(1)) != NoFault) + if (xc->getMemPtr()->readString(new_name, xc->getSyscallArg(1)) != NoFault) return -EFAULT; int64_t result = rename(old_name.c_str(), new_name.c_str()); @@ -222,7 +222,7 @@ truncateFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) { string path; - if (xc->mem->readString(path, xc->getSyscallArg(0)) != NoFault) + if (xc->getMemPtr()->readString(path, xc->getSyscallArg(0)) != NoFault) return -EFAULT; off_t length = xc->getSyscallArg(1); @@ -250,7 +250,7 @@ chownFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc) { string path; - if (xc->mem->readString(path, xc->getSyscallArg(0)) != NoFault) + if (xc->getMemPtr()->readString(path, xc->getSyscallArg(0)) != NoFault) return -EFAULT; /* XXX endianess */ diff --git a/sim/syscall_emul.hh b/sim/syscall_emul.hh index f49248dea..32f98600c 100644 --- a/sim/syscall_emul.hh +++ b/sim/syscall_emul.hh @@ -321,7 +321,7 @@ openFunc(SyscallDesc *desc, int callnum, Process *process, { std::string path; - if (xc->mem->readString(path, xc->getSyscallArg(0)) != NoFault) + if (xc->getMemPtr()->readString(path, xc->getSyscallArg(0)) != NoFault) return -EFAULT; if (path == "/dev/sysdev0") { @@ -368,7 +368,7 @@ chmodFunc(SyscallDesc *desc, int callnum, Process *process, { std::string path; - if (xc->mem->readString(path, xc->getSyscallArg(0)) != NoFault) + if (xc->getMemPtr()->readString(path, xc->getSyscallArg(0)) != NoFault) return -EFAULT; uint32_t mode = xc->getSyscallArg(1); @@ -421,7 +421,7 @@ statFunc(SyscallDesc *desc, int callnum, Process *process, { std::string path; - if (xc->mem->readString(path, xc->getSyscallArg(0)) != NoFault) + if (xc->getMemPtr()->readString(path, xc->getSyscallArg(0)) != NoFault) return -EFAULT; struct stat hostBuf; @@ -430,7 +430,7 @@ statFunc(SyscallDesc *desc, int callnum, Process *process, if (result < 0) return errno; - OS::copyOutStatBuf(xc->mem, xc->getSyscallArg(1), &hostBuf); + OS::copyOutStatBuf(xc->getMemPtr(), xc->getSyscallArg(1), &hostBuf); return 0; } @@ -459,7 +459,7 @@ fstat64Func(SyscallDesc *desc, int callnum, Process *process, if (result < 0) return errno; - OS::copyOutStat64Buf(xc->mem, fd, xc->getSyscallArg(1), &hostBuf); + OS::copyOutStat64Buf(xc->getMemPtr(), fd, xc->getSyscallArg(1), &hostBuf); return 0; } @@ -473,7 +473,7 @@ lstatFunc(SyscallDesc *desc, int callnum, Process *process, { std::string path; - if (xc->mem->readString(path, xc->getSyscallArg(0)) != NoFault) + if (xc->getMemPtr()->readString(path, xc->getSyscallArg(0)) != NoFault) return -EFAULT; struct stat hostBuf; @@ -482,7 +482,7 @@ lstatFunc(SyscallDesc *desc, int callnum, Process *process, if (result < 0) return -errno; - OS::copyOutStatBuf(xc->mem, xc->getSyscallArg(1), &hostBuf); + OS::copyOutStatBuf(xc->getMemPtr(), xc->getSyscallArg(1), &hostBuf); return 0; } @@ -495,7 +495,7 @@ lstat64Func(SyscallDesc *desc, int callnum, Process *process, { std::string path; - if (xc->mem->readString(path, xc->getSyscallArg(0)) != NoFault) + if (xc->getMemPtr()->readString(path, xc->getSyscallArg(0)) != NoFault) return -EFAULT; #if BSD_HOST @@ -509,7 +509,7 @@ lstat64Func(SyscallDesc *desc, int callnum, Process *process, if (result < 0) return -errno; - OS::copyOutStat64Buf(xc->mem, -1, xc->getSyscallArg(1), &hostBuf); + OS::copyOutStat64Buf(xc->getMemPtr(), -1, xc->getSyscallArg(1), &hostBuf); return 0; } @@ -533,7 +533,7 @@ fstatFunc(SyscallDesc *desc, int callnum, Process *process, if (result < 0) return -errno; - OS::copyOutStatBuf(xc->mem, xc->getSyscallArg(1), &hostBuf); + OS::copyOutStatBuf(xc->getMemPtr(), xc->getSyscallArg(1), &hostBuf); return 0; } @@ -546,7 +546,7 @@ statfsFunc(SyscallDesc *desc, int callnum, Process *process, { std::string path; - if (xc->mem->readString(path, xc->getSyscallArg(0)) != NoFault) + if (xc->getMemPtr()->readString(path, xc->getSyscallArg(0)) != NoFault) return -EFAULT; struct statfs hostBuf; @@ -555,7 +555,7 @@ statfsFunc(SyscallDesc *desc, int callnum, Process *process, if (result < 0) return errno; - OS::copyOutStatfsBuf(xc->mem, xc->getSyscallArg(1), &hostBuf); + OS::copyOutStatfsBuf(xc->getMemPtr(), xc->getSyscallArg(1), &hostBuf); return 0; } @@ -578,7 +578,7 @@ fstatfsFunc(SyscallDesc *desc, int callnum, Process *process, if (result < 0) return errno; - OS::copyOutStatfsBuf(xc->mem, xc->getSyscallArg(1), &hostBuf); + OS::copyOutStatfsBuf(xc->getMemPtr(), xc->getSyscallArg(1), &hostBuf); return 0; } @@ -602,11 +602,11 @@ writevFunc(SyscallDesc *desc, int callnum, Process *process, for (int i = 0; i < count; ++i) { typename OS::tgt_iovec tiov; - xc->mem->access(Read, tiov_base + i*sizeof(typename OS::tgt_iovec), + xc->getMemPtr()->access(Read, tiov_base + i*sizeof(typename OS::tgt_iovec), &tiov, sizeof(typename OS::tgt_iovec)); hiov[i].iov_len = gtoh(tiov.iov_len); hiov[i].iov_base = new char [hiov[i].iov_len]; - xc->mem->access(Read, gtoh(tiov.iov_base), + xc->getMemPtr()->access(Read, gtoh(tiov.iov_base), hiov[i].iov_base, hiov[i].iov_len); } @@ -689,7 +689,7 @@ getrlimitFunc(SyscallDesc *desc, int callnum, Process *process, break; } - rlp.copyOut(xc->mem); + rlp.copyOut(xc->getMemPtr()); return 0; } @@ -706,7 +706,7 @@ gettimeofdayFunc(SyscallDesc *desc, int callnum, Process *process, tp->tv_sec = htog(tp->tv_sec); tp->tv_usec = htog(tp->tv_usec); - tp.copyOut(xc->mem); + tp.copyOut(xc->getMemPtr()); return 0; } @@ -720,11 +720,11 @@ utimesFunc(SyscallDesc *desc, int callnum, Process *process, { std::string path; - if (xc->mem->readString(path, xc->getSyscallArg(0)) != NoFault) + if (xc->getMemPtr()->readString(path, xc->getSyscallArg(0)) != NoFault) return -EFAULT; TypedBufferArg tp(xc->getSyscallArg(1)); - tp.copyIn(xc->mem); + tp.copyIn(xc->getMemPtr()); struct timeval hostTimeval[2]; for (int i = 0; i < 2; ++i) @@ -776,7 +776,7 @@ getrusageFunc(SyscallDesc *desc, int callnum, Process *process, rup->ru_nvcsw = 0; rup->ru_nivcsw = 0; - rup.copyOut(xc->mem); + rup.copyOut(xc->getMemPtr()); return 0; } From d01a593433137fa986b7367f536a65692e75b230 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Sat, 4 Mar 2006 20:45:01 -0500 Subject: [PATCH 148/180] move alpha specific code into arch/alpha System -> AlphaSystem SConscript: Move some more files around arch/alpha/freebsd/system.cc: arch/alpha/freebsd/system.hh: System -> AlphaSystem arch/alpha/linux/aligned.hh: arch/alpha/linux/hwrpb.hh: arch/alpha/linux/system.cc: arch/alpha/linux/thread_info.hh: arch/alpha/linux/threadinfo.hh: move alpha specific code into arch/alpha python/m5/objects/System.py: Split off arch specific parts of system into AlphaSystem --HG-- rename : kern/freebsd/freebsd_system.cc => arch/alpha/freebsd/system.cc rename : kern/freebsd/freebsd_system.hh => arch/alpha/freebsd/system.hh rename : kern/linux/aligned.hh => arch/alpha/linux/aligned.hh rename : kern/linux/hwrpb.hh => arch/alpha/linux/hwrpb.hh rename : kern/linux/linux_system.cc => arch/alpha/linux/system.cc rename : kern/linux/linux_system.hh => arch/alpha/linux/system.hh rename : kern/linux/thread_info.hh => arch/alpha/linux/thread_info.hh rename : kern/linux/linux_threadinfo.hh => arch/alpha/linux/threadinfo.hh rename : kern/tru64/tru64_system.cc => arch/alpha/tru64/system.cc rename : kern/tru64/tru64_system.hh => arch/alpha/tru64/system.hh extra : convert_revision : 1c496efb823326a4b629574bd9b5f30e99a0aa40 --- SConscript | 7 ++- .../alpha/freebsd/system.cc | 28 +++++----- .../alpha/freebsd/system.hh | 6 +- {kern => arch/alpha}/linux/aligned.hh | 8 +-- {kern => arch/alpha}/linux/hwrpb.hh | 8 +-- .../alpha/linux/system.cc | 56 ++++++++----------- .../alpha/linux/system.hh | 35 +++++------- {kern => arch/alpha}/linux/thread_info.hh | 8 +-- .../alpha/linux/threadinfo.hh | 9 +-- .../alpha/tru64/system.cc | 24 ++++---- .../alpha/tru64/system.hh | 13 +++-- kern/linux/events.cc | 54 ++++++++++++++++++ kern/linux/events.hh | 50 +++++++++++++++++ python/m5/objects/System.py | 12 ++-- 14 files changed, 206 insertions(+), 112 deletions(-) rename kern/freebsd/freebsd_system.cc => arch/alpha/freebsd/system.cc (87%) rename kern/freebsd/freebsd_system.hh => arch/alpha/freebsd/system.hh (95%) rename {kern => arch/alpha}/linux/aligned.hh (92%) rename {kern => arch/alpha}/linux/hwrpb.hh (90%) rename kern/linux/linux_system.cc => arch/alpha/linux/system.cc (90%) rename kern/linux/linux_system.hh => arch/alpha/linux/system.hh (87%) rename {kern => arch/alpha}/linux/thread_info.hh (91%) rename kern/linux/linux_threadinfo.hh => arch/alpha/linux/threadinfo.hh (92%) rename kern/tru64/tru64_system.cc => arch/alpha/tru64/system.cc (91%) rename kern/tru64/tru64_system.hh => arch/alpha/tru64/system.hh (90%) create mode 100644 kern/linux/events.cc create mode 100644 kern/linux/events.hh diff --git a/SConscript b/SConscript index 54d02ea4c..f58d78798 100644 --- a/SConscript +++ b/SConscript @@ -212,7 +212,10 @@ mysql_sources = Split(''' # Full-system sources full_system_sources = Split(''' + arch/alpha/freebsd/system.cc + arch/alpha/linux/system.cc arch/alpha/system.cc + arch/alpha/tru64/system.cc base/crc.cc base/inet.cc @@ -253,15 +256,13 @@ full_system_sources = Split(''' kern/kernel_binning.cc kern/kernel_stats.cc kern/system_events.cc - kern/freebsd/freebsd_system.cc + kern/linux/events.cc kern/linux/linux_syscalls.cc - kern/linux/linux_system.cc kern/linux/printk.cc kern/tru64/dump_mbuf.cc kern/tru64/printf.cc kern/tru64/tru64_events.cc kern/tru64/tru64_syscalls.cc - kern/tru64/tru64_system.cc mem/functional/memory_control.cc mem/functional/physical.cc diff --git a/kern/freebsd/freebsd_system.cc b/arch/alpha/freebsd/system.cc similarity index 87% rename from kern/freebsd/freebsd_system.cc rename to arch/alpha/freebsd/system.cc index 7ba385267..681d4ad46 100644 --- a/kern/freebsd/freebsd_system.cc +++ b/arch/alpha/freebsd/system.cc @@ -34,9 +34,9 @@ */ #include "arch/alpha/system.hh" +#include "arch/alpha/freebsd/system.hh" #include "base/loader/symtab.hh" #include "cpu/exec_context.hh" -#include "kern/freebsd/freebsd_system.hh" #include "mem/functional/memory_control.hh" #include "mem/functional/physical.hh" #include "sim/builder.hh" @@ -47,9 +47,9 @@ #define TIMER_FREQUENCY 1193180 using namespace std; -using namespace TheISA; +using namespace AlphaISA; -FreebsdSystem::FreebsdSystem(Params *p) +FreebsdAlphaSystem::FreebsdAlphaSystem(Params *p) : AlphaSystem(p) { /** @@ -62,7 +62,7 @@ FreebsdSystem::FreebsdSystem(Params *p) } -FreebsdSystem::~FreebsdSystem() +FreebsdAlphaSystem::~FreebsdAlphaSystem() { delete skipDelayEvent; delete skipCalibrateClocks; @@ -70,7 +70,7 @@ FreebsdSystem::~FreebsdSystem() void -FreebsdSystem::doCalibrateClocks(ExecContext *xc) +FreebsdAlphaSystem::doCalibrateClocks(ExecContext *xc) { Addr ppc_vaddr = 0; Addr timer_vaddr = 0; @@ -92,14 +92,14 @@ FreebsdSystem::doCalibrateClocks(ExecContext *xc) void -FreebsdSystem::SkipCalibrateClocksEvent::process(ExecContext *xc) +FreebsdAlphaSystem::SkipCalibrateClocksEvent::process(ExecContext *xc) { SkipFuncEvent::process(xc); - ((FreebsdSystem *)xc->system)->doCalibrateClocks(xc); + ((FreebsdAlphaSystem *)xc->system)->doCalibrateClocks(xc); } -BEGIN_DECLARE_SIM_OBJECT_PARAMS(FreebsdSystem) +BEGIN_DECLARE_SIM_OBJECT_PARAMS(FreebsdAlphaSystem) Param boot_cpu_frequency; SimObjectParam memctrl; @@ -120,9 +120,9 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(FreebsdSystem) VectorParam binned_fns; Param bin_int; -END_DECLARE_SIM_OBJECT_PARAMS(FreebsdSystem) +END_DECLARE_SIM_OBJECT_PARAMS(FreebsdAlphaSystem) -BEGIN_INIT_SIM_OBJECT_PARAMS(FreebsdSystem) +BEGIN_INIT_SIM_OBJECT_PARAMS(FreebsdAlphaSystem) INIT_PARAM(boot_cpu_frequency, "Frequency of the boot CPU"), INIT_PARAM(memctrl, "memory controller"), @@ -140,9 +140,9 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(FreebsdSystem) INIT_PARAM(binned_fns, "functions to be broken down and binned"), INIT_PARAM_DFLT(bin_int, "is interrupt code binned seperately?", true) -END_INIT_SIM_OBJECT_PARAMS(FreebsdSystem) +END_INIT_SIM_OBJECT_PARAMS(FreebsdAlphaSystem) -CREATE_SIM_OBJECT(FreebsdSystem) +CREATE_SIM_OBJECT(FreebsdAlphaSystem) { AlphaSystem::Params *p = new AlphaSystem::Params; p->name = getInstanceName(); @@ -160,8 +160,8 @@ CREATE_SIM_OBJECT(FreebsdSystem) p->bin = bin; p->binned_fns = binned_fns; p->bin_int = bin_int; - return new FreebsdSystem(p); + return new FreebsdAlphaSystem(p); } -REGISTER_SIM_OBJECT("FreebsdSystem", FreebsdSystem) +REGISTER_SIM_OBJECT("FreebsdAlphaSystem", FreebsdAlphaSystem) diff --git a/kern/freebsd/freebsd_system.hh b/arch/alpha/freebsd/system.hh similarity index 95% rename from kern/freebsd/freebsd_system.hh rename to arch/alpha/freebsd/system.hh index f87fb03ef..5d996955e 100644 --- a/kern/freebsd/freebsd_system.hh +++ b/arch/alpha/freebsd/system.hh @@ -31,7 +31,7 @@ #include "kern/system_events.hh" -class FreebsdSystem : public AlphaSystem +class FreebsdAlphaSystem : public AlphaSystem { private: class SkipCalibrateClocksEvent : public SkipFuncEvent @@ -47,8 +47,8 @@ class FreebsdSystem : public AlphaSystem SkipCalibrateClocksEvent *skipCalibrateClocks; public: - FreebsdSystem(Params *p); - ~FreebsdSystem(); + FreebsdAlphaSystem(Params *p); + ~FreebsdAlphaSystem(); void doCalibrateClocks(ExecContext *xc); }; diff --git a/kern/linux/aligned.hh b/arch/alpha/linux/aligned.hh similarity index 92% rename from kern/linux/aligned.hh rename to arch/alpha/linux/aligned.hh index 18d1b43c0..cabecb283 100644 --- a/kern/linux/aligned.hh +++ b/arch/alpha/linux/aligned.hh @@ -26,15 +26,15 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef __KERN_LINUX_ALIGNED_HH__ -#define __KERN_LINUX_ALIGNED_HH__ +#ifndef __ARCH_ALPHA_LINUX_ALIGNED_HH__ +#define __ARCH_ALPHA_LINUX_ALIGNED_HH__ /* GCC 3.3.X has a bug in which attributes+typedefs don't work. 3.2.X is fine * as in 3.4.X, but the bug is marked will not fix in 3.3.X so here is * the work around. */ -#if __GNUC__ == 3 && __GNUC_MINOR__ != 3 +#if (__GNUC__ == 3 && __GNUC_MINOR__ != 3) || __GNUC__ > 3 typedef uint64_t uint64_ta __attribute__ ((aligned (8))) ; typedef int64_t int64_ta __attribute__ ((aligned (8))) ; typedef Addr Addr_a __attribute__ ((aligned (8))) ; @@ -44,4 +44,4 @@ typedef Addr Addr_a __attribute__ ((aligned (8))) ; #define Addr_a Addr __attribute__ ((aligned (8))) #endif /* __GNUC__ __GNUC_MINOR__ */ -#endif /* __KERN_LINUX_ALIGNED_HH__ */ +#endif /* __ARCH_ALPHA_LINUX_ALIGNED_HH__ */ diff --git a/kern/linux/hwrpb.hh b/arch/alpha/linux/hwrpb.hh similarity index 90% rename from kern/linux/hwrpb.hh rename to arch/alpha/linux/hwrpb.hh index 4c8ac32e8..869ce026b 100644 --- a/kern/linux/hwrpb.hh +++ b/arch/alpha/linux/hwrpb.hh @@ -22,10 +22,10 @@ * SOFTWARE. */ -#ifndef __KERN_LINUX_HWRPB_HH__ -#define __KERN_LINUX_HWRPB_HH__ +#ifndef __ARCH_ALPHA_LINUX_HWRPB_HH__ +#define __ARCH_ALPHA_LINUX_HWRPB_HH__ -#include "kern/linux/aligned.hh" +#include "arch/alpha/linux/aligned.hh" namespace Linux { struct pcb_struct { @@ -39,4 +39,4 @@ namespace Linux { uint64_ta res1, res2; }; } -#endif // __KERN_LINUX_HWRPB_HH__ +#endif // __ARCH_ALPHA_LINUX_HWRPB_HH__ diff --git a/kern/linux/linux_system.cc b/arch/alpha/linux/system.cc similarity index 90% rename from kern/linux/linux_system.cc rename to arch/alpha/linux/system.cc index d7ec8a327..6a820d14f 100644 --- a/kern/linux/linux_system.cc +++ b/arch/alpha/linux/system.cc @@ -35,25 +35,27 @@ * up boot time. */ +#include "arch/arguments.hh" +#include "arch/vtophys.hh" +#include "arch/alpha/linux/system.hh" +#include "arch/alpha/linux/threadinfo.hh" #include "arch/alpha/system.hh" #include "base/loader/symtab.hh" #include "cpu/exec_context.hh" #include "cpu/base.hh" -#include "kern/linux/linux_system.hh" -#include "kern/linux/linux_threadinfo.hh" +#include "dev/platform.hh" #include "kern/linux/printk.hh" +#include "kern/linux/events.hh" #include "mem/functional/memory_control.hh" #include "mem/functional/physical.hh" #include "sim/builder.hh" #include "sim/byteswap.hh" -#include "dev/platform.hh" -#include "arch/arguments.hh" -#include "arch/vtophys.hh" using namespace std; -using namespace TheISA; +using namespace AlphaISA; +using namespace Linux; -LinuxSystem::LinuxSystem(Params *p) +LinuxAlphaSystem::LinuxAlphaSystem(Params *p) : AlphaSystem(p) { Addr addr = 0; @@ -166,7 +168,7 @@ LinuxSystem::LinuxSystem(Params *p) } } -LinuxSystem::~LinuxSystem() +LinuxAlphaSystem::~LinuxAlphaSystem() { #ifndef NDEBUG delete kernelPanicEvent; @@ -184,7 +186,7 @@ LinuxSystem::~LinuxSystem() void -LinuxSystem::setDelayLoop(ExecContext *xc) +LinuxAlphaSystem::setDelayLoop(ExecContext *xc) { Addr addr = 0; if (kernelSymtab->findAddress("loops_per_jiffy", addr)) { @@ -200,31 +202,17 @@ LinuxSystem::setDelayLoop(ExecContext *xc) } } + void -LinuxSystem::SkipDelayLoopEvent::process(ExecContext *xc) +LinuxAlphaSystem::SkipDelayLoopEvent::process(ExecContext *xc) { SkipFuncEvent::process(xc); // calculate and set loops_per_jiffy - ((LinuxSystem *)xc->system)->setDelayLoop(xc); + ((LinuxAlphaSystem *)xc->system)->setDelayLoop(xc); } void -LinuxSystem::DebugPrintkEvent::process(ExecContext *xc) -{ - if (DTRACE(DebugPrintf)) { - if (!raw) { - StringWrap name(xc->system->name() + ".dprintk"); - DPRINTFN(""); - } - - AlphaArguments args(xc); - Printk(args); - SkipFuncEvent::process(xc); - } -} - -void -LinuxSystem::PrintThreadInfo::process(ExecContext *xc) +LinuxAlphaSystem::PrintThreadInfo::process(ExecContext *xc) { Linux::ThreadInfo ti(xc); @@ -233,7 +221,7 @@ LinuxSystem::PrintThreadInfo::process(ExecContext *xc) } -BEGIN_DECLARE_SIM_OBJECT_PARAMS(LinuxSystem) +BEGIN_DECLARE_SIM_OBJECT_PARAMS(LinuxAlphaSystem) Param boot_cpu_frequency; SimObjectParam memctrl; @@ -254,9 +242,9 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(LinuxSystem) VectorParam binned_fns; Param bin_int; -END_DECLARE_SIM_OBJECT_PARAMS(LinuxSystem) +END_DECLARE_SIM_OBJECT_PARAMS(LinuxAlphaSystem) -BEGIN_INIT_SIM_OBJECT_PARAMS(LinuxSystem) +BEGIN_INIT_SIM_OBJECT_PARAMS(LinuxAlphaSystem) INIT_PARAM(boot_cpu_frequency, "Frequency of the boot CPU"), INIT_PARAM(memctrl, "memory controller"), @@ -274,9 +262,9 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(LinuxSystem) INIT_PARAM(binned_fns, "functions to be broken down and binned"), INIT_PARAM_DFLT(bin_int, "is interrupt code binned seperately?", true) -END_INIT_SIM_OBJECT_PARAMS(LinuxSystem) +END_INIT_SIM_OBJECT_PARAMS(LinuxAlphaSystem) -CREATE_SIM_OBJECT(LinuxSystem) +CREATE_SIM_OBJECT(LinuxAlphaSystem) { AlphaSystem::Params *p = new AlphaSystem::Params; p->name = getInstanceName(); @@ -294,8 +282,8 @@ CREATE_SIM_OBJECT(LinuxSystem) p->bin = bin; p->binned_fns = binned_fns; p->bin_int = bin_int; - return new LinuxSystem(p); + return new LinuxAlphaSystem(p); } -REGISTER_SIM_OBJECT("LinuxSystem", LinuxSystem) +REGISTER_SIM_OBJECT("LinuxAlphaSystem", LinuxAlphaSystem) diff --git a/kern/linux/linux_system.hh b/arch/alpha/linux/system.hh similarity index 87% rename from kern/linux/linux_system.hh rename to arch/alpha/linux/system.hh index 9fecb7290..035e2a427 100644 --- a/kern/linux/linux_system.hh +++ b/arch/alpha/linux/system.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004-2005 The Regents of The University of Michigan + * Copyright (c) 2004-2006 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,21 +26,27 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef __KERN_LINUX_LINUX_SYSTEM_HH__ -#define __KERN_LINUX_LINUX_SYSTEM_HH__ +#ifndef __ARCH_ALPHA_LINUX_SYSTEM_HH__ +#define __ARCH_ALPHA_LINUX_SYSTEM_HH__ class ExecContext; class BreakPCEvent; class IdleStartEvent; -class PrintThreadInfo; + +#include "arch/alpha/system.hh" +#include "kern/linux/events.hh" + +using namespace AlphaISA; +using namespace Linux; +using namespace std; /** * This class contains linux specific system code (Loading, Events, Binning). * It points to objects that are the system binaries to load and patches them * appropriately to work in simulator. */ -class LinuxSystem : public AlphaSystem +class LinuxAlphaSystem : public AlphaSystem { private: class SkipDelayLoopEvent : public SkipFuncEvent @@ -51,18 +57,6 @@ class LinuxSystem : public AlphaSystem virtual void process(ExecContext *xc); }; - class DebugPrintkEvent : public SkipFuncEvent - { - private: - bool raw; - - public: - DebugPrintkEvent(PCEventQueue *q, const std::string &desc, Addr addr, - bool r = false) - : SkipFuncEvent(q, desc, addr), raw(r) {} - virtual void process(ExecContext *xc); - }; - class PrintThreadInfo : public PCEvent { public: @@ -71,6 +65,7 @@ class LinuxSystem : public AlphaSystem virtual void process(ExecContext *xc); }; + /** * Addresses defining where the kernel bootloader places various * elements. Details found in include/asm-alpha/system.h @@ -142,10 +137,10 @@ class LinuxSystem : public AlphaSystem IdleStartEvent *idleStartEvent; public: - LinuxSystem(Params *p); - ~LinuxSystem(); + LinuxAlphaSystem(Params *p); + ~LinuxAlphaSystem(); void setDelayLoop(ExecContext *xc); }; -#endif // __KERN_LINUX_LINUX_SYSTEM_HH__ +#endif // __ARCH_ALPHA_LINUX_SYSTEM_HH__ diff --git a/kern/linux/thread_info.hh b/arch/alpha/linux/thread_info.hh similarity index 91% rename from kern/linux/thread_info.hh rename to arch/alpha/linux/thread_info.hh index cf24ef939..88791b00d 100644 --- a/kern/linux/thread_info.hh +++ b/arch/alpha/linux/thread_info.hh @@ -26,10 +26,10 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef __KERN_LINUX_THREAD_INFO_H__ -#define __KERN_LINUX_THREAD_INFO_H__ +#ifndef __ARCH_ALPHA_LINUX_THREAD_INFO_H__ +#define __ARCH_ALPHA_LINUX_THREAD_INFO_H__ -#include "kern/linux/hwrpb.hh" +#include "arch/alpha/linux/hwrpb.hh" namespace Linux { struct thread_info { @@ -38,4 +38,4 @@ namespace Linux { }; } -#endif // __KERN_LINUX_THREAD_INFO_H__ +#endif // __ARCH_ALPHA_LINUX_THREAD_INFO_H__ diff --git a/kern/linux/linux_threadinfo.hh b/arch/alpha/linux/threadinfo.hh similarity index 92% rename from kern/linux/linux_threadinfo.hh rename to arch/alpha/linux/threadinfo.hh index a1c378d6a..bdb8e1e4c 100644 --- a/kern/linux/linux_threadinfo.hh +++ b/arch/alpha/linux/threadinfo.hh @@ -26,10 +26,11 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef __KERN_LINUX_LINUX_TREADNIFO_HH__ -#define __KERN_LINUX_LINUX_TREADNIFO_HH__ +#ifndef __ARCH_ALPHA_LINUX_LINUX_TREADNIFO_HH__ +#define __ARCH_ALPHA_LINUX_LINUX_TREADNIFO_HH__ -#include "kern/linux/thread_info.hh" +#include "arch/alpha/linux/thread_info.hh" +#include "cpu/exec_context.hh" #include "kern/linux/sched.hh" #include "sim/vptr.hh" @@ -85,4 +86,4 @@ class ThreadInfo /* namespace Linux */ } -#endif // __KERN_LINUX_LINUX_THREADINFO_HH__ +#endif // __ARCH_ALPHA_LINUX_LINUX_THREADINFO_HH__ diff --git a/kern/tru64/tru64_system.cc b/arch/alpha/tru64/system.cc similarity index 91% rename from kern/tru64/tru64_system.cc rename to arch/alpha/tru64/system.cc index aa78e8de6..d09a0c85d 100644 --- a/kern/tru64/tru64_system.cc +++ b/arch/alpha/tru64/system.cc @@ -26,22 +26,22 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include "arch/alpha/tru64/system.hh" +#include "arch/isa_traits.hh" +#include "arch/vtophys.hh" #include "base/loader/symtab.hh" #include "base/trace.hh" #include "cpu/base.hh" #include "cpu/exec_context.hh" #include "kern/tru64/tru64_events.hh" -#include "kern/tru64/tru64_system.hh" #include "kern/system_events.hh" #include "mem/functional/memory_control.hh" #include "mem/functional/physical.hh" #include "sim/builder.hh" -#include "arch/isa_traits.hh" -#include "arch/vtophys.hh" using namespace std; -Tru64System::Tru64System(Tru64System::Params *p) +Tru64AlphaSystem::Tru64AlphaSystem(Tru64AlphaSystem::Params *p) : AlphaSystem(p) { Addr addr = 0; @@ -77,7 +77,7 @@ Tru64System::Tru64System(Tru64System::Params *p) #endif } -Tru64System::~Tru64System() +Tru64AlphaSystem::~Tru64AlphaSystem() { #ifdef DEBUG delete kernelPanicEvent; @@ -93,7 +93,7 @@ Tru64System::~Tru64System() #endif } -BEGIN_DECLARE_SIM_OBJECT_PARAMS(Tru64System) +BEGIN_DECLARE_SIM_OBJECT_PARAMS(Tru64AlphaSystem) Param boot_cpu_frequency; SimObjectParam memctrl; @@ -113,9 +113,9 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(Tru64System) Param bin; VectorParam binned_fns; -END_DECLARE_SIM_OBJECT_PARAMS(Tru64System) +END_DECLARE_SIM_OBJECT_PARAMS(Tru64AlphaSystem) -BEGIN_INIT_SIM_OBJECT_PARAMS(Tru64System) +BEGIN_INIT_SIM_OBJECT_PARAMS(Tru64AlphaSystem) INIT_PARAM(boot_cpu_frequency, "frequency of the boot cpu"), INIT_PARAM(memctrl, "memory controller"), @@ -132,9 +132,9 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(Tru64System) INIT_PARAM_DFLT(bin, "is this system to be binned", false), INIT_PARAM(binned_fns, "functions to be broken down and binned") -END_INIT_SIM_OBJECT_PARAMS(Tru64System) +END_INIT_SIM_OBJECT_PARAMS(Tru64AlphaSystem) -CREATE_SIM_OBJECT(Tru64System) +CREATE_SIM_OBJECT(Tru64AlphaSystem) { AlphaSystem::Params *p = new AlphaSystem::Params; p->name = getInstanceName(); @@ -153,7 +153,7 @@ CREATE_SIM_OBJECT(Tru64System) p->binned_fns = binned_fns; p->bin_int = false; - return new Tru64System(p); + return new Tru64AlphaSystem(p); } -REGISTER_SIM_OBJECT("Tru64System", Tru64System) +REGISTER_SIM_OBJECT("Tru64AlphaSystem", Tru64AlphaSystem) diff --git a/kern/tru64/tru64_system.hh b/arch/alpha/tru64/system.hh similarity index 90% rename from kern/tru64/tru64_system.hh rename to arch/alpha/tru64/system.hh index 38e6d9dd7..0e0cc1bc8 100644 --- a/kern/tru64/tru64_system.hh +++ b/arch/alpha/tru64/system.hh @@ -26,8 +26,8 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef __KERN_TRU64_TRU64_SYSTEM_HH__ -#define __KERN_TRU64_TRU64_SYSTEM_HH__ +#ifndef __ARCH_ALPHA_TRU64_SYSTEM_HH__ +#define __ARCH_ALPHA_TRU64_SYSTEM_HH__ #include "arch/alpha/system.hh" #include "arch/isa_traits.hh" @@ -40,10 +40,11 @@ class BadAddrEvent; class SkipFuncEvent; class PrintfEvent; class DebugPrintfEvent; +class DebugPrintfrEvent; class DumpMbufEvent; class AlphaArguments; -class Tru64System : public AlphaSystem +class Tru64AlphaSystem : public AlphaSystem { private: #ifdef DEBUG @@ -60,11 +61,11 @@ class Tru64System : public AlphaSystem DumpMbufEvent *dumpMbufEvent; public: - Tru64System(Params *p); - ~Tru64System(); + Tru64AlphaSystem(Params *p); + ~Tru64AlphaSystem(); static void Printf(AlphaArguments args); static void DumpMbuf(AlphaArguments args); }; -#endif // __KERN_TRU64_TRU64_SYSTEM_HH__ +#endif // __ARCH_ALPHA_TRU64_SYSTEM_HH__ diff --git a/kern/linux/events.cc b/kern/linux/events.cc new file mode 100644 index 000000000..a781165ac --- /dev/null +++ b/kern/linux/events.cc @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2004-2006 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "arch/arguments.hh" +#include "base/trace.hh" +#include "cpu/exec_context.hh" +#include "kern/linux/events.hh" +#include "kern/linux/printk.hh" +#include "kern/system_events.hh" + + +namespace Linux { + +void +DebugPrintkEvent::process(ExecContext *xc) +{ + if (DTRACE(DebugPrintf)) { + if (!raw) { + StringWrap name(xc->system->name() + ".dprintk"); + DPRINTFN(""); + } + + AlphaArguments args(xc); + Printk(args); + SkipFuncEvent::process(xc); + } +} + +} // namespace linux diff --git a/kern/linux/events.hh b/kern/linux/events.hh new file mode 100644 index 000000000..95c268976 --- /dev/null +++ b/kern/linux/events.hh @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2004-2006 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __KERN_LINUX_EVENTS_HH__ +#define __KERN_LINUX_EVENTS_HH__ + +#include "kern/system_events.hh" + +namespace Linux { + +class DebugPrintkEvent : public SkipFuncEvent +{ + private: + bool raw; + + public: + DebugPrintkEvent(PCEventQueue *q, const std::string &desc, Addr addr, + bool r = false) + : SkipFuncEvent(q, desc, addr), raw(r) {} + virtual void process(ExecContext *xc); +}; + +} + +#endif diff --git a/python/m5/objects/System.py b/python/m5/objects/System.py index 6d1d6a68c..5925cadf5 100644 --- a/python/m5/objects/System.py +++ b/python/m5/objects/System.py @@ -1,17 +1,21 @@ from m5 import * + class System(SimObject): type = 'System' boot_cpu_frequency = Param.Frequency(Self.cpu[0].clock.frequency, "boot processor frequency") memctrl = Param.MemoryController(Parent.any, "memory controller") physmem = Param.PhysicalMemory(Parent.any, "phsyical memory") + init_param = Param.UInt64(0, "numerical value to pass into simulator") + bin = Param.Bool(False, "is this system binned") + binned_fns = VectorParam.String([], "functions broken down and binned") kernel = Param.String("file that contains the kernel code") + readfile = Param.String("", "file to read startup script from") + +class AlphaSystem(System): + type = 'AlphaSystem' console = Param.String("file that contains the console code") pal = Param.String("file that contains palcode") - readfile = Param.String("", "file to read startup script from") - init_param = Param.UInt64(0, "numerical value to pass into simulator") boot_osflags = Param.String("a", "boot flags to pass to the kernel") system_type = Param.UInt64("Type of system we are emulating") system_rev = Param.UInt64("Revision of system we are emulating") - bin = Param.Bool(False, "is this system binned") - binned_fns = VectorParam.String([], "functions broken down and binned") From d2ee20073bcfa93988d7cfb47079281b58d5aa0a Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Sat, 4 Mar 2006 21:06:40 -0500 Subject: [PATCH 149/180] Emulated syscalls should return -errno on failure (not plain errno). Thanks to Jos Delbar. --HG-- extra : convert_revision : bd15ba1c99f25b8560938566d3922734172ab905 --- sim/syscall_emul.hh | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/sim/syscall_emul.hh b/sim/syscall_emul.hh index f49248dea..eca9f79e0 100644 --- a/sim/syscall_emul.hh +++ b/sim/syscall_emul.hh @@ -380,7 +380,7 @@ chmodFunc(SyscallDesc *desc, int callnum, Process *process, // do the chmod int result = chmod(path.c_str(), hostMode); if (result < 0) - return errno; + return -errno; return 0; } @@ -407,7 +407,7 @@ fchmodFunc(SyscallDesc *desc, int callnum, Process *process, // do the fchmod int result = fchmod(process->sim_fd(fd), hostMode); if (result < 0) - return errno; + return -errno; return 0; } @@ -428,7 +428,7 @@ statFunc(SyscallDesc *desc, int callnum, Process *process, int result = stat(path.c_str(), &hostBuf); if (result < 0) - return errno; + return -errno; OS::copyOutStatBuf(xc->mem, xc->getSyscallArg(1), &hostBuf); @@ -457,7 +457,7 @@ fstat64Func(SyscallDesc *desc, int callnum, Process *process, #endif if (result < 0) - return errno; + return -errno; OS::copyOutStat64Buf(xc->mem, fd, xc->getSyscallArg(1), &hostBuf); @@ -553,7 +553,7 @@ statfsFunc(SyscallDesc *desc, int callnum, Process *process, int result = statfs(path.c_str(), &hostBuf); if (result < 0) - return errno; + return -errno; OS::copyOutStatfsBuf(xc->mem, xc->getSyscallArg(1), &hostBuf); @@ -576,7 +576,7 @@ fstatfsFunc(SyscallDesc *desc, int callnum, Process *process, int result = fstatfs(fd, &hostBuf); if (result < 0) - return errno; + return -errno; OS::copyOutStatfsBuf(xc->mem, xc->getSyscallArg(1), &hostBuf); @@ -618,7 +618,7 @@ writevFunc(SyscallDesc *desc, int callnum, Process *process, } if (result < 0) - return errno; + return -errno; return 0; } From ebd28075abb304bcc9f33873f32a686ffff21604 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sat, 4 Mar 2006 22:30:09 -0500 Subject: [PATCH 150/180] Changed targetarch to arch --HG-- extra : convert_revision : f54d8afd2c7eb338133046e612cddc1d5689a55c --- arch/alpha/system.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/alpha/system.cc b/arch/alpha/system.cc index b841a6d53..460131d43 100644 --- a/arch/alpha/system.cc +++ b/arch/alpha/system.cc @@ -35,7 +35,7 @@ #include "mem/functional/physical.hh" #include "sim/byteswap.hh" #include "sim/builder.hh" -#include "targetarch/vtophys.hh" +#include "arch/vtophys.hh" using namespace LittleEndianGuest; From 9358681756e4ec2cc66062700e8075effebb40dc Mon Sep 17 00:00:00 2001 From: Kevin Lim Date: Sun, 5 Mar 2006 00:13:32 -0500 Subject: [PATCH 151/180] Remove call to swap_palshadow that is no longer needed. arch/alpha/faults.cc: Remove call to swap_palshadow. --HG-- extra : convert_revision : 10282c11080379fc4e8a166ff35d18d728f0d5a4 --- arch/alpha/faults.cc | 3 --- 1 file changed, 3 deletions(-) diff --git a/arch/alpha/faults.cc b/arch/alpha/faults.cc index 0a836363c..84f785c0a 100644 --- a/arch/alpha/faults.cc +++ b/arch/alpha/faults.cc @@ -119,9 +119,6 @@ void AlphaFault::invoke(ExecContext * xc) xc->readMiscReg(AlphaISA::IPR_EXC_ADDR) + 4); } - if (!xc->inPalMode()) - AlphaISA::swap_palshadow(&(xc->regs), true); - xc->regs.pc = xc->readMiscReg(AlphaISA::IPR_PAL_BASE) + vect(); xc->regs.npc = xc->regs.pc + sizeof(MachInst); } From fd69f40e209d1b77ce167bf59c189e513a6815f3 Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Tue, 7 Mar 2006 02:11:11 -0500 Subject: [PATCH 152/180] Rename default options path from "build_options/default" to "default_options", and current options path from "build_options/current" to "options". This way we can symlink default_options to a different build dir w/o clobbering the current options. --HG-- rename : build/build_options/default/ALPHA_FS => build/default_options/ALPHA_FS rename : build/build_options/default/ALPHA_FS_TL => build/default_options/ALPHA_FS_TL rename : build/build_options/default/ALPHA_SE => build/default_options/ALPHA_SE rename : build/build_options/default/MIPS_SE => build/default_options/MIPS_SE rename : build/build_options/default/SPARC_SE => build/default_options/SPARC_SE extra : convert_revision : 8c0d3139cdd7e9ed40a9f2deeb47f65f24e52799 --- build/SConstruct | 6 +++--- build/{build_options/default => default_options}/ALPHA_FS | 0 .../{build_options/default => default_options}/ALPHA_FS_TL | 0 build/{build_options/default => default_options}/ALPHA_SE | 0 build/{build_options/default => default_options}/MIPS_SE | 0 build/{build_options/default => default_options}/SPARC_SE | 0 6 files changed, 3 insertions(+), 3 deletions(-) rename build/{build_options/default => default_options}/ALPHA_FS (100%) rename build/{build_options/default => default_options}/ALPHA_FS_TL (100%) rename build/{build_options/default => default_options}/ALPHA_SE (100%) rename build/{build_options/default => default_options}/MIPS_SE (100%) rename build/{build_options/default => default_options}/SPARC_SE (100%) diff --git a/build/SConstruct b/build/SConstruct index 2d64afb3e..306d3a9dc 100644 --- a/build/SConstruct +++ b/build/SConstruct @@ -341,11 +341,11 @@ for build_dir in build_dirs: sticky_opts.files = [] # Name of default options file is taken from 'default=' on command # line if set, otherwise name of build dir. - default_options_file = os.path.join('build_options', 'default', + default_options_file = os.path.join('default_options', ARGUMENTS.get('default', build_dir)) if os.path.isfile(default_options_file): sticky_opts.files.append(default_options_file) - current_options_file = os.path.join('build_options', 'current', build_dir) + current_options_file = os.path.join('options', build_dir) if os.path.isfile(current_options_file): sticky_opts.files.append(current_options_file) else: @@ -355,7 +355,7 @@ for build_dir in build_dirs: if not os.path.isdir(opt_dir): os.mkdir(opt_dir) if not sticky_opts.files: - print "%s: No options file found in build_options, using defaults." \ + print "%s: No options file found in options, using defaults." \ % build_dir # Apply current option settings to env diff --git a/build/build_options/default/ALPHA_FS b/build/default_options/ALPHA_FS similarity index 100% rename from build/build_options/default/ALPHA_FS rename to build/default_options/ALPHA_FS diff --git a/build/build_options/default/ALPHA_FS_TL b/build/default_options/ALPHA_FS_TL similarity index 100% rename from build/build_options/default/ALPHA_FS_TL rename to build/default_options/ALPHA_FS_TL diff --git a/build/build_options/default/ALPHA_SE b/build/default_options/ALPHA_SE similarity index 100% rename from build/build_options/default/ALPHA_SE rename to build/default_options/ALPHA_SE diff --git a/build/build_options/default/MIPS_SE b/build/default_options/MIPS_SE similarity index 100% rename from build/build_options/default/MIPS_SE rename to build/default_options/MIPS_SE diff --git a/build/build_options/default/SPARC_SE b/build/default_options/SPARC_SE similarity index 100% rename from build/build_options/default/SPARC_SE rename to build/default_options/SPARC_SE From b7ebc2d97f54e1f1cb6a2a7d33daa3d4fe6e0107 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 7 Mar 2006 04:25:42 -0500 Subject: [PATCH 153/180] Moved where some alpha specific source files were mentioned to be in the alpha specific Sconscript, and took advantage of the os specific directories for the process files. arch/sparc/faults.cc: Remove fake fault, fix to have normal m5 line length limit, and change pointers to be const pointers so that the default faults aren't changed accidentally. arch/sparc/faults.hh: Fix to have normal m5 line length limit, change pointers to const pointers. arch/sparc/faults.hh: Added a typedef for the Addr type, and changed the formatting of the faults slightly. arch/sparc/faults.hh: ur Using cleaned up fault class deiffinitions arch/sparc/faults.hh: Added typedef for Addr arch/sparc/faults.hh: Made Addr a global type arch/sparc/faults.cc: arch/sparc/faults.hh: Changed Fault * to Fault, which is a typedef to FaultBase *, which is the old Fault class renamed. arch/sparc/faults.cc: arch/sparc/faults.hh: Changed Fault to be a RefCountingPtr arch/sparc/faults.cc: arch/sparc/faults.hh: MachineCheckFaults and AlignmentFaults are now generated by the ISA, rather than being created directly. arch/sparc/faults.cc: arch/sparc/faults.hh: Put the Alpha faults into the AlphaISA namespace arch/sparc/faults.cc: arch/sparc/faults.hh: Moved the _stat for MachineCheckFault and AlignmentFault into the isa specific classes to prevent instantiation of the generic classes. arch/sparc/faults.cc: arch/sparc/faults.hh: Changed ev5_trap from a function of the execution context to a function of the fault. The actual function still resides in the execution context. arch/sparc/faults.cc: AlphaFault is now an abstract class. arch/sparc/faults.hh: AlphaFault is now an abstract class. Also, AlphaMachineCheckFault and AlphaAlignmentFault multiply inherit from both AlphaFault and from MachineCheckFault and AlignmentFault respectively. These classes get their name from the generic classes. arch/sparc/faults.cc: arch/sparc/faults.hh: moved ev5_trap fully into the fault class. arch/sparc/faults.cc: arch/sparc/faults.hh: Changed the name of the fault's invocation method from ev5_trap to invoke. arch/sparc/faults.cc: arch/sparc/faults.hh: Moved the fault invocation code into the fault class fully, and got rid of the need for isA. arch/sparc/faults.cc: arch/sparc/faults.hh: Got rid of the multiple inheritance in the Fault classes, and the base MachineCheck and Alignment faults. arch/sparc/faults.cc: bk cp ../alpha/faults.cc faults.cc arch/sparc/faults.hh: bk cp ../alpha/faults.hh faults.hh SConscript: Moved the alpha specific source files into the alpha specific SConscript arch/alpha/SConscript: Moved the alpha specific source files into the alpha specific SConscript, and moved the process files into the new os specific subfolders. arch/alpha/linux/process.cc: arch/alpha/process.hh: arch/sparc/process.hh: arch/alpha/tru64/process.cc: Changed the include paths to use the new os specific directories. --HG-- rename : arch/alpha/linux_process.cc => arch/alpha/linux/process.cc rename : arch/alpha/linux_process.hh => arch/alpha/linux/process.hh rename : arch/alpha/tru64_process.cc => arch/alpha/tru64/process.cc rename : arch/alpha/tru64_process.hh => arch/alpha/tru64/process.hh rename : arch/sparc/linux_process.cc => arch/sparc/linux/process.cc rename : arch/sparc/linux_process.hh => arch/sparc/linux/process.hh extra : convert_revision : dc7eed7994b9c5e7308c771f43758292e78ce3e3 --- SConscript | 5 - arch/alpha/SConscript | 8 +- .../{linux_process.cc => linux/process.cc} | 2 +- .../{linux_process.hh => linux/process.hh} | 0 arch/alpha/process.hh | 4 +- .../{tru64_process.cc => tru64/process.cc} | 2 +- .../{tru64_process.hh => tru64/process.hh} | 0 arch/sparc/faults.cc | 170 +++++++++++ arch/sparc/faults.hh | 268 ++++++++++++++++++ .../{linux_process.cc => linux/process.cc} | 0 .../{linux_process.hh => linux/process.hh} | 0 arch/sparc/process.hh | 2 +- 12 files changed, 449 insertions(+), 12 deletions(-) rename arch/alpha/{linux_process.cc => linux/process.cc} (99%) rename arch/alpha/{linux_process.hh => linux/process.hh} (100%) rename arch/alpha/{tru64_process.cc => tru64/process.cc} (99%) rename arch/alpha/{tru64_process.hh => tru64/process.hh} (100%) create mode 100644 arch/sparc/faults.cc create mode 100644 arch/sparc/faults.hh rename arch/sparc/{linux_process.cc => linux/process.cc} (100%) rename arch/sparc/{linux_process.hh => linux/process.hh} (100%) diff --git a/SConscript b/SConscript index efcb2baf6..ce95b28fe 100644 --- a/SConscript +++ b/SConscript @@ -212,11 +212,6 @@ mysql_sources = Split(''' # Full-system sources full_system_sources = Split(''' - arch/alpha/freebsd/system.cc - arch/alpha/linux/system.cc - arch/alpha/system.cc - arch/alpha/tru64/system.cc - base/crc.cc base/inet.cc base/remote_gdb.cc diff --git a/arch/alpha/SConscript b/arch/alpha/SConscript index 03d73eef7..6dec2d070 100644 --- a/arch/alpha/SConscript +++ b/arch/alpha/SConscript @@ -56,14 +56,18 @@ full_system_sources = Split(''' osfpal.cc stacktrace.cc vtophys.cc + system.cc + freebsd/system.cc + linux/system.cc + tru64/system.cc ''') # Syscall emulation (non-full-system) sources syscall_emulation_sources = Split(''' common_syscall_emul.cc - linux_process.cc - tru64_process.cc + linux/process.cc + tru64/process.cc process.cc ''') diff --git a/arch/alpha/linux_process.cc b/arch/alpha/linux/process.cc similarity index 99% rename from arch/alpha/linux_process.cc rename to arch/alpha/linux/process.cc index 0b193fb55..d78e6a4ee 100644 --- a/arch/alpha/linux_process.cc +++ b/arch/alpha/linux/process.cc @@ -27,7 +27,7 @@ */ #include "arch/alpha/common_syscall_emul.hh" -#include "arch/alpha/linux_process.hh" +#include "arch/alpha/linux/process.hh" #include "arch/alpha/isa_traits.hh" #include "base/trace.hh" diff --git a/arch/alpha/linux_process.hh b/arch/alpha/linux/process.hh similarity index 100% rename from arch/alpha/linux_process.hh rename to arch/alpha/linux/process.hh diff --git a/arch/alpha/process.hh b/arch/alpha/process.hh index 7b660ddd0..4a2a4212e 100644 --- a/arch/alpha/process.hh +++ b/arch/alpha/process.hh @@ -31,8 +31,8 @@ #include -#include "arch/alpha/linux_process.hh" -#include "arch/alpha/tru64_process.hh" +#include "arch/alpha/linux/process.hh" +#include "arch/alpha/tru64/process.hh" #include "base/loader/object_file.hh" namespace AlphaISA diff --git a/arch/alpha/tru64_process.cc b/arch/alpha/tru64/process.cc similarity index 99% rename from arch/alpha/tru64_process.cc rename to arch/alpha/tru64/process.cc index 90e8b1139..58d41e3ef 100644 --- a/arch/alpha/tru64_process.cc +++ b/arch/alpha/tru64/process.cc @@ -28,7 +28,7 @@ #include "arch/alpha/isa_traits.hh" #include "arch/alpha/common_syscall_emul.hh" -#include "arch/alpha/tru64_process.hh" +#include "arch/alpha/tru64/process.hh" #include "cpu/exec_context.hh" #include "kern/tru64/tru64.hh" #include "mem/functional/functional.hh" diff --git a/arch/alpha/tru64_process.hh b/arch/alpha/tru64/process.hh similarity index 100% rename from arch/alpha/tru64_process.hh rename to arch/alpha/tru64/process.hh diff --git a/arch/sparc/faults.cc b/arch/sparc/faults.cc new file mode 100644 index 000000000..0a836363c --- /dev/null +++ b/arch/sparc/faults.cc @@ -0,0 +1,170 @@ +/* + * 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/alpha/faults.hh" +#include "cpu/exec_context.hh" +#include "cpu/base.hh" +#include "base/trace.hh" +#include "kern/kernel_stats.hh" + +namespace AlphaISA +{ + +FaultName MachineCheckFault::_name = "mchk"; +FaultVect MachineCheckFault::_vect = 0x0401; +FaultStat MachineCheckFault::_stat; + +FaultName AlignmentFault::_name = "unalign"; +FaultVect AlignmentFault::_vect = 0x0301; +FaultStat AlignmentFault::_stat; + +FaultName ResetFault::_name = "reset"; +FaultVect ResetFault::_vect = 0x0001; +FaultStat ResetFault::_stat; + +FaultName ArithmeticFault::_name = "arith"; +FaultVect ArithmeticFault::_vect = 0x0501; +FaultStat ArithmeticFault::_stat; + +FaultName InterruptFault::_name = "interrupt"; +FaultVect InterruptFault::_vect = 0x0101; +FaultStat InterruptFault::_stat; + +FaultName NDtbMissFault::_name = "dtb_miss_single"; +FaultVect NDtbMissFault::_vect = 0x0201; +FaultStat NDtbMissFault::_stat; + +FaultName PDtbMissFault::_name = "dtb_miss_double"; +FaultVect PDtbMissFault::_vect = 0x0281; +FaultStat PDtbMissFault::_stat; + +FaultName DtbPageFault::_name = "dfault"; +FaultVect DtbPageFault::_vect = 0x0381; +FaultStat DtbPageFault::_stat; + +FaultName DtbAcvFault::_name = "dfault"; +FaultVect DtbAcvFault::_vect = 0x0381; +FaultStat DtbAcvFault::_stat; + +FaultName ItbMissFault::_name = "itbmiss"; +FaultVect ItbMissFault::_vect = 0x0181; +FaultStat ItbMissFault::_stat; + +FaultName ItbPageFault::_name = "itbmiss"; +FaultVect ItbPageFault::_vect = 0x0181; +FaultStat ItbPageFault::_stat; + +FaultName ItbAcvFault::_name = "iaccvio"; +FaultVect ItbAcvFault::_vect = 0x0081; +FaultStat ItbAcvFault::_stat; + +FaultName UnimplementedOpcodeFault::_name = "opdec"; +FaultVect UnimplementedOpcodeFault::_vect = 0x0481; +FaultStat UnimplementedOpcodeFault::_stat; + +FaultName FloatEnableFault::_name = "fen"; +FaultVect FloatEnableFault::_vect = 0x0581; +FaultStat FloatEnableFault::_stat; + +FaultName PalFault::_name = "pal"; +FaultVect PalFault::_vect = 0x2001; +FaultStat PalFault::_stat; + +FaultName IntegerOverflowFault::_name = "intover"; +FaultVect IntegerOverflowFault::_vect = 0x0501; +FaultStat IntegerOverflowFault::_stat; + +#if FULL_SYSTEM + +void AlphaFault::invoke(ExecContext * xc) +{ + DPRINTF(Fault, "Fault %s at PC: %#x\n", name(), xc->regs.pc); + xc->cpu->recordEvent(csprintf("Fault %s", name())); + + assert(!xc->misspeculating()); + xc->kernelStats->fault(this); + + // exception restart address + if (setRestartAddress() || !xc->inPalMode()) + xc->setMiscReg(AlphaISA::IPR_EXC_ADDR, xc->regs.pc); + + if (skipFaultingInstruction()) { + // traps... skip faulting instruction. + xc->setMiscReg(AlphaISA::IPR_EXC_ADDR, + xc->readMiscReg(AlphaISA::IPR_EXC_ADDR) + 4); + } + + if (!xc->inPalMode()) + AlphaISA::swap_palshadow(&(xc->regs), true); + + xc->regs.pc = xc->readMiscReg(AlphaISA::IPR_PAL_BASE) + vect(); + xc->regs.npc = xc->regs.pc + sizeof(MachInst); +} + +void ArithmeticFault::invoke(ExecContext * xc) +{ + DPRINTF(Fault, "Fault %s at PC: %#x\n", name(), xc->regs.pc); + xc->cpu->recordEvent(csprintf("Fault %s", name())); + + assert(!xc->misspeculating()); + xc->kernelStats->fault(this); + + panic("Arithmetic traps are unimplemented!"); +} + + +/*void ArithmeticFault::invoke(ExecContext * xc) +{ + panic("Arithmetic traps are unimplemented!"); +}*/ + +#endif + +} // namespace AlphaISA + +/*Fault * ListOfFaults[] = { + (Fault *)&NoFault, + (Fault *)&ResetFault, + (Fault *)&MachineCheckFault, + (Fault *)&ArithmeticFault, + (Fault *)&InterruptFault, + (Fault *)&NDtbMissFault, + (Fault *)&PDtbMissFault, + (Fault *)&AlignmentFault, + (Fault *)&DtbPageFault, + (Fault *)&DtbAcvFault, + (Fault *)&ItbMissFault, + (Fault *)&ItbPageFault, + (Fault *)&ItbAcvFault, + (Fault *)&UnimplementedOpcodeFault, + (Fault *)&FloatEnableFault, + (Fault *)&PalFault, + (Fault *)&IntegerOverflowFault, + }; + +int NumFaults = sizeof(ListOfFaults) / sizeof(Fault *);*/ diff --git a/arch/sparc/faults.hh b/arch/sparc/faults.hh new file mode 100644 index 000000000..c4a72e07c --- /dev/null +++ b/arch/sparc/faults.hh @@ -0,0 +1,268 @@ +/* + * 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 __ALPHA_FAULTS_HH__ +#define __ALPHA_FAULTS_HH__ + +#include "sim/faults.hh" + +// The design of the "name" and "vect" functions is in sim/faults.hh + +namespace AlphaISA +{ + +typedef const Addr FaultVect; + +class AlphaFault : public virtual FaultBase +{ + protected: + virtual bool skipFaultingInstruction() {return false;} + virtual bool setRestartAddress() {return true;} + public: +#if FULL_SYSTEM + void invoke(ExecContext * xc); +#endif + virtual FaultVect vect() = 0; +}; + +class MachineCheckFault : public AlphaFault +{ + private: + static FaultName _name; + static FaultVect _vect; + static FaultStat _stat; + public: + FaultName name() {return _name;} + FaultVect vect() {return _vect;} + FaultStat & stat() {return _stat;} + bool isMachineCheckFault() {return true;} +}; + +class AlignmentFault : public AlphaFault +{ + private: + static FaultName _name; + static FaultVect _vect; + static FaultStat _stat; + public: + FaultName name() {return _name;} + FaultVect vect() {return _vect;} + FaultStat & stat() {return _stat;} + bool isAlignmentFault() {return true;} +}; + +static inline Fault genMachineCheckFault() +{ + return new MachineCheckFault; +} + +static inline Fault genAlignmentFault() +{ + return new AlignmentFault; +} + +class ResetFault : public AlphaFault +{ + private: + static FaultName _name; + static FaultVect _vect; + static FaultStat _stat; + public: + FaultName name() {return _name;} + FaultVect vect() {return _vect;} + FaultStat & stat() {return _stat;} +}; + +class ArithmeticFault : public AlphaFault +{ + protected: + bool skipFaultingInstruction() {return true;} + private: + static FaultName _name; + static FaultVect _vect; + static FaultStat _stat; + public: + FaultName name() {return _name;} + FaultVect vect() {return _vect;} + FaultStat & stat() {return _stat;} +#if FULL_SYSTEM + void invoke(ExecContext * xc); +#endif +}; + +class InterruptFault : public AlphaFault +{ + protected: + bool setRestartAddress() {return false;} + private: + static FaultName _name; + static FaultVect _vect; + static FaultStat _stat; + public: + FaultName name() {return _name;} + FaultVect vect() {return _vect;} + FaultStat & stat() {return _stat;} +}; + +class NDtbMissFault : public AlphaFault +{ + private: + static FaultName _name; + static FaultVect _vect; + static FaultStat _stat; + public: + FaultName name() {return _name;} + FaultVect vect() {return _vect;} + FaultStat & stat() {return _stat;} +}; + +class PDtbMissFault : public AlphaFault +{ + private: + static FaultName _name; + static FaultVect _vect; + static FaultStat _stat; + public: + FaultName name() {return _name;} + FaultVect vect() {return _vect;} + FaultStat & stat() {return _stat;} +}; + +class DtbPageFault : public AlphaFault +{ + private: + static FaultName _name; + static FaultVect _vect; + static FaultStat _stat; + public: + FaultName name() {return _name;} + FaultVect vect() {return _vect;} + FaultStat & stat() {return _stat;} +}; + +class DtbAcvFault : public AlphaFault +{ + private: + static FaultName _name; + static FaultVect _vect; + static FaultStat _stat; + public: + FaultName name() {return _name;} + FaultVect vect() {return _vect;} + FaultStat & stat() {return _stat;} +}; + +class ItbMissFault : public AlphaFault +{ + private: + static FaultName _name; + static FaultVect _vect; + static FaultStat _stat; + public: + FaultName name() {return _name;} + FaultVect vect() {return _vect;} + FaultStat & stat() {return _stat;} +}; + +class ItbPageFault : public AlphaFault +{ + private: + static FaultName _name; + static FaultVect _vect; + static FaultStat _stat; + public: + FaultName name() {return _name;} + FaultVect vect() {return _vect;} + FaultStat & stat() {return _stat;} +}; + +class ItbAcvFault : public AlphaFault +{ + private: + static FaultName _name; + static FaultVect _vect; + static FaultStat _stat; + public: + FaultName name() {return _name;} + FaultVect vect() {return _vect;} + FaultStat & stat() {return _stat;} +}; + +class UnimplementedOpcodeFault : public AlphaFault +{ + private: + static FaultName _name; + static FaultVect _vect; + static FaultStat _stat; + public: + FaultName name() {return _name;} + FaultVect vect() {return _vect;} + FaultStat & stat() {return _stat;} +}; + +class FloatEnableFault : public AlphaFault +{ + private: + static FaultName _name; + static FaultVect _vect; + static FaultStat _stat; + public: + FaultName name() {return _name;} + FaultVect vect() {return _vect;} + FaultStat & stat() {return _stat;} +}; + +class PalFault : public AlphaFault +{ + protected: + bool skipFaultingInstruction() {return true;} + private: + static FaultName _name; + static FaultVect _vect; + static FaultStat _stat; + public: + FaultName name() {return _name;} + FaultVect vect() {return _vect;} + FaultStat & stat() {return _stat;} +}; + +class IntegerOverflowFault : public AlphaFault +{ + private: + static FaultName _name; + static FaultVect _vect; + static FaultStat _stat; + public: + FaultName name() {return _name;} + FaultVect vect() {return _vect;} + FaultStat & stat() {return _stat;} +}; + +} // AlphaISA namespace + +#endif // __FAULTS_HH__ diff --git a/arch/sparc/linux_process.cc b/arch/sparc/linux/process.cc similarity index 100% rename from arch/sparc/linux_process.cc rename to arch/sparc/linux/process.cc diff --git a/arch/sparc/linux_process.hh b/arch/sparc/linux/process.hh similarity index 100% rename from arch/sparc/linux_process.hh rename to arch/sparc/linux/process.hh diff --git a/arch/sparc/process.hh b/arch/sparc/process.hh index 387649d47..48041a316 100644 --- a/arch/sparc/process.hh +++ b/arch/sparc/process.hh @@ -29,7 +29,7 @@ #ifndef __SPARC_PROCESS_HH__ #define __SPARC_PROCESS_HH__ -#include "arch/sparc/linux_process.hh" +#include "arch/sparc/linux/process.hh" #include "base/loader/object_file.hh" namespace SparcISA From b5111285078cf790a2330c725b63fbc1f791db14 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 7 Mar 2006 04:31:38 -0500 Subject: [PATCH 154/180] Some clean up work with faults. arch/alpha/faults.cc: Renamed the _stat stat to a more descriptive _count, got rid of some old commented out code, and moved common fault handling code, ie recording that the fault happend and that it wasn't mispeculated, into the FaultBase class. arch/alpha/faults.hh: Renamed the _stat stat to the more descriptive _count, and renamed the appropriate accessor functions. kern/kernel_stats.cc: kern/kernel_stats.hh: The fault statistics are now handled by the fault classes themselves. sim/faults.cc: The default implementation of the "invoke" method now does what all faults should do first, ie record that the fault happened, and make sure the fault isn't being executed on a mispeculated execution path. sim/faults.hh: There is now a default implementation of invoke, and the stat function is taken care of in the architecture specific fault classes. --HG-- extra : convert_revision : f6656fbea991df9addf85cad740ac37b1036b71a --- arch/alpha/faults.cc | 74 ++++++++++++-------------------------------- arch/alpha/faults.hh | 67 +++++++++++++++++++-------------------- kern/kernel_stats.cc | 13 -------- kern/kernel_stats.hh | 5 --- sim/faults.cc | 9 ++++++ sim/faults.hh | 3 +- 6 files changed, 63 insertions(+), 108 deletions(-) diff --git a/arch/alpha/faults.cc b/arch/alpha/faults.cc index 0a836363c..c840b6842 100644 --- a/arch/alpha/faults.cc +++ b/arch/alpha/faults.cc @@ -30,84 +30,80 @@ #include "cpu/exec_context.hh" #include "cpu/base.hh" #include "base/trace.hh" -#include "kern/kernel_stats.hh" namespace AlphaISA { FaultName MachineCheckFault::_name = "mchk"; FaultVect MachineCheckFault::_vect = 0x0401; -FaultStat MachineCheckFault::_stat; +FaultStat MachineCheckFault::_count; FaultName AlignmentFault::_name = "unalign"; FaultVect AlignmentFault::_vect = 0x0301; -FaultStat AlignmentFault::_stat; +FaultStat AlignmentFault::_count; FaultName ResetFault::_name = "reset"; FaultVect ResetFault::_vect = 0x0001; -FaultStat ResetFault::_stat; +FaultStat ResetFault::_count; FaultName ArithmeticFault::_name = "arith"; FaultVect ArithmeticFault::_vect = 0x0501; -FaultStat ArithmeticFault::_stat; +FaultStat ArithmeticFault::_count; FaultName InterruptFault::_name = "interrupt"; FaultVect InterruptFault::_vect = 0x0101; -FaultStat InterruptFault::_stat; +FaultStat InterruptFault::_count; FaultName NDtbMissFault::_name = "dtb_miss_single"; FaultVect NDtbMissFault::_vect = 0x0201; -FaultStat NDtbMissFault::_stat; +FaultStat NDtbMissFault::_count; FaultName PDtbMissFault::_name = "dtb_miss_double"; FaultVect PDtbMissFault::_vect = 0x0281; -FaultStat PDtbMissFault::_stat; +FaultStat PDtbMissFault::_count; FaultName DtbPageFault::_name = "dfault"; FaultVect DtbPageFault::_vect = 0x0381; -FaultStat DtbPageFault::_stat; +FaultStat DtbPageFault::_count; FaultName DtbAcvFault::_name = "dfault"; FaultVect DtbAcvFault::_vect = 0x0381; -FaultStat DtbAcvFault::_stat; +FaultStat DtbAcvFault::_count; FaultName ItbMissFault::_name = "itbmiss"; FaultVect ItbMissFault::_vect = 0x0181; -FaultStat ItbMissFault::_stat; +FaultStat ItbMissFault::_count; FaultName ItbPageFault::_name = "itbmiss"; FaultVect ItbPageFault::_vect = 0x0181; -FaultStat ItbPageFault::_stat; +FaultStat ItbPageFault::_count; FaultName ItbAcvFault::_name = "iaccvio"; FaultVect ItbAcvFault::_vect = 0x0081; -FaultStat ItbAcvFault::_stat; +FaultStat ItbAcvFault::_count; FaultName UnimplementedOpcodeFault::_name = "opdec"; FaultVect UnimplementedOpcodeFault::_vect = 0x0481; -FaultStat UnimplementedOpcodeFault::_stat; +FaultStat UnimplementedOpcodeFault::_count; FaultName FloatEnableFault::_name = "fen"; FaultVect FloatEnableFault::_vect = 0x0581; -FaultStat FloatEnableFault::_stat; +FaultStat FloatEnableFault::_count; FaultName PalFault::_name = "pal"; FaultVect PalFault::_vect = 0x2001; -FaultStat PalFault::_stat; +FaultStat PalFault::_count; FaultName IntegerOverflowFault::_name = "intover"; FaultVect IntegerOverflowFault::_vect = 0x0501; -FaultStat IntegerOverflowFault::_stat; +FaultStat IntegerOverflowFault::_count; #if FULL_SYSTEM void AlphaFault::invoke(ExecContext * xc) { - DPRINTF(Fault, "Fault %s at PC: %#x\n", name(), xc->regs.pc); - xc->cpu->recordEvent(csprintf("Fault %s", name())); - - assert(!xc->misspeculating()); - xc->kernelStats->fault(this); + FaultBase::invoke(xc); + countStat()++; // exception restart address if (setRestartAddress() || !xc->inPalMode()) @@ -128,43 +124,11 @@ void AlphaFault::invoke(ExecContext * xc) void ArithmeticFault::invoke(ExecContext * xc) { - DPRINTF(Fault, "Fault %s at PC: %#x\n", name(), xc->regs.pc); - xc->cpu->recordEvent(csprintf("Fault %s", name())); - - assert(!xc->misspeculating()); - xc->kernelStats->fault(this); - + FaultBase::invoke(xc); panic("Arithmetic traps are unimplemented!"); } - -/*void ArithmeticFault::invoke(ExecContext * xc) -{ - panic("Arithmetic traps are unimplemented!"); -}*/ - #endif } // namespace AlphaISA -/*Fault * ListOfFaults[] = { - (Fault *)&NoFault, - (Fault *)&ResetFault, - (Fault *)&MachineCheckFault, - (Fault *)&ArithmeticFault, - (Fault *)&InterruptFault, - (Fault *)&NDtbMissFault, - (Fault *)&PDtbMissFault, - (Fault *)&AlignmentFault, - (Fault *)&DtbPageFault, - (Fault *)&DtbAcvFault, - (Fault *)&ItbMissFault, - (Fault *)&ItbPageFault, - (Fault *)&ItbAcvFault, - (Fault *)&UnimplementedOpcodeFault, - (Fault *)&FloatEnableFault, - (Fault *)&PalFault, - (Fault *)&IntegerOverflowFault, - }; - -int NumFaults = sizeof(ListOfFaults) / sizeof(Fault *);*/ diff --git a/arch/alpha/faults.hh b/arch/alpha/faults.hh index c4a72e07c..1a196cc94 100644 --- a/arch/alpha/faults.hh +++ b/arch/alpha/faults.hh @@ -38,7 +38,7 @@ namespace AlphaISA typedef const Addr FaultVect; -class AlphaFault : public virtual FaultBase +class AlphaFault : public FaultBase { protected: virtual bool skipFaultingInstruction() {return false;} @@ -48,6 +48,7 @@ class AlphaFault : public virtual FaultBase void invoke(ExecContext * xc); #endif virtual FaultVect vect() = 0; + virtual FaultStat & countStat() = 0; }; class MachineCheckFault : public AlphaFault @@ -55,11 +56,11 @@ class MachineCheckFault : public AlphaFault private: static FaultName _name; static FaultVect _vect; - static FaultStat _stat; + static FaultStat _count; public: FaultName name() {return _name;} FaultVect vect() {return _vect;} - FaultStat & stat() {return _stat;} + FaultStat & countStat() {return _count;} bool isMachineCheckFault() {return true;} }; @@ -68,11 +69,11 @@ class AlignmentFault : public AlphaFault private: static FaultName _name; static FaultVect _vect; - static FaultStat _stat; + static FaultStat _count; public: FaultName name() {return _name;} FaultVect vect() {return _vect;} - FaultStat & stat() {return _stat;} + FaultStat & countStat() {return _count;} bool isAlignmentFault() {return true;} }; @@ -91,11 +92,11 @@ class ResetFault : public AlphaFault private: static FaultName _name; static FaultVect _vect; - static FaultStat _stat; + static FaultStat _count; public: FaultName name() {return _name;} FaultVect vect() {return _vect;} - FaultStat & stat() {return _stat;} + FaultStat & countStat() {return _count;} }; class ArithmeticFault : public AlphaFault @@ -105,11 +106,11 @@ class ArithmeticFault : public AlphaFault private: static FaultName _name; static FaultVect _vect; - static FaultStat _stat; + static FaultStat _count; public: FaultName name() {return _name;} FaultVect vect() {return _vect;} - FaultStat & stat() {return _stat;} + FaultStat & countStat() {return _count;} #if FULL_SYSTEM void invoke(ExecContext * xc); #endif @@ -122,11 +123,11 @@ class InterruptFault : public AlphaFault private: static FaultName _name; static FaultVect _vect; - static FaultStat _stat; + static FaultStat _count; public: FaultName name() {return _name;} FaultVect vect() {return _vect;} - FaultStat & stat() {return _stat;} + FaultStat & countStat() {return _count;} }; class NDtbMissFault : public AlphaFault @@ -134,11 +135,11 @@ class NDtbMissFault : public AlphaFault private: static FaultName _name; static FaultVect _vect; - static FaultStat _stat; + static FaultStat _count; public: FaultName name() {return _name;} FaultVect vect() {return _vect;} - FaultStat & stat() {return _stat;} + FaultStat & countStat() {return _count;} }; class PDtbMissFault : public AlphaFault @@ -146,11 +147,11 @@ class PDtbMissFault : public AlphaFault private: static FaultName _name; static FaultVect _vect; - static FaultStat _stat; + static FaultStat _count; public: FaultName name() {return _name;} FaultVect vect() {return _vect;} - FaultStat & stat() {return _stat;} + FaultStat & countStat() {return _count;} }; class DtbPageFault : public AlphaFault @@ -158,11 +159,11 @@ class DtbPageFault : public AlphaFault private: static FaultName _name; static FaultVect _vect; - static FaultStat _stat; + static FaultStat _count; public: FaultName name() {return _name;} FaultVect vect() {return _vect;} - FaultStat & stat() {return _stat;} + FaultStat & countStat() {return _count;} }; class DtbAcvFault : public AlphaFault @@ -170,11 +171,11 @@ class DtbAcvFault : public AlphaFault private: static FaultName _name; static FaultVect _vect; - static FaultStat _stat; + static FaultStat _count; public: FaultName name() {return _name;} FaultVect vect() {return _vect;} - FaultStat & stat() {return _stat;} + FaultStat & countStat() {return _count;} }; class ItbMissFault : public AlphaFault @@ -182,11 +183,11 @@ class ItbMissFault : public AlphaFault private: static FaultName _name; static FaultVect _vect; - static FaultStat _stat; + static FaultStat _count; public: FaultName name() {return _name;} FaultVect vect() {return _vect;} - FaultStat & stat() {return _stat;} + FaultStat & countStat() {return _count;} }; class ItbPageFault : public AlphaFault @@ -194,11 +195,11 @@ class ItbPageFault : public AlphaFault private: static FaultName _name; static FaultVect _vect; - static FaultStat _stat; + static FaultStat _count; public: FaultName name() {return _name;} FaultVect vect() {return _vect;} - FaultStat & stat() {return _stat;} + FaultStat & countStat() {return _count;} }; class ItbAcvFault : public AlphaFault @@ -206,11 +207,11 @@ class ItbAcvFault : public AlphaFault private: static FaultName _name; static FaultVect _vect; - static FaultStat _stat; + static FaultStat _count; public: FaultName name() {return _name;} FaultVect vect() {return _vect;} - FaultStat & stat() {return _stat;} + FaultStat & countStat() {return _count;} }; class UnimplementedOpcodeFault : public AlphaFault @@ -218,11 +219,11 @@ class UnimplementedOpcodeFault : public AlphaFault private: static FaultName _name; static FaultVect _vect; - static FaultStat _stat; + static FaultStat _count; public: FaultName name() {return _name;} FaultVect vect() {return _vect;} - FaultStat & stat() {return _stat;} + FaultStat & countStat() {return _count;} }; class FloatEnableFault : public AlphaFault @@ -230,11 +231,11 @@ class FloatEnableFault : public AlphaFault private: static FaultName _name; static FaultVect _vect; - static FaultStat _stat; + static FaultStat _count; public: FaultName name() {return _name;} FaultVect vect() {return _vect;} - FaultStat & stat() {return _stat;} + FaultStat & countStat() {return _count;} }; class PalFault : public AlphaFault @@ -244,11 +245,11 @@ class PalFault : public AlphaFault private: static FaultName _name; static FaultVect _vect; - static FaultStat _stat; + static FaultStat _count; public: FaultName name() {return _name;} FaultVect vect() {return _vect;} - FaultStat & stat() {return _stat;} + FaultStat & countStat() {return _count;} }; class IntegerOverflowFault : public AlphaFault @@ -256,11 +257,11 @@ class IntegerOverflowFault : public AlphaFault private: static FaultName _name; static FaultVect _vect; - static FaultStat _stat; + static FaultStat _count; public: FaultName name() {return _name;} FaultVect vect() {return _vect;} - FaultStat & stat() {return _stat;} + FaultStat & countStat() {return _count;} }; } // AlphaISA namespace diff --git a/kern/kernel_stats.cc b/kern/kernel_stats.cc index 33485ca15..f898dad94 100644 --- a/kern/kernel_stats.cc +++ b/kern/kernel_stats.cc @@ -136,19 +136,6 @@ Statistics::regStats(const string &_name) } } -/* _faults - .init(NumFaults) - .name(name() + ".faults") - .desc("number of faults") - .flags(total | pdf | nozero | nonan) - ; - - for (int i = 1; i < NumFaults; ++i) { - const char *str = (*ListOfFaults[i])->name; - if (str) - _faults.subname(i, str); - }*/ - _mode .init(cpu_mode_num) .name(name() + ".mode_switch") diff --git a/kern/kernel_stats.hh b/kern/kernel_stats.hh index 4896a0705..830bfe09d 100644 --- a/kern/kernel_stats.hh +++ b/kern/kernel_stats.hh @@ -176,11 +176,6 @@ class Statistics : public Serializable void ivlb() { _ivlb++; } void ivle() { _ivle++; } void hwrei() { _hwrei++; } - void fault(Fault fault) - { - if(fault != NoFault) - fault->stat()++; - }// FIXME: When there are no generic system fault objects, this will go back to _faults[fault]++; } void swpipl(int ipl); void mode(cpu_mode newmode); void context(Addr oldpcbb, Addr newpcbb); diff --git a/sim/faults.cc b/sim/faults.cc index 9b4a0ea7f..2b93353ce 100644 --- a/sim/faults.cc +++ b/sim/faults.cc @@ -28,10 +28,19 @@ #include "sim/faults.hh" #include "cpu/exec_context.hh" +#include "cpu/base.hh" #if !FULL_SYSTEM void FaultBase::invoke(ExecContext * xc) { fatal("fault (%s) detected @ PC 0x%08p", name(), xc->readPC()); } +#else +void FaultBase::invoke(ExecContext * xc) +{ + DPRINTF(Fault, "Fault %s at PC: %#x\n", name(), xc->regs.pc); + xc->cpu->recordEvent(csprintf("Fault %s", name())); + + assert(!xc->misspeculating()); +} #endif diff --git a/sim/faults.hh b/sim/faults.hh index 9e8d224cd..18601e8f1 100644 --- a/sim/faults.hh +++ b/sim/faults.hh @@ -51,9 +51,8 @@ class FaultBase : public RefCounted { public: virtual FaultName name() = 0; - virtual FaultStat & stat() = 0; #if FULL_SYSTEM - virtual void invoke(ExecContext * xc) = 0; + virtual void invoke(ExecContext * xc); #else virtual void invoke(ExecContext * xc); #endif From d4b246b3e9b78a77f021c6c155313abb28fa2cb9 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 7 Mar 2006 04:32:34 -0500 Subject: [PATCH 155/180] Implemented SPARC fault classes. arch/sparc/faults.cc: arch/sparc/faults.hh: Implemented the SPARC fault classes. The invoke method still needs to be written, but this depends on the misc regfile. --HG-- extra : convert_revision : bc9d2785600cee5ea1cba72e563ca5d1a20f37fd --- arch/sparc/faults.cc | 274 +++++++++++++------- arch/sparc/faults.hh | 591 +++++++++++++++++++++++++++++++++---------- 2 files changed, 631 insertions(+), 234 deletions(-) diff --git a/arch/sparc/faults.cc b/arch/sparc/faults.cc index 0a836363c..b48fc600b 100644 --- a/arch/sparc/faults.cc +++ b/arch/sparc/faults.cc @@ -26,90 +26,206 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "arch/alpha/faults.hh" +#include "arch/sparc/faults.hh" #include "cpu/exec_context.hh" #include "cpu/base.hh" #include "base/trace.hh" -#include "kern/kernel_stats.hh" -namespace AlphaISA +namespace SparcISA { -FaultName MachineCheckFault::_name = "mchk"; -FaultVect MachineCheckFault::_vect = 0x0401; -FaultStat MachineCheckFault::_stat; +FaultName InternalProcessorError::_name = "intprocerr"; +TrapType InternalProcessorError::_trapType = 0x029; +FaultPriority InternalProcessorError::_priority = 4; +FaultStat InternalProcessorError::_count; -FaultName AlignmentFault::_name = "unalign"; -FaultVect AlignmentFault::_vect = 0x0301; -FaultStat AlignmentFault::_stat; +FaultName MemAddressNotAligned::_name = "unalign"; +TrapType MemAddressNotAligned::_trapType = 0x034; +FaultPriority MemAddressNotAligned::_priority = 10; +FaultStat MemAddressNotAligned::_count; -FaultName ResetFault::_name = "reset"; -FaultVect ResetFault::_vect = 0x0001; -FaultStat ResetFault::_stat; +FaultName PowerOnReset::_name = "pow_reset"; +TrapType PowerOnReset::_trapType = 0x001; +FaultPriority PowerOnReset::_priority = 0; +FaultStat PowerOnReset::_count; -FaultName ArithmeticFault::_name = "arith"; -FaultVect ArithmeticFault::_vect = 0x0501; -FaultStat ArithmeticFault::_stat; +FaultName WatchDogReset::_name = "watch_dog_reset"; +TrapType WatchDogReset::_trapType = 0x002; +FaultPriority WatchDogReset::_priority = 1; +FaultStat WatchDogReset::_count; -FaultName InterruptFault::_name = "interrupt"; -FaultVect InterruptFault::_vect = 0x0101; -FaultStat InterruptFault::_stat; +FaultName ExternallyInitiatedReset::_name = "extern_reset"; +TrapType ExternallyInitiatedReset::_trapType = 0x003; +FaultPriority ExternallyInitiatedReset::_priority = 1; +FaultStat ExternallyInitiatedReset::_count; -FaultName NDtbMissFault::_name = "dtb_miss_single"; -FaultVect NDtbMissFault::_vect = 0x0201; -FaultStat NDtbMissFault::_stat; +FaultName SoftwareInitiatedReset::_name = "software_reset"; +TrapType SoftwareInitiatedReset::_trapType = 0x004; +FaultPriority SoftwareInitiatedReset::_priority = 1; +FaultStat SoftwareInitiatedReset::_count; -FaultName PDtbMissFault::_name = "dtb_miss_double"; -FaultVect PDtbMissFault::_vect = 0x0281; -FaultStat PDtbMissFault::_stat; +FaultName REDStateException::_name = "red_counte"; +TrapType REDStateException::_trapType = 0x005; +FaultPriority REDStateException::_priority = 1; +FaultStat REDStateException::_count; -FaultName DtbPageFault::_name = "dfault"; -FaultVect DtbPageFault::_vect = 0x0381; -FaultStat DtbPageFault::_stat; +FaultName InstructionAccessException::_name = "inst_access"; +TrapType InstructionAccessException::_trapType = 0x008; +FaultPriority InstructionAccessException::_priority = 5; +FaultStat InstructionAccessException::_count; -FaultName DtbAcvFault::_name = "dfault"; -FaultVect DtbAcvFault::_vect = 0x0381; -FaultStat DtbAcvFault::_stat; +FaultName InstructionAccessMMUMiss::_name = "inst_mmu"; +TrapType InstructionAccessMMUMiss::_trapType = 0x009; +FaultPriority InstructionAccessMMUMiss::_priority = 2; +FaultStat InstructionAccessMMUMiss::_count; -FaultName ItbMissFault::_name = "itbmiss"; -FaultVect ItbMissFault::_vect = 0x0181; -FaultStat ItbMissFault::_stat; +FaultName InstructionAccessError::_name = "inst_error"; +TrapType InstructionAccessError::_trapType = 0x00A; +FaultPriority InstructionAccessError::_priority = 3; +FaultStat InstructionAccessError::_count; -FaultName ItbPageFault::_name = "itbmiss"; -FaultVect ItbPageFault::_vect = 0x0181; -FaultStat ItbPageFault::_stat; +FaultName IllegalInstruction::_name = "illegal_inst"; +TrapType IllegalInstruction::_trapType = 0x010; +FaultPriority IllegalInstruction::_priority = 7; +FaultStat IllegalInstruction::_count; -FaultName ItbAcvFault::_name = "iaccvio"; -FaultVect ItbAcvFault::_vect = 0x0081; -FaultStat ItbAcvFault::_stat; +FaultName PrivelegedOpcode::_name = "priv_opcode"; +TrapType PrivelegedOpcode::_trapType = 0x011; +FaultPriority PrivelegedOpcode::_priority = 6; +FaultStat PrivelegedOpcode::_count; -FaultName UnimplementedOpcodeFault::_name = "opdec"; -FaultVect UnimplementedOpcodeFault::_vect = 0x0481; -FaultStat UnimplementedOpcodeFault::_stat; +FaultName UnimplementedLDD::_name = "unimp_ldd"; +TrapType UnimplementedLDD::_trapType = 0x012; +FaultPriority UnimplementedLDD::_priority = 6; +FaultStat UnimplementedLDD::_count; -FaultName FloatEnableFault::_name = "fen"; -FaultVect FloatEnableFault::_vect = 0x0581; -FaultStat FloatEnableFault::_stat; +FaultName UnimplementedSTD::_name = "unimp_std"; +TrapType UnimplementedSTD::_trapType = 0x013; +FaultPriority UnimplementedSTD::_priority = 6; +FaultStat UnimplementedSTD::_count; + +FaultName FpDisabled::_name = "fp_disabled"; +TrapType FpDisabled::_trapType = 0x020; +FaultPriority FpDisabled::_priority = 8; +FaultStat FpDisabled::_count; + +FaultName FpExceptionIEEE754::_name = "fp_754"; +TrapType FpExceptionIEEE754::_trapType = 0x021; +FaultPriority FpExceptionIEEE754::_priority = 11; +FaultStat FpExceptionIEEE754::_count; + +FaultName FpExceptionOther::_name = "fp_other"; +TrapType FpExceptionOther::_trapType = 0x022; +FaultPriority FpExceptionOther::_priority = 11; +FaultStat FpExceptionOther::_count; + +FaultName TagOverflow::_name = "tag_overflow"; +TrapType TagOverflow::_trapType = 0x023; +FaultPriority TagOverflow::_priority = 14; +FaultStat TagOverflow::_count; + +FaultName DivisionByZero::_name = "div_by_zero"; +TrapType DivisionByZero::_trapType = 0x028; +FaultPriority DivisionByZero::_priority = 15; +FaultStat DivisionByZero::_count; + +FaultName DataAccessException::_name = "data_access"; +TrapType DataAccessException::_trapType = 0x030; +FaultPriority DataAccessException::_priority = 12; +FaultStat DataAccessException::_count; + +FaultName DataAccessMMUMiss::_name = "data_mmu"; +TrapType DataAccessMMUMiss::_trapType = 0x031; +FaultPriority DataAccessMMUMiss::_priority = 12; +FaultStat DataAccessMMUMiss::_count; + +FaultName DataAccessError::_name = "data_error"; +TrapType DataAccessError::_trapType = 0x032; +FaultPriority DataAccessError::_priority = 12; +FaultStat DataAccessError::_count; + +FaultName DataAccessProtection::_name = "data_protection"; +TrapType DataAccessProtection::_trapType = 0x033; +FaultPriority DataAccessProtection::_priority = 12; +FaultStat DataAccessProtection::_count; + +FaultName LDDFMemAddressNotAligned::_name = "unalign_lddf"; +TrapType LDDFMemAddressNotAligned::_trapType = 0x035; +FaultPriority LDDFMemAddressNotAligned::_priority = 10; +FaultStat LDDFMemAddressNotAligned::_count; + +FaultName STDFMemAddressNotAligned::_name = "unalign_stdf"; +TrapType STDFMemAddressNotAligned::_trapType = 0x036; +FaultPriority STDFMemAddressNotAligned::_priority = 10; +FaultStat STDFMemAddressNotAligned::_count; + +FaultName PrivelegedAction::_name = "priv_action"; +TrapType PrivelegedAction::_trapType = 0x037; +FaultPriority PrivelegedAction::_priority = 11; +FaultStat PrivelegedAction::_count; + +FaultName LDQFMemAddressNotAligned::_name = "unalign_ldqf"; +TrapType LDQFMemAddressNotAligned::_trapType = 0x038; +FaultPriority LDQFMemAddressNotAligned::_priority = 10; +FaultStat LDQFMemAddressNotAligned::_count; + +FaultName STQFMemAddressNotAligned::_name = "unalign_stqf"; +TrapType STQFMemAddressNotAligned::_trapType = 0x039; +FaultPriority STQFMemAddressNotAligned::_priority = 10; +FaultStat STQFMemAddressNotAligned::_count; + +FaultName AsyncDataError::_name = "async_data"; +TrapType AsyncDataError::_trapType = 0x040; +FaultPriority AsyncDataError::_priority = 2; +FaultStat AsyncDataError::_count; + +//The enumerated faults + +FaultName CleanWindow::_name = "clean_win"; +TrapType CleanWindow::_baseTrapType = 0x024; +FaultPriority CleanWindow::_priority = 10; +FaultStat CleanWindow::_count; + +FaultName InterruptLevelN::_name = "interrupt_n"; +TrapType InterruptLevelN::_baseTrapType = 0x041; +FaultStat InterruptLevelN::_count; + +FaultName SpillNNormal::_name = "spill_n_normal"; +TrapType SpillNNormal::_baseTrapType = 0x080; +FaultPriority SpillNNormal::_priority = 9; +FaultStat SpillNNormal::_count; + +FaultName SpillNOther::_name = "spill_n_other"; +TrapType SpillNOther::_baseTrapType = 0x0A0; +FaultPriority SpillNOther::_priority = 9; +FaultStat SpillNOther::_count; + +FaultName FillNNormal::_name = "fill_n_normal"; +TrapType FillNNormal::_baseTrapType = 0x0C0; +FaultPriority FillNNormal::_priority = 9; +FaultStat FillNNormal::_count; + +FaultName FillNOther::_name = "fill_n_other"; +TrapType FillNOther::_baseTrapType = 0x0E0; +FaultPriority FillNOther::_priority = 9; +FaultStat FillNOther::_count; + +FaultName TrapInstruction::_name = "trap_inst_n"; +TrapType TrapInstruction::_baseTrapType = 0x100; +FaultPriority TrapInstruction::_priority = 16; +FaultStat TrapInstruction::_count; -FaultName PalFault::_name = "pal"; -FaultVect PalFault::_vect = 0x2001; -FaultStat PalFault::_stat; -FaultName IntegerOverflowFault::_name = "intover"; -FaultVect IntegerOverflowFault::_vect = 0x0501; -FaultStat IntegerOverflowFault::_stat; #if FULL_SYSTEM -void AlphaFault::invoke(ExecContext * xc) +void SparcFault::invoke(ExecContext * xc) { - DPRINTF(Fault, "Fault %s at PC: %#x\n", name(), xc->regs.pc); - xc->cpu->recordEvent(csprintf("Fault %s", name())); + FaultBase::invoke(xc); + countStat()++; - assert(!xc->misspeculating()); - xc->kernelStats->fault(this); - - // exception restart address + //Use the SPARC trap state machine + /*// exception restart address if (setRestartAddress() || !xc->inPalMode()) xc->setMiscReg(AlphaISA::IPR_EXC_ADDR, xc->regs.pc); @@ -123,48 +239,10 @@ void AlphaFault::invoke(ExecContext * xc) AlphaISA::swap_palshadow(&(xc->regs), true); xc->regs.pc = xc->readMiscReg(AlphaISA::IPR_PAL_BASE) + vect(); - xc->regs.npc = xc->regs.pc + sizeof(MachInst); + xc->regs.npc = xc->regs.pc + sizeof(MachInst);*/ } -void ArithmeticFault::invoke(ExecContext * xc) -{ - DPRINTF(Fault, "Fault %s at PC: %#x\n", name(), xc->regs.pc); - xc->cpu->recordEvent(csprintf("Fault %s", name())); - - assert(!xc->misspeculating()); - xc->kernelStats->fault(this); - - panic("Arithmetic traps are unimplemented!"); -} - - -/*void ArithmeticFault::invoke(ExecContext * xc) -{ - panic("Arithmetic traps are unimplemented!"); -}*/ - #endif -} // namespace AlphaISA +} // namespace SparcISA -/*Fault * ListOfFaults[] = { - (Fault *)&NoFault, - (Fault *)&ResetFault, - (Fault *)&MachineCheckFault, - (Fault *)&ArithmeticFault, - (Fault *)&InterruptFault, - (Fault *)&NDtbMissFault, - (Fault *)&PDtbMissFault, - (Fault *)&AlignmentFault, - (Fault *)&DtbPageFault, - (Fault *)&DtbAcvFault, - (Fault *)&ItbMissFault, - (Fault *)&ItbPageFault, - (Fault *)&ItbAcvFault, - (Fault *)&UnimplementedOpcodeFault, - (Fault *)&FloatEnableFault, - (Fault *)&PalFault, - (Fault *)&IntegerOverflowFault, - }; - -int NumFaults = sizeof(ListOfFaults) / sizeof(Fault *);*/ diff --git a/arch/sparc/faults.hh b/arch/sparc/faults.hh index c4a72e07c..318b1ad5a 100644 --- a/arch/sparc/faults.hh +++ b/arch/sparc/faults.hh @@ -33,236 +33,555 @@ // The design of the "name" and "vect" functions is in sim/faults.hh -namespace AlphaISA +namespace SparcISA { -typedef const Addr FaultVect; +typedef const uint32_t TrapType; +typedef const uint32_t FaultPriority; -class AlphaFault : public virtual FaultBase +class SparcFault : public FaultBase { - protected: - virtual bool skipFaultingInstruction() {return false;} - virtual bool setRestartAddress() {return true;} public: #if FULL_SYSTEM void invoke(ExecContext * xc); #endif - virtual FaultVect vect() = 0; + virtual TrapType trapType() = 0; + virtual FaultPriority priority() = 0; + virtual FaultStat & countStat() = 0; }; -class MachineCheckFault : public AlphaFault +class InternalProcessorError : public SparcFault { private: static FaultName _name; - static FaultVect _vect; - static FaultStat _stat; + static TrapType _trapType; + static FaultPriority _priority; + static FaultStat _count; public: FaultName name() {return _name;} - FaultVect vect() {return _vect;} - FaultStat & stat() {return _stat;} + TrapType trapType() {return _trapType;} + FaultPriority priority() {return _priority;} + FaultStat & countStat() {return _count;} bool isMachineCheckFault() {return true;} }; -class AlignmentFault : public AlphaFault +class MemAddressNotAligned : public SparcFault { private: static FaultName _name; - static FaultVect _vect; - static FaultStat _stat; + static TrapType _trapType; + static FaultPriority _priority; + static FaultStat _count; public: FaultName name() {return _name;} - FaultVect vect() {return _vect;} - FaultStat & stat() {return _stat;} + TrapType trapType() {return _trapType;} + FaultPriority priority() {return _priority;} + FaultStat & countStat() {return _count;} bool isAlignmentFault() {return true;} }; static inline Fault genMachineCheckFault() { - return new MachineCheckFault; + return new InternalProcessorError; } static inline Fault genAlignmentFault() { - return new AlignmentFault; + return new MemAddressNotAligned; } -class ResetFault : public AlphaFault +class PowerOnReset : public SparcFault { private: static FaultName _name; - static FaultVect _vect; - static FaultStat _stat; + static TrapType _trapType; + static FaultPriority _priority; + static FaultStat _count; public: FaultName name() {return _name;} - FaultVect vect() {return _vect;} - FaultStat & stat() {return _stat;} + TrapType trapType() {return _trapType;} + FaultPriority priority() {return _priority;} + FaultStat & countStat() {return _count;} }; -class ArithmeticFault : public AlphaFault +class WatchDogReset : public SparcFault +{ + private: + static FaultName _name; + static TrapType _trapType; + static FaultPriority _priority; + static FaultStat _count; + public: + FaultName name() {return _name;} + TrapType trapType() {return _trapType;} + FaultPriority priority() {return _priority;} + FaultStat & countStat() {return _count;} +}; + +class ExternallyInitiatedReset : public SparcFault +{ + private: + static FaultName _name; + static TrapType _trapType; + static FaultPriority _priority; + static FaultStat _count; + public: + FaultName name() {return _name;} + TrapType trapType() {return _trapType;} + FaultPriority priority() {return _priority;} + FaultStat & countStat() {return _count;} +}; + +class SoftwareInitiatedReset : public SparcFault +{ + private: + static FaultName _name; + static TrapType _trapType; + static FaultPriority _priority; + static FaultStat _count; + public: + FaultName name() {return _name;} + TrapType trapType() {return _trapType;} + FaultPriority priority() {return _priority;} + FaultStat & countStat() {return _count;} +}; + +class REDStateException : public SparcFault +{ + private: + static FaultName _name; + static TrapType _trapType; + static FaultPriority _priority; + static FaultStat _count; + public: + FaultName name() {return _name;} + TrapType trapType() {return _trapType;} + FaultPriority priority() {return _priority;} + FaultStat & countStat() {return _count;} +}; + +class InstructionAccessException : public SparcFault +{ + private: + static FaultName _name; + static TrapType _trapType; + static FaultPriority _priority; + static FaultStat _count; + public: + FaultName name() {return _name;} + TrapType trapType() {return _trapType;} + FaultPriority priority() {return _priority;} + FaultStat & countStat() {return _count;} +}; + +class InstructionAccessMMUMiss : public SparcFault +{ + private: + static FaultName _name; + static TrapType _trapType; + static FaultPriority _priority; + static FaultStat _count; + public: + FaultName name() {return _name;} + TrapType trapType() {return _trapType;} + FaultPriority priority() {return _priority;} + FaultStat & countStat() {return _count;} +}; + +class InstructionAccessError : public SparcFault +{ + private: + static FaultName _name; + static TrapType _trapType; + static FaultPriority _priority; + static FaultStat _count; + public: + FaultName name() {return _name;} + TrapType trapType() {return _trapType;} + FaultPriority priority() {return _priority;} + FaultStat & countStat() {return _count;} +}; + +class IllegalInstruction : public SparcFault +{ + private: + static FaultName _name; + static TrapType _trapType; + static FaultPriority _priority; + static FaultStat _count; + public: + FaultName name() {return _name;} + TrapType trapType() {return _trapType;} + FaultPriority priority() {return _priority;} + FaultStat & countStat() {return _count;} +}; + +class PrivelegedOpcode : public SparcFault +{ + private: + static FaultName _name; + static TrapType _trapType; + static FaultPriority _priority; + static FaultStat _count; + public: + FaultName name() {return _name;} + TrapType trapType() {return _trapType;} + FaultPriority priority() {return _priority;} + FaultStat & countStat() {return _count;} +}; + +class UnimplementedLDD : public SparcFault +{ + private: + static FaultName _name; + static TrapType _trapType; + static FaultPriority _priority; + static FaultStat _count; + public: + FaultName name() {return _name;} + TrapType trapType() {return _trapType;} + FaultPriority priority() {return _priority;} + FaultStat & countStat() {return _count;} +}; + +class UnimplementedSTD : public SparcFault +{ + private: + static FaultName _name; + static TrapType _trapType; + static FaultPriority _priority; + static FaultStat _count; + public: + FaultName name() {return _name;} + TrapType trapType() {return _trapType;} + FaultPriority priority() {return _priority;} + FaultStat & countStat() {return _count;} +}; + +class FpDisabled : public SparcFault +{ + private: + static FaultName _name; + static TrapType _trapType; + static FaultPriority _priority; + static FaultStat _count; + public: + FaultName name() {return _name;} + TrapType trapType() {return _trapType;} + FaultPriority priority() {return _priority;} + FaultStat & countStat() {return _count;} +}; + +class FpExceptionIEEE754 : public SparcFault +{ + private: + static FaultName _name; + static TrapType _trapType; + static FaultPriority _priority; + static FaultStat _count; + public: + FaultName name() {return _name;} + TrapType trapType() {return _trapType;} + FaultPriority priority() {return _priority;} + FaultStat & countStat() {return _count;} +}; + +class FpExceptionOther : public SparcFault +{ + private: + static FaultName _name; + static TrapType _trapType; + static FaultPriority _priority; + static FaultStat _count; + public: + FaultName name() {return _name;} + TrapType trapType() {return _trapType;} + FaultPriority priority() {return _priority;} + FaultStat & countStat() {return _count;} +}; + +class TagOverflow : public SparcFault +{ + private: + static FaultName _name; + static TrapType _trapType; + static FaultPriority _priority; + static FaultStat _count; + public: + FaultName name() {return _name;} + TrapType trapType() {return _trapType;} + FaultPriority priority() {return _priority;} + FaultStat & countStat() {return _count;} +}; + +class DivisionByZero : public SparcFault +{ + private: + static FaultName _name; + static TrapType _trapType; + static FaultPriority _priority; + static FaultStat _count; + public: + FaultName name() {return _name;} + TrapType trapType() {return _trapType;} + FaultPriority priority() {return _priority;} + FaultStat & countStat() {return _count;} +}; + +class DataAccessException : public SparcFault +{ + private: + static FaultName _name; + static TrapType _trapType; + static FaultPriority _priority; + static FaultStat _count; + public: + FaultName name() {return _name;} + TrapType trapType() {return _trapType;} + FaultPriority priority() {return _priority;} + FaultStat & countStat() {return _count;} +}; + +class DataAccessMMUMiss : public SparcFault +{ + private: + static FaultName _name; + static TrapType _trapType; + static FaultPriority _priority; + static FaultStat _count; + public: + FaultName name() {return _name;} + TrapType trapType() {return _trapType;} + FaultPriority priority() {return _priority;} + FaultStat & countStat() {return _count;} +}; + +class DataAccessError : public SparcFault +{ + private: + static FaultName _name; + static TrapType _trapType; + static FaultPriority _priority; + static FaultStat _count; + public: + FaultName name() {return _name;} + TrapType trapType() {return _trapType;} + FaultPriority priority() {return _priority;} + FaultStat & countStat() {return _count;} +}; + +class DataAccessProtection : public SparcFault +{ + private: + static FaultName _name; + static TrapType _trapType; + static FaultPriority _priority; + static FaultStat _count; + public: + FaultName name() {return _name;} + TrapType trapType() {return _trapType;} + FaultPriority priority() {return _priority;} + FaultStat & countStat() {return _count;} +}; + +class LDDFMemAddressNotAligned : public SparcFault +{ + private: + static FaultName _name; + static TrapType _trapType; + static FaultPriority _priority; + static FaultStat _count; + public: + FaultName name() {return _name;} + TrapType trapType() {return _trapType;} + FaultPriority priority() {return _priority;} + FaultStat & countStat() {return _count;} +}; + +class STDFMemAddressNotAligned : public SparcFault +{ + private: + static FaultName _name; + static TrapType _trapType; + static FaultPriority _priority; + static FaultStat _count; + public: + FaultName name() {return _name;} + TrapType trapType() {return _trapType;} + FaultPriority priority() {return _priority;} + FaultStat & countStat() {return _count;} +}; + +class PrivelegedAction : public SparcFault +{ + private: + static FaultName _name; + static TrapType _trapType; + static FaultPriority _priority; + static FaultStat _count; + public: + FaultName name() {return _name;} + TrapType trapType() {return _trapType;} + FaultPriority priority() {return _priority;} + FaultStat & countStat() {return _count;} +}; + +class LDQFMemAddressNotAligned : public SparcFault +{ + private: + static FaultName _name; + static TrapType _trapType; + static FaultPriority _priority; + static FaultStat _count; + public: + FaultName name() {return _name;} + TrapType trapType() {return _trapType;} + FaultPriority priority() {return _priority;} + FaultStat & countStat() {return _count;} +}; + +class STQFMemAddressNotAligned : public SparcFault +{ + private: + static FaultName _name; + static TrapType _trapType; + static FaultPriority _priority; + static FaultStat _count; + public: + FaultName name() {return _name;} + TrapType trapType() {return _trapType;} + FaultPriority priority() {return _priority;} + FaultStat & countStat() {return _count;} +}; + +class AsyncDataError : public SparcFault +{ + private: + static FaultName _name; + static TrapType _trapType; + static FaultPriority _priority; + static FaultStat _count; + public: + FaultName name() {return _name;} + TrapType trapType() {return _trapType;} + FaultPriority priority() {return _priority;} + FaultStat & countStat() {return _count;} +}; + +class EnumeratedFault : public SparcFault { protected: - bool skipFaultingInstruction() {return true;} - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _stat; + uint32_t _n; + virtual TrapType baseTrapType() = 0; public: - FaultName name() {return _name;} - FaultVect vect() {return _vect;} - FaultStat & stat() {return _stat;} -#if FULL_SYSTEM - void invoke(ExecContext * xc); -#endif + EnumeratedFault(uint32_t n) : SparcFault() {_n = n;} + TrapType trapType() {return baseTrapType() + _n;} }; -class InterruptFault : public AlphaFault -{ - protected: - bool setRestartAddress() {return false;} - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _stat; - public: - FaultName name() {return _name;} - FaultVect vect() {return _vect;} - FaultStat & stat() {return _stat;} -}; - -class NDtbMissFault : public AlphaFault +class CleanWindow : public EnumeratedFault { private: static FaultName _name; - static FaultVect _vect; - static FaultStat _stat; + static TrapType _baseTrapType; + static FaultPriority _priority; + static FaultStat _count; + TrapType baseTrapType() {return _baseTrapType;} public: + CleanWindow(uint32_t n) : EnumeratedFault(n) {;} FaultName name() {return _name;} - FaultVect vect() {return _vect;} - FaultStat & stat() {return _stat;} + FaultPriority priority() {return _priority;} + FaultStat & countStat() {return _count;} }; -class PDtbMissFault : public AlphaFault +class InterruptLevelN : public EnumeratedFault { private: static FaultName _name; - static FaultVect _vect; - static FaultStat _stat; + static TrapType _baseTrapType; + static FaultStat _count; + TrapType baseTrapType() {return _baseTrapType;} public: + InterruptLevelN(uint32_t n) : EnumeratedFault(n) {;} FaultName name() {return _name;} - FaultVect vect() {return _vect;} - FaultStat & stat() {return _stat;} + FaultPriority priority() {return 32 - _n;} + FaultStat & countStat() {return _count;} }; -class DtbPageFault : public AlphaFault +class SpillNNormal : public EnumeratedFault { private: static FaultName _name; - static FaultVect _vect; - static FaultStat _stat; + static TrapType _baseTrapType; + static FaultPriority _priority; + static FaultStat _count; + TrapType baseTrapType() {return _baseTrapType;} public: + SpillNNormal(uint32_t n) : EnumeratedFault(n) {;} FaultName name() {return _name;} - FaultVect vect() {return _vect;} - FaultStat & stat() {return _stat;} + FaultPriority priority() {return _priority;} + FaultStat & countStat() {return _count;} }; -class DtbAcvFault : public AlphaFault +class SpillNOther : public EnumeratedFault { private: static FaultName _name; - static FaultVect _vect; - static FaultStat _stat; + static TrapType _baseTrapType; + static FaultPriority _priority; + static FaultStat _count; + TrapType baseTrapType() {return _baseTrapType;} public: + SpillNOther(uint32_t n) : EnumeratedFault(n) {;} FaultName name() {return _name;} - FaultVect vect() {return _vect;} - FaultStat & stat() {return _stat;} + FaultPriority priority() {return _priority;} + FaultStat & countStat() {return _count;} }; -class ItbMissFault : public AlphaFault +class FillNNormal : public EnumeratedFault { private: static FaultName _name; - static FaultVect _vect; - static FaultStat _stat; + static TrapType _baseTrapType; + static FaultPriority _priority; + static FaultStat _count; + TrapType baseTrapType() {return _baseTrapType;} public: + FillNNormal(uint32_t n) : EnumeratedFault(n) {;} FaultName name() {return _name;} - FaultVect vect() {return _vect;} - FaultStat & stat() {return _stat;} + FaultPriority priority() {return _priority;} + FaultStat & countStat() {return _count;} }; -class ItbPageFault : public AlphaFault +class FillNOther : public EnumeratedFault { private: static FaultName _name; - static FaultVect _vect; - static FaultStat _stat; + static TrapType _baseTrapType; + static FaultPriority _priority; + static FaultStat _count; + TrapType baseTrapType() {return _baseTrapType;} public: + FillNOther(uint32_t n) : EnumeratedFault(n) {;} FaultName name() {return _name;} - FaultVect vect() {return _vect;} - FaultStat & stat() {return _stat;} + FaultPriority priority() {return _priority;} + FaultStat & countStat() {return _count;} }; -class ItbAcvFault : public AlphaFault +class TrapInstruction : public EnumeratedFault { private: static FaultName _name; - static FaultVect _vect; - static FaultStat _stat; + static TrapType _baseTrapType; + static FaultPriority _priority; + static FaultStat _count; + TrapType baseTrapType() {return _baseTrapType;} public: + TrapInstruction(uint32_t n) : EnumeratedFault(n) {;} FaultName name() {return _name;} - FaultVect vect() {return _vect;} - FaultStat & stat() {return _stat;} + FaultPriority priority() {return _priority;} + FaultStat & countStat() {return _count;} }; -class UnimplementedOpcodeFault : public AlphaFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _stat; - public: - FaultName name() {return _name;} - FaultVect vect() {return _vect;} - FaultStat & stat() {return _stat;} -}; - -class FloatEnableFault : public AlphaFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _stat; - public: - FaultName name() {return _name;} - FaultVect vect() {return _vect;} - FaultStat & stat() {return _stat;} -}; - -class PalFault : public AlphaFault -{ - protected: - bool skipFaultingInstruction() {return true;} - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _stat; - public: - FaultName name() {return _name;} - FaultVect vect() {return _vect;} - FaultStat & stat() {return _stat;} -}; - -class IntegerOverflowFault : public AlphaFault -{ - private: - static FaultName _name; - static FaultVect _vect; - static FaultStat _stat; - public: - FaultName name() {return _name;} - FaultVect vect() {return _vect;} - FaultStat & stat() {return _stat;} -}; - -} // AlphaISA namespace +} // SparcISA namespace #endif // __FAULTS_HH__ From 9e43f70ac2ad7e7283a449fabafc03a5daac7029 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 7 Mar 2006 04:33:10 -0500 Subject: [PATCH 156/180] Clean up of the SPARC isa description. --HG-- extra : convert_revision : 21fe35fe4719f487168c89dd7bfc87dc38af0267 --- arch/sparc/isa/base.isa | 151 ++++++--- arch/sparc/isa/decoder.isa | 490 ++++++++++++++------------- arch/sparc/isa/formats/basic.isa | 39 ++- arch/sparc/isa/formats/branch.isa | 46 ++- arch/sparc/isa/formats/integerop.isa | 20 +- arch/sparc/isa/formats/mem.isa | 45 ++- arch/sparc/isa/formats/noop.isa | 29 +- arch/sparc/isa/formats/trap.isa | 32 +- arch/sparc/isa/includes.isa | 5 +- arch/sparc/isa/operands.isa | 7 +- 10 files changed, 467 insertions(+), 397 deletions(-) diff --git a/arch/sparc/isa/base.isa b/arch/sparc/isa/base.isa index b504f1906..992504369 100644 --- a/arch/sparc/isa/base.isa +++ b/arch/sparc/isa/base.isa @@ -4,79 +4,126 @@ // output header {{ + + struct condCodes + { + uint8_t c:1; + uint8_t v:1; + uint8_t z:1; + uint8_t n:1; + } + + enum condTest + { + Always=0x8, + Never=0x0, + NotEqual=0x9, + Equal=0x1, + Greater=0xA, + LessOrEqual=0x2, + GreaterOrEqual=0xB, + Less=0x3, + GreaterUnsigned=0xC, + LessOrEqualUnsigned=0x4, + CarryClear=0xD, + CarrySet=0x5, + Positive=0xE, + Negative=0x6, + OverflowClear=0xF, + OverflowSet=0x7 + } + /** * Base class for all SPARC static instructions. */ - class SparcStaticInst : public StaticInst + class SparcStaticInst : public StaticInst { - protected: - - // Constructor. - SparcStaticInst(const char *mnem, MachInst _machInst, OpClass __opClass) - : StaticInst(mnem, _machInst, __opClass) + protected: + // Constructor. + SparcStaticInst(const char *mnem, + MachInst _machInst, OpClass __opClass) + : StaticInst(mnem, _machInst, __opClass) { } - std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; + std::string generateDisassembly(Addr pc, + const SymbolTable *symtab) const; }; - bool passesCondition(struct {uint8_t c:1; uint8_t v:1; uint8_t z:1; uint8_t n:1} codes, uint8_t condition); + bool passesCondition(condCodes codes, condTest condition); }}; output decoder {{ - std::string SparcStaticInst::generateDisassembly(Addr pc, const SymbolTable *symtab) const + std::string SparcStaticInst::generateDisassembly(Addr pc, + const SymbolTable *symtab) const { - std::stringstream ss; + std::stringstream ss; - ccprintf(ss, "%-10s ", mnemonic); + ccprintf(ss, "%-10s ", mnemonic); - // just print the first two source regs... if there's - // a third one, it's a read-modify-write dest (Rc), - // e.g. for CMOVxx + // just print the first two source regs... if there's + // a third one, it's a read-modify-write dest (Rc), + // e.g. for CMOVxx + if(_numSrcRegs > 0) + { + printReg(ss, _srcRegIdx[0]); + } + if(_numSrcRegs > 1) + { + ss << ","; + printReg(ss, _srcRegIdx[1]); + } + + // just print the first dest... if there's a second one, + // it's generally implicit + if(_numDestRegs > 0) + { if(_numSrcRegs > 0) - { - printReg(ss, _srcRegIdx[0]); - } - if(_numSrcRegs > 1) - { - ss << ","; - printReg(ss, _srcRegIdx[1]); - } + ss << ","; + printReg(ss, _destRegIdx[0]); + } - // just print the first dest... if there's a second one, - // it's generally implicit - if(_numDestRegs > 0) - { - if(_numSrcRegs > 0) - ss << ","; - printReg(ss, _destRegIdx[0]); - } - - return ss.str(); + return ss.str(); } - bool passesCondition(struct {uint8_t c:1; uint8_t v:1; uint8_t z:1; uint8_t n:1} codes, uint8_t condition) + bool passesCondition(condCodes codes, condTest condition) { - switch(condition) - { - case 0b1000: return true; - case 0b0000: return false; - case 0b1001: return !codes.z; - case 0b0001: return codes.z; - case 0b1010: return !(codes.z | (codes.n ^ codes.v)); - case 0b0010: return codes.z | (codes.n ^ codes.v); - case 0b1011: return !(codes.n ^ codes.v); - case 0b0011: return (codes.n ^ codes.v); - case 0b1100: return !(codes.c | codes.z); - case 0b0100: return (codes.c | codes.z); - case 0b1101: return !codes.c; - case 0b0101: return codes.c; - case 0b1110: return !codes.n; - case 0b0110: return codes.n; - case 0b1111: return !codes.v; - case 0b0111: return codes.v; - } + switch(condition) + { + case Always: + return true; + case Never: + return false; + case NotEqual: + return !codes.z; + case Equal: + return codes.z; + case Greater: + return !(codes.z | (codes.n ^ codes.v)); + case LessOrEqual: + return codes.z | (codes.n ^ codes.v); + case GreaterOrEqual: + return !(codes.n ^ codes.v); + case Less: + return (codes.n ^ codes.v); + case GreaterUnsigned: + return !(codes.c | codes.z); + case LessOrEqualUnsigned: + return (codes.c | codes.z); + case CarryClear: + return !codes.c; + case CarrySet: + return codes.c; + case Positive: + return !codes.n; + case Negative: + return codes.n; + case OverflowClear: + return !codes.v; + case OverflowSet: + return codes.v; + } } }}; diff --git a/arch/sparc/isa/decoder.isa b/arch/sparc/isa/decoder.isa index 06834ecc3..eb458211b 100644 --- a/arch/sparc/isa/decoder.isa +++ b/arch/sparc/isa/decoder.isa @@ -3,55 +3,64 @@ // The actual decoder specification // -decode OP default Trap::unknown({{illegal_instruction}}) { +decode OP default Trap::unknown({{IllegalInstruction}}) { 0x0: decode OP2 { - 0x0: Trap::illtrap({{illegal_instruction}}); //ILLTRAP - 0x1: Branch::bpcc({{ - switch((CC12 << 1) | CC02) - { - case 1: case 3: - throw illegal_instruction; - case 0: - if(passesCondition(xc->regs.MiscRegs.ccrFields.icc, COND2)) - ;//branchHere - break; - case 2: - if(passesCondition(xc->regs.MiscRegs.ccrFields.xcc, COND2)) - ;//branchHere - break; - } - }});//BPcc - 0x2: Branch::bicc({{ - if(passesCondition(xc->regs.MiscRegs.ccrFields.icc, COND2)) - ;//branchHere - }});//Bicc - 0x3: Branch::bpr({{ - switch(RCOND) - { - case 0: case 4: - throw illegal_instruction; - case 1: - if(Rs1 == 0) ;//branchHere - break; - case 2: - if(Rs1 <= 0) ;//branchHere - break; - case 3: - if(Rs1 < 0) ;//branchHere - break; - case 5: - if(Rs1 != 0) ;//branchHere - break; - case 6: - if(Rs1 > 0) ;//branchHere - break; - case 7: - if(Rs1 >= 0) ;//branchHere - break; - } + 0x0: Trap::illtrap({{illegal_instruction}}); //ILLTRAP + 0x1: Branch::bpcc({{ + switch((CC12 << 1) | CC02) + { + case 1: + case 3: + fault = new IllegalInstruction; + case 0: + if(passesCondition(xc->regs.MiscRegs.ccrFields.icc, COND2)) + ;//branchHere + break; + case 2: + if(passesCondition(xc->regs.MiscRegs.ccrFields.xcc, COND2)) + ;//branchHere + break; + } + }});//BPcc + 0x2: Branch::bicc({{ + if(passesCondition(xc->regs.MiscRegs.ccrFields.icc, COND2)) + ;//branchHere + }});//Bicc + 0x3: Branch::bpr({{ + switch(RCOND) + { + case 0: + case 4: + fault = new IllegalInstruction; + case 1: + if(Rs1 == 0) + ;//branchHere + break; + case 2: + if(Rs1 <= 0) + ;//branchHere + break; + case 3: + if(Rs1 < 0) + ;//branchHere + break; + case 5: + if(Rs1 != 0) + ;//branchHere + break; + case 6: + if(Rs1 > 0) + ;//branchHere + break; + case 7: + if(Rs1 >= 0) + ;//branchHere + break; + } }}); //BPr - 0x4: IntegerOp::sethi({{Rd = (IMM22 << 10) & 0xFFFFFC00;}}); //SETHI (or NOP if rd == 0 and imm == 0) + //SETHI (or NOP if rd == 0 and imm == 0) + 0x4: IntegerOp::sethi({{Rd = (IMM22 << 10) & 0xFFFFFC00;}}); 0x5: Trap::fbpfcc({{throw fp_disabled;}}); //FBPfcc 0x6: Trap::fbfcc({{throw fp_disabled;}}); //FBfcc } @@ -60,150 +69,165 @@ decode OP default Trap::unknown({{illegal_instruction}}) { Rd = xc->pc; }}); 0x2: decode OP3 { - format IntegerOp { - 0x00: add({{ - INT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); - Rd = Rs1.sdw + val2; - }});//ADD - 0x01: and({{ - UINT64 val2 = (I ? SIMM13.sdw : Rs2.udw); - Rd = Rs1.udw & val2; - }});//AND - 0x02: or({{ - UINT64 val2 = (I ? SIMM13.sdw : Rs2.udw); - Rd = Rs1.udw | val2; - }});//OR - 0x03: xor({{ - UINT64 val2 = (I ? SIMM13.sdw : Rs2.udw); - Rd = Rs1.udw ^ val2; - }});//XOR - 0x04: sub({{ - INT64 val2 = ~((UINT64)(I ? SIMM13.sdw : Rs2.udw))+1; - Rd = Rs1.sdw + val2; - }});//SUB - 0x05: andn({{ - UINT64 val2 = (I ? SIMM13.sdw : Rs2.udw); - Rd = Rs1.udw & ~val2; - }});//ANDN - 0x06: orn({{ - UINT64 val2 = (I ? SIMM13.sdw : Rs2.udw); - Rd = Rs1.udw | ~val2; - }});//ORN - 0x07: xnor({{ - UINT64 val2 = (I ? SIMM13.sdw : Rs2.udw); - Rd = ~(Rs1.udw ^ val2); - }});//XNOR - 0x08: addc({{ - INT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); - INT64 carryin = xc->regs.MiscRegs.ccrfields.iccfields.c; - Rd = Rs1.sdw + val2 + carryin; - }});//ADDC - 0x09: mulx({{ - INT64 val2 = (I ? SIMM13.sdw : Rs2); - Rd = Rs1 * val2; - }});//MULX - 0x0A: umul({{ - UINT64 resTemp, val2 = (I ? SIMM13.sdw : Rs2.udw); - Rd = resTemp = Rs1.udw<31:0> * val2<31:0>; - xc->regs.MiscRegs.yFields.value = resTemp<63:32>; - }});//UMUL - 0x0B: smul({{ - INT64 resTemp, val2 = (I ? SIMM13.sdw : Rs2.sdw); - rd.sdw = resTemp = Rs1.sdw<31:0> * val2<31:0>; - xc->regs.MiscRegs.yFields.value = resTemp<63:32>; - }});//SMUL - 0x0C: subc({{ - INT64 val2 = ~((INT64)(I ? SIMM13.sdw : Rs2.sdw))+1; - INT64 carryin = xc->regs.MiscRegs.ccrfields.iccfields.c; - Rd.sdw = Rs1.sdw + val2 + carryin; - }});//SUBC - 0x0D: udivx({{ - UINT64 val2 = (I ? SIMM13.sdw : Rs2.udw); - if(val2 == 0) throw division_by_zero; - Rd.udw = Rs1.udw / val2; - }});//UDIVX - 0x0E: udiv({{ - UINT32 resTemp, val2 = (I ? SIMM13.sw : Rs2.udw<31:0>); - if(val2 == 0) throw division_by_zero; - resTemp = (UINT64)((xc->regs.MiscRegs.yFields.value << 32) | Rs1.udw<31:0>) / val2; - INT32 overflow = (resTemp<63:32> != 0); - if(overflow) rd.udw = resTemp = 0xFFFFFFFF; - else rd.udw = resTemp; - }}); //UDIV - 0x0F: sdiv({{ - INT32 resTemp, val2 = (I ? SIMM13.sw : Rs2.sdw<31:0>); - if(val2 == 0) throw division_by_zero; - Rd.sdw = resTemp = (INT64)((xc->regs.MiscRegs.yFields.value << 32) | Rs1.sdw<31:0>) / val2; - INT32 overflow = (resTemp<63:31> != 0); - INT32 underflow = (resTemp<63:> && resTemp<62:31> != 0xFFFFFFFF); - if(overflow) rd.udw = resTemp = 0x7FFFFFFF; - else if(underflow) rd.udw = resTemp = 0xFFFFFFFF80000000; - else rd.udw = resTemp; - }});//SDIV - } - format IntegerOpCc { - 0x10: addcc({{ - INT64 resTemp, val2 = (I ? SIMM13.sdw : Rs2); - Rd = resTemp = Rs1 + val2;}}, - {{((Rs1 & 0xFFFFFFFF + val2 & 0xFFFFFFFF) >> 31)}}, - {{Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>}}, - {{((Rs1 >> 1) + (val2 >> 1) + (Rs1 & val2 & 0x1))<63:>}}, - {{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}} - );//ADDcc - 0x11: andcc({{ - INT64 val2 = (I ? SIMM13.sdw : Rs2); - Rd = Rs1 & val2;}} - ,{{0}},{{0}},{{0}},{{0}});//ANDcc - 0x12: orcc({{ - INT64 val2 = (I ? SIMM13.sdw : Rs2); - Rd = Rs1 | val2;}} - ,{{0}},{{0}},{{0}},{{0}});//ORcc - 0x13: xorcc({{ - INT64 val2 = (I ? SIMM13.sdw : Rs2); - Rd = Rs1 ^ val2;}} - ,{{0}},{{0}},{{0}},{{0}});//XORcc - 0x14: subcc({{ - INT64 resTemp, val2 = (INT64)(I ? SIMM13.sdw : Rs2); - Rd = resTemp = Rs1 - val2;}}, - {{((Rs1 & 0xFFFFFFFF + (~val2) & 0xFFFFFFFF + 1) >> 31)}}, - {{Rs1<31:> != val2<31:> && Rs1<31:> != resTemp<31:>}}, - {{((Rs1 >> 1) + (~val2) >> 1) + ((Rs1 | ~val2) & 0x1))<63:>}}, - {{Rs1<63:> != val2<63:> && Rs1<63:> != resTemp<63:>}} - );//SUBcc - 0x15: andncc({{ - INT64 val2 = (I ? SIMM13.sdw : Rs2); - Rd = Rs1 & ~val2;}} - ,{{0}},{{0}},{{0}},{{0}});//ANDNcc - 0x16: orncc({{ - INT64 val2 = (I ? SIMM13.sdw : Rs2); - Rd = Rs1 | ~val2;}} - ,{{0}},{{0}},{{0}},{{0}});//ORNcc - 0x17: xnorcc({{ - INT64 val2 = (I ? SIMM13.sdw : Rs2); - Rd = ~(Rs1 ^ val2);}} - ,{{0}},{{0}},{{0}},{{0}});//XNORcc - 0x18: addccc({{ - INT64 resTemp, val2 = (I ? SIMM13.sdw : Rs2); - INT64 carryin = xc->regs.MiscRegs.ccrfields.iccfields.c; - Rd = resTemp = Rs1 + val2 + carryin;}}, - {{((Rs1 & 0xFFFFFFFF + val2 & 0xFFFFFFFF) >> 31 + carryin)}}, - {{Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>}}, - {{((Rs1 >> 1) + (val2 >> 1) + ((Rs1 & val2) | (carryin & (Rs1 | val2)) & 0x1))<63:>}}, - {{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}} - );//ADDCcc - 0x1A: umulcc({{ - UINT64 resTemp, val2 = (I ? SIMM13.sdw : Rs2); - Rd = resTemp = Rs1.udw<31:0> * val2<31:0>; - xc->regs.MiscRegs.yFields.value = resTemp<63:32>;}} - ,{{0}},{{0}},{{0}},{{0}});//UMULcc + format IntegerOp { + 0x00: add({{ + int64_t val2 = (I ? SIMM13.sdw : Rs2.sdw); + Rd = Rs1.sdw + val2; + }});//ADD + 0x01: and({{ + uint64_t val2 = (I ? SIMM13.sdw : Rs2.udw); + Rd = Rs1.udw & val2; + }});//AND + 0x02: or({{ + uint64_t val2 = (I ? SIMM13.sdw : Rs2.udw); + Rd = Rs1.udw | val2; + }});//OR + 0x03: xor({{ + uint64_t val2 = (I ? SIMM13.sdw : Rs2.udw); + Rd = Rs1.udw ^ val2; + }});//XOR + 0x04: sub({{ + int64_t val2 = ~((uint64_t)(I ? SIMM13.sdw : Rs2.udw))+1; + Rd = Rs1.sdw + val2; + }});//SUB + 0x05: andn({{ + uint64_t val2 = (I ? SIMM13.sdw : Rs2.udw); + Rd = Rs1.udw & ~val2; + }});//ANDN + 0x06: orn({{ + uint64_t val2 = (I ? SIMM13.sdw : Rs2.udw); + Rd = Rs1.udw | ~val2; + }});//ORN + 0x07: xnor({{ + uint64_t val2 = (I ? SIMM13.sdw : Rs2.udw); + Rd = ~(Rs1.udw ^ val2); + }});//XNOR + 0x08: addc({{ + int64_t val2 = (I ? SIMM13.sdw : Rs2.sdw); + int64_t carryin = xc->regs.MiscRegs.ccrfields.iccfields.c; + Rd = Rs1.sdw + val2 + carryin; + }});//ADDC + 0x09: mulx({{ + int64_t val2 = (I ? SIMM13.sdw : Rs2); + Rd = Rs1 * val2; + }});//MULX + 0x0A: umul({{ + uint64_t resTemp, val2 = (I ? SIMM13.sdw : Rs2.udw); + Rd = resTemp = Rs1.udw<31:0> * val2<31:0>; + xc->regs.MiscRegs.yFields.value = resTemp<63:32>; + }});//UMUL + 0x0B: smul({{ + int64_t resTemp, val2 = (I ? SIMM13.sdw : Rs2.sdw); + rd.sdw = resTemp = Rs1.sdw<31:0> * val2<31:0>; + xc->regs.MiscRegs.yFields.value = resTemp<63:32>; + }});//SMUL + 0x0C: subc({{ + int64_t val2 = ~((int64_t)(I ? SIMM13.sdw : Rs2.sdw))+1; + int64_t carryin = xc->regs.MiscRegs.ccrfields.iccfields.c; + Rd.sdw = Rs1.sdw + val2 + carryin; + }});//SUBC + 0x0D: udivx({{ + uint64_t val2 = (I ? SIMM13.sdw : Rs2.udw); + if(val2 == 0) throw division_by_zero; + Rd.udw = Rs1.udw / val2; + }});//UDIVX + 0x0E: udiv({{ + uint32_t resTemp, val2 = (I ? SIMM13.sw : Rs2.udw<31:0>); + if(val2 == 0) + fault = new DivisionByZero; + resTemp = (uint64_t)((xc->regs.MiscRegs.yFields.value << 32) + | Rs1.udw<31:0>) / val2; + int32_t overflow = (resTemp<63:32> != 0); + if(overflow) + rd.udw = resTemp = 0xFFFFFFFF; + else + rd.udw = resTemp; + }}); //UDIV + 0x0F: sdiv({{ + int32_t resTemp, val2 = (I ? SIMM13.sw : Rs2.sdw<31:0>); + if(val2 == 0) + fault = new DivisionByZero; + + Rd.sdw = (int64_t)((xc->regs.MiscRegs.yFields.value << 32) | + Rs1.sdw<31:0>) / val2; + resTemp = Rd.sdw; + int32_t overflow = (resTemp<63:31> != 0); + int32_t underflow = + (resTemp<63:> && resTemp<62:31> != 0xFFFFFFFF); + if(overflow) + rd.udw = resTemp = 0x7FFFFFFF; + else if(underflow) + rd.udw = resTemp = 0xFFFFFFFF80000000; + else + rd.udw = resTemp; + }});//SDIV + } + format IntegerOpCc { + 0x10: addcc({{ + int64_t resTemp, val2 = (I ? SIMM13.sdw : Rs2); + Rd = resTemp = Rs1 + val2;}}, + {{((Rs1 & 0xFFFFFFFF + val2 & 0xFFFFFFFF) >> 31)}}, + {{Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>}}, + {{((Rs1 >> 1) + (val2 >> 1) + (Rs1 & val2 & 0x1))<63:>}}, + {{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}} + );//ADDcc + 0x11: andcc({{ + int64_t val2 = (I ? SIMM13.sdw : Rs2); + Rd = Rs1 & val2;}}, + {{0}},{{0}},{{0}},{{0}});//ANDcc + 0x12: orcc({{ + int64_t val2 = (I ? SIMM13.sdw : Rs2); + Rd = Rs1 | val2;}}, + {{0}},{{0}},{{0}},{{0}});//ORcc + 0x13: xorcc({{ + int64_t val2 = (I ? SIMM13.sdw : Rs2); + Rd = Rs1 ^ val2;}}, + {{0}},{{0}},{{0}},{{0}});//XORcc + 0x14: subcc({{ + int64_t resTemp, val2 = (int64_t)(I ? SIMM13.sdw : Rs2); + Rd = resTemp = Rs1 - val2;}}, + {{((Rs1 & 0xFFFFFFFF + (~val2) & 0xFFFFFFFF + 1) >> 31)}}, + {{Rs1<31:> != val2<31:> && Rs1<31:> != resTemp<31:>}}, + {{((Rs1 >> 1) + (~val2) >> 1) + + ((Rs1 | ~val2) & 0x1))<63:>}}, + {{Rs1<63:> != val2<63:> && Rs1<63:> != resTemp<63:>}} + );//SUBcc + 0x15: andncc({{ + int64_t val2 = (I ? SIMM13.sdw : Rs2); + Rd = Rs1 & ~val2;}}, + {{0}},{{0}},{{0}},{{0}});//ANDNcc + 0x16: orncc({{ + int64_t val2 = (I ? SIMM13.sdw : Rs2); + Rd = Rs1 | ~val2;}}, + {{0}},{{0}},{{0}},{{0}});//ORNcc + 0x17: xnorcc({{ + int64_t val2 = (I ? SIMM13.sdw : Rs2); + Rd = ~(Rs1 ^ val2);}}, + {{0}},{{0}},{{0}},{{0}});//XNORcc + 0x18: addccc({{ + int64_t resTemp, val2 = (I ? SIMM13.sdw : Rs2); + int64_t carryin = xc->regs.MiscRegs.ccrfields.iccfields.c; + Rd = resTemp = Rs1 + val2 + carryin;}}, + {{((Rs1 & 0xFFFFFFFF + val2 & 0xFFFFFFFF) >> 31 + + carryin)}}, + {{Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>}}, + {{((Rs1 >> 1) + (val2 >> 1) + + ((Rs1 & val2) | (carryin & (Rs1 | val2)) & 0x1))<63:>}}, + {{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}} + );//ADDCcc + 0x1A: umulcc({{ + uint64_t resTemp, val2 = (I ? SIMM13.sdw : Rs2); + Rd = resTemp = Rs1.udw<31:0> * val2<31:0>; + xc->regs.MiscRegs.yFields.value = resTemp<63:32>;}}, + {{0}},{{0}},{{0}},{{0}});//UMULcc 0x1B: smulcc({{ - INT64 resTemp, val2 = (I ? SIMM13.sdw : Rs2); + int64_t resTemp, val2 = (I ? SIMM13.sdw : Rs2); Rd = resTemp = Rs1.sdw<31:0> * val2<31:0>; xc->regs.MiscRegs.yFields.value = resTemp<63:32>;}} ,{{0}},{{0}},{{0}},{{0}});//SMULcc 0x1C: subccc({{ - INT64 resTemp, val2 = (INT64)(I ? SIMM13.sdw : Rs2); - INT64 carryin = xc->regs.MiscRegs.ccrfields.iccfields.c; + int64_t resTemp, val2 = (int64_t)(I ? SIMM13.sdw : Rs2); + int64_t carryin = xc->regs.MiscRegs.ccrfields.iccfields.c; Rd = resTemp = Rs1 + ~(val2 + carryin) + 1;}}, {{((Rs1 & 0xFFFFFFFF + (~(val2 + carryin)) & 0xFFFFFFFF + 1) >> 31)}}, {{Rs1<31:> != val2<31:> && Rs1<31:> != resTemp<31:>}}, @@ -211,15 +235,15 @@ decode OP default Trap::unknown({{illegal_instruction}}) { {{Rs1<63:> != val2<63:> && Rs1<63:> != resTemp<63:>}} );//SUBCcc 0x1D: udivxcc({{ - UINT64 val2 = (I ? SIMM13.sdw : Rs2.udw); + uint64_t val2 = (I ? SIMM13.sdw : Rs2.udw); if(val2 == 0) throw division_by_zero; Rd.udw = Rs1.udw / val2;}} ,{{0}},{{0}},{{0}},{{0}});//UDIVXcc 0x1E: udivcc({{ - UINT32 resTemp, val2 = (I ? SIMM13.sw : Rs2.udw<31:0>); + uint32_t resTemp, val2 = (I ? SIMM13.sw : Rs2.udw<31:0>); if(val2 == 0) throw division_by_zero; - resTemp = (UINT64)((xc->regs.MiscRegs.yFields.value << 32) | Rs1.udw<31:0>) / val2; - INT32 overflow = (resTemp<63:32> != 0); + resTemp = (uint64_t)((xc->regs.MiscRegs.yFields.value << 32) | Rs1.udw<31:0>) / val2; + int32_t overflow = (resTemp<63:32> != 0); if(overflow) rd.udw = resTemp = 0xFFFFFFFF; else rd.udw = resTemp;}}, {{0}}, @@ -228,11 +252,11 @@ decode OP default Trap::unknown({{illegal_instruction}}) { {{0}} );//UDIVcc 0x1F: sdivcc({{ - INT32 resTemp, val2 = (I ? SIMM13.sw : Rs2.sdw<31:0>); + int32_t resTemp, val2 = (I ? SIMM13.sw : Rs2.sdw<31:0>); if(val2 == 0) throw division_by_zero; - Rd.sdw = resTemp = (INT64)((xc->regs.MiscRegs.yFields.value << 32) | Rs1.sdw<31:0>) / val2; - INT32 overflow = (resTemp<63:31> != 0); - INT32 underflow = (resTemp<63:> && resTemp<62:31> != 0xFFFFFFFF); + Rd.sdw = resTemp = (int64_t)((xc->regs.MiscRegs.yFields.value << 32) | Rs1.sdw<31:0>) / val2; + int32_t overflow = (resTemp<63:31> != 0); + int32_t underflow = (resTemp<63:> && resTemp<62:31> != 0xFFFFFFFF); if(overflow) rd.udw = resTemp = 0x7FFFFFFF; else if(underflow) rd.udw = resTemp = 0xFFFFFFFF80000000; else rd.udw = resTemp;}}, @@ -242,27 +266,27 @@ decode OP default Trap::unknown({{illegal_instruction}}) { {{0}} );//SDIVcc 0x20: taddcc({{ - INT64 resTemp, val2 = (I ? SIMM13.sdw : Rs2); + int64_t resTemp, val2 = (I ? SIMM13.sdw : Rs2); Rd = resTemp = Rs1 + val2; - INT32 overflow = Rs1<1:0> || val2<1:0> || (Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>);}}, + int32_t overflow = Rs1<1:0> || val2<1:0> || (Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>);}}, {{((Rs1 & 0xFFFFFFFF + val2 & 0xFFFFFFFF) >> 31)}}, {{overflow}}, {{((Rs1 >> 1) + (val2 >> 1) + (Rs1 & val2 & 0x1))<63:>}}, {{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}} );//TADDcc 0x21: tsubcc({{ - INT64 resTemp, val2 = (I ? SIMM13.sdw : Rs2); + int64_t resTemp, val2 = (I ? SIMM13.sdw : Rs2); Rd = resTemp = Rs1 + val2; - INT32 overflow = Rs1<1:0> || val2<1:0> || (Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>);}}, + int32_t overflow = Rs1<1:0> || val2<1:0> || (Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>);}}, {{(Rs1 & 0xFFFFFFFF + val2 & 0xFFFFFFFF) >> 31)}}, {{overflow}}, {{((Rs1 >> 1) + (val2 >> 1) + (Rs1 & val2 & 0x1))<63:>}}, {{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}} );//TSUBcc 0x22: taddcctv({{ - INT64 resTemp, val2 = (I ? SIMM13.sdw : Rs2); + int64_t resTemp, val2 = (I ? SIMM13.sdw : Rs2); Rd = resTemp = Rs1 + val2; - INT32 overflow = Rs1<1:0> || val2<1:0> || (Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>); + int32_t overflow = Rs1<1:0> || val2<1:0> || (Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>); if(overflow) throw tag_overflow;}}, {{((Rs1 & 0xFFFFFFFF + val2 & 0xFFFFFFFF) >> 31)}}, {{overflow}}, @@ -270,9 +294,9 @@ decode OP default Trap::unknown({{illegal_instruction}}) { {{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}} );//TADDccTV 0x23: tsubcctv({{ - INT64 resTemp, val2 = (I ? SIMM13.sdw : Rs2); + int64_t resTemp, val2 = (I ? SIMM13.sdw : Rs2); Rd = resTemp = Rs1 + val2; - INT32 overflow = Rs1<1:0> || val2<1:0> || (Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>); + int32_t overflow = Rs1<1:0> || val2<1:0> || (Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>); if(overflow) throw tag_overflow;}}, {{((Rs1 & 0xFFFFFFFF + val2 & 0xFFFFFFFF) >> 31)}}, {{overflow}}, @@ -280,9 +304,9 @@ decode OP default Trap::unknown({{illegal_instruction}}) { {{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}} );//TSUBccTV 0x24: mulscc({{ - INT64 resTemp, multiplicand = (I ? SIMM13.sdw : Rs2); - INT32 multiplier = Rs1<31:0>; - INT32 savedLSB = Rs1<0:>; + int64_t resTemp, multiplicand = (I ? SIMM13.sdw : Rs2); + int32_t multiplier = Rs1<31:0>; + int32_t savedLSB = Rs1<0:>; multiplier = multipler<31:1> | ((xc->regs.MiscRegs.ccrFields.iccFields.n ^ xc->regs.MiscRegs.ccrFields.iccFields.v) << 32); @@ -368,14 +392,14 @@ decode OP default Trap::unknown({{illegal_instruction}}) { } }});//MOVcc 0x2D: sdivx({{ - INT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); + int64_t val2 = (I ? SIMM13.sdw : Rs2.sdw); if(val2 == 0) throw division_by_zero; Rd.sdw = Rs1.sdw / val2; }});//SDIVX 0x2E: decode RS1 { 0x0: IntegerOp::popc({{ - INT64 count = 0, val2 = (I ? SIMM13.sdw : Rs2.sdw); - UINT8 oneBits[] = {0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4} + int64_t count = 0, val2 = (I ? SIMM13.sdw : Rs2.sdw); + uint8_t oneBits[] = {0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4} for(unsigned int x = 0; x < 16; x++) { count += oneBits[val2 & 0xF]; @@ -384,7 +408,7 @@ decode OP default Trap::unknown({{illegal_instruction}}) { }});//POPC } 0x2F: movr({{ - UINT64 val2 = (I ? SIMM10.sdw : Rs2.sdw); + uint64_t val2 = (I ? SIMM10.sdw : Rs2.sdw); switch(RCOND) { case 0: case 4: @@ -412,19 +436,19 @@ decode OP default Trap::unknown({{illegal_instruction}}) { }});//MOVR 0x30: decode RD { 0x0: wry({{ - UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); + uint64_t val2 = (I ? SIMM13.sdw : Rs2.sdw); xc->regs.MiscRegs.y = Rs1 ^ val2; }});//WRY 0x2: wrccr({{ - UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); + uint64_t val2 = (I ? SIMM13.sdw : Rs2.sdw); xc->regs.MiscRegs.ccr = Rs1 ^ val2; }});//WRCCR 0x3: wrasi({{ - UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); + uint64_t val2 = (I ? SIMM13.sdw : Rs2.sdw); xc->regs.MiscRegs.asi = Rs1 ^ val2; }});//WRASI 0x6: wrfprs({{ - UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); + uint64_t val2 = (I ? SIMM13.sdw : Rs2.sdw); xc->regs.MiscRegs.asi = Rs1 ^ val2; }});//WRFPRS 0xF: Trap::sir({{software_initiated_reset}}); //SIR @@ -435,63 +459,63 @@ decode OP default Trap::unknown({{illegal_instruction}}) { } 0x32: decode RD { 0x0: wrprtpc({{checkPriv - UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); + uint64_t val2 = (I ? SIMM13.sdw : Rs2.sdw); xc->regs.MiscRegs.tpc[xc->regs.MiscRegs.tl] = Rs1 ^ val2; }}); 0x1: wrprtnpc({{checkPriv - UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); + uint64_t val2 = (I ? SIMM13.sdw : Rs2.sdw); xc->regs.MiscRegs.tnpc[xc->regs.MiscRegs.tl] = Rs1 ^ val2; }}); 0x2: wrprtstate({{checkPriv - UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); + uint64_t val2 = (I ? SIMM13.sdw : Rs2.sdw); xc->regs.MiscRegs.tstate[xc->regs.MiscRegs.tl] = Rs1 ^ val2; }}); 0x3: wrprtt({{checkPriv - UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); + uint64_t val2 = (I ? SIMM13.sdw : Rs2.sdw); xc->regs.MiscRegs.tt[xc->regs.MiscRegs.tl] = Rs1 ^ val2; }}); 0x4: wrprtick({{checkPriv - UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); + uint64_t val2 = (I ? SIMM13.sdw : Rs2.sdw); xc->regs.MiscRegs.tick = Rs1 ^ val2; }}); 0x5: wrprtba({{checkPriv - UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); + uint64_t val2 = (I ? SIMM13.sdw : Rs2.sdw); xc->regs.MiscRegs.tba = Rs1 ^ val2; }}); 0x6: wrprpstate({{checkPriv - UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); + uint64_t val2 = (I ? SIMM13.sdw : Rs2.sdw); xc->regs.MiscRegs.pstate = Rs1 ^ val2; }}); 0x7: wrprtl({{checkPriv - UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); + uint64_t val2 = (I ? SIMM13.sdw : Rs2.sdw); xc->regs.MiscRegs.tl = Rs1 ^ val2; }}); 0x8: wrprpil({{checkPriv - UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); + uint64_t val2 = (I ? SIMM13.sdw : Rs2.sdw); xc->regs.MiscRegs.pil = Rs1 ^ val2; }}); 0x9: wrprcwp({{checkPriv - UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); + uint64_t val2 = (I ? SIMM13.sdw : Rs2.sdw); xc->regs.MiscRegs.cwp = Rs1 ^ val2; }}); 0xA: wrprcansave({{checkPriv - UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); + uint64_t val2 = (I ? SIMM13.sdw : Rs2.sdw); xc->regs.MiscRegs.cansave = Rs1 ^ val2; }}); 0xB: wrprcanrestore({{checkPriv - UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); + uint64_t val2 = (I ? SIMM13.sdw : Rs2.sdw); xc->regs.MiscRegs.canrestore = Rs1 ^ val2; }}); 0xC: wrprcleanwin({{checkPriv - UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); + uint64_t val2 = (I ? SIMM13.sdw : Rs2.sdw); xc->regs.MiscRegs.cleanwin = Rs1 ^ val2; }}); 0xD: wrprotherwin({{checkPriv - UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); + uint64_t val2 = (I ? SIMM13.sdw : Rs2.sdw); xc->regs.MiscRegs.otherwin = Rs1 ^ val2; }}); 0xE: wrprwstate({{checkPriv - UINT64 val2 = (I ? SIMM13.sdw : Rs2.sdw); + uint64_t val2 = (I ? SIMM13.sdw : Rs2.sdw); xc->regs.MiscRegs.wstate = Rs1 ^ val2; }}); } @@ -532,7 +556,7 @@ decode OP default Trap::unknown({{illegal_instruction}}) { 0x01: ldub({{Rd.ub = Mem.ub;}}); //LDUB 0x02: lduh({{Rd.uhw = Mem.uhw;}}); //LDUH 0x03: ldd({{ - UINT64 val = Mem.udw; + uint64_t val = Mem.udw; setIntReg(RD & (~1), val<31:0>); setIntReg(RD | 1, val<63:32>); }});//LDD @@ -553,7 +577,7 @@ decode OP default Trap::unknown({{illegal_instruction}}) { }}); //LDSTUB 0x0E: stx({{Rd.udw = Mem.udw;}}); //STX 0x0F: swap({{ - UINT32 temp = Rd.uw; + uint32_t temp = Rd.uw; Rd.uw = Mem.uw; Mem.uw = temp; }}); //SWAP @@ -561,7 +585,7 @@ decode OP default Trap::unknown({{illegal_instruction}}) { 0x11: lduba({{Rd.ub = Mem.ub;}}); //LDUBA 0x12: lduha({{Rd.uhw = Mem.uhw;}}); //LDUHA 0x13: ldda({{ - UINT64 val = Mem.udw; + uint64_t val = Mem.udw; setIntReg(RD & (~1), val<31:0>); setIntReg(RD | 1, val<63:32>); }}); //LDDA @@ -582,7 +606,7 @@ decode OP default Trap::unknown({{illegal_instruction}}) { }}); //LDSTUBA 0x1E: stxa({{Mem.sdw = Rd.sdw}}); //STXA 0x1F: swapa({{ - UINT32 temp = Rd.uw; + uint32_t temp = Rd.uw; Rd.uw = Mem.uw; Mem.uw = temp; }}); //SWAPA @@ -621,14 +645,14 @@ decode OP default Trap::unknown({{illegal_instruction}}) { 0x3C: Cas::casa( - {{UINT64 val = Mem.uw; + {{uint64_t val = Mem.uw; if(Rs2.uw == val) Mem.uw = Rd.uw; Rd.uw = val; }}); //CASA 0x3D: Noop::prefetcha({{ }}); //PREFETCHA 0x3E: Cas::casxa( - {{UINT64 val = Mem.udw; + {{uint64_t val = Mem.udw; if(Rs2 == val) Mem.udw = Rd; Rd = val; diff --git a/arch/sparc/isa/formats/basic.isa b/arch/sparc/isa/formats/basic.isa index 1994df41c..73df7617d 100644 --- a/arch/sparc/isa/formats/basic.isa +++ b/arch/sparc/isa/formats/basic.isa @@ -11,16 +11,17 @@ def template BasicDeclare {{ */ class %(class_name)s : public %(base_class)s { - public: - /// Constructor. - %(class_name)s(MachInst machInst); - %(BasicExecDeclare)s - }; + public: + // Constructor. + %(class_name)s(MachInst machInst); + %(BasicExecDeclare)s + }; }}; // Basic instruction class constructor template. def template BasicConstructor {{ - inline %(class_name)s::%(class_name)s(MachInst machInst) : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s) + inline %(class_name)s::%(class_name)s(MachInst machInst) + : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s) { %(constructor)s; } @@ -28,20 +29,21 @@ def template BasicConstructor {{ // Basic instruction class execute method template. def template BasicExecute {{ - Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const + Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const { - Fault fault = No_Fault; + Fault fault = NoFault; - %(fp_enable_check)s; - %(op_decl)s; - %(op_rd)s; - %(code)s; + %(fp_enable_check)s; + %(op_decl)s; + %(op_rd)s; + %(code)s; - if(fault == No_Fault) - { - %(op_wb)s; - } - return fault; + if(fault == NoFault) + { + %(op_wb)s; + } + return fault; } }}; @@ -57,7 +59,8 @@ def template BasicDecodeWithMnemonic {{ // The most basic instruction format... used only for a few misc. insts def format BasicOperate(code, *flags) {{ - iop = InstObjParams(name, Name, 'SparcStaticInst', CodeBlock(code), flags) + iop = InstObjParams(name, Name, 'SparcStaticInst', + CodeBlock(code), flags) header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) decode_block = BasicDecode.subst(iop) diff --git a/arch/sparc/isa/formats/branch.isa b/arch/sparc/isa/formats/branch.isa index c4c0a90af..80101de1b 100644 --- a/arch/sparc/isa/formats/branch.isa +++ b/arch/sparc/isa/formats/branch.isa @@ -9,48 +9,44 @@ output header {{ */ class Branch : public SparcStaticInst { - protected: + protected: + // Constructor + Branch(const char *mnem, MachInst _machInst, OpClass __opClass) : + SparcStaticInst(mnem, _machInst, __opClass) + { + } - /// Constructor - Branch(const char *mnem, MachInst _machInst, OpClass __opClass) : SparcStaticInst(mnem, _machInst, __opClass) - { - } - - std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; + std::string generateDisassembly(Addr pc, + const SymbolTable *symtab) const; }; }}; output decoder {{ std::string Branch::generateDisassembly(Addr pc, const SymbolTable *symtab) const { - return "Disassembly of integer instruction\n"; + return "Branch instruction\n"; } }}; def template BranchExecute {{ - Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const + Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const { - //Attempt to execute the instruction - try - { - checkPriv; + //Attempt to execute the instruction + Fault fault = NoFault; + checkPriv; - %(op_decl)s; - %(op_rd)s; - %(code)s; - } - //If we have an exception for some reason, - //deal with it - catch(SparcException except) - { - //Deal with exception - return No_Fault; - } + %(op_decl)s; + %(op_rd)s; + %(code)s; + if(fault == NoFault) + { //Write the resulting state to the execution context %(op_wb)s; + } - return No_Fault; + return fault; } }}; diff --git a/arch/sparc/isa/formats/integerop.isa b/arch/sparc/isa/formats/integerop.isa index 275a346d3..5a9e09896 100644 --- a/arch/sparc/isa/formats/integerop.isa +++ b/arch/sparc/isa/formats/integerop.isa @@ -9,21 +9,23 @@ output header {{ */ class IntegerOp : public SparcStaticInst { - protected: + protected: + // Constructor + IntegerOp(const char *mnem, MachInst _machInst, OpClass __opClass) : + SparcStaticInst(mnem, _machInst, __opClass) + { + } - /// Constructor - IntegerOp(const char *mnem, MachInst _machInst, OpClass __opClass) : SparcStaticInst(mnem, _machInst, __opClass) - { - } - - std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; + std::string generateDisassembly(Addr pc, + const SymbolTable *symtab) const; }; }}; output decoder {{ - std::string IntegerOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const + std::string IntegerOp::generateDisassembly(Addr pc, + const SymbolTable *symtab) const { - return "Disassembly of integer instruction\n"; + return "Integer instruction\n"; } }}; diff --git a/arch/sparc/isa/formats/mem.isa b/arch/sparc/isa/formats/mem.isa index abc00b6f2..d72de47d0 100644 --- a/arch/sparc/isa/formats/mem.isa +++ b/arch/sparc/isa/formats/mem.isa @@ -9,48 +9,43 @@ output header {{ */ class Mem : public SparcStaticInst { - protected: + protected: - /// Constructor - Mem(const char *mnem, MachInst _machInst, OpClass __opClass) : SparcStaticInst(mnem, _machInst, __opClass) - { - } + // Constructor + Mem(const char *mnem, MachInst _machInst, OpClass __opClass) : + SparcStaticInst(mnem, _machInst, __opClass) + { + } - std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; + std::string generateDisassembly(Addr pc, + const SymbolTable *symtab) const; }; }}; output decoder {{ std::string Mem::generateDisassembly(Addr pc, const SymbolTable *symtab) const { - return "Disassembly of integer instruction\n"; + return "Memory instruction\n"; } }}; def template MemExecute {{ - Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const + Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const { - //Attempt to execute the instruction - try - { - - %(op_decl)s; - %(op_rd)s; - ea_code - %(code)s; - } - //If we have an exception for some reason, - //deal with it - catch(SparcException except) - { - //Deal with exception - return No_Fault; - } + Fault fault = NoFault; + %(op_decl)s; + %(op_rd)s; + ea_code + %(code)s; + if(fault == NoFault) + { //Write the resulting state to the execution context %(op_wb)s; + } - return No_Fault; + return fault; } }}; diff --git a/arch/sparc/isa/formats/noop.isa b/arch/sparc/isa/formats/noop.isa index bc83e3261..fa4047f06 100644 --- a/arch/sparc/isa/formats/noop.isa +++ b/arch/sparc/isa/formats/noop.isa @@ -5,33 +5,36 @@ output header {{ /** - * Base class for integer operations. + * Noop class. */ class Noop : public SparcStaticInst { - protected: + protected: + // Constructor + Noop(const char *mnem, MachInst _machInst, OpClass __opClass) : + SparcStaticInst(mnem, _machInst, __opClass) + { + } - /// Constructor - Noop(const char *mnem, MachInst _machInst, OpClass __opClass) : SparcStaticInst(mnem, _machInst, __opClass) - { - } - - std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; + std::string generateDisassembly(Addr pc, + const SymbolTable *symtab) const; }; }}; output decoder {{ - std::string Noop::generateDisassembly(Addr pc, const SymbolTable *symtab) const + std::string Noop::generateDisassembly(Addr pc, + const SymbolTable *symtab) const { - return "Disassembly of integer instruction\n"; + return "Noop\n"; } }}; def template NoopExecute {{ - Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const + Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const { - //Nothing to see here, move along - return No_Fault; + //Nothing to see here, move along + return NoFault; } }}; diff --git a/arch/sparc/isa/formats/trap.isa b/arch/sparc/isa/formats/trap.isa index bee77fe69..ff3aadf72 100644 --- a/arch/sparc/isa/formats/trap.isa +++ b/arch/sparc/isa/formats/trap.isa @@ -9,35 +9,33 @@ output header {{ */ class Trap : public SparcStaticInst { - protected: + protected: - /// Constructor - Trap(const char *mnem, MachInst _machInst, OpClass __opClass) : SparcStaticInst(mnem, _machInst, __opClass) - { - } + // Constructor + Trap(const char *mnem, MachInst _machInst, OpClass __opClass) : + SparcStaticInst(mnem, _machInst, __opClass) + { + } - std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; + std::string generateDisassembly(Addr pc, + const SymbolTable *symtab) const; }; }}; output decoder {{ - std::string Trap::generateDisassembly(Addr pc, const SymbolTable *symtab) const + std::string Trap::generateDisassembly(Addr pc, + const SymbolTable *symtab) const { - return "Disassembly of integer instruction\n"; + return "Trap instruction\n"; } }}; def template TrapExecute {{ - Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const + Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const { - //Call into the trap handler with the appropriate fault - return No_Fault; - } - - //Write the resulting state to the execution context - %(op_wb)s; - - return No_Fault; + //TODO: set up a software fault and return it. + return NoFault; } }}; diff --git a/arch/sparc/isa/includes.isa b/arch/sparc/isa/includes.isa index ff7cb7d1d..a99018b49 100644 --- a/arch/sparc/isa/includes.isa +++ b/arch/sparc/isa/includes.isa @@ -9,8 +9,9 @@ output header {{ #include #include "cpu/static_inst.hh" -#include "traps.hh" +#include "arch/sparc/faults.hh" #include "mem/mem_req.hh" // some constructors use MemReq flags +#include "arch/sparc/isa_traits.hh" }}; output decoder {{ @@ -22,6 +23,8 @@ output decoder {{ #if defined(linux) #include #endif + +using namespace SparcISA; }}; output exec {{ diff --git a/arch/sparc/isa/operands.isa b/arch/sparc/isa/operands.isa index c5ba263d6..64f5abd08 100644 --- a/arch/sparc/isa/operands.isa +++ b/arch/sparc/isa/operands.isa @@ -22,11 +22,10 @@ def operands {{ #'Fa': ('FloatReg', 'df', 'FA', 'IsFloating', 1), #'Fb': ('FloatReg', 'df', 'FB', 'IsFloating', 2), #'Fc': ('FloatReg', 'df', 'FC', 'IsFloating', 3), - 'Mem': ('Mem', 'udw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 4) + 'Mem': ('Mem', 'udw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 4), #'NPC': ('NPC', 'uq', None, ( None, None, 'IsControl' ), 4), #'Runiq': ('ControlReg', 'uq', 'Uniq', None, 1), #'FPCR': ('ControlReg', 'uq', 'Fpcr', None, 1), - # The next two are hacks for non-full-system call-pal emulation - #'R0': ('IntReg', 'uq', '0', None, 1), - #'R16': ('IntReg', 'uq', '16', None, 1) + 'R0': ('IntReg', 'udw', '0', None, 1), + 'R16': ('IntReg', 'udw', '16', None, 1) }}; From 547999eb1fe88aa2d1d59ace639a4a0561430662 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 7 Mar 2006 04:33:40 -0500 Subject: [PATCH 157/180] Clean up of the SPARC isa_traits. This still doesn't compile, but it's closer. --HG-- extra : convert_revision : 7b22a4a4af5bcb13e2d9322ef93d3f582e8efa92 --- arch/sparc/isa_traits.hh | 847 +++++++++++++++++++-------------------- 1 file changed, 412 insertions(+), 435 deletions(-) diff --git a/arch/sparc/isa_traits.hh b/arch/sparc/isa_traits.hh index 7dd49aed9..5a58bbaef 100644 --- a/arch/sparc/isa_traits.hh +++ b/arch/sparc/isa_traits.hh @@ -29,22 +29,24 @@ #ifndef __ARCH_SPARC_ISA_TRAITS_HH__ #define __ARCH_SPARC_ISA_TRAITS_HH__ +#include "arch/sparc/faults.hh" +#include "base/misc.hh" +#include "config/full_system.hh" +#include "sim/host.hh" + //This makes sure the big endian versions of certain functions are used. namespace BigEndianGuest {} using namespace BigEndianGuest; -#include "arch/sparc/faults.hh" -#include "base/misc.hh" -#include "sim/host.hh" - +class ExecContext; class FastCPU; //class FullCPU; -//class Checkpoint; +class Checkpoint; #define TARGET_SPARC -template class StaticInst; -template class StaticInstPtr; +class StaticInst; +class StaticInstPtr; //namespace EV5 //{ @@ -52,479 +54,454 @@ template class StaticInstPtr; // int ITB_ASN_ASN(uint64_t reg); //} -class SPARCISA +namespace SparcISA { - public: + typedef uint32_t MachInst; + typedef uint64_t Addr; + typedef uint8_t RegIndex; - typedef uint32_t MachInst; - typedef uint64_t Addr; - typedef uint8_t RegIndex; + enum + { + MemoryEnd = 0xffffffffffffffffULL, - enum - { - MemoryEnd = 0xffffffffffffffffULL, + NumFloatRegs = 32, + NumMiscRegs = 32, - NumFloatRegs = 32, - NumMiscRegs = 32, + MaxRegsOfAnyType = 32, + // Static instruction parameters + MaxInstSrcRegs = 3, + MaxInstDestRegs = 2, - MaxRegsOfAnyType = 32, - // Static instruction parameters - MaxInstSrcRegs = 3, - MaxInstDestRegs = 2, + // Maximum trap level + MaxTL = 4, - // Maximum trap level - MaxTL = 4 + // semantically meaningful register indices + ZeroReg = 0 // architecturally meaningful + // the rest of these depend on the ABI + }; + typedef uint64_t IntReg; - // semantically meaningful register indices - ZeroReg = 0, // architecturally meaningful - // the rest of these depend on the ABI - } - typedef uint64_t IntReg; - - class IntRegFile - { + class IntRegFile + { private: - //For right now, let's pretend the register file is static - IntReg regs[32]; + //For right now, let's pretend the register file is static + IntReg regs[32]; public: - IntReg & operator [] (RegIndex index) + IntReg & operator [] (RegIndex index) + { + //Don't allow indexes outside of the 32 registers + index &= 0x1F; + return regs[index]; + } + }; + + void serialize(std::ostream & os); + + void unserialize(Checkpoint *cp, const std::string §ion); + + class FloatRegFile + { + private: + //By using the largest data type, we ensure everything + //is aligned correctly in memory + union + { + long double rawRegs[16]; + uint64_t regDump[32]; + }; + class QuadRegs + { + private: + FloatRegFile * parent; + public: + QuadRegs(FloatRegFile * p) : parent(p) {;} + long double & operator [] (RegIndex index) + { + //Quad floats are index by the single + //precision register the start on, + //and only 16 should be accessed + index = (index >> 2) & 0xF; + return parent->rawRegs[index]; + } + }; + class DoubleRegs + { + private: + FloatRegFile * parent; + public: + DoubleRegs(FloatRegFile * p) : parent(p) {;} + double & operator [] (RegIndex index) + { + //Double floats are index by the single + //precision register the start on, + //and only 32 should be accessed + index = (index >> 1) & 0x1F; + return ((double *)parent->rawRegs)[index]; + } + }; + class SingleRegs + { + private: + FloatRegFile * parent; + public: + SingleRegs(FloatRegFile * p) : parent(p) {;} + float & operator [] (RegIndex index) + { + //Only 32 single floats should be accessed + index &= 0x1F; + return ((float *)parent->rawRegs)[index]; + } + }; + public: + void serialize(std::ostream & os); + + void unserialize(Checkpoint * cp, std::string & section); + + QuadRegs quadRegs; + DoubleRegs doubleRegs; + SingleRegs singleRegs; + FloatRegFile() : quadRegs(this), doubleRegs(this), singleRegs(this) + {;} + }; + + // control register file contents + typedef uint64_t MiscReg; + // The control registers, broken out into fields + class MiscRegFile + { + public: + union + { + uint16_t pstate; // Process State Register + struct + { + uint16_t ag:1; // Alternate Globals + uint16_t ie:1; // Interrupt enable + uint16_t priv:1; // Privelege mode + uint16_t am:1; // Address mask + uint16_t pef:1; // PSTATE enable floating-point + uint16_t red:1; // RED (reset, error, debug) state + uint16_t mm:2; // Memory Model + uint16_t tle:1; // Trap little-endian + uint16_t cle:1; // Current little-endian + } pstateFields; + }; + uint64_t tba; // Trap Base Address + union + { + uint64_t y; // Y (used in obsolete multiplication) + struct + { + uint64_t value:32; // The actual value stored in y + const uint64_t :32; // reserved bits + } yFields; + }; + uint8_t pil; // Process Interrupt Register + uint8_t cwp; // Current Window Pointer + uint16_t tt[MaxTL]; // Trap Type (Type of trap which occured + // on the previous level) + union + { + uint8_t ccr; // Condition Code Register + struct + { + union { - //Don't allow indexes outside of the 32 registers - index &= 0x1F - return regs[index]; - } + uint8_t icc:4; // 32-bit condition codes + struct + { + uint8_t c:1; // Carry + uint8_t v:1; // Overflow + uint8_t z:1; // Zero + uint8_t n:1; // Negative + } iccFields:4; + } :4; + union + { + uint8_t xcc:4; // 64-bit condition codes + struct + { + uint8_t c:1; // Carry + uint8_t v:1; // Overflow + uint8_t z:1; // Zero + uint8_t n:1; // Negative + } xccFields:4; + } :4; + } ccrFields; + }; + uint8_t asi; // Address Space Identifier + uint8_t tl; // Trap Level + uint64_t tpc[MaxTL]; // Trap Program Counter (value from + // previous trap level) + uint64_t tnpc[MaxTL]; // Trap Next Program Counter (value from + // previous trap level) + union + { + uint64_t tstate[MaxTL]; // Trap State + struct + { + //Values are from previous trap level + uint64_t cwp:5; // Current Window Pointer + const uint64_t :2; // Reserved bits + uint64_t pstate:10; // Process State + const uint64_t :6; // Reserved bits + uint64_t asi:8; // Address Space Identifier + uint64_t ccr:8; // Condition Code Register + } tstateFields[MaxTL]; + }; + union + { + uint64_t tick; // Hardware clock-tick counter + struct + { + uint64_t counter:63; // Clock-tick count + uint64_t npt:1; // Non-priveleged trap + } tickFields; + } + uint8_t cansave; // Savable windows + uint8_t canrestore; // Restorable windows + uint8_t otherwin; // Other windows + uint8_t cleanwin; // Clean windows + union + { + uint8_t wstate; // Window State + struct + { + uint8_t normal:3; // Bits TT<4:2> are set to on a normal + // register window trap + uint8_t other:3; // Bits TT<4:2> are set to on an "otherwin" + // register window trap + } wstateFields; + }; + union + { + uint64_t ver; // Version + struct + { + uint64_t maxwin:5; // Max CWP value + const uint64_t :2; // Reserved bits + uint64_t maxtl:8; // Maximum trap level + const uint64_t :8; // Reserved bits + uint64_t mask:8; // Processor mask set revision number + uint64_t impl:16; // Implementation identification number + uint64_t manuf:16; // Manufacturer code + } verFields; + }; + union + { + uint64_t fsr; // Floating-Point State Register + struct + { + union + { + uint64_t cexc:5; // Current excpetion + struct + { + uint64_t nxc:1; // Inexact + uint64_t dzc:1; // Divide by zero + uint64_t ufc:1; // Underflow + uint64_t ofc:1; // Overflow + uint64_t nvc:1; // Invalid operand + } cexecFields:5; + } :5; + union + { + uint64_t aexc:5; // Accrued exception + struct + { + uint64_t nxc:1; // Inexact + uint64_t dzc:1; // Divide by zero + uint64_t ufc:1; // Underflow + uint64_t ofc:1; // Overflow + uint64_t nvc:1; // Invalid operand + } aexecFields:5; + } :5; + uint64_t fcc0:2; // Floating-Point condtion codes + const uint64_t :1; // Reserved bits + uint64_t qne:1; // Deferred trap queue not empty + // with no queue, it should read 0 + uint64_t ftt:3; // Floating-Point trap type + uint64_t ver:3; // Version (of the FPU) + const uint64_t :2; // Reserved bits + uint64_t ns:1; // Nonstandard floating point + union + { + uint64_t tem:5; // Trap Enable Mask + struct + { + uint64_t nxm:1; // Inexact + uint64_t dzm:1; // Divide by zero + uint64_t ufm:1; // Underflow + uint64_t ofm:1; // Overflow + uint64_t nvm:1; // Invalid operand + } temFields:5; + } :5; + const uint64_t :2; // Reserved bits + uint64_t rd:2; // Rounding direction + uint64_t fcc1:2; // Floating-Point condition codes + uint64_t fcc2:2; // Floating-Point condition codes + uint64_t fcc3:2; // Floating-Point condition codes + const uint64_t :26; // Reserved bits + } fsrFields; + } + union + { + uint8_t fprs; // Floating-Point Register State + struct + { + uint8_t dl:1; // Dirty lower + uint8_t du:1; // Dirty upper + fef:1; // FPRS enable floating-Point + } fprsFields; }; - void inline serialize(std::ostream & os) + void serialize(std::ostream & os) { - SERIALIZE_ARRAY(regs, 32); + SERIALIZE_SCALAR(pstate); + SERIAlIZE_SCALAR(tba); + SERIALIZE_SCALAR(y); + SERIALIZE_SCALAR(pil); + SERIALIZE_SCALAR(cwp); + SERIALIZE_ARRAY(tt, MaxTL); + SERIALIZE_SCALAR(ccr); + SERIALIZE_SCALAR(asi); + SERIALIZE_SCALAR(tl); + SERIALIZE_SCALAR(tpc); + SERIALIZE_SCALAR(tnpc); + SERIALIZE_ARRAY(tstate, MaxTL); + SERIALIZE_SCALAR(tick); + SERIALIZE_SCALAR(cansave); + SERIALIZE_SCALAR(canrestore); + SERIALIZE_SCALAR(otherwin); + SERIALIZE_SCALAR(cleanwin); + SERIALIZE_SCALAR(wstate); + SERIALIZE_SCALAR(ver); + SERIALIZE_SCALAR(fsr); + SERIALIZE_SCALAR(fprs); } - void inline unserialize(Checkpoint &*cp, const std::string §ion) + void unserialize(Checkpoint &* cp, std::string & section) { - UNSERIALIZE_ARRAY(regs, 32); + UNSERIALIZE_SCALAR(pstate); + UNSERIAlIZE_SCALAR(tba); + UNSERIALIZE_SCALAR(y); + UNSERIALIZE_SCALAR(pil); + UNSERIALIZE_SCALAR(cwp); + UNSERIALIZE_ARRAY(tt, MaxTL); + UNSERIALIZE_SCALAR(ccr); + UNSERIALIZE_SCALAR(asi); + UNSERIALIZE_SCALAR(tl); + UNSERIALIZE_SCALAR(tpc); + UNSERIALIZE_SCALAR(tnpc); + UNSERIALIZE_ARRAY(tstate, MaxTL); + UNSERIALIZE_SCALAR(tick); + UNSERIALIZE_SCALAR(cansave); + UNSERIALIZE_SCALAR(canrestore); + UNSERIALIZE_SCALAR(otherwin); + UNSERIALIZE_SCALAR(cleanwin); + UNSERIALIZE_SCALAR(wstate); + UNSERIALIZE_SCALAR(ver); + UNSERIALIZE_SCALAR(fsr); + UNSERIALIZE_SCALAR(fprs); } + }; - class FloatRegFile - { - private: - //By using the largest data type, we ensure everything - //is aligned correctly in memory - union - { - double double rawRegs[16]; - uint64_t regDump[32]; - }; - class QuadRegs - { - private: - FloatRegFile * parent; - public: - QuadRegs(FloatRegFile * p) : parent(p) {;} - double double & operator [] (RegIndex index) - { - //Quad floats are index by the single - //precision register the start on, - //and only 16 should be accessed - index = (index >> 2) & 0xF; - return parent->rawRegs[index]; - } - }; - class DoubleRegs - { - private: - FloatRegFile * parent; - public: - DoubleRegs(FloatRegFile * p) : parent(p) {;} - double & operator [] (RegIndex index) - { - //Double floats are index by the single - //precision register the start on, - //and only 32 should be accessed - index = (index >> 1) & 0x1F - return ((double [])parent->rawRegs)[index]; - } - } - class SingleRegs - { - private: - FloatRegFile * parent; - public: - SingleRegs(FloatRegFile * p) : parent(p) {;} - double & operator [] (RegFile index) - { - //Only 32 single floats should be accessed - index &= 0x1F - return ((float [])parent->rawRegs)[index]; - } - } - public: - void inline serialize(std::ostream & os) - { - SERIALIZE_ARRAY(regDump, 32); - } + typedef union + { + IntReg intreg; + FloatReg fpreg; + MiscReg ctrlreg; + } AnyReg; - void inline unserialize(Checkpoint &* cp, std::string & section) - { - UNSERIALIZE_ARRAY(regDump, 32); - } + struct RegFile + { + IntRegFile intRegFile; // (signed) integer register file + FloatRegFile floatRegFile; // floating point register file + MiscRegFile miscRegFile; // control register file - QuadRegs quadRegs; - DoubleRegs doubleRegs; - SingleRegs singleRegs; - FloatRegFile() : quadRegs(this), doubleRegs(this), singleRegs(this) - {;} - }; + Addr pc; // Program Counter + Addr npc; // Next Program Counter - // control register file contents - typedef uint64_t MiscReg; - // The control registers, broken out into fields - class MiscRegFile - { - public: - union - { - uint16_t pstate; // Process State Register - struct - { - uint16_t ag:1; // Alternate Globals - uint16_t ie:1; // Interrupt enable - uint16_t priv:1; // Privelege mode - uint16_t am:1; // Address mask - uint16_t pef:1; // PSTATE enable floating-point - uint16_t red:1; // RED (reset, error, debug) state - uint16_t mm:2; // Memory Model - uint16_t tle:1; // Trap little-endian - uint16_t cle:1; // Current little-endian - } pstateFields; - } - uint64_t tba; // Trap Base Address - union - { - uint64_t y; // Y (used in obsolete multiplication) - struct - { - uint64_t value:32; // The actual value stored in y - const uint64_t :32; // reserved bits - } yFields; - } - uint8_t pil; // Process Interrupt Register - uint8_t cwp; // Current Window Pointer - uint16_t tt[MaxTL]; // Trap Type (Type of trap which occured on the previous level) - union - { - uint8_t ccr; // Condition Code Register - struct - { - union - { - uint8_t icc:4; // 32-bit condition codes - struct - { - uint8_t c:1; // Carry - uint8_t v:1; // Overflow - uint8_t z:1; // Zero - uint8_t n:1; // Negative - } iccFields:4; - } :4; - union - { - uint8_t xcc:4; // 64-bit condition codes - struct - { - uint8_t c:1; // Carry - uint8_t v:1; // Overflow - uint8_t z:1; // Zero - uint8_t n:1; // Negative - } xccFields:4; - } :4; - } ccrFields; - } - uint8_t asi; // Address Space Identifier - uint8_t tl; // Trap Level - uint64_t tpc[MaxTL]; // Trap Program Counter (value from previous trap level) - uint64_t tnpc[MaxTL]; // Trap Next Program Counter (value from previous trap level) - union - { - uint64_t tstate[MaxTL]; // Trap State - struct - { - //Values are from previous trap level - uint64_t cwp:5; // Current Window Pointer - const uint64_t :2; // Reserved bits - uint64_t pstate:10; // Process State - const uint64_t :6; // Reserved bits - uint64_t asi:8; // Address Space Identifier - uint64_t ccr:8; // Condition Code Register - } tstateFields[MaxTL]; - } - union - { - uint64_t tick; // Hardware clock-tick counter - struct - { - uint64_t counter:63; // Clock-tick count - uint64_t npt:1; // Non-priveleged trap - } tickFields; - } - uint8_t cansave; // Savable windows - uint8_t canrestore; // Restorable windows - uint8_t otherwin; // Other windows - uint8_t cleanwin; // Clean windows - union - { - uint8_t wstate; // Window State - struct - { - uint8_t normal:3; // Bits TT<4:2> are set to on a normal - // register window trap - uint8_t other:3; // Bits TT<4:2> are set to on an "otherwin" - // register window trap - } wstateFields; - } - union - { - uint64_t ver; // Version - struct - { - uint64_t maxwin:5; // Max CWP value - const uint64_t :2; // Reserved bits - uint64_t maxtl:8; // Maximum trap level - const uint64_t :8; // Reserved bits - uint64_t mask:8; // Processor mask set revision number - uint64_t impl:16; // Implementation identification number - uint64_t manuf:16; // Manufacturer code - } verFields; - } - union - { - uint64_t fsr; // Floating-Point State Register - struct - { - union - { - uint64_t cexc:5; // Current excpetion - struct - { - uint64_t nxc:1; // Inexact - uint64_t dzc:1; // Divide by zero - uint64_t ufc:1; // Underflow - uint64_t ofc:1; // Overflow - uint64_t nvc:1; // Invalid operand - } cexecFields:5; - } :5; - union - { - uint64_t aexc:5; // Accrued exception - struct - { - uint64_t nxc:1; // Inexact - uint64_t dzc:1; // Divide by zero - uint64_t ufc:1; // Underflow - uint64_t ofc:1; // Overflow - uint64_t nvc:1; // Invalid operand - } aexecFields:5; - } :5; - uint64_t fcc0:2; // Floating-Point condtion codes - const uint64_t :1; // Reserved bits - uint64_t qne:1; // Deferred trap queue not empty - // with no queue, it should read 0 - uint64_t ftt:3; // Floating-Point trap type - uint64_t ver:3; // Version (of the FPU) - const uint64_t :2; // Reserved bits - uint64_t ns:1; // Nonstandard floating point - union - { - uint64_t tem:5; // Trap Enable Mask - struct - { - uint64_t nxm:1; // Inexact - uint64_t dzm:1; // Divide by zero - uint64_t ufm:1; // Underflow - uint64_t ofm:1; // Overflow - uint64_t nvm:1; // Invalid operand - } temFields:5; - } :5; - const uint64_t :2; // Reserved bits - uint64_t rd:2; // Rounding direction - uint64_t fcc1:2; // Floating-Point condition codes - uint64_t fcc2:2; // Floating-Point condition codes - uint64_t fcc3:2; // Floating-Point condition codes - const uint64_t :26; // Reserved bits - } fsrFields; - } - union - { - uint8_t fprs; // Floating-Point Register State - struct - { - dl:1; // Dirty lower - du:1; // Dirty upper - fef:1; // FPRS enable floating-Point - } fprsFields; - }; + void serialize(std::ostream &os); + void unserialize(Checkpoint *cp, const std::string §ion); + }; - void serialize(std::ostream & os) - { - SERIALIZE_SCALAR(pstate); - SERIAlIZE_SCALAR(tba); - SERIALIZE_SCALAR(y); - SERIALIZE_SCALAR(pil); - SERIALIZE_SCALAR(cwp); - SERIALIZE_ARRAY(tt, MaxTL); - SERIALIZE_SCALAR(ccr); - SERIALIZE_SCALAR(asi); - SERIALIZE_SCALAR(tl); - SERIALIZE_SCALAR(tpc); - SERIALIZE_SCALAR(tnpc); - SERIALIZE_ARRAY(tstate, MaxTL); - SERIALIZE_SCALAR(tick); - SERIALIZE_SCALAR(cansave); - SERIALIZE_SCALAR(canrestore); - SERIALIZE_SCALAR(otherwin); - SERIALIZE_SCALAR(cleanwin); - SERIALIZE_SCALAR(wstate); - SERIALIZE_SCALAR(ver); - SERIALIZE_SCALAR(fsr); - SERIALIZE_SCALAR(fprs); - } + static StaticInstPtr decodeInst(MachInst); - void unserialize(Checkpoint &* cp, std::string & section) - { - UNSERIALIZE_SCALAR(pstate); - UNSERIAlIZE_SCALAR(tba); - UNSERIALIZE_SCALAR(y); - UNSERIALIZE_SCALAR(pil); - UNSERIALIZE_SCALAR(cwp); - UNSERIALIZE_ARRAY(tt, MaxTL); - UNSERIALIZE_SCALAR(ccr); - UNSERIALIZE_SCALAR(asi); - UNSERIALIZE_SCALAR(tl); - UNSERIALIZE_SCALAR(tpc); - UNSERIALIZE_SCALAR(tnpc); - UNSERIALIZE_ARRAY(tstate, MaxTL); - UNSERIALIZE_SCALAR(tick); - UNSERIALIZE_SCALAR(cansave); - UNSERIALIZE_SCALAR(canrestore); - UNSERIALIZE_SCALAR(otherwin); - UNSERIALIZE_SCALAR(cleanwin); - UNSERIALIZE_SCALAR(wstate); - UNSERIALIZE_SCALAR(ver); - UNSERIALIZE_SCALAR(fsr); - UNSERIALIZE_SCALAR(fprs); - } - }; + // return a no-op instruction... used for instruction fetch faults + static const MachInst NoopMachInst; - typedef union - { - IntReg intreg; - FloatReg fpreg; - MiscReg ctrlreg; - } AnyReg; + // Instruction address compression hooks + static inline Addr realPCToFetchPC(const Addr &addr) + { + return addr; + } - struct RegFile - { - IntRegFile intRegFile; // (signed) integer register file - FloatRegFile floatRegFile; // floating point register file - MiscRegFile miscRegFile; // control register file + static inline Addr fetchPCToRealPC(const Addr &addr) + { + return addr; + } - Addr pc; // Program Counter - Addr npc; // Next Program Counter + // the size of "fetched" instructions (not necessarily the size + // of real instructions for PISA) + static inline size_t fetchInstSize() + { + return sizeof(MachInst); + } - void serialize(std::ostream &os); - void unserialize(Checkpoint *cp, const std::string §ion); - }; - - static StaticInstPtr decodeInst(MachInst); - - // return a no-op instruction... used for instruction fetch faults - static const MachInst NoopMachInst; - - // Instruction address compression hooks - static inline Addr realPCToFetchPC(const Addr &addr) - { - return addr; - } - - static inline Addr fetchPCToRealPC(const Addr &addr) - { - return addr; - } - - // the size of "fetched" instructions (not necessarily the size - // of real instructions for PISA) - static inline size_t fetchInstSize() - { - return sizeof(MachInst); - } - - /** - * Function to insure ISA semantics about 0 registers. - * @param xc The execution context. - */ - template - static void zeroRegisters(XC *xc); + /** + * Function to insure ISA semantics about 0 registers. + * @param xc The execution context. + */ + template + static void zeroRegisters(XC *xc); }; - -typedef SPARCISA TheISA; - -typedef TheISA::MachInst MachInst; -typedef TheISA::Addr Addr; -typedef TheISA::RegIndex RegIndex; -typedef TheISA::IntReg IntReg; -typedef TheISA::IntRegFile IntRegFile; -typedef TheISA::FloatReg FloatReg; -typedef TheISA::FloatRegFile FloatRegFile; -typedef TheISA::MiscReg MiscReg; -typedef TheISA::MiscRegFile MiscRegFile; -typedef TheISA::AnyReg AnyReg; -typedef TheISA::RegFile RegFile; - const int VMPageSize = TheISA::VMPageSize; const int LogVMPageSize = TheISA::LogVMPageSize; const int ZeroReg = TheISA::ZeroReg; const int BranchPredAddrShiftAmt = TheISA::BranchPredAddrShiftAmt; const int MaxAddr = (Addr)-1; -#ifndef FULL_SYSTEM -class SyscallReturn { - public: - template - SyscallReturn(T v, bool s) - { - retval = (uint64_t)v; - success = s; - } +#if !FULL_SYSTEM +class SyscallReturn +{ + public: + template + SyscallReturn(T v, bool s) + { + retval = (uint64_t)v; + success = s; + } - template - SyscallReturn(T v) - { - success = (v >= 0); - retval = (uint64_t)v; - } + template + SyscallReturn(T v) + { + success = (v >= 0); + retval = (uint64_t)v; + } - ~SyscallReturn() {} + ~SyscallReturn() {} - SyscallReturn& operator=(const SyscallReturn& s) { - retval = s.retval; - success = s.success; - return *this; - } + SyscallReturn& operator=(const SyscallReturn& s) + { + retval = s.retval; + success = s.success; + return *this; + } - bool successful() { return success; } - uint64_t value() { return retval; } + bool successful() { return success; } + uint64_t value() { return retval; } - - private: - uint64_t retval; - bool success; + private: + uint64_t retval; + bool success; }; #endif -#ifdef FULL_SYSTEM +#if FULL_SYSTEM #include "arch/alpha/ev5.hh" #endif From 5aa0669b52cb1a1e5fdb6a372d6b481ebb46b02a Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 7 Mar 2006 04:34:21 -0500 Subject: [PATCH 158/180] Changed the include paths to take advantage of the os specific directories. --HG-- extra : convert_revision : 287d5323268806adc7cfb9cb3600605e837e3764 --- arch/sparc/linux/process.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/sparc/linux/process.cc b/arch/sparc/linux/process.cc index d1c439d72..ebfbb2f64 100644 --- a/arch/sparc/linux/process.cc +++ b/arch/sparc/linux/process.cc @@ -27,7 +27,7 @@ */ #include "arch/sparc/common_syscall_emul.hh" -#include "arch/sparc/linux_process.hh" +#include "arch/sparc/linux/process.hh" #include "arch/sparc/isa_traits.hh" #include "base/trace.hh" From b0eeb15d72722f8ae5a1e653ee5bcbf591c1531b Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 7 Mar 2006 07:34:43 -0500 Subject: [PATCH 159/180] Fixed up some issues to be more compilable. --HG-- extra : convert_revision : a70d9cdbe26f44fa9d94e1cbadd92f8c909596ec --- arch/sparc/isa_traits.hh | 143 +++++++++++++++------------------------ 1 file changed, 54 insertions(+), 89 deletions(-) diff --git a/arch/sparc/isa_traits.hh b/arch/sparc/isa_traits.hh index 5a58bbaef..0fdac1662 100644 --- a/arch/sparc/isa_traits.hh +++ b/arch/sparc/isa_traits.hh @@ -76,8 +76,12 @@ namespace SparcISA MaxTL = 4, // semantically meaningful register indices - ZeroReg = 0 // architecturally meaningful + ZeroReg = 0, // architecturally meaningful // the rest of these depend on the ABI + //8K. This value is implmentation specific, and should probably + //be somewhere else. + LogVMPageSize = 13, + VMPageSize = (1 << LogVMPageSize) }; typedef uint64_t IntReg; @@ -99,6 +103,12 @@ namespace SparcISA void unserialize(Checkpoint *cp, const std::string §ion); + typedef float float32_t; + typedef double float64_t; + //FIXME This actually usually refers to a 10 byte float, rather than a + //16 byte float as required. This data type may have to be emulated. + typedef long double float128_t; + class FloatRegFile { private: @@ -106,7 +116,7 @@ namespace SparcISA //is aligned correctly in memory union { - long double rawRegs[16]; + float128_t rawRegs[16]; uint64_t regDump[32]; }; class QuadRegs @@ -115,7 +125,7 @@ namespace SparcISA FloatRegFile * parent; public: QuadRegs(FloatRegFile * p) : parent(p) {;} - long double & operator [] (RegIndex index) + float128_t & operator [] (RegIndex index) { //Quad floats are index by the single //precision register the start on, @@ -130,13 +140,13 @@ namespace SparcISA FloatRegFile * parent; public: DoubleRegs(FloatRegFile * p) : parent(p) {;} - double & operator [] (RegIndex index) + float64_t & operator [] (RegIndex index) { //Double floats are index by the single //precision register the start on, //and only 32 should be accessed index = (index >> 1) & 0x1F; - return ((double *)parent->rawRegs)[index]; + return ((float64_t *)parent->rawRegs)[index]; } }; class SingleRegs @@ -145,11 +155,11 @@ namespace SparcISA FloatRegFile * parent; public: SingleRegs(FloatRegFile * p) : parent(p) {;} - float & operator [] (RegIndex index) + float32_t & operator [] (RegIndex index) { //Only 32 single floats should be accessed index &= 0x1F; - return ((float *)parent->rawRegs)[index]; + return ((float32_t *)parent->rawRegs)[index]; } }; public: @@ -193,7 +203,7 @@ namespace SparcISA struct { uint64_t value:32; // The actual value stored in y - const uint64_t :32; // reserved bits + uint64_t :32; // reserved bits } yFields; }; uint8_t pil; // Process Interrupt Register @@ -214,8 +224,8 @@ namespace SparcISA uint8_t v:1; // Overflow uint8_t z:1; // Zero uint8_t n:1; // Negative - } iccFields:4; - } :4; + } iccFields; + }; union { uint8_t xcc:4; // 64-bit condition codes @@ -225,8 +235,8 @@ namespace SparcISA uint8_t v:1; // Overflow uint8_t z:1; // Zero uint8_t n:1; // Negative - } xccFields:4; - } :4; + } xccFields; + }; } ccrFields; }; uint8_t asi; // Address Space Identifier @@ -242,9 +252,9 @@ namespace SparcISA { //Values are from previous trap level uint64_t cwp:5; // Current Window Pointer - const uint64_t :2; // Reserved bits + uint64_t :2; // Reserved bits uint64_t pstate:10; // Process State - const uint64_t :6; // Reserved bits + uint64_t :6; // Reserved bits uint64_t asi:8; // Address Space Identifier uint64_t ccr:8; // Condition Code Register } tstateFields[MaxTL]; @@ -257,7 +267,7 @@ namespace SparcISA uint64_t counter:63; // Clock-tick count uint64_t npt:1; // Non-priveleged trap } tickFields; - } + }; uint8_t cansave; // Savable windows uint8_t canrestore; // Restorable windows uint8_t otherwin; // Other windows @@ -279,9 +289,9 @@ namespace SparcISA struct { uint64_t maxwin:5; // Max CWP value - const uint64_t :2; // Reserved bits + uint64_t :2; // Reserved bits uint64_t maxtl:8; // Maximum trap level - const uint64_t :8; // Reserved bits + uint64_t :8; // Reserved bits uint64_t mask:8; // Processor mask set revision number uint64_t impl:16; // Implementation identification number uint64_t manuf:16; // Manufacturer code @@ -302,8 +312,8 @@ namespace SparcISA uint64_t ufc:1; // Underflow uint64_t ofc:1; // Overflow uint64_t nvc:1; // Invalid operand - } cexecFields:5; - } :5; + } cexecFields; + }; union { uint64_t aexc:5; // Accrued exception @@ -314,15 +324,15 @@ namespace SparcISA uint64_t ufc:1; // Underflow uint64_t ofc:1; // Overflow uint64_t nvc:1; // Invalid operand - } aexecFields:5; - } :5; + } aexecFields; + }; uint64_t fcc0:2; // Floating-Point condtion codes - const uint64_t :1; // Reserved bits + uint64_t :1; // Reserved bits uint64_t qne:1; // Deferred trap queue not empty // with no queue, it should read 0 uint64_t ftt:3; // Floating-Point trap type uint64_t ver:3; // Version (of the FPU) - const uint64_t :2; // Reserved bits + uint64_t :2; // Reserved bits uint64_t ns:1; // Nonstandard floating point union { @@ -334,16 +344,16 @@ namespace SparcISA uint64_t ufm:1; // Underflow uint64_t ofm:1; // Overflow uint64_t nvm:1; // Invalid operand - } temFields:5; - } :5; - const uint64_t :2; // Reserved bits + } temFields; + }; + uint64_t :2; // Reserved bits uint64_t rd:2; // Rounding direction uint64_t fcc1:2; // Floating-Point condition codes uint64_t fcc2:2; // Floating-Point condition codes uint64_t fcc3:2; // Floating-Point condition codes - const uint64_t :26; // Reserved bits + uint64_t :26; // Reserved bits } fsrFields; - } + }; union { uint8_t fprs; // Floating-Point Register State @@ -351,61 +361,22 @@ namespace SparcISA { uint8_t dl:1; // Dirty lower uint8_t du:1; // Dirty upper - fef:1; // FPRS enable floating-Point + uint8_t fef:1; // FPRS enable floating-Point } fprsFields; }; - void serialize(std::ostream & os) - { - SERIALIZE_SCALAR(pstate); - SERIAlIZE_SCALAR(tba); - SERIALIZE_SCALAR(y); - SERIALIZE_SCALAR(pil); - SERIALIZE_SCALAR(cwp); - SERIALIZE_ARRAY(tt, MaxTL); - SERIALIZE_SCALAR(ccr); - SERIALIZE_SCALAR(asi); - SERIALIZE_SCALAR(tl); - SERIALIZE_SCALAR(tpc); - SERIALIZE_SCALAR(tnpc); - SERIALIZE_ARRAY(tstate, MaxTL); - SERIALIZE_SCALAR(tick); - SERIALIZE_SCALAR(cansave); - SERIALIZE_SCALAR(canrestore); - SERIALIZE_SCALAR(otherwin); - SERIALIZE_SCALAR(cleanwin); - SERIALIZE_SCALAR(wstate); - SERIALIZE_SCALAR(ver); - SERIALIZE_SCALAR(fsr); - SERIALIZE_SCALAR(fprs); - } + void serialize(std::ostream & os); - void unserialize(Checkpoint &* cp, std::string & section) - { - UNSERIALIZE_SCALAR(pstate); - UNSERIAlIZE_SCALAR(tba); - UNSERIALIZE_SCALAR(y); - UNSERIALIZE_SCALAR(pil); - UNSERIALIZE_SCALAR(cwp); - UNSERIALIZE_ARRAY(tt, MaxTL); - UNSERIALIZE_SCALAR(ccr); - UNSERIALIZE_SCALAR(asi); - UNSERIALIZE_SCALAR(tl); - UNSERIALIZE_SCALAR(tpc); - UNSERIALIZE_SCALAR(tnpc); - UNSERIALIZE_ARRAY(tstate, MaxTL); - UNSERIALIZE_SCALAR(tick); - UNSERIALIZE_SCALAR(cansave); - UNSERIALIZE_SCALAR(canrestore); - UNSERIALIZE_SCALAR(otherwin); - UNSERIALIZE_SCALAR(cleanwin); - UNSERIALIZE_SCALAR(wstate); - UNSERIALIZE_SCALAR(ver); - UNSERIALIZE_SCALAR(fsr); - UNSERIALIZE_SCALAR(fprs); - } + void unserialize(Checkpoint * cp, std::string & section); }; + typedef union + { + float32_t singReg; + float64_t doubReg; + float128_t quadReg; + } FloatReg; + typedef union { IntReg intreg; @@ -426,25 +397,25 @@ namespace SparcISA void unserialize(Checkpoint *cp, const std::string §ion); }; - static StaticInstPtr decodeInst(MachInst); + StaticInstPtr decodeInst(MachInst); // return a no-op instruction... used for instruction fetch faults - static const MachInst NoopMachInst; + extern const MachInst NoopMachInst; // Instruction address compression hooks - static inline Addr realPCToFetchPC(const Addr &addr) + inline Addr realPCToFetchPC(const Addr &addr) { return addr; } - static inline Addr fetchPCToRealPC(const Addr &addr) + inline Addr fetchPCToRealPC(const Addr &addr) { return addr; } // the size of "fetched" instructions (not necessarily the size // of real instructions for PISA) - static inline size_t fetchInstSize() + inline size_t fetchInstSize() { return sizeof(MachInst); } @@ -454,15 +425,9 @@ namespace SparcISA * @param xc The execution context. */ template - static void zeroRegisters(XC *xc); + void zeroRegisters(XC *xc); }; -const int VMPageSize = TheISA::VMPageSize; -const int LogVMPageSize = TheISA::LogVMPageSize; -const int ZeroReg = TheISA::ZeroReg; -const int BranchPredAddrShiftAmt = TheISA::BranchPredAddrShiftAmt; -const int MaxAddr = (Addr)-1; - #if !FULL_SYSTEM class SyscallReturn { From 531216e9f385c346433a02a83d60ad5d03ced47f Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 7 Mar 2006 09:11:00 -0500 Subject: [PATCH 160/180] Got rid of some commented out code. --HG-- extra : convert_revision : 7de82ed72650d877cdb2ecb66c61ae41117658d9 --- arch/alpha/isa_traits.hh | 35 +---------------------------------- 1 file changed, 1 insertion(+), 34 deletions(-) diff --git a/arch/alpha/isa_traits.hh b/arch/alpha/isa_traits.hh index a551db485..742539e89 100644 --- a/arch/alpha/isa_traits.hh +++ b/arch/alpha/isa_traits.hh @@ -303,37 +303,7 @@ extern const int reg_redir[NumIntRegs]; template void zeroRegisters(XC *xc); - -//typedef AlphaISA TheISA; - -//typedef TheISA::MachInst MachInst; -//typedef TheISA::Addr Addr; -//typedef TheISA::RegIndex RegIndex; -//typedef TheISA::IntReg IntReg; -//typedef TheISA::IntRegFile IntRegFile; -//typedef TheISA::FloatReg FloatReg; -//typedef TheISA::FloatRegFile FloatRegFile; -//typedef TheISA::MiscReg MiscReg; -//typedef TheISA::MiscRegFile MiscRegFile; -//typedef TheISA::AnyReg AnyReg; -//typedef TheISA::RegFile RegFile; - -//const int NumIntRegs = TheISA::NumIntRegs; -//const int NumFloatRegs = TheISA::NumFloatRegs; -//const int NumMiscRegs = TheISA::NumMiscRegs; -//const int TotalNumRegs = TheISA::TotalNumRegs; -//const int VMPageSize = TheISA::VMPageSize; -//const int LogVMPageSize = TheISA::LogVMPageSize; -//const int ZeroReg = TheISA::ZeroReg; -//const int StackPointerReg = TheISA::StackPointerReg; -//const int GlobalPointerReg = TheISA::GlobalPointerReg; -//const int ReturnAddressReg = TheISA::ReturnAddressReg; -//const int ReturnValueReg = TheISA::ReturnValueReg; -//const int ArgumentReg0 = TheISA::ArgumentReg0; -//const int ArgumentReg1 = TheISA::ArgumentReg1; -//const int ArgumentReg2 = TheISA::ArgumentReg2; -//const int BranchPredAddrShiftAmt = TheISA::BranchPredAddrShiftAmt; -const Addr MaxAddr = (Addr)-1; + const Addr MaxAddr = (Addr)-1; }; #if !FULL_SYSTEM @@ -386,9 +356,6 @@ AlphaISA::makeExtMI(AlphaISA::MachInst inst, const uint64_t &pc) { } #if FULL_SYSTEM -//typedef TheISA::InternalProcReg InternalProcReg; -//const int NumInternalProcRegs = TheISA::NumInternalProcRegs; -//const int NumInterruptLevels = TheISA::NumInterruptLevels; #include "arch/alpha/ev5.hh" #endif From cd62fed1a7c535befaa00c8775de78f9f29b1274 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 7 Mar 2006 09:34:24 -0500 Subject: [PATCH 161/180] The a.out and ecoff object file formats will only be supported on Alpha for now. arch/SConscript: aout_machdep.h and ecoff_machdep.h are no longer bridging headers, since support of these formats is limitted to alpha. base/loader/exec_aout.h: Include the alpha specific version of aout_machdep.h, since only the alpha version of aout will be supported for now. base/loader/exec_ecoff.h: Include the alpha specific version of ecoff_machdep.h, since only the alpha version of ecoff will be supported for now. --HG-- extra : convert_revision : 15328aae54538c26d2c10d7476501e0daa3d22d0 --- arch/SConscript | 2 -- base/loader/exec_aout.h | 3 ++- base/loader/exec_ecoff.h | 3 ++- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/SConscript b/arch/SConscript index b4b7a1ddb..380cda307 100644 --- a/arch/SConscript +++ b/arch/SConscript @@ -48,8 +48,6 @@ isa_switch_hdrs = Split(''' isa_traits.hh tlb.hh process.hh - aout_machdep.h - ecoff_machdep.h arguments.hh stacktrace.hh vtophys.hh diff --git a/base/loader/exec_aout.h b/base/loader/exec_aout.h index 3863a92fb..eed44baee 100644 --- a/base/loader/exec_aout.h +++ b/base/loader/exec_aout.h @@ -55,6 +55,7 @@ (N_GETMAGIC(ex) != NMAGIC && N_GETMAGIC(ex) != OMAGIC && \ N_GETMAGIC(ex) != ZMAGIC) -#include "arch/aout_machdep.h" +//Only alpha will be able to load aout for now +#include "arch/alpha/aout_machdep.h" #endif /* !_SYS_EXEC_AOUT_H_ */ diff --git a/base/loader/exec_ecoff.h b/base/loader/exec_ecoff.h index 79cd22a6e..555589806 100644 --- a/base/loader/exec_ecoff.h +++ b/base/loader/exec_ecoff.h @@ -37,7 +37,8 @@ #ifndef _SYS_EXEC_ECOFF_H_ #define _SYS_EXEC_ECOFF_H_ -#include "arch/ecoff_machdep.h" +//Only alpha will be able to load ecoff files for now +#include "arch/alpha/ecoff_machdep.h" struct ecoff_filehdr { coff_ushort f_magic; /* magic number */ From 8106a804508a42455650082a83f4cdb366ca5148 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 7 Mar 2006 14:08:01 -0500 Subject: [PATCH 162/180] Pushed ev5.hh out of the non-alpha code. arch/SConscript: ev5 should now be contained within alpha specific code. arch/alpha/ev5.cc: arch/alpha/isa_traits.hh: Added getInstAsid and getDataAsid functions. These should be removed when the SimpleScalar cpu model is removed. arch/sparc/isa_traits.hh: Added getInstAsid and getDataAsid functions. These should be removed when the SimpleScalar cpu model is removed. Also made some small fixes. cpu/o3/alpha_cpu.hh: Added typedefs which are required now that there isn't a using namespace EV5. cpu/o3/alpha_cpu_impl.hh: Some small changes so that ev5.hh isn't needed directly. cpu/o3/cpu.hh: Removed including ev5.hh, and pushed retrieving the Asid into the MiscRegFile. cpu/o3/regfile.hh: Removed the include of ev5.hh, using namespace EV5, and the now redundant ipr array. --HG-- extra : convert_revision : 5ef8f69435a3a888a3f06d0095d89326dafb33fd --- arch/SConscript | 1 - arch/alpha/ev5.cc | 12 ++++++++++++ arch/alpha/isa_traits.hh | 5 +++++ arch/sparc/isa_traits.hh | 14 ++++++++++++-- cpu/o3/alpha_cpu.hh | 2 ++ cpu/o3/alpha_cpu_impl.hh | 3 ++- cpu/o3/cpu.hh | 9 ++------- cpu/o3/regfile.hh | 3 --- 8 files changed, 35 insertions(+), 14 deletions(-) diff --git a/arch/SConscript b/arch/SConscript index 380cda307..0533261a2 100644 --- a/arch/SConscript +++ b/arch/SConscript @@ -52,7 +52,6 @@ isa_switch_hdrs = Split(''' stacktrace.hh vtophys.hh faults.hh - ev5.hh ''') # Generate the header. target[0] is the full path of the output diff --git a/arch/alpha/ev5.cc b/arch/alpha/ev5.cc index e313c1a1c..47ada6de6 100644 --- a/arch/alpha/ev5.cc +++ b/arch/alpha/ev5.cc @@ -152,6 +152,18 @@ ExecContext::hwrei() return NoFault; } +int +AlphaISA::MiscRegFile::getInstAsid() +{ + return EV5::ITB_ASN_ASN(ipr[IPR_ITB_ASN]); +} + +int +AlphaISA::MiscRegFile::getDataAsid() +{ + return EV5::DTB_ASN_ASN(ipr[IPR_DTB_ASN]); +} + void AlphaISA::MiscRegFile::clearIprs() { diff --git a/arch/alpha/isa_traits.hh b/arch/alpha/isa_traits.hh index 742539e89..be6d5111d 100644 --- a/arch/alpha/isa_traits.hh +++ b/arch/alpha/isa_traits.hh @@ -166,6 +166,11 @@ extern const int reg_redir[NumIntRegs]; public: MiscReg readReg(int misc_reg); + //These functions should be removed once the simplescalar cpu model + //has been replaced. + int getInstAsid(); + int getDataAsid(); + MiscReg readRegWithEffect(int misc_reg, Fault &fault, ExecContext *xc); Fault setReg(int misc_reg, const MiscReg &val); diff --git a/arch/sparc/isa_traits.hh b/arch/sparc/isa_traits.hh index 0fdac1662..73daae8a9 100644 --- a/arch/sparc/isa_traits.hh +++ b/arch/sparc/isa_traits.hh @@ -57,7 +57,7 @@ class StaticInstPtr; namespace SparcISA { typedef uint32_t MachInst; - typedef uint64_t Addr; + typedef uint64_t ExtMachInst; typedef uint8_t RegIndex; enum @@ -179,7 +179,7 @@ namespace SparcISA // The control registers, broken out into fields class MiscRegFile { - public: + private: union { uint16_t pstate; // Process State Register @@ -365,6 +365,16 @@ namespace SparcISA } fprsFields; }; + public: + MiscReg readReg(int misc_reg); + + MiscReg readRegWithEffect(int misc_reg, Fault &fault, ExecContext *xc); + + Fault setReg(int misc_reg, const MiscReg &val); + + Fault setRegWithEffect(int misc_reg, const MiscReg &val, + ExecContext *xc); + void serialize(std::ostream & os); void unserialize(Checkpoint * cp, std::string & section); diff --git a/cpu/o3/alpha_cpu.hh b/cpu/o3/alpha_cpu.hh index 38c00a3a9..55fde1f1d 100644 --- a/cpu/o3/alpha_cpu.hh +++ b/cpu/o3/alpha_cpu.hh @@ -42,6 +42,8 @@ class AlphaFullCPU : public FullO3CPU protected: typedef TheISA::IntReg IntReg; typedef TheISA::MiscReg MiscReg; + typedef TheISA::RegFile RegFile; + typedef TheISA::MiscRegFile MiscRegFile; public: typedef typename Impl::Params Params; diff --git a/cpu/o3/alpha_cpu_impl.hh b/cpu/o3/alpha_cpu_impl.hh index a1c659b51..5ab9e6e75 100644 --- a/cpu/o3/alpha_cpu_impl.hh +++ b/cpu/o3/alpha_cpu_impl.hh @@ -26,6 +26,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include "arch/alpha/faults.hh" #include "base/cprintf.hh" #include "base/statistics.hh" #include "base/timebuf.hh" @@ -257,7 +258,7 @@ Fault AlphaFullCPU::hwrei() { if (!inPalMode()) - return new UnimplementedOpcodeFault; + return new AlphaISA::UnimplementedOpcodeFault; this->setNextPC(this->regFile.miscRegs.readReg(AlphaISA::IPR_EXC_ADDR)); diff --git a/cpu/o3/cpu.hh b/cpu/o3/cpu.hh index 02908887e..31a1b604b 100644 --- a/cpu/o3/cpu.hh +++ b/cpu/o3/cpu.hh @@ -49,11 +49,6 @@ #include "cpu/exec_context.hh" #include "sim/process.hh" -#if FULL_SYSTEM -#include "arch/ev5.hh" -using namespace EV5; -#endif - class FunctionalMemory; class Process; @@ -152,11 +147,11 @@ class FullO3CPU : public BaseFullCPU /** Get instruction asid. */ int getInstAsid() - { return ITB_ASN_ASN(regFile.miscRegs.readReg(TheISA::IPR_ITB_ASN)); } + { return regFile.miscRegs.getInstAsid(); } /** Get data asid. */ int getDataAsid() - { return DTB_ASN_ASN(regFile.miscRegs.readReg(TheISA::IPR_DTB_ASN)); } + { return regFile.miscRegs.getDataAsid(); } #else bool validInstAddr(Addr addr) { return thread[0]->validInstAddr(addr); } diff --git a/cpu/o3/regfile.hh b/cpu/o3/regfile.hh index 03ad2da46..1e6e10f29 100644 --- a/cpu/o3/regfile.hh +++ b/cpu/o3/regfile.hh @@ -38,10 +38,8 @@ #include "cpu/o3/comm.hh" #if FULL_SYSTEM -#include "arch/ev5.hh" #include "kern/kernel_stats.hh" -using namespace EV5; #endif // This really only depends on the ISA, and not the Impl. It might be nicer @@ -237,7 +235,6 @@ class PhysRegFile private: // This is ISA specifc stuff; remove it eventually once ISAImpl is used // IntReg palregs[NumIntRegs]; // PAL shadow registers - InternalProcReg ipr[NumInternalProcRegs]; // internal processor regs int intrflag; // interrupt flag bool pal_shadow; // using pal_shadow registers #endif From b5f65c36c756c4dc1dd8746f5f46a99a132ed13b Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 7 Mar 2006 14:34:11 -0500 Subject: [PATCH 163/180] Corrected a mispelling of "unimplemented". arch/sparc/stacktrace.hh: - Change the StackTrace code so that the class can more easily be cleaned out and reused to avoid extra allocations. - Allow trace() to accept a static instruction pointer so it can determine if the instruction is worth tracing. This is moved from the CPU. - provide constants for special meaning PCs (user, console, unknown), instead of magic numbers arch/sparc/stacktrace.hh: Added some typedefs for Addr and MachInst, and untemplatized StaticInstPtr arch/sparc/stacktrace.hh: Made Addr a global type arch/sparc/stacktrace.hh: bk cp ../alpha/stacktrace.hh stacktrace.hh --HG-- extra : convert_revision : 8fd15e5ec8d676d081380b21886234561c5f3678 --- arch/sparc/linux/process.cc | 568 ++++++++++++++++++------------------ arch/sparc/stacktrace.hh | 119 ++++++++ 2 files changed, 403 insertions(+), 284 deletions(-) create mode 100644 arch/sparc/stacktrace.hh diff --git a/arch/sparc/linux/process.cc b/arch/sparc/linux/process.cc index ebfbb2f64..fab7a4db6 100644 --- a/arch/sparc/linux/process.cc +++ b/arch/sparc/linux/process.cc @@ -141,290 +141,290 @@ osf_setsysinfoFunc(SyscallDesc *desc, int callnum, Process *process, } SyscallDesc SparcLinuxProcess::syscallDescs[] = { - /* 0 */ SyscallDesc("restart_syscall", unimplimentedFunc); - /* 1 */ SyscallDesc("exit", unimplimentedFunc); - /* 2 */ SyscallDesc("fork", unimplimentedFunc); - /* 3 */ SyscallDesc("read", unimplimentedFunc); - /* 4 */ SyscallDesc("write", unimplimentedFunc); - /* 5 */ SyscallDesc("open", unimplimentedFunc); - /* 6 */ SyscallDesc("close", unimplimentedFunc); - /* 7 */ SyscallDesc("wait4", unimplimentedFunc); - /* 8 */ SyscallDesc("creat", unimplimentedFunc); - /* 9 */ SyscallDesc("link", unimplimentedFunc); - /* 10 */ SyscallDesc("unlink", unimplimentedFunc); - /* 11 */ SyscallDesc("execv", unimplimentedFunc); - /* 12 */ SyscallDesc("chdir", unimplimentedFunc); - /* 13 */ SyscallDesc("chown", unimplimentedFunc); - /* 14 */ SyscallDesc("mknod", unimplimentedFunc); - /* 15 */ SyscallDesc("chmod", unimplimentedFunc); - /* 16 */ SyscallDesc("lchown", unimplimentedFunc); - /* 17 */ SyscallDesc("brk", unimplimentedFunc); - /* 18 */ SyscallDesc("perfctr", unimplimentedFunc); - /* 19 */ SyscallDesc("lseek", unimplimentedFunc); - /* 20 */ SyscallDesc("getpid", unimplimentedFunc); - /* 21 */ SyscallDesc("capget", unimplimentedFunc); - /* 22 */ SyscallDesc("capset", unimplimentedFunc); - /* 23 */ SyscallDesc("setuid", unimplimentedFunc); - /* 24 */ SyscallDesc("getuid", unimplimentedFunc); - /* 25 */ SyscallDesc("time", unimplimentedFunc); - /* 26 */ SyscallDesc("ptrace", unimplimentedFunc); - /* 27 */ SyscallDesc("alarm", unimplimentedFunc); - /* 28 */ SyscallDesc("sigaltstack", unimplimentedFunc); - /* 29 */ SyscallDesc("pause", unimplimentedFunc); - /* 30 */ SyscallDesc("utime", unimplimentedFunc); - /* 31 */ SyscallDesc("lchown32", unimplimentedFunc); - /* 32 */ SyscallDesc("fchown32", unimplimentedFunc); - /* 33 */ SyscallDesc("access", unimplimentedFunc); - /* 34 */ SyscallDesc("nice", unimplimentedFunc); - /* 35 */ SyscallDesc("chown32", unimplimentedFunc); - /* 36 */ SyscallDesc("sync", unimplimentedFunc); - /* 37 */ SyscallDesc("kill", unimplimentedFunc); - /* 38 */ SyscallDesc("stat", unimplimentedFunc); - /* 39 */ SyscallDesc("sendfile", unimplimentedFunc); - /* 40 */ SyscallDesc("lstat", unimplimentedFunc); - /* 41 */ SyscallDesc("dup", unimplimentedFunc); - /* 42 */ SyscallDesc("pipe", unimplimentedFunc); - /* 43 */ SyscallDesc("times", unimplimentedFunc); - /* 44 */ SyscallDesc("getuid32", unimplimentedFunc); - /* 45 */ SyscallDesc("umount2", unimplimentedFunc); - /* 46 */ SyscallDesc("setgid", unimplimentedFunc); - /* 47 */ SyscallDesc("getgid", unimplimentedFunc); - /* 48 */ SyscallDesc("signal", unimplimentedFunc); - /* 49 */ SyscallDesc("geteuid", unimplimentedFunc); - /* 50 */ SyscallDesc("getegid", unimplimentedFunc); - /* 51 */ SyscallDesc("acct", unimplimentedFunc); - /* 52 */ SyscallDesc("memory_ordering", unimplimentedFunc); - /* 53 */ SyscallDesc("getgid32", unimplimentedFunc); - /* 54 */ SyscallDesc("ioctl", unimplimentedFunc); - /* 55 */ SyscallDesc("reboot", unimplimentedFunc); - /* 56 */ SyscallDesc("mmap2", unimplimentedFunc); - /* 57 */ SyscallDesc("symlink", unimplimentedFunc); - /* 58 */ SyscallDesc("readlink", unimplimentedFunc); - /* 59 */ SyscallDesc("execve", unimplimentedFunc); - /* 60 */ SyscallDesc("umask", unimplimentedFunc); - /* 61 */ SyscallDesc("chroot", unimplimentedFunc); - /* 62 */ SyscallDesc("fstat", unimplimentedFunc); - /* 63 */ SyscallDesc("fstat64", unimplimentedFunc); - /* 64 */ SyscallDesc("getpagesize", unimplimentedFunc); - /* 65 */ SyscallDesc("msync", unimplimentedFunc); - /* 66 */ SyscallDesc("vfork", unimplimentedFunc); - /* 67 */ SyscallDesc("pread64", unimplimentedFunc); - /* 68 */ SyscallDesc("pwrite64", unimplimentedFunc); - /* 69 */ SyscallDesc("geteuid32", unimplimentedFunc); - /* 70 */ SyscallDesc("getdgid32", unimplimentedFunc); - /* 71 */ SyscallDesc("mmap", unimplimentedFunc); - /* 72 */ SyscallDesc("setreuid32", unimplimentedFunc); - /* 73 */ SyscallDesc("munmap", unimplimentedFunc); - /* 74 */ SyscallDesc("mprotect", unimplimentedFunc); - /* 75 */ SyscallDesc("madvise", unimplimentedFunc); - /* 76 */ SyscallDesc("vhangup", unimplimentedFunc); - /* 77 */ SyscallDesc("truncate64", unimplimentedFunc); - /* 78 */ SyscallDesc("mincore", unimplimentedFunc); - /* 79 */ SyscallDesc("getgroups", unimplimentedFunc); - /* 80 */ SyscallDesc("setgroups", unimplimentedFunc); - /* 81 */ SyscallDesc("getpgrp", unimplimentedFunc); - /* 82 */ SyscallDesc("setgroups32", unimplimentedFunc); - /* 83 */ SyscallDesc("setitimer", unimplimentedFunc); - /* 84 */ SyscallDesc("ftruncate64", unimplimentedFunc); - /* 85 */ SyscallDesc("swapon", unimplimentedFunc); - /* 86 */ SyscallDesc("getitimer", unimplimentedFunc); - /* 87 */ SyscallDesc("setuid32", unimplimentedFunc); - /* 88 */ SyscallDesc("sethostname", unimplimentedFunc); - /* 89 */ SyscallDesc("setgid32", unimplimentedFunc); - /* 90 */ SyscallDesc("dup2", unimplimentedFunc); - /* 91 */ SyscallDesc("setfsuid32", unimplimentedFunc); - /* 92 */ SyscallDesc("fcntl", unimplimentedFunc); - /* 93 */ SyscallDesc("select", unimplimentedFunc); - /* 94 */ SyscallDesc("setfsgid32", unimplimentedFunc); - /* 95 */ SyscallDesc("fsync", unimplimentedFunc); - /* 96 */ SyscallDesc("setpriority", unimplimentedFunc); - /* 97 */ SyscallDesc("socket", unimplimentedFunc); - /* 98 */ SyscallDesc("connect", unimplimentedFunc); - /* 99 */ SyscallDesc("accept", unimplimentedFunc); - /* 100 */ SyscallDesc("getpriority", unimplimentedFunc); - /* 101 */ SyscallDesc("rt_sigreturn", unimplimentedFunc); - /* 102 */ SyscallDesc("rt_sigaction", unimplimentedFunc); - /* 103 */ SyscallDesc("rt_sigprocmask", unimplimentedFunc); - /* 104 */ SyscallDesc("rt_sigpending", unimplimentedFunc); - /* 105 */ SyscallDesc("rt_sigtimedwait", unimplimentedFunc); - /* 106 */ SyscallDesc("rt_sigqueueinfo", unimplimentedFunc); - /* 107 */ SyscallDesc("rt_sigsuspend", unimplimentedFunc); - /* 108 */ SyscallDesc("setresuid", unimplimentedFunc); - /* 109 */ SyscallDesc("getresuid", unimplimentedFunc); - /* 110 */ SyscallDesc("setresgid", unimplimentedFunc); - /* 111 */ SyscallDesc("getresgid", unimplimentedFunc); - /* 112 */ SyscallDesc("setregid32", unimplimentedFunc); - /* 113 */ SyscallDesc("recvmsg", unimplimentedFunc); - /* 114 */ SyscallDesc("sendmsg", unimplimentedFunc); - /* 115 */ SyscallDesc("getgroups32", unimplimentedFunc); - /* 116 */ SyscallDesc("gettimeofday", unimplimentedFunc); - /* 117 */ SyscallDesc("getrusage", unimplimentedFunc); - /* 118 */ SyscallDesc("getsockopt", unimplimentedFunc); - /* 119 */ SyscallDesc("getcwd", unimplimentedFunc); - /* 120 */ SyscallDesc("readv", unimplimentedFunc); - /* 121 */ SyscallDesc("writev", unimplimentedFunc); - /* 122 */ SyscallDesc("settimeofday", unimplimentedFunc); - /* 123 */ SyscallDesc("fchown", unimplimentedFunc); - /* 124 */ SyscallDesc("fchmod", unimplimentedFunc); - /* 125 */ SyscallDesc("recvfrom", unimplimentedFunc); - /* 126 */ SyscallDesc("setreuid", unimplimentedFunc); - /* 127 */ SyscallDesc("setregid", unimplimentedFunc); - /* 128 */ SyscallDesc("rename", unimplimentedFunc); - /* 129 */ SyscallDesc("truncate", unimplimentedFunc); - /* 130 */ SyscallDesc("ftruncate", unimplimentedFunc); - /* 131 */ SyscallDesc("flock", unimplimentedFunc); - /* 132 */ SyscallDesc("lstat64", unimplimentedFunc); - /* 133 */ SyscallDesc("sendto", unimplimentedFunc); - /* 134 */ SyscallDesc("shutdown", unimplimentedFunc); - /* 135 */ SyscallDesc("socketpair", unimplimentedFunc); - /* 136 */ SyscallDesc("mkdir", unimplimentedFunc); - /* 137 */ SyscallDesc("rmdir", unimplimentedFunc); - /* 138 */ SyscallDesc("utimes", unimplimentedFunc); - /* 139 */ SyscallDesc("stat64", unimplimentedFunc); - /* 140 */ SyscallDesc("sendfile64", unimplimentedFunc); - /* 141 */ SyscallDesc("getpeername", unimplimentedFunc); - /* 142 */ SyscallDesc("futex", unimplimentedFunc); - /* 143 */ SyscallDesc("gettid", unimplimentedFunc); - /* 144 */ SyscallDesc("getrlimit", unimplimentedFunc); - /* 145 */ SyscallDesc("setrlimit", unimplimentedFunc); - /* 146 */ SyscallDesc("pivot_root", unimplimentedFunc); - /* 147 */ SyscallDesc("prctl", unimplimentedFunc); - /* 148 */ SyscallDesc("pciconfig_read", unimplimentedFunc); - /* 149 */ SyscallDesc("pciconfig_write", unimplimentedFunc); - /* 150 */ SyscallDesc("getsockname", unimplimentedFunc); - /* 151 */ SyscallDesc("inotify_init", unimplimentedFunc); - /* 152 */ SyscallDesc("inotify_add_watch", unimplimentedFunc); - /* 153 */ SyscallDesc("poll", unimplimentedFunc); - /* 154 */ SyscallDesc("getdents64", unimplimentedFunc); - /* 155 */ SyscallDesc("fcntl64", unimplimentedFunc); - /* 156 */ SyscallDesc("inotify_rm_watch", unimplimentedFunc); - /* 157 */ SyscallDesc("statfs", unimplimentedFunc); - /* 158 */ SyscallDesc("fstatfs", unimplimentedFunc); - /* 159 */ SyscallDesc("umount", unimplimentedFunc); - /* 160 */ SyscallDesc("sched_set_affinity", unimplimentedFunc); - /* 161 */ SyscallDesc("sched_get_affinity", unimplimentedFunc); - /* 162 */ SyscallDesc("getdomainname", unimplimentedFunc); - /* 163 */ SyscallDesc("setdomainname", unimplimentedFunc); - /* 164 */ SyscallDesc("utrap_install", unimplimentedFunc); - /* 165 */ SyscallDesc("quotactl", unimplimentedFunc); - /* 166 */ SyscallDesc("set_tid_address", unimplimentedFunc); - /* 167 */ SyscallDesc("mount", unimplimentedFunc); - /* 168 */ SyscallDesc("ustat", unimplimentedFunc); - /* 169 */ SyscallDesc("setxattr", unimplimentedFunc); - /* 170 */ SyscallDesc("lsetxattr", unimplimentedFunc); - /* 171 */ SyscallDesc("fsetxattr", unimplimentedFunc); - /* 172 */ SyscallDesc("getxattr", unimplimentedFunc); - /* 173 */ SyscallDesc("lgetxattr", unimplimentedFunc); - /* 174 */ SyscallDesc("getdents", unimplimentedFunc); - /* 175 */ SyscallDesc("setsid", unimplimentedFunc); - /* 176 */ SyscallDesc("fchdir", unimplimentedFunc); - /* 177 */ SyscallDesc("fgetxattr", unimplimentedFunc); - /* 178 */ SyscallDesc("listxattr", unimplimentedFunc); - /* 179 */ SyscallDesc("llistxattr", unimplimentedFunc); - /* 180 */ SyscallDesc("flistxattr", unimplimentedFunc); - /* 181 */ SyscallDesc("removexattr", unimplimentedFunc); - /* 182 */ SyscallDesc("lremovexattr", unimplimentedFunc); - /* 183 */ SyscallDesc("sigpending", unimplimentedFunc); - /* 184 */ SyscallDesc("query_module", unimplimentedFunc); - /* 185 */ SyscallDesc("setpgid", unimplimentedFunc); - /* 186 */ SyscallDesc("fremovexattr", unimplimentedFunc); - /* 187 */ SyscallDesc("tkill", unimplimentedFunc); - /* 188 */ SyscallDesc("exit_group", unimplimentedFunc); - /* 189 */ SyscallDesc("uname", unimplimentedFunc); - /* 190 */ SyscallDesc("init_module", unimplimentedFunc); - /* 191 */ SyscallDesc("personality", unimplimentedFunc); - /* 192 */ SyscallDesc("remap_file_pages", unimplimentedFunc); - /* 193 */ SyscallDesc("epoll_create", unimplimentedFunc); - /* 194 */ SyscallDesc("epoll_ctl", unimplimentedFunc); - /* 195 */ SyscallDesc("epoll_wait", unimplimentedFunc); - /* 196 */ SyscallDesc("ioprio_set", unimplimentedFunc); - /* 197 */ SyscallDesc("getppid", unimplimentedFunc); - /* 198 */ SyscallDesc("sigaction", unimplimentedFunc); - /* 199 */ SyscallDesc("sgetmask", unimplimentedFunc); - /* 200 */ SyscallDesc("ssetmask", unimplimentedFunc); - /* 201 */ SyscallDesc("sigsuspend", unimplimentedFunc); - /* 202 */ SyscallDesc("oldlstat", unimplimentedFunc); - /* 203 */ SyscallDesc("uselib", unimplimentedFunc); - /* 204 */ SyscallDesc("readdir", unimplimentedFunc); - /* 205 */ SyscallDesc("readahead", unimplimentedFunc); - /* 206 */ SyscallDesc("socketcall", unimplimentedFunc); - /* 207 */ SyscallDesc("syslog", unimplimentedFunc); - /* 208 */ SyscallDesc("lookup_dcookie", unimplimentedFunc); - /* 209 */ SyscallDesc("fadvise64", unimplimentedFunc); - /* 210 */ SyscallDesc("fadvise64_64", unimplimentedFunc); - /* 211 */ SyscallDesc("tgkill", unimplimentedFunc); - /* 212 */ SyscallDesc("waitpid", unimplimentedFunc); - /* 213 */ SyscallDesc("swapoff", unimplimentedFunc); - /* 214 */ SyscallDesc("sysinfo", unimplimentedFunc); - /* 215 */ SyscallDesc("ipc", unimplimentedFunc); - /* 216 */ SyscallDesc("sigreturn", unimplimentedFunc); - /* 217 */ SyscallDesc("clone", unimplimentedFunc); - /* 218 */ SyscallDesc("ioprio_get", unimplimentedFunc); - /* 219 */ SyscallDesc("adjtimex", unimplimentedFunc); - /* 220 */ SyscallDesc("sigprocmask", unimplimentedFunc); - /* 221 */ SyscallDesc("create_module", unimplimentedFunc); - /* 222 */ SyscallDesc("delete_module", unimplimentedFunc); - /* 223 */ SyscallDesc("get_kernel_syms", unimplimentedFunc); - /* 224 */ SyscallDesc("getpgid", unimplimentedFunc); - /* 225 */ SyscallDesc("bdflush", unimplimentedFunc); - /* 226 */ SyscallDesc("sysfs", unimplimentedFunc); - /* 227 */ SyscallDesc("afs_syscall", unimplimentedFunc); - /* 228 */ SyscallDesc("setfsuid", unimplimentedFunc); - /* 229 */ SyscallDesc("setfsgid", unimplimentedFunc); - /* 230 */ SyscallDesc("_newselect", unimplimentedFunc); - /* 231 */ SyscallDesc("time", unimplimentedFunc); - /* 232 */ SyscallDesc("oldstat", unimplimentedFunc); - /* 233 */ SyscallDesc("stime", unimplimentedFunc); - /* 234 */ SyscallDesc("statfs64", unimplimentedFunc); - /* 235 */ SyscallDesc("fstatfs64", unimplimentedFunc); - /* 236 */ SyscallDesc("_llseek", unimplimentedFunc); - /* 237 */ SyscallDesc("mlock", unimplimentedFunc); - /* 238 */ SyscallDesc("munlock", unimplimentedFunc); - /* 239 */ SyscallDesc("mlockall", unimplimentedFunc); - /* 240 */ SyscallDesc("munlockall", unimplimentedFunc); - /* 241 */ SyscallDesc("sched_setparam", unimplimentedFunc); - /* 242 */ SyscallDesc("sched_getparam", unimplimentedFunc); - /* 243 */ SyscallDesc("sched_setscheduler", unimplimentedFunc); - /* 244 */ SyscallDesc("sched_getscheduler", unimplimentedFunc); - /* 245 */ SyscallDesc("sched_yield", unimplimentedFunc); - /* 246 */ SyscallDesc("sched_get_priority_max", unimplimented); - /* 247 */ SyscallDesc("sched_get_priority_min", unimplimented); - /* 248 */ SyscallDesc("sched_rr_get_interval", unimplimented); - /* 249 */ SyscallDesc("nanosleep", unimplimentedFunc); - /* 250 */ SyscallDesc("mremap", unimplimentedFunc); - /* 251 */ SyscallDesc("_sysctl", unimplimentedFunc); - /* 252 */ SyscallDesc("getsid", unimplimentedFunc); - /* 253 */ SyscallDesc("fdatasync", unimplimentedFunc); - /* 254 */ SyscallDesc("nfsservctl", unimplimentedFunc); - /* 255 */ SyscallDesc("aplib", unimplimentedFunc); - /* 256 */ SyscallDesc("clock_settime", unimplimentedFunc); - /* 257 */ SyscallDesc("clock_gettime", unimplimentedFunc); - /* 258 */ SyscallDesc("clock_getres", unimplimentedFunc); - /* 259 */ SyscallDesc("clock_nanosleep", unimplimentedFunc); - /* 260 */ SyscallDesc("sched_getaffinity", unimplimentedFunc); - /* 261 */ SyscallDesc("sched_setaffinity", unimplimentedFunc); - /* 262 */ SyscallDesc("timer_settime", unimplimentedFunc); - /* 263 */ SyscallDesc("timer_gettime", unimplimentedFunc); - /* 264 */ SyscallDesc("timer_getoverrun", unimplimentedFunc); - /* 265 */ SyscallDesc("timer_delete", unimplimentedFunc); - /* 266 */ SyscallDesc("timer_create", unimplimentedFunc); - /* 267 */ SyscallDesc("vserver", unimplimentedFunc); - /* 268 */ SyscallDesc("io_setup", unimplimentedFunc); - /* 269 */ SyscallDesc("io_destroy", unimplimentedFunc); - /* 270 */ SyscallDesc("io_submit", unimplimentedFunc); - /* 271 */ SyscallDesc("io_cancel", unimplimentedFunc); - /* 272 */ SyscallDesc("io_getevents", unimplimentedFunc); - /* 273 */ SyscallDesc("mq_open", unimplimentedFunc); - /* 274 */ SyscallDesc("mq_unlink", unimplimentedFunc); - /* 275 */ SyscallDesc("mq_timedsend", unimplimentedFunc); - /* 276 */ SyscallDesc("mq_timedreceive", unimplimentedFunc); - /* 277 */ SyscallDesc("mq_notify", unimplimentedFunc); - /* 278 */ SyscallDesc("mq_getsetattr", unimplimentedFunc); - /* 279 */ SyscallDesc("waitid", unimplimentedFunc); - /* 280 */ SyscallDesc("sys_setaltroot", unimplimentedFunc); - /* 281 */ SyscallDesc("add_key", unimplimentedFunc); - /* 282 */ SyscallDesc("request_key", unimplimentedFunc); - /* 283 */ SyscallDesc("keyctl", unimplimentedFunc); + /* 0 */ SyscallDesc("restart_syscall", unimplementedFunc); + /* 1 */ SyscallDesc("exit", unimplementedFunc); + /* 2 */ SyscallDesc("fork", unimplementedFunc); + /* 3 */ SyscallDesc("read", unimplementedFunc); + /* 4 */ SyscallDesc("write", unimplementedFunc); + /* 5 */ SyscallDesc("open", unimplementedFunc); + /* 6 */ SyscallDesc("close", unimplementedFunc); + /* 7 */ SyscallDesc("wait4", unimplementedFunc); + /* 8 */ SyscallDesc("creat", unimplementedFunc); + /* 9 */ SyscallDesc("link", unimplementedFunc); + /* 10 */ SyscallDesc("unlink", unimplementedFunc); + /* 11 */ SyscallDesc("execv", unimplementedFunc); + /* 12 */ SyscallDesc("chdir", unimplementedFunc); + /* 13 */ SyscallDesc("chown", unimplementedFunc); + /* 14 */ SyscallDesc("mknod", unimplementedFunc); + /* 15 */ SyscallDesc("chmod", unimplementedFunc); + /* 16 */ SyscallDesc("lchown", unimplementedFunc); + /* 17 */ SyscallDesc("brk", unimplementedFunc); + /* 18 */ SyscallDesc("perfctr", unimplementedFunc); + /* 19 */ SyscallDesc("lseek", unimplementedFunc); + /* 20 */ SyscallDesc("getpid", unimplementedFunc); + /* 21 */ SyscallDesc("capget", unimplementedFunc); + /* 22 */ SyscallDesc("capset", unimplementedFunc); + /* 23 */ SyscallDesc("setuid", unimplementedFunc); + /* 24 */ SyscallDesc("getuid", unimplementedFunc); + /* 25 */ SyscallDesc("time", unimplementedFunc); + /* 26 */ SyscallDesc("ptrace", unimplementedFunc); + /* 27 */ SyscallDesc("alarm", unimplementedFunc); + /* 28 */ SyscallDesc("sigaltstack", unimplementedFunc); + /* 29 */ SyscallDesc("pause", unimplementedFunc); + /* 30 */ SyscallDesc("utime", unimplementedFunc); + /* 31 */ SyscallDesc("lchown32", unimplementedFunc); + /* 32 */ SyscallDesc("fchown32", unimplementedFunc); + /* 33 */ SyscallDesc("access", unimplementedFunc); + /* 34 */ SyscallDesc("nice", unimplementedFunc); + /* 35 */ SyscallDesc("chown32", unimplementedFunc); + /* 36 */ SyscallDesc("sync", unimplementedFunc); + /* 37 */ SyscallDesc("kill", unimplementedFunc); + /* 38 */ SyscallDesc("stat", unimplementedFunc); + /* 39 */ SyscallDesc("sendfile", unimplementedFunc); + /* 40 */ SyscallDesc("lstat", unimplementedFunc); + /* 41 */ SyscallDesc("dup", unimplementedFunc); + /* 42 */ SyscallDesc("pipe", unimplementedFunc); + /* 43 */ SyscallDesc("times", unimplementedFunc); + /* 44 */ SyscallDesc("getuid32", unimplementedFunc); + /* 45 */ SyscallDesc("umount2", unimplementedFunc); + /* 46 */ SyscallDesc("setgid", unimplementedFunc); + /* 47 */ SyscallDesc("getgid", unimplementedFunc); + /* 48 */ SyscallDesc("signal", unimplementedFunc); + /* 49 */ SyscallDesc("geteuid", unimplementedFunc); + /* 50 */ SyscallDesc("getegid", unimplementedFunc); + /* 51 */ SyscallDesc("acct", unimplementedFunc); + /* 52 */ SyscallDesc("memory_ordering", unimplementedFunc); + /* 53 */ SyscallDesc("getgid32", unimplementedFunc); + /* 54 */ SyscallDesc("ioctl", unimplementedFunc); + /* 55 */ SyscallDesc("reboot", unimplementedFunc); + /* 56 */ SyscallDesc("mmap2", unimplementedFunc); + /* 57 */ SyscallDesc("symlink", unimplementedFunc); + /* 58 */ SyscallDesc("readlink", unimplementedFunc); + /* 59 */ SyscallDesc("execve", unimplementedFunc); + /* 60 */ SyscallDesc("umask", unimplementedFunc); + /* 61 */ SyscallDesc("chroot", unimplementedFunc); + /* 62 */ SyscallDesc("fstat", unimplementedFunc); + /* 63 */ SyscallDesc("fstat64", unimplementedFunc); + /* 64 */ SyscallDesc("getpagesize", unimplementedFunc); + /* 65 */ SyscallDesc("msync", unimplementedFunc); + /* 66 */ SyscallDesc("vfork", unimplementedFunc); + /* 67 */ SyscallDesc("pread64", unimplementedFunc); + /* 68 */ SyscallDesc("pwrite64", unimplementedFunc); + /* 69 */ SyscallDesc("geteuid32", unimplementedFunc); + /* 70 */ SyscallDesc("getdgid32", unimplementedFunc); + /* 71 */ SyscallDesc("mmap", unimplementedFunc); + /* 72 */ SyscallDesc("setreuid32", unimplementedFunc); + /* 73 */ SyscallDesc("munmap", unimplementedFunc); + /* 74 */ SyscallDesc("mprotect", unimplementedFunc); + /* 75 */ SyscallDesc("madvise", unimplementedFunc); + /* 76 */ SyscallDesc("vhangup", unimplementedFunc); + /* 77 */ SyscallDesc("truncate64", unimplementedFunc); + /* 78 */ SyscallDesc("mincore", unimplementedFunc); + /* 79 */ SyscallDesc("getgroups", unimplementedFunc); + /* 80 */ SyscallDesc("setgroups", unimplementedFunc); + /* 81 */ SyscallDesc("getpgrp", unimplementedFunc); + /* 82 */ SyscallDesc("setgroups32", unimplementedFunc); + /* 83 */ SyscallDesc("setitimer", unimplementedFunc); + /* 84 */ SyscallDesc("ftruncate64", unimplementedFunc); + /* 85 */ SyscallDesc("swapon", unimplementedFunc); + /* 86 */ SyscallDesc("getitimer", unimplementedFunc); + /* 87 */ SyscallDesc("setuid32", unimplementedFunc); + /* 88 */ SyscallDesc("sethostname", unimplementedFunc); + /* 89 */ SyscallDesc("setgid32", unimplementedFunc); + /* 90 */ SyscallDesc("dup2", unimplementedFunc); + /* 91 */ SyscallDesc("setfsuid32", unimplementedFunc); + /* 92 */ SyscallDesc("fcntl", unimplementedFunc); + /* 93 */ SyscallDesc("select", unimplementedFunc); + /* 94 */ SyscallDesc("setfsgid32", unimplementedFunc); + /* 95 */ SyscallDesc("fsync", unimplementedFunc); + /* 96 */ SyscallDesc("setpriority", unimplementedFunc); + /* 97 */ SyscallDesc("socket", unimplementedFunc); + /* 98 */ SyscallDesc("connect", unimplementedFunc); + /* 99 */ SyscallDesc("accept", unimplementedFunc); + /* 100 */ SyscallDesc("getpriority", unimplementedFunc); + /* 101 */ SyscallDesc("rt_sigreturn", unimplementedFunc); + /* 102 */ SyscallDesc("rt_sigaction", unimplementedFunc); + /* 103 */ SyscallDesc("rt_sigprocmask", unimplementedFunc); + /* 104 */ SyscallDesc("rt_sigpending", unimplementedFunc); + /* 105 */ SyscallDesc("rt_sigtimedwait", unimplementedFunc); + /* 106 */ SyscallDesc("rt_sigqueueinfo", unimplementedFunc); + /* 107 */ SyscallDesc("rt_sigsuspend", unimplementedFunc); + /* 108 */ SyscallDesc("setresuid", unimplementedFunc); + /* 109 */ SyscallDesc("getresuid", unimplementedFunc); + /* 110 */ SyscallDesc("setresgid", unimplementedFunc); + /* 111 */ SyscallDesc("getresgid", unimplementedFunc); + /* 112 */ SyscallDesc("setregid32", unimplementedFunc); + /* 113 */ SyscallDesc("recvmsg", unimplementedFunc); + /* 114 */ SyscallDesc("sendmsg", unimplementedFunc); + /* 115 */ SyscallDesc("getgroups32", unimplementedFunc); + /* 116 */ SyscallDesc("gettimeofday", unimplementedFunc); + /* 117 */ SyscallDesc("getrusage", unimplementedFunc); + /* 118 */ SyscallDesc("getsockopt", unimplementedFunc); + /* 119 */ SyscallDesc("getcwd", unimplementedFunc); + /* 120 */ SyscallDesc("readv", unimplementedFunc); + /* 121 */ SyscallDesc("writev", unimplementedFunc); + /* 122 */ SyscallDesc("settimeofday", unimplementedFunc); + /* 123 */ SyscallDesc("fchown", unimplementedFunc); + /* 124 */ SyscallDesc("fchmod", unimplementedFunc); + /* 125 */ SyscallDesc("recvfrom", unimplementedFunc); + /* 126 */ SyscallDesc("setreuid", unimplementedFunc); + /* 127 */ SyscallDesc("setregid", unimplementedFunc); + /* 128 */ SyscallDesc("rename", unimplementedFunc); + /* 129 */ SyscallDesc("truncate", unimplementedFunc); + /* 130 */ SyscallDesc("ftruncate", unimplementedFunc); + /* 131 */ SyscallDesc("flock", unimplementedFunc); + /* 132 */ SyscallDesc("lstat64", unimplementedFunc); + /* 133 */ SyscallDesc("sendto", unimplementedFunc); + /* 134 */ SyscallDesc("shutdown", unimplementedFunc); + /* 135 */ SyscallDesc("socketpair", unimplementedFunc); + /* 136 */ SyscallDesc("mkdir", unimplementedFunc); + /* 137 */ SyscallDesc("rmdir", unimplementedFunc); + /* 138 */ SyscallDesc("utimes", unimplementedFunc); + /* 139 */ SyscallDesc("stat64", unimplementedFunc); + /* 140 */ SyscallDesc("sendfile64", unimplementedFunc); + /* 141 */ SyscallDesc("getpeername", unimplementedFunc); + /* 142 */ SyscallDesc("futex", unimplementedFunc); + /* 143 */ SyscallDesc("gettid", unimplementedFunc); + /* 144 */ SyscallDesc("getrlimit", unimplementedFunc); + /* 145 */ SyscallDesc("setrlimit", unimplementedFunc); + /* 146 */ SyscallDesc("pivot_root", unimplementedFunc); + /* 147 */ SyscallDesc("prctl", unimplementedFunc); + /* 148 */ SyscallDesc("pciconfig_read", unimplementedFunc); + /* 149 */ SyscallDesc("pciconfig_write", unimplementedFunc); + /* 150 */ SyscallDesc("getsockname", unimplementedFunc); + /* 151 */ SyscallDesc("inotify_init", unimplementedFunc); + /* 152 */ SyscallDesc("inotify_add_watch", unimplementedFunc); + /* 153 */ SyscallDesc("poll", unimplementedFunc); + /* 154 */ SyscallDesc("getdents64", unimplementedFunc); + /* 155 */ SyscallDesc("fcntl64", unimplementedFunc); + /* 156 */ SyscallDesc("inotify_rm_watch", unimplementedFunc); + /* 157 */ SyscallDesc("statfs", unimplementedFunc); + /* 158 */ SyscallDesc("fstatfs", unimplementedFunc); + /* 159 */ SyscallDesc("umount", unimplementedFunc); + /* 160 */ SyscallDesc("sched_set_affinity", unimplementedFunc); + /* 161 */ SyscallDesc("sched_get_affinity", unimplementedFunc); + /* 162 */ SyscallDesc("getdomainname", unimplementedFunc); + /* 163 */ SyscallDesc("setdomainname", unimplementedFunc); + /* 164 */ SyscallDesc("utrap_install", unimplementedFunc); + /* 165 */ SyscallDesc("quotactl", unimplementedFunc); + /* 166 */ SyscallDesc("set_tid_address", unimplementedFunc); + /* 167 */ SyscallDesc("mount", unimplementedFunc); + /* 168 */ SyscallDesc("ustat", unimplementedFunc); + /* 169 */ SyscallDesc("setxattr", unimplementedFunc); + /* 170 */ SyscallDesc("lsetxattr", unimplementedFunc); + /* 171 */ SyscallDesc("fsetxattr", unimplementedFunc); + /* 172 */ SyscallDesc("getxattr", unimplementedFunc); + /* 173 */ SyscallDesc("lgetxattr", unimplementedFunc); + /* 174 */ SyscallDesc("getdents", unimplementedFunc); + /* 175 */ SyscallDesc("setsid", unimplementedFunc); + /* 176 */ SyscallDesc("fchdir", unimplementedFunc); + /* 177 */ SyscallDesc("fgetxattr", unimplementedFunc); + /* 178 */ SyscallDesc("listxattr", unimplementedFunc); + /* 179 */ SyscallDesc("llistxattr", unimplementedFunc); + /* 180 */ SyscallDesc("flistxattr", unimplementedFunc); + /* 181 */ SyscallDesc("removexattr", unimplementedFunc); + /* 182 */ SyscallDesc("lremovexattr", unimplementedFunc); + /* 183 */ SyscallDesc("sigpending", unimplementedFunc); + /* 184 */ SyscallDesc("query_module", unimplementedFunc); + /* 185 */ SyscallDesc("setpgid", unimplementedFunc); + /* 186 */ SyscallDesc("fremovexattr", unimplementedFunc); + /* 187 */ SyscallDesc("tkill", unimplementedFunc); + /* 188 */ SyscallDesc("exit_group", unimplementedFunc); + /* 189 */ SyscallDesc("uname", unimplementedFunc); + /* 190 */ SyscallDesc("init_module", unimplementedFunc); + /* 191 */ SyscallDesc("personality", unimplementedFunc); + /* 192 */ SyscallDesc("remap_file_pages", unimplementedFunc); + /* 193 */ SyscallDesc("epoll_create", unimplementedFunc); + /* 194 */ SyscallDesc("epoll_ctl", unimplementedFunc); + /* 195 */ SyscallDesc("epoll_wait", unimplementedFunc); + /* 196 */ SyscallDesc("ioprio_set", unimplementedFunc); + /* 197 */ SyscallDesc("getppid", unimplementedFunc); + /* 198 */ SyscallDesc("sigaction", unimplementedFunc); + /* 199 */ SyscallDesc("sgetmask", unimplementedFunc); + /* 200 */ SyscallDesc("ssetmask", unimplementedFunc); + /* 201 */ SyscallDesc("sigsuspend", unimplementedFunc); + /* 202 */ SyscallDesc("oldlstat", unimplementedFunc); + /* 203 */ SyscallDesc("uselib", unimplementedFunc); + /* 204 */ SyscallDesc("readdir", unimplementedFunc); + /* 205 */ SyscallDesc("readahead", unimplementedFunc); + /* 206 */ SyscallDesc("socketcall", unimplementedFunc); + /* 207 */ SyscallDesc("syslog", unimplementedFunc); + /* 208 */ SyscallDesc("lookup_dcookie", unimplementedFunc); + /* 209 */ SyscallDesc("fadvise64", unimplementedFunc); + /* 210 */ SyscallDesc("fadvise64_64", unimplementedFunc); + /* 211 */ SyscallDesc("tgkill", unimplementedFunc); + /* 212 */ SyscallDesc("waitpid", unimplementedFunc); + /* 213 */ SyscallDesc("swapoff", unimplementedFunc); + /* 214 */ SyscallDesc("sysinfo", unimplementedFunc); + /* 215 */ SyscallDesc("ipc", unimplementedFunc); + /* 216 */ SyscallDesc("sigreturn", unimplementedFunc); + /* 217 */ SyscallDesc("clone", unimplementedFunc); + /* 218 */ SyscallDesc("ioprio_get", unimplementedFunc); + /* 219 */ SyscallDesc("adjtimex", unimplementedFunc); + /* 220 */ SyscallDesc("sigprocmask", unimplementedFunc); + /* 221 */ SyscallDesc("create_module", unimplementedFunc); + /* 222 */ SyscallDesc("delete_module", unimplementedFunc); + /* 223 */ SyscallDesc("get_kernel_syms", unimplementedFunc); + /* 224 */ SyscallDesc("getpgid", unimplementedFunc); + /* 225 */ SyscallDesc("bdflush", unimplementedFunc); + /* 226 */ SyscallDesc("sysfs", unimplementedFunc); + /* 227 */ SyscallDesc("afs_syscall", unimplementedFunc); + /* 228 */ SyscallDesc("setfsuid", unimplementedFunc); + /* 229 */ SyscallDesc("setfsgid", unimplementedFunc); + /* 230 */ SyscallDesc("_newselect", unimplementedFunc); + /* 231 */ SyscallDesc("time", unimplementedFunc); + /* 232 */ SyscallDesc("oldstat", unimplementedFunc); + /* 233 */ SyscallDesc("stime", unimplementedFunc); + /* 234 */ SyscallDesc("statfs64", unimplementedFunc); + /* 235 */ SyscallDesc("fstatfs64", unimplementedFunc); + /* 236 */ SyscallDesc("_llseek", unimplementedFunc); + /* 237 */ SyscallDesc("mlock", unimplementedFunc); + /* 238 */ SyscallDesc("munlock", unimplementedFunc); + /* 239 */ SyscallDesc("mlockall", unimplementedFunc); + /* 240 */ SyscallDesc("munlockall", unimplementedFunc); + /* 241 */ SyscallDesc("sched_setparam", unimplementedFunc); + /* 242 */ SyscallDesc("sched_getparam", unimplementedFunc); + /* 243 */ SyscallDesc("sched_setscheduler", unimplementedFunc); + /* 244 */ SyscallDesc("sched_getscheduler", unimplementedFunc); + /* 245 */ SyscallDesc("sched_yield", unimplementedFunc); + /* 246 */ SyscallDesc("sched_get_priority_max", unimplemented); + /* 247 */ SyscallDesc("sched_get_priority_min", unimplemented); + /* 248 */ SyscallDesc("sched_rr_get_interval", unimplemented); + /* 249 */ SyscallDesc("nanosleep", unimplementedFunc); + /* 250 */ SyscallDesc("mremap", unimplementedFunc); + /* 251 */ SyscallDesc("_sysctl", unimplementedFunc); + /* 252 */ SyscallDesc("getsid", unimplementedFunc); + /* 253 */ SyscallDesc("fdatasync", unimplementedFunc); + /* 254 */ SyscallDesc("nfsservctl", unimplementedFunc); + /* 255 */ SyscallDesc("aplib", unimplementedFunc); + /* 256 */ SyscallDesc("clock_settime", unimplementedFunc); + /* 257 */ SyscallDesc("clock_gettime", unimplementedFunc); + /* 258 */ SyscallDesc("clock_getres", unimplementedFunc); + /* 259 */ SyscallDesc("clock_nanosleep", unimplementedFunc); + /* 260 */ SyscallDesc("sched_getaffinity", unimplementedFunc); + /* 261 */ SyscallDesc("sched_setaffinity", unimplementedFunc); + /* 262 */ SyscallDesc("timer_settime", unimplementedFunc); + /* 263 */ SyscallDesc("timer_gettime", unimplementedFunc); + /* 264 */ SyscallDesc("timer_getoverrun", unimplementedFunc); + /* 265 */ SyscallDesc("timer_delete", unimplementedFunc); + /* 266 */ SyscallDesc("timer_create", unimplementedFunc); + /* 267 */ SyscallDesc("vserver", unimplementedFunc); + /* 268 */ SyscallDesc("io_setup", unimplementedFunc); + /* 269 */ SyscallDesc("io_destroy", unimplementedFunc); + /* 270 */ SyscallDesc("io_submit", unimplementedFunc); + /* 271 */ SyscallDesc("io_cancel", unimplementedFunc); + /* 272 */ SyscallDesc("io_getevents", unimplementedFunc); + /* 273 */ SyscallDesc("mq_open", unimplementedFunc); + /* 274 */ SyscallDesc("mq_unlink", unimplementedFunc); + /* 275 */ SyscallDesc("mq_timedsend", unimplementedFunc); + /* 276 */ SyscallDesc("mq_timedreceive", unimplementedFunc); + /* 277 */ SyscallDesc("mq_notify", unimplementedFunc); + /* 278 */ SyscallDesc("mq_getsetattr", unimplementedFunc); + /* 279 */ SyscallDesc("waitid", unimplementedFunc); + /* 280 */ SyscallDesc("sys_setaltroot", unimplementedFunc); + /* 281 */ SyscallDesc("add_key", unimplementedFunc); + /* 282 */ SyscallDesc("request_key", unimplementedFunc); + /* 283 */ SyscallDesc("keyctl", unimplementedFunc); }; SparcLinuxProcess::SparcLinuxProcess(const std::string &name, diff --git a/arch/sparc/stacktrace.hh b/arch/sparc/stacktrace.hh new file mode 100644 index 000000000..1d8d97a79 --- /dev/null +++ b/arch/sparc/stacktrace.hh @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2005 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __ARCH_ALPHA_STACKTRACE_HH__ +#define __ARCH_ALPHA_STACKTRACE_HH__ + +#include "base/trace.hh" +#include "cpu/static_inst.hh" + +class ExecContext; +class StackTrace; + +class ProcessInfo +{ + private: + ExecContext *xc; + + int thread_info_size; + int task_struct_size; + int task_off; + int pid_off; + int name_off; + + public: + ProcessInfo(ExecContext *_xc); + + Addr task(Addr ksp) const; + int pid(Addr ksp) const; + std::string name(Addr ksp) const; +}; + +class StackTrace +{ + protected: + typedef TheISA::MachInst MachInst; + private: + ExecContext *xc; + std::vector stack; + + private: + bool isEntry(Addr addr); + bool decodePrologue(Addr sp, Addr callpc, Addr func, int &size, Addr &ra); + bool decodeSave(MachInst inst, int ®, int &disp); + bool decodeStack(MachInst inst, int &disp); + + void trace(ExecContext *xc, bool is_call); + + public: + StackTrace(); + StackTrace(ExecContext *xc, StaticInstPtr inst); + ~StackTrace(); + + void clear() + { + xc = 0; + stack.clear(); + } + + bool valid() const { return xc != NULL; } + bool trace(ExecContext *xc, StaticInstPtr inst); + + public: + const std::vector &getstack() const { return stack; } + + static const int user = 1; + static const int console = 2; + static const int unknown = 3; + +#if TRACING_ON + private: + void dump(); + + public: + void dprintf() { if (DTRACE(Stack)) dump(); } +#else + public: + void dprintf() {} +#endif +}; + +inline bool +StackTrace::trace(ExecContext *xc, StaticInstPtr inst) +{ + if (!inst->isCall() && !inst->isReturn()) + return false; + + if (valid()) + clear(); + + trace(xc, !inst->isReturn()); + return true; +} + +#endif // __ARCH_ALPHA_STACKTRACE_HH__ From 11aead894d4186916b587b1449075f276319a235 Mon Sep 17 00:00:00 2001 From: Kevin Lim Date: Tue, 7 Mar 2006 19:59:12 -0500 Subject: [PATCH 164/180] Updates for the quiesceEvent that was added to the XC. Also several files need to include system.hh or symtab.hh. This is because exec_context.hh has less #includes than before, requiring some of the files that include it to include some other files as well. arch/alpha/faults.cc: Avoid accessing XC directly. arch/alpha/stacktrace.cc: StackTrace needs to include system.hh. cpu/cpu_exec_context.cc: Update for change to CPUExecContext. cpu/cpu_exec_context.hh: Make quiesce events use CPUExecContext instead of ExecContext. Include functions to allow the quiesce event and last activate/suspend be accessed. cpu/exec_context.hh: Include functions for quiesceEvent. cpu/intr_control.cc: Needs to include cpu/exec_context.hh. cpu/profile.cc: Needs to include symtab.hh for the symbol table. cpu/profile.hh: Needs forward declare of ExecContext. cpu/simple/cpu.cc: Rename xc to cpuXC. dev/tsunami_cchip.cc: Needs to include exec_context.hh. kern/kernel_stats.cc: Needs to include system.hh. kern/linux/events.cc: Needs to include system.hh. Also avoid accessing objects directly from the XC. kern/tru64/dump_mbuf.cc: Include symtab.hh for the SymbolTable and system.hh. kern/tru64/tru64_events.cc: Include system.hh sim/pseudo_inst.cc: Avoid accessing objects directly within the XC. --HG-- extra : convert_revision : 78fe30d98cd20f7403fa216f772071458b675c84 --- arch/alpha/faults.cc | 18 +++++++------- arch/alpha/stacktrace.cc | 1 + cpu/cpu_exec_context.cc | 37 +++++++++++++++------------- cpu/cpu_exec_context.hh | 10 ++++++-- cpu/exec_context.hh | 49 ++++++++++++++++++++++---------------- cpu/intr_control.cc | 1 + cpu/profile.cc | 1 + cpu/profile.hh | 2 ++ cpu/simple/cpu.cc | 2 +- dev/tsunami_cchip.cc | 1 + kern/kernel_stats.cc | 1 + kern/linux/events.cc | 3 ++- kern/tru64/dump_mbuf.cc | 2 ++ kern/tru64/tru64_events.cc | 1 + sim/pseudo_inst.cc | 24 ++++++++++++------- 15 files changed, 93 insertions(+), 60 deletions(-) diff --git a/arch/alpha/faults.cc b/arch/alpha/faults.cc index 84f785c0a..2d16317ec 100644 --- a/arch/alpha/faults.cc +++ b/arch/alpha/faults.cc @@ -103,15 +103,15 @@ FaultStat IntegerOverflowFault::_stat; void AlphaFault::invoke(ExecContext * xc) { - DPRINTF(Fault, "Fault %s at PC: %#x\n", name(), xc->regs.pc); - xc->cpu->recordEvent(csprintf("Fault %s", name())); + DPRINTF(Fault, "Fault %s at PC: %#x\n", name(), xc->readPC()); + xc->getCpuPtr()->recordEvent(csprintf("Fault %s", name())); assert(!xc->misspeculating()); - xc->kernelStats->fault(this); + xc->getCpuPtr()->kernelStats->fault(this); // exception restart address if (setRestartAddress() || !xc->inPalMode()) - xc->setMiscReg(AlphaISA::IPR_EXC_ADDR, xc->regs.pc); + xc->setMiscReg(AlphaISA::IPR_EXC_ADDR, xc->readPC()); if (skipFaultingInstruction()) { // traps... skip faulting instruction. @@ -119,17 +119,17 @@ void AlphaFault::invoke(ExecContext * xc) xc->readMiscReg(AlphaISA::IPR_EXC_ADDR) + 4); } - xc->regs.pc = xc->readMiscReg(AlphaISA::IPR_PAL_BASE) + vect(); - xc->regs.npc = xc->regs.pc + sizeof(MachInst); + xc->setPC(xc->readMiscReg(AlphaISA::IPR_PAL_BASE) + vect()); + xc->setNextPC(xc->readPC() + sizeof(MachInst)); } void ArithmeticFault::invoke(ExecContext * xc) { - DPRINTF(Fault, "Fault %s at PC: %#x\n", name(), xc->regs.pc); - xc->cpu->recordEvent(csprintf("Fault %s", name())); + DPRINTF(Fault, "Fault %s at PC: %#x\n", name(), xc->readPC()); + xc->getCpuPtr()->recordEvent(csprintf("Fault %s", name())); assert(!xc->misspeculating()); - xc->kernelStats->fault(this); + xc->getCpuPtr()->kernelStats->fault(this); panic("Arithmetic traps are unimplemented!"); } diff --git a/arch/alpha/stacktrace.cc b/arch/alpha/stacktrace.cc index 50f2e4d21..26656ab5c 100644 --- a/arch/alpha/stacktrace.cc +++ b/arch/alpha/stacktrace.cc @@ -35,6 +35,7 @@ #include "base/trace.hh" #include "cpu/base.hh" #include "cpu/exec_context.hh" +#include "sim/system.hh" using namespace std; using namespace AlphaISA; diff --git a/cpu/cpu_exec_context.cc b/cpu/cpu_exec_context.cc index ae428646d..74b609764 100644 --- a/cpu/cpu_exec_context.cc +++ b/cpu/cpu_exec_context.cc @@ -57,8 +57,7 @@ CPUExecContext::CPUExecContext(BaseCPU *_cpu, int _thread_num, System *_sys, : _status(ExecContext::Unallocated), cpu(_cpu), thread_num(_thread_num), cpu_id(-1), lastActivate(0), lastSuspend(0), mem(_mem), itb(_itb), dtb(_dtb), system(_sys), memctrl(_sys->memctrl), physmem(_sys->physmem), - fnbin(kernelBinning->fnbin), profile(NULL), quiesceEvent(this), - func_exe_inst(0), storeCondFailures(0) + profile(NULL), quiesceEvent(this), func_exe_inst(0), storeCondFailures(0) { proxy = new ProxyExecContext(this); @@ -119,21 +118,22 @@ void CPUExecContext::dumpFuncProfile() { std::ostream *os = simout.create(csprintf("profile.%s.dat", cpu->name())); + profile->dump(proxy, *os); } -ExecContext::EndQuiesceEvent::EndQuiesceEvent(ExecContext *_xc) - : Event(&mainEventQueue), xc(_xc) +CPUExecContext::EndQuiesceEvent::EndQuiesceEvent(CPUExecContext *_cpuXC) + : Event(&mainEventQueue), cpuXC(_cpuXC) { } void -ExecContext::EndQuiesceEvent::process() +CPUExecContext::EndQuiesceEvent::process() { - xc->activate(); + cpuXC->activate(); } const char* -ExecContext::EndQuiesceEvent::description() +CPUExecContext::EndQuiesceEvent::description() { return "End Quiesce Event."; } @@ -142,25 +142,25 @@ ExecContext::EndQuiesceEvent::description() void CPUExecContext::takeOverFrom(ExecContext *oldContext) { -/* // some things should already be set up - assert(mem == oldContext->mem); + assert(mem == oldContext->getMemPtr()); #if FULL_SYSTEM - assert(system == oldContext->system); + assert(system == oldContext->getSystemPtr()); #else - assert(process == oldContext->process); + assert(process == oldContext->getProcessPtr()); #endif // copy over functional state - _status = oldContext->_status; - regs = oldContext->regs; - cpu_id = oldContext->cpu_id; - func_exe_inst = oldContext->func_exe_inst; + _status = oldContext->status(); + copyArchRegs(oldContext); + cpu_id = oldContext->readCpuId(); +#if !FULL_SYSTEM + func_exe_inst = oldContext->readFuncExeInst(); +#endif storeCondFailures = 0; - oldContext->_status = CPUExecContext::Unallocated; -*/ + oldContext->setStatus(ExecContext::Unallocated); } void @@ -281,6 +281,9 @@ CPUExecContext::copyArchRegs(ExecContext *xc) setMiscReg(AlphaISA::Lock_Addr_DepTag, xc->readMiscReg(AlphaISA::Lock_Addr_DepTag)); + // Also need to copy all the IPRs. Probably should just have a copy misc + // regs function defined on the misc regs. + // Lastly copy PC/NPC setPC(xc->readPC()); setNextPC(xc->readNextPC()); diff --git a/cpu/cpu_exec_context.hh b/cpu/cpu_exec_context.hh index a40253d4b..f5c57da22 100644 --- a/cpu/cpu_exec_context.hh +++ b/cpu/cpu_exec_context.hh @@ -139,9 +139,9 @@ class CPUExecContext struct EndQuiesceEvent : public Event { /** A pointer to the execution context that is quiesced */ - ExecContext *xc; + CPUExecContext *cpuXC; - EndQuiesceEvent(ExecContext *_xc); + EndQuiesceEvent(CPUExecContext *_cpuXC); /** Event process to occur at interrupt*/ virtual void process(); @@ -151,6 +151,12 @@ class CPUExecContext }; EndQuiesceEvent quiesceEvent; + Event *getQuiesceEvent() { return &quiesceEvent; } + + Tick readLastActivate() { return lastActivate; } + + Tick readLastSuspend() { return lastSuspend; } + #else Process *process; diff --git a/cpu/exec_context.hh b/cpu/exec_context.hh index 9c96b5c42..b7653f121 100644 --- a/cpu/exec_context.hh +++ b/cpu/exec_context.hh @@ -42,6 +42,7 @@ class AlphaDTB; class AlphaITB; class BaseCPU; +class Event; class FunctionalMemory; class PhysicalMemory; class Process; @@ -102,6 +103,8 @@ class ExecContext virtual Status status() const = 0; + virtual void setStatus(Status new_status) = 0; + /// Set the status to Active. Optional delay indicates number of /// cycles to wait before beginning execution. virtual void activate(int delay = 1) = 0; @@ -119,13 +122,22 @@ class ExecContext virtual void dumpFuncProfile() = 0; #endif - virtual void takeOverFrom(ExecContext *oldContext) = 0; + virtual void takeOverFrom(ExecContext *old_context) = 0; virtual void regStats(const std::string &name) = 0; virtual void serialize(std::ostream &os) = 0; virtual void unserialize(Checkpoint *cp, const std::string §ion) = 0; +#if FULL_SYSTEM + virtual Event *getQuiesceEvent() = 0; + + // Not necessarily the best location for these... + // Having an extra function just to read these is obnoxious + virtual Tick readLastActivate() = 0; + virtual Tick readLastSuspend() = 0; +#endif + virtual int getThreadNum() = 0; virtual bool validInstAddr(Addr addr) = 0; @@ -139,6 +151,7 @@ class ExecContext virtual Fault translateDataWriteReq(MemReqPtr &req) = 0; + // Also somewhat obnoxious. Really only used for the TLB fault. virtual TheISA::MachInst getInst() = 0; virtual void copyArchRegs(ExecContext *xc) = 0; @@ -180,6 +193,8 @@ class ExecContext virtual Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val) = 0; + // Also not necessarily the best location for these two. Hopefully will go + // away once we decide upon where st cond failures goes. virtual unsigned readStCondFailures() = 0; virtual void setStCondFailures(unsigned sc_failures) = 0; @@ -189,20 +204,12 @@ class ExecContext virtual void setIntrFlag(int val) = 0; virtual Fault hwrei() = 0; virtual bool inPalMode() = 0; - virtual void ev5_trap(Fault fault) = 0; virtual bool simPalCheck(int palFunc) = 0; #endif + // Only really makes sense for old CPU model. Still could be useful though. virtual bool misspeculating() = 0; - /** Meant to be more generic trap function to be - * called when an instruction faults. - * @param fault The fault generated by executing the instruction. - * @todo How to do this properly so it's dependent upon ISA only? - */ - - virtual void trap(Fault fault) = 0; - #if !FULL_SYSTEM virtual IntReg getSyscallArg(int i) = 0; @@ -213,6 +220,7 @@ class ExecContext virtual void syscall() = 0; + // Same with st cond failures. virtual Counter readFuncExeInst() = 0; virtual void setFuncExeInst(Counter new_val) = 0; @@ -253,6 +261,8 @@ class ProxyExecContext : public ExecContext Status status() const { return actualXC->status(); } + void setStatus(Status new_status) { actualXC->setStatus(new_status); } + /// Set the status to Active. Optional delay indicates number of /// cycles to wait before beginning execution. void activate(int delay = 1) { actualXC->activate(delay); } @@ -279,6 +289,13 @@ class ProxyExecContext : public ExecContext void unserialize(Checkpoint *cp, const std::string §ion) { actualXC->unserialize(cp, section); } +#if FULL_SYSTEM + Event *getQuiesceEvent() { return actualXC->getQuiesceEvent(); } + + Tick readLastActivate() { return actualXC->readLastActivate(); } + Tick readLastSuspend() { return actualXC->readLastSuspend(); } +#endif + int getThreadNum() { return actualXC->getThreadNum(); } bool validInstAddr(Addr addr) { return actualXC->validInstAddr(addr); } @@ -365,21 +382,11 @@ class ProxyExecContext : public ExecContext bool inPalMode() { return actualXC->inPalMode(); } - void ev5_trap(Fault fault) { actualXC->ev5_trap(fault); } - bool simPalCheck(int palFunc) { return actualXC->simPalCheck(palFunc); } #endif // @todo: Fix this! - bool misspeculating() { return false; } - - /** Meant to be more generic trap function to be - * called when an instruction faults. - * @param fault The fault generated by executing the instruction. - * @todo How to do this properly so it's dependent upon ISA only? - */ - - void trap(Fault fault) { actualXC->trap(fault); } + bool misspeculating() { return actualXC->misspeculating(); } #if !FULL_SYSTEM IntReg getSyscallArg(int i) { return actualXC->getSyscallArg(i); } diff --git a/cpu/intr_control.cc b/cpu/intr_control.cc index d1866a0c4..43e7f654c 100644 --- a/cpu/intr_control.cc +++ b/cpu/intr_control.cc @@ -30,6 +30,7 @@ #include #include "cpu/base.hh" +#include "cpu/exec_context.hh" #include "cpu/intr_control.hh" #include "sim/builder.hh" #include "sim/sim_object.hh" diff --git a/cpu/profile.cc b/cpu/profile.cc index 1a38792a0..fe3458b61 100644 --- a/cpu/profile.cc +++ b/cpu/profile.cc @@ -32,6 +32,7 @@ #include "base/callback.hh" #include "base/statistics.hh" #include "base/trace.hh" +#include "base/loader/symtab.hh" #include "cpu/base.hh" #include "cpu/exec_context.hh" #include "cpu/profile.hh" diff --git a/cpu/profile.hh b/cpu/profile.hh index 1eb012a27..d55c9eec9 100644 --- a/cpu/profile.hh +++ b/cpu/profile.hh @@ -35,6 +35,8 @@ #include "sim/host.hh" #include "arch/stacktrace.hh" +class ExecContext; + class ProfileNode { private: diff --git a/cpu/simple/cpu.cc b/cpu/simple/cpu.cc index 38b43fef5..fd0163677 100644 --- a/cpu/simple/cpu.cc +++ b/cpu/simple/cpu.cc @@ -766,7 +766,7 @@ SimpleCPU::tick() // decode the instruction inst = gtoh(inst); - curStaticInst = StaticInst::decode(makeExtMI(inst, xc->readPC())); + curStaticInst = StaticInst::decode(makeExtMI(inst, cpuXC->readPC())); traceData = Trace::getInstRecord(curTick, xcProxy, this, curStaticInst, cpuXC->readPC()); diff --git a/dev/tsunami_cchip.cc b/dev/tsunami_cchip.cc index d311df4f5..2649fe27a 100644 --- a/dev/tsunami_cchip.cc +++ b/dev/tsunami_cchip.cc @@ -42,6 +42,7 @@ #include "mem/bus/pio_interface.hh" #include "mem/bus/pio_interface_impl.hh" #include "mem/functional/memory_control.hh" +#include "cpu/exec_context.hh" #include "cpu/intr_control.hh" #include "sim/builder.hh" #include "sim/system.hh" diff --git a/kern/kernel_stats.cc b/kern/kernel_stats.cc index 988b0f639..a887ebf09 100644 --- a/kern/kernel_stats.cc +++ b/kern/kernel_stats.cc @@ -35,6 +35,7 @@ #include "cpu/exec_context.hh" #include "kern/kernel_stats.hh" #include "kern/tru64/tru64_syscalls.hh" +#include "sim/system.hh" using namespace std; using namespace Stats; diff --git a/kern/linux/events.cc b/kern/linux/events.cc index a781165ac..9f50eef04 100644 --- a/kern/linux/events.cc +++ b/kern/linux/events.cc @@ -32,6 +32,7 @@ #include "kern/linux/events.hh" #include "kern/linux/printk.hh" #include "kern/system_events.hh" +#include "sim/system.hh" namespace Linux { @@ -41,7 +42,7 @@ DebugPrintkEvent::process(ExecContext *xc) { if (DTRACE(DebugPrintf)) { if (!raw) { - StringWrap name(xc->system->name() + ".dprintk"); + StringWrap name(xc->getSystemPtr()->name() + ".dprintk"); DPRINTFN(""); } diff --git a/kern/tru64/dump_mbuf.cc b/kern/tru64/dump_mbuf.cc index 25ed82ef3..c3c37531a 100644 --- a/kern/tru64/dump_mbuf.cc +++ b/kern/tru64/dump_mbuf.cc @@ -31,9 +31,11 @@ #include "base/cprintf.hh" #include "base/trace.hh" +#include "base/loader/symtab.hh" #include "cpu/exec_context.hh" #include "kern/tru64/mbuf.hh" #include "sim/host.hh" +#include "sim/system.hh" #include "arch/arguments.hh" #include "arch/isa_traits.hh" #include "arch/vtophys.hh" diff --git a/kern/tru64/tru64_events.cc b/kern/tru64/tru64_events.cc index 12aae6950..8f2be6d9b 100644 --- a/kern/tru64/tru64_events.cc +++ b/kern/tru64/tru64_events.cc @@ -35,6 +35,7 @@ #include "mem/functional/memory_control.hh" #include "arch/arguments.hh" #include "arch/isa_traits.hh" +#include "sim/system.hh" using namespace TheISA; diff --git a/sim/pseudo_inst.cc b/sim/pseudo_inst.cc index 85b26ef23..e475006e7 100644 --- a/sim/pseudo_inst.cc +++ b/sim/pseudo_inst.cc @@ -83,13 +83,15 @@ namespace AlphaPseudo if (!doQuiesce || ns == 0) return; - if (xc->quiesceEvent.scheduled()) - xc->quiesceEvent.reschedule(curTick + Clock::Int::ns * ns); + Event *quiesceEvent = xc->getQuiesceEvent(); + + if (quiesceEvent->scheduled()) + quiesceEvent->reschedule(curTick + Clock::Int::ns * ns); else - xc->quiesceEvent.schedule(curTick + Clock::Int::ns * ns); + quiesceEvent->schedule(curTick + Clock::Int::ns * ns); xc->suspend(); - xc->kernelStats->quiesce(); + xc->getCpuPtr()->kernelStats->quiesce(); } void @@ -98,19 +100,23 @@ namespace AlphaPseudo if (!doQuiesce || cycles == 0) return; - if (xc->quiesceEvent.scheduled()) - xc->quiesceEvent.reschedule(curTick + xc->cpu->cycles(cycles)); + Event *quiesceEvent = xc->getQuiesceEvent(); + + if (quiesceEvent->scheduled()) + quiesceEvent->reschedule(curTick + + xc->getCpuPtr()->cycles(cycles)); else - xc->quiesceEvent.schedule(curTick + xc->cpu->cycles(cycles)); + quiesceEvent->schedule(curTick + + xc->getCpuPtr()->cycles(cycles)); xc->suspend(); - xc->kernelStats->quiesce(); + xc->getCpuPtr()->kernelStats->quiesce(); } uint64_t quiesceTime(ExecContext *xc) { - return (xc->lastActivate - xc->lastSuspend) / Clock::Int::ns ; + return (xc->readLastActivate() - xc->readLastSuspend()) / Clock::Int::ns; } void From 7712232e556c93204f78807194417e5b13d91cbe Mon Sep 17 00:00:00 2001 From: Kevin Lim Date: Tue, 7 Mar 2006 22:21:39 -0500 Subject: [PATCH 165/180] Fixes to allow the ExecContext to be used for profiling. cpu/base.cc: Change to be calls through the ExecContext instead of accessing the profile object directly. cpu/cpu_exec_context.cc: Add functions to clear and sample the profile object. cpu/cpu_exec_context.hh: Add functions to clear and sample the profile object. These are not the most flexible functions; it might be better to eventually move the quiesce, profile, and store conditional stuff out of ExecContext so they don't clutter the interface. cpu/exec_context.hh: Include functions to support using the profile object to clear itself and take samples. --HG-- extra : convert_revision : 40849915fd51303673451515debb9ecdc7afb8c8 --- cpu/base.cc | 13 ++++++------- cpu/cpu_exec_context.cc | 15 +++++++++++++++ cpu/cpu_exec_context.hh | 4 ++++ cpu/exec_context.hh | 7 +++++++ 4 files changed, 32 insertions(+), 7 deletions(-) diff --git a/cpu/base.cc b/cpu/base.cc index e2a4c214a..2eb5f7fd3 100644 --- a/cpu/base.cc +++ b/cpu/base.cc @@ -271,11 +271,10 @@ BaseCPU::takeOverFrom(BaseCPU *oldCPU) for (int i = 0; i < TheISA::NumInterruptLevels; ++i) interrupts[i] = oldCPU->interrupts[i]; intstatus = oldCPU->intstatus; -/* + for (int i = 0; i < execContexts.size(); ++i) - if (execContexts[i]->profile) - execContexts[i]->profile->clear(); -*/ + execContexts[i]->profileClear(); + if (profileEvent) profileEvent->schedule(curTick); #endif @@ -290,11 +289,11 @@ BaseCPU::ProfileEvent::ProfileEvent(BaseCPU *_cpu, int _interval) void BaseCPU::ProfileEvent::process() { -/* for (int i = 0, size = cpu->execContexts.size(); i < size; ++i) { + for (int i = 0, size = cpu->execContexts.size(); i < size; ++i) { ExecContext *xc = cpu->execContexts[i]; - xc->profile->sample(xc->profileNode, xc->profilePC); + xc->profileSample(); } -*/ + schedule(curTick + interval); } diff --git a/cpu/cpu_exec_context.cc b/cpu/cpu_exec_context.cc index 74b609764..683d07787 100644 --- a/cpu/cpu_exec_context.cc +++ b/cpu/cpu_exec_context.cc @@ -137,6 +137,21 @@ CPUExecContext::EndQuiesceEvent::description() { return "End Quiesce Event."; } + +void +CPUExecContext::profileClear() +{ + if (profile) + profile->clear(); +} + +void +CPUExecContext::profileSample() +{ + if (profile) + profile->sample(profileNode, profilePC); +} + #endif void diff --git a/cpu/cpu_exec_context.hh b/cpu/cpu_exec_context.hh index f5c57da22..e2fbb2368 100644 --- a/cpu/cpu_exec_context.hh +++ b/cpu/cpu_exec_context.hh @@ -157,6 +157,10 @@ class CPUExecContext Tick readLastSuspend() { return lastSuspend; } + void profileClear(); + + void profileSample(); + #else Process *process; diff --git a/cpu/exec_context.hh b/cpu/exec_context.hh index b7653f121..2b6c41bd7 100644 --- a/cpu/exec_context.hh +++ b/cpu/exec_context.hh @@ -136,6 +136,9 @@ class ExecContext // Having an extra function just to read these is obnoxious virtual Tick readLastActivate() = 0; virtual Tick readLastSuspend() = 0; + + virtual void profileClear() = 0; + virtual void profileSample() = 0; #endif virtual int getThreadNum() = 0; @@ -152,6 +155,7 @@ class ExecContext virtual Fault translateDataWriteReq(MemReqPtr &req) = 0; // Also somewhat obnoxious. Really only used for the TLB fault. + // However, may be quite useful in SPARC. virtual TheISA::MachInst getInst() = 0; virtual void copyArchRegs(ExecContext *xc) = 0; @@ -294,6 +298,9 @@ class ProxyExecContext : public ExecContext Tick readLastActivate() { return actualXC->readLastActivate(); } Tick readLastSuspend() { return actualXC->readLastSuspend(); } + + void profileClear() { return actualXC->profileClear(); } + void profileSample() { return actualXC->profileSample(); } #endif int getThreadNum() { return actualXC->getThreadNum(); } From 6a42e3653f46aa4c4cf091b2fb176f2e6667e3cc Mon Sep 17 00:00:00 2001 From: Kevin Lim Date: Tue, 7 Mar 2006 22:23:14 -0500 Subject: [PATCH 166/180] Avoid accessing objects directly within the XC. --HG-- extra : convert_revision : abda610caab885ae39b4e48df4f75cddb93b27ed --- sim/faults.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sim/faults.cc b/sim/faults.cc index 2b93353ce..701384989 100644 --- a/sim/faults.cc +++ b/sim/faults.cc @@ -38,8 +38,8 @@ void FaultBase::invoke(ExecContext * xc) #else void FaultBase::invoke(ExecContext * xc) { - DPRINTF(Fault, "Fault %s at PC: %#x\n", name(), xc->regs.pc); - xc->cpu->recordEvent(csprintf("Fault %s", name())); + DPRINTF(Fault, "Fault %s at PC: %#x\n", name(), xc->readPC()); + xc->getCpuPtr()->recordEvent(csprintf("Fault %s", name())); assert(!xc->misspeculating()); } From 556d069e77f1b6dffa4e4ece7aa86ab462ab8f4f Mon Sep 17 00:00:00 2001 From: Kevin Lim Date: Tue, 7 Mar 2006 22:24:37 -0500 Subject: [PATCH 167/180] Fixes for accesses to the misc regs. --HG-- extra : convert_revision : 47c7d90be5a147cb644f11980adcf8165b0ab3bb --- cpu/o3/alpha_cpu_impl.hh | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/cpu/o3/alpha_cpu_impl.hh b/cpu/o3/alpha_cpu_impl.hh index 33e363d4f..30ef4bd43 100644 --- a/cpu/o3/alpha_cpu_impl.hh +++ b/cpu/o3/alpha_cpu_impl.hh @@ -179,12 +179,16 @@ AlphaFullCPU::copyToXC() this->cpuXC->setFloatRegInt(i, this->regFile.readFloatRegInt(renamed_reg)); } -/* - this->cpuXC->regs.miscRegs.fpcr = this->regFile.miscRegs.fpcr; - this->cpuXC->regs.miscRegs.uniq = this->regFile.miscRegs.uniq; - this->cpuXC->regs.miscRegs.lock_flag = this->regFile.miscRegs.lock_flag; - this->cpuXC->regs.miscRegs.lock_addr = this->regFile.miscRegs.lock_addr; -*/ + + this->cpuXC->setMiscReg(AlphaISA::Fpcr_DepTag, + this->regFile.readMiscReg(AlphaISA::Fpcr_DepTag)); + this->cpuXC->setMiscReg(AlphaISA::Uniq_DepTag, + this->regFile.readMiscReg(AlphaISA::Uniq_DepTag)); + this->cpuXC->setMiscReg(AlphaISA::Lock_Flag_DepTag, + this->regFile.readMiscReg(AlphaISA::Lock_Flag_DepTag)); + this->cpuXC->setMiscReg(AlphaISA::Lock_Addr_DepTag, + this->regFile.readMiscReg(AlphaISA::Lock_Addr_DepTag)); + this->cpuXC->setPC(this->rob.readHeadPC()); this->cpuXC->setNextPC(this->cpuXC->readPC()+4); @@ -223,13 +227,17 @@ AlphaFullCPU::copyFromXC() this->regFile.setFloatRegInt(renamed_reg, this->cpuXC->readFloatRegInt(i)); } - /* + // Then loop through the misc registers. - this->regFile.miscRegs.fpcr = this->cpuXC->regs.miscRegs.fpcr; - this->regFile.miscRegs.uniq = this->cpuXC->regs.miscRegs.uniq; - this->regFile.miscRegs.lock_flag = this->cpuXC->regs.miscRegs.lock_flag; - this->regFile.miscRegs.lock_addr = this->cpuXC->regs.miscRegs.lock_addr; - */ + this->regFile.setMiscReg(AlphaISA::Fpcr_DepTag, + this->cpuXC->readMiscReg(AlphaISA::Fpcr_DepTag)); + this->regFile.setMiscReg(AlphaISA::Uniq_DepTag, + this->cpuXC->readMiscReg(AlphaISA::Uniq_DepTag)); + this->regFile.setMiscReg(AlphaISA::Lock_Flag_DepTag, + this->cpuXC->readMiscReg(AlphaISA::Lock_Flag_DepTag)); + this->regFile.setMiscReg(AlphaISA::Lock_Addr_DepTag, + this->cpuXC->readMiscReg(AlphaISA::Lock_Addr_DepTag)); + // Then finally set the PC and the next PC. // regFile.pc = cpuXC->regs.pc; // regFile.npc = cpuXC->regs.npc; From b5638330751f87930d61743030979e251cacd4ad Mon Sep 17 00:00:00 2001 From: Kevin Lim Date: Tue, 7 Mar 2006 22:56:12 -0500 Subject: [PATCH 168/180] Needs forward declaration of MemoryController. --HG-- extra : convert_revision : 07f397742a026cb6320dc29722d1db21157f26fa --- dev/baddev.hh | 2 ++ dev/isa_fake.hh | 2 ++ 2 files changed, 4 insertions(+) diff --git a/dev/baddev.hh b/dev/baddev.hh index c2a204c05..189f28331 100644 --- a/dev/baddev.hh +++ b/dev/baddev.hh @@ -37,6 +37,8 @@ #include "base/range.hh" #include "dev/io_device.hh" +class MemoryController; + /** * BadDevice * This device just panics when accessed. It is supposed to warn diff --git a/dev/isa_fake.hh b/dev/isa_fake.hh index 290b24b54..73e40c681 100644 --- a/dev/isa_fake.hh +++ b/dev/isa_fake.hh @@ -37,6 +37,8 @@ #include "base/range.hh" #include "dev/io_device.hh" +class MemoryController; + /** * IsaFake is a device that returns -1 on all reads and * accepts all writes. It is meant to be placed at an address range From 20e9a90edcaae9c91280abce0340b602ce4d313e Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Wed, 8 Mar 2006 02:05:38 -0500 Subject: [PATCH 170/180] updated MIPS ISA files .... all files should be able to compile/build with MIPS option except isa_traits.* which I need to update the misc. regfile accesses arch/mips/faults.cc: arch/mips/faults.hh: alpha to mips arch/mips/isa/base.isa: add includes arch/mips/isa/bitfields.isa: more bitfields arch/mips/isa/decoder.isa: lots o' lots o' lots o' changes!!!! arch/mips/isa/formats.isa: include cop0.isa arch/mips/isa/formats/basic.isa: fix faults arch/mips/isa/formats/branch.isa: arch/mips/isa/formats/fp.isa: arch/mips/isa/formats/int.isa: arch/mips/isa/formats/mem.isa: arch/mips/isa/formats/noop.isa: arch/mips/isa/formats/trap.isa: arch/mips/isa/formats/unimp.isa: arch/mips/isa/formats/unknown.isa: arch/mips/isa/formats/util.isa: arch/mips/isa/operands.isa: arch/mips/isa_traits.cc: arch/mips/linux_process.cc: merge MIPS-specific comilable/buidable files code into multiarch arch/mips/isa_traits.hh: merge MIPS-specific comilable/buidable files code into multiarch... the miscRegs file accesses i have need to be recoded and everything should build then ... arch/mips/stacktrace.hh: file copied over --HG-- extra : convert_revision : 4a72e14fc5fb0a0d1f8b205dadbbf69636b7fb1f --- arch/mips/faults.cc | 2 +- arch/mips/faults.hh | 66 +++---- arch/mips/isa/base.isa | 11 +- arch/mips/isa/bitfields.isa | 5 + arch/mips/isa/decoder.isa | 311 +++++++++++++++--------------- arch/mips/isa/formats.isa | 3 + arch/mips/isa/formats/basic.isa | 4 +- arch/mips/isa/formats/branch.isa | 83 ++++---- arch/mips/isa/formats/fp.isa | 41 ---- arch/mips/isa/formats/int.isa | 65 ++++++- arch/mips/isa/formats/mem.isa | 9 +- arch/mips/isa/formats/noop.isa | 10 +- arch/mips/isa/formats/trap.isa | 11 +- arch/mips/isa/formats/unimp.isa | 4 +- arch/mips/isa/formats/unknown.isa | 2 +- arch/mips/isa/formats/util.isa | 69 ++++--- arch/mips/isa/operands.isa | 11 +- arch/mips/isa_traits.cc | 273 +++++++++++++++++++++++++- arch/mips/isa_traits.hh | 196 ++++++++++++++----- arch/mips/linux_process.cc | 4 +- arch/mips/stacktrace.hh | 119 ++++++++++++ 21 files changed, 917 insertions(+), 382 deletions(-) create mode 100644 arch/mips/stacktrace.hh diff --git a/arch/mips/faults.cc b/arch/mips/faults.cc index e05b3fe59..142dfe0a4 100644 --- a/arch/mips/faults.cc +++ b/arch/mips/faults.cc @@ -26,7 +26,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "arch/alpha/faults.hh" +#include "arch/mips/faults.hh" ResetFaultType * const ResetFault = new ResetFaultType("reset", 1, 0x0001); diff --git a/arch/mips/faults.hh b/arch/mips/faults.hh index 60c9e735c..c1cb956b0 100644 --- a/arch/mips/faults.hh +++ b/arch/mips/faults.hh @@ -26,131 +26,131 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef __ALPHA_FAULTS_HH__ -#define __ALPHA_FAULTS_HH__ +#ifndef __MIPS_FAULTS_HH__ +#define __MIPS_FAULTS_HH__ #include "sim/faults.hh" #include "arch/isa_traits.hh" //For the Addr type -class AlphaFault : public Fault +class MipsFault : public FaultBase { public: - AlphaFault(char * newName, int newId, Addr newVect) - : Fault(newName, newId), vect(newVect) + MipsFault(char * newName, int newId, Addr newVect) + : FaultBase(newName, newId), vect(newVect) {;} Addr vect; }; -extern class ResetFaultType : public AlphaFault +extern class ResetFaultType : public MipsFault { public: ResetFaultType(char * newName, int newId, Addr newVect) - : AlphaFault(newName, newId, newVect) + : MipsFault(newName, newId, newVect) {;} } * const ResetFault; -extern class ArithmeticFaultType : public AlphaFault +extern class ArithmeticFaultType : public MipsFault { public: ArithmeticFaultType(char * newName, int newId, Addr newVect) - : AlphaFault(newName, newId, newVect) + : MipsFault(newName, newId, newVect) {;} } * const ArithmeticFault; -extern class InterruptFaultType : public AlphaFault +extern class InterruptFaultType : public MipsFault { public: InterruptFaultType(char * newName, int newId, Addr newVect) - : AlphaFault(newName, newId, newVect) + : MipsFault(newName, newId, newVect) {;} } * const InterruptFault; -extern class NDtbMissFaultType : public AlphaFault +extern class NDtbMissFaultType : public MipsFault { public: NDtbMissFaultType(char * newName, int newId, Addr newVect) - : AlphaFault(newName, newId, newVect) + : MipsFault(newName, newId, newVect) {;} } * const NDtbMissFault; -extern class PDtbMissFaultType : public AlphaFault +extern class PDtbMissFaultType : public MipsFault { public: PDtbMissFaultType(char * newName, int newId, Addr newVect) - : AlphaFault(newName, newId, newVect) + : MipsFault(newName, newId, newVect) {;} } * const PDtbMissFault; -extern class DtbPageFaultType : public AlphaFault +extern class DtbPageFaultType : public MipsFault { public: DtbPageFaultType(char * newName, int newId, Addr newVect) - : AlphaFault(newName, newId, newVect) + : MipsFault(newName, newId, newVect) {;} } * const DtbPageFault; -extern class DtbAcvFaultType : public AlphaFault +extern class DtbAcvFaultType : public MipsFault { public: DtbAcvFaultType(char * newName, int newId, Addr newVect) - : AlphaFault(newName, newId, newVect) + : MipsFault(newName, newId, newVect) {;} } * const DtbAcvFault; -extern class ItbMissFaultType : public AlphaFault +extern class ItbMissFaultType : public MipsFault { public: ItbMissFaultType(char * newName, int newId, Addr newVect) - : AlphaFault(newName, newId, newVect) + : MipsFault(newName, newId, newVect) {;} } * const ItbMissFault; -extern class ItbPageFaultType : public AlphaFault +extern class ItbPageFaultType : public MipsFault { public: ItbPageFaultType(char * newName, int newId, Addr newVect) - : AlphaFault(newName, newId, newVect) + : MipsFault(newName, newId, newVect) {;} } * const ItbPageFault; -extern class ItbAcvFaultType : public AlphaFault +extern class ItbAcvFaultType : public MipsFault { public: ItbAcvFaultType(char * newName, int newId, Addr newVect) - : AlphaFault(newName, newId, newVect) + : MipsFault(newName, newId, newVect) {;} } * const ItbAcvFault; -extern class UnimplementedOpcodeFaultType : public AlphaFault +extern class UnimplementedOpcodeFaultType : public MipsFault { public: UnimplementedOpcodeFaultType(char * newName, int newId, Addr newVect) - : AlphaFault(newName, newId, newVect) + : MipsFault(newName, newId, newVect) {;} } * const UnimplementedOpcodeFault; -extern class FloatEnableFaultType : public AlphaFault +extern class FloatEnableFaultType : public MipsFault { public: FloatEnableFaultType(char * newName, int newId, Addr newVect) - : AlphaFault(newName, newId, newVect) + : MipsFault(newName, newId, newVect) {;} } * const FloatEnableFault; -extern class PalFaultType : public AlphaFault +extern class PalFaultType : public MipsFault { public: PalFaultType(char * newName, int newId, Addr newVect) - : AlphaFault(newName, newId, newVect) + : MipsFault(newName, newId, newVect) {;} } * const PalFault; -extern class IntegerOverflowFaultType : public AlphaFault +extern class IntegerOverflowFaultType : public MipsFault { public: IntegerOverflowFaultType(char * newName, int newId, Addr newVect) - : AlphaFault(newName, newId, newVect) + : MipsFault(newName, newId, newVect) {;} } * const IntegerOverflowFault; diff --git a/arch/mips/isa/base.isa b/arch/mips/isa/base.isa index 7600632d3..4125b5101 100644 --- a/arch/mips/isa/base.isa +++ b/arch/mips/isa/base.isa @@ -7,7 +7,13 @@ //Outputs to decoder.hh output header {{ + #define R31 31 +#include "arch/mips/faults.hh" +#include "arch/mips/isa_traits.hh" + + using namespace MipsISA; + /** * Base class for all MIPS static instructions. @@ -19,12 +25,12 @@ output header {{ /// Make MipsISA register dependence tags directly visible in /// this class and derived classes. Maybe these should really /// live here and not in the MipsISA namespace. - enum DependenceTags { + /*enum DependenceTags { FP_Base_DepTag = MipsISA::FP_Base_DepTag, Fpcr_DepTag = MipsISA::Fpcr_DepTag, Uniq_DepTag = MipsISA::Uniq_DepTag, IPR_Base_DepTag = MipsISA::IPR_Base_DepTag - }; + };*/ // Constructor MipsStaticInst(const char *mnem, MachInst _machInst, OpClass __opClass) @@ -67,6 +73,7 @@ output decoder {{ { printReg(ss, _srcRegIdx[0]); } + if(_numSrcRegs > 1) { ss << ","; diff --git a/arch/mips/isa/bitfields.isa b/arch/mips/isa/bitfields.isa index 3a01b64ee..58d487ad2 100644 --- a/arch/mips/isa/bitfields.isa +++ b/arch/mips/isa/bitfields.isa @@ -33,10 +33,12 @@ def bitfield INTIMM <15: 0>; // integer immediate (literal) // Floating-point operate format def bitfield FMT <25:21>; +def bitfield FR <25:21>; def bitfield FT <20:16>; def bitfield FS <15:11>; def bitfield FD <10:6>; +def bitfield CC <20:18>; def bitfield ND <17:17>; def bitfield TF <16:16>; def bitfield MOVCI <16:16>; @@ -45,6 +47,9 @@ def bitfield SRL <21:21>; def bitfield SRLV < 6: 6>; def bitfield SA <10: 6>; +// CP0 Register Select +def bitfield SEL < 2: 0>; + // Interrupts def bitfield SC < 5: 5>; diff --git a/arch/mips/isa/decoder.isa b/arch/mips/isa/decoder.isa index f16da7f87..b2410f9b9 100644 --- a/arch/mips/isa/decoder.isa +++ b/arch/mips/isa/decoder.isa @@ -20,8 +20,8 @@ decode OPCODE_HI default Unknown::unknown() { 0x0: decode FUNCTION_LO { 0x1: decode MOVCI { format BasicOp { - 0: movf({{ if( xc->miscRegs.fpcr == 0) Rd = Rs}}); - 1: movt({{ if( xc->miscRegs.fpcr == 1) Rd = Rs}}); + 0: movf({{ if (xc->readMiscReg(FPCR,0) != CC) Rd = Rs}}); + 1: movt({{ if (xc->readMiscReg(FPCR,0) == CC) Rd = Rs}}); } } @@ -60,9 +60,9 @@ decode OPCODE_HI default Unknown::unknown() { //to distinguish JR from JR.HB and JALR from JALR.HB" format Jump { 0x0: decode HINT { - 0:jr({{ NNPC = Rs; }},IsReturn); + 0:jr({{ NNPC = Rs & ~1; }},IsReturn); - 1:jr_hb({{ NNPC = Rs; clear_exe_inst_hazards(); }},IsReturn); + 1:jr_hb({{ NNPC = Rs & ~1; clear_exe_inst_hazards(); }},IsReturn); } 0x1: decode HINT { @@ -86,10 +86,10 @@ decode OPCODE_HI default Unknown::unknown() { 0x2: decode FUNCTION_LO { format BasicOp { - 0x0: mfhi({{ Rd = xc->miscRegs.hi; }}); - 0x1: mthi({{ xc->miscRegs.hi = Rs; }}); - 0x2: mflo({{ Rd = xc->miscRegs.lo; }}); - 0x3: mtlo({{ xc->miscRegs.lo = Rs; }}); + 0x0: mfhi({{ Rd = xc->readMiscReg(Hi,0); }}); + 0x1: mthi({{ xc->setMiscReg(Hi,0,Rs); }}); + 0x2: mflo({{ Rd = xc->readMiscReg(Lo,0); }}); + 0x3: mtlo({{ xc->setMiscReg(Lo,0,Rs); }}); } } @@ -97,39 +97,38 @@ decode OPCODE_HI default Unknown::unknown() { format IntOp { 0x0: mult({{ int64_t temp1 = Rs.sw * Rt.sw; - xc->miscRegs.hi->temp1<63:32>; - xc->miscRegs.lo->temp1<31:0>; + xc->setMiscReg(Hi,0,temp1<63:32>); + xc->setMiscReg(Lo,0,temp1<31:0>); }}); 0x1: multu({{ int64_t temp1 = Rs.uw * Rt.uw; - xc->miscRegs.hi->temp1<63:32>; - xc->miscRegs.lo->temp1<31:0> - Rd.sw = Rs.uw * Rt.uw; + xc->setMiscReg(Hi,0,temp1<63:32>); + xc->setMiscReg(Lo,0,temp1<31:0>); }}); 0x2: div({{ - xc->miscRegs.hi = Rs.sw % Rt.sw; - xc->miscRegs.lo = Rs.sw / Rt.sw; + xc->setMiscReg(Hi,0,Rs.sw % Rt.sw); + xc->setMiscReg(Lo,0,Rs.sw / Rt.sw); }}); 0x3: divu({{ - xc->miscRegs.hi = Rs.uw % Rt.uw; - xc->miscRegs.lo = Rs.uw / Rt.uw; + xc->setMiscReg(Hi,0,Rs.uw % Rt.uw); + xc->setMiscReg(Lo,0,Rs.uw / Rt.uw); }}); } } 0x4: decode FUNCTION_LO { format IntOp { - 0x0: add({{ Rd.sw = Rs.sw + Rt.sw;}}); - 0x1: addu({{ Rd.uw = Rs.uw + Rt.uw;}}); - 0x2: sub({{ Rd.sw = Rs.sw - Rt.sw;}}); - 0x3: subu({{ Rd.uw = Rs.uw - Rt.uw;}}); - 0x4: and({{ Rd.sw = Rs.uw & Rt.uw;}}); - 0x5: or({{ Rd.sw = Rs.uw | Rt.uw;}}); - 0x6: xor({{ Rd.sw = Rs.uw ^ Rt.uw;}}); - 0x7: nor({{ Rd.sw = ~(Rs.uw | Rt.uw);}}); + 0x0: add({{ Rd.sw = Rs.sw + Rt.sw;/*Trap on Overflow*/}}); + 0x1: addu({{ Rd.sw = Rs.sw + Rt.sw;}}); + 0x2: sub({{ Rd.sw = Rs.sw - Rt.sw; /*Trap on Overflow*/}}); + 0x3: subu({{ Rd.sw = Rs.sw - Rt.uw;}}); + 0x4: and({{ Rd = Rs & Rt;}}); + 0x5: or({{ Rd = Rs | Rt;}}); + 0x6: xor({{ Rd = Rs ^ Rt;}}); + 0x7: nor({{ Rd = ~(Rs | Rt);}}); } } @@ -141,8 +140,8 @@ decode OPCODE_HI default Unknown::unknown() { } 0x6: decode FUNCTION_LO { - format BasicOp { - 0x0: tge({{ cond = (Rs.sw >= Rt.sw); }}); + format Trap { + 0x0: tge({{ cond = (Rs.sw >= Rt.sw); }}); 0x1: tgeu({{ cond = (Rs.uw >= Rt.uw); }}); 0x2: tlt({{ cond = (Rs.sw < Rt.sw); }}); 0x3: tltu({{ cond = (Rs.uw >= Rt.uw); }}); @@ -167,7 +166,7 @@ decode OPCODE_HI default Unknown::unknown() { } 0x1: decode REGIMM_LO { - format BasicOp { + format Trap { 0x0: tgei( {{ cond = (Rs.sw >= INTIMM); }}); 0x1: tgeiu({{ cond = (Rs.uw >= INTIMM); }}); 0x2: tlti( {{ cond = (Rs.sw < INTIMM); }}); @@ -198,14 +197,14 @@ decode OPCODE_HI default Unknown::unknown() { } format Jump { - 0x2: j({{ NNPC = (NPC & 0xF0000000) & (0x00000000 & JMPTARG << 2);}}); + 0x2: j({{ NNPC = (NPC & 0xF0000000) | (JMPTARG << 2);}}); - 0x3: jal({{ NNPC = (NPC & 0xF0000000) & (0x00000000 & JMPTARG << 2);}},IsCall,IsReturn); + 0x3: jal({{ NNPC = (NPC & 0xF0000000) | (JMPTARG << 2); }},IsCall,IsReturn); } format Branch { - 0x4: beq({{ cond = (Rs.sw == 0); }}); - 0x5: bne({{ cond = (Rs.sw != 0); }}); + 0x4: beq({{ cond = (Rs.sw == Rt.sw); }}); + 0x5: bne({{ cond = (Rs.sw != Rt.sw); }}); 0x6: blez({{ cond = (Rs.sw <= 0); }}); 0x7: bgtz({{ cond = (Rs.sw > 0); }}); } @@ -213,10 +212,10 @@ decode OPCODE_HI default Unknown::unknown() { 0x1: decode OPCODE_LO { format IntOp { - 0x0: addi({{ Rt.sw = Rs.sw + INTIMM; }}); - 0x1: addiu({{ Rt.uw = Rs.uw + INTIMM;}}); - 0x2: slti({{ Rt.sw = ( Rs.sw < INTIMM ) ? 1 : 0 }}); - 0x3: sltiu({{ Rt.uw = ( Rs.uw < INTIMM ) ? 1 : 0 }}); + 0x0: addi({{ Rt.sw = Rs.sw + imm; /*Trap If Overflow*/}}); + 0x1: addiu({{ Rt.sw = Rs.sw + imm;}}); + 0x2: slti({{ Rt.sw = ( Rs.sw < imm) ? 1 : 0 }}); + 0x3: sltiu({{ Rt.sw = ( Rs.sw < imm ) ? 1 : 0 }}); 0x4: andi({{ Rt.sw = Rs.sw & INTIMM;}}); 0x5: ori({{ Rt.sw = Rs.sw | INTIMM;}}); 0x6: xori({{ Rt.sw = Rs.sw ^ INTIMM;}}); @@ -229,33 +228,17 @@ decode OPCODE_HI default Unknown::unknown() { //Table A-11 MIPS32 COP0 Encoding of rs Field 0x0: decode RS_MSB { 0x0: decode RS { - format BasicOp { + format System { 0x0: mfc0({{ - //The contents of the coprocessor 0 register specified by the - //combination of rd and sel are loaded into general register - //rt. Note that not all coprocessor 0 registers support the - //sel field. In those instances, the sel field must be zero. + //uint64_t reg_num = Rd.uw; - if (SEL > 0) - panic("Can't Handle Cop0 with register select yet\n"); - - uint64_t reg_num = Rd.uw; - - Rt = xc->miscRegs.cop0[reg_num]; + Rt = xc->readMiscReg(RD,SEL); }}); 0x4: mtc0({{ - //The contents of the coprocessor 0 register specified by the - //combination of rd and sel are loaded into general register - //rt. Note that not all coprocessor 0 registers support the - //sel field. In those instances, the sel field must be zero. + //uint64_t reg_num = Rd.uw; - if (SEL > 0) - panic("Can't Handle Cop0 with register select yet\n"); - - uint64_t reg_num = Rd.uw; - - xc->miscRegs.cop0[reg_num] = Rt; + xc->setMiscReg(RD,SEL,Rt); }}); 0x8: mftr({{ @@ -279,64 +262,84 @@ decode OPCODE_HI default Unknown::unknown() { 0xA: rdpgpr({{ //Accessing Previous Shadow Set Register Number - uint64_t prev = xc->miscRegs.cop0[SRSCtl][PSS]; - uint64_t reg_num = Rt.uw; + //uint64_t prev = xc->readMiscReg(SRSCtl)/*[PSS]*/; + //uint64_t reg_num = Rt.uw; - Rd = xc->shadowIntRegFile[prev][reg_num]; + //Rd = xc->regs.IntRegFile[prev]; + //Rd = xc->shadowIntRegFile[prev][reg_num]; }}); 0xB: decode RD { 0x0: decode SC { 0x0: dvpe({{ - Rt.sw = xc->miscRegs.cop0.MVPControl; - xc->miscRegs.cop0.MVPControl[EVP] = 0; + int idx; + int sel; + getMiscRegIdx(MVPControl,idx,sel); + Rt.sw = xc->readMiscReg(idx,sel); + xc->setMiscReg(idx,sel,0); }}); 0x1: evpe({{ - Rt.sw = xc->miscRegs.cop0.MVPControl; - xc->miscRegs.cop0.MVPControl[EVP] = 1; + int idx; + int sel; + getMiscRegIdx(MVPControl,idx,sel); + Rt.sw = xc->readMiscReg(idx,sel); + xc->setMiscReg(idx,sel,1); }}); } 0x1: decode SC { 0x0: dmt({{ - Rt.sw = xc->miscRegs.cop0.VPEControl; - xc->miscRegs.cop0.VPEControl[THREAD_ENABLE] = 0; + int idx; + int sel; + getMiscRegIdx(VPEControl,idx,sel); + Rt.sw = xc->readMiscReg(idx,sel); + xc->setMiscReg(idx,sel,0); }}); 0x1: emt({{ - Rt.sw = xc->miscRegs.cop0.VPEControl; - xc->miscRegs.cop0.VPEControl[THREAD_ENABLE] = 1; + int idx; + int sel; + getMiscRegIdx(VPEControl,idx,sel); + Rt.sw = xc->readMiscReg(idx,sel); + xc->setMiscReg(idx,sel,1); }}); } 0xC: decode SC { 0x0: di({{ - Rt.sw = xc->miscRegs.cop0.Status; - xc->miscRegs.cop0.Status[INTERRUPT_ENABLE] = 0; + int idx; + int sel; + getMiscRegIdx(Status,idx,sel); + Rt.sw = xc->readMiscReg(idx,sel); + xc->setMiscReg(idx,sel,0); }}); 0x1: ei({{ - Rt.sw = xc->miscRegs.cop0.Status; - xc->miscRegs.cop0.Status[INTERRUPT_ENABLE] = 1; + int idx; + int sel; + getMiscRegIdx(Status,idx,sel); + Rt.sw = xc->readMiscReg(idx,sel); + xc->setMiscReg(idx,sel,1); }}); } } 0xE: wrpgpr({{ //Accessing Previous Shadow Set Register Number - uint64_t prev = xc->miscRegs.cop0[SRSCtl][PSS]; - uint64_t reg_num = Rd.uw; + //uint64_t prev = xc->readMiscReg(SRSCtl/*[PSS]*/); + //uint64_t reg_num = Rd.uw; - xc->shadowIntRegFile[prev][reg_num] = Rt; + //xc->regs.IntRegFile[prev]; + //xc->shadowIntRegFile[prev][reg_num] = Rt; }}); } } //Table A-12 MIPS32 COP0 Encoding of Function Field When rs=CO 0x1: decode FUNCTION { - format BasicOp { + format System { 0x01: tlbr({{ }}); 0x02: tlbwi({{ }}); 0x06: tlbwr({{ }}); @@ -357,27 +360,27 @@ decode OPCODE_HI default Unknown::unknown() { 0x0: decode RS_HI { 0x0: decode RS_LO { format FloatOp { - 0x0: mfc1({{ Rt = Fs<31:0>; }}); - 0x2: cfc1({{ Rt = xc->miscRegs.fpcr[Fs];}}); - 0x3: mfhc1({{ Rt = Fs<63:32>;}}); - 0x4: mtc1({{ Fs<31:0> = Rt}}); - 0x6: ctc1({{ xc->miscRegs.fpcr[Fs] = Rt;}}); - 0x7: mftc1({{ Fs<63:32> = Rt}}); + 0x0: mfc1({{ /*Rt.uw = Fs.ud<31:0>;*/ }}); + 0x2: cfc1({{ /*Rt.uw = xc->readMiscReg(FPCR[Fs]);*/}}); + 0x3: mfhc1({{ /*Rt.uw = Fs.ud<63:32>*/;}}); + 0x4: mtc1({{ /*Fs = Rt.uw*/}}); + 0x6: ctc1({{ /*xc->setMiscReg(FPCR[Fs],Rt);*/}}); + 0x7: mthc1({{ /*Fs<63:32> = Rt.uw*/}}); } } 0x1: decode ND { 0x0: decode TF { format Branch { - 0x0: bc1f({{ cond = (xc->miscRegs.fpcr == 0); }}); - 0x1: bc1t({{ cond = (xc->miscRegs.fpcr == 1); }}); + 0x0: bc1f({{ cond = (xc->readMiscReg(FPCR,0) == 0); }}); + 0x1: bc1t({{ cond = (xc->readMiscReg(FPCR,0) == 1); }}); } } 0x1: decode TF { format BranchLikely { - 0x0: bc1fl({{ cond = (xc->miscRegs.fpcr == 0); }}); - 0x1: bc1tl({{ cond = (xc->miscRegs.fpcr == 1); }}); + 0x0: bc1fl({{ cond = (xc->readMiscReg(FPCR,0) == 0); }}); + 0x1: bc1tl({{ cond = (xc->readMiscReg(FPCR,0) == 1); }}); } } } @@ -396,7 +399,7 @@ decode OPCODE_HI default Unknown::unknown() { 0x2: muls({{ Fd.sf = Fs.sf * Ft.sf;}}); 0x3: divs({{ Fd.sf = Fs.sf / Ft.sf;}}); 0x4: sqrts({{ Fd.sf = sqrt(Fs.sf);}}); - 0x5: abss({{ Fd.sf = abs(Fs.sf);}}); + 0x5: abss({{ Fd.sf = fabs(Fs.sf);}}); 0x6: movs({{ Fd.sf = Fs.sf;}}); 0x7: negs({{ Fd.sf = -1 * Fs.sf;}}); } @@ -422,8 +425,8 @@ decode OPCODE_HI default Unknown::unknown() { 0x2: decode RS_LO { 0x1: decode MOVCF { format FloatOp { - 0x0: movfs({{ if ( FPConditionCode(CC) == 0 ) Fd = Fs; }}); - 0x1: movts({{ if ( FPConditionCode(CC) == 1 ) Fd = Fs;}}); + 0x0: movfs({{if (xc->readMiscReg(FPCR,0) != CC) Fd = Fs; }}); + 0x1: movts({{if (xc->readMiscReg(FPCR,0) == CC) Fd = Fs;}}); } } @@ -434,29 +437,29 @@ decode OPCODE_HI default Unknown::unknown() { format Float64Op { 0x5: recips({{ Fd = 1 / Fs; }}); - 0x6: rsqrts({{ Fd = 1 / sqrt(Fs.ud);}}); + 0x6: rsqrts({{ Fd = 1 / sqrt((double)Fs.ud);}}); } } 0x4: decode RS_LO { format FloatOp { - 0x1: cvt_d_s({{ int rnd_mode = xc->miscRegs.fcsr; + 0x1: cvt_d_s({{ int rnd_mode = xc->readMiscReg(FCSR,0); Fd = convert_and_round(Fs.sf,rnd_mode,FP_DOUBLE,FP_SINGLE); }}); - 0x4: cvt_w_s({{ int rnd_mode = xc->miscRegs.fcsr; + 0x4: cvt_w_s({{ int rnd_mode = xc->readMiscReg(FCSR,0); Fd = convert_and_round(Fs.sf,rnd_mode,FP_WORD,FP_SINGLE); }}); } //only legal for 64 bit format Float64Op { - 0x5: cvt_l_s({{ int rnd_mode = xc->miscRegs.fcsr; + 0x5: cvt_l_s({{ int rnd_mode = xc->readMiscReg(FCSR,0); Fd = convert_and_round(Fs.sf,rnd_mode,FP_LONG,FP_SINGLE); }}); - 0x6: cvt_ps_s({{ Fd.df = Fs.df<31:0> | Ft.df<31:0>; }}); + 0x6: cvt_ps_s({{ /*Fd.df = Fs.df<31:0> | Ft.df<31:0>;*/ }}); } } } @@ -470,7 +473,7 @@ decode OPCODE_HI default Unknown::unknown() { 0x2: muld({{ Fd.df = Fs.df * Ft.df;}}); 0x3: divd({{ Fd.df = Fs.df / Ft.df;}}); 0x4: sqrtd({{ Fd.df = sqrt(Fs.df);}}); - 0x5: absd({{ Fd.df = abs(Fs.df);}}); + 0x5: absd({{ Fd.df = fabs(Fs.df);}}); 0x6: movd({{ Fd.df = Fs.df;}}); 0x7: negd({{ Fd.df = -1 * Fs.df;}}); } @@ -496,8 +499,8 @@ decode OPCODE_HI default Unknown::unknown() { 0x2: decode RS_LO { 0x1: decode MOVCF { format FloatOp { - 0x0: movfd({{ if (FPConditionCode(CC) == 0) Fd.df = Fs.df; }}); - 0x1: movtd({{ if (FPConditionCode(CC) == 1) Fd.df = Fs.df; }}); + 0x0: movfd({{if (xc->readMiscReg(FPCR,0) != CC) Fd.df = Fs.df; }}); + 0x1: movtd({{if (xc->readMiscReg(FPCR,0) == CC) Fd.df = Fs.df; }}); } } @@ -515,12 +518,12 @@ decode OPCODE_HI default Unknown::unknown() { 0x4: decode RS_LO { format FloatOp { 0x0: cvt_s_d({{ - int rnd_mode = xc->miscRegs.fcsr; + int rnd_mode = xc->readMiscReg(FCSR,0); Fd = convert_and_round(Fs.df,rnd_mode,FP_SINGLE,FP_DOUBLE); }}); 0x4: cvt_w_d({{ - int rnd_mode = xc->miscRegs.fcsr; + int rnd_mode = xc->readMiscReg(FCSR,0); Fd = convert_and_round(Fs.df,rnd_mode,FP_WORD,FP_DOUBLE); }}); } @@ -528,7 +531,7 @@ decode OPCODE_HI default Unknown::unknown() { //only legal for 64 bit format Float64Op { 0x5: cvt_l_d({{ - int rnd_mode = xc->miscRegs.fcsr; + int rnd_mode = xc->readMiscReg(FCSR,0); Fd = convert_and_round(Fs.df,rnd_mode,FP_LONG,FP_DOUBLE); }}); } @@ -539,12 +542,12 @@ decode OPCODE_HI default Unknown::unknown() { 0x4: decode FUNCTION { format FloatOp { 0x20: cvt_s({{ - int rnd_mode = xc->miscRegs.fcsr; + int rnd_mode = xc->readMiscReg(FCSR,0); Fd = convert_and_round(Fs.df,rnd_mode,FP_SINGLE,FP_WORD); }}); 0x21: cvt_d({{ - int rnd_mode = xc->miscRegs.fcsr; + int rnd_mode = xc->readMiscReg(FCSR,0); Fd = convert_and_round(Fs.df,rnd_mode,FP_DOUBLE,FP_WORD); }}); } @@ -556,12 +559,12 @@ decode OPCODE_HI default Unknown::unknown() { 0x5: decode FUNCTION_HI { format FloatOp { 0x10: cvt_s_l({{ - int rnd_mode = xc->miscRegs.fcsr; + int rnd_mode = xc->readMiscReg(FCSR,0); Fd = convert_and_round(Fs.df,rnd_mode,FP_SINGLE,FP_LONG); }}); 0x11: cvt_d_l({{ - int rnd_mode = xc->miscRegs.fcsr; + int rnd_mode = xc->readMiscReg(FCSR,0); Fd = convert_and_round(Fs.df,rnd_mode,FP_DOUBLE,FP_LONG); }}); } @@ -590,12 +593,12 @@ decode OPCODE_HI default Unknown::unknown() { 0x5: absps({{ //Must Check for Exception Here... Supposed to Operate on Upper and //Lower Halves Independently but we take simulator shortcut - Fd.df = abs(Fs.df); + Fd.df = fabs(Fs.df); }}); 0x6: movps({{ //Must Check for Exception Here... Supposed to Operate on Upper and //Lower Halves Independently but we take simulator shortcut - Fd.df = Fs<31:0> | Ft<31:0>; + //Fd.df = Fs<31:0> | Ft<31:0>; }}); 0x7: negps({{ //Must Check for Exception Here... Supposed to Operate on Upper and @@ -608,21 +611,21 @@ decode OPCODE_HI default Unknown::unknown() { 0x2: decode RS_LO { 0x1: decode MOVCF { format Float64Op { - 0x0: movfps({{ if ( FPConditionCode(CC) == 0) Fd = Fs;}}); - 0x1: movtps({{ if ( FPConditionCode(CC) == 0) Fd = Fs;}}); + 0x0: movfps({{if (xc->readMiscReg(FPCR,0) != CC) Fd = Fs;}}); + 0x1: movtps({{if (xc->readMiscReg(FPCR,0) == CC) Fd = Fs;}}); } } format BasicOp { - 0x2: movzps({{ if ( FPConditionCode(CC) == 0) Fd = Fs; }}); - 0x3: movnps({{ if ( FPConditionCode(CC) == 0) Fd = Fs; }}); + 0x2: movzps({{if (xc->readMiscReg(FPCR,0) != CC) Fd = Fs; }}); + 0x3: movnps({{if (xc->readMiscReg(FPCR,0) == CC) Fd = Fs; }}); } } 0x4: decode RS_LO { 0x0: Float64Op::cvt_s_pu({{ - int rnd_mode = xc->miscRegs.fcsr; + int rnd_mode = xc->readMiscReg(FCSR,0); Fd = convert_and_round(Fs.df,rnd_mode,FP_DOUBLE,FP_PS_HI); }}); } @@ -630,13 +633,13 @@ decode OPCODE_HI default Unknown::unknown() { 0x5: decode RS_LO { format Float64Op { 0x0: cvt_s_pl({{ - int rnd_mode = xc->miscRegs.fcsr; + int rnd_mode = xc->readMiscReg(FCSR,0); Fd = convert_and_round(Fs.df,rnd_mode,FP_SINGLE,FP_PS_LO); }}); - 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.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>*/}}); } } } @@ -682,23 +685,23 @@ decode OPCODE_HI default Unknown::unknown() { 0x3: decode FUNCTION_HI { 0x0: decode FUNCTION_LO { format LoadMemory2 { - 0x0: lwxc1({{ EA = Rs + Rt; }},{{ Ft<31:0> = Mem.sf; }}); - 0x1: ldxc1({{ EA = Rs + Rt; }},{{ Ft<63:0> = Mem.df; }}); + 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; }}, - {{ Ft<31:0> = Mem.df; }}); + {{ /*F_t<31:0> = Mem.df; */}}); } } 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>}}); + 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 = Ft<63:0>;}}); + {{ /*Mem.df = F_t<63:0>;*/}}); } 0x7: WarnUnimpl::prefx(); @@ -768,33 +771,33 @@ decode OPCODE_HI default Unknown::unknown() { 0x0: decode FUNCTION_LO { format IntOp { 0x0: madd({{ - int64_t temp1 = Hi.sw << 32 | Lo.sw >> 32; + int64_t temp1 = xc->readMiscReg(Hi,0) << 32 | xc->readMiscReg(Lo,0) >> 32; temp1 = temp1 + (Rs.sw * Rt.sw); - xc->miscRegs.hi->temp1<63:32>; - xc->miscRegs.lo->temp1<31:0> + xc->setMiscReg(Hi,0,temp1<63:32>); + xc->setMiscReg(Lo,0,temp1<31:0>); }}); 0x1: maddu({{ - int64_t temp1 = Hi.uw << 32 | Lo.uw >> 32; + int64_t temp1 = xc->readMiscReg(Hi,0) << 32 | xc->readMiscReg(Lo,0) >> 32; temp1 = temp1 + (Rs.uw * Rt.uw); - xc->miscRegs.hi->temp1<63:32>; - xc->miscRegs.lo->temp1<31:0> + xc->setMiscReg(Hi,0,temp1<63:32>); + xc->setMiscReg(Lo,0,temp1<31:0>); }}); - 0x2: mul({{ Rd.sw = Rs.sw * Rt.sw; }}); + 0x2: mul({{ Rd.sw = Rs.sw * Rt.sw; }}); 0x4: msub({{ - int64_t temp1 = Hi.sw << 32 | Lo.sw >> 32; + int64_t temp1 = xc->readMiscReg(Hi,0) << 32 | xc->readMiscReg(Lo,0) >> 32; temp1 = temp1 - (Rs.sw * Rt.sw); - xc->miscRegs.hi->temp1<63:32>; - xc->miscRegs.lo->temp1<31:0> + xc->setMiscReg(Hi,0,temp1<63:32>); + xc->setMiscReg(Lo,0,temp1<31:0>); }}); 0x5: msubu({{ - int64_t temp1 = Hi.uw << 32 | Lo.uw >> 32; + int64_t temp1 = xc->readMiscReg(Hi,0) << 32 | xc->readMiscReg(Lo,0) >> 32; temp1 = temp1 - (Rs.uw * Rt.uw); - xc->miscRegs.hi->temp1<63:32>; - xc->miscRegs.lo->temp1<31:0> + xc->setMiscReg(Hi,0,temp1<63:32>); + xc->setMiscReg(Lo,0,temp1<31:0>); }}); } } @@ -802,25 +805,25 @@ decode OPCODE_HI default Unknown::unknown() { 0x4: decode FUNCTION_LO { format BasicOp { 0x0: clz({{ - int cnt = 0; + /*int cnt = 0; int idx = 0; - while ( Rs.uw!= 1) { + while ( Rs.uw != 1) { cnt++; idx--; } - Rd.uw = cnt; + Rd.uw = cnt;*/ }}); 0x1: clo({{ - int cnt = 0; + /*int cnt = 0; int idx = 0; - while ( Rs.uw!= 0) { + while ( Rs.uw != 0) { cnt++; idx--; } - Rd.uw = cnt; + Rd.uw = cnt;*/ }}); } } @@ -860,20 +863,20 @@ decode OPCODE_HI default Unknown::unknown() { } 0x6: decode FUNCTION_LO { - 0x7: BasicOp::rdhwr({{ Rt = xc->hwRegs[RD];}}); + 0x7: BasicOp::rdhwr({{ /*Rt = xc->hwRegs[RD];*/ }}); } } } 0x4: decode OPCODE_LO default FailUnimpl::reserved() { format LoadMemory { - 0x0: lb({{ Rb.sw = Mem.sb; }}); - 0x1: lh({{ Rb.sw = Mem.sh; }}); - 0x2: lwl({{ Rb.sw = Mem.sw; }});//, WordAlign); - 0x3: lw({{ Rb.uq = Mem.sb; }}); - 0x4: lbu({{ Rb.uw = Mem.ub; }}); - 0x5: lhu({{ Rb.uw = Mem.uh; }}); - 0x6: lwr({{ Rb.uw = Mem.uw; }});//, WordAlign); + 0x0: lb({{ Rt.sw = Mem.sb; }}); + 0x1: lh({{ Rt.sw = Mem.sh; }}); + 0x2: lwl({{ Rt.sw = Mem.sw; }});//, WordAlign); + 0x3: lw({{ Rt.sw = Mem.sb; }}); + 0x4: lbu({{ Rt.uw = Mem.ub; }}); + 0x5: lhu({{ Rt.uw = Mem.uh; }}); + 0x6: lwr({{ Rt.uw = Mem.uw; }});//, WordAlign); } 0x7: FailUnimpl::reserved(); @@ -898,19 +901,19 @@ decode OPCODE_HI default Unknown::unknown() { 0x0: WarnUnimpl::ll(); format LoadMemory { - 0x1: lwc1({{ Ft<31:0> = Mem.sf; }}); - 0x5: ldc1({{ Ft<63:0> = Mem.df; }}); + 0x1: lwc1({{ /*F_t<31:0> = Mem.sf; */}}); + 0x5: ldc1({{ /*F_t<63:0> = Mem.df; */}}); } } + 0x7: decode OPCODE_LO default FailUnimpl::reserved() { 0x0: WarnUnimpl::sc(); format StoreMemory { - 0x1: swc1({{ Mem.sf = Ft<31:0>; }}); - 0x5: sdc1({{ Mem.df = Ft<63:0>; }}); + 0x1: swc1({{ //Mem.sf = Ft<31:0>; }}); + 0x5: sdc1({{ //Mem.df = Ft<63:0>; }}); } - } } diff --git a/arch/mips/isa/formats.isa b/arch/mips/isa/formats.isa index a6aec9437..f7a9e4ce2 100644 --- a/arch/mips/isa/formats.isa +++ b/arch/mips/isa/formats.isa @@ -10,6 +10,9 @@ //Include utility formats/functions ##include "m5/arch/mips/isa/formats/util.isa" +//Include the cop0 formats +##include "m5/arch/mips/isa/formats/cop0.isa" + //Include the integer formats ##include "m5/arch/mips/isa/formats/int.isa" diff --git a/arch/mips/isa/formats/basic.isa b/arch/mips/isa/formats/basic.isa index 3b62aa5c3..c02af7ddc 100644 --- a/arch/mips/isa/formats/basic.isa +++ b/arch/mips/isa/formats/basic.isa @@ -31,14 +31,14 @@ def template BasicConstructor {{ def template BasicExecute {{ Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const { - Fault fault = No_Fault; + Fault fault = NoFault; %(fp_enable_check)s; %(op_decl)s; %(op_rd)s; %(code)s; - if(fault == No_Fault) + if(fault == NoFault) { %(op_wb)s; } diff --git a/arch/mips/isa/formats/branch.isa b/arch/mips/isa/formats/branch.isa index c896e9b2d..0d2ad7855 100644 --- a/arch/mips/isa/formats/branch.isa +++ b/arch/mips/isa/formats/branch.isa @@ -7,6 +7,9 @@ output header {{ +#include + using namespace std; + /** * Base class for instructions whose disassembly is not purely a * function of the machine instruction (i.e., it depends on the @@ -52,6 +55,10 @@ output header {{ : PCDependentDisassembly(mnem, _machInst, __opClass), disp(OFFSET << 2) { + //If Bit 17 is 1 then Sign Extend + if ( (disp & 0x00020000) > 0 ) { + disp |= 0xFFFE0000; + } } Addr branchTarget(Addr branchPC) const; @@ -74,6 +81,7 @@ output header {{ : PCDependentDisassembly(mnem, _machInst, __opClass), disp(OFFSET << 2) { + } Addr branchTarget(Addr branchPC) const; @@ -93,11 +101,13 @@ output header {{ /// Displacement to target address (signed). int32_t disp; + uint32_t target; + public: /// Constructor Jump(const char *mnem, MachInst _machInst, OpClass __opClass) : PCDependentDisassembly(mnem, _machInst, __opClass), - disp(OFFSET) + disp(JMPTARG << 2) { } @@ -159,23 +169,17 @@ output decoder {{ // either a source (the condition for conditional // branches) or a destination (the link reg for // unconditional branches) - if (_numSrcRegs > 0) { + if (_numSrcRegs == 1) { printReg(ss, _srcRegIdx[0]); ss << ","; - } - else if (_numDestRegs > 0) { - printReg(ss, _destRegIdx[0]); + } else if(_numSrcRegs == 2) { + printReg(ss, _srcRegIdx[0]); + ss << ","; + printReg(ss, _srcRegIdx[1]); ss << ","; } -#ifdef SS_COMPATIBLE_DISASSEMBLY - if (_numSrcRegs == 0 && _numDestRegs == 0) { - printReg(ss, 31); - ss << ","; - } -#endif - - Addr target = pc + 4 + disp; + Addr target = pc + 8 + disp; std::string str; if (symtab && symtab->findSymbol(target, str)) @@ -206,13 +210,6 @@ output decoder {{ ss << ","; } -#ifdef SS_COMPATIBLE_DISASSEMBLY - if (_numSrcRegs == 0 && _numDestRegs == 0) { - printReg(ss, 31); - ss << ","; - } -#endif - Addr target = pc + 4 + disp; std::string str; @@ -231,19 +228,24 @@ output decoder {{ ccprintf(ss, "%-10s ", mnemonic); -#ifdef SS_COMPATIBLE_DISASSEMBLY - if (_numDestRegs == 0) { - printReg(ss, 31); + if ( mnemonic == "jal" ) { + Addr npc = pc + 4; + ccprintf(ss,"0x%x",(npc & 0xF0000000) | disp); + } else if (_numSrcRegs == 0) { + std::string str; + if (symtab && symtab->findSymbol(disp, str)) + ss << str; + else + ccprintf(ss, "0x%x", disp); + } else if (_numSrcRegs == 1) { + printReg(ss, _srcRegIdx[0]); + } else if(_numSrcRegs == 2) { + printReg(ss, _srcRegIdx[0]); ss << ","; + printReg(ss, _srcRegIdx[1]); + } else { + panic(">= 3 Source Registers!!!"); } -#endif - - if (_numDestRegs > 0) { - printReg(ss, _destRegIdx[0]); - ss << ","; - } - - ccprintf(ss, "(r%d)", RT); return ss.str(); } @@ -253,16 +255,18 @@ def format Branch(code,*flags) {{ #Add Link Code if Link instruction strlen = len(name) if name[strlen-2:] == 'al': - code += 'R31 = NNPC;\n' + code += 'r31 = NNPC;\n' #Condition code code = 'bool cond;\n' + code code += 'if (cond) {\n' - #code += '//NPC=NPC: just placeholder to force parser to writeback NPC\n' - #code += ' NPC = NPC; \n' code += ' NNPC = NPC + disp;\n' + code += '} else {\n' + code += ' NNPC = NNPC;\n' code += '} \n' + code += 'cout << hex << "NPC: " << NPC << " + " << disp << " = " << NNPC << endl;' + iop = InstObjParams(name, Name, 'Branch', CodeBlock(code), ('IsDirectControl', 'IsCondControl')) @@ -277,13 +281,11 @@ def format BranchLikely(code,*flags) {{ #Add Link Code if Link instruction strlen = len(name) if name[strlen-3:] == 'all': - code += 'R31 = NNPC;\n' + code += 'r31 = NNPC;\n' #Condition code code = 'bool cond;\n' + code code += 'if (cond) {' - #code += '//NPC=NPC: just placeholder to force parser to writeback NPC\n' - #code += 'NPC = NPC; \n' code += 'NNPC = NPC + disp;\n' code += '} \n' @@ -300,8 +302,11 @@ def format BranchLikely(code,*flags) {{ def format Jump(code,*flags) {{ #Add Link Code if Link instruction strlen = len(name) - if strlen >= 3 and name[2:3] == 'al': - code = 'R31 = NNPC;\n' + code + if strlen > 1 and name[1:] == 'al': + code = 'r31 = NNPC;\n' + code + + #code += 'if(NNPC == 0x80000638) { NNPC = r31; cout << "SKIPPING JUMP TO SIM_GET_MEM_CONF" << endl;}' + #code += 'target = NNPC;' iop = InstObjParams(name, Name, 'Jump', CodeBlock(code),\ ('IsIndirectControl', 'IsUncondControl')) diff --git a/arch/mips/isa/formats/fp.isa b/arch/mips/isa/formats/fp.isa index 7dd1e8442..34b71acf7 100644 --- a/arch/mips/isa/formats/fp.isa +++ b/arch/mips/isa/formats/fp.isa @@ -29,47 +29,6 @@ output decoder {{ } }}; -def template FloatingPointExecute {{ - Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const - { - //These are set to constants when the execute method - //is generated - bool useCc = ; - bool checkPriv = ; - - //Attempt to execute the instruction - try - { - checkPriv; - - %(op_decl)s; - %(op_rd)s; - %(code)s; - } - //If we have an exception for some reason, - //deal with it - catch(MipsException except) - { - //Deal with exception - return No_Fault; - } - - //Write the resulting state to the execution context - %(op_wb)s; - if(useCc) - { - xc->regs.miscRegFile.ccrFields.iccFields.n = Rd & (1 << 63); - xc->regs.miscRegFile.ccrFields.iccFields.z = (Rd == 0); - xc->regs.miscRegFile.ccrFields.iccFields.v = ivValue; - xc->regs.miscRegFile.ccrFields.iccFields.c = icValue; - xc->regs.miscRegFile.ccrFields.xccFields.n = Rd & (1 << 31); - xc->regs.miscRegFile.ccrFields.xccFields.z = ((Rd & 0xFFFFFFFF) == 0); - xc->regs.miscRegFile.ccrFields.xccFields.v = xvValue; - xc->regs.miscRegFile.ccrFields.xccFields.c = xcValue; - } - return No_Fault; - } -}}; // Primary format for integer operate instructions: def format FloatOp(code, *flags) {{ diff --git a/arch/mips/isa/formats/int.isa b/arch/mips/isa/formats/int.isa index cf06741a1..a47844bee 100644 --- a/arch/mips/isa/formats/int.isa +++ b/arch/mips/isa/formats/int.isa @@ -7,6 +7,8 @@ //Outputs to decoder.hh output header {{ +#include + using namespace std; /** * Base class for integer operations. */ @@ -26,15 +28,24 @@ output header {{ class IntImmOp : public MipsStaticInst { protected: - uint16_t imm; + + int32_t imm; /// Constructor IntImmOp(const char *mnem, MachInst _machInst, OpClass __opClass) : MipsStaticInst(mnem, _machInst, __opClass),imm(INTIMM) { + //If Bit 15 is 1 then Sign Extend + int32_t temp = imm & 0x00008000; + + if (temp > 0 && mnemonic != "lui") { + imm |= 0xFFFF0000; + } } std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; + + }; }}; @@ -43,15 +54,59 @@ output header {{ output decoder {{ std::string IntOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const { - return "Disassembly of integer instruction\n"; + std::stringstream ss; + + ccprintf(ss, "%-10s ", mnemonic); + + // just print the first dest... if there's a second one, + // it's generally implicit + if (_numDestRegs > 0) { + printReg(ss, _destRegIdx[0]); + } + + ss << ","; + + // just print the first two source regs... if there's + // a third one, it's a read-modify-write dest (Rc), + // e.g. for CMOVxx + if (_numSrcRegs > 0) { + printReg(ss, _srcRegIdx[0]); + } + + if (_numSrcRegs > 1) { + ss << ","; + printReg(ss, _srcRegIdx[1]); + } + + return ss.str(); } std::string IntImmOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const { - return "Disassembly of integer immediate instruction\n"; - } -}}; + std::stringstream ss; + ccprintf(ss, "%-10s ", mnemonic); + + if (_numDestRegs > 0) { + printReg(ss, _destRegIdx[0]); + } + + ss << ","; + + if (_numSrcRegs > 0) { + printReg(ss, _srcRegIdx[0]); + ss << ","; + } + + if( mnemonic == "lui") + ccprintf(ss, "%08p ", imm); + else + ss << (int) imm; + + return ss.str(); + } + +}}; //Used by decoder.isa def format IntOp(code, *opt_flags) {{ diff --git a/arch/mips/isa/formats/mem.isa b/arch/mips/isa/formats/mem.isa index fcdb577c6..8a07e63d4 100644 --- a/arch/mips/isa/formats/mem.isa +++ b/arch/mips/isa/formats/mem.isa @@ -40,6 +40,7 @@ output header {{ const StaticInstPtr eaCompPtr; /// Pointer to MemAcc object. const StaticInstPtr memAccPtr; + /// Displacement for EA calculation (signed). int32_t disp; @@ -51,6 +52,12 @@ output header {{ memAccessFlags(0), eaCompPtr(_eaCompPtr), memAccPtr(_memAccPtr), disp(OFFSET) { + //If Bit 15 is 1 then Sign Extend + int32_t temp = disp & 0x00008000; + + if (temp > 0) { + disp |= 0xFFFF0000; + } } std::string @@ -70,7 +77,7 @@ output decoder {{ Memory::generateDisassembly(Addr pc, const SymbolTable *symtab) const { return csprintf("%-10s %c%d,%d(r%d)", mnemonic, - flags[IsFloating] ? 'f' : 'r', RS, JMPTARG, RT); + flags[IsFloating] ? 'f' : 'r', RT, disp, RS); } }}; diff --git a/arch/mips/isa/formats/noop.isa b/arch/mips/isa/formats/noop.isa index 05c5ac10f..d35179005 100644 --- a/arch/mips/isa/formats/noop.isa +++ b/arch/mips/isa/formats/noop.isa @@ -59,7 +59,7 @@ output exec {{ Fault Nop::execute(%(CPU_exec_context)s *, Trace::InstRecord *) const { - return No_Fault; + return NoFault; } }}; @@ -68,9 +68,11 @@ output exec {{ def template OperateNopCheckDecode {{ { MipsStaticInst *i = new %(class_name)s(machInst); - if (RD == 0) { - i = makeNop(i); - } + + //if (RD == 0) { + // i = makeNop(i); + //} + return i; } }}; diff --git a/arch/mips/isa/formats/trap.isa b/arch/mips/isa/formats/trap.isa index 78f8d87b0..6884d4fa8 100644 --- a/arch/mips/isa/formats/trap.isa +++ b/arch/mips/isa/formats/trap.isa @@ -42,12 +42,11 @@ def template TrapExecute {{ }}; // Primary format for integer operate instructions: -def format Trap(code, *opt_flags) {{ - orig_code = code - cblk = CodeBlock(code) - iop = InstObjParams(name, Name, 'MipsStaticInst', cblk, opt_flags) +def format Trap(code, *flags) {{ + code = 'bool cond;\n' + code; + iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags) header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) - decode_block = BasicDecodeWithMnemonic.subst(iop) - exec_output = TrapExecute.subst(iop) + decode_block = BasicDecode.subst(iop) + exec_output = BasicExecute.subst(iop) }}; diff --git a/arch/mips/isa/formats/unimp.isa b/arch/mips/isa/formats/unimp.isa index a7a71c681..adbd5b5b1 100644 --- a/arch/mips/isa/formats/unimp.isa +++ b/arch/mips/isa/formats/unimp.isa @@ -111,7 +111,7 @@ output exec {{ { panic("attempt to execute unimplemented instruction '%s' " "(inst 0x%08x, opcode 0x%x)", mnemonic, machInst, OPCODE); - return Unimplemented_Opcode_Fault; + return UnimplementedOpcodeFault; } Fault @@ -123,7 +123,7 @@ output exec {{ warned = true; } - return No_Fault; + return NoFault; } }}; diff --git a/arch/mips/isa/formats/unknown.isa b/arch/mips/isa/formats/unknown.isa index 6eba5b4f9..4601b3684 100644 --- a/arch/mips/isa/formats/unknown.isa +++ b/arch/mips/isa/formats/unknown.isa @@ -42,7 +42,7 @@ output exec {{ { panic("attempt to execute unknown instruction " "(inst 0x%08x, opcode 0x%x)", machInst, OPCODE); - return Unimplemented_Opcode_Fault; + return UnimplementedOpcodeFault; } }}; diff --git a/arch/mips/isa/formats/util.isa b/arch/mips/isa/formats/util.isa index c06877b35..db4bf204a 100644 --- a/arch/mips/isa/formats/util.isa +++ b/arch/mips/isa/formats/util.isa @@ -1,29 +1,6 @@ // -*- mode:c++ -*- let {{ -def UncondCtrlBase(name, Name, base_class, npc_expr, flags): - # Declare basic control transfer w/o link (i.e. link reg is R31) - nolink_code = 'NPC = %s;\n' % npc_expr - nolink_iop = InstObjParams(name, Name, base_class, - CodeBlock(nolink_code), flags) - header_output = BasicDeclare.subst(nolink_iop) - decoder_output = BasicConstructor.subst(nolink_iop) - exec_output = BasicExecute.subst(nolink_iop) - - # Generate declaration of '*AndLink' version, append to decls - link_code = 'Ra = NPC & ~3;\n' + nolink_code - link_iop = InstObjParams(name, Name + 'AndLink', base_class, - CodeBlock(link_code), flags) - header_output += BasicDeclare.subst(link_iop) - decoder_output += BasicConstructor.subst(link_iop) - exec_output += BasicExecute.subst(link_iop) - - # need to use link_iop for the decode template since it is expecting - # the shorter version of class_name (w/o "AndLink") - - return (header_output, decoder_output, - JumpOrBranchDecode.subst(nolink_iop), exec_output) - def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, postacc_code = '', base_class = 'Memory', decode_template = BasicDecode, exec_template_base = ''): @@ -116,10 +93,56 @@ def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, output exec {{ +using namespace MipsISA; + + /// CLEAR ALL CPU INST/EXE HAZARDS inline void clear_exe_inst_hazards() { //CODE HERE } + + + /// Check "FP enabled" machine status bit. Called when executing any FP + /// instruction in full-system mode. + /// @retval Full-system mode: NoFault if FP is enabled, FenFault + /// if not. Non-full-system mode: always returns NoFault. +#if FULL_SYSTEM + inline Fault checkFpEnableFault(%(CPU_exec_context)s *xc) + { + Fault fault = NoFault; // dummy... this ipr access should not fault + if (!Mips34k::ICSR_FPE(xc->readIpr(MipsISA::IPR_ICSR, fault))) { + fault = FloatEnableFault; + } + return fault; + } +#else + inline Fault checkFpEnableFault(%(CPU_exec_context)s *xc) + { + return NoFault; + } +#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/operands.isa b/arch/mips/isa/operands.isa index 65ef2245f..13870337b 100644 --- a/arch/mips/isa/operands.isa +++ b/arch/mips/isa/operands.isa @@ -16,21 +16,18 @@ def operands {{ 'Rd': ('IntReg', 'uw', 'RD', 'IsInteger', 1), 'Rs': ('IntReg', 'uw', 'RS', 'IsInteger', 2), 'Rt': ('IntReg', 'uw', 'RT', 'IsInteger', 3), - 'R31': ('IntReg', 'uw','R31','IsInteger', 4), + 'r31': ('IntReg', 'uw','R31','IsInteger', 4), + 'R0': ('IntReg', 'uw','R0', 'IsInteger', 5), 'IntImm': ('IntReg', 'uw', 'INTIMM', 'IsInteger', 3), - 'Sa': ('IntReg', 'uw', 'SA', 'IsInteger', 4), 'Fd': ('FloatReg', 'sf', 'FD', 'IsFloating', 1), 'Fs': ('FloatReg', 'sf', 'FS', 'IsFloating', 2), 'Ft': ('FloatReg', 'sf', 'FT', 'IsFloating', 3), + 'Fr': ('FloatReg', 'sf', 'FR', 'IsFloating', 3), 'Mem': ('Mem', 'ud', None, ('IsMemRef', 'IsLoad', 'IsStore'), 4), 'NPC': ('NPC', 'uw', None, ( None, None, 'IsControl' ), 4), - 'NNPC': ('NNPC', 'uw', None, ( None, None, 'IsControl' ), 4) - #'Runiq': ('ControlReg', 'uq', 'Uniq', None, 1), - #'FPCR': ('ControlReg', 'uq', 'Fpcr', None, 1), - # The next two are hacks for non-full-system call-pal emulation - #'R0': ('IntReg', 'uq', '0', None, 1), + 'NNPC':('NNPC', 'uw', None, ( None, None, 'IsControl' ), 4) }}; diff --git a/arch/mips/isa_traits.cc b/arch/mips/isa_traits.cc index 02a857af7..85afd4a02 100644 --- a/arch/mips/isa_traits.cc +++ b/arch/mips/isa_traits.cc @@ -33,6 +33,256 @@ using namespace MipsISA; + +void +MipsISA::getMiscRegIdx(int reg_name,int &idx, int &sel) +{ + switch(reg_name) + { + case Index: idx = 0; sel = 0; break; //0-0 Index into the TLB array + case MVPControl: idx = 0; sel = 1; break; //0-1 Per-processor register containing global + case MVPConf0: idx = 0; sel = 2; break; //0-2 Per-processor register containing global + case MVPConf1: idx = 0; sel = 3; break; //0-3 Per-processor register containing global + case Random: idx = 1; sel = 3; break; //1-0 Randomly generated index into the TLB array + case VPEControl: idx = 1; sel = 1; break; //1-1 Per-VPE register containing relatively volatile + //thread configuration data + case VPEConf0: idx = 1; sel = 2; break; //1-2 Per-VPE multi-thread configuration + //information + case VPEConf1: idx = 1; sel = 3; break; //1-3 Per-VPE multi-thread configuration + //information + case YQMask: idx = 1; sel = 4; break; //Per-VPE register defining which YIELD + //qualifier bits may be used without generating + //an exception + case VPESchedule: idx = 1; sel = 5; break; + case VPEScheFBack: idx = 1; sel = 6; break; + case VPEOpt: idx = 1; sel = 7; break; + case EntryLo0: idx = 1; sel = 5; break; + case TCStatus: idx = 1; sel = 5; break; + case TCBind: idx = 1; sel = 5; break; + case TCRestart: idx = 1; sel = 5; break; + case TCHalt: idx = 1; sel = 5; break; + case TCContext: idx = 1; sel = 5; break; + case TCSchedule: idx = 1; sel = 5; break; + case TCScheFBack: panic("Accessing Unimplemented CP0 Register"); break; + case EntryLo1: panic("Accessing Unimplemented CP0 Register"); break; + case Context: panic("Accessing Unimplemented CP0 Register"); break; + case ContextConfig: panic("Accessing Unimplemented CP0 Register"); break; + //case PageMask: panic("Accessing Unimplemented CP0 Register"); break; + case PageGrain: panic("Accessing Unimplemented CP0 Register"); break; + case Wired: panic("Accessing Unimplemented CP0 Register"); break; + case SRSConf0: panic("Accessing Unimplemented CP0 Register"); break; + case SRSConf1: panic("Accessing Unimplemented CP0 Register"); break; + case SRSConf2: panic("Accessing Unimplemented CP0 Register"); break; + case SRSConf3: panic("Accessing Unimplemented CP0 Register"); break; + case SRSConf4: panic("Accessing Unimplemented CP0 Register"); break; + case BadVAddr: panic("Accessing Unimplemented CP0 Register"); break; + case Count: panic("Accessing Unimplemented CP0 Register"); break; + case EntryHi: panic("Accessing Unimplemented CP0 Register"); break; + case Compare: panic("Accessing Unimplemented CP0 Register"); break; + case Status: idx = 12; sel = 0; break; //12-0 Processor status and control + case IntCtl: idx = 12; sel = 1; break; //12-1 Interrupt system status and control + case SRSCtl: idx = 12; sel = 2; break; //12-2 Shadow register set status and control + case SRSMap: idx = 12; sel = 3; break; //12-3 Shadow set IPL mapping + case Cause: idx = 13; sel = 0; break; //13-0 Cause of last general exception + case EPC: idx = 14; sel = 0; break; //14-0 Program counter at last exception + case PRId: idx = 15; sel = 0; break; //15-0 Processor identification and revision + case EBase: idx = 15; sel = 1; break; //15-1 Exception vector base register + case Config: panic("Accessing Unimplemented CP0 Register"); break; + case Config1: panic("Accessing Unimplemented CP0 Register"); break; + case Config2: panic("Accessing Unimplemented CP0 Register"); break; + case Config3: panic("Accessing Unimplemented CP0 Register"); break; + case LLAddr: panic("Accessing Unimplemented CP0 Register"); break; + case WatchLo: panic("Accessing Unimplemented CP0 Register"); break; + case WatchHi: panic("Accessing Unimplemented CP0 Register"); break; + case Debug: panic("Accessing Unimplemented CP0 Register"); break; + case TraceControl1: panic("Accessing Unimplemented CP0 Register"); break; + case TraceControl2: panic("Accessing Unimplemented CP0 Register"); break; + case UserTraceData: panic("Accessing Unimplemented CP0 Register"); break; + case TraceBPC: panic("Accessing Unimplemented CP0 Register"); break; + case DEPC: panic("Accessing Unimplemented CP0 Register"); break; + case PerfCnt: panic("Accessing Unimplemented CP0 Register"); break; + case ErrCtl: panic("Accessing Unimplemented CP0 Register"); break; + case CacheErr0: panic("Accessing Unimplemented CP0 Register"); break; + case CacheErr1: panic("Accessing Unimplemented CP0 Register"); break; + case CacheErr2: panic("Accessing Unimplemented CP0 Register"); break; + case CacheErr3: panic("Accessing Unimplemented CP0 Register"); break; + case TagLo: panic("Accessing Unimplemented CP0 Register"); break; + case DataLo: panic("Accessing Unimplemented CP0 Register"); break; + case TagHi: panic("Accessing Unimplemented CP0 Register"); break; + case DataHi: panic("Accessing Unimplemented CP0 Register"); break; + case ErrorEPC: panic("Accessing Unimplemented CP0 Register"); break; + + default: + panic("Accessing Unimplemented Misc. Register"); + } +} + +void RegFile::coldReset() +{ + //CP0 Random Reg: + //Randomly generated index into the TLB array + miscRegs[1][0] = 0x0000003f; + + //CP0 Wired Reg. + miscRegs[6][0] = 0x0000000; + + //CP0 HWRENA + miscRegs[7][0] = 0x0000000; + + //CP0 Status Reg. + miscRegs[12][0] = 0x0400004; + + //CP0 INTCNTL + miscRegs[12][1] = 0xfc00000; + + //CP0 SRSCNTL + miscRegs[12][2] = 0x0c00000; + + //CP0 SRSMAP + miscRegs[12][3] = 0x0000000; + + //CP0 Cause + miscRegs[13][0] = 0x0000000; + + //CP0 Processor ID + miscRegs[15][0] = 0x0019300; + + //CP0 EBASE + miscRegs[15][1] = 0x8000000; + + //CP0 Config Reg. + miscRegs[16][0] = 0x80040482; + + //CP0 Config 1 Reg. + miscRegs[16][1] = 0xfee3719e; + + //CP0 Config 2 Reg. + miscRegs[16][2] = 0x8000000; + + //CP0 Config 3 Reg. + miscRegs[16][3] = 0x0000020; + + //CP0 Config 7 Reg. + miscRegs[16][7] = 0x0000000; + + //CP0 Debug + miscRegs[23][0] = 0x0201800; + + //CP0 PERFCNTL1 + miscRegs[25][0] = 0x0000000; + + //CP0 PERFCNTL2 + miscRegs[25][1] = 0x0000000; + +} + +void RegFile::createCP0Regs() +{ +//Resize Coprocessor Register Banks to +// the number specified in MIPS32K VOL.III +// Chapter 8 + // + //Cop-0 Regs. Bank 0: Index, + miscRegs[0].resize(4); + + //Cop-0 Regs. Bank 1: + miscRegs[1].resize(8); + + //Cop-0 Regs. Bank 2: + miscRegs[2].resize(8); + + //Cop-0 Regs. Bank 3: + miscRegs[3].resize(1); + + //Cop-0 Regs. Bank 4: + miscRegs[4].resize(2); + + //Cop-0 Regs. Bank 5: + miscRegs[5].resize(2); + + //Cop-0 Regs. Bank 6: + miscRegs[6].resize(6); + + //Cop-0 Regs. Bank 7: + miscRegs[7].resize(1); + + //Cop-0 Regs. Bank 8: + miscRegs[8].resize(1); + + //Cop-0 Regs. Bank 9: + miscRegs[9].resize(1); + + //Cop-0 Regs. Bank 10: + miscRegs[10].resize(1); + + //Cop-0 Regs. Bank 11: + miscRegs[11].resize(1); + + //Cop-0 Regs. Bank 12: + miscRegs[12].resize(4); + + //Cop-0 Regs. Bank 13: + miscRegs[13].resize(1); + + //Cop-0 Regs. Bank 14: + miscRegs[14].resize(1); + + //Cop-0 Regs. Bank 15: + miscRegs[15].resize(2); + + //Cop-0 Regs. Bank 16: + miscRegs[16].resize(4); + + //Cop-0 Regs. Bank 17: + miscRegs[17].resize(1); + + //Cop-0 Regs. Bank 18: + miscRegs[18].resize(8); + + //Cop-0 Regs. Bank 19: + miscRegs[19].resize(8); + + //Cop-0 Regs. Bank 20: + miscRegs[20].resize(1); + + //Cop-0 Regs. Bank 21: + //miscRegs[21].resize(1); + //Reserved for future extensions + + //Cop-0 Regs. Bank 22: + //miscRegs[22].resize(4); + //Available for implementation dependent use + + //Cop-0 Regs. Bank 23: + miscRegs[23].resize(5); + + //Cop-0 Regs. Bank 24: + miscRegs[24].resize(1); + + //Cop-0 Regs. Bank 25: + miscRegs[25].resize(8); + + //Cop-0 Regs. Bank 26: + miscRegs[26].resize(1); + + //Cop-0 Regs. Bank 27: + miscRegs[27].resize(4); + + //Cop-0 Regs. Bank 28: + miscRegs[28].resize(8); + + //Cop-0 Regs. Bank 29: + miscRegs[29].resize(8); + + //Cop-0 Regs. Bank 30: + miscRegs[30].resize(1); + + //Cop-0 Regs. Bank 31: + miscRegs[31].resize(1); + +} + + const Addr MipsISA::PageShift = 13; const Addr MipsISA::PageBytes = ULL(1) << PageShift; const Addr MipsISA::PageMask = ~(PageBytes - 1); @@ -64,8 +314,8 @@ const Addr MipsISA::K1SegEnd = ULL(0xffffffffffffffff); #endif -// Mips UNOP (ldq_u r31,0(r0)) -const MachInst MipsISA::NoopMachInst = 0x2ffe0000; +// Mips UNOP (sll r0,r0,r0) +const MachInst MipsISA::NoopMachInst = 0x00000000; static inline Addr TruncPage(Addr addr) @@ -74,17 +324,19 @@ TruncPage(Addr addr) static inline Addr RoundPage(Addr addr) { return (addr + MipsISA::PageBytes - 1) & ~(MipsISA::PageBytes - 1); } + void RegFile::serialize(std::ostream &os) { SERIALIZE_ARRAY(intRegFile, NumIntRegs); SERIALIZE_ARRAY(floatRegFile.q, NumFloatRegs); - SERIALIZE_SCALAR(miscRegs.fpcr); - SERIALIZE_SCALAR(miscRegs.uniq); - SERIALIZE_SCALAR(miscRegs.lock_flag); - SERIALIZE_SCALAR(miscRegs.lock_addr); + //SERIALIZE_SCALAR(miscRegs.fpcr); + //SERIALIZE_SCALAR(miscRegs.uniq); + //SERIALIZE_SCALAR(miscRegs.lock_flag); + //SERIALIZE_SCALAR(miscRegs.lock_addr); SERIALIZE_SCALAR(pc); SERIALIZE_SCALAR(npc); + SERIALIZE_SCALAR(nnpc); #if FULL_SYSTEM SERIALIZE_ARRAY(palregs, NumIntRegs); SERIALIZE_ARRAY(ipr, NumInternalProcRegs); @@ -99,12 +351,13 @@ RegFile::unserialize(Checkpoint *cp, const std::string §ion) { UNSERIALIZE_ARRAY(intRegFile, NumIntRegs); UNSERIALIZE_ARRAY(floatRegFile.q, NumFloatRegs); - UNSERIALIZE_SCALAR(miscRegs.fpcr); - UNSERIALIZE_SCALAR(miscRegs.uniq); - UNSERIALIZE_SCALAR(miscRegs.lock_flag); - UNSERIALIZE_SCALAR(miscRegs.lock_addr); + //UNSERIALIZE_SCALAR(miscRegs.fpcr); + //UNSERIALIZE_SCALAR(miscRegs.uniq); + //UNSERIALIZE_SCALAR(miscRegs.lock_flag); + //UNSERIALIZE_SCALAR(miscRegs.lock_addr); UNSERIALIZE_SCALAR(pc); UNSERIALIZE_SCALAR(npc); + UNSERIALIZE_SCALAR(nnpc); #if FULL_SYSTEM UNSERIALIZE_ARRAY(palregs, NumIntRegs); UNSERIALIZE_ARRAY(ipr, NumInternalProcRegs); diff --git a/arch/mips/isa_traits.hh b/arch/mips/isa_traits.hh index 71da82ffa..35f33c237 100644 --- a/arch/mips/isa_traits.hh +++ b/arch/mips/isa_traits.hh @@ -29,19 +29,21 @@ #ifndef __ARCH_MIPS_ISA_TRAITS_HH__ #define __ARCH_MIPS_ISA_TRAITS_HH__ -namespace LittleEndianGuest {} -using namespace LittleEndianGuest; - -//#include "arch/mips/faults.hh" +//#include "arch/mips/misc_regfile.hh" #include "base/misc.hh" #include "config/full_system.hh" #include "sim/host.hh" #include "sim/faults.hh" +#include + class FastCPU; class FullCPU; class Checkpoint; +namespace LittleEndianGuest {}; +using namespace LittleEndianGuest; + #define TARGET_MIPS class StaticInst; @@ -50,11 +52,10 @@ class StaticInstPtr; namespace MIPS34K { int DTB_ASN_ASN(uint64_t reg); int ITB_ASN_ASN(uint64_t reg); -} +}; namespace MipsISA { - typedef uint32_t MachInst; // typedef uint64_t Addr; typedef uint8_t RegIndex; @@ -64,7 +65,7 @@ namespace MipsISA NumIntRegs = 32, NumFloatRegs = 32, - NumMiscRegs = 32, + NumMiscRegs = 256, MaxRegsOfAnyType = 32, // Static instruction parameters @@ -72,7 +73,7 @@ namespace MipsISA MaxInstDestRegs = 2, // semantically meaningful register indices - ZeroReg = 31, // architecturally meaningful + ZeroReg = 0, // architecturally meaningful // the rest of these depend on the ABI StackPointerReg = 30, GlobalPointerReg = 29, @@ -106,7 +107,8 @@ namespace MipsISA Ctrl_Base_DepTag = 64, Fpcr_DepTag = 64, // floating point control register Uniq_DepTag = 65, - IPR_Base_DepTag = 66 + IPR_Base_DepTag = 66, + MiscReg_DepTag = 67 }; typedef uint64_t IntReg; @@ -123,14 +125,123 @@ namespace MipsISA double d[NumFloatRegs]; // double-precision floating point view } FloatRegFile; - // control register file contents + // cop-0/cop-1 system control register file typedef uint64_t MiscReg; - typedef struct { - uint64_t fpcr; // floating point condition codes - uint64_t uniq; // process-unique register - bool lock_flag; // lock flag for LL/SC - Addr lock_addr; // lock address for LL/SC - } MiscRegFile; +//typedef MiscReg MiscRegFile[NumMiscRegs]; + + typedef std::vector MiscRegFile[NumMiscRegs]; +// typedef MiscRegBank MiscRegBanks[NumMiscRegs]; + + + enum MiscRegTags { + //Coprocessor 0 Registers + //Reference MIPS32 Arch. for Programmers, Vol. III, Ch.8 + //(Register Number-Register Select) Summary of Register + //------------------------------------------------------ + Index, //0-0 Index into the TLB array + + MVPControl, //0-1 Per-processor register containing global + //MIPS® MT configuration data + + MVPConf0, //0-2 Per-processor register containing global + //MIPS® MT configuration data + + MVPConf1, //0-3 Per-processor register containing global + //MIPS® MT configuration data + + Random, //1-0 Randomly generated index into the TLB array + + VPEControl, //1-1 Per-VPE register containing relatively volatile + //thread configuration data + + VPEConf0, //1-2 Per-VPE multi-thread configuration + //information + + + VPEConf1, //1-2 Per-VPE multi-thread configuration + //information + + YQMask, //Per-VPE register defining which YIELD + //qualifier bits may be used without generating + //an exception + + VPESchedule, + VPEScheFBack, + VPEOpt, + EntryLo0, + TCStatus, + TCBind, + TCRestart, + TCHalt, + TCContext, + TCSchedule, + TCScheFBack, + EntryLo1, + Context, + ContextConfig, + //PageMask, + PageGrain, + Wired, + SRSConf0, + SRSConf1, + SRSConf2, + SRSConf3, + SRSConf4, + BadVAddr, + Count, + EntryHi, + Compare, + Status, //12-0 Processor status and control + IntCtl, //12-1 Interrupt system status and control + SRSCtl, //12-2 Shadow register set status and control + SRSMap, //12-3 Shadow set IPL mapping + Cause, //13-0 Cause of last general exception + EPC, //14-0 Program counter at last exception + PRId, //15-0 Processor identification and revision + EBase, //15-1 Exception vector base register + Config, + Config1, + Config2, + Config3, + LLAddr, + WatchLo, + WatchHi, + Debug, + TraceControl1, + TraceControl2, + UserTraceData, + TraceBPC, + + DEPC, + + PerfCnt, + + ErrCtl, + + CacheErr0, + CacheErr1, + CacheErr2, + CacheErr3, + + TagLo, + DataLo, + TagHi, + DataHi, + ErrorEPC, + DESAVE, + + //More Misc. Regs + Hi, + Lo, + FCSR, + FPCR, + LockAddr, + LockFlag, + + //Alpha Regs, but here now, for + //compiling sake + UNIQ + }; extern const Addr PageShift; extern const Addr PageBytes; @@ -168,19 +279,33 @@ extern const Addr PageOffset; IntRegFile intRegFile; // (signed) integer register file FloatRegFile floatRegFile; // floating point register file MiscRegFile miscRegs; // control register file + + Addr pc; // program counter Addr npc; // next-cycle program counter + Addr nnpc; // next-next-cycle program counter + // used to implement branch delay slot + // not real register + + MiscReg hi; // MIPS HI Register + MiscReg lo; // MIPS LO Register + + #if FULL_SYSTEM IntReg palregs[NumIntRegs]; // PAL shadow registers InternalProcReg ipr[NumInternalProcRegs]; // internal processor regs int intrflag; // interrupt flag bool pal_shadow; // using pal_shadow registers - inline int instAsid() { return EV5::ITB_ASN_ASN(ipr[IPR_ITB_ASN]); } - inline int dataAsid() { return EV5::DTB_ASN_ASN(ipr[IPR_DTB_ASN]); } + inline int instAsid() { return MIPS34K::ITB_ASN_ASN(ipr[IPR_ITB_ASN]); } + inline int dataAsid() { return MIPS34K::DTB_ASN_ASN(ipr[IPR_DTB_ASN]); } #endif // FULL_SYSTEM + //void initCP0Regs(); void serialize(std::ostream &os); void unserialize(Checkpoint *cp, const std::string §ion); + + void createCP0Regs(); + void coldReset(); }; StaticInstPtr decodeInst(MachInst); @@ -194,6 +319,9 @@ extern const Addr PageOffset; ITOUCH_ANNOTE = 0xffffffff, }; + void getMiscRegIdx(int reg_name,int &idx, int &sel); + + static inline bool isCallerSaveIntegerRegister(unsigned int reg) { panic("register classification not implemented"); return (reg >= 1 && reg <= 8 || reg >= 22 && reg <= 25 || reg == 27); @@ -264,37 +392,7 @@ extern const Addr PageOffset; template void zeroRegisters(XC *xc); - -//typedef MipsISA TheISA; - -//typedef TheISA::MachInst MachInst; -//typedef TheISA::Addr Addr; -//typedef TheISA::RegIndex RegIndex; -//typedef TheISA::IntReg IntReg; -//typedef TheISA::IntRegFile IntRegFile; -//typedef TheISA::FloatReg FloatReg; -//typedef TheISA::FloatRegFile FloatRegFile; -//typedef TheISA::MiscReg MiscReg; -//typedef TheISA::MiscRegFile MiscRegFile; -//typedef TheISA::AnyReg AnyReg; -//typedef TheISA::RegFile RegFile; - -//const int NumIntRegs = TheISA::NumIntRegs; -//const int NumFloatRegs = TheISA::NumFloatRegs; -//const int NumMiscRegs = TheISA::NumMiscRegs; -//const int TotalNumRegs = TheISA::TotalNumRegs; -//const int VMPageSize = TheISA::VMPageSize; -//const int LogVMPageSize = TheISA::LogVMPageSize; -//const int ZeroReg = TheISA::ZeroReg; -//const int StackPointerReg = TheISA::StackPointerReg; -//const int GlobalPointerReg = TheISA::GlobalPointerReg; -//const int ReturnAddressReg = TheISA::ReturnAddressReg; -//const int ReturnValueReg = TheISA::ReturnValueReg; -//const int ArgumentReg0 = TheISA::ArgumentReg0; -//const int ArgumentReg1 = TheISA::ArgumentReg1; -//const int ArgumentReg2 = TheISA::ArgumentReg2; -//const int BranchPredAddrShiftAmt = TheISA::BranchPredAddrShiftAmt; -const Addr MaxAddr = (Addr)-1; + const Addr MaxAddr = (Addr)-1; }; #if !FULL_SYSTEM diff --git a/arch/mips/linux_process.cc b/arch/mips/linux_process.cc index d3aca15bc..1d4f62350 100644 --- a/arch/mips/linux_process.cc +++ b/arch/mips/linux_process.cc @@ -26,8 +26,8 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "arch/mips/mips_common_syscall_emul.hh" -#include "arch/mips/mips_linux_process.hh" +#include "arch/mips/common_syscall_emul.hh" +#include "arch/mips/linux_process.hh" #include "arch/mips/isa_traits.hh" #include "base/trace.hh" diff --git a/arch/mips/stacktrace.hh b/arch/mips/stacktrace.hh new file mode 100644 index 000000000..1d8d97a79 --- /dev/null +++ b/arch/mips/stacktrace.hh @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2005 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __ARCH_ALPHA_STACKTRACE_HH__ +#define __ARCH_ALPHA_STACKTRACE_HH__ + +#include "base/trace.hh" +#include "cpu/static_inst.hh" + +class ExecContext; +class StackTrace; + +class ProcessInfo +{ + private: + ExecContext *xc; + + int thread_info_size; + int task_struct_size; + int task_off; + int pid_off; + int name_off; + + public: + ProcessInfo(ExecContext *_xc); + + Addr task(Addr ksp) const; + int pid(Addr ksp) const; + std::string name(Addr ksp) const; +}; + +class StackTrace +{ + protected: + typedef TheISA::MachInst MachInst; + private: + ExecContext *xc; + std::vector stack; + + private: + bool isEntry(Addr addr); + bool decodePrologue(Addr sp, Addr callpc, Addr func, int &size, Addr &ra); + bool decodeSave(MachInst inst, int ®, int &disp); + bool decodeStack(MachInst inst, int &disp); + + void trace(ExecContext *xc, bool is_call); + + public: + StackTrace(); + StackTrace(ExecContext *xc, StaticInstPtr inst); + ~StackTrace(); + + void clear() + { + xc = 0; + stack.clear(); + } + + bool valid() const { return xc != NULL; } + bool trace(ExecContext *xc, StaticInstPtr inst); + + public: + const std::vector &getstack() const { return stack; } + + static const int user = 1; + static const int console = 2; + static const int unknown = 3; + +#if TRACING_ON + private: + void dump(); + + public: + void dprintf() { if (DTRACE(Stack)) dump(); } +#else + public: + void dprintf() {} +#endif +}; + +inline bool +StackTrace::trace(ExecContext *xc, StaticInstPtr inst) +{ + if (!inst->isCall() && !inst->isReturn()) + return false; + + if (valid()) + clear(); + + trace(xc, !inst->isReturn()); + return true; +} + +#endif // __ARCH_ALPHA_STACKTRACE_HH__ From bfd820f704cd67519be276967c659d025bc502d1 Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Wed, 8 Mar 2006 04:36:55 -0500 Subject: [PATCH 171/180] Update MiscReg enum and miscRegFile definition update miscReg file access arch/mips/isa/decoder.isa: arch/mips/isa_traits.cc: update miscRegfile access arch/mips/isa_traits.hh: Update MiscReg enum and miscRegFile definition --HG-- extra : convert_revision : 9b6b9343d674e1e38e25bb9a4ffe4325142e7424 --- arch/mips/isa/decoder.isa | 106 ++++++++++---------- arch/mips/isa_traits.cc | 45 +++++---- arch/mips/isa_traits.hh | 206 +++++++++++++++++++++++++------------- 3 files changed, 211 insertions(+), 146 deletions(-) diff --git a/arch/mips/isa/decoder.isa b/arch/mips/isa/decoder.isa index b2410f9b9..9994acd0b 100644 --- a/arch/mips/isa/decoder.isa +++ b/arch/mips/isa/decoder.isa @@ -86,10 +86,10 @@ decode OPCODE_HI default Unknown::unknown() { 0x2: decode FUNCTION_LO { format BasicOp { - 0x0: mfhi({{ Rd = xc->readMiscReg(Hi,0); }}); - 0x1: mthi({{ xc->setMiscReg(Hi,0,Rs); }}); - 0x2: mflo({{ Rd = xc->readMiscReg(Lo,0); }}); - 0x3: mtlo({{ xc->setMiscReg(Lo,0,Rs); }}); + 0x0: mfhi({{ Rd = xc->readMiscReg(Hi); }}); + 0x1: mthi({{ xc->setMiscReg(Hi,Rs); }}); + 0x2: mflo({{ Rd = xc->readMiscReg(Lo); }}); + 0x3: mtlo({{ xc->setMiscReg(Lo,Rs); }}); } } @@ -97,24 +97,24 @@ decode OPCODE_HI default Unknown::unknown() { format IntOp { 0x0: mult({{ int64_t temp1 = Rs.sw * Rt.sw; - xc->setMiscReg(Hi,0,temp1<63:32>); - xc->setMiscReg(Lo,0,temp1<31:0>); + xc->setMiscReg(Hi,temp1<63:32>); + xc->setMiscReg(Lo,temp1<31:0>); }}); 0x1: multu({{ int64_t temp1 = Rs.uw * Rt.uw; - xc->setMiscReg(Hi,0,temp1<63:32>); - xc->setMiscReg(Lo,0,temp1<31:0>); + xc->setMiscReg(Hi,temp1<63:32>); + xc->setMiscReg(Lo,temp1<31:0>); }}); 0x2: div({{ - xc->setMiscReg(Hi,0,Rs.sw % Rt.sw); - xc->setMiscReg(Lo,0,Rs.sw / Rt.sw); + xc->setMiscReg(Hi,Rs.sw % Rt.sw); + xc->setMiscReg(Lo,Rs.sw / Rt.sw); }}); 0x3: divu({{ - xc->setMiscReg(Hi,0,Rs.uw % Rt.uw); - xc->setMiscReg(Lo,0,Rs.uw / Rt.uw); + xc->setMiscReg(Hi,Rs.uw % Rt.uw); + xc->setMiscReg(Lo,Rs.uw / Rt.uw); }}); } } @@ -232,13 +232,13 @@ decode OPCODE_HI default Unknown::unknown() { 0x0: mfc0({{ //uint64_t reg_num = Rd.uw; - Rt = xc->readMiscReg(RD,SEL); + Rt = xc->readMiscReg(RD << 5 | SEL); }}); 0x4: mtc0({{ //uint64_t reg_num = Rd.uw; - xc->setMiscReg(RD,SEL,Rt); + xc->setMiscReg(RD << 5 | SEL,Rt); }}); 0x8: mftr({{ @@ -277,7 +277,7 @@ decode OPCODE_HI default Unknown::unknown() { int sel; getMiscRegIdx(MVPControl,idx,sel); Rt.sw = xc->readMiscReg(idx,sel); - xc->setMiscReg(idx,sel,0); + xc->setMiscReg(idx,sel); }}); 0x1: evpe({{ @@ -295,7 +295,7 @@ decode OPCODE_HI default Unknown::unknown() { int sel; getMiscRegIdx(VPEControl,idx,sel); Rt.sw = xc->readMiscReg(idx,sel); - xc->setMiscReg(idx,sel,0); + xc->setMiscReg(idx,sel); }}); 0x1: emt({{ @@ -313,7 +313,7 @@ decode OPCODE_HI default Unknown::unknown() { int sel; getMiscRegIdx(Status,idx,sel); Rt.sw = xc->readMiscReg(idx,sel); - xc->setMiscReg(idx,sel,0); + xc->setMiscReg(idx,sel); }}); 0x1: ei({{ @@ -372,15 +372,15 @@ decode OPCODE_HI default Unknown::unknown() { 0x1: decode ND { 0x0: decode TF { format Branch { - 0x0: bc1f({{ cond = (xc->readMiscReg(FPCR,0) == 0); }}); - 0x1: bc1t({{ cond = (xc->readMiscReg(FPCR,0) == 1); }}); + 0x0: bc1f({{ cond = (xc->readMiscReg(FPCR) == 0); }}); + 0x1: bc1t({{ cond = (xc->readMiscReg(FPCR) == 1); }}); } } 0x1: decode TF { format BranchLikely { - 0x0: bc1fl({{ cond = (xc->readMiscReg(FPCR,0) == 0); }}); - 0x1: bc1tl({{ cond = (xc->readMiscReg(FPCR,0) == 1); }}); + 0x0: bc1fl({{ cond = (xc->readMiscReg(FPCR) == 0); }}); + 0x1: bc1tl({{ cond = (xc->readMiscReg(FPCR) == 1); }}); } } } @@ -425,8 +425,8 @@ decode OPCODE_HI default Unknown::unknown() { 0x2: decode RS_LO { 0x1: decode MOVCF { format FloatOp { - 0x0: movfs({{if (xc->readMiscReg(FPCR,0) != CC) Fd = Fs; }}); - 0x1: movts({{if (xc->readMiscReg(FPCR,0) == CC) Fd = Fs;}}); + 0x0: movfs({{if (xc->readMiscReg(FPCR) != CC) Fd = Fs; }}); + 0x1: movts({{if (xc->readMiscReg(FPCR) == CC) Fd = Fs;}}); } } @@ -444,18 +444,18 @@ decode OPCODE_HI default Unknown::unknown() { 0x4: decode RS_LO { format FloatOp { - 0x1: cvt_d_s({{ int rnd_mode = xc->readMiscReg(FCSR,0); + 0x1: cvt_d_s({{ int rnd_mode = xc->readMiscReg(FCSR); Fd = convert_and_round(Fs.sf,rnd_mode,FP_DOUBLE,FP_SINGLE); }}); - 0x4: cvt_w_s({{ int rnd_mode = xc->readMiscReg(FCSR,0); + 0x4: cvt_w_s({{ int rnd_mode = xc->readMiscReg(FCSR); Fd = convert_and_round(Fs.sf,rnd_mode,FP_WORD,FP_SINGLE); }}); } //only legal for 64 bit format Float64Op { - 0x5: cvt_l_s({{ int rnd_mode = xc->readMiscReg(FCSR,0); + 0x5: cvt_l_s({{ int rnd_mode = xc->readMiscReg(FCSR); Fd = convert_and_round(Fs.sf,rnd_mode,FP_LONG,FP_SINGLE); }}); @@ -499,8 +499,8 @@ decode OPCODE_HI default Unknown::unknown() { 0x2: decode RS_LO { 0x1: decode MOVCF { format FloatOp { - 0x0: movfd({{if (xc->readMiscReg(FPCR,0) != CC) Fd.df = Fs.df; }}); - 0x1: movtd({{if (xc->readMiscReg(FPCR,0) == CC) Fd.df = Fs.df; }}); + 0x0: movfd({{if (xc->readMiscReg(FPCR) != CC) Fd.df = Fs.df; }}); + 0x1: movtd({{if (xc->readMiscReg(FPCR) == CC) Fd.df = Fs.df; }}); } } @@ -518,12 +518,12 @@ decode OPCODE_HI default Unknown::unknown() { 0x4: decode RS_LO { format FloatOp { 0x0: cvt_s_d({{ - int rnd_mode = xc->readMiscReg(FCSR,0); + int rnd_mode = xc->readMiscReg(FCSR); Fd = convert_and_round(Fs.df,rnd_mode,FP_SINGLE,FP_DOUBLE); }}); 0x4: cvt_w_d({{ - int rnd_mode = xc->readMiscReg(FCSR,0); + int rnd_mode = xc->readMiscReg(FCSR); Fd = convert_and_round(Fs.df,rnd_mode,FP_WORD,FP_DOUBLE); }}); } @@ -531,7 +531,7 @@ decode OPCODE_HI default Unknown::unknown() { //only legal for 64 bit format Float64Op { 0x5: cvt_l_d({{ - int rnd_mode = xc->readMiscReg(FCSR,0); + int rnd_mode = xc->readMiscReg(FCSR); Fd = convert_and_round(Fs.df,rnd_mode,FP_LONG,FP_DOUBLE); }}); } @@ -542,12 +542,12 @@ decode OPCODE_HI default Unknown::unknown() { 0x4: decode FUNCTION { format FloatOp { 0x20: cvt_s({{ - int rnd_mode = xc->readMiscReg(FCSR,0); + int rnd_mode = xc->readMiscReg(FCSR); Fd = convert_and_round(Fs.df,rnd_mode,FP_SINGLE,FP_WORD); }}); 0x21: cvt_d({{ - int rnd_mode = xc->readMiscReg(FCSR,0); + int rnd_mode = xc->readMiscReg(FCSR); Fd = convert_and_round(Fs.df,rnd_mode,FP_DOUBLE,FP_WORD); }}); } @@ -559,12 +559,12 @@ decode OPCODE_HI default Unknown::unknown() { 0x5: decode FUNCTION_HI { format FloatOp { 0x10: cvt_s_l({{ - int rnd_mode = xc->readMiscReg(FCSR,0); + int rnd_mode = xc->readMiscReg(FCSR); Fd = convert_and_round(Fs.df,rnd_mode,FP_SINGLE,FP_LONG); }}); 0x11: cvt_d_l({{ - int rnd_mode = xc->readMiscReg(FCSR,0); + int rnd_mode = xc->readMiscReg(FCSR); Fd = convert_and_round(Fs.df,rnd_mode,FP_DOUBLE,FP_LONG); }}); } @@ -611,21 +611,21 @@ decode OPCODE_HI default Unknown::unknown() { 0x2: decode RS_LO { 0x1: decode MOVCF { format Float64Op { - 0x0: movfps({{if (xc->readMiscReg(FPCR,0) != CC) Fd = Fs;}}); - 0x1: movtps({{if (xc->readMiscReg(FPCR,0) == CC) Fd = Fs;}}); + 0x0: movfps({{if (xc->readMiscReg(FPCR) != CC) Fd = Fs;}}); + 0x1: movtps({{if (xc->readMiscReg(FPCR) == CC) Fd = Fs;}}); } } format BasicOp { - 0x2: movzps({{if (xc->readMiscReg(FPCR,0) != CC) Fd = Fs; }}); - 0x3: movnps({{if (xc->readMiscReg(FPCR,0) == CC) Fd = Fs; }}); + 0x2: movzps({{if (xc->readMiscReg(FPCR) != CC) Fd = Fs; }}); + 0x3: movnps({{if (xc->readMiscReg(FPCR) == CC) Fd = Fs; }}); } } 0x4: decode RS_LO { 0x0: Float64Op::cvt_s_pu({{ - int rnd_mode = xc->readMiscReg(FCSR,0); + int rnd_mode = xc->readMiscReg(FCSR); Fd = convert_and_round(Fs.df,rnd_mode,FP_DOUBLE,FP_PS_HI); }}); } @@ -633,7 +633,7 @@ decode OPCODE_HI default Unknown::unknown() { 0x5: decode RS_LO { format Float64Op { 0x0: cvt_s_pl({{ - int rnd_mode = xc->readMiscReg(FCSR,0); + int rnd_mode = xc->readMiscReg(FCSR); Fd = convert_and_round(Fs.df,rnd_mode,FP_SINGLE,FP_PS_LO); }}); 0x4: pll({{ /*Fd.df = Fs<31:0> | Ft<31:0>*/}}); @@ -771,33 +771,33 @@ decode OPCODE_HI default Unknown::unknown() { 0x0: decode FUNCTION_LO { format IntOp { 0x0: madd({{ - int64_t temp1 = xc->readMiscReg(Hi,0) << 32 | xc->readMiscReg(Lo,0) >> 32; + int64_t temp1 = xc->readMiscReg(Hi) << 32 | xc->readMiscReg(Lo) >> 32; temp1 = temp1 + (Rs.sw * Rt.sw); - xc->setMiscReg(Hi,0,temp1<63:32>); - xc->setMiscReg(Lo,0,temp1<31:0>); + xc->setMiscReg(Hi,temp1<63:32>); + xc->setMiscReg(Lo,temp1<31:0>); }}); 0x1: maddu({{ - int64_t temp1 = xc->readMiscReg(Hi,0) << 32 | xc->readMiscReg(Lo,0) >> 32; + int64_t temp1 = xc->readMiscReg(Hi) << 32 | xc->readMiscReg(Lo) >> 32; temp1 = temp1 + (Rs.uw * Rt.uw); - xc->setMiscReg(Hi,0,temp1<63:32>); - xc->setMiscReg(Lo,0,temp1<31:0>); + xc->setMiscReg(Hi,temp1<63:32>); + xc->setMiscReg(Lo,temp1<31:0>); }}); 0x2: mul({{ Rd.sw = Rs.sw * Rt.sw; }}); 0x4: msub({{ - int64_t temp1 = xc->readMiscReg(Hi,0) << 32 | xc->readMiscReg(Lo,0) >> 32; + int64_t temp1 = xc->readMiscReg(Hi) << 32 | xc->readMiscReg(Lo) >> 32; temp1 = temp1 - (Rs.sw * Rt.sw); - xc->setMiscReg(Hi,0,temp1<63:32>); - xc->setMiscReg(Lo,0,temp1<31:0>); + xc->setMiscReg(Hi,temp1<63:32>); + xc->setMiscReg(Lo,temp1<31:0>); }}); 0x5: msubu({{ - int64_t temp1 = xc->readMiscReg(Hi,0) << 32 | xc->readMiscReg(Lo,0) >> 32; + int64_t temp1 = xc->readMiscReg(Hi) << 32 | xc->readMiscReg(Lo) >> 32; temp1 = temp1 - (Rs.uw * Rt.uw); - xc->setMiscReg(Hi,0,temp1<63:32>); - xc->setMiscReg(Lo,0,temp1<31:0>); + xc->setMiscReg(Hi,temp1<63:32>); + xc->setMiscReg(Lo,temp1<31:0>); }}); } } diff --git a/arch/mips/isa_traits.cc b/arch/mips/isa_traits.cc index 85afd4a02..d01fa6bd4 100644 --- a/arch/mips/isa_traits.cc +++ b/arch/mips/isa_traits.cc @@ -34,6 +34,9 @@ using namespace MipsISA; +//Function now Obsolete in current state. +//If anyting this should return the correct miscreg index +//but that is handled implicitly with enums anyway void MipsISA::getMiscRegIdx(int reg_name,int &idx, int &sel) { @@ -85,7 +88,7 @@ MipsISA::getMiscRegIdx(int reg_name,int &idx, int &sel) case SRSMap: idx = 12; sel = 3; break; //12-3 Shadow set IPL mapping case Cause: idx = 13; sel = 0; break; //13-0 Cause of last general exception case EPC: idx = 14; sel = 0; break; //14-0 Program counter at last exception - case PRId: idx = 15; sel = 0; break; //15-0 Processor identification and revision + case PrId: idx = 15; sel = 0; break; //15-0 Processor identification and revision case EBase: idx = 15; sel = 1; break; //15-1 Exception vector base register case Config: panic("Accessing Unimplemented CP0 Register"); break; case Config1: panic("Accessing Unimplemented CP0 Register"); break; @@ -121,58 +124,58 @@ void RegFile::coldReset() { //CP0 Random Reg: //Randomly generated index into the TLB array - miscRegs[1][0] = 0x0000003f; + miscRegs[Random] = 0x0000003f; //CP0 Wired Reg. - miscRegs[6][0] = 0x0000000; + miscRegs[Wired] = 0x0000000; //CP0 HWRENA - miscRegs[7][0] = 0x0000000; + miscRegs[HWRena] = 0x0000000; //CP0 Status Reg. - miscRegs[12][0] = 0x0400004; + miscRegs[Status] = 0x0400004; //CP0 INTCNTL - miscRegs[12][1] = 0xfc00000; + miscRegs[IntCtl] = 0xfc00000; //CP0 SRSCNTL - miscRegs[12][2] = 0x0c00000; + miscRegs[SRSCtl] = 0x0c00000; //CP0 SRSMAP - miscRegs[12][3] = 0x0000000; + miscRegs[SRSMap] = 0x0000000; //CP0 Cause - miscRegs[13][0] = 0x0000000; + miscRegs[Cause] = 0x0000000; //CP0 Processor ID - miscRegs[15][0] = 0x0019300; + miscRegs[PrId] = 0x0019300; //CP0 EBASE - miscRegs[15][1] = 0x8000000; + miscRegs[EBase] = 0x8000000; //CP0 Config Reg. - miscRegs[16][0] = 0x80040482; + miscRegs[Config] = 0x80040482; //CP0 Config 1 Reg. - miscRegs[16][1] = 0xfee3719e; + miscRegs[Config1] = 0xfee3719e; //CP0 Config 2 Reg. - miscRegs[16][2] = 0x8000000; + miscRegs[Config2] = 0x8000000; //CP0 Config 3 Reg. - miscRegs[16][3] = 0x0000020; + miscRegs[Config3] = 0x0000020; //CP0 Config 7 Reg. - miscRegs[16][7] = 0x0000000; + miscRegs[Config7] = 0x0000000; //CP0 Debug - miscRegs[23][0] = 0x0201800; + miscRegs[Debug] = 0x0201800; //CP0 PERFCNTL1 - miscRegs[25][0] = 0x0000000; + miscRegs[PerfCnt0] = 0x0000000; //CP0 PERFCNTL2 - miscRegs[25][1] = 0x0000000; + miscRegs[PerfCnt1] = 0x0000000; } @@ -181,7 +184,7 @@ void RegFile::createCP0Regs() //Resize Coprocessor Register Banks to // the number specified in MIPS32K VOL.III // Chapter 8 - // + /* //Cop-0 Regs. Bank 0: Index, miscRegs[0].resize(4); @@ -278,7 +281,7 @@ void RegFile::createCP0Regs() miscRegs[30].resize(1); //Cop-0 Regs. Bank 31: - miscRegs[31].resize(1); + miscRegs[31].resize(1);*/ } diff --git a/arch/mips/isa_traits.hh b/arch/mips/isa_traits.hh index 35f33c237..408cc3463 100644 --- a/arch/mips/isa_traits.hh +++ b/arch/mips/isa_traits.hh @@ -127,10 +127,7 @@ namespace MipsISA // cop-0/cop-1 system control register file typedef uint64_t MiscReg; -//typedef MiscReg MiscRegFile[NumMiscRegs]; - - typedef std::vector MiscRegFile[NumMiscRegs]; -// typedef MiscRegBank MiscRegBanks[NumMiscRegs]; + typedef MiscReg MiscRegFile[NumMiscRegs]; enum MiscRegTags { @@ -138,97 +135,162 @@ namespace MipsISA //Reference MIPS32 Arch. for Programmers, Vol. III, Ch.8 //(Register Number-Register Select) Summary of Register //------------------------------------------------------ - Index, //0-0 Index into the TLB array + Index = 0, //0-0 Index into the TLB array - MVPControl, //0-1 Per-processor register containing global + MVPControl = 1, //0-1 Per-processor register containing global //MIPS® MT configuration data - MVPConf0, //0-2 Per-processor register containing global + MVPConf0 = 2, //0-2 Per-processor register containing global //MIPS® MT configuration data - MVPConf1, //0-3 Per-processor register containing global + MVPConf1 = 3, //0-3 Per-processor register containing global //MIPS® MT configuration data - Random, //1-0 Randomly generated index into the TLB array + Random = 8, //1-0 Randomly generated index into the TLB array - VPEControl, //1-1 Per-VPE register containing relatively volatile + VPEControl = 9, //1-1 Per-VPE register containing relatively volatile //thread configuration data - VPEConf0, //1-2 Per-VPE multi-thread configuration + VPEConf0 = 10, //1-2 Per-VPE multi-thread configuration //information - VPEConf1, //1-2 Per-VPE multi-thread configuration + VPEConf1 = 11, //1-2 Per-VPE multi-thread configuration //information - YQMask, //Per-VPE register defining which YIELD + YQMask = 12, //Per-VPE register defining which YIELD //qualifier bits may be used without generating //an exception - VPESchedule, - VPEScheFBack, - VPEOpt, - EntryLo0, - TCStatus, - TCBind, - TCRestart, - TCHalt, - TCContext, - TCSchedule, - TCScheFBack, - EntryLo1, - Context, - ContextConfig, - //PageMask, - PageGrain, - Wired, - SRSConf0, - SRSConf1, - SRSConf2, - SRSConf3, - SRSConf4, - BadVAddr, - Count, - EntryHi, - Compare, - Status, //12-0 Processor status and control - IntCtl, //12-1 Interrupt system status and control - SRSCtl, //12-2 Shadow register set status and control - SRSMap, //12-3 Shadow set IPL mapping - Cause, //13-0 Cause of last general exception - EPC, //14-0 Program counter at last exception - PRId, //15-0 Processor identification and revision - EBase, //15-1 Exception vector base register - Config, - Config1, - Config2, - Config3, - LLAddr, - WatchLo, - WatchHi, - Debug, - TraceControl1, - TraceControl2, - UserTraceData, - TraceBPC, + VPESchedule = 13, + VPEScheFBack = 14, + VPEOpt = 15, + EntryLo0 = 16, // Bank 3: 16 - 23 + TCStatus = 17, + TCBind = 18, + TCRestart = 19, + TCHalt = 20, + TCContext = 21, + TCSchedule = 22, + TCScheFBack = 23, - DEPC, + EntryLo1 = 24,// Bank 4: 24 - 31 - PerfCnt, + Context = 32, // Bank 5: 32 - 39 + ContextConfig = 33, - ErrCtl, + //PageMask = 40, //Bank 6: 40 - 47 + PageGrain = 41, - CacheErr0, - CacheErr1, - CacheErr2, - CacheErr3, + Wired = 48, //Bank 7:48 - 55 + SRSConf0 = 49, + SRSConf1 = 50, + SRSConf2 = 51, + SRSConf3 = 52, + SRSConf4 = 53, + BadVAddr = 54, - TagLo, - DataLo, - TagHi, - DataHi, - ErrorEPC, - DESAVE, + HWRena = 56,//Bank 8:56 - 63 + + Count = 64, //Bank 9:64 - 71 + + EntryHi = 72,//Bank 10:72 - 79 + + Compare = 80,//Bank 11:80 - 87 + + Status = 88,//Bank 12:88 - 96 //12-0 Processor status and control + IntCtl = 89, //12-1 Interrupt system status and control + SRSCtl = 90, //12-2 Shadow register set status and control + SRSMap = 91, //12-3 Shadow set IPL mapping + + Cause = 97,//97-104 //13-0 Cause of last general exception + + EPC = 105,//105-112 //14-0 Program counter at last exception + + PrId = 113//113-120, //15-0 Processor identification and revision + EBase = 114, //15-1 Exception vector base register + + Config = 121,//121-128 + Config1 = 122, + Config2 = 123, + Config3 = 124, + Config6 = 127, + Config7 = 128, + + + LLAddr = 129,//129-136 + + WatchLo0 = 137,//137-144 + WatchLo1 = 138, + WatchLo2 = 139, + WatchLo3 = 140, + WatchLo4 = 141, + WatchLo5 = 142, + WatchLo6 = 143, + WatchLo7 = 144, + + WatchHi0 = 145,//145-152 + WatchHi1 = 146, + WatchHi2 = 147, + WatchHi3 = 148, + WatchHi4 = 149, + WatchHi5 = 150, + WatchHi6 = 151, + WatchHi7 = 152, + + XCContext64 = 153,//153-160 + + //161-168 + + //169-176 + + Debug = 177, //177-184 + TraceControl1 = 178, + TraceControl2 = 179, + UserTraceData = 180, + TraceBPC = 181, + + DEPC = 185,//185-192 + + PerfCnt0 = 193,//193 - 200 + PerfCnt1 = 194, + PerfCnt2 = 195, + PerfCnt3 = 196, + PerfCnt4 = 197, + PerfCnt5 = 198, + PerfCnt6 = 199, + PerfCnt7 = 200, + + ErrCtl = 201, //201 - 208 + + CacheErr0 = 209, //209 - 216 + CacheErr1 = 210, + CacheErr2 = 211, + CacheErr3 = 212, + + TagLo0 = 217,//217 - 224 + TagLo2 = 219, + TagLo4 = 221, + TagLo6 = 223, + + DataLo1 = 226,//225 - 232 + DataLo3 = 228, + DataLo5 = 220, + DataLo7 = 232, + + TagHi0 = 233,//233 - 240 + TagHi2 = 235, + TagHi4 = 237, + TagHi6 = 239, + + DataHi0 = 241,//241 - 248 + DataHi2 = 243, + DataHi4 = 245, + DataHi6 = 247, + + ErrorEPC = 249,//249 - 256 + + DESAVE = 257, //More Misc. Regs Hi, From 3b7d756907c8dd0f7c6387953f7b156330fcc47d Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 8 Mar 2006 08:09:27 -0500 Subject: [PATCH 172/180] Working towards compiling SPARC_SE arch/alpha/isa_traits.hh: Changed the enums to const ints, and got rid of a few unnecessary constants. arch/sparc/isa_traits.hh: Got rid of the enums, and added in some missing constants. --HG-- extra : convert_revision : ee47890af9d8c67300b31d8e0dda1d580bd21479 --- arch/alpha/isa_traits.hh | 85 +++++++++++++++++----------------------- arch/sparc/isa_traits.hh | 47 ++++++++++++---------- 2 files changed, 63 insertions(+), 69 deletions(-) diff --git a/arch/alpha/isa_traits.hh b/arch/alpha/isa_traits.hh index be6d5111d..9db16a1bf 100644 --- a/arch/alpha/isa_traits.hh +++ b/arch/alpha/isa_traits.hh @@ -60,52 +60,45 @@ namespace AlphaISA typedef uint64_t ExtMachInst; typedef uint8_t RegIndex; - enum { - MemoryEnd = 0xffffffffffffffffULL, + const int NumIntArchRegs = 32; + const int NumPALShadowRegs = 8; + const int NumFloatArchRegs = 32; + // @todo: Figure out what this number really should be. + const int NumMiscArchRegs = 32; - NumIntArchRegs = 32, - NumPALShadowRegs = 8, - NumFloatArchRegs = 32, - // @todo: Figure out what this number really should be. - NumMiscArchRegs = 32, + // Static instruction parameters + const int MaxInstSrcRegs = 3; + const int MaxInstDestRegs = 2; - MaxRegsOfAnyType = 32, - // Static instruction parameters - MaxInstSrcRegs = 3, - MaxInstDestRegs = 2, + // semantically meaningful register indices + const int ZeroReg = 31; // architecturally meaningful + // the rest of these depend on the ABI + const int StackPointerReg = 30; + const int GlobalPointerReg = 29; + const int ProcedureValueReg = 27; + const int ReturnAddressReg = 26; + const int ReturnValueReg = 0; + const int FramePointerReg = 15; + const int ArgumentReg0 = 16; + const int ArgumentReg1 = 17; + const int ArgumentReg2 = 18; + const int ArgumentReg3 = 19; + const int ArgumentReg4 = 20; + const int ArgumentReg5 = 21; - // semantically meaningful register indices - ZeroReg = 31, // architecturally meaningful - // the rest of these depend on the ABI - StackPointerReg = 30, - GlobalPointerReg = 29, - ProcedureValueReg = 27, - ReturnAddressReg = 26, - ReturnValueReg = 0, - FramePointerReg = 15, - ArgumentReg0 = 16, - ArgumentReg1 = 17, - ArgumentReg2 = 18, - ArgumentReg3 = 19, - ArgumentReg4 = 20, - ArgumentReg5 = 21, + const int LogVMPageSize = 13; // 8K bytes + const int VMPageSize = (1 << LogVMPageSize); - LogVMPageSize = 13, // 8K bytes - VMPageSize = (1 << LogVMPageSize), + const int BranchPredAddrShiftAmt = 2; // instructions are 4-byte aligned - BranchPredAddrShiftAmt = 2, // instructions are 4-byte aligned + const int WordBytes = 4; + const int HalfwordBytes = 2; + const int ByteBytes = 1; - WordBytes = 4, - HalfwordBytes = 2, - ByteBytes = 1, - DepNA = 0, - }; - enum { - NumIntRegs = NumIntArchRegs + NumPALShadowRegs, - NumFloatRegs = NumFloatArchRegs, - NumMiscRegs = NumMiscArchRegs - }; + const int NumIntRegs = NumIntArchRegs + NumPALShadowRegs; + const int NumFloatRegs = NumFloatArchRegs; + const int NumMiscRegs = NumMiscArchRegs; // These enumerate all the registers for dependence tracking. enum DependenceTags { @@ -149,9 +142,7 @@ extern const int reg_redir[NumIntRegs]; #include "arch/alpha/isa_fullsys_traits.hh" #else - enum { - NumInternalProcRegs = 0 - }; + const int NumInternalProcRegs = 0; #endif // control register file contents @@ -192,14 +183,10 @@ extern const int reg_redir[NumIntRegs]; friend class RegFile; }; - enum { - TotalNumRegs = - NumIntRegs + NumFloatRegs + NumMiscRegs + NumInternalProcRegs - }; + const int TotalNumRegs = NumIntRegs + NumFloatRegs + + NumMiscRegs + NumInternalProcRegs; - enum { - TotalDataRegs = NumIntRegs + NumFloatRegs - }; + const int TotalDataRegs = NumIntRegs + NumFloatRegs; typedef union { IntReg intreg; diff --git a/arch/sparc/isa_traits.hh b/arch/sparc/isa_traits.hh index 73daae8a9..c592a05ed 100644 --- a/arch/sparc/isa_traits.hh +++ b/arch/sparc/isa_traits.hh @@ -60,29 +60,36 @@ namespace SparcISA typedef uint64_t ExtMachInst; typedef uint8_t RegIndex; - enum - { - MemoryEnd = 0xffffffffffffffffULL, + const int NumFloatRegs = 32; + const int NumMiscRegs = 32; - NumFloatRegs = 32, - NumMiscRegs = 32, + const int MaxRegsOfAnyType = 32; + const int // Static instruction parameters + const int MaxInstSrcRegs = 3; + const int MaxInstDestRegs = 2; - MaxRegsOfAnyType = 32, - // Static instruction parameters - MaxInstSrcRegs = 3, - MaxInstDestRegs = 2, + const int // Maximum trap level + const int MaxTL = 4; + const int + const int // semantically meaningful register indices + const int ZeroReg = 0; // architecturally meaningful + const int // the rest of these depend on the ABI + const int StackPointerReg = 14; + const int ReturnAddressReg = 31; + const int ReturnValueReg = 24; + const int FramePointerReg = 30; + const int ArgumentReg0 = 24; + const int ArgumentReg1 = 25; + const int ArgumentReg2 = 26; + const int ArgumentReg3 = 27; + const int ArgumentReg4 = 28; + const int ArgumentReg5 = 29; + const int + const int //8K. This value is implmentation specific; and should probably + const int //be somewhere else. + const int LogVMPageSize = 13; + const int VMPageSize = (1 << LogVMPageSize); - // Maximum trap level - MaxTL = 4, - - // semantically meaningful register indices - ZeroReg = 0, // architecturally meaningful - // the rest of these depend on the ABI - //8K. This value is implmentation specific, and should probably - //be somewhere else. - LogVMPageSize = 13, - VMPageSize = (1 << LogVMPageSize) - }; typedef uint64_t IntReg; class IntRegFile From 4d44e53736507de176e48cbf99b064ffa0ae5a7a Mon Sep 17 00:00:00 2001 From: Kevin Lim Date: Wed, 8 Mar 2006 11:34:41 -0500 Subject: [PATCH 173/180] Forward declaration of MemoryController. My change to exec_context.hh probably affected these files to no longer have MemoryController forward declared through a long chain of includes. MemoryController should be forward declared where it is used anyways. dev/alpha_console.hh: dev/uart.hh: dev/uart8250.hh: Forward declaration of MemoryController. --HG-- extra : convert_revision : afaac4014e0eb3b6d5d385cd4444b77511e03b51 --- dev/alpha_console.hh | 1 + dev/uart.hh | 1 + dev/uart8250.hh | 1 + 3 files changed, 3 insertions(+) diff --git a/dev/alpha_console.hh b/dev/alpha_console.hh index 86ef021e9..f63c6ad7e 100644 --- a/dev/alpha_console.hh +++ b/dev/alpha_console.hh @@ -43,6 +43,7 @@ class BaseCPU; class SimConsole; class AlphaSystem; class SimpleDisk; +class MemoryController; /** * Memory mapped interface to the system console. This device diff --git a/dev/uart.hh b/dev/uart.hh index 145b9ca9e..78b1dc68e 100644 --- a/dev/uart.hh +++ b/dev/uart.hh @@ -37,6 +37,7 @@ #include "dev/io_device.hh" class SimConsole; +class MemoryController; class Platform; const int RX_INT = 0x1; diff --git a/dev/uart8250.hh b/dev/uart8250.hh index 88abf8e24..63d1da3cf 100644 --- a/dev/uart8250.hh +++ b/dev/uart8250.hh @@ -53,6 +53,7 @@ #define IIR_LINE 0x06 /* Rx Line Status (highest priority)*/ class SimConsole; +class MemoryController; class Platform; class Uart8250 : public Uart From 77e40756b723e6cf18462bbb15653792b5c90346 Mon Sep 17 00:00:00 2001 From: Kevin Lim Date: Wed, 8 Mar 2006 15:10:47 -0500 Subject: [PATCH 174/180] Include ability to copy all misc regs. arch/alpha/ev5.cc: Include function for the MiscRegFile to copy all of the Iprs from an ExecContext. arch/alpha/isa_traits.hh: Include functions to copy MiscRegs from an ExecContext. cpu/cpu_exec_context.cc: Be sure to copy all of the misc regs when copying all architectural state. --HG-- extra : convert_revision : cb948b5ff141ea0f739a1016f98236bd2a512f76 --- arch/alpha/ev5.cc | 8 ++++++++ arch/alpha/isa_traits.hh | 4 ++++ cpu/cpu_exec_context.cc | 10 +--------- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/arch/alpha/ev5.cc b/arch/alpha/ev5.cc index ccdcf7502..019e83dd4 100644 --- a/arch/alpha/ev5.cc +++ b/arch/alpha/ev5.cc @@ -541,6 +541,14 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ExecContext *xc) return NoFault; } +void +AlphaISA::MiscRegFile::copyIprs(ExecContext *xc) +{ + for (int i = IPR_Base_DepTag; i < NumInternalProcRegs; ++i) { + ipr[i] = xc->readMiscReg(i); + } +} + /** * Check for special simulator handling of specific PAL calls. * If return value is false, actual PAL call will be suppressed. diff --git a/arch/alpha/isa_traits.hh b/arch/alpha/isa_traits.hh index b719b12b0..8e1f21a35 100644 --- a/arch/alpha/isa_traits.hh +++ b/arch/alpha/isa_traits.hh @@ -169,6 +169,8 @@ extern const int reg_redir[NumIntRegs]; Fault setRegWithEffect(int misc_reg, const MiscReg &val, ExecContext *xc); + void copyMiscRegs(ExecContext *xc); + #if FULL_SYSTEM protected: InternalProcReg ipr[NumInternalProcRegs]; // Internal processor regs @@ -177,6 +179,8 @@ extern const int reg_redir[NumIntRegs]; MiscReg readIpr(int idx, Fault &fault, ExecContext *xc); Fault setIpr(int idx, uint64_t val, ExecContext *xc); + + void copyIprs(ExecContext *xc); #endif friend class RegFile; }; diff --git a/cpu/cpu_exec_context.cc b/cpu/cpu_exec_context.cc index 683d07787..b7238e73a 100644 --- a/cpu/cpu_exec_context.cc +++ b/cpu/cpu_exec_context.cc @@ -289,15 +289,7 @@ CPUExecContext::copyArchRegs(ExecContext *xc) } // Copy misc. registers - setMiscReg(AlphaISA::Fpcr_DepTag, xc->readMiscReg(AlphaISA::Fpcr_DepTag)); - setMiscReg(AlphaISA::Uniq_DepTag, xc->readMiscReg(AlphaISA::Uniq_DepTag)); - setMiscReg(AlphaISA::Lock_Flag_DepTag, - xc->readMiscReg(AlphaISA::Lock_Flag_DepTag)); - setMiscReg(AlphaISA::Lock_Addr_DepTag, - xc->readMiscReg(AlphaISA::Lock_Addr_DepTag)); - - // Also need to copy all the IPRs. Probably should just have a copy misc - // regs function defined on the misc regs. + regs.miscRegs.copyMiscRegs(xc); // Lastly copy PC/NPC setPC(xc->readPC()); From 5a0fd8d9dabe5f6786946817eaec59c649a4b550 Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Wed, 8 Mar 2006 16:53:44 -0500 Subject: [PATCH 175/180] add explicit support for nop,ssnop, and ehb instructions --HG-- extra : convert_revision : 41151d38cabb6ce0ea81e5d78e4474d8f2ffeb67 --- arch/mips/isa/decoder.isa | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/arch/mips/isa/decoder.isa b/arch/mips/isa/decoder.isa index 9994acd0b..7d770c554 100644 --- a/arch/mips/isa/decoder.isa +++ b/arch/mips/isa/decoder.isa @@ -30,7 +30,17 @@ decode OPCODE_HI default Unknown::unknown() { //Table A-3 Note: "1. Specific encodings of the rt, rd, and sa fields //are used to distinguish among the SLL, NOP, SSNOP and EHB functions." - 0x0: sll({{ Rd = Rt.uw << SA; }}); + 0x0: decode RS { + 0x0: decode RT default BasicOp::sll({{ Rd = Rt.uw << SA; }}) { + 0x0: decode RD{ + 0x0: decode HINT { + 0x0:nop({{}}); + 0x1:ssnop({{}}); + 0x3:ehb({{}}); + } + } + } + } 0x2: decode SRL { 0: srl({{ Rd = Rt.uw >> SA; }}); From 9e304ed3e6d96e2090981a8aa825dab5b662909a Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Thu, 9 Mar 2006 02:34:12 -0500 Subject: [PATCH 176/180] minor comments to decoder.isa arch/mips/isa/decoder.isa: comments --HG-- extra : convert_revision : 8e4fdf36d7f7365cda062bc169a313bf860a4fe5 --- arch/mips/isa/decoder.isa | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/mips/isa/decoder.isa b/arch/mips/isa/decoder.isa index 7d770c554..3f054f6a5 100644 --- a/arch/mips/isa/decoder.isa +++ b/arch/mips/isa/decoder.isa @@ -34,9 +34,9 @@ decode OPCODE_HI default Unknown::unknown() { 0x0: decode RT default BasicOp::sll({{ Rd = Rt.uw << SA; }}) { 0x0: decode RD{ 0x0: decode HINT { - 0x0:nop({{}}); - 0x1:ssnop({{}}); - 0x3:ehb({{}}); + 0x0:nop({{}}); //really sll r0,r0,0 + 0x1:ssnop({{}});//really sll r0,r0,1 + 0x3:ehb({{}}); //really sll r0,r0,3 } } } From a3aae21d031c93ab1b9a90d435d9590dad2482c4 Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Thu, 9 Mar 2006 03:27:51 -0500 Subject: [PATCH 177/180] last changes before big merge arch/alpha/isa_traits.hh: arch/sparc/isa_traits.hh: add nnpc for compiling purposes in exec_context setNextNPC function cpu/exec_context.hh: set NNPC function cpu/simple/cpu.cc: use NNPC in determining what PC we are using --HG-- extra : convert_revision : e810cfbc5dc31879b20d2cc40bf9871613203532 --- arch/alpha/isa_traits.hh | 2 + arch/mips/isa_traits.hh | 103 +++++++++++++++++++++++++++------------ arch/sparc/isa_traits.hh | 1 + cpu/exec_context.hh | 6 +++ cpu/simple/cpu.cc | 8 +++ 5 files changed, 89 insertions(+), 31 deletions(-) diff --git a/arch/alpha/isa_traits.hh b/arch/alpha/isa_traits.hh index 9db16a1bf..940e3f300 100644 --- a/arch/alpha/isa_traits.hh +++ b/arch/alpha/isa_traits.hh @@ -200,6 +200,8 @@ extern const int reg_redir[NumIntRegs]; MiscRegFile miscRegs; // control register file Addr pc; // program counter Addr npc; // next-cycle program counter + Addr nnpc; + #if FULL_SYSTEM int intrflag; // interrupt flag inline int instAsid() diff --git a/arch/mips/isa_traits.hh b/arch/mips/isa_traits.hh index 408cc3463..1dfa0dc7a 100644 --- a/arch/mips/isa_traits.hh +++ b/arch/mips/isa_traits.hh @@ -65,7 +65,7 @@ namespace MipsISA NumIntRegs = 32, NumFloatRegs = 32, - NumMiscRegs = 256, + NumMiscRegs = 258, //account for hi,lo regs MaxRegsOfAnyType = 32, // Static instruction parameters @@ -127,8 +127,50 @@ namespace MipsISA // cop-0/cop-1 system control register file typedef uint64_t MiscReg; - typedef MiscReg MiscRegFile[NumMiscRegs]; +//typedef MiscReg MiscRegFile[NumMiscRegs]; + class MiscRegFile { + public: + MiscReg + protected: + uint64_t fpcr; // floating point condition codes + uint64_t uniq; // process-unique register + bool lock_flag; // lock flag for LL/SC + Addr lock_addr; // lock address for LL/SC + MiscReg miscRegFile[NumMiscRegs]; + + public: + //These functions should be removed once the simplescalar cpu model + //has been replaced. + int getInstAsid(); + int getDataAsid(); + + MiscReg readReg(int misc_reg) + { return miscRegFile[misc_reg]; } + + MiscReg readRegWithEffect(int misc_reg, Fault &fault, ExecContext *xc) + { return miscRegFile[misc_reg];} + + Fault setReg(int misc_reg, const MiscReg &val) + { miscRegFile[misc_reg] = val; return NoFault; } + + Fault setRegWithEffect(int misc_reg, const MiscReg &val, + ExecContext *xc) + { miscRegFile[misc_reg] = val; return NoFault; } + +#if FULL_SYSTEM + void clearIprs() { }; + + protected: + InternalProcReg ipr[NumInternalProcRegs]; // Internal processor regs + + private: + MiscReg readIpr(int idx, Fault &fault, ExecContext *xc) { } + + Fault setIpr(int idx, uint64_t val, ExecContext *xc) { } +#endif + friend class RegFile; + }; enum MiscRegTags { //Coprocessor 0 Registers @@ -207,10 +249,10 @@ namespace MipsISA EPC = 105,//105-112 //14-0 Program counter at last exception - PrId = 113//113-120, //15-0 Processor identification and revision + PRId = 113//113-120, //15-0 Processor identification and revision EBase = 114, //15-1 Exception vector base register - Config = 121,//121-128 + Config = 121,//Bank 16: 121-128 Config1 = 122, Config2 = 123, Config3 = 124, @@ -218,9 +260,9 @@ namespace MipsISA Config7 = 128, - LLAddr = 129,//129-136 + LLAddr = 129,//Bank 17: 129-136 - WatchLo0 = 137,//137-144 + WatchLo0 = 137,//Bank 18: 137-144 WatchLo1 = 138, WatchLo2 = 139, WatchLo3 = 140, @@ -229,7 +271,7 @@ namespace MipsISA WatchLo6 = 143, WatchLo7 = 144, - WatchHi0 = 145,//145-152 + WatchHi0 = 145,//Bank 19: 145-152 WatchHi1 = 146, WatchHi2 = 147, WatchHi3 = 148, @@ -238,21 +280,21 @@ namespace MipsISA WatchHi6 = 151, WatchHi7 = 152, - XCContext64 = 153,//153-160 + XCContext64 = 153,//Bank 20: 153-160 - //161-168 + //Bank 21: 161-168 - //169-176 + //Bank 22: 169-176 - Debug = 177, //177-184 + Debug = 177, //Bank 23: 177-184 TraceControl1 = 178, TraceControl2 = 179, UserTraceData = 180, TraceBPC = 181, - DEPC = 185,//185-192 + DEPC = 185,//Bank 24: 185-192 - PerfCnt0 = 193,//193 - 200 + PerfCnt0 = 193,//Bank 25: 193 - 200 PerfCnt1 = 194, PerfCnt2 = 195, PerfCnt3 = 196, @@ -261,48 +303,47 @@ namespace MipsISA PerfCnt6 = 199, PerfCnt7 = 200, - ErrCtl = 201, //201 - 208 + ErrCtl = 201, //Bank 26: 201 - 208 - CacheErr0 = 209, //209 - 216 + CacheErr0 = 209, //Bank 27: 209 - 216 CacheErr1 = 210, CacheErr2 = 211, CacheErr3 = 212, - TagLo0 = 217,//217 - 224 + TagLo0 = 217,//Bank 28: 217 - 224 + DataLo1 = 218, TagLo2 = 219, + DataLo3 = 220, TagLo4 = 221, + DataLo5 = 222, TagLo6 = 223, + DataLo7 = 234, - DataLo1 = 226,//225 - 232 - DataLo3 = 228, - DataLo5 = 220, - DataLo7 = 232, - - TagHi0 = 233,//233 - 240 + TagHi0 = 233,//Bank 29: 233 - 240 + DataHi1 = 234, TagHi2 = 235, + DataHi3 = 236, TagHi4 = 237, + DataHi5 = 238, TagHi6 = 239, + DataHi7 = 240, - DataHi0 = 241,//241 - 248 - DataHi2 = 243, - DataHi4 = 245, - DataHi6 = 247, - ErrorEPC = 249,//249 - 256 + ErrorEPC = 249,//Bank 30: 241 - 248 - DESAVE = 257, + DESAVE = 257,//Bank 31: 249-256 //More Misc. Regs Hi, Lo, FCSR, FPCR, - LockAddr, - LockFlag, //Alpha Regs, but here now, for //compiling sake - UNIQ + UNIQ, + LockAddr, + LockFlag }; extern const Addr PageShift; diff --git a/arch/sparc/isa_traits.hh b/arch/sparc/isa_traits.hh index c592a05ed..1752ed194 100644 --- a/arch/sparc/isa_traits.hh +++ b/arch/sparc/isa_traits.hh @@ -409,6 +409,7 @@ namespace SparcISA Addr pc; // Program Counter Addr npc; // Next Program Counter + Addr nnpc; void serialize(std::ostream &os); void unserialize(Checkpoint *cp, const std::string §ion); diff --git a/cpu/exec_context.hh b/cpu/exec_context.hh index bc3551b4f..550a1ca23 100644 --- a/cpu/exec_context.hh +++ b/cpu/exec_context.hh @@ -422,6 +422,12 @@ class ExecContext regs.npc = val; } + void setNextNPC(uint64_t val) + { + regs.nnpc = val; + } + + MiscReg readMiscReg(int misc_reg) { return regs.miscRegs.readReg(misc_reg); diff --git a/cpu/simple/cpu.cc b/cpu/simple/cpu.cc index 51d679a63..f1a3ebd0b 100644 --- a/cpu/simple/cpu.cc +++ b/cpu/simple/cpu.cc @@ -818,9 +818,17 @@ SimpleCPU::tick() #endif // FULL_SYSTEM } else { +#if THE_ISA != MIPS_ISA // go to the next instruction xc->regs.pc = xc->regs.npc; xc->regs.npc += sizeof(MachInst); +#else + // go to the next instruction + xc->regs.pc = xc->regs.npc; + xc->regs.npc = xc->regs.nnpc; + xc->regs.nnpc += sizeof(MachInst); +#endif + } #if FULL_SYSTEM From e30bce8f8e4fdb3dbf4f8161f496c94c85d3d8cf Mon Sep 17 00:00:00 2001 From: Kevin Lim Date: Thu, 9 Mar 2006 15:10:55 -0500 Subject: [PATCH 178/180] Use functions to access XC. cpu/exec_context.hh: Include readNextNPC function. cpu/simple/cpu.cc: Use functions to set and access nextPC, nextNPC. --HG-- extra : convert_revision : 22622b9c110e1d99cc9106a2a27c479579d7e1ad --- cpu/exec_context.hh | 5 +++++ cpu/simple/cpu.cc | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/cpu/exec_context.hh b/cpu/exec_context.hh index 550a1ca23..d6a3fef8b 100644 --- a/cpu/exec_context.hh +++ b/cpu/exec_context.hh @@ -422,6 +422,11 @@ class ExecContext regs.npc = val; } + uint64_t readNextNPC() + { + return regs.nnpc; + } + void setNextNPC(uint64_t val) { regs.nnpc = val; diff --git a/cpu/simple/cpu.cc b/cpu/simple/cpu.cc index f1a3ebd0b..c85154521 100644 --- a/cpu/simple/cpu.cc +++ b/cpu/simple/cpu.cc @@ -825,8 +825,8 @@ SimpleCPU::tick() #else // go to the next instruction xc->regs.pc = xc->regs.npc; - xc->regs.npc = xc->regs.nnpc; - xc->regs.nnpc += sizeof(MachInst); + xc->setNextPC(xc->readNextNPC()); + xc->setNextNPC(xc->readNextNPC() + sizeof(MachInst)); #endif } From ce3a6343b6c54e95d63403d46c9ddea384e49476 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Thu, 9 Mar 2006 15:42:09 -0500 Subject: [PATCH 179/180] no more common syscall emulation, now common for everyone check abi-tag note section of elf binary for OS add pseudo functions (moved from alpha and made to be generic) move setsyscallreturn into isa traits arch/alpha/SConscript: no more common syscall emulation, now common for everyone arch/alpha/isa_traits.hh: move setsyscallreturn into isa description arch/alpha/linux/process.cc: arch/alpha/tru64/process.cc: use generic functions rather than alpha specific ones arch/sparc/isa_traits.hh: have consts for generic pseudo syscalls arch/sparc/linux/process.cc: use generic functions base/loader/elf_object.cc: check abi-tag note section of elf binary for OS cpu/exec_context.hh: move syssyscallreturn into isa traits sim/process.cc: find call num with a more generic sim/syscall_emul.cc: sim/syscall_emul.hh: add pseudo functions (moved from alpha and made to be generic) --HG-- extra : convert_revision : 5a31024ecde7e39b830365ddd84593ea501a34d2 --- arch/alpha/SConscript | 1 - arch/alpha/isa_traits.hh | 94 ++++++++++++++++----------- arch/alpha/linux/process.cc | 31 ++------- arch/alpha/tru64/process.cc | 7 +- arch/sparc/isa_traits.hh | 32 ++++++++- arch/sparc/linux/process.cc | 125 +++++++----------------------------- base/loader/elf_object.cc | 53 ++++++++++++--- cpu/exec_context.hh | 14 +--- sim/process.cc | 2 +- sim/syscall_emul.cc | 114 ++++++++++++++++++++++++++++++++ sim/syscall_emul.hh | 48 ++++++++++++++ 11 files changed, 328 insertions(+), 193 deletions(-) diff --git a/arch/alpha/SConscript b/arch/alpha/SConscript index 6dec2d070..ed7fd3404 100644 --- a/arch/alpha/SConscript +++ b/arch/alpha/SConscript @@ -65,7 +65,6 @@ full_system_sources = Split(''' # Syscall emulation (non-full-system) sources syscall_emulation_sources = Split(''' - common_syscall_emul.cc linux/process.cc tru64/process.cc process.cc diff --git a/arch/alpha/isa_traits.hh b/arch/alpha/isa_traits.hh index a551db485..198473918 100644 --- a/arch/alpha/isa_traits.hh +++ b/arch/alpha/isa_traits.hh @@ -53,6 +53,44 @@ int DTB_ASN_ASN(uint64_t reg); int ITB_ASN_ASN(uint64_t reg); } +#if !FULL_SYSTEM +class SyscallReturn { + public: + template + SyscallReturn(T v, bool s) + { + retval = (uint64_t)v; + success = s; + } + + template + SyscallReturn(T v) + { + success = (v >= 0); + retval = (uint64_t)v; + } + + ~SyscallReturn() {} + + SyscallReturn& operator=(const SyscallReturn& s) { + retval = s.retval; + success = s.success; + return *this; + } + + bool successful() { return success; } + uint64_t value() { return retval; } + + + private: + uint64_t retval; + bool success; +}; + +#endif + + + namespace AlphaISA { @@ -82,6 +120,7 @@ namespace AlphaISA ProcedureValueReg = 27, ReturnAddressReg = 26, ReturnValueReg = 0, + SyscallNumReg = 0, FramePointerReg = 15, ArgumentReg0 = 16, ArgumentReg1 = 17, @@ -89,6 +128,10 @@ namespace AlphaISA ArgumentReg3 = 19, ArgumentReg4 = 20, ArgumentReg5 = 21, + SyscallSuccessReg = 19, + // Some OS use a second register (o1) to return a second value + // for some syscalls + SyscallPseudoReturnReg = ArgumentReg4, LogVMPageSize = 13, // 8K bytes VMPageSize = (1 << LogVMPageSize), @@ -303,6 +346,21 @@ extern const int reg_redir[NumIntRegs]; template void zeroRegisters(XC *xc); + static inline void setSyscallReturn(SyscallReturn return_value, RegFile *regs) + { + // check for error condition. Alpha syscall convention is to + // indicate success/failure in reg a3 (r19) and put the + // return value itself in the standard return value reg (v0). + if (return_value.successful()) { + // no error + regs->intRegFile[SyscallSuccessReg] = 0; + regs->intRegFile[ReturnValueReg] = return_value.value(); + } else { + // got an error, return details + regs->intRegFile[SyscallSuccessReg] = (IntReg) -1; + regs->intRegFile[ReturnValueReg] = -return_value.value(); + } + } //typedef AlphaISA TheISA; @@ -336,42 +394,6 @@ extern const int reg_redir[NumIntRegs]; const Addr MaxAddr = (Addr)-1; }; -#if !FULL_SYSTEM -class SyscallReturn { - public: - template - SyscallReturn(T v, bool s) - { - retval = (uint64_t)v; - success = s; - } - - template - SyscallReturn(T v) - { - success = (v >= 0); - retval = (uint64_t)v; - } - - ~SyscallReturn() {} - - SyscallReturn& operator=(const SyscallReturn& s) { - retval = s.retval; - success = s.success; - return *this; - } - - bool successful() { return success; } - uint64_t value() { return retval; } - - - private: - uint64_t retval; - bool success; -}; - -#endif - static inline AlphaISA::ExtMachInst AlphaISA::makeExtMI(AlphaISA::MachInst inst, const uint64_t &pc) { #if FULL_SYSTEM diff --git a/arch/alpha/linux/process.cc b/arch/alpha/linux/process.cc index d78e6a4ee..2ebdbfc0f 100644 --- a/arch/alpha/linux/process.cc +++ b/arch/alpha/linux/process.cc @@ -26,7 +26,6 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "arch/alpha/common_syscall_emul.hh" #include "arch/alpha/linux/process.hh" #include "arch/alpha/isa_traits.hh" @@ -41,29 +40,7 @@ using namespace std; using namespace AlphaISA; -/// Target pipe() handler. Even though this is a generic Posix call, -/// the Alpha return convention is funky, so that makes it -/// Alpha-specific. -SyscallReturn -pipeFunc(SyscallDesc *desc, int callnum, Process *process, - ExecContext *xc) -{ - int fds[2], sim_fds[2]; - int pipe_retval = pipe(fds); - if (pipe_retval < 0) { - // error - return pipe_retval; - } - - sim_fds[0] = process->alloc_fd(fds[0]); - sim_fds[1] = process->alloc_fd(fds[1]); - - // Alpha Linux convention for pipe() is that fd[0] is returned as - // the return value of the function, and fd[1] is returned in r20. - xc->regs.intRegFile[20] = sim_fds[1]; - return sim_fds[0]; -} /// Target uname() handler. @@ -162,11 +139,11 @@ SyscallDesc AlphaLinuxProcess::syscallDescs[] = { /* 17 */ SyscallDesc("brk", obreakFunc), /* 18 */ SyscallDesc("osf_getfsstat", unimplementedFunc), /* 19 */ SyscallDesc("lseek", lseekFunc), - /* 20 */ SyscallDesc("getxpid", getpidFunc), + /* 20 */ SyscallDesc("getxpid", getpidPseudoFunc), /* 21 */ SyscallDesc("osf_mount", unimplementedFunc), /* 22 */ SyscallDesc("umount", unimplementedFunc), /* 23 */ SyscallDesc("setuid", setuidFunc), - /* 24 */ SyscallDesc("getxuid", getuidFunc), + /* 24 */ SyscallDesc("getxuid", getuidPseudoFunc), /* 25 */ SyscallDesc("exec_with_loader", unimplementedFunc), /* 26 */ SyscallDesc("osf_ptrace", unimplementedFunc), /* 27 */ SyscallDesc("osf_nrecvmsg", unimplementedFunc), @@ -184,12 +161,12 @@ SyscallDesc AlphaLinuxProcess::syscallDescs[] = { /* 39 */ SyscallDesc("setpgid", unimplementedFunc), /* 40 */ SyscallDesc("osf_old_lstat", unimplementedFunc), /* 41 */ SyscallDesc("dup", unimplementedFunc), - /* 42 */ SyscallDesc("pipe", pipeFunc), + /* 42 */ SyscallDesc("pipe", pipePseudoFunc), /* 43 */ SyscallDesc("osf_set_program_attributes", unimplementedFunc), /* 44 */ SyscallDesc("osf_profil", unimplementedFunc), /* 45 */ SyscallDesc("open", openFunc), /* 46 */ SyscallDesc("osf_old_sigaction", unimplementedFunc), - /* 47 */ SyscallDesc("getxgid", getgidFunc), + /* 47 */ SyscallDesc("getxgid", getgidPseudoFunc), /* 48 */ SyscallDesc("osf_sigprocmask", ignoreFunc), /* 49 */ SyscallDesc("osf_getlogin", unimplementedFunc), /* 50 */ SyscallDesc("osf_setlogin", unimplementedFunc), diff --git a/arch/alpha/tru64/process.cc b/arch/alpha/tru64/process.cc index 58d41e3ef..16621a8e2 100644 --- a/arch/alpha/tru64/process.cc +++ b/arch/alpha/tru64/process.cc @@ -27,7 +27,6 @@ */ #include "arch/alpha/isa_traits.hh" -#include "arch/alpha/common_syscall_emul.hh" #include "arch/alpha/tru64/process.hh" #include "cpu/exec_context.hh" #include "kern/tru64/tru64.hh" @@ -179,11 +178,11 @@ SyscallDesc AlphaTru64Process::syscallDescs[] = { /* 17 */ SyscallDesc("obreak", obreakFunc), /* 18 */ SyscallDesc("pre_F64_getfsstat", unimplementedFunc), /* 19 */ SyscallDesc("lseek", lseekFunc), - /* 20 */ SyscallDesc("getpid", getpidFunc), + /* 20 */ SyscallDesc("getpid", getpidPseudoFunc), /* 21 */ SyscallDesc("mount", unimplementedFunc), /* 22 */ SyscallDesc("unmount", unimplementedFunc), /* 23 */ SyscallDesc("setuid", setuidFunc), - /* 24 */ SyscallDesc("getuid", getuidFunc), + /* 24 */ SyscallDesc("getuid", getuidPseudoFunc), /* 25 */ SyscallDesc("exec_with_loader", unimplementedFunc), /* 26 */ SyscallDesc("ptrace", unimplementedFunc), /* 27 */ SyscallDesc("recvmsg", unimplementedFunc), @@ -206,7 +205,7 @@ SyscallDesc AlphaTru64Process::syscallDescs[] = { /* 44 */ SyscallDesc("profil", unimplementedFunc), /* 45 */ SyscallDesc("open", openFunc), /* 46 */ SyscallDesc("obsolete osigaction", unimplementedFunc), - /* 47 */ SyscallDesc("getgid", getgidFunc), + /* 47 */ SyscallDesc("getgid", getgidPseudoFunc), /* 48 */ SyscallDesc("sigprocmask", ignoreFunc), /* 49 */ SyscallDesc("getlogin", unimplementedFunc), /* 50 */ SyscallDesc("setlogin", unimplementedFunc), diff --git a/arch/sparc/isa_traits.hh b/arch/sparc/isa_traits.hh index 5a58bbaef..7f654e33b 100644 --- a/arch/sparc/isa_traits.hh +++ b/arch/sparc/isa_traits.hh @@ -78,7 +78,21 @@ namespace SparcISA // semantically meaningful register indices ZeroReg = 0 // architecturally meaningful // the rest of these depend on the ABI - }; + SyscallNumReg = 1, + ArgumentReg0 = 8, + ArgumentReg1 = 9, + ArgumentReg2 = 10, + ArgumentReg3 = 11, + ArgumentReg4 = 12, + ArgumentReg5 = 13, + StackPoniterReg = 14, + ReturnAddressReg = 31, // Post Call, precall, 15 + ReturnValueReg = 8, // Post return, 24 is pre-return. + // Some OS use a second register (o1) to return a second value + // for some syscalls + SyscallPseudoReturnReg = 9, + FramePointerReg = 30 +}; typedef uint64_t IntReg; class IntRegFile @@ -455,6 +469,22 @@ namespace SparcISA */ template static void zeroRegisters(XC *xc); + + static inline setSyscallReturn(SyscallReturn return_value, RegFile *regs) + { + // check for error condition. SPARC syscall convention is to + // indicate success/failure in reg the carry bit of the ccr + // and put the return value itself in the standard return value reg (). + if (return_value.successful()) { + // no error + regs->miscRegFile.ccrFields.iccFields.c = 0; + regs->intRegFile[ReturnValueReg] = return_value.value(); + } else { + // got an error, return details + regs->miscRegFile.ccrFields.iccFields.c = 1; + regs->intRegFile[ReturnValueReg] = -return_value.value(); + } + } }; const int VMPageSize = TheISA::VMPageSize; diff --git a/arch/sparc/linux/process.cc b/arch/sparc/linux/process.cc index ebfbb2f64..456f99b32 100644 --- a/arch/sparc/linux/process.cc +++ b/arch/sparc/linux/process.cc @@ -41,30 +41,6 @@ using namespace std; using namespace SparcISA; -/// Target pipe() handler. Even though this is a generic Posix call, -/// the Alpha return convention is funky, so that makes it -/// Alpha-specific. -SyscallReturn -pipeFunc(SyscallDesc *desc, int callnum, Process *process, - ExecContext *xc) -{ - int fds[2], sim_fds[2]; - int pipe_retval = pipe(fds); - - if (pipe_retval < 0) { - // error - return pipe_retval; - } - - sim_fds[0] = process->alloc_fd(fds[0]); - sim_fds[1] = process->alloc_fd(fds[1]); - - // Alpha Linux convention for pipe() is that fd[0] is returned as - // the return value of the function, and fd[1] is returned in r20. - xc->regs.intRegFile[20] = sim_fds[1]; - return sim_fds[0]; -} - /// Target uname() handler. static SyscallReturn @@ -77,95 +53,38 @@ unameFunc(SyscallDesc *desc, int callnum, Process *process, strcpy(name->nodename, "m5.eecs.umich.edu"); strcpy(name->release, "2.4.20"); strcpy(name->version, "#1 Mon Aug 18 11:32:15 EDT 2003"); - strcpy(name->machine, "alpha"); + strcpy(name->machine, "sparc"); name.copyOut(xc->mem); return 0; } -/// Target osf_getsysyinfo() handler. Even though this call is -/// borrowed from Tru64, the subcases that get used appear to be -/// different in practice from those used by Tru64 processes. -static SyscallReturn -osf_getsysinfoFunc(SyscallDesc *desc, int callnum, Process *process, - ExecContext *xc) -{ - unsigned op = xc->getSyscallArg(0); - // unsigned nbytes = xc->getSyscallArg(2); - - switch (op) { - - case 45: { // GSI_IEEE_FP_CONTROL - TypedBufferArg fpcr(xc->getSyscallArg(1)); - // I don't think this exactly matches the HW FPCR - *fpcr = 0; - fpcr.copyOut(xc->mem); - return 0; - } - - default: - cerr << "osf_getsysinfo: unknown op " << op << endl; - abort(); - break; - } - - return 1; -} - -/// Target osf_setsysinfo() handler. -static SyscallReturn -osf_setsysinfoFunc(SyscallDesc *desc, int callnum, Process *process, - ExecContext *xc) -{ - unsigned op = xc->getSyscallArg(0); - // unsigned nbytes = xc->getSyscallArg(2); - - switch (op) { - - case 14: { // SSI_IEEE_FP_CONTROL - TypedBufferArg fpcr(xc->getSyscallArg(1)); - // I don't think this exactly matches the HW FPCR - fpcr.copyIn(xc->mem); - DPRINTFR(SyscallVerbose, "osf_setsysinfo(SSI_IEEE_FP_CONTROL): " - " setting FPCR to 0x%x\n", gtoh(*(uint64_t*)fpcr)); - return 0; - } - - default: - cerr << "osf_setsysinfo: unknown op " << op << endl; - abort(); - break; - } - - return 1; -} - SyscallDesc SparcLinuxProcess::syscallDescs[] = { /* 0 */ SyscallDesc("restart_syscall", unimplimentedFunc); - /* 1 */ SyscallDesc("exit", unimplimentedFunc); + /* 1 */ SyscallDesc("exit", exitFunc); /* 2 */ SyscallDesc("fork", unimplimentedFunc); - /* 3 */ SyscallDesc("read", unimplimentedFunc); - /* 4 */ SyscallDesc("write", unimplimentedFunc); - /* 5 */ SyscallDesc("open", unimplimentedFunc); - /* 6 */ SyscallDesc("close", unimplimentedFunc); + /* 3 */ SyscallDesc("read", readFunc); + /* 4 */ SyscallDesc("write", writeFunc); + /* 5 */ SyscallDesc("open", openFunc); + /* 6 */ SyscallDesc("close", closeFinc); /* 7 */ SyscallDesc("wait4", unimplimentedFunc); /* 8 */ SyscallDesc("creat", unimplimentedFunc); /* 9 */ SyscallDesc("link", unimplimentedFunc); - /* 10 */ SyscallDesc("unlink", unimplimentedFunc); + /* 10 */ SyscallDesc("unlink", unlinkFunc); /* 11 */ SyscallDesc("execv", unimplimentedFunc); /* 12 */ SyscallDesc("chdir", unimplimentedFunc); - /* 13 */ SyscallDesc("chown", unimplimentedFunc); + /* 13 */ SyscallDesc("chown", chownFunc); /* 14 */ SyscallDesc("mknod", unimplimentedFunc); - /* 15 */ SyscallDesc("chmod", unimplimentedFunc); + /* 15 */ SyscallDesc("chmod", chmodFunc); /* 16 */ SyscallDesc("lchown", unimplimentedFunc); - /* 17 */ SyscallDesc("brk", unimplimentedFunc); + /* 17 */ SyscallDesc("brk", obreakFunc); /* 18 */ SyscallDesc("perfctr", unimplimentedFunc); - /* 19 */ SyscallDesc("lseek", unimplimentedFunc); - /* 20 */ SyscallDesc("getpid", unimplimentedFunc); + /* 19 */ SyscallDesc("lseek", lseekFunc); + /* 20 */ SyscallDesc("getpid", getpidFunc); /* 21 */ SyscallDesc("capget", unimplimentedFunc); /* 22 */ SyscallDesc("capset", unimplimentedFunc); - /* 23 */ SyscallDesc("setuid", unimplimentedFunc); - /* 24 */ SyscallDesc("getuid", unimplimentedFunc); + /* 23 */ SyscallDesc("setuid", setuidFunc); + /* 24 */ SyscallDesc("getuid", getuidFunc); /* 25 */ SyscallDesc("time", unimplimentedFunc); /* 26 */ SyscallDesc("ptrace", unimplimentedFunc); /* 27 */ SyscallDesc("alarm", unimplimentedFunc); @@ -183,15 +102,15 @@ SyscallDesc SparcLinuxProcess::syscallDescs[] = { /* 39 */ SyscallDesc("sendfile", unimplimentedFunc); /* 40 */ SyscallDesc("lstat", unimplimentedFunc); /* 41 */ SyscallDesc("dup", unimplimentedFunc); - /* 42 */ SyscallDesc("pipe", unimplimentedFunc); + /* 42 */ SyscallDesc("pipe", pipePseudoFunc); /* 43 */ SyscallDesc("times", unimplimentedFunc); /* 44 */ SyscallDesc("getuid32", unimplimentedFunc); /* 45 */ SyscallDesc("umount2", unimplimentedFunc); /* 46 */ SyscallDesc("setgid", unimplimentedFunc); - /* 47 */ SyscallDesc("getgid", unimplimentedFunc); + /* 47 */ SyscallDesc("getgid", getgidFunc); /* 48 */ SyscallDesc("signal", unimplimentedFunc); - /* 49 */ SyscallDesc("geteuid", unimplimentedFunc); - /* 50 */ SyscallDesc("getegid", unimplimentedFunc); + /* 49 */ SyscallDesc("geteuid", geteuidFunc); + /* 50 */ SyscallDesc("getegid", getegidFunc); /* 51 */ SyscallDesc("acct", unimplimentedFunc); /* 52 */ SyscallDesc("memory_ordering", unimplimentedFunc); /* 53 */ SyscallDesc("getgid32", unimplimentedFunc); @@ -330,7 +249,7 @@ SyscallDesc SparcLinuxProcess::syscallDescs[] = { /* 186 */ SyscallDesc("fremovexattr", unimplimentedFunc); /* 187 */ SyscallDesc("tkill", unimplimentedFunc); /* 188 */ SyscallDesc("exit_group", unimplimentedFunc); - /* 189 */ SyscallDesc("uname", unimplimentedFunc); + /* 189 */ SyscallDesc("uname", unameFunc); /* 190 */ SyscallDesc("init_module", unimplimentedFunc); /* 191 */ SyscallDesc("personality", unimplimentedFunc); /* 192 */ SyscallDesc("remap_file_pages", unimplimentedFunc); @@ -338,7 +257,7 @@ SyscallDesc SparcLinuxProcess::syscallDescs[] = { /* 194 */ SyscallDesc("epoll_ctl", unimplimentedFunc); /* 195 */ SyscallDesc("epoll_wait", unimplimentedFunc); /* 196 */ SyscallDesc("ioprio_set", unimplimentedFunc); - /* 197 */ SyscallDesc("getppid", unimplimentedFunc); + /* 197 */ SyscallDesc("getppid", getppidFunc); /* 198 */ SyscallDesc("sigaction", unimplimentedFunc); /* 199 */ SyscallDesc("sgetmask", unimplimentedFunc); /* 200 */ SyscallDesc("ssetmask", unimplimentedFunc); @@ -437,6 +356,10 @@ SparcLinuxProcess::SparcLinuxProcess(const std::string &name, : LiveProcess(name, objFile, stdin_fd, stdout_fd, stderr_fd, argv, envp), Num_Syscall_Descs(sizeof(syscallDescs) / sizeof(SyscallDesc)) { + // The sparc syscall table must be <= 283 entries because that is all there + // is space for. + assert(Num_Syscall_Descs <= 283); + init_regs->intRegFile[0] = 0; } diff --git a/base/loader/elf_object.cc b/base/loader/elf_object.cc index fd69c9e56..791c6f6de 100644 --- a/base/loader/elf_object.cc +++ b/base/loader/elf_object.cc @@ -75,15 +75,6 @@ ElfObject::tryFile(const string &fname, int fd, size_t len, uint8_t *data) return NULL; } else { -// if (ehdr.e_ident[EI_CLASS] == ELFCLASS32) -// panic("32 bit ELF Binary, Not Supported"); - /* @todo this emachine value isn't offical yet. - * so we probably shouldn't check it. */ -// if (ehdr.e_machine != EM_ALPHA) -// panic("Non Alpha Binary, Not Supported"); - - elf_end(elf); - //Detect the architecture //Versioning issues in libelf need to be resolved to get the correct //SPARC constants. @@ -109,17 +100,61 @@ ElfObject::tryFile(const string &fname, int fd, size_t len, uint8_t *data) //Detect the operating system switch (ehdr.e_ident[EI_OSABI]) { + case ELFOSABI_LINUX: opSys = ObjectFile::Linux; break; case ELFOSABI_SOLARIS: opSys = ObjectFile::Solaris; + break; case ELFOSABI_TRU64: opSys = ObjectFile::Tru64; + break; default: opSys = ObjectFile::UnknownOpSys; } + //take a look at the .note.ABI section + //It can let us know what's what. + if (opSys == ObjectFile::UnknownOpSys) + { + Elf_Scn *section; + GElf_Shdr shdr; + Elf_Data *data; + uint32_t osAbi;; + int secIdx = 1; + + // Get the first section + section = elf_getscn(elf, secIdx); + + // While there are no more sections + while (section != NULL) { + gelf_getshdr(section, &shdr); + if (shdr.sh_type == SHT_NOTE && !strcmp(".note.ABI-tag", + elf_strptr(elf, ehdr.e_shstrndx, shdr.sh_name))) { + // we have found a ABI note section + // Check the 5th 32bit word for OS 0 == linux, 1 == hurd, + // 2 == solaris, 3 == freebsd + data = elf_rawdata(section, NULL); + assert(data->d_buf); + if(ehdr.e_ident[EI_DATA] == ELFDATA2LSB) + osAbi = htole(((uint32_t*)data->d_buf)[4]); + else + osAbi = htobe(((uint32_t*)data->d_buf)[4]); + + switch(osAbi) { + case 0: + opSys = ObjectFile::Linux; + break; + case 2: + opSys = ObjectFile::Solaris; + break; + } + } // if section found + section = elf_getscn(elf, ++secIdx); + } // while sections + } + elf_end(elf); return new ElfObject(fname, fd, len, data, arch, opSys); } } diff --git a/cpu/exec_context.hh b/cpu/exec_context.hh index bc3551b4f..97bfc5f0d 100644 --- a/cpu/exec_context.hh +++ b/cpu/exec_context.hh @@ -464,19 +464,7 @@ class ExecContext void setSyscallReturn(SyscallReturn return_value) { - // check for error condition. Alpha syscall convention is to - // indicate success/failure in reg a3 (r19) and put the - // return value itself in the standard return value reg (v0). - const int RegA3 = 19; // only place this is used - if (return_value.successful()) { - // no error - regs.intRegFile[RegA3] = 0; - regs.intRegFile[TheISA::ReturnValueReg] = return_value.value(); - } else { - // got an error, return details - regs.intRegFile[RegA3] = (TheISA::IntReg) -1; - regs.intRegFile[TheISA::ReturnValueReg] = -return_value.value(); - } + TheISA::setSyscallReturn(return_value, ®s); } void syscall() diff --git a/sim/process.cc b/sim/process.cc index fddd9a0b9..894beeb05 100644 --- a/sim/process.cc +++ b/sim/process.cc @@ -354,7 +354,7 @@ LiveProcess::syscall(ExecContext *xc) { num_syscalls++; - int64_t callnum = xc->regs.intRegFile[ReturnValueReg]; + int64_t callnum = xc->regs.intRegFile[SyscallNumReg]; SyscallDesc *desc = getDesc(callnum); if (desc == NULL) diff --git a/sim/syscall_emul.cc b/sim/syscall_emul.cc index d22dde3b8..682d11267 100644 --- a/sim/syscall_emul.cc +++ b/sim/syscall_emul.cc @@ -324,4 +324,118 @@ fcntlFunc(SyscallDesc *desc, int num, Process *process, } } +SyscallReturn +pipePseudoFunc(SyscallDesc *desc, int callnum, Process *process, + ExecContext *xc) +{ + int fds[2], sim_fds[2]; + int pipe_retval = pipe(fds); + + if (pipe_retval < 0) { + // error + return pipe_retval; + } + + sim_fds[0] = process->alloc_fd(fds[0]); + sim_fds[1] = process->alloc_fd(fds[1]); + + // Alpha Linux convention for pipe() is that fd[0] is returned as + // the return value of the function, and fd[1] is returned in r20. + xc->regs.intRegFile[SyscallPseudoReturnReg] = sim_fds[1]; + return sim_fds[0]; +} + + +SyscallReturn +getpidPseudoFunc(SyscallDesc *desc, int callnum, Process *process, + ExecContext *xc) +{ + // Make up a PID. There's no interprocess communication in + // fake_syscall mode, so there's no way for a process to know it's + // not getting a unique value. + + xc->regs.intRegFile[SyscallPseudoReturnReg] = 99; + return 100; +} + + +SyscallReturn +getuidPseudoFunc(SyscallDesc *desc, int callnum, Process *process, + ExecContext *xc) +{ + // Make up a UID and EUID... it shouldn't matter, and we want the + // simulation to be deterministic. + + // EUID goes in r20. + xc->regs.intRegFile[SyscallPseudoReturnReg] = 100; // EUID + return 100; // UID +} + + +SyscallReturn +getgidPseudoFunc(SyscallDesc *desc, int callnum, Process *process, + ExecContext *xc) +{ + // Get current group ID. EGID goes in r20. + xc->regs.intRegFile[SyscallPseudoReturnReg] = 100; + return 100; +} + + +SyscallReturn +setuidFunc(SyscallDesc *desc, int callnum, Process *process, + ExecContext *xc) +{ + // can't fathom why a benchmark would call this. + warn("Ignoring call to setuid(%d)\n", xc->getSyscallArg(0)); + return 0; +} + +SyscallReturn +getpidFunc(SyscallDesc *desc, int callnum, Process *process, + ExecContext *xc) +{ + // Make up a PID. There's no interprocess communication in + // fake_syscall mode, so there's no way for a process to know it's + // not getting a unique value. + + xc->regs.intRegFile[SyscallPseudoReturnReg] = 99; + return 100; +} + +SyscallReturn +getppidFunc(SyscallDesc *desc, int callnum, Process *process, + ExecContext *xc) +{ + return 99; +} + +SyscallReturn +getuidFunc(SyscallDesc *desc, int callnum, Process *process, + ExecContext *xc) +{ + return 100; // UID +} + +SyscallReturn +geteuidFunc(SyscallDesc *desc, int callnum, Process *process, + ExecContext *xc) +{ + return 100; // UID +} + +SyscallReturn +getgidFunc(SyscallDesc *desc, int callnum, Process *process, + ExecContext *xc) +{ + return 100; +} + +SyscallReturn +getegidFunc(SyscallDesc *desc, int callnum, Process *process, + ExecContext *xc) +{ + return 100; +} + diff --git a/sim/syscall_emul.hh b/sim/syscall_emul.hh index eca9f79e0..539358b8f 100644 --- a/sim/syscall_emul.hh +++ b/sim/syscall_emul.hh @@ -243,6 +243,54 @@ SyscallReturn fchownFunc(SyscallDesc *desc, int num, SyscallReturn fcntlFunc(SyscallDesc *desc, int num, Process *process, ExecContext *xc); +/// Target setuid() handler. +SyscallReturn setuidFunc(SyscallDesc *desc, int num, + Process *p, ExecContext *xc); + +/// Target getpid() handler. +SyscallReturn getpidFunc(SyscallDesc *desc, int num, + Process *p, ExecContext *xc); + +/// Target getuid() handler. +SyscallReturn getuidFunc(SyscallDesc *desc, int num, + Process *p, ExecContext *xc); + +/// Target getgid() handler. +SyscallReturn getgidFunc(SyscallDesc *desc, int num, + Process *p, ExecContext *xc); + +/// Target getppid() handler. +SyscallReturn getppidFunc(SyscallDesc *desc, int num, + Process *p, ExecContext *xc); + +/// Target geteuid() handler. +SyscallReturn geteuidFunc(SyscallDesc *desc, int num, + Process *p, ExecContext *xc); + +/// Target getegid() handler. +SyscallReturn getegidFunc(SyscallDesc *desc, int num, + Process *p, ExecContext *xc); + + + +/// Pseudo Funcs - These functions use a different return convension, +/// returning a second value in a register other than the normal return register +SyscallReturn pipePseudoFunc(SyscallDesc *desc, int num, + Process *process, ExecContext *xc); + +/// Target getpidPseudo() handler. +SyscallReturn getpidPseudoFunc(SyscallDesc *desc, int num, + Process *p, ExecContext *xc); + +/// Target getuidPseudo() handler. +SyscallReturn getuidPseudoFunc(SyscallDesc *desc, int num, + Process *p, ExecContext *xc); + +/// Target getgidPseudo() handler. +SyscallReturn getgidPseudoFunc(SyscallDesc *desc, int num, + Process *p, ExecContext *xc); + + /// This struct is used to build an target-OS-dependent table that /// maps the target's open() flags to the host open() flags. struct OpenFlagTransTable { From 7b283dbc090d1197593b00fd1279b92f7c2e693e Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Thu, 9 Mar 2006 16:17:10 -0500 Subject: [PATCH 180/180] fix merging issues arch/alpha/isa_traits.hh: arch/sparc/linux/process.cc: fix merging problem sim/syscall_emul.cc: use setIntReg --HG-- extra : convert_revision : e88d72e415493cd17d7b88c22c7e995f3199e396 --- arch/alpha/isa_traits.hh | 4 + arch/sparc/linux/process.cc | 523 ++++++++++++++++++------------------ sim/syscall_emul.cc | 10 +- 3 files changed, 271 insertions(+), 266 deletions(-) diff --git a/arch/alpha/isa_traits.hh b/arch/alpha/isa_traits.hh index 6f6b11e62..0cf31cb50 100644 --- a/arch/alpha/isa_traits.hh +++ b/arch/alpha/isa_traits.hh @@ -125,6 +125,7 @@ namespace AlphaISA const int ArgumentReg5 = 21; const int SyscallNumReg = ReturnValueReg; const int SyscallPseudoReturnReg = ArgumentReg4; + const int SyscallSuccessReg = 19; @@ -341,6 +342,8 @@ extern const int reg_redir[NumIntRegs]; template void zeroRegisters(XC *xc); + const Addr MaxAddr = (Addr)-1; + static inline void setSyscallReturn(SyscallReturn return_value, RegFile *regs) { // check for error condition. Alpha syscall convention is to @@ -356,6 +359,7 @@ extern const int reg_redir[NumIntRegs]; regs->intRegFile[ReturnValueReg] = -return_value.value(); } } +}; static inline AlphaISA::ExtMachInst AlphaISA::makeExtMI(AlphaISA::MachInst inst, const uint64_t &pc) { diff --git a/arch/sparc/linux/process.cc b/arch/sparc/linux/process.cc index 5965e6da9..fa2a7b9f5 100644 --- a/arch/sparc/linux/process.cc +++ b/arch/sparc/linux/process.cc @@ -60,289 +60,290 @@ unameFunc(SyscallDesc *desc, int callnum, Process *process, } SyscallDesc SparcLinuxProcess::syscallDescs[] = { - /* 0 */ SyscallDesc("restart_syscall", unimplimentedFunc); + /* 0 */ SyscallDesc("restart_syscall", unimplementedFunc); /* 1 */ SyscallDesc("exit", exitFunc); + /* 2 */ SyscallDesc("fork", unimplementedFunc); /* 3 */ SyscallDesc("read", readFunc); /* 4 */ SyscallDesc("write", writeFunc); /* 5 */ SyscallDesc("open", openFunc); /* 6 */ SyscallDesc("close", closeFinc); - /* 7 */ SyscallDesc("wait4", unimplimentedFunc); - /* 8 */ SyscallDesc("creat", unimplimentedFunc); - /* 9 */ SyscallDesc("link", unimplimentedFunc); + /* 7 */ SyscallDesc("wait4", unimplementedFunc); + /* 8 */ SyscallDesc("creat", unimplementedFunc); + /* 9 */ SyscallDesc("link", unimplementedFunc); /* 10 */ SyscallDesc("unlink", unlinkFunc); - /* 11 */ SyscallDesc("execv", unimplimentedFunc); - /* 12 */ SyscallDesc("chdir", unimplimentedFunc); + /* 11 */ SyscallDesc("execv", unimplementedFunc); + /* 12 */ SyscallDesc("chdir", unimplementedFunc); /* 13 */ SyscallDesc("chown", chownFunc); - /* 14 */ SyscallDesc("mknod", unimplimentedFunc); + /* 14 */ SyscallDesc("mknod", unimplementedFunc); /* 15 */ SyscallDesc("chmod", chmodFunc); - /* 16 */ SyscallDesc("lchown", unimplimentedFunc); + /* 16 */ SyscallDesc("lchown", unimplementedFunc); /* 17 */ SyscallDesc("brk", obreakFunc); - /* 18 */ SyscallDesc("perfctr", unimplimentedFunc); + /* 18 */ SyscallDesc("perfctr", unimplementedFunc); /* 19 */ SyscallDesc("lseek", lseekFunc); /* 20 */ SyscallDesc("getpid", getpidFunc); - /* 21 */ SyscallDesc("capget", unimplimentedFunc); - /* 22 */ SyscallDesc("capset", unimplimentedFunc); + /* 21 */ SyscallDesc("capget", unimplementedFunc); + /* 22 */ SyscallDesc("capset", unimplementedFunc); /* 23 */ SyscallDesc("setuid", setuidFunc); /* 24 */ SyscallDesc("getuid", getuidFunc); - /* 25 */ SyscallDesc("time", unimplimentedFunc); - /* 26 */ SyscallDesc("ptrace", unimplimentedFunc); - /* 27 */ SyscallDesc("alarm", unimplimentedFunc); - /* 28 */ SyscallDesc("sigaltstack", unimplimentedFunc); - /* 29 */ SyscallDesc("pause", unimplimentedFunc); - /* 30 */ SyscallDesc("utime", unimplimentedFunc); - /* 31 */ SyscallDesc("lchown32", unimplimentedFunc); - /* 32 */ SyscallDesc("fchown32", unimplimentedFunc); - /* 33 */ SyscallDesc("access", unimplimentedFunc); - /* 34 */ SyscallDesc("nice", unimplimentedFunc); - /* 35 */ SyscallDesc("chown32", unimplimentedFunc); - /* 36 */ SyscallDesc("sync", unimplimentedFunc); - /* 37 */ SyscallDesc("kill", unimplimentedFunc); - /* 38 */ SyscallDesc("stat", unimplimentedFunc); - /* 39 */ SyscallDesc("sendfile", unimplimentedFunc); - /* 40 */ SyscallDesc("lstat", unimplimentedFunc); - /* 41 */ SyscallDesc("dup", unimplimentedFunc); + /* 25 */ SyscallDesc("time", unimplementedFunc); + /* 26 */ SyscallDesc("ptrace", unimplementedFunc); + /* 27 */ SyscallDesc("alarm", unimplementedFunc); + /* 28 */ SyscallDesc("sigaltstack", unimplementedFunc); + /* 29 */ SyscallDesc("pause", unimplementedFunc); + /* 30 */ SyscallDesc("utime", unimplementedFunc); + /* 31 */ SyscallDesc("lchown32", unimplementedFunc); + /* 32 */ SyscallDesc("fchown32", unimplementedFunc); + /* 33 */ SyscallDesc("access", unimplementedFunc); + /* 34 */ SyscallDesc("nice", unimplementedFunc); + /* 35 */ SyscallDesc("chown32", unimplementedFunc); + /* 36 */ SyscallDesc("sync", unimplementedFunc); + /* 37 */ SyscallDesc("kill", unimplementedFunc); + /* 38 */ SyscallDesc("stat", unimplementedFunc); + /* 39 */ SyscallDesc("sendfile", unimplementedFunc); + /* 40 */ SyscallDesc("lstat", unimplementedFunc); + /* 41 */ SyscallDesc("dup", unimplementedFunc); /* 42 */ SyscallDesc("pipe", pipePseudoFunc); - /* 43 */ SyscallDesc("times", unimplimentedFunc); - /* 44 */ SyscallDesc("getuid32", unimplimentedFunc); - /* 45 */ SyscallDesc("umount2", unimplimentedFunc); - /* 46 */ SyscallDesc("setgid", unimplimentedFunc); + /* 43 */ SyscallDesc("times", unimplementedFunc); + /* 44 */ SyscallDesc("getuid32", unimplementedFunc); + /* 45 */ SyscallDesc("umount2", unimplementedFunc); + /* 46 */ SyscallDesc("setgid", unimplementedFunc); /* 47 */ SyscallDesc("getgid", getgidFunc); - /* 48 */ SyscallDesc("signal", unimplimentedFunc); + /* 48 */ SyscallDesc("signal", unimplementedFunc); /* 49 */ SyscallDesc("geteuid", geteuidFunc); /* 50 */ SyscallDesc("getegid", getegidFunc); - /* 51 */ SyscallDesc("acct", unimplimentedFunc); - /* 52 */ SyscallDesc("memory_ordering", unimplimentedFunc); - /* 53 */ SyscallDesc("getgid32", unimplimentedFunc); - /* 54 */ SyscallDesc("ioctl", unimplimentedFunc); - /* 55 */ SyscallDesc("reboot", unimplimentedFunc); - /* 56 */ SyscallDesc("mmap2", unimplimentedFunc); - /* 57 */ SyscallDesc("symlink", unimplimentedFunc); - /* 58 */ SyscallDesc("readlink", unimplimentedFunc); - /* 59 */ SyscallDesc("execve", unimplimentedFunc); - /* 60 */ SyscallDesc("umask", unimplimentedFunc); - /* 61 */ SyscallDesc("chroot", unimplimentedFunc); - /* 62 */ SyscallDesc("fstat", unimplimentedFunc); - /* 63 */ SyscallDesc("fstat64", unimplimentedFunc); - /* 64 */ SyscallDesc("getpagesize", unimplimentedFunc); - /* 65 */ SyscallDesc("msync", unimplimentedFunc); - /* 66 */ SyscallDesc("vfork", unimplimentedFunc); - /* 67 */ SyscallDesc("pread64", unimplimentedFunc); - /* 68 */ SyscallDesc("pwrite64", unimplimentedFunc); - /* 69 */ SyscallDesc("geteuid32", unimplimentedFunc); - /* 70 */ SyscallDesc("getdgid32", unimplimentedFunc); - /* 71 */ SyscallDesc("mmap", unimplimentedFunc); - /* 72 */ SyscallDesc("setreuid32", unimplimentedFunc); - /* 73 */ SyscallDesc("munmap", unimplimentedFunc); - /* 74 */ SyscallDesc("mprotect", unimplimentedFunc); - /* 75 */ SyscallDesc("madvise", unimplimentedFunc); - /* 76 */ SyscallDesc("vhangup", unimplimentedFunc); - /* 77 */ SyscallDesc("truncate64", unimplimentedFunc); - /* 78 */ SyscallDesc("mincore", unimplimentedFunc); - /* 79 */ SyscallDesc("getgroups", unimplimentedFunc); - /* 80 */ SyscallDesc("setgroups", unimplimentedFunc); - /* 81 */ SyscallDesc("getpgrp", unimplimentedFunc); - /* 82 */ SyscallDesc("setgroups32", unimplimentedFunc); - /* 83 */ SyscallDesc("setitimer", unimplimentedFunc); - /* 84 */ SyscallDesc("ftruncate64", unimplimentedFunc); - /* 85 */ SyscallDesc("swapon", unimplimentedFunc); - /* 86 */ SyscallDesc("getitimer", unimplimentedFunc); - /* 87 */ SyscallDesc("setuid32", unimplimentedFunc); - /* 88 */ SyscallDesc("sethostname", unimplimentedFunc); - /* 89 */ SyscallDesc("setgid32", unimplimentedFunc); - /* 90 */ SyscallDesc("dup2", unimplimentedFunc); - /* 91 */ SyscallDesc("setfsuid32", unimplimentedFunc); - /* 92 */ SyscallDesc("fcntl", unimplimentedFunc); - /* 93 */ SyscallDesc("select", unimplimentedFunc); - /* 94 */ SyscallDesc("setfsgid32", unimplimentedFunc); - /* 95 */ SyscallDesc("fsync", unimplimentedFunc); - /* 96 */ SyscallDesc("setpriority", unimplimentedFunc); - /* 97 */ SyscallDesc("socket", unimplimentedFunc); - /* 98 */ SyscallDesc("connect", unimplimentedFunc); - /* 99 */ SyscallDesc("accept", unimplimentedFunc); - /* 100 */ SyscallDesc("getpriority", unimplimentedFunc); - /* 101 */ SyscallDesc("rt_sigreturn", unimplimentedFunc); - /* 102 */ SyscallDesc("rt_sigaction", unimplimentedFunc); - /* 103 */ SyscallDesc("rt_sigprocmask", unimplimentedFunc); - /* 104 */ SyscallDesc("rt_sigpending", unimplimentedFunc); - /* 105 */ SyscallDesc("rt_sigtimedwait", unimplimentedFunc); - /* 106 */ SyscallDesc("rt_sigqueueinfo", unimplimentedFunc); - /* 107 */ SyscallDesc("rt_sigsuspend", unimplimentedFunc); - /* 108 */ SyscallDesc("setresuid", unimplimentedFunc); - /* 109 */ SyscallDesc("getresuid", unimplimentedFunc); - /* 110 */ SyscallDesc("setresgid", unimplimentedFunc); - /* 111 */ SyscallDesc("getresgid", unimplimentedFunc); - /* 112 */ SyscallDesc("setregid32", unimplimentedFunc); - /* 113 */ SyscallDesc("recvmsg", unimplimentedFunc); - /* 114 */ SyscallDesc("sendmsg", unimplimentedFunc); - /* 115 */ SyscallDesc("getgroups32", unimplimentedFunc); - /* 116 */ SyscallDesc("gettimeofday", unimplimentedFunc); - /* 117 */ SyscallDesc("getrusage", unimplimentedFunc); - /* 118 */ SyscallDesc("getsockopt", unimplimentedFunc); - /* 119 */ SyscallDesc("getcwd", unimplimentedFunc); - /* 120 */ SyscallDesc("readv", unimplimentedFunc); - /* 121 */ SyscallDesc("writev", unimplimentedFunc); - /* 122 */ SyscallDesc("settimeofday", unimplimentedFunc); - /* 123 */ SyscallDesc("fchown", unimplimentedFunc); - /* 124 */ SyscallDesc("fchmod", unimplimentedFunc); - /* 125 */ SyscallDesc("recvfrom", unimplimentedFunc); - /* 126 */ SyscallDesc("setreuid", unimplimentedFunc); - /* 127 */ SyscallDesc("setregid", unimplimentedFunc); - /* 128 */ SyscallDesc("rename", unimplimentedFunc); - /* 129 */ SyscallDesc("truncate", unimplimentedFunc); - /* 130 */ SyscallDesc("ftruncate", unimplimentedFunc); - /* 131 */ SyscallDesc("flock", unimplimentedFunc); - /* 132 */ SyscallDesc("lstat64", unimplimentedFunc); - /* 133 */ SyscallDesc("sendto", unimplimentedFunc); - /* 134 */ SyscallDesc("shutdown", unimplimentedFunc); - /* 135 */ SyscallDesc("socketpair", unimplimentedFunc); - /* 136 */ SyscallDesc("mkdir", unimplimentedFunc); - /* 137 */ SyscallDesc("rmdir", unimplimentedFunc); - /* 138 */ SyscallDesc("utimes", unimplimentedFunc); - /* 139 */ SyscallDesc("stat64", unimplimentedFunc); - /* 140 */ SyscallDesc("sendfile64", unimplimentedFunc); - /* 141 */ SyscallDesc("getpeername", unimplimentedFunc); - /* 142 */ SyscallDesc("futex", unimplimentedFunc); - /* 143 */ SyscallDesc("gettid", unimplimentedFunc); - /* 144 */ SyscallDesc("getrlimit", unimplimentedFunc); - /* 145 */ SyscallDesc("setrlimit", unimplimentedFunc); - /* 146 */ SyscallDesc("pivot_root", unimplimentedFunc); - /* 147 */ SyscallDesc("prctl", unimplimentedFunc); - /* 148 */ SyscallDesc("pciconfig_read", unimplimentedFunc); - /* 149 */ SyscallDesc("pciconfig_write", unimplimentedFunc); - /* 150 */ SyscallDesc("getsockname", unimplimentedFunc); - /* 151 */ SyscallDesc("inotify_init", unimplimentedFunc); - /* 152 */ SyscallDesc("inotify_add_watch", unimplimentedFunc); - /* 153 */ SyscallDesc("poll", unimplimentedFunc); - /* 154 */ SyscallDesc("getdents64", unimplimentedFunc); - /* 155 */ SyscallDesc("fcntl64", unimplimentedFunc); - /* 156 */ SyscallDesc("inotify_rm_watch", unimplimentedFunc); - /* 157 */ SyscallDesc("statfs", unimplimentedFunc); - /* 158 */ SyscallDesc("fstatfs", unimplimentedFunc); - /* 159 */ SyscallDesc("umount", unimplimentedFunc); - /* 160 */ SyscallDesc("sched_set_affinity", unimplimentedFunc); - /* 161 */ SyscallDesc("sched_get_affinity", unimplimentedFunc); - /* 162 */ SyscallDesc("getdomainname", unimplimentedFunc); - /* 163 */ SyscallDesc("setdomainname", unimplimentedFunc); - /* 164 */ SyscallDesc("utrap_install", unimplimentedFunc); - /* 165 */ SyscallDesc("quotactl", unimplimentedFunc); - /* 166 */ SyscallDesc("set_tid_address", unimplimentedFunc); - /* 167 */ SyscallDesc("mount", unimplimentedFunc); - /* 168 */ SyscallDesc("ustat", unimplimentedFunc); - /* 169 */ SyscallDesc("setxattr", unimplimentedFunc); - /* 170 */ SyscallDesc("lsetxattr", unimplimentedFunc); - /* 171 */ SyscallDesc("fsetxattr", unimplimentedFunc); - /* 172 */ SyscallDesc("getxattr", unimplimentedFunc); - /* 173 */ SyscallDesc("lgetxattr", unimplimentedFunc); - /* 174 */ SyscallDesc("getdents", unimplimentedFunc); - /* 175 */ SyscallDesc("setsid", unimplimentedFunc); - /* 176 */ SyscallDesc("fchdir", unimplimentedFunc); - /* 177 */ SyscallDesc("fgetxattr", unimplimentedFunc); - /* 178 */ SyscallDesc("listxattr", unimplimentedFunc); - /* 179 */ SyscallDesc("llistxattr", unimplimentedFunc); - /* 180 */ SyscallDesc("flistxattr", unimplimentedFunc); - /* 181 */ SyscallDesc("removexattr", unimplimentedFunc); - /* 182 */ SyscallDesc("lremovexattr", unimplimentedFunc); - /* 183 */ SyscallDesc("sigpending", unimplimentedFunc); - /* 184 */ SyscallDesc("query_module", unimplimentedFunc); - /* 185 */ SyscallDesc("setpgid", unimplimentedFunc); - /* 186 */ SyscallDesc("fremovexattr", unimplimentedFunc); - /* 187 */ SyscallDesc("tkill", unimplimentedFunc); - /* 188 */ SyscallDesc("exit_group", unimplimentedFunc); + /* 51 */ SyscallDesc("acct", unimplementedFunc); + /* 52 */ SyscallDesc("memory_ordering", unimplementedFunc); + /* 53 */ SyscallDesc("getgid32", unimplementedFunc); + /* 54 */ SyscallDesc("ioctl", unimplementedFunc); + /* 55 */ SyscallDesc("reboot", unimplementedFunc); + /* 56 */ SyscallDesc("mmap2", unimplementedFunc); + /* 57 */ SyscallDesc("symlink", unimplementedFunc); + /* 58 */ SyscallDesc("readlink", unimplementedFunc); + /* 59 */ SyscallDesc("execve", unimplementedFunc); + /* 60 */ SyscallDesc("umask", unimplementedFunc); + /* 61 */ SyscallDesc("chroot", unimplementedFunc); + /* 62 */ SyscallDesc("fstat", unimplementedFunc); + /* 63 */ SyscallDesc("fstat64", unimplementedFunc); + /* 64 */ SyscallDesc("getpagesize", unimplementedFunc); + /* 65 */ SyscallDesc("msync", unimplementedFunc); + /* 66 */ SyscallDesc("vfork", unimplementedFunc); + /* 67 */ SyscallDesc("pread64", unimplementedFunc); + /* 68 */ SyscallDesc("pwrite64", unimplementedFunc); + /* 69 */ SyscallDesc("geteuid32", unimplementedFunc); + /* 70 */ SyscallDesc("getdgid32", unimplementedFunc); + /* 71 */ SyscallDesc("mmap", unimplementedFunc); + /* 72 */ SyscallDesc("setreuid32", unimplementedFunc); + /* 73 */ SyscallDesc("munmap", unimplementedFunc); + /* 74 */ SyscallDesc("mprotect", unimplementedFunc); + /* 75 */ SyscallDesc("madvise", unimplementedFunc); + /* 76 */ SyscallDesc("vhangup", unimplementedFunc); + /* 77 */ SyscallDesc("truncate64", unimplementedFunc); + /* 78 */ SyscallDesc("mincore", unimplementedFunc); + /* 79 */ SyscallDesc("getgroups", unimplementedFunc); + /* 80 */ SyscallDesc("setgroups", unimplementedFunc); + /* 81 */ SyscallDesc("getpgrp", unimplementedFunc); + /* 82 */ SyscallDesc("setgroups32", unimplementedFunc); + /* 83 */ SyscallDesc("setitimer", unimplementedFunc); + /* 84 */ SyscallDesc("ftruncate64", unimplementedFunc); + /* 85 */ SyscallDesc("swapon", unimplementedFunc); + /* 86 */ SyscallDesc("getitimer", unimplementedFunc); + /* 87 */ SyscallDesc("setuid32", unimplementedFunc); + /* 88 */ SyscallDesc("sethostname", unimplementedFunc); + /* 89 */ SyscallDesc("setgid32", unimplementedFunc); + /* 90 */ SyscallDesc("dup2", unimplementedFunc); + /* 91 */ SyscallDesc("setfsuid32", unimplementedFunc); + /* 92 */ SyscallDesc("fcntl", unimplementedFunc); + /* 93 */ SyscallDesc("select", unimplementedFunc); + /* 94 */ SyscallDesc("setfsgid32", unimplementedFunc); + /* 95 */ SyscallDesc("fsync", unimplementedFunc); + /* 96 */ SyscallDesc("setpriority", unimplementedFunc); + /* 97 */ SyscallDesc("socket", unimplementedFunc); + /* 98 */ SyscallDesc("connect", unimplementedFunc); + /* 99 */ SyscallDesc("accept", unimplementedFunc); + /* 100 */ SyscallDesc("getpriority", unimplementedFunc); + /* 101 */ SyscallDesc("rt_sigreturn", unimplementedFunc); + /* 102 */ SyscallDesc("rt_sigaction", unimplementedFunc); + /* 103 */ SyscallDesc("rt_sigprocmask", unimplementedFunc); + /* 104 */ SyscallDesc("rt_sigpending", unimplementedFunc); + /* 105 */ SyscallDesc("rt_sigtimedwait", unimplementedFunc); + /* 106 */ SyscallDesc("rt_sigqueueinfo", unimplementedFunc); + /* 107 */ SyscallDesc("rt_sigsuspend", unimplementedFunc); + /* 108 */ SyscallDesc("setresuid", unimplementedFunc); + /* 109 */ SyscallDesc("getresuid", unimplementedFunc); + /* 110 */ SyscallDesc("setresgid", unimplementedFunc); + /* 111 */ SyscallDesc("getresgid", unimplementedFunc); + /* 112 */ SyscallDesc("setregid32", unimplementedFunc); + /* 113 */ SyscallDesc("recvmsg", unimplementedFunc); + /* 114 */ SyscallDesc("sendmsg", unimplementedFunc); + /* 115 */ SyscallDesc("getgroups32", unimplementedFunc); + /* 116 */ SyscallDesc("gettimeofday", unimplementedFunc); + /* 117 */ SyscallDesc("getrusage", unimplementedFunc); + /* 118 */ SyscallDesc("getsockopt", unimplementedFunc); + /* 119 */ SyscallDesc("getcwd", unimplementedFunc); + /* 120 */ SyscallDesc("readv", unimplementedFunc); + /* 121 */ SyscallDesc("writev", unimplementedFunc); + /* 122 */ SyscallDesc("settimeofday", unimplementedFunc); + /* 123 */ SyscallDesc("fchown", unimplementedFunc); + /* 124 */ SyscallDesc("fchmod", unimplementedFunc); + /* 125 */ SyscallDesc("recvfrom", unimplementedFunc); + /* 126 */ SyscallDesc("setreuid", unimplementedFunc); + /* 127 */ SyscallDesc("setregid", unimplementedFunc); + /* 128 */ SyscallDesc("rename", unimplementedFunc); + /* 129 */ SyscallDesc("truncate", unimplementedFunc); + /* 130 */ SyscallDesc("ftruncate", unimplementedFunc); + /* 131 */ SyscallDesc("flock", unimplementedFunc); + /* 132 */ SyscallDesc("lstat64", unimplementedFunc); + /* 133 */ SyscallDesc("sendto", unimplementedFunc); + /* 134 */ SyscallDesc("shutdown", unimplementedFunc); + /* 135 */ SyscallDesc("socketpair", unimplementedFunc); + /* 136 */ SyscallDesc("mkdir", unimplementedFunc); + /* 137 */ SyscallDesc("rmdir", unimplementedFunc); + /* 138 */ SyscallDesc("utimes", unimplementedFunc); + /* 139 */ SyscallDesc("stat64", unimplementedFunc); + /* 140 */ SyscallDesc("sendfile64", unimplementedFunc); + /* 141 */ SyscallDesc("getpeername", unimplementedFunc); + /* 142 */ SyscallDesc("futex", unimplementedFunc); + /* 143 */ SyscallDesc("gettid", unimplementedFunc); + /* 144 */ SyscallDesc("getrlimit", unimplementedFunc); + /* 145 */ SyscallDesc("setrlimit", unimplementedFunc); + /* 146 */ SyscallDesc("pivot_root", unimplementedFunc); + /* 147 */ SyscallDesc("prctl", unimplementedFunc); + /* 148 */ SyscallDesc("pciconfig_read", unimplementedFunc); + /* 149 */ SyscallDesc("pciconfig_write", unimplementedFunc); + /* 150 */ SyscallDesc("getsockname", unimplementedFunc); + /* 151 */ SyscallDesc("inotify_init", unimplementedFunc); + /* 152 */ SyscallDesc("inotify_add_watch", unimplementedFunc); + /* 153 */ SyscallDesc("poll", unimplementedFunc); + /* 154 */ SyscallDesc("getdents64", unimplementedFunc); + /* 155 */ SyscallDesc("fcntl64", unimplementedFunc); + /* 156 */ SyscallDesc("inotify_rm_watch", unimplementedFunc); + /* 157 */ SyscallDesc("statfs", unimplementedFunc); + /* 158 */ SyscallDesc("fstatfs", unimplementedFunc); + /* 159 */ SyscallDesc("umount", unimplementedFunc); + /* 160 */ SyscallDesc("sched_set_affinity", unimplementedFunc); + /* 161 */ SyscallDesc("sched_get_affinity", unimplementedFunc); + /* 162 */ SyscallDesc("getdomainname", unimplementedFunc); + /* 163 */ SyscallDesc("setdomainname", unimplementedFunc); + /* 164 */ SyscallDesc("utrap_install", unimplementedFunc); + /* 165 */ SyscallDesc("quotactl", unimplementedFunc); + /* 166 */ SyscallDesc("set_tid_address", unimplementedFunc); + /* 167 */ SyscallDesc("mount", unimplementedFunc); + /* 168 */ SyscallDesc("ustat", unimplementedFunc); + /* 169 */ SyscallDesc("setxattr", unimplementedFunc); + /* 170 */ SyscallDesc("lsetxattr", unimplementedFunc); + /* 171 */ SyscallDesc("fsetxattr", unimplementedFunc); + /* 172 */ SyscallDesc("getxattr", unimplementedFunc); + /* 173 */ SyscallDesc("lgetxattr", unimplementedFunc); + /* 174 */ SyscallDesc("getdents", unimplementedFunc); + /* 175 */ SyscallDesc("setsid", unimplementedFunc); + /* 176 */ SyscallDesc("fchdir", unimplementedFunc); + /* 177 */ SyscallDesc("fgetxattr", unimplementedFunc); + /* 178 */ SyscallDesc("listxattr", unimplementedFunc); + /* 179 */ SyscallDesc("llistxattr", unimplementedFunc); + /* 180 */ SyscallDesc("flistxattr", unimplementedFunc); + /* 181 */ SyscallDesc("removexattr", unimplementedFunc); + /* 182 */ SyscallDesc("lremovexattr", unimplementedFunc); + /* 183 */ SyscallDesc("sigpending", unimplementedFunc); + /* 184 */ SyscallDesc("query_module", unimplementedFunc); + /* 185 */ SyscallDesc("setpgid", unimplementedFunc); + /* 186 */ SyscallDesc("fremovexattr", unimplementedFunc); + /* 187 */ SyscallDesc("tkill", unimplementedFunc); + /* 188 */ SyscallDesc("exit_group", unimplementedFunc); /* 189 */ SyscallDesc("uname", unameFunc); - /* 190 */ SyscallDesc("init_module", unimplimentedFunc); - /* 191 */ SyscallDesc("personality", unimplimentedFunc); - /* 192 */ SyscallDesc("remap_file_pages", unimplimentedFunc); - /* 193 */ SyscallDesc("epoll_create", unimplimentedFunc); - /* 194 */ SyscallDesc("epoll_ctl", unimplimentedFunc); - /* 195 */ SyscallDesc("epoll_wait", unimplimentedFunc); - /* 196 */ SyscallDesc("ioprio_set", unimplimentedFunc); + /* 190 */ SyscallDesc("init_module", unimplementedFunc); + /* 191 */ SyscallDesc("personality", unimplementedFunc); + /* 192 */ SyscallDesc("remap_file_pages", unimplementedFunc); + /* 193 */ SyscallDesc("epoll_create", unimplementedFunc); + /* 194 */ SyscallDesc("epoll_ctl", unimplementedFunc); + /* 195 */ SyscallDesc("epoll_wait", unimplementedFunc); + /* 196 */ SyscallDesc("ioprio_set", unimplementedFunc); /* 197 */ SyscallDesc("getppid", getppidFunc); - /* 198 */ SyscallDesc("sigaction", unimplimentedFunc); - /* 199 */ SyscallDesc("sgetmask", unimplimentedFunc); - /* 200 */ SyscallDesc("ssetmask", unimplimentedFunc); - /* 201 */ SyscallDesc("sigsuspend", unimplimentedFunc); - /* 202 */ SyscallDesc("oldlstat", unimplimentedFunc); - /* 203 */ SyscallDesc("uselib", unimplimentedFunc); - /* 204 */ SyscallDesc("readdir", unimplimentedFunc); - /* 205 */ SyscallDesc("readahead", unimplimentedFunc); - /* 206 */ SyscallDesc("socketcall", unimplimentedFunc); - /* 207 */ SyscallDesc("syslog", unimplimentedFunc); - /* 208 */ SyscallDesc("lookup_dcookie", unimplimentedFunc); - /* 209 */ SyscallDesc("fadvise64", unimplimentedFunc); - /* 210 */ SyscallDesc("fadvise64_64", unimplimentedFunc); - /* 211 */ SyscallDesc("tgkill", unimplimentedFunc); - /* 212 */ SyscallDesc("waitpid", unimplimentedFunc); - /* 213 */ SyscallDesc("swapoff", unimplimentedFunc); - /* 214 */ SyscallDesc("sysinfo", unimplimentedFunc); - /* 215 */ SyscallDesc("ipc", unimplimentedFunc); - /* 216 */ SyscallDesc("sigreturn", unimplimentedFunc); - /* 217 */ SyscallDesc("clone", unimplimentedFunc); - /* 218 */ SyscallDesc("ioprio_get", unimplimentedFunc); - /* 219 */ SyscallDesc("adjtimex", unimplimentedFunc); - /* 220 */ SyscallDesc("sigprocmask", unimplimentedFunc); - /* 221 */ SyscallDesc("create_module", unimplimentedFunc); - /* 222 */ SyscallDesc("delete_module", unimplimentedFunc); - /* 223 */ SyscallDesc("get_kernel_syms", unimplimentedFunc); - /* 224 */ SyscallDesc("getpgid", unimplimentedFunc); - /* 225 */ SyscallDesc("bdflush", unimplimentedFunc); - /* 226 */ SyscallDesc("sysfs", unimplimentedFunc); - /* 227 */ SyscallDesc("afs_syscall", unimplimentedFunc); - /* 228 */ SyscallDesc("setfsuid", unimplimentedFunc); - /* 229 */ SyscallDesc("setfsgid", unimplimentedFunc); - /* 230 */ SyscallDesc("_newselect", unimplimentedFunc); - /* 231 */ SyscallDesc("time", unimplimentedFunc); - /* 232 */ SyscallDesc("oldstat", unimplimentedFunc); - /* 233 */ SyscallDesc("stime", unimplimentedFunc); - /* 234 */ SyscallDesc("statfs64", unimplimentedFunc); - /* 235 */ SyscallDesc("fstatfs64", unimplimentedFunc); - /* 236 */ SyscallDesc("_llseek", unimplimentedFunc); - /* 237 */ SyscallDesc("mlock", unimplimentedFunc); - /* 238 */ SyscallDesc("munlock", unimplimentedFunc); - /* 239 */ SyscallDesc("mlockall", unimplimentedFunc); - /* 240 */ SyscallDesc("munlockall", unimplimentedFunc); - /* 241 */ SyscallDesc("sched_setparam", unimplimentedFunc); - /* 242 */ SyscallDesc("sched_getparam", unimplimentedFunc); - /* 243 */ SyscallDesc("sched_setscheduler", unimplimentedFunc); - /* 244 */ SyscallDesc("sched_getscheduler", unimplimentedFunc); - /* 245 */ SyscallDesc("sched_yield", unimplimentedFunc); + /* 198 */ SyscallDesc("sigaction", unimplementedFunc); + /* 199 */ SyscallDesc("sgetmask", unimplementedFunc); + /* 200 */ SyscallDesc("ssetmask", unimplementedFunc); + /* 201 */ SyscallDesc("sigsuspend", unimplementedFunc); + /* 202 */ SyscallDesc("oldlstat", unimplementedFunc); + /* 203 */ SyscallDesc("uselib", unimplementedFunc); + /* 204 */ SyscallDesc("readdir", unimplementedFunc); + /* 205 */ SyscallDesc("readahead", unimplementedFunc); + /* 206 */ SyscallDesc("socketcall", unimplementedFunc); + /* 207 */ SyscallDesc("syslog", unimplementedFunc); + /* 208 */ SyscallDesc("lookup_dcookie", unimplementedFunc); + /* 209 */ SyscallDesc("fadvise64", unimplementedFunc); + /* 210 */ SyscallDesc("fadvise64_64", unimplementedFunc); + /* 211 */ SyscallDesc("tgkill", unimplementedFunc); + /* 212 */ SyscallDesc("waitpid", unimplementedFunc); + /* 213 */ SyscallDesc("swapoff", unimplementedFunc); + /* 214 */ SyscallDesc("sysinfo", unimplementedFunc); + /* 215 */ SyscallDesc("ipc", unimplementedFunc); + /* 216 */ SyscallDesc("sigreturn", unimplementedFunc); + /* 217 */ SyscallDesc("clone", unimplementedFunc); + /* 218 */ SyscallDesc("ioprio_get", unimplementedFunc); + /* 219 */ SyscallDesc("adjtimex", unimplementedFunc); + /* 220 */ SyscallDesc("sigprocmask", unimplementedFunc); + /* 221 */ SyscallDesc("create_module", unimplementedFunc); + /* 222 */ SyscallDesc("delete_module", unimplementedFunc); + /* 223 */ SyscallDesc("get_kernel_syms", unimplementedFunc); + /* 224 */ SyscallDesc("getpgid", unimplementedFunc); + /* 225 */ SyscallDesc("bdflush", unimplementedFunc); + /* 226 */ SyscallDesc("sysfs", unimplementedFunc); + /* 227 */ SyscallDesc("afs_syscall", unimplementedFunc); + /* 228 */ SyscallDesc("setfsuid", unimplementedFunc); + /* 229 */ SyscallDesc("setfsgid", unimplementedFunc); + /* 230 */ SyscallDesc("_newselect", unimplementedFunc); + /* 231 */ SyscallDesc("time", unimplementedFunc); + /* 232 */ SyscallDesc("oldstat", unimplementedFunc); + /* 233 */ SyscallDesc("stime", unimplementedFunc); + /* 234 */ SyscallDesc("statfs64", unimplementedFunc); + /* 235 */ SyscallDesc("fstatfs64", unimplementedFunc); + /* 236 */ SyscallDesc("_llseek", unimplementedFunc); + /* 237 */ SyscallDesc("mlock", unimplementedFunc); + /* 238 */ SyscallDesc("munlock", unimplementedFunc); + /* 239 */ SyscallDesc("mlockall", unimplementedFunc); + /* 240 */ SyscallDesc("munlockall", unimplementedFunc); + /* 241 */ SyscallDesc("sched_setparam", unimplementedFunc); + /* 242 */ SyscallDesc("sched_getparam", unimplementedFunc); + /* 243 */ SyscallDesc("sched_setscheduler", unimplementedFunc); + /* 244 */ SyscallDesc("sched_getscheduler", unimplementedFunc); + /* 245 */ SyscallDesc("sched_yield", unimplementedFunc); /* 246 */ SyscallDesc("sched_get_priority_max", unimplimented); /* 247 */ SyscallDesc("sched_get_priority_min", unimplimented); /* 248 */ SyscallDesc("sched_rr_get_interval", unimplimented); - /* 249 */ SyscallDesc("nanosleep", unimplimentedFunc); - /* 250 */ SyscallDesc("mremap", unimplimentedFunc); - /* 251 */ SyscallDesc("_sysctl", unimplimentedFunc); - /* 252 */ SyscallDesc("getsid", unimplimentedFunc); - /* 253 */ SyscallDesc("fdatasync", unimplimentedFunc); - /* 254 */ SyscallDesc("nfsservctl", unimplimentedFunc); - /* 255 */ SyscallDesc("aplib", unimplimentedFunc); - /* 256 */ SyscallDesc("clock_settime", unimplimentedFunc); - /* 257 */ SyscallDesc("clock_gettime", unimplimentedFunc); - /* 258 */ SyscallDesc("clock_getres", unimplimentedFunc); - /* 259 */ SyscallDesc("clock_nanosleep", unimplimentedFunc); - /* 260 */ SyscallDesc("sched_getaffinity", unimplimentedFunc); - /* 261 */ SyscallDesc("sched_setaffinity", unimplimentedFunc); - /* 262 */ SyscallDesc("timer_settime", unimplimentedFunc); - /* 263 */ SyscallDesc("timer_gettime", unimplimentedFunc); - /* 264 */ SyscallDesc("timer_getoverrun", unimplimentedFunc); - /* 265 */ SyscallDesc("timer_delete", unimplimentedFunc); - /* 266 */ SyscallDesc("timer_create", unimplimentedFunc); - /* 267 */ SyscallDesc("vserver", unimplimentedFunc); - /* 268 */ SyscallDesc("io_setup", unimplimentedFunc); - /* 269 */ SyscallDesc("io_destroy", unimplimentedFunc); - /* 270 */ SyscallDesc("io_submit", unimplimentedFunc); - /* 271 */ SyscallDesc("io_cancel", unimplimentedFunc); - /* 272 */ SyscallDesc("io_getevents", unimplimentedFunc); - /* 273 */ SyscallDesc("mq_open", unimplimentedFunc); - /* 274 */ SyscallDesc("mq_unlink", unimplimentedFunc); - /* 275 */ SyscallDesc("mq_timedsend", unimplimentedFunc); - /* 276 */ SyscallDesc("mq_timedreceive", unimplimentedFunc); - /* 277 */ SyscallDesc("mq_notify", unimplimentedFunc); - /* 278 */ SyscallDesc("mq_getsetattr", unimplimentedFunc); - /* 279 */ SyscallDesc("waitid", unimplimentedFunc); - /* 280 */ SyscallDesc("sys_setaltroot", unimplimentedFunc); - /* 281 */ SyscallDesc("add_key", unimplimentedFunc); - /* 282 */ SyscallDesc("request_key", unimplimentedFunc); - /* 283 */ SyscallDesc("keyctl", unimplimentedFunc); + /* 249 */ SyscallDesc("nanosleep", unimplementedFunc); + /* 250 */ SyscallDesc("mremap", unimplementedFunc); + /* 251 */ SyscallDesc("_sysctl", unimplementedFunc); + /* 252 */ SyscallDesc("getsid", unimplementedFunc); + /* 253 */ SyscallDesc("fdatasync", unimplementedFunc); + /* 254 */ SyscallDesc("nfsservctl", unimplementedFunc); + /* 255 */ SyscallDesc("aplib", unimplementedFunc); + /* 256 */ SyscallDesc("clock_settime", unimplementedFunc); + /* 257 */ SyscallDesc("clock_gettime", unimplementedFunc); + /* 258 */ SyscallDesc("clock_getres", unimplementedFunc); + /* 259 */ SyscallDesc("clock_nanosleep", unimplementedFunc); + /* 260 */ SyscallDesc("sched_getaffinity", unimplementedFunc); + /* 261 */ SyscallDesc("sched_setaffinity", unimplementedFunc); + /* 262 */ SyscallDesc("timer_settime", unimplementedFunc); + /* 263 */ SyscallDesc("timer_gettime", unimplementedFunc); + /* 264 */ SyscallDesc("timer_getoverrun", unimplementedFunc); + /* 265 */ SyscallDesc("timer_delete", unimplementedFunc); + /* 266 */ SyscallDesc("timer_create", unimplementedFunc); + /* 267 */ SyscallDesc("vserver", unimplementedFunc); + /* 268 */ SyscallDesc("io_setup", unimplementedFunc); + /* 269 */ SyscallDesc("io_destroy", unimplementedFunc); + /* 270 */ SyscallDesc("io_submit", unimplementedFunc); + /* 271 */ SyscallDesc("io_cancel", unimplementedFunc); + /* 272 */ SyscallDesc("io_getevents", unimplementedFunc); + /* 273 */ SyscallDesc("mq_open", unimplementedFunc); + /* 274 */ SyscallDesc("mq_unlink", unimplementedFunc); + /* 275 */ SyscallDesc("mq_timedsend", unimplementedFunc); + /* 276 */ SyscallDesc("mq_timedreceive", unimplementedFunc); + /* 277 */ SyscallDesc("mq_notify", unimplementedFunc); + /* 278 */ SyscallDesc("mq_getsetattr", unimplementedFunc); + /* 279 */ SyscallDesc("waitid", unimplementedFunc); + /* 280 */ SyscallDesc("sys_setaltroot", unimplementedFunc); + /* 281 */ SyscallDesc("add_key", unimplementedFunc); + /* 282 */ SyscallDesc("request_key", unimplementedFunc); + /* 283 */ SyscallDesc("keyctl", unimplementedFunc); }; SparcLinuxProcess::SparcLinuxProcess(const std::string &name, diff --git a/sim/syscall_emul.cc b/sim/syscall_emul.cc index 793c0c6cb..00168b025 100644 --- a/sim/syscall_emul.cc +++ b/sim/syscall_emul.cc @@ -341,7 +341,7 @@ pipePseudoFunc(SyscallDesc *desc, int callnum, Process *process, // Alpha Linux convention for pipe() is that fd[0] is returned as // the return value of the function, and fd[1] is returned in r20. - xc->regs.intRegFile[SyscallPseudoReturnReg] = sim_fds[1]; + xc->setIntReg(SyscallPseudoReturnReg, sim_fds[1]); return sim_fds[0]; } @@ -354,7 +354,7 @@ getpidPseudoFunc(SyscallDesc *desc, int callnum, Process *process, // fake_syscall mode, so there's no way for a process to know it's // not getting a unique value. - xc->regs.intRegFile[SyscallPseudoReturnReg] = 99; + xc->setIntReg(SyscallPseudoReturnReg, 99); return 100; } @@ -367,7 +367,7 @@ getuidPseudoFunc(SyscallDesc *desc, int callnum, Process *process, // simulation to be deterministic. // EUID goes in r20. - xc->regs.intRegFile[SyscallPseudoReturnReg] = 100; // EUID + xc->setIntReg(SyscallPseudoReturnReg, 100); //EUID return 100; // UID } @@ -377,7 +377,7 @@ getgidPseudoFunc(SyscallDesc *desc, int callnum, Process *process, ExecContext *xc) { // Get current group ID. EGID goes in r20. - xc->regs.intRegFile[SyscallPseudoReturnReg] = 100; + xc->setIntReg(SyscallPseudoReturnReg, 100); //EGID return 100; } @@ -399,7 +399,7 @@ getpidFunc(SyscallDesc *desc, int callnum, Process *process, // fake_syscall mode, so there's no way for a process to know it's // not getting a unique value. - xc->regs.intRegFile[SyscallPseudoReturnReg] = 99; + xc->setIntReg(SyscallPseudoReturnReg, 99); //PID return 100; }