diff options
author | Gabe Black <gblack@eecs.umich.edu> | 2007-12-01 23:03:39 -0800 |
---|---|---|
committer | Gabe Black <gblack@eecs.umich.edu> | 2007-12-01 23:03:39 -0800 |
commit | dc6f96017135da7f3beae5055195de3cf8e47c6c (patch) | |
tree | b8fad747c652fe34db462bf585be4d184da02d6b /src/arch/x86/isa/microops/regop.isa | |
parent | a548067b01ed99d4abc9483ca11466d3d9d4ceca (diff) | |
download | gem5-dc6f96017135da7f3beae5055195de3cf8e47c6c.tar.xz |
X86: Reorganize segmentation and implement segment selector movs.
--HG--
extra : convert_revision : 553c3ffeda1f5312cf02493f602e7d4ba2fe66e8
Diffstat (limited to 'src/arch/x86/isa/microops/regop.isa')
-rw-r--r-- | src/arch/x86/isa/microops/regop.isa | 97 |
1 files changed, 89 insertions, 8 deletions
diff --git a/src/arch/x86/isa/microops/regop.isa b/src/arch/x86/isa/microops/regop.isa index f37b4327b..7f72fcf1d 100644 --- a/src/arch/x86/isa/microops/regop.isa +++ b/src/arch/x86/isa/microops/regop.isa @@ -937,19 +937,100 @@ let {{ } ''' - class Wrbase(RegOp): + # Microops for manipulating segmentation registers + class SegOp(RegOp): + abstract = True def __init__(self, dest, src1, flags=None, dataSize="env.dataSize"): - super(Wrbase, self).__init__(dest, \ + super(SegOp, self).__init__(dest, \ src1, "NUM_INTREGS", flags, dataSize) + + class Wrbase(SegOp): code = ''' - SysSegBaseDest = psrc1; + SegBaseDest = psrc1; ''' - class Wrlimit(RegOp): - def __init__(self, dest, src1, flags=None, dataSize="env.dataSize"): - super(Wrlimit, self).__init__(dest, \ - src1, "NUM_INTREGS", flags, dataSize) + class Wrlimit(SegOp): + code = ''' + SegLimitDest = psrc1; + ''' + + class Wrsel(SegOp): + code = ''' + SegSelDest = psrc1; + ''' + + class Rdbase(SegOp): + code = ''' + DestReg = SegBaseDest; + ''' + + class Rdlimit(SegOp): + code = ''' + DestReg = SegLimitSrc1; + ''' + + class Rdsel(SegOp): code = ''' - SysSegLimitDest = psrc1; + DestReg = SegSelSrc1; + ''' + + class Chks(SegOp): + code = ''' + // The selector is in source 1. + SegSelector selector = psrc1; + + // Compute the address of the descriptor and set DestReg to it. + if (selector.ti) { + // A descriptor in the LDT + Addr target = (selector.esi << 3) + LDTRBase; + if (!LDTRSel || (selector.esi << 3) + dataSize > LDTRLimit) + fault = new GeneralProtection(selector & mask(16)); + DestReg = target; + } else { + // A descriptor in the GDT + Addr target = (selector.esi << 3) + GDTRBase; + if ((selector.esi << 3) + dataSize > GDTRLimit) + fault = new GeneralProtection(selector & mask(16)); + DestReg = target; + } + ''' + flag_code = ''' + // Check for a NULL selector and set ZF,EZF appropriately. + ccFlagBits = ccFlagBits & ~(ext & (ZFBit | EZFBit)); + if (!selector.esi && !selector.ti) + ccFlagBits = ccFlagBits | (ext & (ZFBit | EZFBit)); + ''' + + class Wrdh(RegOp): + code = ''' + + ''' + + class Wrdl(RegOp): + code = ''' + SegDescriptor desc = SrcReg1; + SegAttr attr = 0; + Addr base = 0, limit = 0; + attr.dpl = desc.dpl; + attr.defaultSize = desc.d; + if (!desc.p) + panic("Segment not present.\\n"); + if (!desc.s) + panic("System segment encountered.\\n"); + if (desc.type.codeOrData) { + panic("Code segment encountered with c = %d, r = %d, a = %d.\\n", + desc.type.c, desc.type.r, desc.type.a); + } else { + attr.expandDown = desc.type.e; + attr.readable = 1; + attr.writable = desc.type.w; + base = desc.baseLow | (desc.baseHigh << 24); + limit = desc.limitLow | (desc.limitHigh << 16); + if (desc.g) + limit = (limit << 12) | mask(12); + } + SegBaseDest = base; + SegLimitDest = limit; + SegAttrDest = attr; ''' }}; |