X86: Implement the ENTER instruction. This could probably be optimized by cleaning...
authorGabe Black <gblack@eecs.umich.edu>
Fri, 19 Oct 2007 22:09:37 +0000 (15:09 -0700)
committerGabe Black <gblack@eecs.umich.edu>
Fri, 19 Oct 2007 22:09:37 +0000 (15:09 -0700)
--HG--
extra : convert_revision : ad2d560f2a6f36176b22b8510c58cd6fe5a2c9c2

src/arch/x86/isa/decoder/one_byte_opcodes.isa
src/arch/x86/isa/insts/general_purpose/data_transfer/stack_operations.py

index 4365c23fd7eec795b16df0c9e8cde3cdd9665186..538bb4c3213bbed43648ff97663e0b96995f19e1 100644 (file)
         }
         format WarnUnimpl {
             0x19: decode OPCODE_OP_BOTTOM3 {
-                0x0: enter_Iw_Ib();
+                // The second parameter here should be of size b, but
+                // immediate sizes are determined elsewhere and this would
+                // confuse the instruction type specialization code.
+                0x0: Inst::ENTER(Iw,Iw);
                 0x1: Inst::LEAVE();
                 0x2: ret_far_Iw();
                 0x3: ret_far();
index 5fb2b21720a193165e2557976c8e062fa636b9f0..4c4aec000ec80f42c228c9c73be9259fc605bbf1 100644 (file)
@@ -156,8 +156,51 @@ def macroop LEAVE {
     mov rsp, rsp, t1
     addi rsp, rsp, dsz
 };
+
+def macroop ENTER_I_I {
+    # This needs to check all the addresses it writes to before it actually
+    # writes any values.
+
+    # Pull the different components out of the immediate
+    limm t1, imm
+    zext t2, t1, 16, dataSize=2
+    srl t1, t1, 16
+    zext t1, t1, 6
+    # t1 is now the masked nesting level, and t2 is the amount of storage.
+
+    # Push rbp.
+    st rbp, ss, [1, t0, rsp], "-env.dataSize"
+    subi rsp, rsp, dsz
+
+    # Save the stack pointer for later
+    mov t6, t6, rsp
+
+    # If the nesting level is zero, skip all this stuff.
+    subi t0, t1, t0, flags=(EZF,), dataSize=2
+    bri t0, label("skipLoop"), flags=(CEZF,)
+
+    # If the level was 1, only push the saved rbp
+    subi t0, t1, 1, flags=(EZF,)
+    bri t0, label("bottomOfLoop"), flags=(CEZF,)
+
+    limm t4, "ULL(-1)", dataSize=8
+topOfLoop:
+    ld t5, ss, [dsz, t4, rbp]
+    st t5, ss, [1, t0, rsp], "-env.dataSize"
+    subi rsp, rsp, dsz
+
+    # If we're not done yet, loop
+    subi t4, t4, 1, dataSize=8
+    add t0, t4, t1, flags=(EZF,)
+    bri t0, label("topOfLoop"), flags=(nCEZF,)
+
+bottomOfLoop:
+    # Push the old rbp onto the stack
+    st t6, ss, [1, t0, rsp], "-env.dataSize"
+    subi rsp, rsp, dsz
+
+skipLoop:
+    sub rsp, rsp, t2
+    mov rbp, rbp, t6
+};
 '''
-#let {{
-#    class ENTER(Inst):
-#      "GenFault ${new UnimpInstFault}"
-#}};