Gabe Black has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/55883 )

Change subject: arch-x86: Fill out the implementation of LXS instructions.
......................................................................

arch-x86: Fill out the implementation of LXS instructions.

These are the LDS, LES, LFS, LGS, and LSS instructions. They had already
been implemented in real mode. This change implements them in protected
mode, and also consolidates the implementation of both using python
string substitution.

Change-Id: I3974e6d1a4d07bcfad63a767820e0e7d7687b18d
---
M src/arch/x86/isa/insts/general_purpose/load_segment_registers.py
M src/arch/x86/isa/decoder/two_byte_opcodes.isa
M src/arch/x86/isa/decoder/one_byte_opcodes.isa
3 files changed, 129 insertions(+), 113 deletions(-)



diff --git a/src/arch/x86/isa/decoder/one_byte_opcodes.isa b/src/arch/x86/isa/decoder/one_byte_opcodes.isa
index 104d205..e490189 100644
--- a/src/arch/x86/isa/decoder/one_byte_opcodes.isa
+++ b/src/arch/x86/isa/decoder/one_byte_opcodes.isa
@@ -390,12 +390,12 @@
             0x4: decode MODE_SUBMODE {
                 0x0: UD2();
                 0x3, 0x4: LES_REAL(Gz,Mz);
-                default: WarnUnimpl::les_Gz_Mp();
+                default: LES(Gz,Mz);
             }
             0x5: decode MODE_SUBMODE {
                 0x0: UD2();
                 0x3, 0x4: LDS_REAL(Gz,Mz);
-                default: WarnUnimpl::lds_Gz_Mp();
+                default: LDS(Gz,Mz);
             }
             //0x6: group12_Eb_Ib();
             0x6: decode MODRM_REG {
diff --git a/src/arch/x86/isa/decoder/two_byte_opcodes.isa b/src/arch/x86/isa/decoder/two_byte_opcodes.isa
index b82afb0..46135fe 100644
--- a/src/arch/x86/isa/decoder/two_byte_opcodes.isa
+++ b/src/arch/x86/isa/decoder/two_byte_opcodes.isa
@@ -752,16 +752,16 @@
                 0x1: CMPXCHG(Ev,Gv);
                 0x2: decode MODE_SUBMODE {
                     0x3, 0x4: LSS_REAL(Gz,Mz);
-                    default: WarnUnimpl::lss_Gz_Mp();
+                    default: LSS(Gz,Mz);
                 }
                 0x3: BTR(Ev,Gv);
                 0x4: decode MODE_SUBMODE {
                     0x3, 0x4: LFS_REAL(Gz,Mz);
-                    default: WarnUnimpl::lfs_Gz_Mp();
+                    default: LFS(Gz,Mz);
                 }
                 0x5: decode MODE_SUBMODE {
                     0x3, 0x4: LGS_REAL(Gz,Mz);
-                    default: WarnUnimpl::lgs_Gz_Mp();
+                    default: LGS(Gz,Mz);
                 }
                 //The size of the second operand in these instructions
                 //should really be "b" or "w", but it's set to v in order
diff --git a/src/arch/x86/isa/insts/general_purpose/load_segment_registers.py b/src/arch/x86/isa/insts/general_purpose/load_segment_registers.py
index 1967820..bffa1a4 100644
--- a/src/arch/x86/isa/insts/general_purpose/load_segment_registers.py
+++ b/src/arch/x86/isa/insts/general_purpose/load_segment_registers.py
@@ -33,121 +33,123 @@
 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

-microcode = '''
-
-#
-# Real mode versions of the load far pointer instructions.
-#
-
-def macroop LDS_REAL_R_M {
+lxs_template = '''
+def macroop %(full_inst)s {
     # Calculate the address of the pointer.
-    lea t1, seg, sib, disp, dataSize=asz
+%(addr_calc)s

     # Load the selector into a temporary.
     ld t2, seg, [1, t0, t1], dsz, dataSize=2
     # Load the offset.
-    ld reg, seg, [1, t0, t1], 0
-    # Install the selector value.
-    wrsel ds, t2
-    # Make sure there isn't any junk in the upper bits of the base.
-    mov t2, t0, t2
-    # Compute and set the base.
-    slli t2, t2, 4, dataSize=8
-    wrbase ds, t2, dataSize=8
+    ld t1, seg, [1, t0, t1], 0
+
+    # Figure out if this is a null selector.
+    andi t0, t2, 0xFC, flags=(EZF,), dataSize=2
+    br label("processDescriptor"), flags=(CEZF,)
+
+    # Extract the index.
+    andi t3, t2, 0xF8, dataSize=8
+
+    # Check if this is a local or global descriptor.
+    andi t0, t2, 0x4, flags=(EZF,), dataSize=2
+    br label("globalDescriptor"), flags=(CEZF,)
+
+    # It's local.
+    ld t4, tsl, [1, t0, t3], dataSize=8, addressSize=8
+    br label("processDescriptor")
+
+    # It's global.
+globalDescriptor:
+    ld t4, tsg, [1, t0, t3], dataSize=8, addressSize=8
+
+    # Install the descriptor.
+processDescriptor:
+    chks t2, t4, %(check_type)sdataSize=8
+    wrdl %(seg)s, t4, t2
+    wrsel %(seg)s, t2
+
+    # Install the offset.
+    mov reg, reg, t1
 };
-
-def macroop LES_REAL_R_M {
-    # Calculate the address of the pointer.
-    lea t1, seg, sib, disp, dataSize=asz
-
-    # Load the selector into a temporary.
-    ld t2, seg, [1, t0, t1], dsz, dataSize=2
-    # Load the offset.
-    ld reg, seg, [1, t0, t1], 0
-    # Install the selector value.
-    wrsel es, t2
-    # Make sure there isn't any junk in the upper bits of the base.
-    mov t2, t0, t2
-    # Compute and set the base.
-    slli t2, t2, 4, dataSize=8
-    wrbase es, t2, dataSize=8
-};
-
-def macroop LFS_REAL_R_M {
-    # Calculate the address of the pointer.
-    lea t1, seg, sib, disp, dataSize=asz
-
-    # Load the selector into a temporary.
-    ld t2, seg, [1, t0, t1], dsz, dataSize=2
-    # Load the offset.
-    ld reg, seg, [1, t0, t1], 0
-    # Install the selector value.
-    wrsel fs, t2
-    # Make sure there isn't any junk in the upper bits of the base.
-    mov t2, t0, t2
-    # Compute and set the base.
-    slli t2, t2, 4, dataSize=8
-    wrbase fs, t2, dataSize=8
-};
-
-def macroop LGS_REAL_R_M {
-    # Calculate the address of the pointer.
-    lea t1, seg, sib, disp, dataSize=asz
-
-    # Load the selector into a temporary.
-    ld t2, seg, [1, t0, t1], dsz, dataSize=2
-    # Load the offset.
-    ld reg, seg, [1, t0, t1], 0
-    # Install the selector value.
-    wrsel gs, t2
-    # Make sure there isn't any junk in the upper bits of the base.
-    mov t2, t0, t2
-    # Compute and set the base.
-    slli t2, t2, 4, dataSize=8
-    wrbase gs, t2, dataSize=8
-};
-
-def macroop LSS_REAL_R_M {
-    # Calculate the address of the pointer.
-    lea t1, seg, sib, disp, dataSize=asz
-
-    # Load the selector into a temporary.
-    ld t2, seg, [1, t0, t1], dsz, dataSize=2
-    # Load the offset.
-    ld reg, seg, [1, t0, t1], 0
-    # Install the selector value.
-    wrsel ss, t2
-    # Make sure there isn't any junk in the upper bits of the base.
-    mov t2, t0, t2
-    # Compute and set the base.
-    slli t2, t2, 4, dataSize=8
-    wrbase ss, t2, dataSize=8
-};
-
-# Versions for RIP relative addressing, even though these instructions are
-# illegal in 64 bit mode, where RIP relative addressing is available.
-
-def macroop LDS_REAL_R_P {
-    panic "Real mode LDS doesn't support RIP relative addressing."
-};
-
-def macroop LES_REAL_R_P {
-    panic "Real mode LES doesn't support RIP relative addressing."
-};
-
-def macroop LFS_REAL_R_P {
-    panic "Real mode LFS doesn't support RIP relative addressing."
-};
-
-def macroop LGS_REAL_R_P {
-    panic "Real mode LGS doesn't support RIP relative addressing."
-};
-
-def macroop LSS_REAL_R_P {
-    panic "Real mode LSS doesn't support RIP relative addressing."
-};
-
 '''
+
+lxs_template = \
+    lxs_template % {
+        'full_inst'  : '%(inst)s_R_M',
+        'addr_calc'  : '    lea t1, seg, sib, disp, dataSize=asz',
+        'check_type' : '%(check_type)s',
+        'seg'        : '%(seg)s',
+    } + lxs_template % {
+        'full_inst'  : '%(inst)s_R_P',
+        'addr_calc'  : '    rdip t7\n' \
+                       '    lea t1, seg, riprel, disp, dataSize=asz',
+        'check_type' : '%(check_type)s',
+        'seg'        : '%(seg)s',
+    }
+
+microcode = lxs_template % {
+    'inst'       : 'LDS',
+    'check_type' : '',
+    'seg'        : 'ds',
+} + lxs_template % {
+    'inst'       : 'LES',
+    'check_type' : '',
+    'seg'        : 'es',
+} + lxs_template % {
+    'inst'       : 'LFS',
+    'check_type' : '',
+    'seg'        : 'fs',
+} + lxs_template % {
+    'inst'       : 'LGS',
+    'check_type' : '',
+    'seg'        : 'gs',
+} + lxs_template % {
+    'inst'       : 'LSS',
+    'check_type' : 'SSCheck, ',
+    'seg'        : 'ss',
+}
+
+# Real mode versions of the load far pointer instructions.
+lxs_template = '''
+def macroop %(inst)s_REAL_R_M {
+    # Calculate the address of the pointer.
+    lea t1, seg, sib, disp, dataSize=asz
+
+    # Load the selector into a temporary.
+    ld t2, seg, [1, t0, t1], dsz, dataSize=2
+    # Load the offset.
+    ld reg, seg, [1, t0, t1], 0
+    # Install the selector value.
+    wrsel %(seg)s, t2
+    # Make sure there isn't any junk in the upper bits of the base.
+    mov t2, t0, t2
+    # Compute and set the base.
+    slli t2, t2, 4, dataSize=8
+    wrbase %(seg)s, t2, dataSize=8
+};
+
+def macroop %(inst)s_REAL_R_P {
+    panic "Real mode %(inst)s doesn't support RIP relative addressing."
+};
+'''
+
+microcode += lxs_template % {
+    'inst' : 'LDS',
+    'seg'  : 'ds',
+} + lxs_template % {
+    'inst' : 'LES',
+    'seg'  : 'es',
+} + lxs_template % {
+    'inst' : 'LFS',
+    'seg'  : 'fs',
+} + lxs_template % {
+    'inst' : 'LGS',
+    'seg'  : 'gs',
+} + lxs_template % {
+    'inst' : 'LSS',
+    'seg'  : 'ss',
+}
+
 #let {{
 #    class LDS(Inst):
 #       "GenFault ${new UnimpInstFault}"

--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/55883
To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings

Gerrit-Project: public/gem5
Gerrit-Branch: develop
Gerrit-Change-Id: I3974e6d1a4d07bcfad63a767820e0e7d7687b18d
Gerrit-Change-Number: 55883
Gerrit-PatchSet: 1
Gerrit-Owner: Gabe Black <gabe.bl...@gmail.com>
Gerrit-MessageType: newchange
_______________________________________________
gem5-dev mailing list -- gem5-dev@gem5.org
To unsubscribe send an email to gem5-dev-le...@gem5.org
%(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s

Reply via email to