annotate lwasm/insn_rel.c @ 211:6f2e18f1fe67

Improve autobranchlength pragma Improve detection of 8 bit relative offsets when autobranchlength is in effect. This should eliminate all but the most obscure corner cases where the 16 bit mode is selected when 8 bit mode will do.
author William Astle <lost@l-w.ca>
date Sat, 09 Jun 2012 17:23:04 -0600
parents 2be2649841f8
children d0e9dbe9afbe
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;
116
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
54 if (CURPRAGMA(l, PRAGMA_AUTOBRANCHLENGTH) == 0)
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
55 {
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
56 l -> lint = instab[l -> insn].ops[1];
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
57 }
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
58 else
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
59 {
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
60 if (**p == '>' && (((*p)[1]) && !isspace((*p)[1])))
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
61 {
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
62 (*p)++;
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
63 l -> lint = 16;
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
64 }
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
65 else if (**p == '<' && (((*p)[1]) && !isspace((*p)[1])))
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
66 {
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
67 (*p)++;
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
68 l -> lint = 8;
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
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
72 /* forced sizes handled */
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
73
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
74 // 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
75 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
76 (*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
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 t = lwasm_parse_expr(as, p);
116
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
79
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
80 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
81 {
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 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
83 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
84 }
116
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
85
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
86 // if we know the length of the instruction, set it now
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
87 if (l -> lint == 8)
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
88 {
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
89 l -> len = OPLEN(instab[l -> insn].ops[2]) + 1;
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
90 }
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
91 else if (l -> lint == 16)
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
92 {
122
2be2649841f8 Fixed embarrassing off by one in insn_rel length calculation
lost@l-w.ca
parents: 116
diff changeset
93 l -> len = OPLEN(instab[l -> insn].ops[3]) + 2;
116
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
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
96 // the offset calculation here depends on the length of this line!
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
97 // how to calculate requirements?
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
98 // this is the same problem faced by ,pcr indexing
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
99 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
100 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
101 lw_expr_destroy(e2);
116
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
102 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
103 lw_expr_destroy(e1);
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
104 lwasm_save_expr(l, 0, e2);
89
651b85a98c1b Fixed memory leaks revealed by valgrind
lost@l-w.ca
parents: 2
diff changeset
105 lw_expr_destroy(t);
116
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
106
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
107 if (l -> len == -1)
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
108 {
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
109 e1 = lw_expr_copy(e2);
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
110 l -> len = OPLEN(instab[l -> insn].ops[2]) + 1;
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
111 lwasm_reduce_expr(as, e1);
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
112 l -> len = -1;
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
113 if (lw_expr_istype(e1, lw_expr_type_int))
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
114 {
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
115 int v;
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
116 v = lw_expr_intval(e1);
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
117 if (v >= -128 && v <= 127)
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
118 {
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
119 l -> lint = 8;
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
120 l -> len = OPLEN(instab[l -> insn].ops[2]) + 1;
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
121 }
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
122 else
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
123 {
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
124 l -> lint = 16;
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
125 l -> len = OPLEN(instab[l -> insn].ops[3]) + 2;
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 }
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
128 lw_expr_destroy(e1);
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
129 }
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
130 }
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
116
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
132 RESOLVEFUNC(insn_resolve_relgen)
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
133 {
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
134 lw_expr_t e, e2;
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
135 int offs;
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
136
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
137 if (l -> lint == -1)
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
138 {
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
139 e = lwasm_fetch_expr(l, 0);
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
140 if (!lw_expr_istype(e, lw_expr_type_int))
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
141 {
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
142 // temporarily set the instruction length to see if we get a
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
143 // constant for our expression; if so, we can select an instruction
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
144 // size
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
145 e2 = lw_expr_copy(e);
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
146 // size of 8-bit opcode + 8 bit offset
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
147 l -> len = OPLEN(instab[l -> insn].ops[2]) + 1;
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
148 lwasm_reduce_expr(as, e2);
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
149 l -> len = -1;
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
150 if (lw_expr_istype(e2, lw_expr_type_int))
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
151 {
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
152 // it reduced to an integer; is it in 8 bit range?
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
153 offs = lw_expr_intval(e2);
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
154 if (offs >= -128 && offs <= 127)
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
155 {
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
156 // fits in 8 bits
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
157 l -> len = OPLEN(instab[l -> insn].ops[2]) + 1;
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
158 l -> lint = 8;
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
159 }
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
160 else
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
161 {
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
162 // requires 16 bits
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
163 l -> len = OPLEN(instab[l -> insn].ops[3]) + 2;
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
164 l -> lint = 16;
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 }
211
6f2e18f1fe67 Improve autobranchlength pragma
William Astle <lost@l-w.ca>
parents: 122
diff changeset
167 // size of 8-bit opcode + 8 bit offset
6f2e18f1fe67 Improve autobranchlength pragma
William Astle <lost@l-w.ca>
parents: 122
diff changeset
168 l -> len = OPLEN(instab[l -> insn].ops[2]) + 1;
6f2e18f1fe67 Improve autobranchlength pragma
William Astle <lost@l-w.ca>
parents: 122
diff changeset
169 as -> pretendmax = 1;
6f2e18f1fe67 Improve autobranchlength pragma
William Astle <lost@l-w.ca>
parents: 122
diff changeset
170 lwasm_reduce_expr(as, e2);
6f2e18f1fe67 Improve autobranchlength pragma
William Astle <lost@l-w.ca>
parents: 122
diff changeset
171 as -> pretendmax = 0;
6f2e18f1fe67 Improve autobranchlength pragma
William Astle <lost@l-w.ca>
parents: 122
diff changeset
172 l -> len = -1;
6f2e18f1fe67 Improve autobranchlength pragma
William Astle <lost@l-w.ca>
parents: 122
diff changeset
173 if (lw_expr_istype(e2, lw_expr_type_int))
6f2e18f1fe67 Improve autobranchlength pragma
William Astle <lost@l-w.ca>
parents: 122
diff changeset
174 {
6f2e18f1fe67 Improve autobranchlength pragma
William Astle <lost@l-w.ca>
parents: 122
diff changeset
175 // 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
176 offs = lw_expr_intval(e2);
6f2e18f1fe67 Improve autobranchlength pragma
William Astle <lost@l-w.ca>
parents: 122
diff changeset
177 if (offs >= -128 && offs <= 127)
6f2e18f1fe67 Improve autobranchlength pragma
William Astle <lost@l-w.ca>
parents: 122
diff changeset
178 {
6f2e18f1fe67 Improve autobranchlength pragma
William Astle <lost@l-w.ca>
parents: 122
diff changeset
179 // fits in 8 bits with a worst case scenario
6f2e18f1fe67 Improve autobranchlength pragma
William Astle <lost@l-w.ca>
parents: 122
diff changeset
180 l -> len = OPLEN(instab[l -> insn].ops[2]) + 1;
6f2e18f1fe67 Improve autobranchlength pragma
William Astle <lost@l-w.ca>
parents: 122
diff changeset
181 l -> lint = 8;
6f2e18f1fe67 Improve autobranchlength pragma
William Astle <lost@l-w.ca>
parents: 122
diff changeset
182 }
6f2e18f1fe67 Improve autobranchlength pragma
William Astle <lost@l-w.ca>
parents: 122
diff changeset
183 }
116
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
184 lw_expr_destroy(e2);
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 (lw_expr_istype(e, lw_expr_type_int))
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
187 {
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
188 // it reduced to an integer; is it in 8 bit range?
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
189 offs = lw_expr_intval(e);
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
190 if (offs >= -128 && offs <= 127)
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
191 {
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
192 // fits in 8 bits
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
193 l -> len = OPLEN(instab[l -> insn].ops[2]) + 1;
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
194 l -> lint = 8;
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 else
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
197 {
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
198 // requires 16 bits
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
199 l -> len = OPLEN(instab[l -> insn].ops[3]) + 2;
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
200 l -> lint = 16;
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
201 }
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 if (!force)
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
205 return;
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
206
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
207 if (l -> len == -1)
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
208 {
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
209 l -> len = OPLEN(instab[l -> insn].ops[3]) + 2;
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
210 l -> lint = 16;
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
211 }
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 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
215 {
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 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
217 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
218
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 e = lwasm_fetch_expr(l, 0);
116
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
220 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
221 {
116
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
222 if (!lw_expr_istype(e, lw_expr_type_int))
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
223 {
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
224 lwasm_register_error(as, l, "Illegal non-constant expression");
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
225 return;
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
226 }
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
227
116
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
228 offs = lw_expr_intval(e);
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
229 if (l -> lint == 8 && (offs < -128 || offs > 127))
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
230 {
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
231 lwasm_register_error(as, l, "Byte overflow");
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
232 return;
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
233 }
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
234
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
235
116
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
236 lwasm_emitop(l, instab[l -> insn].ops[2]);
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
237 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
238 }
116
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
239 else
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
240 {
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
241 lwasm_emitop(l, instab[l -> insn].ops[3]);
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
242 lwasm_emitexpr(l, e, 2);
7b0716264251 Pragma autobranchlength implementation completed
lost@l-w.ca
parents: 91
diff changeset
243 }
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
244 }