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 }