Mercurial > hg > index.cgi
annotate lwasm/insn_rel.c @ 273:1409debcb1a0
Fix crash on listing when nested noexpand macros are used
Macros flagged noexpand were causing a segfault during listing. The problem
was incorrect accounting for nesting levels for noexpand macros causing the
listing handler to fall off the end of the program in certain circumstances
and in other circumstances it would fail to suppress expansion. Both the
segfault in the case of misbehaviour and the misbhaviour itself are
corrected with this update.
If you do not use nested noexpand macros, this bug has no effect.
author | William Astle <lost@l-w.ca> |
---|---|
date | Sat, 25 May 2013 13:35:46 -0600 |
parents | d0e9dbe9afbe |
children | 8764142b3192 |
rev | line source |
---|---|
0
2c24602be78f
Initial import from lwtools 3.0.1 version, with new hand built build system and file reorganization
lost@l-w.ca
parents:
diff
changeset
|
1 /* |
2c24602be78f
Initial import from lwtools 3.0.1 version, with new hand built build system and file reorganization
lost@l-w.ca
parents:
diff
changeset
|
2 insn_rel.c |
2c24602be78f
Initial import from lwtools 3.0.1 version, with new hand built build system and file reorganization
lost@l-w.ca
parents:
diff
changeset
|
3 Copyright © 2009 William Astle |
2c24602be78f
Initial import from lwtools 3.0.1 version, with new hand built build system and file reorganization
lost@l-w.ca
parents:
diff
changeset
|
4 |
2c24602be78f
Initial import from lwtools 3.0.1 version, with new hand built build system and file reorganization
lost@l-w.ca
parents:
diff
changeset
|
5 This file is part of LWASM. |
2c24602be78f
Initial import from lwtools 3.0.1 version, with new hand built build system and file reorganization
lost@l-w.ca
parents:
diff
changeset
|
6 |
2c24602be78f
Initial import from lwtools 3.0.1 version, with new hand built build system and file reorganization
lost@l-w.ca
parents:
diff
changeset
|
7 LWASM is free software: you can redistribute it and/or modify it under the |
2c24602be78f
Initial import from lwtools 3.0.1 version, with new hand built build system and file reorganization
lost@l-w.ca
parents:
diff
changeset
|
8 terms of the GNU General Public License as published by the Free Software |
2c24602be78f
Initial import from lwtools 3.0.1 version, with new hand built build system and file reorganization
lost@l-w.ca
parents:
diff
changeset
|
9 Foundation, either version 3 of the License, or (at your option) any later |
2c24602be78f
Initial import from lwtools 3.0.1 version, with new hand built build system and file reorganization
lost@l-w.ca
parents:
diff
changeset
|
10 version. |
2c24602be78f
Initial import from lwtools 3.0.1 version, with new hand built build system and file reorganization
lost@l-w.ca
parents:
diff
changeset
|
11 |
2c24602be78f
Initial import from lwtools 3.0.1 version, with new hand built build system and file reorganization
lost@l-w.ca
parents:
diff
changeset
|
12 This program is distributed in the hope that it will be useful, but WITHOUT |
2c24602be78f
Initial import from lwtools 3.0.1 version, with new hand built build system and file reorganization
lost@l-w.ca
parents:
diff
changeset
|
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
2c24602be78f
Initial import from lwtools 3.0.1 version, with new hand built build system and file reorganization
lost@l-w.ca
parents:
diff
changeset
|
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
2c24602be78f
Initial import from lwtools 3.0.1 version, with new hand built build system and file reorganization
lost@l-w.ca
parents:
diff
changeset
|
15 more details. |
2c24602be78f
Initial import from lwtools 3.0.1 version, with new hand built build system and file reorganization
lost@l-w.ca
parents:
diff
changeset
|
16 |
2c24602be78f
Initial import from lwtools 3.0.1 version, with new hand built build system and file reorganization
lost@l-w.ca
parents:
diff
changeset
|
17 You should have received a copy of the GNU General Public License along with |
2c24602be78f
Initial import from lwtools 3.0.1 version, with new hand built build system and file reorganization
lost@l-w.ca
parents:
diff
changeset
|
18 this program. If not, see <http://www.gnu.org/licenses/>. |
2c24602be78f
Initial import from lwtools 3.0.1 version, with new hand built build system and file reorganization
lost@l-w.ca
parents:
diff
changeset
|
19 */ |
2c24602be78f
Initial import from lwtools 3.0.1 version, with new hand built build system and file reorganization
lost@l-w.ca
parents:
diff
changeset
|
20 |
2c24602be78f
Initial import from lwtools 3.0.1 version, with new hand built build system and file reorganization
lost@l-w.ca
parents:
diff
changeset
|
21 /* |
2c24602be78f
Initial import from lwtools 3.0.1 version, with new hand built build system and file reorganization
lost@l-w.ca
parents:
diff
changeset
|
22 for handling relative mode instructions |
2c24602be78f
Initial import from lwtools 3.0.1 version, with new hand built build system and file reorganization
lost@l-w.ca
parents:
diff
changeset
|
23 */ |
2c24602be78f
Initial import from lwtools 3.0.1 version, with new hand built build system and file reorganization
lost@l-w.ca
parents:
diff
changeset
|
24 |
116
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
25 #include <ctype.h> |
0
2c24602be78f
Initial import from lwtools 3.0.1 version, with new hand built build system and file reorganization
lost@l-w.ca
parents:
diff
changeset
|
26 #include <stdlib.h> |
116
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
27 #include <stdio.h> |
0
2c24602be78f
Initial import from lwtools 3.0.1 version, with new hand built build system and file reorganization
lost@l-w.ca
parents:
diff
changeset
|
28 |
2c24602be78f
Initial import from lwtools 3.0.1 version, with new hand built build system and file reorganization
lost@l-w.ca
parents:
diff
changeset
|
29 #include <lw_expr.h> |
2c24602be78f
Initial import from lwtools 3.0.1 version, with new hand built build system and file reorganization
lost@l-w.ca
parents:
diff
changeset
|
30 |
2c24602be78f
Initial import from lwtools 3.0.1 version, with new hand built build system and file reorganization
lost@l-w.ca
parents:
diff
changeset
|
31 #include "lwasm.h" |
2c24602be78f
Initial import from lwtools 3.0.1 version, with new hand built build system and file reorganization
lost@l-w.ca
parents:
diff
changeset
|
32 #include "instab.h" |
2c24602be78f
Initial import from lwtools 3.0.1 version, with new hand built build system and file reorganization
lost@l-w.ca
parents:
diff
changeset
|
33 |
116
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
34 /* |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
35 For generic relative, the first "opcode" is the natural opcode for the |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
36 mneumonic. The second "opcode" is the natural size of the relative offset. |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
37 These will be used when pragma autobranchlength is NOT in effect. |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
38 |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
39 The third "opcode" is the short (8 bit) version of the branch. The final one |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
40 is the long (16 bit) version of the branch. These will be used when pragma |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
41 autobranchlength is in effect. |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
42 |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
43 When autobranchlength is in effect, the branch target can be prefixed with |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
44 either < or > to force a short or long branch. Note that in this mode, |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
45 a > or < on its own still specifies a branch point. |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
46 |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
47 */ |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
48 PARSEFUNC(insn_parse_relgen) |
0
2c24602be78f
Initial import from lwtools 3.0.1 version, with new hand built build system and file reorganization
lost@l-w.ca
parents:
diff
changeset
|
49 { |
2c24602be78f
Initial import from lwtools 3.0.1 version, with new hand built build system and file reorganization
lost@l-w.ca
parents:
diff
changeset
|
50 lw_expr_t t, e1, e2; |
116
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
51 |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
52 l -> lint = -1; |
211
6f2e18f1fe67
Improve autobranchlength pragma
William Astle <lost@l-w.ca>
parents:
122
diff
changeset
|
53 l -> maxlen = OPLEN(instab[l -> insn].ops[3]) + 2; |
241
d0e9dbe9afbe
Add new heuristic for resolving instruction sizes.
William Astle <lost@l-w.ca>
parents:
211
diff
changeset
|
54 l -> minlen = OPLEN(instab[l -> insn].ops[2]) + 1; |
116
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
55 if (CURPRAGMA(l, PRAGMA_AUTOBRANCHLENGTH) == 0) |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
56 { |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
57 l -> lint = instab[l -> insn].ops[1]; |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
58 } |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
59 else |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
60 { |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
61 if (**p == '>' && (((*p)[1]) && !isspace((*p)[1]))) |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
62 { |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
63 (*p)++; |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
64 l -> lint = 16; |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
65 } |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
66 else if (**p == '<' && (((*p)[1]) && !isspace((*p)[1]))) |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
67 { |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
68 (*p)++; |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
69 l -> lint = 8; |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
70 } |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
71 } |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
72 |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
73 /* forced sizes handled */ |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
74 |
0
2c24602be78f
Initial import from lwtools 3.0.1 version, with new hand built build system and file reorganization
lost@l-w.ca
parents:
diff
changeset
|
75 // sometimes there is a "#", ignore if there |
2c24602be78f
Initial import from lwtools 3.0.1 version, with new hand built build system and file reorganization
lost@l-w.ca
parents:
diff
changeset
|
76 if (**p == '#') |
2c24602be78f
Initial import from lwtools 3.0.1 version, with new hand built build system and file reorganization
lost@l-w.ca
parents:
diff
changeset
|
77 (*p)++; |
2c24602be78f
Initial import from lwtools 3.0.1 version, with new hand built build system and file reorganization
lost@l-w.ca
parents:
diff
changeset
|
78 |
2c24602be78f
Initial import from lwtools 3.0.1 version, with new hand built build system and file reorganization
lost@l-w.ca
parents:
diff
changeset
|
79 t = lwasm_parse_expr(as, p); |
116
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
80 |
0
2c24602be78f
Initial import from lwtools 3.0.1 version, with new hand built build system and file reorganization
lost@l-w.ca
parents:
diff
changeset
|
81 if (!t) |
2c24602be78f
Initial import from lwtools 3.0.1 version, with new hand built build system and file reorganization
lost@l-w.ca
parents:
diff
changeset
|
82 { |
2c24602be78f
Initial import from lwtools 3.0.1 version, with new hand built build system and file reorganization
lost@l-w.ca
parents:
diff
changeset
|
83 lwasm_register_error(as, l, "Bad operand"); |
2c24602be78f
Initial import from lwtools 3.0.1 version, with new hand built build system and file reorganization
lost@l-w.ca
parents:
diff
changeset
|
84 return; |
2c24602be78f
Initial import from lwtools 3.0.1 version, with new hand built build system and file reorganization
lost@l-w.ca
parents:
diff
changeset
|
85 } |
116
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
86 |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
87 // if we know the length of the instruction, set it now |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
88 if (l -> lint == 8) |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
89 { |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
90 l -> len = OPLEN(instab[l -> insn].ops[2]) + 1; |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
91 } |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
92 else if (l -> lint == 16) |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
93 { |
122
2be2649841f8
Fixed embarrassing off by one in insn_rel length calculation
lost@l-w.ca
parents:
116
diff
changeset
|
94 l -> len = OPLEN(instab[l -> insn].ops[3]) + 2; |
116
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
95 } |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
96 |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
97 // the offset calculation here depends on the length of this line! |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
98 // how to calculate requirements? |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
99 // this is the same problem faced by ,pcr indexing |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
100 e2 = lw_expr_build(lw_expr_type_special, lwasm_expr_linelen, l); |
0
2c24602be78f
Initial import from lwtools 3.0.1 version, with new hand built build system and file reorganization
lost@l-w.ca
parents:
diff
changeset
|
101 e1 = lw_expr_build(lw_expr_type_oper, lw_expr_oper_minus, t, e2); |
2c24602be78f
Initial import from lwtools 3.0.1 version, with new hand built build system and file reorganization
lost@l-w.ca
parents:
diff
changeset
|
102 lw_expr_destroy(e2); |
116
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
103 e2 = lw_expr_build(lw_expr_type_oper, lw_expr_oper_minus, e1, l -> addr); |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
104 lw_expr_destroy(e1); |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
105 lwasm_save_expr(l, 0, e2); |
89 | 106 lw_expr_destroy(t); |
116
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
107 |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
108 if (l -> len == -1) |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
109 { |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
110 e1 = lw_expr_copy(e2); |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
111 l -> len = OPLEN(instab[l -> insn].ops[2]) + 1; |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
112 lwasm_reduce_expr(as, e1); |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
113 l -> len = -1; |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
114 if (lw_expr_istype(e1, lw_expr_type_int)) |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
115 { |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
116 int v; |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
117 v = lw_expr_intval(e1); |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
118 if (v >= -128 && v <= 127) |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
119 { |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
120 l -> lint = 8; |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
121 l -> len = OPLEN(instab[l -> insn].ops[2]) + 1; |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
122 } |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
123 else |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
124 { |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
125 l -> lint = 16; |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
126 l -> len = OPLEN(instab[l -> insn].ops[3]) + 2; |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
127 } |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
128 } |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
129 lw_expr_destroy(e1); |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
130 } |
0
2c24602be78f
Initial import from lwtools 3.0.1 version, with new hand built build system and file reorganization
lost@l-w.ca
parents:
diff
changeset
|
131 } |
2c24602be78f
Initial import from lwtools 3.0.1 version, with new hand built build system and file reorganization
lost@l-w.ca
parents:
diff
changeset
|
132 |
116
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
133 RESOLVEFUNC(insn_resolve_relgen) |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
134 { |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
135 lw_expr_t e, e2; |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
136 int offs; |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
137 |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
138 if (l -> lint == -1) |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
139 { |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
140 e = lwasm_fetch_expr(l, 0); |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
141 if (!lw_expr_istype(e, lw_expr_type_int)) |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
142 { |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
143 // temporarily set the instruction length to see if we get a |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
144 // constant for our expression; if so, we can select an instruction |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
145 // size |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
146 e2 = lw_expr_copy(e); |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
147 // size of 8-bit opcode + 8 bit offset |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
148 l -> len = OPLEN(instab[l -> insn].ops[2]) + 1; |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
149 lwasm_reduce_expr(as, e2); |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
150 l -> len = -1; |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
151 if (lw_expr_istype(e2, lw_expr_type_int)) |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
152 { |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
153 // it reduced to an integer; is it in 8 bit range? |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
154 offs = lw_expr_intval(e2); |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
155 if (offs >= -128 && offs <= 127) |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
156 { |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
157 // fits in 8 bits |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
158 l -> len = OPLEN(instab[l -> insn].ops[2]) + 1; |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
159 l -> lint = 8; |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
160 } |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
161 else |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
162 { |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
163 // requires 16 bits |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
164 l -> len = OPLEN(instab[l -> insn].ops[3]) + 2; |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
165 l -> lint = 16; |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
166 } |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
167 } |
211
6f2e18f1fe67
Improve autobranchlength pragma
William Astle <lost@l-w.ca>
parents:
122
diff
changeset
|
168 // size of 8-bit opcode + 8 bit offset |
6f2e18f1fe67
Improve autobranchlength pragma
William Astle <lost@l-w.ca>
parents:
122
diff
changeset
|
169 l -> len = OPLEN(instab[l -> insn].ops[2]) + 1; |
6f2e18f1fe67
Improve autobranchlength pragma
William Astle <lost@l-w.ca>
parents:
122
diff
changeset
|
170 as -> pretendmax = 1; |
6f2e18f1fe67
Improve autobranchlength pragma
William Astle <lost@l-w.ca>
parents:
122
diff
changeset
|
171 lwasm_reduce_expr(as, e2); |
6f2e18f1fe67
Improve autobranchlength pragma
William Astle <lost@l-w.ca>
parents:
122
diff
changeset
|
172 as -> pretendmax = 0; |
6f2e18f1fe67
Improve autobranchlength pragma
William Astle <lost@l-w.ca>
parents:
122
diff
changeset
|
173 l -> len = -1; |
6f2e18f1fe67
Improve autobranchlength pragma
William Astle <lost@l-w.ca>
parents:
122
diff
changeset
|
174 if (lw_expr_istype(e2, lw_expr_type_int)) |
6f2e18f1fe67
Improve autobranchlength pragma
William Astle <lost@l-w.ca>
parents:
122
diff
changeset
|
175 { |
6f2e18f1fe67
Improve autobranchlength pragma
William Astle <lost@l-w.ca>
parents:
122
diff
changeset
|
176 // it reduced to an integer; is it in 8 bit range? |
6f2e18f1fe67
Improve autobranchlength pragma
William Astle <lost@l-w.ca>
parents:
122
diff
changeset
|
177 offs = lw_expr_intval(e2); |
6f2e18f1fe67
Improve autobranchlength pragma
William Astle <lost@l-w.ca>
parents:
122
diff
changeset
|
178 if (offs >= -128 && offs <= 127) |
6f2e18f1fe67
Improve autobranchlength pragma
William Astle <lost@l-w.ca>
parents:
122
diff
changeset
|
179 { |
6f2e18f1fe67
Improve autobranchlength pragma
William Astle <lost@l-w.ca>
parents:
122
diff
changeset
|
180 // fits in 8 bits with a worst case scenario |
6f2e18f1fe67
Improve autobranchlength pragma
William Astle <lost@l-w.ca>
parents:
122
diff
changeset
|
181 l -> len = OPLEN(instab[l -> insn].ops[2]) + 1; |
6f2e18f1fe67
Improve autobranchlength pragma
William Astle <lost@l-w.ca>
parents:
122
diff
changeset
|
182 l -> lint = 8; |
6f2e18f1fe67
Improve autobranchlength pragma
William Astle <lost@l-w.ca>
parents:
122
diff
changeset
|
183 } |
6f2e18f1fe67
Improve autobranchlength pragma
William Astle <lost@l-w.ca>
parents:
122
diff
changeset
|
184 } |
116
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
185 lw_expr_destroy(e2); |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
186 } |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
187 if (lw_expr_istype(e, lw_expr_type_int)) |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
188 { |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
189 // it reduced to an integer; is it in 8 bit range? |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
190 offs = lw_expr_intval(e); |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
191 if (offs >= -128 && offs <= 127) |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
192 { |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
193 // fits in 8 bits |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
194 l -> len = OPLEN(instab[l -> insn].ops[2]) + 1; |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
195 l -> lint = 8; |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
196 } |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
197 else |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
198 { |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
199 // requires 16 bits |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
200 l -> len = OPLEN(instab[l -> insn].ops[3]) + 2; |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
201 l -> lint = 16; |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
202 } |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
203 } |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
204 } |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
205 if (!force) |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
206 return; |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
207 |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
208 if (l -> len == -1) |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
209 { |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
210 l -> len = OPLEN(instab[l -> insn].ops[3]) + 2; |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
211 l -> lint = 16; |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
212 } |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
213 } |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
214 |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
215 EMITFUNC(insn_emit_relgen) |
0
2c24602be78f
Initial import from lwtools 3.0.1 version, with new hand built build system and file reorganization
lost@l-w.ca
parents:
diff
changeset
|
216 { |
2c24602be78f
Initial import from lwtools 3.0.1 version, with new hand built build system and file reorganization
lost@l-w.ca
parents:
diff
changeset
|
217 lw_expr_t e; |
2c24602be78f
Initial import from lwtools 3.0.1 version, with new hand built build system and file reorganization
lost@l-w.ca
parents:
diff
changeset
|
218 int offs; |
2c24602be78f
Initial import from lwtools 3.0.1 version, with new hand built build system and file reorganization
lost@l-w.ca
parents:
diff
changeset
|
219 |
2c24602be78f
Initial import from lwtools 3.0.1 version, with new hand built build system and file reorganization
lost@l-w.ca
parents:
diff
changeset
|
220 e = lwasm_fetch_expr(l, 0); |
116
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
221 if (l -> lint == 8) |
0
2c24602be78f
Initial import from lwtools 3.0.1 version, with new hand built build system and file reorganization
lost@l-w.ca
parents:
diff
changeset
|
222 { |
116
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
223 if (!lw_expr_istype(e, lw_expr_type_int)) |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
224 { |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
225 lwasm_register_error(as, l, "Illegal non-constant expression"); |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
226 return; |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
227 } |
0
2c24602be78f
Initial import from lwtools 3.0.1 version, with new hand built build system and file reorganization
lost@l-w.ca
parents:
diff
changeset
|
228 |
116
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
229 offs = lw_expr_intval(e); |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
230 if (l -> lint == 8 && (offs < -128 || offs > 127)) |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
231 { |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
232 lwasm_register_error(as, l, "Byte overflow"); |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
233 return; |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
234 } |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
235 |
0
2c24602be78f
Initial import from lwtools 3.0.1 version, with new hand built build system and file reorganization
lost@l-w.ca
parents:
diff
changeset
|
236 |
116
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
237 lwasm_emitop(l, instab[l -> insn].ops[2]); |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
238 lwasm_emit(l, offs); |
0
2c24602be78f
Initial import from lwtools 3.0.1 version, with new hand built build system and file reorganization
lost@l-w.ca
parents:
diff
changeset
|
239 } |
116
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
240 else |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
241 { |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
242 lwasm_emitop(l, instab[l -> insn].ops[3]); |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
243 lwasm_emitexpr(l, e, 2); |
7b0716264251
Pragma autobranchlength implementation completed
lost@l-w.ca
parents:
91
diff
changeset
|
244 } |
0
2c24602be78f
Initial import from lwtools 3.0.1 version, with new hand built build system and file reorganization
lost@l-w.ca
parents:
diff
changeset
|
245 } |