Gabe Black has uploaded this change for review. (
https://gem5-review.googlesource.com/c/public/gem5/+/55623 )
Change subject: arch-x86: Implement real mode far call.
......................................................................
arch-x86: Implement real mode far call.
Change-Id: I720a0b0e4aa227171c59804d899baba64b8d320b
---
M src/arch/x86/isa/decoder/one_byte_opcodes.isa
M src/arch/x86/isa/insts/general_purpose/control_transfer/call.py
2 files changed, 84 insertions(+), 1 deletion(-)
diff --git a/src/arch/x86/isa/decoder/one_byte_opcodes.isa
b/src/arch/x86/isa/decoder/one_byte_opcodes.isa
index e369621..64e10ba 100644
--- a/src/arch/x86/isa/decoder/one_byte_opcodes.isa
+++ b/src/arch/x86/isa/decoder/one_byte_opcodes.isa
@@ -305,6 +305,7 @@
0x1: CQO(rAv,rDv);
0x2: decode MODE_SUBMODE {
0x0: UD2();
+ 0x4: CALL_FAR_REAL(Iz);
default: WarnUnimpl::call_far_Ap();
}
0x3: WarnUnimpl::fwait(); //aka wait
@@ -568,7 +569,10 @@
0x0: INC(Ev);
0x1: DEC(Ev);
0x2: CALL_NEAR(Ev);
- 0x3: WarnUnimpl::call_far_Mp();
+ 0x3: decode MODE_SUBMODE {
+ 0x4: CALL_FAR_REAL(Mz);
+ default: WarnUnimpl::call_far_Mp();
+ }
0x4: JMP(Ev);
0x5: decode MODE_SUBMODE {
0x0: JMP_FAR(Mz);
diff --git
a/src/arch/x86/isa/insts/general_purpose/control_transfer/call.py
b/src/arch/x86/isa/insts/general_purpose/control_transfer/call.py
index 8000bc3..5e4b072 100644
--- a/src/arch/x86/isa/insts/general_purpose/control_transfer/call.py
+++ b/src/arch/x86/isa/insts/general_purpose/control_transfer/call.py
@@ -92,6 +92,76 @@
subi rsp, rsp, dsz, dataSize=ssz
wripi t1, 0
};
+
+def macroop CALL_FAR_REAL_I {
+ .function_call
+ .control_indirect
+
+ limm t1, imm, dataSize=8
+
+ # Multiply the data size by 8 to get the size of the offset in bits.
+ limm t3, dsz, dataSize=8
+ slli t3, t3, 3, dataSize=8
+
+ # Extract the selector from the far pointer.
+ srl t2, t1, t3, dataSize=8
+ # Extract the offset from the far pointer.
+ zext t1, t1, t3, dataSize=8
+
+ # Compute the base.
+ slli t3, t2, 4, dataSize=8
+
+ # Make sure pushing the RIP will work after we push cs.
+ cda ss, [1, t0, rsp], "-env.dataSize * 2", addressSize=ssz
+
+ # Push CS.
+ rdsel t4, cs, dataSize=8
+ st t4, ss, [1, t0, rsp], "-env.dataSize", addressSize=ssz
+ # Push RIP.
+ rdip t7
+ st t7, ss, [1, t0, rsp], "-env.dataSize * 2", addressSize=ssz
+ subi rsp, rsp, "env.dataSize * 2", dataSize=ssz
+
+ # Install the new selector, base and RIP values.
+ wrsel cs, t2, dataSize=2
+ wrbase cs, t3, dataSize=8
+ wrip t1, t0
+};
+
+def macroop CALL_FAR_REAL_M {
+ .function_call
+ .control_indirect
+
+ lea t1, seg, sib, disp, dataSize=asz
+ # Load the selector.
+ ld t2, seg, [1, t0, t1], dsz, dataSize=2
+ # Load the offset.
+ ld t1, seg, [1, t0, t1]
+
+ # Compute the base.
+ zexti t3, t2, 15, dataSize=8
+ slli t3, t3, 4, dataSize=8
+
+ # Make sure pushing the RIP will work after we push cs.
+ cda ss, [1, t0, rsp], "-env.dataSize * 2", addressSize=ssz
+
+ # Push CS.
+ rdsel t4, cs, dataSize=8
+ st t4, ss, [1, t0, rsp], "-env.dataSize", addressSize=ssz
+ # Push RIP.
+ rdip t7
+ st t7, ss, [1, t0, rsp], "-env.dataSize * 2", addressSize=ssz
+ subi rsp, rsp, "env.dataSize * 2", dataSize=ssz
+
+ # Install the new selector, base and RIP values.
+ wrsel cs, t2, dataSize=2
+ wrbase cs, t3, dataSize=8
+ wrip t1, t0
+};
+
+def macroop CALL_FAR_REAL_P {
+ panic "Far call in real mode doesn't support RIP addressing."
+};
'''
#let {{
# class CALL(Inst):
--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/55623
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: I720a0b0e4aa227171c59804d899baba64b8d320b
Gerrit-Change-Number: 55623
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