comparison src/insn_gen.c @ 33:74a3fef7c8d0

Added general addressing modes (immediate, base page, extended, indexed)
author lost
date Fri, 02 Jan 2009 05:02:47 +0000
parents 34568fab6058
children b29eec6f3819
comparison
equal deleted inserted replaced
32:9bd0fbfe7405 33:74a3fef7c8d0
1 /* 1 /*
2 insn_gen.c, Copyright © 2008 William Astle 2 insn_gen.c, Copyright © 2009 William Astle
3 3
4 This file is part of LWASM. 4 This file is part of LWASM.
5 5
6 LWASM is free software: you can redistribute it and/or modify it under the 6 LWASM is free software: you can redistribute it and/or modify it under the
7 terms of the GNU General Public License as published by the Free Software 7 terms of the GNU General Public License as published by the Free Software
18 18
19 Contains code for parsing general addressing modes (IMM+DIR+EXT+IND) 19 Contains code for parsing general addressing modes (IMM+DIR+EXT+IND)
20 */ 20 */
21 21
22 #include <ctype.h> 22 #include <ctype.h>
23 #include <stdlib.h>
24
23 #include "lwasm.h" 25 #include "lwasm.h"
24 #include "instab.h" 26 #include "instab.h"
25 27 #include "expr.h"
26 extern void insn_indexed_aux(asmstate_t *as, sourceline_t *cl, char **optr, int *b1, int *b2, int *b3); 28
27 29 extern void insn_indexed_aux(asmstate_t *as, lwasm_line_t *l, const char **p, int *b1, int *b2, int *b3);
28 void insn_gen_aux(asmstate_t *as, sourceline_t *cl, char **optr, int *b1, int *b2, int *b3, int *op) 30
29 { 31 void insn_gen_aux(asmstate_t *as, lwasm_line_t *l, char **optr, int opnum)
30 *b1 = *b2 = *b3 = -1; 32 {
31 char *optr2; 33 int b1 = -1, b2 = -1, b3 = -1;
34
35 const char *optr2;
32 int v1, tv, rval; 36 int v1, tv, rval;
37 lwasm_expr_stack_t *s;
38 int f8 = 0;
39 int f16 = 0;
33 40
34 optr2 = *optr; 41 optr2 = *optr;
35 while (*optr2 && !isspace(*optr2) && *optr2 != ',') optr2++ 42 while (*optr2 && !isspace(*optr2) && *optr2 != ',') optr2++
36 ; 43 /* do nothing */ ;
44
37 if (*optr2 != ',' && **optr != '[') 45 if (*optr2 != ',' && **optr != '[')
38 { 46 {
39 // not indexed 47 // not indexed
48 if (l -> fsize == 1)
49 f8 = 1;
50 else if (l -> fsize == 2)
51 f16 = 1;
52
40 if (**optr == '<') 53 if (**optr == '<')
41 { 54 {
42 (*optr)++; 55 (*optr)++;
43 rval = eval_expr(as, cl, optr, &v1); 56 f8 = 1;
57 }
58 else if (**optr == '>')
59 {
60 (*optr)++;
61 f16 = 1;
62 }
63 s = lwasm_expr_eval(*optr, NULL);
64 if (!s)
65 {
66 register_error(as, l, 1, "Bad expression");
67 return;
68 }
69 if (!lwasm_expr_is_constant(s))
70 {
71 f16 = 1;
72 l -> fsize = 2;
73 register_error(as, l, 2, "Incomplete reference");
74 }
75 v1 = lwasm_expr_get_value(s);
76 lwasm_expr_stack_free(s);
77
78 if (f8 || (!f16 && v1 >= -128 && v1 <= 255))
79 {
44 v1 = v1 & 0xffff; 80 v1 = v1 & 0xffff;
45 tv = v1 - ((cl -> dpval) << 8); 81 tv = v1 - ((as -> dpval) << 8);
46 if (tv < 0 || tv > 0xff) 82 if (tv < 0 || tv > 0xff)
47 { 83 {
48 errorp2(ERR_OVERFLOW); 84 register_error(as, l, 2, "Byte overflow");
49 } 85 }
50 v1 = v1 & 0xff; 86 v1 = v1 & 0xff;
51 goto ins_gen_dir; 87 lwasm_emitop(as, l, instab[opnum].ops[0]);
52 } 88 lwasm_emit(as, l, v1 & 0xff);
53 else if (**optr == '>') 89 return;
54 { 90 }
55 // extended mode 91 else
56 (*optr)++; 92 {
57 rval = eval_expr(as, cl, optr, &v1); 93 // everything else is 16 bit....
58 goto ins_gen_ext; 94 lwasm_emitop(as, l, instab[opnum].ops[2]);
59 } 95 lwasm_emit(as, l, v1 >> 8);
60 else 96 lwasm_emit(as, l, v1 & 0xff);
61 { 97 return;
62 // eval expr and see how big it is 98 }
63 rval = eval_expr(as, cl, optr, &v1);
64 v1 = v1 & 0xFFFF;
65
66 if (cl -> undef && as -> passnum == 1)
67 {
68 cl -> p1f16 = 1;
69 goto ins_gen_ext;
70 }
71
72 tv = v1 - (cl -> dpval << 8);
73
74 if (tv < 0 || tv > 0xff || cl -> p1f16)
75 goto ins_gen_ext;
76 else
77 {
78 v1 = v1 & 0xff;
79 goto ins_gen_dir;
80 }
81 }
82 return;
83 } 99 }
84 100
85 *op = instab[cl -> opcode].ops[1]; 101 lwasm_emitop(as, l, instab[opnum].ops[1]);
86 insn_indexed_aux(as, cl, optr, b1, b2, b3); 102 insn_indexed_aux(as, l, (const char **)optr, &b1, &b2, &b3);
103 if (b1 != -1)
104 lwasm_emit(as, l, b1);
105 if (b2 != -1)
106 lwasm_emit(as, l, b2);
107 if (b3 != -1)
108 lwasm_emit(as, l, b3);
87 return; 109 return;
88 110 }
89 ins_gen_dir: 111
90 *op = instab[cl -> opcode].ops[0]; 112 // the various insn_gen? functions have an immediate mode of ? bits
91 // cl -> code_operlen = 1; 113 OPFUNC(insn_gen0)
92 cl -> addrmode = OPER_DIR; 114 {
93 if ((v1 & 0xFFFF) > 0xff) 115 if (**p == '#')
94 errorp2(ERR_OVERFLOW); 116 {
95 *b1 = (v1); 117 register_error(as, l, 1, "Immediate mode not allowed");
96 return; 118 return;
97 119 }
98 ins_gen_ext: 120
99 *op = instab[cl -> opcode].ops[2]; 121 // handle non-immediate
100 // cl -> code_operlen = 2; 122 insn_gen_aux(as, l, p, opnum);
101 cl -> addrmode = OPER_EXT; 123 }
102 *b1 = (v1 >> 8); 124
103 *b2 = (v1 & 0xff); 125 OPFUNC(insn_gen8)
104 return; 126 {
105 } 127 lwasm_expr_stack_t *s;
106 128 int rval;
107 void insn_gen(asmstate_t *as, sourceline_t *cl, char **optr) 129
108 { 130 if (**p == '#')
109 int rval; 131 {
110 int v1; 132 lwasm_emitop(as, l, instab[opnum].ops[3]);
111 int b1, b2, b3, op; 133 (*p)++;
112 134 s = lwasm_expr_eval(*p, NULL);
113 if (**optr == '#') 135 if (!s)
114 { 136 {
115 // immediate mode has perterbations on instruction size 137 register_error(as, l, 1, "Bad expression");
116 (*optr)++; 138 rval = 0;
117 emitop(instab[cl -> opcode].ops[3]); 139 }
118 rval = eval_expr(as, cl, optr, &v1); 140 else
119 141 {
120 switch (instab[cl -> opcode].instype) 142 if (!lwasm_expr_is_constant(s))
121 { 143 register_error(as, l, 2, "Incomplete reference");
122 case INSTYPE_GEN8: 144 rval = lwasm_expr_get_value(s);
123 case INSTYPE_IMM8: 145 lwasm_expr_stack_free(s);
124 cl -> addrmode = OPER_IMM8; 146 }
125 // cl -> code_operlen = 1; 147 if (rval < -128 || rval > 255)
126 emit(v1 & 0xff); 148 register_error(as, l, 2, "Byte overflow");
127 if (v1 < -128 || v1 > 255) 149 lwasm_emit(as, l, rval & 0xff);
128 errorp2(ERR_OVERFLOW); 150 return;
129 return; 151 }
130 152
131 case INSTYPE_GEN: 153 insn_gen_aux(as, l, p, opnum);
132 cl -> addrmode = OPER_IMM16; 154 }
133 // cl -> code_operlen = 2; 155
134 emit(v1 >> 8); 156 OPFUNC(insn_gen16)
135 emit(v1 & 0xff); 157 {
136 return; 158 lwasm_expr_stack_t *s;
137 159 int rval;
138 case INSTYPE_GEN32: 160
139 cl -> addrmode = OPER_IMM32; 161 if (**p == '#')
140 // cl -> code_operlen = 4; 162 {
141 emit(v1 >> 24); 163 lwasm_emitop(as, l, instab[opnum].ops[3]);
142 emit((v1 >> 16) & 0xff); 164 (*p)++;
143 emit((v1 >> 8) & 0xff); 165 s = lwasm_expr_eval(*p, NULL);
144 emit(v1 & 0xff); 166 if (!s)
145 return; 167 {
146 168 register_error(as, l, 1, "Bad expression");
147 default: 169 rval = 0;
148 errorp1(ERR_BADOPER); 170 }
149 return; 171 else
150 172 {
151 } 173 if (!lwasm_expr_is_constant(s))
152 174 register_error(as, l, 2, "Incomplete reference");
153 return; 175 rval = lwasm_expr_get_value(s);
154 } 176 lwasm_expr_stack_free(s);
155 if (instab[cl -> opcode].instype == INSTYPE_IMM8) 177 }
156 { 178 lwasm_emit(as, l, (rval >> 8) & 0xff);
157 errorp1(ERR_BADOPER); 179 lwasm_emit(as, l, rval & 0xff);
158 return; 180 return;
159 } 181 }
160 182
161 insn_gen_aux(as, cl, optr, &b1, &b2, &b3, &op); 183 insn_gen_aux(as, l, p, opnum);
162 emitop(op); 184 }
163 if (b1 != -1) 185
164 emit(b1); 186 OPFUNC(insn_gen32)
165 if (b2 != -1) 187 {
166 emit(b2); 188 lwasm_expr_stack_t *s;
167 if (b3 != -1) 189 int rval;
168 emit(b3); 190
169 } 191 if (**p == '#')
192 {
193 lwasm_emitop(as, l, instab[opnum].ops[3]);
194 (*p)++;
195 s = lwasm_expr_eval(*p, NULL);
196 if (!s)
197 {
198 register_error(as, l, 1, "Bad expression");
199 rval = 0;
200 }
201 else
202 {
203 if (!lwasm_expr_is_constant(s))
204 register_error(as, l, 2, "Incomplete reference");
205 rval = lwasm_expr_get_value(s);
206 lwasm_expr_stack_free(s);
207 }
208 lwasm_emit(as, l, (rval >> 24) & 0xff);
209 lwasm_emit(as, l, (rval >> 16) & 0xff);
210 lwasm_emit(as, l, (rval >> 8) & 0xff);
211 lwasm_emit(as, l, rval & 0xff);
212 return;
213 }
214
215 insn_gen_aux(as, l, p, opnum);
216 }
217
218 OPFUNC(insn_imm8)
219 {
220 lwasm_expr_stack_t *s;
221 int rval;
222
223 if (**p == '#')
224 {
225 lwasm_emitop(as, l, instab[opnum].ops[0]);
226 (*p)++;
227 s = lwasm_expr_eval(*p, NULL);
228 if (!s)
229 {
230 register_error(as, l, 1, "Bad expression");
231 rval = 0;
232 }
233 else
234 {
235 if (!lwasm_expr_is_constant(s))
236 register_error(as, l, 2, "Incomplete reference");
237 rval = lwasm_expr_get_value(s);
238 lwasm_expr_stack_free(s);
239 }
240 if (rval < -128 || rval > 255)
241 register_error(as, l, 2, "Byte overflow");
242 lwasm_emit(as, l, rval & 0xff);
243 return;
244 }
245
246 register_error(as, l, 1, "Bad operand");
247 }