annotate src/insn_indexed.c @ 159:71561c12b20b

Updated docs to reflect new cescapes pragma and discuss implicit assumption of the bss section flag for sections named bss and .bss
author lost
date Sat, 31 Jan 2009 06:32:27 +0000
parents f59c0916753d
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
32
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
1 /*
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
2 insn_indexed.c
33
74a3fef7c8d0 Added general addressing modes (immediate, base page, extended, indexed)
lost
parents: 32
diff changeset
3 Copyright © 2009 William Astle
32
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
4
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
5 This file is part of LWASM.
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
6
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
7 LWASM is free software: you can redistribute it and/or modify it under the
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
8 terms of the GNU General Public License as published by the Free Software
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
9 Foundation, either version 3 of the License, or (at your option) any later
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
10 version.
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
11
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
12 This program is distributed in the hope that it will be useful, but WITHOUT
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
15 more details.
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
16
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
17 You should have received a copy of the GNU General Public License along with
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
18 this program. If not, see <http://www.gnu.org/licenses/>.
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
19 */
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
20
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
21 /*
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
22 for handling indexed mode instructions
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
23 */
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
24
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
25 #define __insn_indexed_c_seen__
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
26
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
27 #include <ctype.h>
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
28 #include <string.h>
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
29
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
30 #include "lwasm.h"
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
31 #include "instab.h"
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
32 #include "expr.h"
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
33
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
34 void insn_indexed_aux(asmstate_t *as, lwasm_line_t *l, const char **p, int *b1, int *b2, int *b3)
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
35 {
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
36 static const char *regs = "X Y U S W PCRPC ";
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
37 static const struct { char *opstr; int pb; } simpleindex[] =
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
38 {
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
39 {",x", 0x84}, {",y", 0xa4}, {",u", 0xc4}, {",s", 0xe4},
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
40 {",x+", 0x80}, {",y+", 0xa0}, {",u+", 0xc0}, {",s+", 0xe0},
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
41 {",x++", 0x81}, {",y++", 0xa1}, {",u++", 0xc1}, {",s++", 0xe1},
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
42 {",-x", 0x82}, {",-y", 0xa2}, {",-u", 0xc2}, {",-s", 0xe2},
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
43 {",--x", 0x83}, {",--y", 0xa3}, {",--u", 0xc3}, {",--s", 0xe3},
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
44 {"a,x", 0x86}, {"a,y", 0xa6}, {"a,u", 0xc6}, {"a,s", 0xe6},
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
45 {"b,x", 0x85}, {"b,y", 0xa5}, {"b,u", 0xc5}, {"b,s", 0xe5},
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
46 {"e,x", 0x87}, {"e,y", 0xa7}, {"e,u", 0xc7}, {"e,s", 0xe7},
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
47 {"f,x", 0x8a}, {"f,y", 0xaa}, {"f,u", 0xca}, {"f,s", 0xea},
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
48 {"d,x", 0x8b}, {"d,y", 0xab}, {"d,u", 0xcb}, {"d,s", 0xed},
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
49 {"w,x", 0x8e}, {"w,y", 0xae}, {"w,u", 0xce}, {"w,s", 0xee},
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
50 {",w", 0x8f}, {",w++", 0xcf}, {",--w", 0xef},
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
51
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
52 {"[,x]", 0x94}, {"[,y]", 0xb4}, {"[,u", 0xd4}, {"[,s]", 0xf4},
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
53 {"[,x++]", 0x91}, {"[,y++]", 0xb1}, {"[,u++]", 0xd1}, {"[,s++]", 0xf1},
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
54 {"[,--x]", 0x93}, {"[,--y]", 0xb3}, {"[,--u]", 0xd3}, {"[,--s]", 0xf3},
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
55 {"[a,x]", 0x96}, {"[a,y]", 0xb6}, {"[a,u]", 0xd6}, {"[a,s]", 0xf6},
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
56 {"[b,x]", 0x95}, {"[b,y]", 0xb5}, {"[b,u]", 0xd5}, {"[b,s]", 0xf5},
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
57 {"[e,x]", 0x97}, {"[e,y]", 0xb7}, {"[e,u]", 0xd7}, {"[e,s]", 0xf7},
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
58 {"[f,x]", 0x9a}, {"[f,y]", 0xba}, {"[f,u]", 0xda}, {"[f,s]", 0xfa},
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
59 {"[d,x]", 0x9b}, {"[d,y]", 0xbb}, {"[d,u]", 0xdb}, {"[d,s]", 0xfd},
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
60 {"[w,x]", 0x9e}, {"[w,y]", 0xbe}, {"[w,u]", 0xde}, {"[w,s]", 0xfe},
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
61 {"[,w]", 0x90}, {"[,w++]", 0xd0}, {"[,--w]", 0xf0},
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
62
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
63 { "", -1 }
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
64 };
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
65 char stbuf[25];
81
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
66 int i, j, rn;
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
67 int f8 = 0, f16 = 0, f0 = 0;
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
68 int r, v;
32
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
69 int indir = 0;
101
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 84
diff changeset
70 int fs8 = 0, fs16 = 0;
81
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
71
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
72 // initialize output bytes
32
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
73 *b1 = *b2 = *b3 = -1;
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
74
81
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
75 // fetch out operand for lookup
32
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
76 for (i = 0; i < 24; i++)
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
77 {
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
78 if (*((*p) + i) && !isspace(*((*p) + i)))
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
79 stbuf[i] = *((*p) + i);
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
80 else
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
81 break;
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
82 }
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
83 stbuf[i] = '\0';
81
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
84
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
85 // now look up operand in "simple" table
32
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
86 if (!*((*p) + i) || isspace(*((*p) + i)))
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
87 {
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
88 // do simple lookup
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
89 for (j = 0; simpleindex[j].opstr[0]; j++)
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
90 {
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
91 if (!strcasecmp(stbuf, simpleindex[j].opstr))
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
92 break;
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
93 }
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
94 if (simpleindex[j].opstr[0])
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
95 {
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
96 *b1 = simpleindex[j].pb;
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
97 (*p) += i;
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
98 return;
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
99 }
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
100 }
81
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
101
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
102 // now do the "hard" ones
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
103
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
104 // is it indirect?
32
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
105 if (**p == '[')
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
106 {
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
107 indir = 1;
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
108 (*p)++;
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
109 }
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
110
81
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
111 // look for a "," - all indexed modes have a "," except extended indir
32
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
112 rn = 0;
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
113 for (i = 0; (*p)[i] && !isspace((*p)[i]); i++)
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
114 {
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
115 if ((*p)[i] == ',')
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
116 {
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
117 rn = 1;
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
118 break;
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
119 }
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
120 }
81
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
121
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
122 // if no "," and indirect, do extended indir
32
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
123 if (!rn && indir)
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
124 {
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
125 // extended indir
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
126 *b1 = 0x9f;
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
127 *b2 = 0;
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
128 *b3 = 0;
81
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
129 r = lwasm_expr_result2(as, l, (char **)p, 0, &v, 0);
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
130 if (r < 0)
32
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
131 {
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
132 return;
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
133 }
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
134 if (**p != ']')
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
135 {
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
136 register_error(as, l, 1, "Bad operand");
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
137 return;
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
138 }
81
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
139
32
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
140 (*p)++;
81
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
141
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
142 if (r == 1 && as -> passnum == 2)
32
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
143 {
81
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
144 l -> relocoff = as -> addr - l -> codeaddr + 1;
32
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
145 }
81
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
146
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
147 *b2 = (v >> 8) & 0xff;
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
148 *b3 = v & 0xff;
32
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
149 return;
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
150 }
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
151
81
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
152 // if we've previously forced the offset size, make a note of it
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
153 if (l -> fsize == 1)
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
154 f8 = 1;
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
155 else if (l -> fsize == 2)
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
156 f16 = 1;
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
157
32
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
158 if (**p == '<')
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
159 {
101
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 84
diff changeset
160 fs8 = 1;
32
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
161 (*p)++;
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
162 }
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
163 else if (**p == '>')
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
164 {
101
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 84
diff changeset
165 fs16 = 1;
32
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
166 (*p)++;
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
167 }
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
168
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
169 if (**p == '0' && *(*p+1) == ',')
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
170 {
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
171 f0 = 1;
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
172 }
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
173
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
174 // now we have to evaluate the expression
81
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
175 r = lwasm_expr_result2(as, l, (char **)p, 0, &v, 0);
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
176 if (r < 0)
32
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
177 {
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
178 return;
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
179 }
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
180 // now look for a comma; if not present, explode
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
181 if (*(*p)++ != ',')
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
182 {
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
183 // syntax error; force 0 bit
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
184 *b1 = 00;
81
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
185 l -> fsize = 0;
32
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
186 return;
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
187 }
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
188
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
189 // now get the register
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
190 rn = lwasm_lookupreg3(regs, p);
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
191 if (rn < 0)
81
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
192 {
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
193 *b1 = 0;
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
194 l -> fsize = 0;
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
195 register_error(as, l, 1, "Bad register");
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
196 return;
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
197 }
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
198
32
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
199 if (indir)
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
200 {
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
201 if (**p != ']')
81
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
202 {
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
203 register_error(as, l, 1, "Bad operand");
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
204 l -> fsize = 0;
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
205 *b1 = 0;
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
206 return;
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
207 }
32
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
208 else
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
209 (*p)++;
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
210 }
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
211
81
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
212 // incomplete reference on pass 1 forces 16 bit
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
213 if (r == 1 && as -> passnum == 1)
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
214 {
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
215 f16 = 1;
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
216 l -> fsize = 2;
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
217 }
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
218
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
219 // incomplete reference on pass 2 needs relocoff set
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
220 if (r == 1 && as -> passnum == 2)
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
221 {
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
222 l -> relocoff = as -> addr - l -> codeaddr + 1;
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
223 }
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
224
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
225 // nnnn,W is only 16 bit (or 0 bit)
32
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
226 if (rn == 4)
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
227 {
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
228 if (f8)
81
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
229 {
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
230 register_error(as, l, 1, "n,W cannot be 8 bit");
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
231 l -> fsize = 0;
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
232 *b1 = 0;
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
233 return;
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
234 }
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
235 // note: set f16 above for incomplete references
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
236 // also set reloc offset
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
237 if (!f16 && !f0 && !(as -> pragmas & PRAGMA_NOINDEX0TONONE) && v == 0)
32
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
238 {
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
239 if (indir)
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
240 *b1 = 0x90;
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
241 else
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
242 *b1 = 0x8f;
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
243 return;
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
244 }
81
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
245
32
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
246 if (indir)
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
247 *b1 = 0xb0;
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
248 else
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
249 *b1 = 0xcf;
81
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
250 *b2 = (v >> 8) & 0xff;
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
251 *b3 = v & 0xff;
32
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
252 return;
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
253 }
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
254
81
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
255 // set indir to correct bit value
32
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
256 if (indir) indir = 0x10;
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
257
81
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
258 // PCR? then we have PC relative addressing (like B??, LB??)
32
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
259 if (rn == 5)
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
260 {
101
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 84
diff changeset
261 lwasm_expr_term_t *t;
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 84
diff changeset
262 // external references are handled exactly the same as for
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 84
diff changeset
263 // relative addressing modes
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 84
diff changeset
264 // on pass 1, adjust the expression for a subtraction of the
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 84
diff changeset
265 // current address
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 84
diff changeset
266
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 84
diff changeset
267 // need to re-evaluate the expression with "SECTCONST"...
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 84
diff changeset
268 r = lwasm_expr_result2(as, l, (char **)p, EXPR_SECTCONST | EXPR_REEVAL, &v, 0);
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 84
diff changeset
269 if (r != 0)
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 84
diff changeset
270 v = 0;
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 84
diff changeset
271 if (as -> passnum == 1)
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 84
diff changeset
272 {
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 84
diff changeset
273 l -> fsize = 0;
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 84
diff changeset
274 }
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 84
diff changeset
275 f8 = f16 = 0;
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 84
diff changeset
276 if (r == 1 && as -> passnum == 1 && !fs8)
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 84
diff changeset
277 {
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 84
diff changeset
278 l -> fsize = 2;
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 84
diff changeset
279 f16 = 1;
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 84
diff changeset
280 }
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 84
diff changeset
281 if (fs8)
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 84
diff changeset
282 f8 = 1;
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 84
diff changeset
283 if (fs16)
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 84
diff changeset
284 f16 = 1;
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 84
diff changeset
285 if (l -> fsize == 2)
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 84
diff changeset
286 f16 = 1;
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 84
diff changeset
287 else if (l -> fsize == 1)
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 84
diff changeset
288 f8 = 1;
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 84
diff changeset
289 if (as -> passnum == 1)
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 84
diff changeset
290 v -= as -> addr;
32
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
291
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
292 // we have a slight problem here
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
293 // PCR based on current insn loc is really
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
294 // -125 <= offset <= +130 (8 bit offset)
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
295 // NOTE: when we are called, we already have the opcode emitted
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
296 // so we only need to worry about the size of the operand
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
297 // hence the 2 and 3 magic numbers below instead of 3 and 4
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
298 // (and that also avoids errors with two byte opcodes, etc)
81
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
299 if (f8 || (!f16 && v >= -125 && v <= 130))
32
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
300 {
101
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 84
diff changeset
301 f8 = 1;
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 84
diff changeset
302 l -> fsize = 1;
32
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
303 *b1 = indir | 0x8C;
101
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 84
diff changeset
304 if (as -> passnum == 1)
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 84
diff changeset
305 v -= 2;
81
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
306 if (v < -128 || v > 127)
32
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
307 register_error(as, l, 2, "Byte overflow");
81
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
308 *b2 = v & 0xff;
101
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 84
diff changeset
309 if (r != 0 && as -> passnum == 2)
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 84
diff changeset
310 {
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 84
diff changeset
311 register_error(as, l, 2, "Illegal incomplete reference");
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 84
diff changeset
312 }
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 84
diff changeset
313 goto finpcr;
32
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
314 }
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
315
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
316 // anything else is 16 bit offset
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
317 // need 16 bit
101
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 84
diff changeset
318
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 84
diff changeset
319 l -> fsize = 2;
32
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
320 *b1 = indir | 0x8D;
101
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 84
diff changeset
321 if (as -> passnum == 1)
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 84
diff changeset
322 v -= 3;
81
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
323 *b2 = (v >> 8) & 0xff;
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
324 *b3 = v & 0xff;
101
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 84
diff changeset
325 if (as -> passnum == 2 && r == 1)
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 84
diff changeset
326 {
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 84
diff changeset
327 t = lwasm_expr_term_create_secbase();
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 84
diff changeset
328 lwasm_expr_stack_push(l -> exprs[0], t);
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 84
diff changeset
329 lwasm_expr_term_free(t);
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 84
diff changeset
330 t = lwasm_expr_term_create_oper(LWASM_OPER_MINUS);
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 84
diff changeset
331 lwasm_expr_stack_push(l -> exprs[0], t);
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 84
diff changeset
332 lwasm_expr_term_free(t);
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 84
diff changeset
333 }
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 84
diff changeset
334
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 84
diff changeset
335 finpcr:
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 84
diff changeset
336 if (as -> passnum == 1)
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 84
diff changeset
337 {
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 84
diff changeset
338 // need to adjust the expression
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 84
diff changeset
339 if (l -> exprs[0])
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 84
diff changeset
340 {
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 84
diff changeset
341 t = lwasm_expr_term_create_int(as -> addr + (f8 ? 2 : 3));
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 84
diff changeset
342 lwasm_expr_stack_push(l -> exprs[0], t);
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 84
diff changeset
343 lwasm_expr_term_free(t);
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 84
diff changeset
344 t = lwasm_expr_term_create_oper(LWASM_OPER_MINUS);
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 84
diff changeset
345 lwasm_expr_stack_push(l -> exprs[0], t);
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 84
diff changeset
346 lwasm_expr_term_free(t);
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 84
diff changeset
347 }
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 84
diff changeset
348 else
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 84
diff changeset
349 {
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 84
diff changeset
350 l -> exprvals[0] -= as -> addr + (f8 ? 2 : 3);
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 84
diff changeset
351 }
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 84
diff changeset
352 }
32
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
353 return;
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
354 }
101
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 84
diff changeset
355 if (fs16)
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 84
diff changeset
356 f16 = 1;
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 84
diff changeset
357 if (fs8)
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 84
diff changeset
358 f8 = 1;
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 84
diff changeset
359
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 84
diff changeset
360 if (f8 && r != 0)
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 84
diff changeset
361 {
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 84
diff changeset
362 register_error(as, l, 2, "Illegal external or inter-section reference");
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 84
diff changeset
363 r = 0;
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 84
diff changeset
364 v = 0;
f59c0916753d Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents: 84
diff changeset
365 }
32
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
366
81
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
367 // constant offset from PC (using PC as regular register :) )
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
368 // FIXME: handle external references intelligently
32
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
369 if (rn == 6)
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
370 {
81
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
371 if (f8 || (!f16 && v >= -128 && v <= 127))
32
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
372 {
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
373 *b1 = indir | 0x8C;
81
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
374 if (v < -128 || v > 127)
32
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
375 register_error(as, l, 2, "Byte overflow");
81
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
376 *b2 = v & 0xff;
32
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
377 return;
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
378 }
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
379
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
380 // everything else must be 16 bit
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
381 // need 16 bit
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
382 *b1 = indir | 0x8D;
81
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
383 *b2 = (v >> 8) & 0xff;
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
384 *b3 = v & 0xff;
32
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
385 return;
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
386 }
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
387
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
388 // we only have to deal with x,y,u,s here
81
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
389 if (!f8 && !f16 && v >= -16 && v <= 15)
32
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
390 {
81
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
391 // zero offset going to ,R?
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
392 if (v == 0 && !f0 && !(as -> pragmas & PRAGMA_NOINDEX0TONONE))
32
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
393 {
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
394 *b1 = rn << 5 | indir | 0x80 | 0x04;
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
395 return;
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
396 }
81
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
397
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
398 // no 5 bit on indirect
32
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
399 if (indir)
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
400 {
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
401 f8 = 1;
81
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
402 l -> fsize = 1;
32
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
403 goto no5bit;
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
404 }
81
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
405
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
406 // 5 bit addressing
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
407 *b1 = rn << 5 | (v & 0x1F);
32
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
408 return;
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
409 }
81
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
410
32
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
411 no5bit:
81
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
412 if (f16 || (!f8 && (v < -128 || v > 127)))
32
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
413 {
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
414 // must be a 16 bit offset here
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
415 *b1 = rn << 5 | indir | 0x80 | 0x09;
81
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
416 *b2 = (v >> 8) & 0xff;
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
417 *b3 = v & 0xff;
32
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
418 return;
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
419 }
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
420
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
421 // if we're here, we have an 8 bit offset
81
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
422 // note: cannot get here if incomplete reference detected above
32
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
423 *b1 = rn << 5 | indir | 0x80 | 0x08;
81
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
424 if (v < -128 || v > 127)
32
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
425 register_error(as, l, 2, "Byte overflow");
81
b6b1e79cc277 Moved indexed modes to new expression framework
lost
parents: 37
diff changeset
426 *b2 = v & 0xff;
32
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
427 return;
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
428 }
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
429
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
430 OPFUNC(insn_indexed)
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
431 {
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
432 int b1, b2, b3;
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
433
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
434 lwasm_emitop(as, l, instab[opnum].ops[0]);
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
435
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
436 insn_indexed_aux(as, l, (const char **)p, &b1, &b2, &b3);
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
437 if (b1 != -1)
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
438 lwasm_emit(as, l, b1);
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
439 if (b2 != -1)
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
440 lwasm_emit(as, l, b2);
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
441 if (b3 != -1)
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
442 lwasm_emit(as, l, b3);
9bd0fbfe7405 Added basic indexed mode handling
lost
parents:
diff changeset
443 }