comparison src/insn_gen.c @ 0:57495da01900

Initial checking of LWASM
author lost
date Fri, 03 Oct 2008 02:44:20 +0000
parents
children 34568fab6058
comparison
equal deleted inserted replaced
-1:000000000000 0:57495da01900
1 /*
2 * insn_gen.c
3 *
4 * parsing general addressing modes (IMM+DIR+EXT+IND)
5 */
6
7 #include <ctype.h>
8 #include "lwasm.h"
9 #include "instab.h"
10
11 extern void insn_indexed_aux(asmstate_t *as, sourceline_t *cl, char **optr, int *b1, int *b2, int *b3);
12
13 void insn_gen_aux(asmstate_t *as, sourceline_t *cl, char **optr, int *b1, int *b2, int *b3, int *op)
14 {
15 *b1 = *b2 = *b3 = -1;
16 char *optr2;
17 int v1, tv, rval;
18
19 optr2 = *optr;
20 while (*optr2 && !isspace(*optr2) && *optr2 != ',') optr2++
21 ;
22 if (*optr2 != ',' && **optr != '[')
23 {
24 // not indexed
25 if (**optr == '<')
26 {
27 (*optr)++;
28 rval = eval_expr(as, cl, optr, &v1);
29 v1 = v1 & 0xffff;
30 tv = v1 - ((cl -> dpval) << 8);
31 if (tv < 0 || tv > 0xff)
32 {
33 errorp2(ERR_OVERFLOW);
34 }
35 v1 = v1 & 0xff;
36 goto ins_gen_dir;
37 }
38 else if (**optr == '>')
39 {
40 // extended mode
41 (*optr)++;
42 rval = eval_expr(as, cl, optr, &v1);
43 goto ins_gen_ext;
44 }
45 else
46 {
47 // eval expr and see how big it is
48 rval = eval_expr(as, cl, optr, &v1);
49 v1 = v1 & 0xFFFF;
50
51 if (cl -> undef && as -> passnum == 1)
52 {
53 cl -> p1f16 = 1;
54 goto ins_gen_ext;
55 }
56
57 tv = v1 - (cl -> dpval << 8);
58
59 if (tv < 0 || tv > 0xff || cl -> p1f16)
60 goto ins_gen_ext;
61 else
62 {
63 v1 = v1 & 0xff;
64 goto ins_gen_dir;
65 }
66 }
67 return;
68 }
69
70 *op = instab[cl -> opcode].ops[1];
71 insn_indexed_aux(as, cl, optr, b1, b2, b3);
72 return;
73
74 ins_gen_dir:
75 *op = instab[cl -> opcode].ops[0];
76 // cl -> code_operlen = 1;
77 cl -> addrmode = OPER_DIR;
78 if ((v1 & 0xFFFF) > 0xff)
79 errorp2(ERR_OVERFLOW);
80 *b1 = (v1);
81 return;
82
83 ins_gen_ext:
84 *op = instab[cl -> opcode].ops[2];
85 // cl -> code_operlen = 2;
86 cl -> addrmode = OPER_EXT;
87 *b1 = (v1 >> 8);
88 *b2 = (v1 & 0xff);
89 return;
90 }
91
92 void insn_gen(asmstate_t *as, sourceline_t *cl, char **optr)
93 {
94 int rval;
95 int v1;
96 int b1, b2, b3, op;
97
98 if (**optr == '#')
99 {
100 // immediate mode has perterbations on instruction size
101 (*optr)++;
102 emitop(instab[cl -> opcode].ops[3]);
103 rval = eval_expr(as, cl, optr, &v1);
104
105 switch (instab[cl -> opcode].instype)
106 {
107 case INSTYPE_GEN8:
108 case INSTYPE_IMM8:
109 cl -> addrmode = OPER_IMM8;
110 // cl -> code_operlen = 1;
111 emit(v1 & 0xff);
112 if (v1 < -128 || v1 > 255)
113 errorp2(ERR_OVERFLOW);
114 return;
115
116 case INSTYPE_GEN:
117 cl -> addrmode = OPER_IMM16;
118 // cl -> code_operlen = 2;
119 emit(v1 >> 8);
120 emit(v1 & 0xff);
121 return;
122
123 case INSTYPE_GEN32:
124 cl -> addrmode = OPER_IMM32;
125 // cl -> code_operlen = 4;
126 emit(v1 >> 24);
127 emit((v1 >> 16) & 0xff);
128 emit((v1 >> 8) & 0xff);
129 emit(v1 & 0xff);
130 return;
131
132 default:
133 errorp1(ERR_BADOPER);
134 return;
135
136 }
137
138 return;
139 }
140 if (instab[cl -> opcode].instype == INSTYPE_IMM8)
141 {
142 errorp1(ERR_BADOPER);
143 return;
144 }
145
146 insn_gen_aux(as, cl, optr, &b1, &b2, &b3, &op);
147 emitop(op);
148 if (b1 != -1)
149 emit(b1);
150 if (b2 != -1)
151 emit(b2);
152 if (b3 != -1)
153 emit(b3);
154 }