Mercurial > hg-old > index.cgi
comparison lwasm/insn_bitbit.c @ 358:be0f9f8d799f
Bit transfer ops added
author | lost@starbug |
---|---|
date | Wed, 31 Mar 2010 20:37:59 -0600 |
parents | old-trunk/lwasm/old/insn_bitbit.c@eb230fa7d28e |
children |
comparison
equal
deleted
inserted
replaced
357:0cf4948d53b4 | 358:be0f9f8d799f |
---|---|
1 /* | |
2 insn_bitbit.c | |
3 Copyright © 2009 William Astle | |
4 | |
5 This file is part of LWASM. | |
6 | |
7 LWASM is free software: you can redistribute it and/or modify it under the | |
8 terms of the GNU General Public License as published by the Free Software | |
9 Foundation, either version 3 of the License, or (at your option) any later | |
10 version. | |
11 | |
12 This program is distributed in the hope that it will be useful, but WITHOUT | |
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | |
15 more details. | |
16 | |
17 You should have received a copy of the GNU General Public License along with | |
18 this program. If not, see <http://www.gnu.org/licenses/>. | |
19 */ | |
20 | |
21 #include <config.h> | |
22 #include <stdlib.h> | |
23 | |
24 #include <lw_expr.h> | |
25 | |
26 #include "lwasm.h" | |
27 #include "instab.h" | |
28 | |
29 // these instructions cannot tolerate external references | |
30 PARSEFUNC(insn_parse_bitbit) | |
31 { | |
32 int r; | |
33 lw_expr_t e; | |
34 int v1; | |
35 int tv; | |
36 | |
37 r = toupper(*(*p)++); | |
38 if (r == 'A') | |
39 r = 1; | |
40 else if (r == 'B') | |
41 r = 2; | |
42 else if (r == 'C' && toupper(**p) == 'C') | |
43 { | |
44 r = 0; | |
45 (*p)++; | |
46 } | |
47 else | |
48 { | |
49 lwasm_register_error(as, l, "Bad register"); | |
50 return; | |
51 } | |
52 | |
53 if (*(*p)++ != ',') | |
54 { | |
55 lwasm_register_error(as, l, "Bad operand"); | |
56 return; | |
57 } | |
58 e = lwasm_parse_expr(as, p); | |
59 if (!e) | |
60 { | |
61 lwasm_register_error(as, l, "Bad operand"); | |
62 return; | |
63 } | |
64 lwasm_save_expr(l, 0, e); | |
65 if (*(*p)++ != ',') | |
66 { | |
67 lwasm_register_error(as, l, "Bad operand"); | |
68 return; | |
69 } | |
70 | |
71 e = lwasm_parse_expr(as, p); | |
72 if (!e) | |
73 { | |
74 lwasm_register_error(as, l, "Bad operand"); | |
75 return; | |
76 } | |
77 lwasm_save_expr(l, 1, e); | |
78 | |
79 if (*(*p)++ != ',') | |
80 { | |
81 lwasm_register_error(as, l, "Bad operand"); | |
82 return; | |
83 } | |
84 | |
85 // ignore base page address modifier | |
86 if (**p == '<') | |
87 (*p)++; | |
88 | |
89 e = lwasm_parse_expr(as, p); | |
90 if (!e) | |
91 { | |
92 lwasm_register_error(as, l, "Bad operand"); | |
93 return; | |
94 } | |
95 lwasm_save_expr(l, 2, e); | |
96 | |
97 l -> lint = r; | |
98 l -> len = OPLEN(instab[l -> insn].ops[0]) + 2; | |
99 } | |
100 | |
101 EMITFUNC(insn_emit_bitbit) | |
102 { | |
103 int v1, v2; | |
104 lw_expr_t e; | |
105 | |
106 e = lwasm_fetch_expr(l, 0); | |
107 if (!lw_expr_istype(e, lw_expr_type_int)) | |
108 { | |
109 lwasm_register_error(as, l, "Bit number must be fully resolved"); | |
110 return; | |
111 } | |
112 v1 = lw_expr_intval(e); | |
113 if (v1 < 0 || v1 > 7) | |
114 { | |
115 lwasm_register_error(as, l, "Invalid bit number"); | |
116 v1 = 0; | |
117 } | |
118 | |
119 e = lwasm_fetch_expr(l, 1); | |
120 if (!lw_expr_istype(e, lw_expr_type_int)) | |
121 { | |
122 lwasm_register_error(as, l, "Bit number must be fully resolved"); | |
123 return; | |
124 } | |
125 v2 = lw_expr_intval(e); | |
126 if (v2 < 0 || v2 > 7) | |
127 { | |
128 lwasm_register_error(as, l, "Invalid bit number"); | |
129 v2 = 0; | |
130 } | |
131 l -> pb = (l -> lint << 6) | (v1 << 3) | v2; | |
132 | |
133 e = lwasm_fetch_expr(l, 2); | |
134 if (lw_expr_istype(e, lw_expr_type_int)) | |
135 { | |
136 v1 = lw_expr_intval(e) & 0xFFFF; | |
137 v2 = v1 - ((l -> dpval) << 8); | |
138 if (v2 > 0xFF || v2 < 0) | |
139 { | |
140 lwasm_register_error(as, l, "Byte overflow"); | |
141 return; | |
142 } | |
143 } | |
144 lwasm_emitop(l, instab[l -> insn].ops[0]); | |
145 lwasm_emit(l, l -> pb); | |
146 lwasm_emitexpr(l, e, 1); | |
147 } |