Mercurial > hg > index.cgi
comparison lwasm/insn_gen.c @ 241:d0e9dbe9afbe
Add new heuristic for resolving instruction sizes.
Add new heuristic for resolving instruction sizes. This applies to the the
decision between extended and base page addressing by calculating the range
of possible addresses (if reasonably knowable) and deciding on whether to
force extended addressing based on that. (If the whole range is outside the
direct page, extended addressing is required.)
author | William Astle <lost@l-w.ca> |
---|---|
date | Sun, 23 Sep 2012 13:06:43 -0600 |
parents | f8b07153abc4 |
children | ea092ebc5323 |
comparison
equal
deleted
inserted
replaced
240:41d64951eb32 | 241:d0e9dbe9afbe |
---|---|
48 if (*optr2 == ',' || **p == '[') | 48 if (*optr2 == ',' || **p == '[') |
49 { | 49 { |
50 l -> lint = -1; | 50 l -> lint = -1; |
51 l -> lint2 = 1; | 51 l -> lint2 = 1; |
52 insn_parse_indexed_aux(as, l, p); | 52 insn_parse_indexed_aux(as, l, p); |
53 l -> minlen = OPLEN(instab[l -> insn].ops[1]) + 1 + elen; | |
54 l -> maxlen = OPLEN(instab[l -> insn].ops[1]) + 3 + elen; | |
53 goto out; | 55 goto out; |
54 } | 56 } |
55 | 57 |
56 if (**p == '<') | 58 if (**p == '<') |
57 { | 59 { |
78 else | 80 else |
79 { | 81 { |
80 l -> lint2 = -1; | 82 l -> lint2 = -1; |
81 } | 83 } |
82 | 84 |
85 l -> minlen = OPLEN(instab[l -> insn].ops[0]) + 1 + elen; | |
86 l -> maxlen = OPLEN(instab[l -> insn].ops[2]) + 2 + elen; | |
83 s = lwasm_parse_expr(as, p); | 87 s = lwasm_parse_expr(as, p); |
84 if (!s) | 88 if (!s) |
85 { | 89 { |
86 lwasm_register_error(as, l, "Bad operand"); | 90 lwasm_register_error(as, l, "Bad operand"); |
87 return; | 91 return; |
106 { | 110 { |
107 l -> lint2 = 0; | 111 l -> lint2 = 0; |
108 goto out; | 112 goto out; |
109 } | 113 } |
110 l -> lint2 = 2; | 114 l -> lint2 = 2; |
115 } | |
116 else | |
117 { | |
118 int min; | |
119 int max; | |
120 | |
121 if (lwasm_calculate_range(as, s, &min, &max) == 0) | |
122 { | |
123 // fprintf(stderr, "range (P) %d...%d for %s\n", min, max, lw_expr_print(s)); | |
124 if (min > max) | |
125 { | |
126 // we don't know what to do in this case so don't do anything | |
127 goto out; | |
128 } | |
129 min = (min >> 8) & 0xff; | |
130 max = (max >> 8) & 0xff; | |
131 if ((l -> dpval & 0xff) < min || (l -> dpval & 0xff) > max) | |
132 { | |
133 l -> lint2 = 2; | |
134 goto out; | |
135 } | |
136 l -> lint2 = 0; | |
137 goto out; | |
138 } | |
111 } | 139 } |
112 | 140 |
113 out: | 141 out: |
114 if (l -> lint2 != -1) | 142 if (l -> lint2 != -1) |
115 { | 143 { |
141 | 169 |
142 if (l -> lint2 != -1) | 170 if (l -> lint2 != -1) |
143 return; | 171 return; |
144 | 172 |
145 e = lwasm_fetch_expr(l, 0); | 173 e = lwasm_fetch_expr(l, 0); |
174 lwasm_reduce_expr(as, e); | |
146 if (lw_expr_istype(e, lw_expr_type_int)) | 175 if (lw_expr_istype(e, lw_expr_type_int)) |
147 { | 176 { |
148 int v; | 177 int v; |
149 | 178 |
150 v = lw_expr_intval(e); | 179 v = lw_expr_intval(e); |
154 l -> lint2 = 0; | 183 l -> lint2 = 0; |
155 goto out; | 184 goto out; |
156 } | 185 } |
157 l -> lint2 = 2; | 186 l -> lint2 = 2; |
158 goto out; | 187 goto out; |
188 } | |
189 else | |
190 { | |
191 int min; | |
192 int max; | |
193 | |
194 if (lwasm_calculate_range(as, e, &min, &max) == 0) | |
195 { | |
196 // fprintf(stderr, "range (R) %d...%d for %s\n", min, max, lw_expr_print(e)); | |
197 if (min > max) | |
198 { | |
199 // we don't know what to do in this case so don't do anything | |
200 goto out; | |
201 } | |
202 min = (min >> 8) & 0xff; | |
203 max = (max >> 8) & 0xff; | |
204 if ((l -> dpval & 0xff) < min || (l -> dpval & 0xff) > max) | |
205 { | |
206 l -> lint2 = 2; | |
207 goto out; | |
208 } | |
209 l -> lint2 = 0; | |
210 goto out; | |
211 } | |
159 } | 212 } |
160 | 213 |
161 if (force) | 214 if (force) |
162 { | 215 { |
163 l -> lint2 = 2; | 216 l -> lint2 = 2; |