1# Copyright (c) 2013 Andreas Sandberg
2# All rights reserved.
3#
4# Redistribution and use in source and binary forms, with or without
5# modification, are permitted provided that the following conditions are
6# met: redistributions of source code must retain the above copyright
7# notice, this list of conditions and the following disclaimer;
8# redistributions in binary form must reproduce the above copyright
9# notice, this list of conditions and the following disclaimer in the
10# documentation and/or other materials provided with the distribution;
11# neither the name of the copyright holders nor the names of its
12# contributors may be used to endorse or promote products derived from
13# this software without specific prior written permission.
14#
15# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26#
27# Authors: Andreas Sandberg
28
29# Register usage:
30#  t1, t2 == temporaries
31#  t7 == base address (RIP or SIB)
32
33
34loadX87RegTemplate =  '''
35    ld t1, seg, %(mode)s, "DISPLACEMENT + 32 + 16 * %(idx)i", dataSize=8
36    ld t2, seg, %(mode)s, "DISPLACEMENT + 32 + 16 * %(idx)i + 8", dataSize=2
37    cvtint_fp80 st(%(idx)i), t1, t2
38'''
39
40storeX87RegTemplate = '''
41    cvtfp80h_int t1, st(%(idx)i)
42    cvtfp80l_int t2, st(%(idx)i)
43    st t1, seg, %(mode)s, "DISPLACEMENT + 32 + 16 * %(idx)i", dataSize=8
44    st t2, seg, %(mode)s, "DISPLACEMENT + 32 + 16 * %(idx)i + 8", dataSize=2
45'''
46
47loadXMMRegTemplate =  '''
48    ldfp "InstRegIndex(FLOATREG_XMM_LOW(%(idx)i))", seg, %(mode)s, \
49         "DISPLACEMENT + 160 + 16 * %(idx)i", dataSize=8
50    ldfp "InstRegIndex(FLOATREG_XMM_HIGH(%(idx)i))", seg, %(mode)s, \
51         "DISPLACEMENT + 160 + 16 * %(idx)i + 8", dataSize=8
52'''
53
54storeXMMRegTemplate =  '''
55    stfp "InstRegIndex(FLOATREG_XMM_LOW(%(idx)i))", seg, %(mode)s, \
56         "DISPLACEMENT + 160 + 16 * %(idx)i", dataSize=8
57    stfp "InstRegIndex(FLOATREG_XMM_HIGH(%(idx)i))", seg, %(mode)s, \
58         "DISPLACEMENT + 160 + 16 * %(idx)i + 8", dataSize=8
59'''
60
61loadAllDataRegs = \
62    "".join([loadX87RegTemplate % { "idx" : i, "mode" : "%(mode)s" }
63             for i in range(8)]) + \
64    "".join([loadXMMRegTemplate % { "idx" : i, "mode" : "%(mode)s" }
65             for i in range(16)])
66
67storeAllDataRegs = \
68    "".join([storeX87RegTemplate % { "idx" : i, "mode" : "%(mode)s" }
69             for i in range(8)]) + \
70    "".join([storeXMMRegTemplate % { "idx" : i, "mode" : "%(mode)s" }
71             for i in range(16)])
72
73fxsaveCommonTemplate = """
74    rdval t1, fcw
75    st t1, seg, %(mode)s, "DISPLACEMENT + 0", dataSize=2
76
77    # FSW includes TOP when read
78    rdval t1, fsw
79    st t1, seg, %(mode)s, "DISPLACEMENT + 2", dataSize=2
80
81    # FTW
82    rdxftw t1
83    st t1, seg, %(mode)s, "DISPLACEMENT + 4", dataSize=1
84
85    rdval t1, "InstRegIndex(MISCREG_FOP)"
86    st t1, seg, %(mode)s, "DISPLACEMENT + 6", dataSize=2
87
88    rdval t1, "InstRegIndex(MISCREG_MXCSR)"
89    st t1, seg, %(mode)s, "DISPLACEMENT + 16 + 8", dataSize=4
90
91    # MXCSR_MASK, software assumes the default (0xFFBF) if 0.
92    limm t1, 0xFFFF
93    st t1, seg, %(mode)s, "DISPLACEMENT + 16 + 12", dataSize=4
94""" + storeAllDataRegs
95
96fxsave32Template = """
97    rdval t1, "InstRegIndex(MISCREG_FIOFF)"
98    st t1, seg, %(mode)s, "DISPLACEMENT + 8", dataSize=4
99
100    rdval t1, "InstRegIndex(MISCREG_FISEG)"
101    st t1, seg, %(mode)s, "DISPLACEMENT + 12", dataSize=2
102
103    rdval t1, "InstRegIndex(MISCREG_FOOFF)"
104    st t1, seg, %(mode)s, "DISPLACEMENT + 16 + 0", dataSize=4
105
106    rdval t1, "InstRegIndex(MISCREG_FOSEG)"
107    st t1, seg, %(mode)s, "DISPLACEMENT + 16 + 4", dataSize=2
108""" + fxsaveCommonTemplate
109
110fxsave64Template = """
111    rdval t1, "InstRegIndex(MISCREG_FIOFF)"
112    st t1, seg, %(mode)s, "DISPLACEMENT + 8", dataSize=8
113
114    rdval t1, "InstRegIndex(MISCREG_FOOFF)"
115    st t1, seg, %(mode)s, "DISPLACEMENT + 16 + 0", dataSize=8
116""" + fxsaveCommonTemplate
117
118fxrstorCommonTemplate = """
119    ld t1, seg, %(mode)s, "DISPLACEMENT + 0", dataSize=2
120    wrval fcw, t1
121
122    # FSW includes TOP when read
123    ld t1, seg, %(mode)s, "DISPLACEMENT + 2", dataSize=2
124    wrval fsw, t1
125
126    # FTW
127    ld t1, seg, %(mode)s, "DISPLACEMENT + 4", dataSize=1
128    wrxftw t1
129
130    ld t1, seg, %(mode)s, "DISPLACEMENT + 6", dataSize=2
131    wrval "InstRegIndex(MISCREG_FOP)", t1
132
133    ld t1, seg, %(mode)s, "DISPLACEMENT + 16 + 8", dataSize=4
134    wrval "InstRegIndex(MISCREG_MXCSR)", t1
135""" + loadAllDataRegs
136
137fxrstor32Template = """
138    ld t1, seg, %(mode)s, "DISPLACEMENT + 8", dataSize=4
139    wrval "InstRegIndex(MISCREG_FIOFF)", t1
140
141    ld t1, seg, %(mode)s, "DISPLACEMENT + 12", dataSize=2
142    wrval "InstRegIndex(MISCREG_FISEG)", t1
143
144    ld t1, seg, %(mode)s, "DISPLACEMENT + 16 + 0", dataSize=4
145    wrval "InstRegIndex(MISCREG_FOOFF)", t1
146
147    ld t1, seg, %(mode)s, "DISPLACEMENT + 16 + 4", dataSize=2
148    wrval "InstRegIndex(MISCREG_FOSEG)", t1
149""" + fxrstorCommonTemplate
150
151fxrstor64Template = """
152    limm t2, 0, dataSize=8
153
154    ld t1, seg, %(mode)s, "DISPLACEMENT + 8", dataSize=8
155    wrval "InstRegIndex(MISCREG_FIOFF)", t1
156    wrval "InstRegIndex(MISCREG_FISEG)", t2
157
158    ld t1, seg, %(mode)s, "DISPLACEMENT + 16 + 0", dataSize=8
159    wrval "InstRegIndex(MISCREG_FOOFF)", t1
160    wrval "InstRegIndex(MISCREG_FOSEG)", t2
161""" + fxrstorCommonTemplate
162
163microcode = '''
164def macroop FXSAVE_M {
165''' + fxsave32Template % { "mode" : "sib" } + '''
166};
167
168def macroop FXSAVE_P {
169    rdip t7
170''' + fxsave32Template % { "mode" : "riprel" } + '''
171};
172
173def macroop FXSAVE64_M {
174''' + fxsave64Template % { "mode" : "sib" } + '''
175};
176
177def macroop FXSAVE64_P {
178    rdip t7
179''' + fxsave64Template % { "mode" : "riprel" } + '''
180};
181
182def macroop FXRSTOR_M {
183''' + fxrstor32Template % { "mode" : "sib" } + '''
184};
185
186def macroop FXRSTOR_P {
187    rdip t7
188''' + fxrstor32Template % { "mode" : "riprel" } + '''
189};
190
191def macroop FXRSTOR64_M {
192''' + fxrstor64Template % { "mode" : "sib" } + '''
193};
194
195def macroop FXRSTOR64_P {
196    rdip t7
197''' + fxrstor64Template % { "mode" : "riprel" } + '''
198};
199'''
200