]>
Commit | Line | Data |
---|---|---|
e6d6c4be LV |
1 | # -*- coding: utf-8 -*- |
2 | ||
3 | """ | |
4 | Type-transformation rules. | |
5 | """ | |
6 | ||
7 | __author__ = "Lluís Vilanova <vilanova@ac.upc.edu>" | |
3d211d9f | 8 | __copyright__ = "Copyright 2012-2016, Lluís Vilanova <vilanova@ac.upc.edu>" |
e6d6c4be LV |
9 | __license__ = "GPL version 2 or (at your option) any later version" |
10 | ||
11 | __maintainer__ = "Stefan Hajnoczi" | |
12 | __email__ = "stefanha@linux.vnet.ibm.com" | |
13 | ||
14 | ||
15 | def _transform_type(type_, trans): | |
16 | if isinstance(trans, str): | |
17 | return trans | |
18 | elif isinstance(trans, dict): | |
19 | if type_ in trans: | |
20 | return _transform_type(type_, trans[type_]) | |
21 | elif None in trans: | |
22 | return _transform_type(type_, trans[None]) | |
23 | else: | |
24 | return type_ | |
25 | elif callable(trans): | |
26 | return trans(type_) | |
27 | else: | |
28 | raise ValueError("Invalid type transformation rule: %s" % trans) | |
29 | ||
30 | ||
31 | def transform_type(type_, *trans): | |
32 | """Return a new type transformed according to the given rules. | |
33 | ||
34 | Applies each of the transformation rules in trans in order. | |
35 | ||
36 | If an element of trans is a string, return it. | |
37 | ||
38 | If an element of trans is a function, call it with type_ as its only | |
39 | argument. | |
40 | ||
41 | If an element of trans is a dict, search type_ in its keys. If type_ is | |
42 | a key, use the value as a transformation rule for type_. Otherwise, if | |
43 | None is a key use the value as a transformation rule for type_. | |
44 | ||
45 | Otherwise, return type_. | |
46 | ||
47 | Parameters | |
48 | ---------- | |
49 | type_ : str | |
50 | Type to transform. | |
51 | trans : list of function or dict | |
52 | Type transformation rules. | |
53 | """ | |
54 | if len(trans) == 0: | |
55 | raise ValueError | |
56 | res = type_ | |
57 | for t in trans: | |
58 | res = _transform_type(res, t) | |
59 | return res | |
60 | ||
61 | ||
62 | ################################################## | |
63 | # tcg -> host | |
64 | ||
65 | def _tcg_2_host(type_): | |
66 | if type_ == "TCGv": | |
67 | # force a fixed-size type (target-independent) | |
68 | return "uint64_t" | |
69 | else: | |
70 | return type_ | |
71 | ||
72 | TCG_2_HOST = { | |
73 | "TCGv_i32": "uint32_t", | |
74 | "TCGv_i64": "uint64_t", | |
75 | "TCGv_ptr": "void *", | |
76 | None: _tcg_2_host, | |
77 | } | |
78 | ||
79 | ||
80 | ################################################## | |
81 | # host -> host compatible with tcg sizes | |
82 | ||
83 | HOST_2_TCG_COMPAT = { | |
84 | "uint8_t": "uint32_t", | |
504f73f7 | 85 | "uint16_t": "uint32_t", |
e6d6c4be LV |
86 | } |
87 | ||
88 | ||
89 | ################################################## | |
90 | # host/tcg -> tcg | |
91 | ||
92 | def _host_2_tcg(type_): | |
93 | if type_.startswith("TCGv"): | |
94 | return type_ | |
95 | raise ValueError("Don't know how to translate '%s' into a TCG type\n" % type_) | |
96 | ||
97 | HOST_2_TCG = { | |
98 | "uint32_t": "TCGv_i32", | |
99 | "uint64_t": "TCGv_i64", | |
100 | "void *" : "TCGv_ptr", | |
3d211d9f | 101 | "CPUArchState *": "TCGv_env", |
e6d6c4be LV |
102 | None: _host_2_tcg, |
103 | } | |
104 | ||
105 | ||
106 | ################################################## | |
107 | # tcg -> tcg helper definition | |
108 | ||
109 | def _tcg_2_helper_def(type_): | |
110 | if type_ == "TCGv": | |
111 | return "target_ulong" | |
112 | else: | |
113 | return type_ | |
114 | ||
115 | TCG_2_TCG_HELPER_DEF = { | |
116 | "TCGv_i32": "uint32_t", | |
117 | "TCGv_i64": "uint64_t", | |
118 | "TCGv_ptr": "void *", | |
119 | None: _tcg_2_helper_def, | |
120 | } | |
121 | ||
122 | ||
123 | ################################################## | |
124 | # tcg -> tcg helper declaration | |
125 | ||
126 | def _tcg_2_tcg_helper_decl_error(type_): | |
127 | raise ValueError("Don't know how to translate type '%s' into a TCG helper declaration type\n" % type_) | |
128 | ||
129 | TCG_2_TCG_HELPER_DECL = { | |
130 | "TCGv" : "tl", | |
131 | "TCGv_ptr": "ptr", | |
132 | "TCGv_i32": "i32", | |
133 | "TCGv_i64": "i64", | |
3d211d9f | 134 | "TCGv_env": "env", |
e6d6c4be LV |
135 | None: _tcg_2_tcg_helper_decl_error, |
136 | } | |
137 | ||
138 | ||
139 | ################################################## | |
140 | # host/tcg -> tcg temporal constant allocation | |
141 | ||
142 | def _host_2_tcg_tmp_new(type_): | |
143 | if type_.startswith("TCGv"): | |
144 | return "tcg_temp_new_nop" | |
145 | raise ValueError("Don't know how to translate type '%s' into a TCG temporal allocation" % type_) | |
146 | ||
147 | HOST_2_TCG_TMP_NEW = { | |
148 | "uint32_t": "tcg_const_i32", | |
149 | "uint64_t": "tcg_const_i64", | |
150 | "void *" : "tcg_const_ptr", | |
151 | None: _host_2_tcg_tmp_new, | |
152 | } | |
153 | ||
154 | ||
155 | ################################################## | |
156 | # host/tcg -> tcg temporal constant deallocation | |
157 | ||
158 | def _host_2_tcg_tmp_free(type_): | |
159 | if type_.startswith("TCGv"): | |
160 | return "tcg_temp_free_nop" | |
161 | raise ValueError("Don't know how to translate type '%s' into a TCG temporal deallocation" % type_) | |
162 | ||
163 | HOST_2_TCG_TMP_FREE = { | |
164 | "uint32_t": "tcg_temp_free_i32", | |
165 | "uint64_t": "tcg_temp_free_i64", | |
166 | "void *" : "tcg_temp_free_ptr", | |
167 | None: _host_2_tcg_tmp_free, | |
168 | } |