summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGabe Black <gblack@eecs.umich.edu>2007-10-19 15:09:37 -0700
committerGabe Black <gblack@eecs.umich.edu>2007-10-19 15:09:37 -0700
commit7f373225328afdf17875f73ee039a666eaafef0b (patch)
tree98b32eeb596e73adf38304282ce122b3914c4711 /src
parent63f4281d9da864ccd466df1acca2f7c0bec0cfee (diff)
downloadgem5-7f373225328afdf17875f73ee039a666eaafef0b.tar.xz
X86: Implement the ENTER instruction. This could probably be optimized by cleaning up the indexing in the main loop.
--HG-- extra : convert_revision : ad2d560f2a6f36176b22b8510c58cd6fe5a2c9c2
Diffstat (limited to 'src')
-rw-r--r--src/arch/x86/isa/decoder/one_byte_opcodes.isa5
-rw-r--r--src/arch/x86/isa/insts/general_purpose/data_transfer/stack_operations.py51
2 files changed, 51 insertions, 5 deletions
diff --git a/src/arch/x86/isa/decoder/one_byte_opcodes.isa b/src/arch/x86/isa/decoder/one_byte_opcodes.isa
index 4365c23fd..538bb4c32 100644
--- a/src/arch/x86/isa/decoder/one_byte_opcodes.isa
+++ b/src/arch/x86/isa/decoder/one_byte_opcodes.isa
@@ -394,7 +394,10 @@
}
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();
diff --git a/src/arch/x86/isa/insts/general_purpose/data_transfer/stack_operations.py b/src/arch/x86/isa/insts/general_purpose/data_transfer/stack_operations.py
index 5fb2b2172..4c4aec000 100644
--- a/src/arch/x86/isa/insts/general_purpose/data_transfer/stack_operations.py
+++ b/src/arch/x86/isa/insts/general_purpose/data_transfer/stack_operations.py
@@ -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}"
-#}};