annotate lwasm/insn_rel.c @ 283:210d261a614d

Make byte overflow detection for indexing work better There are *two* places where indexed addressing is calculated - lea style instructions and general addressing instructions. Actually check for byte overflows in both places. Also, extend byte overflow checking to all 8 bit offsets from index registers, not just PCR.
author William Astle <lost@l-w.ca>
date Mon, 02 Sep 2013 10:49:57 -0600
parents d0e9dbe9afbe
children 8764142b3192
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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
651b85a98c1b Fixed memory leaks revealed by valgrind
lost@l-w.ca
parents: 2
diff changeset
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 }