Mercurial > hg-old > index.cgi
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 } |