1 /////////////////////////////////////////////////////////////////////////
2 // $Id: stack.h 13699 2019-12-20 07:42:07Z sshwarts $
3 /////////////////////////////////////////////////////////////////////////
4 //
5 //   Copyright (c) 2007-2012 Stanislav Shwartsman
6 //          Written by Stanislav Shwartsman [sshwarts at sourceforge net]
7 //
8 //  This library is free software; you can redistribute it and/or
9 //  modify it under the terms of the GNU Lesser General Public
10 //  License as published by the Free Software Foundation; either
11 //  version 2 of the License, or (at your option) any later version.
12 //
13 //  This library is distributed in the hope that it will be useful,
14 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
15 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 //  Lesser General Public License for more details.
17 //
18 //  You should have received a copy of the GNU Lesser General Public
19 //  License along with this library; if not, write to the Free Software
20 //  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA B 02110-1301 USA
21 //
22 /////////////////////////////////////////////////////////////////////////
23 
24 #ifndef BX_PUSHPOP_H
25 #define BX_PUSHPOP_H
26 
27   BX_CPP_INLINE void BX_CPP_AttrRegparmN(1)
push_16(Bit16u value16)28 BX_CPU_C::push_16(Bit16u value16)
29 {
30 #if BX_SUPPORT_X86_64
31   if (long64_mode()) { /* StackAddrSize = 64 */
32     stack_write_word(RSP-2, value16);
33     RSP -= 2;
34   }
35   else
36 #endif
37   if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) { /* StackAddrSize = 32 */
38     stack_write_word((Bit32u) (ESP-2), value16);
39     ESP -= 2;
40   }
41   else /* StackAddrSize = 16 */
42   {
43     stack_write_word((Bit16u) (SP-2), value16);
44     SP -= 2;
45   }
46 }
47 
48   BX_CPP_INLINE void BX_CPP_AttrRegparmN(1)
push_32(Bit32u value32)49 BX_CPU_C::push_32(Bit32u value32)
50 {
51 #if BX_SUPPORT_X86_64
52   if (long64_mode()) { /* StackAddrSize = 64 */
53     stack_write_dword(RSP-4, value32);
54     RSP -= 4;
55   }
56   else
57 #endif
58   if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) { /* StackAddrSize = 32 */
59     stack_write_dword((Bit32u) (ESP-4), value32);
60     ESP -= 4;
61   }
62   else /* StackAddrSize = 16 */
63   {
64     stack_write_dword((Bit16u) (SP-4), value32);
65     SP -= 4;
66   }
67 }
68 
69 /* push 64 bit operand */
70 #if BX_SUPPORT_X86_64
71   BX_CPP_INLINE void BX_CPP_AttrRegparmN(1)
push_64(Bit64u value64)72 BX_CPU_C::push_64(Bit64u value64)
73 {
74   /* StackAddrSize = 64 */
75   stack_write_qword(RSP-8, value64);
76   RSP -= 8;
77 }
78 #endif
79 
80 /* pop 16 bit operand from the stack */
pop_16(void)81 BX_CPP_INLINE Bit16u BX_CPU_C::pop_16(void)
82 {
83   Bit16u value16;
84 
85 #if BX_SUPPORT_X86_64
86   if (long64_mode()) { /* StackAddrSize = 64 */
87     value16 = stack_read_word(RSP);
88     RSP += 2;
89   }
90   else
91 #endif
92   if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) { /* StackAddrSize = 32 */
93     value16 = stack_read_word(ESP);
94     ESP += 2;
95   }
96   else { /* StackAddrSize = 16 */
97     value16 = stack_read_word(SP);
98     SP += 2;
99   }
100 
101   return value16;
102 }
103 
104 /* pop 32 bit operand from the stack */
pop_32(void)105 BX_CPP_INLINE Bit32u BX_CPU_C::pop_32(void)
106 {
107   Bit32u value32;
108 
109 #if BX_SUPPORT_X86_64
110   if (long64_mode()) { /* StackAddrSize = 64 */
111     value32 = stack_read_dword(RSP);
112     RSP += 4;
113   }
114   else
115 #endif
116   if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) { /* StackAddrSize = 32 */
117     value32 = stack_read_dword(ESP);
118     ESP += 4;
119   }
120   else { /* StackAddrSize = 16 */
121     value32 = stack_read_dword(SP);
122     SP += 4;
123   }
124 
125   return value32;
126 }
127 
128 /* pop 64 bit operand from the stack */
129 #if BX_SUPPORT_X86_64
pop_64(void)130 BX_CPP_INLINE Bit64u BX_CPU_C::pop_64(void)
131 {
132   /* StackAddrSize = 64 */
133   Bit64u value64 = stack_read_qword(RSP);
134   RSP += 8;
135   return value64;
136 }
137 #endif // BX_SUPPORT_X86_64
138 
139 #if BX_SUPPORT_CET
shadow_stack_push_32(Bit32u value32)140 BX_CPP_INLINE void BX_CPP_AttrRegparmN(1) BX_CPU_C::shadow_stack_push_32(Bit32u value32)
141 {
142   shadow_stack_write_dword(SSP-4, CPL, value32);
143   SSP -= 4;
144 }
145 
shadow_stack_push_64(Bit64u value64)146 BX_CPP_INLINE void BX_CPP_AttrRegparmN(1) BX_CPU_C::shadow_stack_push_64(Bit64u value64)
147 {
148   shadow_stack_write_qword(SSP-8, CPL, value64);
149   SSP -= 8;
150 }
151 
shadow_stack_pop_32(void)152 BX_CPP_INLINE Bit32u BX_CPU_C::shadow_stack_pop_32(void)
153 {
154   Bit32u value32 = shadow_stack_read_dword(SSP, CPL);
155   SSP += 4;
156   return value32;
157 }
158 
shadow_stack_pop_64(void)159 BX_CPP_INLINE Bit64u BX_CPU_C::shadow_stack_pop_64(void)
160 {
161   Bit64u value64 = shadow_stack_read_qword(SSP, CPL);
162   SSP += 8;
163   return value64;
164 }
165 
166 #endif // BX_SUPPORT_X86_64
167 
168 #endif
169