annotate lwasm/insn_rel.c @ 122:2be2649841f8

Fixed embarrassing off by one in insn_rel length calculation
author lost@l-w.ca
date Wed, 10 Aug 2011 19:05:49 -0600
parents 7b0716264251
children 6f2e18f1fe67
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;
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
53 if (CURPRAGMA(l, PRAGMA_AUTOBRANCHLENGTH) == 0)
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
54 {
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
55 l -> lint = instab[l -> insn].ops[1];
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 else
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 if (**p == '>' && (((*p)[1]) && !isspace((*p)[1])))
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 (*p)++;
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
62 l -> lint = 16;
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
63 }
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
64 else if (**p == '<' && (((*p)[1]) && !isspace((*p)[1])))
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 (*p)++;
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
67 l -> lint = 8;
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
68 }
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
69 }
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 /* forced sizes handled */
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
72
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
73 // 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
74 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
75 (*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
76
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 t = lwasm_parse_expr(as, p);
116
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
78
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
79 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
80 {
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 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
82 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
83 }
116
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
84
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
85 // if we know the length of the instruction, set it now
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
86 if (l -> lint == 8)
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
87 {
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
88 l -> len = OPLEN(instab[l -> insn].ops[2]) + 1;
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 else if (l -> lint == 16)
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
91 {
122
2be2649841f8 Fixed embarrassing off by one in insn_rel length calculation
lost@l-w.ca
parents: 116
diff changeset
92 l -> len = OPLEN(instab[l -> insn].ops[3]) + 2;
116
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
93 }
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
94
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
95 // the offset calculation here depends on the length of this line!
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
96 // how to calculate requirements?
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
97 // this is the same problem faced by ,pcr indexing
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
98 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
99 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
100 lw_expr_destroy(e2);
116
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
101 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
102 lw_expr_destroy(e1);
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
103 lwasm_save_expr(l, 0, e2);
89
651b85a98c1b Fixed memory leaks revealed by valgrind
lost@l-w.ca
parents: 2
diff changeset
104 lw_expr_destroy(t);
116
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
105
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
106 if (l -> len == -1)
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 e1 = lw_expr_copy(e2);
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
109 l -> len = OPLEN(instab[l -> insn].ops[2]) + 1;
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
110 lwasm_reduce_expr(as, e1);
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
111 l -> len = -1;
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
112 if (lw_expr_istype(e1, lw_expr_type_int))
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
113 {
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
114 int v;
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
115 v = lw_expr_intval(e1);
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
116 if (v >= -128 && v <= 127)
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
117 {
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
118 l -> lint = 8;
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
119 l -> len = OPLEN(instab[l -> insn].ops[2]) + 1;
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
120 }
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
121 else
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 l -> lint = 16;
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
124 l -> len = OPLEN(instab[l -> insn].ops[3]) + 2;
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
125 }
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
126 }
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
127 lw_expr_destroy(e1);
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
128 }
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
129 }
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
130
116
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
131 RESOLVEFUNC(insn_resolve_relgen)
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
132 {
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
133 lw_expr_t e, e2;
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
134 int offs;
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
135
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
136 if (l -> lint == -1)
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 e = lwasm_fetch_expr(l, 0);
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
139 if (!lw_expr_istype(e, lw_expr_type_int))
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
140 {
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
141 // temporarily set the instruction length to see if we get a
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
142 // constant for our expression; if so, we can select an instruction
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
143 // size
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
144 e2 = lw_expr_copy(e);
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
145 // size of 8-bit opcode + 8 bit offset
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
146 l -> len = OPLEN(instab[l -> insn].ops[2]) + 1;
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
147 lwasm_reduce_expr(as, e2);
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
148 l -> len = -1;
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
149 if (lw_expr_istype(e2, lw_expr_type_int))
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
150 {
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
151 // it reduced to an integer; is it in 8 bit range?
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
152 offs = lw_expr_intval(e2);
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
153 if (offs >= -128 && offs <= 127)
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
154 {
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
155 // fits in 8 bits
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
156 l -> len = OPLEN(instab[l -> insn].ops[2]) + 1;
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
157 l -> lint = 8;
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
158 }
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
159 else
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 // requires 16 bits
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
162 l -> len = OPLEN(instab[l -> insn].ops[3]) + 2;
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
163 l -> lint = 16;
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
164 }
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
165 }
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
166 lw_expr_destroy(e2);
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
167 }
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
168 if (lw_expr_istype(e, lw_expr_type_int))
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
169 {
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
170 // it reduced to an integer; is it in 8 bit range?
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
171 offs = lw_expr_intval(e);
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
172 if (offs >= -128 && offs <= 127)
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
173 {
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
174 // fits in 8 bits
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
175 l -> len = OPLEN(instab[l -> insn].ops[2]) + 1;
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
176 l -> lint = 8;
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
177 }
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
178 else
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
179 {
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
180 // requires 16 bits
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
181 l -> len = OPLEN(instab[l -> insn].ops[3]) + 2;
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
182 l -> lint = 16;
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
183 }
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
184 }
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
185 }
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
186 if (!force)
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
187 return;
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 if (l -> len == -1)
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
190 {
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
191 l -> len = OPLEN(instab[l -> insn].ops[3]) + 2;
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
192 l -> lint = 16;
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
193 }
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
194 }
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
195
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
196 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
197 {
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
198 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
199 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
200
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
201 e = lwasm_fetch_expr(l, 0);
116
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
202 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
203 {
116
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
204 if (!lw_expr_istype(e, lw_expr_type_int))
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
205 {
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
206 lwasm_register_error(as, l, "Illegal non-constant expression");
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
207 return;
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
208 }
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
209
116
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
210 offs = lw_expr_intval(e);
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
211 if (l -> lint == 8 && (offs < -128 || offs > 127))
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 lwasm_register_error(as, l, "Byte overflow");
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
214 return;
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
215 }
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
216
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
217
116
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
218 lwasm_emitop(l, instab[l -> insn].ops[2]);
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
219 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
220 }
116
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
221 else
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
222 {
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
223 lwasm_emitop(l, instab[l -> insn].ops[3]);
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
224 lwasm_emitexpr(l, e, 2);
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
225 }
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
226 }