From 4aea5deccb948035459583d811837cb6affd1c07 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 10 Nov 2006 04:02:39 -0500 Subject: Fix up instructions to read and write control registers, and got rid of the control register fields which won't work on a big endian host. --HG-- extra : convert_revision : 1b518873b6e1a073b58cbe27642537d5ae3a604d --- src/arch/sparc/isa/decoder.isa | 197 +++++++++++++++++++++++++++++++----- src/arch/sparc/isa/formats/priv.isa | 24 ++++- src/arch/sparc/isa/includes.isa | 1 + src/arch/sparc/isa/operands.isa | 50 +++++---- 4 files changed, 228 insertions(+), 44 deletions(-) (limited to 'src/arch/sparc/isa') diff --git a/src/arch/sparc/isa/decoder.isa b/src/arch/sparc/isa/decoder.isa index a5f43367d..4f3ea7810 100644 --- a/src/arch/sparc/isa/decoder.isa +++ b/src/arch/sparc/isa/decoder.isa @@ -346,22 +346,93 @@ decode OP default Unknown::unknown() 0x0: sra({{Rd = Rs1.sw >> (I ? SHCNT32 : Rs2<4:0>);}}); 0x1: srax({{Rd = Rs1.sdw >> (I ? SHCNT64 : Rs2<5:0>);}}); } - // XXX might want a format rdipr thing here 0x28: decode RS1 { - 0xF: decode I { + 0x00: NoPriv::rdy({{Rd = Y;}}); + //1 should cause an illegal instruction exception + 0x02: NoPriv::rdccr({{Rd = Ccr;}}); + 0x03: NoPriv::rdasi({{Rd = Asi;}}); + 0x04: PrivCheck::rdtick({{Rd = Tick;}}, {{Tick<63:>}}); + 0x05: NoPriv::rdpc({{ + if(Pstate<3:>) + Rd = (xc->readPC())<31:0>; + else + Rd = xc->readPC();}}); + 0x06: NoPriv::rdfprs({{ + //Wait for all fpops to finish. + Rd = Fprs; + }}); + //7-14 should cause an illegal instruction exception + 0x0F: decode I { 0x0: Nop::stbar({{/*stuff*/}}); 0x1: Nop::membar({{/*stuff*/}}); } - default: rdasr({{ - Rd = xc->readMiscRegWithEffect(RS1 + AsrStart); + 0x10: Priv::rdpcr({{Rd = Pcr;}}); + 0x11: PrivCheck::rdpic({{Rd = Pic;}}, {{Pcr<0:>}}); + //0x12 should cause an illegal instruction exception + 0x13: NoPriv::rdgsr({{ + if(Fprs<2:> == 0 || Pstate<4:> == 0) + Rd = Gsr; + else + fault = new FpDisabled; }}); + //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:>}}); + 0x19: Priv::rdstick_cmpr({{Rd = StickCmpr;}}); + //0x1A-0x1F should cause an illegal instruction exception + } + 0x29: decode RS1 { + 0x00: HPriv::rdhprhpstate({{Rd = Hpstate;}}); + 0x01: HPriv::rdhprhtstate({{ + if(Tl == 0) + return new IllegalInstruction; + Rd = Htstate; + }}); + //0x02 should cause an illegal instruction exception + 0x03: HPriv::rdhprhintp({{Rd = Hintp;}}); + //0x04 should cause an illegal instruction exception + 0x05: HPriv::rdhprhtba({{Rd = Htba;}}); + 0x06: HPriv::rdhprhver({{Rd = Hver;}}); + //0x07-0x1E should cause an illegal instruction exception + 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; + }}); + 0x04: Priv::rdprtick({{Rd = Tick;}}); + 0x05: Priv::rdprtba({{Rd = Tba;}}); + 0x06: Priv::rdprpstate({{Rd = Pstate;}}); + 0x07: Priv::rdprtl({{Rd = Tl;}}); + 0x08: Priv::rdprpil({{Rd = Pil;}}); + 0x09: Priv::rdprcwp({{Rd = Cwp;}}); + 0x0A: Priv::rdprcansave({{Rd = Cansave;}}); + 0x0B: Priv::rdprcanrestore({{Rd = Canrestore;}}); + 0x0C: Priv::rdprcleanwin({{Rd = Cleanwin;}}); + 0x0D: Priv::rdprotherwin({{Rd = Otherwin;}}); + 0x0E: Priv::rdprwstate({{Rd = Wstate;}}); + //0x0F should cause an illegal instruction exception + 0x10: Priv::rdprgl({{Rd = Gl;}}); + //0x11-0x1F should cause an illegal instruction exception } - 0x29: HPriv::rdhpr({{ - Rd = xc->readMiscRegWithEffect(RS1 + HprStart); - }}); - 0x2A: Priv::rdpr({{ - Rd = xc->readMiscRegWithEffect(RS1 + PrStart); - }}); 0x2B: BasicOperate::flushw({{ if(NWindows - 2 - Cansave == 0) { @@ -417,9 +488,35 @@ decode OP default Unknown::unknown() 0x6: movrg({{Rd = (Rs1.sdw > 0) ? Rs2_or_imm10 : Rd;}}); 0x7: movrge({{Rd = (Rs1.sdw >= 0) ? Rs2_or_imm10 : Rd;}}); } - 0x30: wrasr({{ - xc->setMiscRegWithEffect(RD + AsrStart, Rs1 ^ Rs2_or_imm13); - }}); + 0x30: decode RD { + 0x00: NoPriv::wry({{Y = Rs1 ^ Rs2_or_imm13;}}); + //0x01 should cause an illegal instruction exception + 0x02: NoPriv::wrccr({{Ccr = Rs1 ^ Rs2_or_imm13;}}); + 0x03: NoPriv::wrasi({{Ccr = Rs1 ^ Rs2_or_imm13;}}); + //0x04-0x05 should cause an illegal instruction exception + 0x06: NoPriv::wrfprs({{Fprs = Rs1 ^ Rs2_or_imm13;}}); + //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:>}}); + //0x12 should cause an illegal instruction exception + 0x13: NoPriv::wrgsr({{ + if(Fprs<2:> == 0 || Pstate<4:> == 0) + return new FpDisabled; + Gsr = Rs1 ^ Rs2_or_imm13; + }}); + 0x14: Priv::wrsoftint_set({{SoftintSet = Rs1 ^ Rs2_or_imm13;}}); + 0x15: Priv::wrsoftint_clr({{SoftintClr = Rs1 ^ Rs2_or_imm13;}}); + 0x16: Priv::wrsoftint({{Softint = Rs1 ^ Rs2_or_imm13;}}); + 0x17: Priv::wrtick_cmpr({{TickCmpr = Rs1 ^ Rs2_or_imm13;}}); + 0x18: NoPriv::wrstick({{ + if(!Hpstate<2:>) + return new IllegalInstruction; + Stick = Rs1 ^ Rs2_or_imm13; + }}); + 0x19: Priv::wrstick_cmpr({{StickCmpr = Rs1 ^ Rs2_or_imm13;}}); + //0x1A-0x1F should cause an illegal instruction exception + } 0x31: decode FCN { 0x0: Priv::saved({{ assert(Cansave < NWindows - 2); @@ -440,16 +537,70 @@ decode OP default Unknown::unknown() Otherwin = Otherwin - 1; }}); } - 0x32: Priv::wrpr({{ - // XXX Need to protect with format that traps non-priv - // access - xc->setMiscRegWithEffect(RD + PrStart, Rs1 ^ Rs2_or_imm13); - }}); - 0x33: HPriv::wrhpr({{ - // XXX Need to protect with format that traps non-priv/priv - // access - xc->setMiscRegWithEffect(RD + HprStart, Rs1 ^ Rs2_or_imm13); - }}); + 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; + }}); + 0x04: HPriv::wrprtick({{Tick = Rs1 ^ Rs2_or_imm13;}}); + 0x05: Priv::wrprtba({{Tba = Rs1 ^ Rs2_or_imm13;}}); + 0x06: Priv::wrprpstate({{Pstate = Rs1 ^ Rs2_or_imm13;}}); + 0x07: Priv::wrprtl({{ + if(Pstate<2:> && !Hpstate<2:>) + Tl = std::min(Rs1 ^ Rs2_or_imm13, MaxPTL); + else + Tl = std::min(Rs1 ^ Rs2_or_imm13, MaxTL); + }}); + 0x08: Priv::wrprpil({{Pil = Rs1 ^ Rs2_or_imm13;}}); + 0x09: Priv::wrprcwp({{Cwp = Rs1 ^ Rs2_or_imm13;}}); + 0x0A: Priv::wrprcansave({{Cansave = Rs1 ^ Rs2_or_imm13;}}); + 0x0B: Priv::wrprcanrestore({{Canrestore = Rs1 ^ Rs2_or_imm13;}}); + 0x0C: Priv::wrprcleanwin({{Cleanwin = Rs1 ^ Rs2_or_imm13;}}); + 0x0D: Priv::wrprotherwin({{Otherwin = Rs1 ^ Rs2_or_imm13;}}); + 0x0E: Priv::wrprwstate({{Wstate = Rs1 ^ Rs2_or_imm13;}}); + //0x0F should cause an illegal instruction exception + 0x10: Priv::wrprgl({{ + if(Pstate<2:> && !Hpstate<2:>) + Gl = std::min(Rs1 ^ Rs2_or_imm13, MaxPGL); + else + Gl = std::min(Rs1 ^ Rs2_or_imm13, MaxGL); + }}); + //0x11-0x1F should cause an illegal instruction exception + } + 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; + }}); + //0x02 should cause an illegal instruction exception + 0x03: HPriv::wrhprhintp({{Hintp = Rs1 ^ Rs2_or_imm13;}}); + //0x04 should cause an illegal instruction exception + 0x05: HPriv::wrhprhtba({{Htba = Rs1 ^ Rs2_or_imm13;}}); + //0x06-0x01D should cause an illegal instruction exception + 0x1F: HPriv::wrhprhstick_cmpr({{HstickCmpr = Rs1 ^ Rs2_or_imm13;}}); + } 0x34: decode OPF{ format BasicOperate{ 0x01: fmovs({{ diff --git a/src/arch/sparc/isa/formats/priv.isa b/src/arch/sparc/isa/formats/priv.isa index 04c67d332..55bf968f4 100644 --- a/src/arch/sparc/isa/formats/priv.isa +++ b/src/arch/sparc/isa/formats/priv.isa @@ -119,18 +119,34 @@ let {{ return (header_output, decoder_output, exec_output, decode_block) }}; -// Primary format for integer operate instructions: def format Priv(code, *opt_flags) {{ - checkCode = "!(Pstate<2:2> || Hpstate<2:2>)" + checkCode = "!(Pstate<2:> || Hpstate<2:>)" (header_output, decoder_output, exec_output, decode_block) = doPrivFormat(code, - checkCode, name, Name, opt_flags + ('IprAccessOp',)) + checkCode, name, Name, opt_flags) +}}; + +def format NoPriv(code, *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" + (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) }}; def format HPriv(code, *opt_flags) {{ checkCode = "!Hpstate<2:2>" (header_output, decoder_output, exec_output, decode_block) = doPrivFormat(code, - checkCode, name, Name, opt_flags + ('IprAccessOp',)) + checkCode, name, Name, opt_flags) }}; diff --git a/src/arch/sparc/isa/includes.isa b/src/arch/sparc/isa/includes.isa index a324756ec..624afb693 100644 --- a/src/arch/sparc/isa/includes.isa +++ b/src/arch/sparc/isa/includes.isa @@ -54,6 +54,7 @@ output decoder {{ #if defined(linux) #include #endif +#include using namespace SparcISA; }}; diff --git a/src/arch/sparc/isa/operands.isa b/src/arch/sparc/isa/operands.isa index 80b499b91..caee20b0c 100644 --- a/src/arch/sparc/isa/operands.isa +++ b/src/arch/sparc/isa/operands.isa @@ -80,8 +80,6 @@ def operands {{ 'Frs2': ('FloatReg', 'df', 'dfpr(RS2)', 'IsFloating', 12), 'NPC': ('NPC', 'udw', None, ( None, None, 'IsControl' ), 31), 'NNPC': ('NNPC', 'udw', None, (None, None, 'IsControl' ), 32), - #'Runiq': ('ControlReg', 'uq', 'Uniq', None, 1), - #'FPCR': ('ControlReg', 'uq', 'Fpcr', None, 1), 'R0': ('IntReg', 'udw', '0', None, 6), 'R1': ('IntReg', 'udw', '1', None, 7), 'R15': ('IntReg', 'udw', '15', 'IsInteger', 8), @@ -91,24 +89,42 @@ def operands {{ 'Y': ('ControlReg', 'udw', 'MISCREG_Y', None, 40), 'Ccr': ('ControlReg', 'udw', 'MISCREG_CCR', None, 41), 'Asi': ('ControlReg', 'udw', 'MISCREG_ASI', None, 42), + 'Fprs': ('ControlReg', 'udw', 'MISCREG_FPRS', None, 43), + 'Pcr': ('ControlReg', 'udw', 'MISCREG_PCR', None, 44), + 'Pic': ('ControlReg', 'udw', 'MISCREG_PIC', None, 45), + 'Gsr': ('ControlReg', 'udw', 'MISCREG_GSR', None, 46), + 'Softint': ('ControlReg', 'udw', 'MISCREG_SOFTINT', None, 47), + 'SoftintSet': ('ControlReg', 'udw', 'MISCREG_SOFTINT_SET', None, 48), + 'SoftintClr': ('ControlReg', 'udw', 'MISCREG_SOFTINT_CLR', None, 49), + 'TickCmpr': ('ControlReg', 'udw', 'MISCREG_TICK_CMPR', None, 50), + 'Stick': ('ControlReg', 'udw', 'MISCREG_STICK', None, 51), + 'StickCmpr': ('ControlReg', 'udw', 'MISCREG_STICK_CMPR', None, 52), - 'Tpc': ('ControlReg', 'udw', 'MISCREG_TPC', None, 43), - 'Tnpc': ('ControlReg', 'udw', 'MISCREG_TNPC', None, 44), - 'Tstate': ('ControlReg', 'udw', 'MISCREG_TSTATE', None, 45), - 'Pstate': ('ControlReg', 'udw', 'MISCREG_PSTATE', None, 46), - 'Hpstate': ('ControlReg', 'udw', 'MISCREG_HPSTATE', None, 47), - 'Tl': ('ControlReg', 'udw', 'MISCREG_TL', None, 48), + 'Tpc': ('ControlReg', 'udw', 'MISCREG_TPC', None, 53), + 'Tnpc': ('ControlReg', 'udw', 'MISCREG_TNPC', None, 54), + 'Tstate': ('ControlReg', 'udw', 'MISCREG_TSTATE', None, 55), + 'Tt': ('ControlReg', 'udw', 'MISCREG_TT', None, 56), + 'Tick': ('ControlReg', 'udw', 'MISCREG_TICK', None, 57), + 'Tba': ('ControlReg', 'udw', 'MISCREG_TBA', None, 58), + 'Pstate': ('ControlReg', 'udw', 'MISCREG_PSTATE', None, 59), + 'Tl': ('ControlReg', 'udw', 'MISCREG_TL', None, 60), + 'Pil': ('ControlReg', 'udw', 'MISCREG_PIL', None, 61), + 'Cwp': ('ControlReg', 'udw', 'MISCREG_CWP', None, 62), + 'Cansave': ('ControlReg', 'udw', 'MISCREG_CANSAVE', None, 63), + 'Canrestore': ('ControlReg', 'udw', 'MISCREG_CANRESTORE', None, 64), + 'Cleanwin': ('ControlReg', 'udw', 'MISCREG_CLEANWIN', None, 65), + 'Otherwin': ('ControlReg', 'udw', 'MISCREG_OTHERWIN', None, 66), + 'Wstate': ('ControlReg', 'udw', 'MISCREG_WSTATE', None, 67), + 'Gl': ('ControlReg', 'udw', 'MISCREG_GL', None, 68), - 'Cwp': ('ControlReg', 'udw', 'MISCREG_CWP', None, 49), - 'Cansave': ('ControlReg', 'udw', 'MISCREG_CANSAVE', None, 50), - 'Canrestore': ('ControlReg', 'udw', 'MISCREG_CANRESTORE', None, 51), - 'Cleanwin': ('ControlReg', 'udw', 'MISCREG_CLEANWIN', None, 52), - 'Otherwin': ('ControlReg', 'udw', 'MISCREG_OTHERWIN', None, 53), - 'Wstate': ('ControlReg', 'udw', 'MISCREG_WSTATE', None, 54), - 'Gl': ('ControlReg', 'udw', 'MISCREG_GL', None, 55), + 'Hpstate': ('ControlReg', 'udw', 'MISCREG_HPSTATE', None, 69), + 'Htstate': ('ControlReg', 'udw', 'MISCREG_HTSTATE', None, 70), + 'Hintp': ('ControlReg', 'udw', 'MISCREG_HINTP', None, 71), + 'Htba': ('ControlReg', 'udw', 'MISCREG_HTBA', None, 72), + 'HstickCmpr': ('ControlReg', 'udw', 'MISCREG_HSTICK_CMPR', None, 73), + 'Hver': ('ControlReg', 'udw', 'MISCREG_HVER', None, 74), - 'Fsr': ('ControlReg', 'udw', 'MISCREG_FSR', None, 56), - 'Gsr': ('ControlReg', 'udw', 'MISCREG_GSR', None, 57), + 'Fsr': ('ControlReg', 'udw', 'MISCREG_FSR', None, 80), # Mem gets a large number so it's always last 'Mem': ('Mem', 'udw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 100) -- cgit v1.2.3