1 /* $Id: recode-impl.h,v 1.5 2010/06/05 19:05:00 fredette Exp $ */
2 
3 /* libtme/recode-impl.h - private header file for recode support: */
4 
5 /*
6  * Copyright (c) 2007 Matt Fredette
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  * 3. All advertising materials mentioning features or use of this software
18  *    must display the following acknowledgement:
19  *      This product includes software developed by Matt Fredette.
20  * 4. The name of the author may not be used to endorse or promote products
21  *    derived from this software without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
24  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
27  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
29  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
31  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
32  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33  * POSSIBILITY OF SUCH DAMAGE.
34  */
35 
36 #ifndef _TME_RECODE_IMPL_H
37 #define _TME_RECODE_IMPL_H
38 
39 #include <tme/common.h>
40 _TME_RCSID("$Id: recode-impl.h,v 1.5 2010/06/05 19:05:00 fredette Exp $");
41 
42 /* includes: */
43 #include <tme/recode.h>
44 
45 /* types: */
46 
47 /* a recode TLB type: */
48 struct tme_recode_tlb_type {
49 
50   /* the offset of the memory field: */
51   unsigned long tme_recode_tlb_type_offset_memory;
52 
53   /* the offset of the page field: */
54   unsigned long tme_recode_tlb_type_offset_page;
55 
56   /* the offset of the flags: */
57   unsigned long tme_recode_tlb_type_offset_flags;
58 
59   /* the offset of the token: */
60   unsigned long tme_recode_tlb_type_offset_token;
61 
62   /* the offset of any context: */
63   unsigned long tme_recode_tlb_type_offset_context;
64 
65   /* the size: */
66   unsigned long tme_recode_tlb_type_sizeof;
67 };
68 
69 /* prototypes: */
70 
71 /* this host function starts a new IC: */
72 void tme_recode_host_ic_new _TME_P((struct tme_recode_ic *));
73 
74 /* this host function returns a new flags thunk: */
75 struct tme_recode_flags_thunk *tme_recode_host_flags_thunk_new _TME_P((struct tme_recode_ic *, const struct tme_recode_flags_thunk *, const struct tme_recode_flags_group *));
76 
77 /* this host function adds another flags group to an existing flags thunk: */
78 struct tme_recode_flags_thunk *tme_recode_host_flags_thunk_add _TME_P((struct tme_recode_ic *, struct tme_recode_flags_thunk *, const struct tme_recode_flags_group *));
79 
80 /* this generic function returns a mask of flags that are changed in
81    the same deterministic way (defined, set, clear) by all of the
82    instructions in the group and that are provided by the host,
83    optionally matching only a certain condition: */
84 tme_recode_uguest_t tme_recode_flags_group_flags_defined_host _TME_P((const struct tme_recode_flags_group *, unsigned int));
85 
86 /* this generic function returns the mask of sizes for the given
87    flags: */
88 tme_uint32_t tme_recode_flags_group_sizes _TME_P((const struct tme_recode_flags_group *, tme_recode_uguest_t));
89 
90 /* this returns the offset of the first byte of a flags register: */
91 tme_uint32_t tme_recode_flags_reg_offset _TME_P((unsigned int, tme_uint32_t));
92 
93 /* this host function returns a new conditions thunk: */
94 struct tme_recode_conds_thunk *tme_recode_host_conds_thunk_new _TME_P((struct tme_recode_ic *, const struct tme_recode_conds_group *));
95 
96 /* this generic function returns the maximum index for a conditions
97    group's flags: */
98 tme_uint32_t tme_recode_conds_group_flags_index_max _TME_P((const struct tme_recode_conds_group *));
99 
100 /* this generic function returns the indexed combination of a
101    conditions group's flags: */
102 tme_recode_uguest_t tme_recode_conds_group_flags_from_index _TME_P((const struct tme_recode_conds_group *,
103 								    tme_uint32_t));
104 
105 /* this generic function returns a simple mask of a conditions group's
106    flags and one or more bitwise operations that can be used with the
107    mask to test the given condition.  it returns zero if the condition
108    can't be tested with a simple mask: */
109 tme_uint32_t tme_recode_conds_simple_mask _TME_P((const struct tme_recode_conds_group *,
110 						  tme_uint32_t,
111 						  tme_recode_uguest_t *));
112 
113 /* this host function returns a new read/write thunk: */
114 struct tme_recode_rw_thunk *tme_recode_host_rw_thunk_new _TME_P((struct tme_recode_ic *, const struct tme_recode_rw *));
115 
116 /* this host function tries to duplicate a read/write thunk: */
117 struct tme_recode_rw_thunk *tme_recode_host_rw_thunk_dup _TME_P((struct tme_recode_ic *, const struct tme_recode_rw *, const struct tme_recode_rw *));
118 
119 /* this generic function frees all host registers, starting from the
120    given host register: */
121 void tme_recode_regs_host_free_many _TME_P((struct tme_recode_ic *,
122 					    unsigned long));
123 
124 /* this cleans all dirty host registers, freeing those that weren't
125    dirty at the full guest register size: */
126 void tme_recode_regs_host_clean_all _TME_P((struct tme_recode_ic *ic));
127 
128 /* this generic function returns any best host register with the
129    smallest read-uses count less than the given count: */
130 unsigned long tme_recode_regs_host_best _TME_P((const struct tme_recode_ic *,
131 						tme_uint32_t));
132 
133 /* this generic function frees and returns a specific host
134    register: */
135 unsigned long tme_recode_regs_host_free_specific _TME_P((struct tme_recode_ic *,
136 							 unsigned long));
137 
138 /* this generic function reserves one host register, and returns the
139    host register: */
140 unsigned long tme_recode_regs_host_reserve _TME_P((struct tme_recode_ic *,
141 						   unsigned long));
142 
143 /* this generic function unreserves all host registers: */
144 void tme_recode_regs_host_unreserve_all _TME_P((struct tme_recode_ic *));
145 
146 /* this notifies about a source operand before a call to
147    tme_recode_regs_src_any() or tme_recode_regs_src_specific().  calls
148    to this function aren't needed for correctness, but they may enable
149    optimizations.  if called, the next call to
150    tme_recode_regs_src_any() or tme_recode_regs_src_specific() *must*
151    be for the same source operand: */
152 void tme_recode_regs_src_notify _TME_P((struct tme_recode_ic *,
153 					const struct tme_recode_insn *,
154 					signed long));
155 
156 /* this generic function loads an instruction source operand into any
157    host register, and reserves and returns the host register: */
158 unsigned long tme_recode_regs_src_any _TME_P((struct tme_recode_ic *,
159 					      const struct tme_recode_insn *,
160 					      signed long));
161 
162 /* this generic function loads an instruction source operand into a
163    specific host register, and reserves and returns that host
164    register: */
165 unsigned long tme_recode_regs_src_specific _TME_P((struct tme_recode_ic *,
166 						   const struct tme_recode_insn *,
167 						   signed long,
168 						   unsigned long));
169 
170 /* this generic function allocates any host register for the
171    instruction destination operand, and returns the host register: */
172 unsigned long tme_recode_regs_dst_any _TME_P((struct tme_recode_ic *,
173 					      const struct tme_recode_insn *));
174 
175 /* this generic function allocates a specific host register for the
176    instruction destination operand and returns the host register: */
177 unsigned long tme_recode_regs_dst_specific _TME_P((struct tme_recode_ic *,
178 						   const struct tme_recode_insn *,
179 						   unsigned long));
180 
181 /* this host function loads or stores a host register: */
182 void tme_recode_host_reg_move _TME_P((struct tme_recode_ic *,
183 				      tme_uint32_t,
184 				      tme_uint32_t));
185 
186 /* this host function copies a host register into another host register: */
187 void tme_recode_host_reg_copy _TME_P((struct tme_recode_ic *,
188 				      unsigned long,
189 				      unsigned long));
190 
191 /* this host function zeroes a host register, and reserves and returns
192    the host register: */
193 unsigned long tme_recode_host_reg_zero _TME_P((struct tme_recode_ic *,
194 					       const struct tme_recode_insn *,
195 					       unsigned long));
196 
197 /* this host function loads a host register with an immediate, and
198    reserves and returns the host register: */
199 unsigned long tme_recode_host_reg_imm _TME_P((struct tme_recode_ic *,
200 					      const struct tme_recode_insn *,
201 					      unsigned long));
202 
203 /* this host function returns a new instructions thunk: */
204 tme_recode_thunk_off_t tme_recode_host_insns_thunk_new _TME_P((struct tme_recode_ic *,
205 							       const struct tme_recode_insns_group *));
206 
207 /* this host function allocates memory for building and running thunks: */
208 void tme_recode_host_thunks_alloc _TME_P((struct tme_recode_ic *, tme_recode_thunk_off_t));
209 
210 /* this host function starts building a new thunk.  it returns nonzero
211    if a thunk of TME_RECODE_HOST_THUNK_SIZE_MAX bytes can be built: */
212 int tme_recode_host_thunk_start _TME_P((struct tme_recode_ic *));
213 
214 /* this host function finishes building a new thunk: */
215 void tme_recode_host_thunk_finish _TME_P((struct tme_recode_ic *));
216 
217 /* this host function invalidates all thunks starting from the given
218    thunk offset: */
219 void tme_recode_host_thunk_invalidate_all _TME_P((struct tme_recode_ic *, tme_recode_thunk_off_t));
220 
221 /* this generic function checks an address information structure: */
222 void tme_recode_address_type_check _TME_P((const struct tme_recode_ic *,
223 					   const struct tme_recode_address_type *));
224 
225 /* this generic function returns zero if two address information
226    structures are the same: */
227 int tme_recode_address_type_compare _TME_P((const struct tme_recode_ic *,
228 					    const struct tme_recode_address_type *,
229 					    const struct tme_recode_address_type *));
230 
231 /* this returns the recode TLB type for an address type: */
232 void tme_recode_address_type_tlb_type _TME_P((const struct tme_recode_ic *,
233 					      const struct tme_recode_address_type *,
234 					      struct tme_recode_tlb_type *));
235 
236 #ifdef TME_RECODE_DEBUG
237 
238 /* this host function dumps a flags thunk: */
239 void tme_recode_host_flags_thunk_dump _TME_P((_tme_const struct tme_recode_ic *,
240 					      _tme_const struct tme_recode_flags_thunk *));
241 
242 /* this host function dumps a conditions thunk: */
243 void tme_recode_host_conds_thunk_dump _TME_P((_tme_const struct tme_recode_ic *,
244 					      _tme_const struct tme_recode_conds_thunk *,
245 					      _tme_const char * _tme_const *));
246 
247 #endif /* TME_RECODE_DEBUG */
248 
249 #endif /* _TME_RECODE_IMPL_H */
250