summaryrefslogtreecommitdiff
path: root/MdeModulePkg/Universal/EbcDxe
diff options
context:
space:
mode:
Diffstat (limited to 'MdeModulePkg/Universal/EbcDxe')
-rw-r--r--MdeModulePkg/Universal/EbcDxe/Ipf/EbcLowLevel.s78
1 files changed, 57 insertions, 21 deletions
diff --git a/MdeModulePkg/Universal/EbcDxe/Ipf/EbcLowLevel.s b/MdeModulePkg/Universal/EbcDxe/Ipf/EbcLowLevel.s
index 4c0f80fb02..26b3c48616 100644
--- a/MdeModulePkg/Universal/EbcDxe/Ipf/EbcLowLevel.s
+++ b/MdeModulePkg/Universal/EbcDxe/Ipf/EbcLowLevel.s
@@ -121,30 +121,66 @@ PROCEDURE_ENTRY(EbcAsmLLCALLEX)
PROCEDURE_EXIT(EbcAsmLLCALLEX)
+//-----------------------------------------------------------------------------
+//++
+// EbcLLCALLEXNative
+//
+// This function is called to execute an EBC CALLEX instruction.
+// This instruction requires that we thunk out to external native
+// code. On return, we restore the stack pointer to its original location.
+// Destroys no working registers. For IPF, at least 8 register slots
+// must be allocated on the stack frame to support any number of
+// arguments beiung passed to the external native function. The
+// size of the stack frame is FramePtr - EbcSp. If this size is less
+// than 64-bytes, the amount of stack frame allocated is rounded up
+// to 64-bytes
+//
+// Arguments On Entry :
+// in0 = CallAddr The function address.
+// in1 = EbcSp The new EBC stack pointer.
+// in2 = FramePtr The frame pointer.
+//
+// Return Value:
+// None
+//
+// C Function Prototype:
+// VOID
+// EFIAPI
+// EbcLLCALLEXNative (
+// IN UINTN CallAddr,
+// IN UINTN EbcSp,
+// IN VOID *FramePtr
+// );
+//--
+//---------------------------------------------------------------------------
+
PROCEDURE_ENTRY(EbcLLCALLEXNative)
NESTED_SETUP (3,6,3,0)
- mov loc2 = in2;;
- mov loc3 = in1;;
- sub loc2 = loc2, loc3
- mov loc4 = r12;;
- or loc5 = r1, r0
-
- sub r12 = r12, loc2
- mov out2 = loc2;;
-
- and r12 = -0x10, r12
- mov out1 = in1;;
- mov out0 = r12;;
- adds r12 = -0x8, r12
- (p0) br.call.dptk.many b0 = CopyMem;;
- adds r12 = 0x8, r12
-
- mov out0 = in0;;
- mov out1 = r12;;
- (p0) br.call.dptk.many b0 = EbcAsmLLCALLEX;;
- mov r12 = loc4;;
- or r1 = loc5, r0
+ mov loc2 = in2;; // loc2 = in2 = FramePtr
+ mov loc3 = in1;; // loc3 = in1 = EbcSp
+ sub loc2 = loc2, loc3;; // loc2 = loc2 - loc3 = FramePtr - EbcSp
+ mov out2 = loc2;; // out2 = loc2 = FramePtr - EbcSp
+ mov loc4 = 0x40;; // loc4 = 0x40
+ cmp.leu p6 = out2, loc4;; // IF out2 < loc4 THEN P6=1 ELSE P6=0; IF (FramePtr - EbcSp) < 0x40 THEN P6 = 1 ELSE P6=0
+ (p6) mov loc2 = loc4;; // IF P6==1 THEN loc2 = loc4 = 0x40
+ mov loc4 = r12;; // save sp
+ or loc5 = r1, r0 // save gp
+
+ sub r12 = r12, loc2;; // sp = sp - loc2 = sp - MAX (0x40, FramePtr - EbcSp)
+
+ and r12 = -0x10, r12 // Round sp down to the nearest 16-byte boundary
+ mov out1 = in1;; // out1 = EbcSp
+ mov out0 = r12;; // out0 = sp
+ adds r12 = -0x8, r12
+ (p0) br.call.dptk.many b0 = CopyMem;; // CopyMem (sp, EbcSp, (FramePtr - EbcSp))
+ adds r12 = 0x8, r12
+
+ mov out0 = in0;; // out0 = CallAddr
+ mov out1 = r12;; // out1 = sp
+ (p0) br.call.dptk.many b0 = EbcAsmLLCALLEX;; // EbcAsmLLCALLEX (CallAddr, sp)
+ mov r12 = loc4;; // restore sp
+ or r1 = loc5, r0 // restore gp
NESTED_RETURN
PROCEDURE_EXIT(EbcLLCALLEXNative)