comparison lwasm/insn_bitbit.c @ 0:2c24602be78f

Initial import from lwtools 3.0.1 version, with new hand built build system and file reorganization
author lost@l-w.ca
date Wed, 19 Jan 2011 22:27:17 -0700
parents
children 7317fbe024af
comparison
equal deleted inserted replaced
-1:000000000000 0:2c24602be78f
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 <stdlib.h>
22
23 #include <lw_expr.h>
24
25 #include "lwasm.h"
26 #include "instab.h"
27
28 // these instructions cannot tolerate external references
29 PARSEFUNC(insn_parse_bitbit)
30 {
31 int r;
32 lw_expr_t e;
33 int v1;
34 int tv;
35
36 r = toupper(*(*p)++);
37 if (r == 'A')
38 r = 1;
39 else if (r == 'B')
40 r = 2;
41 else if (r == 'C' && toupper(**p) == 'C')
42 {
43 r = 0;
44 (*p)++;
45 }
46 else
47 {
48 lwasm_register_error(as, l, "Bad register");
49 return;
50 }
51
52 if (*(*p)++ != ',')
53 {
54 lwasm_register_error(as, l, "Bad operand");
55 return;
56 }
57 e = lwasm_parse_expr(as, p);
58 if (!e)
59 {
60 lwasm_register_error(as, l, "Bad operand");
61 return;
62 }
63 lwasm_save_expr(l, 0, e);
64 if (*(*p)++ != ',')
65 {
66 lwasm_register_error(as, l, "Bad operand");
67 return;
68 }
69
70 e = lwasm_parse_expr(as, p);
71 if (!e)
72 {
73 lwasm_register_error(as, l, "Bad operand");
74 return;
75 }
76 lwasm_save_expr(l, 1, e);
77
78 if (*(*p)++ != ',')
79 {
80 lwasm_register_error(as, l, "Bad operand");
81 return;
82 }
83
84 // ignore base page address modifier
85 if (**p == '<')
86 (*p)++;
87
88 e = lwasm_parse_expr(as, p);
89 if (!e)
90 {
91 lwasm_register_error(as, l, "Bad operand");
92 return;
93 }
94 lwasm_save_expr(l, 2, e);
95
96 l -> lint = r;
97 l -> len = OPLEN(instab[l -> insn].ops[0]) + 2;
98 }
99
100 EMITFUNC(insn_emit_bitbit)
101 {
102 int v1, v2;
103 lw_expr_t e;
104
105 e = lwasm_fetch_expr(l, 0);
106 if (!lw_expr_istype(e, lw_expr_type_int))
107 {
108 lwasm_register_error(as, l, "Bit number must be fully resolved");
109 return;
110 }
111 v1 = lw_expr_intval(e);
112 if (v1 < 0 || v1 > 7)
113 {
114 lwasm_register_error(as, l, "Invalid bit number");
115 v1 = 0;
116 }
117
118 e = lwasm_fetch_expr(l, 1);
119 if (!lw_expr_istype(e, lw_expr_type_int))
120 {
121 lwasm_register_error(as, l, "Bit number must be fully resolved");
122 return;
123 }
124 v2 = lw_expr_intval(e);
125 if (v2 < 0 || v2 > 7)
126 {
127 lwasm_register_error(as, l, "Invalid bit number");
128 v2 = 0;
129 }
130 l -> pb = (l -> lint << 6) | (v1 << 3) | v2;
131
132 e = lwasm_fetch_expr(l, 2);
133 if (lw_expr_istype(e, lw_expr_type_int))
134 {
135 v1 = lw_expr_intval(e) & 0xFFFF;
136 v2 = v1 - ((l -> dpval) << 8);
137 if (v2 > 0xFF || v2 < 0)
138 {
139 lwasm_register_error(as, l, "Byte overflow");
140 return;
141 }
142 }
143 lwasm_emitop(l, instab[l -> insn].ops[0]);
144 lwasm_emit(l, l -> pb);
145 lwasm_emitexpr(l, e, 1);
146 }