diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/arch/sparc/isa/decoder.isa | 629 | ||||
-rw-r--r-- | src/arch/sparc/isa/formats/basic.isa | 24 | ||||
-rw-r--r-- | src/arch/sparc/isa/formats/branch.isa | 168 | ||||
-rw-r--r-- | src/arch/sparc/isa/formats/integerop.isa | 43 | ||||
-rw-r--r-- | src/arch/sparc/isa/formats/mem/basicmem.isa | 12 | ||||
-rw-r--r-- | src/arch/sparc/isa/formats/mem/blockmem.isa | 12 | ||||
-rw-r--r-- | src/arch/sparc/isa/formats/mem/swap.isa | 12 | ||||
-rw-r--r-- | src/arch/sparc/isa/formats/priv.isa | 46 | ||||
-rw-r--r-- | src/arch/sparc/isa/includes.isa | 1 | ||||
-rw-r--r-- | src/base/condcodes.hh | 2 | ||||
-rw-r--r-- | src/base/loader/elf_object.cc | 92 | ||||
-rw-r--r-- | src/base/loader/elf_object.hh | 8 | ||||
-rw-r--r-- | src/cpu/simple_thread.hh | 16 | ||||
-rw-r--r-- | src/sim/process.cc | 9 |
14 files changed, 507 insertions, 567 deletions
diff --git a/src/arch/sparc/isa/decoder.isa b/src/arch/sparc/isa/decoder.isa index 14c652606..c35b231ff 100644 --- a/src/arch/sparc/isa/decoder.isa +++ b/src/arch/sparc/isa/decoder.isa @@ -45,116 +45,49 @@ decode OP default Unknown::unknown() 0x1: decode COND2 { //Branch Always - 0x8: decode A - { - 0x0: bpa(19, {{ - NNPC = xc->readPC() + disp; - }}); - 0x1: bpa(19, {{ - NPC = xc->readPC() + disp; - NNPC = NPC + 4; - }}, ',a'); - } + 0x8: bpa(19, annul_code={{ + NPC = xc->readPC() + disp; + NNPC = NPC + 4; + }}); //Branch Never - 0x0: decode A - { - 0x0: bpn(19, {{ - NNPC = NNPC;//Don't do anything - }}); - 0x1: bpn(19, {{ - NNPC = NPC + 8; - NPC = NPC + 4; - }}, ',a'); - } + 0x0: bpn(19, {{;}}, + annul_code={{ + NNPC = NPC + 8; + NPC = NPC + 4; + }}); default: decode BPCC { - 0x0: bpcci(19, {{ - if(passesCondition(Ccr<3:0>, COND2)) - NNPC = xc->readPC() + disp; - else - handle_annul - }}); - 0x2: bpccx(19, {{ - if(passesCondition(Ccr<7:4>, COND2)) - NNPC = xc->readPC() + disp; - else - handle_annul - }}); + 0x0: bpcci(19, test={{passesCondition(Ccr<3:0>, COND2)}}); + 0x2: bpccx(19, test={{passesCondition(Ccr<7:4>, COND2)}}); } } //bicc 0x2: decode COND2 { //Branch Always - 0x8: decode A - { - 0x0: ba(22, {{ - NNPC = xc->readPC() + disp; - }}); - 0x1: ba(22, {{ - NPC = xc->readPC() + disp; - NNPC = NPC + 4; - }}, ',a'); - } + 0x8: ba(22, annul_code={{ + NPC = xc->readPC() + disp; + NNPC = NPC + 4; + }}); //Branch Never - 0x0: decode A - { - 0x0: bn(22, {{ - NNPC = NNPC;//Don't do anything - }}); - 0x1: bn(22, {{ - NNPC = NPC + 8; - NPC = NPC + 4; - }}, ',a'); - } - default: bicc(22, {{ - if(passesCondition(Ccr<3:0>, COND2)) - NNPC = xc->readPC() + disp; - else - handle_annul - }}); + 0x0: bn(22, {{;}}, + annul_code={{ + NNPC = NPC + 8; + NPC = NPC + 4; + }}); + default: bicc(22, test={{passesCondition(Ccr<3:0>, COND2)}}); } } 0x3: decode RCOND2 { format BranchSplit { - 0x1: bpreq({{ - if(Rs1.sdw == 0) - NNPC = xc->readPC() + disp; - else - handle_annul - }}); - 0x2: bprle({{ - if(Rs1.sdw <= 0) - NNPC = xc->readPC() + disp; - else - handle_annul - }}); - 0x3: bprl({{ - if(Rs1.sdw < 0) - NNPC = xc->readPC() + disp; - else - handle_annul - }}); - 0x5: bprne({{ - if(Rs1.sdw != 0) - NNPC = xc->readPC() + disp; - else - handle_annul - }}); - 0x6: bprg({{ - if(Rs1.sdw > 0) - NNPC = xc->readPC() + disp; - else - handle_annul - }}); - 0x7: bprge({{ - if(Rs1.sdw >= 0) - NNPC = xc->readPC() + disp; - else - handle_annul - }}); + 0x1: bpreq(test={{Rs1.sdw == 0}}); + 0x2: bprle(test={{Rs1.sdw <= 0}}); + 0x3: bprl(test={{Rs1.sdw < 0}}); + 0x5: bprne(test={{Rs1.sdw != 0}}); + 0x6: bprg(test={{Rs1.sdw > 0}}); + 0x7: bprge(test={{Rs1.sdw >= 0}}); } } //SETHI (or NOP if rd == 0 and imm == 0) @@ -163,52 +96,25 @@ decode OP default Unknown::unknown() 0x5: decode COND2 { format BranchN { //Branch Always - 0x8: decode A - { - 0x0: fbpa(22, {{ - NNPC = xc->readPC() + disp; - }}); - 0x1: fbpa(22, {{ - NPC = xc->readPC() + disp; - NNPC = NPC + 4; - }}, ',a'); - } + 0x8: fbpa(22, annul_code={{ + NPC = xc->readPC() + disp; + NNPC = NPC + 4; + }}); //Branch Never - 0x0: decode A - { - 0x0: fbpn(22, {{ - NNPC = NNPC;//Don't do anything - }}); - 0x1: fbpn(22, {{ - NNPC = NPC + 8; - NPC = NPC + 4; - }}, ',a'); - } + 0x0: fbpn(22, {{;}}, + annul_code={{ + NNPC = NPC + 8; + NPC = NPC + 4; + }}); default: decode BPCC { - 0x0: fbpfcc0(19, {{ - if(passesFpCondition(Fsr<11:10>, COND2)) - NNPC = xc->readPC() + disp; - else - handle_annul - }}); - 0x1: fbpfcc1(19, {{ - if(passesFpCondition(Fsr<33:32>, COND2)) - NNPC = xc->readPC() + disp; - else - handle_annul - }}); - 0x2: fbpfcc2(19, {{ - if(passesFpCondition(Fsr<35:34>, COND2)) - NNPC = xc->readPC() + disp; - else - handle_annul - }}); - 0x3: fbpfcc3(19, {{ - if(passesFpCondition(Fsr<37:36>, COND2)) - NNPC = xc->readPC() + disp; - else - handle_annul - }}); + 0x0: fbpfcc0(19, test= + {{passesFpCondition(Fsr<11:10>, COND2)}}); + 0x1: fbpfcc1(19, test= + {{passesFpCondition(Fsr<33:32>, COND2)}}); + 0x2: fbpfcc2(19, test= + {{passesFpCondition(Fsr<35:34>, COND2)}}); + 0x3: fbpfcc3(19, test= + {{passesFpCondition(Fsr<37:36>, COND2)}}); } } } @@ -216,33 +122,18 @@ decode OP default Unknown::unknown() 0x6: decode COND2 { format BranchN { //Branch Always - 0x8: decode A - { - 0x0: fba(22, {{ - NNPC = xc->readPC() + disp; - }}); - 0x1: fba(22, {{ - NPC = xc->readPC() + disp; - NNPC = NPC + 4; - }}, ',a'); - } + 0x8: fba(22, annul_code={{ + NPC = xc->readPC() + disp; + NNPC = NPC + 4; + }}); //Branch Never - 0x0: decode A - { - 0x0: fbn(22, {{ - NNPC = NNPC;//Don't do anything - }}); - 0x1: fbn(22, {{ - NNPC = NPC + 8; - NPC = NPC + 4; - }}, ',a'); - } - default: fbfcc(22, {{ - if(passesFpCondition(Fsr<11:10>, COND2)) - NNPC = xc->readPC() + disp; - else - handle_annul - }}); + 0x0: fbn(22, {{;}}, + annul_code={{ + NNPC = NPC + 8; + NPC = NPC + 4; + }}); + default: fbfcc(22, test= + {{passesFpCondition(Fsr<11:10>, COND2)}}); } } } @@ -302,37 +193,23 @@ decode OP default Unknown::unknown() } format IntOpCc { 0x10: addcc({{ - int64_t resTemp, val2 = Rs2_or_imm13; - Rd = resTemp = Rs1 + val2;}}, - {{(Rs1<31:0> + val2<31:0>)<32:>}}, - {{Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>}}, - {{(Rs1<63:1> + val2<63:1> + (Rs1 & val2)<0:>)<63:>}}, - {{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}} - ); + int64_t res, op1 = Rs1, op2 = Rs2_or_imm13; + Rd = res = op1 + op2; + }}); 0x11: IntOpCcRes::andcc({{Rd = Rs1 & Rs2_or_imm13;}}); 0x12: IntOpCcRes::orcc({{Rd = Rs1 | Rs2_or_imm13;}}); 0x13: IntOpCcRes::xorcc({{Rd = Rs1 ^ Rs2_or_imm13;}}); 0x14: subcc({{ - int64_t val2 = Rs2_or_imm13; - Rd = Rs1 - val2;}}, - {{(~(Rs1<31:0> + (~val2)<31:0> + 1))<32:>}}, - {{(Rs1<31:> != val2<31:>) && (Rs1<31:> != Rd<31:>)}}, - {{(~(Rs1<63:1> + (~val2)<63:1> + - (Rs1 | ~val2)<0:>))<63:>}}, - {{Rs1<63:> != val2<63:> && Rs1<63:> != Rd<63:>}} - ); + int64_t res, op1 = Rs1, op2 = Rs2_or_imm13; + Rd = res = op1 - op2; + }}, sub=True); 0x15: IntOpCcRes::andncc({{Rd = Rs1 & ~Rs2_or_imm13;}}); 0x16: IntOpCcRes::orncc({{Rd = Rs1 | ~Rs2_or_imm13;}}); 0x17: IntOpCcRes::xnorcc({{Rd = ~(Rs1 ^ Rs2_or_imm13);}}); 0x18: addccc({{ - int64_t resTemp, val2 = Rs2_or_imm13; - int64_t carryin = Ccr<0:0>; - Rd = resTemp = Rs1 + val2 + carryin;}}, - {{(Rs1<31:0> + val2<31:0> + carryin)<32:>}}, - {{Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>}}, - {{((Rs1 & val2) | (~resTemp & (Rs1 | val2)))<63:>}}, - {{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}} - ); + int64_t res, op1 = Rs1, op2 = Rs2_or_imm13; + Rd = res = op1 + op2 + Ccr<0:>; + }}); 0x1A: IntOpCcRes::umulcc({{ uint64_t resTemp; Rd = resTemp = Rs1.udw<31:0> * Rs2_or_imm13.udw<31:0>; @@ -342,107 +219,80 @@ decode OP default Unknown::unknown() Rd = resTemp = sext<32>(Rs1.sdw<31:0>) * sext<32>(Rs2_or_imm13<31:0>); Y = resTemp<63:32>;}}); 0x1C: subccc({{ - int64_t resTemp, val2 = Rs2_or_imm13; - int64_t carryin = Ccr<0:0>; - Rd = resTemp = Rs1 + ~val2 + 1 - carryin;}}, - {{((~Rs1 & val2) | (resTemp & (~Rs1 | val2)))<31:>}}, - {{Rs1<31:> != val2<31:> && Rs1<31:> != resTemp<31:>}}, - {{((~Rs1 & val2) | (resTemp & (~Rs1 | val2)))<63:>}}, - {{Rs1<63:> != val2<63:> && Rs1<63:> != resTemp<63:>}} - ); + int64_t res, op1 = Rs1, op2 = Rs2_or_imm13; + Rd = res = op1 - op2 - Ccr<0:>; + }}, sub=True); 0x1D: IntOpCcRes::udivxcc({{ if(Rs2_or_imm13.udw == 0) fault = new DivisionByZero; else Rd = Rs1.udw / Rs2_or_imm13.udw;}}); - 0x1E: udivcc({{ - uint32_t resTemp, val2 = Rs2_or_imm13.udw; - int32_t overflow = 0; - if(val2 == 0) fault = new DivisionByZero; - else - { - resTemp = (uint64_t)((Y << 32) | Rs1.udw<31:0>) / val2; - overflow = (resTemp<63:32> != 0); - if(overflow) Rd = resTemp = 0xFFFFFFFF; - else Rd = resTemp; - } }}, - {{0}}, - {{overflow}}, - {{0}}, - {{0}} - ); - 0x1F: sdivcc({{ - int64_t val2 = Rs2_or_imm13.sdw<31:0>; - bool overflow = false, underflow = false; - if(val2 == 0) fault = new DivisionByZero; - else - { - Rd = (int64_t)((Y << 32) | Rs1.sdw<31:0>) / val2; - overflow = ((int64_t)Rd >= std::numeric_limits<int32_t>::max()); - underflow = ((int64_t)Rd <= std::numeric_limits<int32_t>::min()); - if(overflow) Rd = 0x7FFFFFFF; - else if(underflow) Rd = ULL(0xFFFFFFFF80000000); - } }}, - {{0}}, - {{overflow || underflow}}, - {{0}}, - {{0}} - ); + 0x1E: IntOpCcRes::udivcc({{ + uint32_t resTemp, val2 = Rs2_or_imm13.udw; + int32_t overflow = 0; + if(val2 == 0) fault = new DivisionByZero; + else + { + resTemp = (uint64_t)((Y << 32) | Rs1.udw<31:0>) / val2; + overflow = (resTemp<63:32> != 0); + if(overflow) Rd = resTemp = 0xFFFFFFFF; + else Rd = resTemp; + } + }}, iv={{overflow}}); + 0x1F: IntOpCcRes::sdivcc({{ + int64_t val2 = Rs2_or_imm13.sdw<31:0>; + bool overflow = false, underflow = false; + if(val2 == 0) fault = new DivisionByZero; + else + { + Rd = (int64_t)((Y << 32) | Rs1.sdw<31:0>) / val2; + overflow = ((int64_t)Rd >= std::numeric_limits<int32_t>::max()); + underflow = ((int64_t)Rd <= std::numeric_limits<int32_t>::min()); + if(overflow) Rd = 0x7FFFFFFF; + else if(underflow) Rd = ULL(0xFFFFFFFF80000000); + } + }}, iv={{overflow || underflow}}); 0x20: taddcc({{ - int64_t resTemp, val2 = Rs2_or_imm13; - Rd = resTemp = Rs1 + val2; - int32_t overflow = Rs1<1:0> || val2<1:0> || (Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>);}}, - {{((Rs1<31:0> + val2<31:0>)<32:0>)}}, - {{overflow}}, - {{((Rs1 >> 1) + (val2 >> 1) + (Rs1 & val2 & 0x1))<63:>}}, - {{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}} - ); + int64_t res, op1 = Rs1, op2 = Rs2_or_imm13; + Rd = res = Rs1 + op2; + }}, iv={{ + (op1 & mask(2)) || (op2 & mask(2)) || + findOverflow(32, res, op1, op2) + }}); 0x21: tsubcc({{ - int64_t resTemp, val2 = Rs2_or_imm13; - Rd = resTemp = Rs1 + val2; - int32_t overflow = Rs1<1:0> || val2<1:0> || (Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>);}}, - {{(Rs1<31:0> + val2<31:0>)<32:0>}}, - {{overflow}}, - {{((Rs1 >> 1) + (val2 >> 1) + (Rs1 & val2 & 0x1))<63:>}}, - {{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}} - ); + int64_t res, op1 = Rs1, op2 = Rs2_or_imm13; + Rd = res = Rs1 - op2; + }}, iv={{ + (op1 & mask(2)) || (op2 & mask(2)) || + findOverflow(32, res, op1, ~op2) + }}, sub=True); 0x22: taddcctv({{ - int64_t val2 = Rs2_or_imm13; - Rd = Rs1 + val2; - int32_t overflow = Rs1<1:0> || val2<1:0> || - (Rs1<31:> == val2<31:> && val2<31:> != Rd<31:>); - if(overflow) fault = new TagOverflow;}}, - {{((Rs1<31:0> + val2<31:0>)<32:0>)}}, - {{overflow}}, - {{((Rs1 >> 1) + (val2 >> 1) + (Rs1 & val2 & 0x1))<63:>}}, - {{Rs1<63:> == val2<63:> && val2<63:> != Rd<63:>}} - ); + int64_t res, op1 = Rs1, op2 = Rs2_or_imm13; + Rd = res = op1 + op2; + bool overflow = (op1 & mask(2)) || (op2 & mask(2)) || + findOverflow(32, res, op1, op2); + if(overflow) fault = new TagOverflow; + }}, iv={{overflow}}); 0x23: tsubcctv({{ - int64_t resTemp, val2 = Rs2_or_imm13; - Rd = resTemp = Rs1 + val2; - int32_t overflow = Rs1<1:0> || val2<1:0> || (Rs1<31:> == val2<31:> && val2<31:> != resTemp<31:>); - if(overflow) fault = new TagOverflow;}}, - {{((Rs1<31:0> + val2<31:0>)<32:0>)}}, - {{overflow}}, - {{((Rs1 >> 1) + (val2 >> 1) + (Rs1 & val2 & 0x1))<63:>}}, - {{Rs1<63:> == val2<63:> && val2<63:> != resTemp<63:>}} - ); + int64_t res, op1 = Rs1, op2 = Rs2_or_imm13; + Rd = res = op1 - op2; + bool overflow = (op1 & mask(2)) || (op2 & mask(2)) || + findOverflow(32, res, op1, ~op2); + if(overflow) fault = new TagOverflow; + }}, iv={{overflow}}, sub=True); 0x24: mulscc({{ - int32_t savedLSB = Rs1<0:>; + int32_t savedLSB = Rs1<0:>; - //Step 1 - int64_t multiplicand = Rs2_or_imm13; - //Step 2 - int32_t partialP = Rs1<31:1> | - ((Ccr<3:3> ^ Ccr<1:1>) << 31); - //Step 3 - int32_t added = Y<0:> ? multiplicand : 0; - Rd = partialP + added; - //Steps 4 & 5 - Y = Y<31:1> | (savedLSB << 31);}}, - {{((partialP<31:0> + added<31:0>)<32:0>)}}, - {{partialP<31:> == added<31:> && added<31:> != Rd<31:>}}, - {{((partialP >> 1) + (added >> 1) + (partialP & added & 0x1))<63:>}}, - {{partialP<63:> == added<63:> && partialP<63:> != Rd<63:>}} - ); + //Step 1 + int64_t multiplicand = Rs2_or_imm13; + //Step 2 + int32_t partialP = Rs1<31:1> | + ((Ccr<3:3> ^ Ccr<1:1>) << 31); + //Step 3 + int32_t added = Y<0:> ? multiplicand : 0; + int64_t res, op1 = partialP, op2 = added; + Rd = res = partialP + added; + //Steps 4 & 5 + Y = Y<31:1> | (savedLSB << 31); + }}); } format IntOp { @@ -463,7 +313,7 @@ decode OP default Unknown::unknown() //1 should cause an illegal instruction exception 0x02: NoPriv::rdccr({{Rd = Ccr;}}); 0x03: NoPriv::rdasi({{Rd = Asi;}}); - 0x04: PrivCheck::rdtick({{Rd = Tick;}}, {{Tick<63:>}}); + 0x04: Priv::rdtick({{Rd = Tick;}}, {{Tick<63:>}}); 0x05: NoPriv::rdpc({{ if(Pstate<3:>) Rd = (xc->readPC())<31:0>; @@ -479,7 +329,7 @@ decode OP default Unknown::unknown() 0x1: Nop::membar({{/*stuff*/}}, IsMemBarrier, MemReadOp); } 0x10: Priv::rdpcr({{Rd = Pcr;}}); - 0x11: PrivCheck::rdpic({{Rd = Pic;}}, {{Pcr<0:>}}); + 0x11: Priv::rdpic({{Rd = Pic;}}, {{Pcr<0:>}}); //0x12 should cause an illegal instruction exception 0x13: NoPriv::rdgsr({{ fault = checkFpEnableFault(xc); @@ -490,7 +340,7 @@ decode OP default Unknown::unknown() //0x14-0x15 should cause an illegal instruction exception 0x16: Priv::rdsoftint({{Rd = Softint;}}); 0x17: Priv::rdtick_cmpr({{Rd = TickCmpr;}}); - 0x18: PrivCheck::rdstick({{Rd = Stick}}, {{Stick<63:>}}); + 0x18: Priv::rdstick({{Rd = Stick}}, {{Stick<63:>}}); 0x19: Priv::rdstick_cmpr({{Rd = StickCmpr;}}); 0x1A: Priv::rdstrand_sts_reg({{ if(Pstate<2:> && !Hpstate<2:>) @@ -504,11 +354,7 @@ decode OP default Unknown::unknown() } 0x29: decode RS1 { 0x00: HPriv::rdhprhpstate({{Rd = Hpstate;}}); - 0x01: HPriv::rdhprhtstate({{ - if(Tl == 0) - return new IllegalInstruction; - Rd = Htstate; - }}); + 0x01: HPriv::rdhprhtstate({{Rd = Htstate;}}, checkTl=true); //0x02 should cause an illegal instruction exception 0x03: HPriv::rdhprhintp({{Rd = Hintp;}}); //0x04 should cause an illegal instruction exception @@ -518,26 +364,10 @@ decode OP default Unknown::unknown() 0x1F: HPriv::rdhprhstick_cmpr({{Rd = HstickCmpr;}}); } 0x2A: decode RS1 { - 0x00: Priv::rdprtpc({{ - if(Tl == 0) - return new IllegalInstruction; - Rd = Tpc; - }}); - 0x01: Priv::rdprtnpc({{ - if(Tl == 0) - return new IllegalInstruction; - Rd = Tnpc; - }}); - 0x02: Priv::rdprtstate({{ - if(Tl == 0) - return new IllegalInstruction; - Rd = Tstate; - }}); - 0x03: Priv::rdprtt({{ - if(Tl == 0) - return new IllegalInstruction; - Rd = Tt; - }}); + 0x00: Priv::rdprtpc({{Rd = Tpc;}}, checkTl=true); + 0x01: Priv::rdprtnpc({{Rd = Tnpc;}}, checkTl=true); + 0x02: Priv::rdprtstate({{Rd = Tstate;}}, checkTl=true); + 0x03: Priv::rdprtt({{Rd = Tt;}}, checkTl=true); 0x04: Priv::rdprtick({{Rd = Tick;}}); 0x05: Priv::rdprtba({{Rd = Tba;}}); 0x06: Priv::rdprpstate({{Rd = Pstate;}}); @@ -605,7 +435,7 @@ decode OP default Unknown::unknown() //0x07-0x0E should cause an illegal instruction exception 0x0F: Trap::softreset({{fault = new SoftwareInitiatedReset;}}); 0x10: Priv::wrpcr({{Pcr = Rs1 ^ Rs2_or_imm13;}}); - 0x11: PrivCheck::wrpic({{Pic = Rs1 ^ Rs2_or_imm13;}}, {{Pcr<0:>}}); + 0x11: Priv::wrpic({{Pic = Rs1 ^ Rs2_or_imm13;}}, {{Pcr<0:>}}); //0x12 should cause an illegal instruction exception 0x13: NoPriv::wrgsr({{ if(Fprs<2:> == 0 || Pstate<4:> == 0) @@ -653,30 +483,14 @@ decode OP default Unknown::unknown() }}); } 0x32: decode RD { - 0x00: Priv::wrprtpc({{ - if(Tl == 0) - return new IllegalInstruction; - else - Tpc = Rs1 ^ Rs2_or_imm13; - }}); - 0x01: Priv::wrprtnpc({{ - if(Tl == 0) - return new IllegalInstruction; - else - Tnpc = Rs1 ^ Rs2_or_imm13; - }}); - 0x02: Priv::wrprtstate({{ - if(Tl == 0) - return new IllegalInstruction; - else - Tstate = Rs1 ^ Rs2_or_imm13; - }}); - 0x03: Priv::wrprtt({{ - if(Tl == 0) - return new IllegalInstruction; - else - Tt = Rs1 ^ Rs2_or_imm13; - }}); + 0x00: Priv::wrprtpc( + {{Tpc = Rs1 ^ Rs2_or_imm13;}}, checkTl=true); + 0x01: Priv::wrprtnpc( + {{Tnpc = Rs1 ^ Rs2_or_imm13;}}, checkTl=true); + 0x02: Priv::wrprtstate( + {{Tstate = Rs1 ^ Rs2_or_imm13;}}, checkTl=true); + 0x03: Priv::wrprtt( + {{Tt = Rs1 ^ Rs2_or_imm13;}}, checkTl=true); 0x04: HPriv::wrprtick({{Tick = Rs1 ^ Rs2_or_imm13;}}); 0x05: Priv::wrprtba({{Tba = Rs1 ^ Rs2_or_imm13;}}); 0x06: Priv::wrprpstate({{Pstate = Rs1 ^ Rs2_or_imm13;}}); @@ -704,11 +518,8 @@ decode OP default Unknown::unknown() } 0x33: decode RD { 0x00: HPriv::wrhprhpstate({{Hpstate = Rs1 ^ Rs2_or_imm13;}}); - 0x01: HPriv::wrhprhtstate({{ - if(Tl == 0) - return new IllegalInstruction; - Htstate = Rs1 ^ Rs2_or_imm13; - }}); + 0x01: HPriv::wrhprhtstate( + {{Htstate = Rs1 ^ Rs2_or_imm13;}}, checkTl=true); //0x02 should cause an illegal instruction exception 0x03: HPriv::wrhprhintp({{Hintp = Rs1 ^ Rs2_or_imm13;}}); //0x04 should cause an illegal instruction exception @@ -718,44 +529,14 @@ decode OP default Unknown::unknown() } 0x34: decode OPF{ format FpBasic{ - 0x01: fmovs({{ - Frds.uw = Frs2s.uw; - //fsr.ftt = fsr.cexc = 0 - Fsr &= ~(7 << 14); - Fsr &= ~(0x1F); - }}); - 0x02: fmovd({{ - Frd.udw = Frs2.udw; - //fsr.ftt = fsr.cexc = 0 - Fsr &= ~(7 << 14); - Fsr &= ~(0x1F); - }}); + 0x01: fmovs({{Frds.uw = Frs2s.uw;}}); + 0x02: fmovd({{Frd.udw = Frs2.udw;}}); 0x03: FpUnimpl::fmovq(); - 0x05: fnegs({{ - Frds.uw = Frs2s.uw ^ (1UL << 31); - //fsr.ftt = fsr.cexc = 0 - Fsr &= ~(7 << 14); - Fsr &= ~(0x1F); - }}); - 0x06: fnegd({{ - Frd.udw = Frs2.udw ^ (1ULL << 63); - //fsr.ftt = fsr.cexc = 0 - Fsr &= ~(7 << 14); - Fsr &= ~(0x1F); - }}); + 0x05: fnegs({{Frds.uw = Frs2s.uw ^ (1UL << 31);}}); + 0x06: fnegd({{Frd.udw = Frs2.udw ^ (1ULL << 63);}}); 0x07: FpUnimpl::fnegq(); - 0x09: fabss({{ - Frds.uw = ((1UL << 31) - 1) & Frs2s.uw; - //fsr.ftt = fsr.cexc = 0 - Fsr &= ~(7 << 14); - Fsr &= ~(0x1F); - }}); - 0x0A: fabsd({{ - Frd.udw = ((1ULL << 63) - 1) & Frs2.udw; - //fsr.ftt = fsr.cexc = 0 - Fsr &= ~(7 << 14); - Fsr &= ~(0x1F); - }}); + 0x09: fabss({{Frds.uw = ((1UL << 31) - 1) & Frs2s.uw;}}); + 0x0A: fabsd({{Frd.udw = ((1ULL << 63) - 1) & Frs2.udw;}}); 0x0B: FpUnimpl::fabsq(); 0x29: fsqrts({{Frds.sf = std::sqrt(Frs2s.sf);}}); 0x2A: fsqrtd({{Frd.df = std::sqrt(Frs2.df);}}); @@ -774,28 +555,16 @@ decode OP default Unknown::unknown() 0x4F: FpUnimpl::fdivq(); 0x69: fsmuld({{Frd.df = Frs1s.sf * Frs2s.sf;}}); 0x6E: FpUnimpl::fdmulq(); - 0x81: fstox({{ - Frd.sdw = static_cast<int64_t>(Frs2s.sf); - }}); - 0x82: fdtox({{ - Frd.sdw = static_cast<int64_t>(Frs2.df); - }}); + 0x81: fstox({{Frd.sdw = static_cast<int64_t>(Frs2s.sf);}}); + 0x82: fdtox({{Frd.sdw = static_cast<int64_t>(Frs2.df);}}); 0x83: FpUnimpl::fqtox(); - 0x84: fxtos({{ - Frds.sf = static_cast<float>(Frs2.sdw); - }}); - 0x88: fxtod({{ - Frd.df = static_cast<double>(Frs2.sdw); - }}); + 0x84: fxtos({{Frds.sf = static_cast<float>(Frs2.sdw);}}); + 0x88: fxtod({{Frd.df = static_cast<double>(Frs2.sdw);}}); 0x8C: FpUnimpl::fxtoq(); - 0xC4: fitos({{ - Frds.sf = static_cast<float>(Frs2s.sw); - }}); + 0xC4: fitos({{Frds.sf = static_cast<float>(Frs2s.sw);}}); 0xC6: fdtos({{Frds.sf = Frs2.df;}}); 0xC7: FpUnimpl::fqtos(); - 0xC8: fitod({{ - Frd.df = static_cast<double>(Frs2s.sw); - }}); + 0xC8: fitod({{Frd.df = static_cast<double>(Frs2s.sw);}}); 0xC9: fstod({{Frd.df = Frs2s.sf;}}); 0xCB: FpUnimpl::fqtod(); 0xCC: FpUnimpl::fitoq(); @@ -1280,9 +1049,6 @@ decode OP default Unknown::unknown() }}); 0x3E: decode FCN { 0x0: Priv::done({{ - if(Tl == 0) - return new IllegalInstruction; - Cwp = Tstate<4:0>; Pstate = Tstate<20:8>; Asi = Tstate<31:24>; @@ -1292,10 +1058,8 @@ decode OP default Unknown::unknown() NPC = Tnpc; NNPC = Tnpc + 4; Tl = Tl - 1; - }}); + }}, checkTl=true); 0x1: Priv::retry({{ - if(Tl == 0) - return new IllegalInstruction; Cwp = Tstate<4:0>; Pstate = Tstate<20:8>; Asi = Tstate<31:24>; @@ -1305,7 +1069,7 @@ decode OP default Unknown::unknown() NPC = Tpc; NNPC = Tnpc; Tl = Tl - 1; - }}); + }}, checkTl=true); } } } @@ -1352,76 +1116,75 @@ decode OP default Unknown::unknown() Rd.uw = tmp; }}, MEM_SWAP); format LoadAlt { - 0x10: lduwa({{Rd = Mem.uw;}}, {{EXT_ASI}}); - 0x11: lduba({{Rd = Mem.ub;}}, {{EXT_ASI}}); - 0x12: lduha({{Rd = Mem.uhw;}}, {{EXT_ASI}}); + 0x10: lduwa({{Rd = Mem.uw;}}); + 0x11: lduba({{Rd = Mem.ub;}}); + 0x12: lduha({{Rd = Mem.uhw;}}); 0x13: decode EXT_ASI { //ASI_LDTD_AIUP 0x22: TwinLoad::ldtx_aiup( {{RdLow.udw = (Mem.tudw).a; - RdHigh.udw = (Mem.tudw).b;}}, {{EXT_ASI}}); + RdHigh.udw = (Mem.tudw).b;}}); //ASI_LDTD_AIUS 0x23: TwinLoad::ldtx_aius( {{RdLow.udw = (Mem.tudw).a; - RdHigh.udw = (Mem.tudw).b;}}, {{EXT_ASI}}); + RdHigh.udw = (Mem.tudw).b;}}); //ASI_QUAD_LDD 0x24: TwinLoad::ldtx_quad_ldd( {{RdLow.udw = (Mem.tudw).a; - RdHigh.udw = (Mem.tudw).b;}}, {{EXT_ASI}}); + RdHigh.udw = (Mem.tudw).b;}}); //ASI_LDTX_REAL 0x26: TwinLoad::ldtx_real( {{RdLow.udw = (Mem.tudw).a; - RdHigh.udw = (Mem.tudw).b;}}, {{EXT_ASI}}); + RdHigh.udw = (Mem.tudw).b;}}); //ASI_LDTX_N 0x27: TwinLoad::ldtx_n( {{RdLow.udw = (Mem.tudw).a; - RdHigh.udw = (Mem.tudw).b;}}, {{EXT_ASI}}); + RdHigh.udw = (Mem.tudw).b;}}); //ASI_LDTX_AIUP_L 0x2A: TwinLoad::ldtx_aiup_l( {{RdLow.udw = (Mem.tudw).a; - RdHigh.udw = (Mem.tudw).b;}}, {{EXT_ASI}}); + RdHigh.udw = (Mem.tudw).b;}}); //ASI_LDTX_AIUS_L 0x2B: TwinLoad::ldtx_aius_l( {{RdLow.udw = (Mem.tudw).a; - RdHigh.udw = (Mem.tudw).b;}}, {{EXT_ASI}}); + RdHigh.udw = (Mem.tudw).b;}}); //ASI_LDTX_L 0x2C: TwinLoad::ldtx_l( {{RdLow.udw = (Mem.tudw).a; - RdHigh.udw = (Mem.tudw).b;}}, {{EXT_ASI}}); + RdHigh.udw = (Mem.tudw).b;}}); //ASI_LDTX_REAL_L 0x2E: TwinLoad::ldtx_real_l( {{RdLow.udw = (Mem.tudw).a; - RdHigh.udw = (Mem.tudw).b;}}, {{EXT_ASI}}); + RdHigh.udw = (Mem.tudw).b;}}); //ASI_LDTX_N_L 0x2F: TwinLoad::ldtx_n_l( {{RdLow.udw = (Mem.tudw).a; - RdHigh.udw = (Mem.tudw).b;}}, {{EXT_ASI}}); + RdHigh.udw = (Mem.tudw).b;}}); //ASI_LDTX_P 0xE2: TwinLoad::ldtx_p( {{RdLow.udw = (Mem.tudw).a; - RdHigh.udw = (Mem.tudw).b;}}, {{EXT_ASI}}); + RdHigh.udw = (Mem.tudw).b;}}); //ASI_LDTX_S 0xE3: TwinLoad::ldtx_s( {{RdLow.udw = (Mem.tudw).a; - RdHigh.udw = (Mem.tudw).b;}}, {{EXT_ASI}}); + RdHigh.udw = (Mem.tudw).b;}}); //ASI_LDTX_PL 0xEA: TwinLoad::ldtx_pl( {{RdLow.udw = (Mem.tudw).a; - RdHigh.udw = (Mem.tudw).b;}}, {{EXT_ASI}}); + RdHigh.udw = (Mem.tudw).b;}}); //ASI_LDTX_SL 0xEB: TwinLoad::ldtx_sl( {{RdLow.udw = (Mem.tudw).a; - RdHigh.udw = (Mem.tudw).b;}}, {{EXT_ASI}}); + RdHigh.udw = (Mem.tudw).b;}}); default: ldtwa({{ RdLow = (Mem.tuw).a; - RdHigh = (Mem.tuw).b; - }}, {{EXT_ASI}}); + RdHigh = (Mem.tuw).b;}}); } } format StoreAlt { - 0x14: stwa({{Mem.uw = Rd;}}, {{EXT_ASI}}); - 0x15: stba({{Mem.ub = Rd;}}, {{EXT_ASI}}); - 0x16: stha({{Mem.uhw = Rd;}}, {{EXT_ASI}}); + 0x14: stwa({{Mem.uw = Rd;}}); + 0x15: stba({{Mem.ub = Rd;}}); + 0x16: stha({{Mem.uhw = Rd;}}); 0x17: sttwa({{ //This temporary needs to be here so that the parser //will correctly identify this instruction as a store. @@ -1431,25 +1194,25 @@ decode OP default Unknown::unknown() temp.a = RdLow<31:0>; temp.b = RdHigh<31:0>; Mem.tuw = temp; - }}, {{EXT_ASI}}); + }}); } format LoadAlt { - 0x18: ldswa({{Rd = (int32_t)Mem.sw;}}, {{EXT_ASI}}); - 0x19: ldsba({{Rd = (int8_t)Mem.sb;}}, {{EXT_ASI}}); - 0x1A: ldsha({{Rd = (int16_t)Mem.shw;}}, {{EXT_ASI}}); - 0x1B: ldxa({{Rd = (int64_t)Mem.sdw;}}, {{EXT_ASI}}); + 0x18: ldswa({{Rd = (int32_t)Mem.sw;}}); + 0x19: ldsba({{Rd = (int8_t)Mem.sb;}}); + 0x1A: ldsha({{Rd = (int16_t)Mem.shw;}}); + 0x1B: ldxa({{Rd = (int64_t)Mem.sdw;}}); } 0x1D: SwapAlt::ldstuba({{Mem.ub = 0xFF;}}, {{ uint8_t tmp = mem_data; Rd.ub = tmp; - }}, {{EXT_ASI}}, MEM_SWAP); - 0x1E: StoreAlt::stxa({{Mem.udw = Rd}}, {{EXT_ASI}}); + }}, MEM_SWAP); + 0x1E: StoreAlt::stxa({{Mem.udw = Rd}}); 0x1F: SwapAlt::swapa({{Mem.uw = Rd.uw}}, {{ uint32_t tmp = mem_data; Rd.uw = tmp; - }}, {{EXT_ASI}}, MEM_SWAP); + }}, MEM_SWAP); format Trap { 0x20: Load::ldf({{Frds.uw = Mem.uw;}}); @@ -1483,7 +1246,7 @@ decode OP default Unknown::unknown() 0x26: stqf({{fault = new FpDisabled;}}); 0x27: Store::stdf({{Mem.udw = Frd.udw;}}); 0x2D: Nop::prefetch({{ }}); - 0x30: LoadAlt::ldfa({{Frds.uw = Mem.uw;}}, {{EXT_ASI}}); + 0x30: LoadAlt::ldfa({{Frds.uw = Mem.uw;}}); 0x32: ldqfa({{fault = new FpDisabled;}}); format LoadAlt { 0x33: decode EXT_ASI { @@ -1535,7 +1298,7 @@ decode OP default Unknown::unknown() //ASI_BLOCK_AS_IF_USER_SECONDARY_LITTLE 0x1F: FailUnimpl::ldblockf_aiusl(); //ASI_BLOCK_PRIMARY - 0xF0: ldblockf_p({{Frd_N.udw = Mem.udw;}}, {{EXT_ASI}}); + 0xF0: ldblockf_p({{Frd_N.udw = Mem.udw;}}); //ASI_BLOCK_SECONDARY 0xF1: FailUnimpl::ldblockf_s(); //ASI_BLOCK_PRIMARY_LITTLE @@ -1618,7 +1381,7 @@ decode OP default Unknown::unknown() //ASI_BLOCK_AS_IF_USER_SECONDARY_LITTLE 0x1F: FailUnimpl::stblockf_aiusl(); //ASI_BLOCK_PRIMARY - 0xF0: stblockf_p({{Mem.udw = Frd_N.udw;}}, {{EXT_ASI}}); + 0xF0: stblockf_p({{Mem.udw = Frd_N.udw;}}); //ASI_BLOCK_SECONDARY 0xF1: FailUnimpl::stblockf_s(); //ASI_BLOCK_PRIMARY_LITTLE @@ -1655,11 +1418,11 @@ decode OP default Unknown::unknown() {{ uint32_t tmp = mem_data; Rd.uw = tmp; - }}, {{EXT_ASI}}, MEM_SWAP_COND); + }}, MEM_SWAP_COND); 0x3D: Nop::prefetcha({{ }}); 0x3E: CasAlt::casxa({{mem_data = gtoh(Rs2); Mem.udw = Rd.udw; }}, - {{ Rd.udw = mem_data; }}, {{EXT_ASI}}, MEM_SWAP_COND); + {{ Rd.udw = mem_data; }}, MEM_SWAP_COND); } } } diff --git a/src/arch/sparc/isa/formats/basic.isa b/src/arch/sparc/isa/formats/basic.isa index 5b0868132..cad759b3e 100644 --- a/src/arch/sparc/isa/formats/basic.isa +++ b/src/arch/sparc/isa/formats/basic.isa @@ -56,6 +56,20 @@ def template BasicDeclare {{ }; }}; +// Basic instruction class declaration template. +def template BasicDeclareWithMnemonic {{ + /** + * Static instruction class for "%(mnemonic)s". + */ + class %(class_name)s : public %(base_class)s + { + public: + // Constructor. + %(class_name)s(const char * mnemonic, ExtMachInst machInst); + %(BasicExecDeclare)s + }; +}}; + // Basic instruction class constructor template. def template BasicConstructor {{ inline %(class_name)s::%(class_name)s(ExtMachInst machInst) @@ -65,6 +79,16 @@ def template BasicConstructor {{ } }}; +// Basic instruction class constructor template. +def template BasicConstructorWithMnemonic {{ + inline %(class_name)s::%(class_name)s(const char * mnemonic, + ExtMachInst machInst) + : %(base_class)s(mnemonic, 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, diff --git a/src/arch/sparc/isa/formats/branch.isa b/src/arch/sparc/isa/formats/branch.isa index f5ab940bb..faaee8842 100644 --- a/src/arch/sparc/isa/formats/branch.isa +++ b/src/arch/sparc/isa/formats/branch.isa @@ -183,7 +183,7 @@ output decoder {{ } }}; -def template BranchExecute {{ +def template JumpExecute {{ Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const { @@ -206,65 +206,135 @@ def template BranchExecute {{ } }}; -let {{ - handle_annul = ''' - { - if(A) - { - NNPC = NPC + 8; - NPC = NPC + 4; - } - else +def template BranchExecute {{ + Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const { - NPC = NPC; - NNPC = NNPC; + //Attempt to execute the instruction + Fault fault = NoFault; + + %(op_decl)s; + %(op_rd)s; + + if (%(cond)s) { + %(code)s; + } else { + %(fail)s; + } + + if(fault == NoFault) + { + //Write the resulting state to the execution context + %(op_wb)s; + } + + return fault; } - }''' +}}; + +def template BranchDecode {{ + if (A) + return new %(class_name)sAnnul("%(mnemonic)s,a", machInst); + else + return new %(class_name)s("%(mnemonic)s", machInst); }}; // Primary format for branch instructions: def format Branch(code, *opt_flags) {{ - (usesImm, code, immCode, - rString, iString) = splitOutImm(code) - iop = InstObjParams(name, Name, 'Branch', code, opt_flags) - header_output = BasicDeclare.subst(iop) - decoder_output = BasicConstructor.subst(iop) + (usesImm, code, immCode, + rString, iString) = splitOutImm(code) + iop = InstObjParams(name, Name, 'Branch', code, opt_flags) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + exec_output = JumpExecute.subst(iop) + if usesImm: + imm_iop = InstObjParams(name, Name + 'Imm', 'BranchImm' + iString, + immCode, opt_flags) + header_output += BasicDeclare.subst(imm_iop) + decoder_output += BasicConstructor.subst(imm_iop) + exec_output += JumpExecute.subst(imm_iop) + decode_block = ROrImmDecode.subst(iop) + else: + decode_block = BasicDecode.subst(iop) +}}; + +let {{ + def doBranch(name, Name, base, cond, + code, annul_code, fail, annul_fail, opt_flags): + iop = InstObjParams(name, Name, base, + {"code": code, + "fail": fail, + "cond": cond + }, + opt_flags) + header_output = BasicDeclareWithMnemonic.subst(iop) + decoder_output = BasicConstructorWithMnemonic.subst(iop) exec_output = BranchExecute.subst(iop) - if usesImm: - imm_iop = InstObjParams(name, Name + 'Imm', 'BranchImm' + iString, - immCode, opt_flags) - header_output += BasicDeclare.subst(imm_iop) - decoder_output += BasicConstructor.subst(imm_iop) - exec_output += BranchExecute.subst(imm_iop) - decode_block = ROrImmDecode.subst(iop) + if annul_code == "None": + decode_block = BasicDecodeWithMnemonic.subst(iop) else: - decode_block = BasicDecode.subst(iop) + decode_block = BranchDecode.subst(iop) + + if annul_code != "None": + iop = InstObjParams(name + ',a', Name + 'Annul', base, + {"code": annul_code, + "fail": annul_fail, + "cond": cond + }, + opt_flags) + header_output += BasicDeclareWithMnemonic.subst(iop) + decoder_output += BasicConstructorWithMnemonic.subst(iop) + exec_output += BranchExecute.subst(iop) + return (header_output, decoder_output, exec_output, decode_block) + + def doCondBranch(name, Name, base, cond, code, opt_flags): + return doBranch(name, Name, base, cond, code, code, + 'NPC = NPC; NNPC = NNPC;', + 'NNPC = NPC + 8; NPC = NPC + 4', + opt_flags) + + def doUncondBranch(name, Name, base, code, annul_code, opt_flags): + return doBranch(name, Name, base, "true", code, annul_code, + ";", ";", opt_flags) + + default_branch_code = "NNPC = xc->readPC() + disp;" }}; -// Primary format for branch instructions: -def format BranchN(bits, code, *opt_flags) {{ - code = re.sub(r'handle_annul', handle_annul, code) - new_opt_flags = [] - for flag in opt_flags: - if flag == ',a': - name += ',a' - Name += 'Annul' - else: - new_opt_flags += flag - iop = InstObjParams(name, Name, "BranchNBits<%d>" % bits, code, new_opt_flags) - header_output = BasicDeclare.subst(iop) - decoder_output = BasicConstructor.subst(iop) - exec_output = BranchExecute.subst(iop) - decode_block = BasicDecode.subst(iop) +// Format for branch instructions with n bit displacements: +def format BranchN(bits, code=default_branch_code, + test=None, annul_code=None, *opt_flags) {{ + if code == "default_branch_code": + code = default_branch_code + if test != "None": + (header_output, + decoder_output, + exec_output, + decode_block) = doCondBranch(name, Name, + "BranchNBits<%d>" % bits, test, code, opt_flags) + else: + (header_output, + decoder_output, + exec_output, + decode_block) = doUncondBranch(name, Name, + "BranchNBits<%d>" % bits, code, annul_code, opt_flags) }}; -// Primary format for branch instructions: -def format BranchSplit(code, *opt_flags) {{ - code = re.sub(r'handle_annul', handle_annul, code) - iop = InstObjParams(name, Name, 'BranchSplit', code, opt_flags) - header_output = BasicDeclare.subst(iop) - decoder_output = BasicConstructor.subst(iop) - exec_output = BranchExecute.subst(iop) - decode_block = BasicDecode.subst(iop) +// Format for branch instructions with split displacements: +def format BranchSplit(code=default_branch_code, + test=None, annul_code=None, *opt_flags) {{ + if code == "default_branch_code": + code = default_branch_code + if test != "None": + (header_output, + decoder_output, + exec_output, + decode_block) = doCondBranch(name, Name, + "BranchSplit", test, code, opt_flags) + else: + (header_output, + decoder_output, + exec_output, + decode_block) = doUncondBranch(name, Name, + "BranchSplit", code, annul_code, opt_flags) }}; diff --git a/src/arch/sparc/isa/formats/integerop.isa b/src/arch/sparc/isa/formats/integerop.isa index f877b8790..55af7e5b3 100644 --- a/src/arch/sparc/isa/formats/integerop.isa +++ b/src/arch/sparc/isa/formats/integerop.isa @@ -287,10 +287,10 @@ let {{ _iz = ((Rd & 0xFFFFFFFF) == 0); _xn = (Rd >> 63) & 1; _xz = (Rd == 0); - _iv = %(ivValue)s & 1; - _ic = %(icValue)s & 1; - _xv = %(xvValue)s & 1; - _xc = %(xcValue)s & 1; + _iv = %(iv)s & 1; + _ic = %(ic)s & 1; + _xv = %(xv)s & 1; + _xc = %(xc)s & 1; Ccr = _ic << 0 | _iv << 1 | _iz << 2 | _in << 3 | _xc << 4 | _xv << 5 | _xz << 6 | _xn << 7; @@ -305,6 +305,15 @@ let {{ DPRINTF(Sparc, "xv = %%d\\n", _xv); DPRINTF(Sparc, "xc = %%d\\n", _xc); ''' + + default_ic = "findCarry(32, res, op1, op2)" + default_iv = "findOverflow(32, res, op1, op2)" + default_xc = "findCarry(64, res, op1, op2)" + default_xv = "findOverflow(64, res, op1, op2)" + default_sub_ic = "!findCarry(32, res, op1, ~op2)" + default_sub_iv = "findOverflow(32, res, op1, ~op2)" + default_sub_xc = "!findCarry(64, res, op1, ~op2)" + default_sub_xv = "findOverflow(64, res, op1, ~op2)" }}; // Primary format for integer operate instructions: @@ -318,7 +327,24 @@ def format IntOp(code, *opt_flags) {{ }}; // Primary format for integer operate instructions: -def format IntOpCc(code, icValue, ivValue, xcValue, xvValue, *opt_flags) {{ +def format IntOpCc(code, ic=default_ic, iv=default_iv, + xc=default_xc, xv=default_xv, + sub=False, *opt_flags) {{ + + if sub == "False": + (def_ic, def_iv, def_xc, def_xv) = \ + (default_ic, default_iv, default_xc, default_xv) + else: + (def_ic, def_iv, def_xc, def_xv) = \ + (default_sub_ic, default_sub_iv, default_sub_xc, default_sub_xv) + if ic == "default_ic": + ic = def_ic + if iv == "default_iv": + iv = def_iv + if xc == "default_xc": + xc = def_xc + if xv == "default_xv": + xv = def_xv ccCode = calcCcCode % vars() (header_output, decoder_output, @@ -328,11 +354,8 @@ def format IntOpCc(code, icValue, ivValue, xcValue, xvValue, *opt_flags) {{ }}; // Primary format for integer operate instructions: -def format IntOpCcRes(code, *opt_flags) {{ - ccCode = calcCcCode % {"icValue":"0", - "ivValue":"0", - "xcValue":"0", - "xvValue":"0"} +def format IntOpCcRes(code, ic=0, iv=0, xc=0, xv=0, *opt_flags) {{ + ccCode = calcCcCode % {"ic" : ic, "iv" : iv, "xc" : xc, "xv" : xv} (header_output, decoder_output, exec_output, diff --git a/src/arch/sparc/isa/formats/mem/basicmem.isa b/src/arch/sparc/isa/formats/mem/basicmem.isa index aa6c4cdea..e3c043cf3 100644 --- a/src/arch/sparc/isa/formats/mem/basicmem.isa +++ b/src/arch/sparc/isa/formats/mem/basicmem.isa @@ -72,22 +72,22 @@ let {{ return (header_output, decoder_output, exec_output, decode_block) }}; -def format LoadAlt(code, asi, *opt_flags) {{ +def format LoadAlt(code, *opt_flags) {{ code = filterDoubles(code) (header_output, decoder_output, exec_output, decode_block) = doMemFormat(code, LoadFuncs, - AlternateASIPrivFaultCheck, name, Name, asi, opt_flags) + AlternateASIPrivFaultCheck, name, Name, "EXT_ASI", opt_flags) }}; -def format StoreAlt(code, asi, *opt_flags) {{ +def format StoreAlt(code, *opt_flags) {{ code = filterDoubles(code) (header_output, decoder_output, exec_output, decode_block) = doMemFormat(code, StoreFuncs, - AlternateASIPrivFaultCheck, name, Name, asi, opt_flags) + AlternateASIPrivFaultCheck, name, Name, "EXT_ASI", opt_flags) }}; def format Load(code, *opt_flags) {{ @@ -108,12 +108,12 @@ def format Store(code, *opt_flags) {{ StoreFuncs, '', name, Name, 0, opt_flags) }}; -def format TwinLoad(code, asi, *opt_flags) {{ +def format TwinLoad(code, *opt_flags) {{ (header_output, decoder_output, exec_output, decode_block) = doMemFormat(code, LoadFuncs, AlternateASIPrivFaultCheck + TwinAlignmentFaultCheck, - name, Name, asi, opt_flags) + name, Name, "EXT_ASI", opt_flags) }}; diff --git a/src/arch/sparc/isa/formats/mem/blockmem.isa b/src/arch/sparc/isa/formats/mem/blockmem.isa index 5d36e5e41..020dc326f 100644 --- a/src/arch/sparc/isa/formats/mem/blockmem.isa +++ b/src/arch/sparc/isa/formats/mem/blockmem.isa @@ -273,7 +273,7 @@ def template BlockMemMicroConstructor {{ let {{ - def doBlockMemFormat(code, faultCode, execute, name, Name, asi, opt_flags): + def doBlockMemFormat(code, faultCode, execute, name, Name, opt_flags): # XXX Need to take care of pstate.hpriv as well. The lower ASIs # are split into ones that are available in priv and hpriv, and # those that are only available in hpriv @@ -313,12 +313,12 @@ let {{ makeMicroName(name + "Imm", microPc), makeMicroName(Name, microPc), makeMicroName(Name + "Imm", microPc), - asi, opt_flags); + "EXT_ASI", opt_flags); faultCode = '' return (header_output, decoder_output, exec_output, decode_block) }}; -def format BlockLoad(code, asi, *opt_flags) {{ +def format BlockLoad(code, *opt_flags) {{ code = filterDoubles(code) # We need to make sure to check the highest priority fault last. # That way, if other faults have been detected, they'll be overwritten @@ -328,10 +328,10 @@ def format BlockLoad(code, asi, *opt_flags) {{ decoder_output, exec_output, decode_block) = doBlockMemFormat(code, faultCode, - LoadFuncs, name, Name, asi, opt_flags) + LoadFuncs, name, Name, opt_flags) }}; -def format BlockStore(code, asi, *opt_flags) {{ +def format BlockStore(code, *opt_flags) {{ code = filterDoubles(code) # We need to make sure to check the highest priority fault last. # That way, if other faults have been detected, they'll be overwritten @@ -341,5 +341,5 @@ def format BlockStore(code, asi, *opt_flags) {{ decoder_output, exec_output, decode_block) = doBlockMemFormat(code, faultCode, - StoreFuncs, name, Name, asi, opt_flags) + StoreFuncs, name, Name, opt_flags) }}; diff --git a/src/arch/sparc/isa/formats/mem/swap.isa b/src/arch/sparc/isa/formats/mem/swap.isa index dde327f5c..2ebe9aa15 100644 --- a/src/arch/sparc/isa/formats/mem/swap.isa +++ b/src/arch/sparc/isa/formats/mem/swap.isa @@ -142,9 +142,9 @@ def format Swap(code, postacc_code, mem_flags, *opt_flags) {{ ["IsStoreConditional"], postacc_code) }}; -def format SwapAlt(code, postacc_code, asi, mem_flags, *opt_flags) {{ +def format SwapAlt(code, postacc_code, mem_flags, *opt_flags) {{ mem_flags = makeList(mem_flags) - mem_flags.append(asi) + mem_flags.append("EXT_ASI") flags = string.join(mem_flags, '|') (header_output, decoder_output, @@ -155,7 +155,7 @@ def format SwapAlt(code, postacc_code, asi, mem_flags, *opt_flags) {{ let {{ - def doCasFormat(code, execute, faultCode, name, Name, asi, opt_flags, postacc_code = ''): + def doCasFormat(code, execute, faultCode, name, Name, mem_flags, opt_flags, postacc_code = ''): addrCalcReg = 'EA = Rs1;' iop = InstObjParams(name, Name, 'Mem', {"code": code, "postacc_code" : postacc_code, @@ -167,15 +167,15 @@ let {{ microParams = {"code": code, "postacc_code" : postacc_code, "ea_code" : addrCalcReg, "fault_check" : faultCode, "EA_trunc" : TruncateEA} - exec_output = doSplitExecute(execute, name, Name, asi, + exec_output = doSplitExecute(execute, name, Name, mem_flags, ["IsStoreConditional"], microParams); return (header_output, decoder_output, exec_output, decode_block) }}; -def format CasAlt(code, postacc_code, asi, mem_flags, *opt_flags) {{ +def format CasAlt(code, postacc_code, mem_flags, *opt_flags) {{ mem_flags = makeList(mem_flags) - mem_flags.append(asi) + mem_flags.append("EXT_ASI") flags = string.join(mem_flags, '|') (header_output, decoder_output, diff --git a/src/arch/sparc/isa/formats/priv.isa b/src/arch/sparc/isa/formats/priv.isa index 36403afb4..795a22958 100644 --- a/src/arch/sparc/isa/formats/priv.isa +++ b/src/arch/sparc/isa/formats/priv.isa @@ -1,4 +1,4 @@ -// Copyright (c) 2006 The Regents of The University of Michigan +// Copyright (c) 2006-2007 The Regents of The University of Michigan // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -207,6 +207,9 @@ def template PrivExecute {{ if(%(check)s) return new PrivilegedAction; + if(%(tlCheck)s) + return new IllegalInstruction; + Fault fault = NoFault; %(code)s; %(op_wb)s; @@ -215,7 +218,7 @@ def template PrivExecute {{ }}; let {{ - def doPrivFormat(code, checkCode, name, Name, opt_flags): + def doPrivFormat(code, checkCode, name, Name, tlCheck, opt_flags): (usesImm, code, immCode, rString, iString) = splitOutImm(code) #If these are rd, rdpr, rdhpr, wr, wrpr, or wrhpr instructions, @@ -236,7 +239,8 @@ let {{ regBase = 'WrPriv' break iop = InstObjParams(name, Name, regBase, - {"code": code, "check": checkCode, "reg_name": regName}, + {"code": code, "check": checkCode, + "tlCheck": tlCheck, "reg_name": regName}, opt_flags) header_output = BasicDeclare.subst(iop) if regName == '': @@ -246,7 +250,8 @@ let {{ exec_output = PrivExecute.subst(iop) if usesImm: imm_iop = InstObjParams(name, Name + 'Imm', regBase + 'Imm', - {"code": immCode, "check": checkCode, "reg_name": regName}, + {"code": immCode, "check": checkCode, + "tlCheck": tlCheck, "reg_name": regName}, opt_flags) header_output += BasicDeclare.subst(imm_iop) if regName == '': @@ -260,34 +265,39 @@ let {{ return (header_output, decoder_output, exec_output, decode_block) }}; -def format Priv(code, *opt_flags) {{ - checkCode = "!(Pstate<2:> || Hpstate<2:>)" +def format Priv(code, extraCond=true, checkTl=false, *opt_flags) {{ + checkCode = "(%s) && !(Pstate<2:> || Hpstate<2:>)" % extraCond + if checkTl != "false": + tlCheck = "Tl == 0" + else: + tlCheck = "false" (header_output, decoder_output, exec_output, decode_block) = doPrivFormat(code, - checkCode, name, Name, opt_flags) + checkCode, name, Name, tlCheck, opt_flags) }}; -def format NoPriv(code, *opt_flags) {{ +def format NoPriv(code, checkTl=false, *opt_flags) {{ #Instructions which use this format don't really check for #any particular mode, but the disassembly is performed #using the control registers actual name checkCode = "false" + if checkTl != "false": + tlCheck = "Tl == 0" + else: + tlCheck = "false" (header_output, decoder_output, exec_output, decode_block) = doPrivFormat(code, - checkCode, name, Name, opt_flags) -}}; - -def format PrivCheck(code, extraCheckCode, *opt_flags) {{ - checkCode = "(%s) && !(Pstate<2:> || Hpstate<2:>)" % extraCheckCode - (header_output, decoder_output, - exec_output, decode_block) = doPrivFormat(code, - checkCode, name, Name, opt_flags) + checkCode, name, Name, tlCheck, opt_flags) }}; -def format HPriv(code, *opt_flags) {{ +def format HPriv(code, checkTl=false, *opt_flags) {{ checkCode = "!Hpstate<2:2>" + if checkTl != "false": + tlCheck = "Tl == 0" + else: + tlCheck = "false" (header_output, decoder_output, exec_output, decode_block) = doPrivFormat(code, - checkCode, name, Name, opt_flags) + checkCode, name, Name, tlCheck, opt_flags) }}; diff --git a/src/arch/sparc/isa/includes.isa b/src/arch/sparc/isa/includes.isa index e9cd660b5..135bd58c3 100644 --- a/src/arch/sparc/isa/includes.isa +++ b/src/arch/sparc/isa/includes.isa @@ -41,6 +41,7 @@ output header {{ #include "arch/sparc/faults.hh" #include "arch/sparc/isa_traits.hh" #include "arch/sparc/regfile.hh" +#include "base/condcodes.hh" #include "base/misc.hh" #include "cpu/static_inst.hh" #include "mem/packet.hh" diff --git a/src/base/condcodes.hh b/src/base/condcodes.hh index efff12dc8..98defdb70 100644 --- a/src/base/condcodes.hh +++ b/src/base/condcodes.hh @@ -54,7 +54,7 @@ inline bool findOverflow(int width, uint64_t dest, uint64_t src1, uint64_t src2) { int shift = width - 1; - return ((src1 ^ ~src2) & (src1 ^ dest)) & (1 << shift); + return ((src1 ^ ~src2) & (src1 ^ dest)) & (1ULL << shift); } /** diff --git a/src/base/loader/elf_object.cc b/src/base/loader/elf_object.cc index ecce175b2..553723e74 100644 --- a/src/base/loader/elf_object.cc +++ b/src/base/loader/elf_object.cc @@ -216,50 +216,76 @@ ElfObject::ElfObject(const string &_filename, int _fd, entry = ehdr.e_entry; - // initialize segment sizes to 0 in case they're not present text.size = data.size = bss.size = 0; + int secIdx = 1; + Elf_Scn *section; + GElf_Shdr shdr; + + // The first address of some important sections. + Addr textSecStart = 0; + Addr dataSecStart = 0; + Addr bssSecStart = 0; + + // Get the first section + section = elf_getscn(elf, secIdx); + + // Find the beginning of the most interesting sections. + while (section != NULL) { + gelf_getshdr(section, &shdr); + char * secName = elf_strptr(elf, ehdr.e_shstrndx, shdr.sh_name); + + if (!strcmp(".text", secName)) { + textSecStart = shdr.sh_addr; + } else if (!strcmp(".data", secName)) { + dataSecStart = shdr.sh_addr; + } else if (!strcmp(".bss", secName)) { + bssSecStart = shdr.sh_addr; + } + + section = elf_getscn(elf, ++secIdx); + } + + // Go through all the segments in the program, record them, and scrape + // out information about the text, data, and bss areas needed by other + // code. for (int i = 0; i < ehdr.e_phnum; ++i) { GElf_Phdr phdr; if (gelf_getphdr(elf, i, &phdr) == 0) { - panic("gelf_getphdr failed for section %d", i); + panic("gelf_getphdr failed for segment %d.", i); } // for now we don't care about non-loadable segments if (!(phdr.p_type & PT_LOAD)) continue; - // the headers don't explicitly distinguish text from data, - // but empirically the text segment comes first. - if (text.size == 0) { // haven't seen text segment yet + // Check to see if this segment contains the bss section. + if (phdr.p_vaddr <= bssSecStart && + phdr.p_vaddr + phdr.p_memsz > bssSecStart && + phdr.p_memsz - phdr.p_filesz > 0) { + bss.baseAddr = phdr.p_vaddr + phdr.p_filesz; + bss.size = phdr.p_memsz - phdr.p_filesz; + bss.fileImage = NULL; + } + + // Check to see if this is the text or data segment + if (phdr.p_vaddr <= textSecStart && + phdr.p_vaddr + phdr.p_filesz > textSecStart) { text.baseAddr = phdr.p_vaddr; text.size = phdr.p_filesz; text.fileImage = fileData + phdr.p_offset; - // if there's any padding at the end that's not in the - // file, call it the bss. This happens in the "text" - // segment if there's only one loadable segment (as for - // kernel images). - bss.size = phdr.p_memsz - phdr.p_filesz; - bss.baseAddr = phdr.p_vaddr + phdr.p_filesz; - bss.fileImage = NULL; - } else if (data.size == 0) { // have text, this must be data + } else if (phdr.p_vaddr <= dataSecStart && + phdr.p_vaddr + phdr.p_filesz > dataSecStart) { data.baseAddr = phdr.p_vaddr; data.size = phdr.p_filesz; data.fileImage = fileData + phdr.p_offset; - // if there's any padding at the end that's not in the - // file, call it the bss. Warn if this happens for both - // the text & data segments (should only have one bss). - if (phdr.p_memsz - phdr.p_filesz > 0 && bss.size != 0) { - warn("Two implied bss segments in file!\n"); - } - bss.size = phdr.p_memsz - phdr.p_filesz; - bss.baseAddr = phdr.p_vaddr + phdr.p_filesz; - bss.fileImage = NULL; } else { - warn("More than two loadable segments in ELF object."); - warn("Ignoring segment @ 0x%x length 0x%x.", - phdr.p_vaddr, phdr.p_filesz); + Segment extra; + extra.baseAddr = phdr.p_vaddr; + extra.size = phdr.p_filesz; + extra.fileImage = fileData + phdr.p_offset; + extraSegments.push_back(extra); } } @@ -343,6 +369,22 @@ ElfObject::loadLocalSymbols(SymbolTable *symtab, Addr addrMask) return loadSomeSymbols(symtab, STB_LOCAL); } +bool +ElfObject::loadSections(Port *memPort, Addr addrMask) +{ + if (!ObjectFile::loadSections(memPort, addrMask)) + return false; + + vector<Segment>::iterator extraIt; + for (extraIt = extraSegments.begin(); + extraIt != extraSegments.end(); extraIt++) { + if (!loadSection(&(*extraIt), memPort, addrMask)) { + return false; + } + } + return true; +} + void ElfObject::getSections() { diff --git a/src/base/loader/elf_object.hh b/src/base/loader/elf_object.hh index 3e7c85874..5c5f6907d 100644 --- a/src/base/loader/elf_object.hh +++ b/src/base/loader/elf_object.hh @@ -33,11 +33,15 @@ #include "base/loader/object_file.hh" #include <set> +#include <vector> class ElfObject : public ObjectFile { protected: + //The global definition of a "Section" is closest to elf's segments. + typedef ObjectFile::Section Segment; + //These values are provided to a linux process by the kernel, so we //need to keep them around. Addr _programHeaderTable; @@ -55,9 +59,13 @@ class ElfObject : public ObjectFile void getSections(); bool sectionExists(std::string sec); + std::vector<Segment> extraSegments; + public: virtual ~ElfObject() {} + bool loadSections(Port *memPort, + Addr addrMask = std::numeric_limits<Addr>::max()); virtual bool loadGlobalSymbols(SymbolTable *symtab, Addr addrMask = std::numeric_limits<Addr>::max()); virtual bool loadLocalSymbols(SymbolTable *symtab, Addr addrMask = diff --git a/src/cpu/simple_thread.hh b/src/cpu/simple_thread.hh index c018e3e49..2b79c9708 100644 --- a/src/cpu/simple_thread.hh +++ b/src/cpu/simple_thread.hh @@ -241,25 +241,25 @@ class SimpleThread : public ThreadState FloatReg readFloatReg(int reg_idx, int width) { - int flatIndex = TheISA::flattenIntIndex(getTC(), reg_idx); + int flatIndex = TheISA::flattenFloatIndex(getTC(), reg_idx); return regs.readFloatReg(flatIndex, width); } FloatReg readFloatReg(int reg_idx) { - int flatIndex = TheISA::flattenIntIndex(getTC(), reg_idx); + int flatIndex = TheISA::flattenFloatIndex(getTC(), reg_idx); return regs.readFloatReg(flatIndex); } FloatRegBits readFloatRegBits(int reg_idx, int width) { - int flatIndex = TheISA::flattenIntIndex(getTC(), reg_idx); + int flatIndex = TheISA::flattenFloatIndex(getTC(), reg_idx); return regs.readFloatRegBits(flatIndex, width); } FloatRegBits readFloatRegBits(int reg_idx) { - int flatIndex = TheISA::flattenIntIndex(getTC(), reg_idx); + int flatIndex = TheISA::flattenFloatIndex(getTC(), reg_idx); return regs.readFloatRegBits(flatIndex); } @@ -271,25 +271,25 @@ class SimpleThread : public ThreadState void setFloatReg(int reg_idx, FloatReg val, int width) { - int flatIndex = TheISA::flattenIntIndex(getTC(), reg_idx); + int flatIndex = TheISA::flattenFloatIndex(getTC(), reg_idx); regs.setFloatReg(flatIndex, val, width); } void setFloatReg(int reg_idx, FloatReg val) { - int flatIndex = TheISA::flattenIntIndex(getTC(), reg_idx); + int flatIndex = TheISA::flattenFloatIndex(getTC(), reg_idx); regs.setFloatReg(flatIndex, val); } void setFloatRegBits(int reg_idx, FloatRegBits val, int width) { - int flatIndex = TheISA::flattenIntIndex(getTC(), reg_idx); + int flatIndex = TheISA::flattenFloatIndex(getTC(), reg_idx); regs.setFloatRegBits(flatIndex, val, width); } void setFloatRegBits(int reg_idx, FloatRegBits val) { - int flatIndex = TheISA::flattenIntIndex(getTC(), reg_idx); + int flatIndex = TheISA::flattenFloatIndex(getTC(), reg_idx); regs.setFloatRegBits(flatIndex, val); } diff --git a/src/sim/process.cc b/src/sim/process.cc index f943cb565..8f36fba1b 100644 --- a/src/sim/process.cc +++ b/src/sim/process.cc @@ -456,13 +456,12 @@ LiveProcess::create(const std::string &nm, System *system, int stdin_fd, "executables are supported!\n Please recompile your " "executable as a static binary and try again.\n"); +#if THE_ISA == ALPHA_ISA if (objFile->hasTLS()) - fatal("Object file has a TLS section and loading of TLS sections " - "are not currently supported!\n Please recompile your " - "executable with a non-TLS toolchain or add TLS support to " - "M5 and try again\n"); + fatal("Object file has a TLS section and single threaded TLS is not\n" + " currently supported for Alpha! Please recompile your " + "executable with \n a non-TLS toolchain.\n"); -#if THE_ISA == ALPHA_ISA if (objFile->getArch() != ObjectFile::Alpha) fatal("Object file architecture does not match compiled ISA (Alpha)."); switch (objFile->getOpSys()) { |