diff options
author | Gabe Black <gblack@eecs.umich.edu> | 2007-11-12 14:38:59 -0800 |
---|---|---|
committer | Gabe Black <gblack@eecs.umich.edu> | 2007-11-12 14:38:59 -0800 |
commit | f1f5dd79bf8c2cf2ef64cc1432a4a0601d475e72 (patch) | |
tree | 7215bb386591b8ff8d3ce53cefd40599c1a44c2a /src/arch/x86/isa | |
parent | 4d4d2883f9c84f0cebec4b65479c11540dbb36f7 (diff) | |
download | gem5-f1f5dd79bf8c2cf2ef64cc1432a4a0601d475e72.tar.xz |
X86: Implement the wrcr microop which writes a control register, and some control register work.
--HG--
extra : convert_revision : 3e9daef9cdd0665c033420e5b4f981649e9908ab
Diffstat (limited to 'src/arch/x86/isa')
-rw-r--r-- | src/arch/x86/isa/decoder/two_byte_opcodes.isa | 2 | ||||
-rw-r--r-- | src/arch/x86/isa/insts/general_purpose/data_transfer/move.py | 4 | ||||
-rw-r--r-- | src/arch/x86/isa/microasm.isa | 3 | ||||
-rw-r--r-- | src/arch/x86/isa/microops/regop.isa | 52 | ||||
-rw-r--r-- | src/arch/x86/isa/operands.isa | 4 | ||||
-rw-r--r-- | src/arch/x86/isa/specialize.isa | 8 |
6 files changed, 71 insertions, 2 deletions
diff --git a/src/arch/x86/isa/decoder/two_byte_opcodes.isa b/src/arch/x86/isa/decoder/two_byte_opcodes.isa index 233a5602d..f3485bc4e 100644 --- a/src/arch/x86/isa/decoder/two_byte_opcodes.isa +++ b/src/arch/x86/isa/decoder/two_byte_opcodes.isa @@ -202,7 +202,7 @@ 0x0: decode OPCODE_OP_BOTTOM3 { 0x0: mov_Rd_Cd(); 0x1: mov_Rd_Dd(); - 0x2: mov_Cd_Rd(); + 0x2: Inst::MOV(Cd,Rd); 0x3: mov_Dd_Rd(); 0x4: mov_Rd_Td(); 0x6: mov_Td_Rd(); diff --git a/src/arch/x86/isa/insts/general_purpose/data_transfer/move.py b/src/arch/x86/isa/insts/general_purpose/data_transfer/move.py index ada7f28a3..a15fc21ef 100644 --- a/src/arch/x86/isa/insts/general_purpose/data_transfer/move.py +++ b/src/arch/x86/isa/insts/general_purpose/data_transfer/move.py @@ -188,6 +188,10 @@ def macroop MOVZX_W_R_P { ld t1, seg, riprel, disp, dataSize=2 zexti reg, t1, 15 }; + +def macroop MOV_C_R { + wrcr reg, regm +}; ''' #let {{ # class MOVD(Inst): diff --git a/src/arch/x86/isa/microasm.isa b/src/arch/x86/isa/microasm.isa index e05582e37..040bb2036 100644 --- a/src/arch/x86/isa/microasm.isa +++ b/src/arch/x86/isa/microasm.isa @@ -113,6 +113,9 @@ let {{ for reg in ('ax', 'bx', 'cx', 'dx', 'sp', 'bp', 'si', 'di'): assembler.symbols["r%s" % reg] = "INTREG_R%s" % reg.upper() + for reg in range(15): + assembler.symbols["cr%d" % reg] = "MISCREG_CR%d" % reg + for flag in ('CF', 'PF', 'ECF', 'AF', 'EZF', 'ZF', 'SF', 'OF'): assembler.symbols[flag] = flag + "Bit" diff --git a/src/arch/x86/isa/microops/regop.isa b/src/arch/x86/isa/microops/regop.isa index b5e17d36d..58b267e0d 100644 --- a/src/arch/x86/isa/microops/regop.isa +++ b/src/arch/x86/isa/microops/regop.isa @@ -884,4 +884,56 @@ let {{ class Zext(RegOp): code = 'DestReg = bits(psrc1, op2, 0);' + + class Wrcr(RegOp): + def __init__(self, dest, src1, flags=None, dataSize="env.dataSize"): + super(Wrcr, self).__init__(dest, \ + src1, "NUM_INTREGS", flags, dataSize) + code = ''' + if (dest == 1 || (dest > 4 && dest < 8) || (dest > 8)) { + fault = new InvalidOpcode(); + } else { + // There are *s in the line below so it doesn't confuse the + // parser. They may be unnecessary. + //Mis*cReg old*Val = pick(Cont*rolDest, 0, dat*aSize); + MiscReg newVal = psrc1; + + // Check for any modifications that would cause a fault. + switch(dest) { + case 0: + { + Efer efer = EferOp; + CR0 cr0 = newVal; + CR4 oldCr4 = CR4Op; + if (bits(newVal, 63, 32) || + (!cr0.pe && cr0.pg) || + (!cr0.cd && cr0.nw) || + (cr0.pg && efer.lme && !oldCr4.pae)) + fault = new GeneralProtection(0); + } + break; + case 2: + break; + case 3: + break; + case 4: + { + CR4 cr4 = newVal; + // PAE can't be disabled in long mode. + if (bits(newVal, 63, 11) || + (machInst.mode.mode == LongMode && !cr4.pae)) + fault = new GeneralProtection(0); + } + break; + case 8: + { + if (bits(newVal, 63, 4)) + fault = new GeneralProtection(0); + } + default: + panic("Unrecognized control register %d.\\n", dest); + } + ControlDest = newVal; + } + ''' }}; diff --git a/src/arch/x86/isa/operands.isa b/src/arch/x86/isa/operands.isa index 8c0eacca2..542638edd 100644 --- a/src/arch/x86/isa/operands.isa +++ b/src/arch/x86/isa/operands.isa @@ -122,5 +122,9 @@ def operands {{ # instructions don't map their indexes with an old value. 'TOP': ('ControlReg', 'ub', 'MISCREG_X87_TOP', None, 61), 'SegBase': ('ControlReg', 'uqw', 'MISCREG_SEG_BASE(segment)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 70), + 'ControlDest': ('ControlReg', 'uqw', 'MISCREG_CR(dest)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 71), + 'ControlSrc1': ('ControlReg', 'uqw', 'MISCREG_CR(src1)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 72), + 'EferOp': ('ControlReg', 'uqw', 'MISCREG_EFER', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 73), + 'CR4Op': ('ControlReg', 'uqw', 'MISCREG_CR4', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 74), 'Mem': ('Mem', 'uqw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 100) }}; diff --git a/src/arch/x86/isa/specialize.isa b/src/arch/x86/isa/specialize.isa index cf6b6ff86..3802d8949 100644 --- a/src/arch/x86/isa/specialize.isa +++ b/src/arch/x86/isa/specialize.isa @@ -153,7 +153,13 @@ let {{ return doRipRelativeDecode(Name, opTypes, env) elif opType.tag == None or opType.size == None: raise Exception, "Problem parsing operand tag: %s" % opType.tag - elif opType.tag in ("C", "D", "G", "P", "S", "T", "V"): + elif opType.tag == "C": + env.addReg(ModRMRegIndex) + Name += "_C" + elif opType.tag == "D": + env.addReg(ModRMRegIndex) + Name += "_D" + elif opType.tag in ("G", "P", "S", "T", "V"): # Use the "reg" field of the ModRM byte to select the register env.addReg(ModRMRegIndex) Name += "_R" |