Mercurial > hg-old > index.cgi
annotate src/insn_bitbit.c @ 183:302b8db5fd89
modified lwlink to merge contiguous sections in the DECB output file to avoid the explosion of preambles
author | lost |
---|---|
date | Sat, 21 Mar 2009 17:03:42 +0000 |
parents | f59c0916753d |
children |
rev | line source |
---|---|
32 | 1 /* |
2 insn_bitbit.c | |
33
74a3fef7c8d0
Added general addressing modes (immediate, base page, extended, indexed)
lost
parents:
32
diff
changeset
|
3 Copyright © 2009 William Astle |
32 | 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 /* | |
22 for handling inherent mode instructions | |
23 */ | |
24 | |
25 #define __insn_bitbit_c_seen__ | |
26 | |
27 #include <stdlib.h> | |
28 | |
29 #include "lwasm.h" | |
30 #include "instab.h" | |
31 #include "expr.h" | |
32 | |
80
8929e1ee99cf
Checkpointing deployment of non-constant expression handling
lost
parents:
37
diff
changeset
|
33 // these instructions cannot tolerate external references |
32 | 34 OPFUNC(insn_bitbit) |
35 { | |
36 int r; | |
37 lwasm_expr_stack_t *s; | |
38 int v1; | |
39 int tv; | |
80
8929e1ee99cf
Checkpointing deployment of non-constant expression handling
lost
parents:
37
diff
changeset
|
40 |
32 | 41 lwasm_emitop(as, l, instab[opnum].ops[0]); |
42 | |
43 r = toupper(*(*p)++); | |
44 if (r == 'A') | |
45 r = 1; | |
46 else if (r == 'B') | |
47 r = 2; | |
48 else if (r == 'C' && toupper(**p) == 'C') | |
49 { | |
50 r = 0; | |
51 (*p)++; | |
52 } | |
53 else | |
54 { | |
55 register_error(as, l, 1, "Bad register"); | |
56 return; | |
57 } | |
58 if (*(*p)++ != ',') | |
59 { | |
60 register_error(as, l, 1, "Bad operand"); | |
61 return; | |
62 } | |
101
f59c0916753d
Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents:
80
diff
changeset
|
63 s = lwasm_evaluate_expr(as, l, *p, NULL, 0); |
32 | 64 if (!s) |
65 { | |
66 register_error(as, l, 1, "Bad operand"); | |
67 return; | |
68 } | |
69 if (!lwasm_expr_is_constant(s)) | |
70 { | |
71 register_error(as, l, 2, "Incomplete reference"); | |
72 } | |
73 v1 = lwasm_expr_get_value(s); | |
74 lwasm_expr_stack_free(s); | |
75 if (v1 < 0 || v1 > 7) | |
76 { | |
77 register_error(as, l, 2, "Invalid bit number"); | |
78 v1 = 0; | |
79 } | |
80 if (*(*p)++ != ',') | |
81 { | |
82 register_error(as, l, 1, "Bad operand"); | |
83 return; | |
84 } | |
85 r = (r << 6) | (v1 << 3); | |
86 | |
101
f59c0916753d
Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents:
80
diff
changeset
|
87 s = lwasm_evaluate_expr(as, l, *p, NULL, 0); |
32 | 88 if (!s) |
89 { | |
90 register_error(as, l, 1, "Bad operand"); | |
91 return; | |
92 } | |
93 if (!lwasm_expr_is_constant(s)) | |
94 { | |
95 register_error(as, l, 1, "Incomplete reference"); | |
96 } | |
97 v1 = lwasm_expr_get_value(s); | |
98 lwasm_expr_stack_free(s); | |
99 if (v1 < 0 || v1 > 7) | |
100 { | |
101 register_error(as, l, 2, "Invalid bit number"); | |
102 v1 = 0; | |
103 } | |
104 if (*(*p)++ != ',') | |
105 { | |
106 register_error(as, l, 1, "Bad operand"); | |
107 return; | |
108 } | |
109 r |= v1; | |
110 | |
111 lwasm_emit(as, l, r); | |
112 | |
113 // ignore base page address modifier | |
114 if (**p == '<') | |
115 (*p)++; | |
116 | |
101
f59c0916753d
Fixed relative branches and PCR addressing to handle constant intra-section references properly
lost
parents:
80
diff
changeset
|
117 s = lwasm_evaluate_expr(as, l, *p, NULL, 0); |
32 | 118 if (!s) |
119 { | |
120 register_error(as, l, 1, "Bad operand"); | |
121 return; | |
122 } | |
123 if (!lwasm_expr_is_constant(s)) | |
124 { | |
125 register_error(as, l, 1, "Incomplete reference"); | |
126 } | |
127 v1 = lwasm_expr_get_value(s); | |
128 lwasm_expr_stack_free(s); | |
129 v1 &= 0xFFFF; | |
130 | |
131 tv = v1 - ((as -> dpval) << 8); | |
132 if (tv > 0xFF || tv < 0) | |
133 { | |
134 register_error(as, l, 2, "Byte overflow"); | |
135 } | |
136 lwasm_emit(as, l, tv & 0xff); | |
137 } |