struct / union in initializer, RFE #901.
[sdcc.git] / sdcc / sdas / aspdk14 / pdk14mch.c
blob263330916ec0d472711b3ed6338a60043b32b9bb
1 /* pdk14mch.c */
3 /*
4 * Copyright (C) 1998-2011 Alan R. Baldwin
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 * Alan R. Baldwin
21 * 721 Berkeley St.
22 * Kent, Ohio 44240
24 * This Assember Ported by
25 * John L. Hartman (JLH)
26 * jhartman at compuserve dot com
27 * noice at noicedebugger dot com
29 * Benny Kim (2011/07/21)
30 * bennykim at coreriver dot com
31 * Fixed bugs in relative address with "."
34 #include "sdas.h"
35 #include "asxxxx.h"
36 #include "pdk.h"
38 char *cpu = "Padauk 14";
39 char *dsft = "asm";
42 * Process machine ops.
44 VOID
45 machine(struct mne *mp)
47 a_uint op, opWithFlags;
48 int combine;
50 opWithFlags = mp->m_valu;
51 op = opWithFlags & PDK_OPCODE_MASK;
52 combine = 0;
54 /* Default instructions are only used for A -> K instructions.
55 * Although they may be (ab)used for other types.
57 struct inst def = {op, 0xFF};
58 switch (mp->m_type) {
60 case S_MOV: {
61 struct inst ioa = {0x0180, 0x3F};
62 struct inst aio = {0x01C0, 0x3F};
63 struct inst ma = {0x0B80, 0x7F};
64 struct inst am = {0x0F80, 0x7F};
65 emov(opWithFlags, def, ioa, aio, ma, am);
66 break;
69 case S_IDXM: {
70 struct inst am = {op | 1, 0x7E};
71 struct inst ma = {op, 0x7E};
72 eidxm(am, ma);
73 break;
76 case S_SUB:
77 combine = 0x80;
78 /* fallthrough */
79 case S_ADD: {
80 struct inst ma = {0x0800 | combine, 0x7F};
81 struct inst am = {0x0C00 | combine, 0x7F};
82 earith(def, ma, am);
83 break;
86 case S_SUBC:
87 combine = 0x80;
88 /* fallthrough */
89 case S_ADDC: {
90 struct inst ma = {0x0900 | combine, 0x7F};
91 struct inst am = {0x0D00 | combine, 0x7F};
92 struct inst m = {0x1000 | combine, 0x7F};
93 struct inst a = {0x0060 + (combine ? 1 : 0), 0x00};
94 earithc(ma, am, m, a);
95 break;
98 case S_SLC:
99 case S_SRC:
100 case S_SL:
101 case S_SR: {
102 if (mp->m_type == S_SRC || mp->m_type == S_SLC)
103 combine = 2;
104 if (mp->m_type == S_SL || mp->m_type == S_SLC)
105 combine += 1;
107 struct inst a = {0x006A + combine, 0x00};
108 struct inst m = {0x1500 + (combine << 7), 0x7F};
109 eshift(a, m);
110 break;
113 case S_OR:
114 case S_XOR:
115 case S_AND: {
116 if (mp->m_type == S_OR) {
117 combine = 0x80;
118 } else
119 if (mp->m_type == S_XOR) {
120 combine = 0x100;
123 struct inst ma = {0x0A00 | combine, 0x7F};
124 struct inst am = {0x0E00 | combine, 0x7F};
125 struct inst ioa = {0x00C0, 0x3F};
126 ebit(opWithFlags, def, ma, am, mp->m_type == S_XOR ? &ioa : NULL);
127 break;
130 case S_NEG:
131 combine = 0x80;
132 /* fallthrough */
133 case S_NOT: {
134 struct inst m = {0x1400 | combine, 0x7F};
135 enot(def, m);
136 break;
139 case S_SET1:
140 combine = 0x200;
141 /* fallthrough */
142 case S_SET0: {
143 struct inst io = {0x1C00 | combine, 0x3F};
144 struct inst m = {0x2400 | combine, 0x3F};
145 ebitn(opWithFlags, io, m, /*N offset*/6);
146 break;
149 case S_CNEQSN:
150 combine = 0x80;
151 /* fallthrough */
152 case S_CEQSN: {
153 struct inst m = {0x1700 | combine, 0xFF};
154 def.op |= combine << 1;
155 eskip(def, m);
156 break;
159 case S_T1SN:
160 combine = 0x200;
161 /* fallthrough */
162 case S_T0SN: {
163 struct inst io = {0x1800 | combine, 0x3F};
164 struct inst m = {0x2000 | combine, 0x3F};
165 ebitn(opWithFlags, io, m, /*N offset*/6);
166 break;
169 case S_DZSN:
170 combine = 0x80;
171 /* fallthrough */
172 case S_IZSN: {
173 struct inst m = {0x1100 | combine, 0x7F};
174 ezsn(def, m);
175 break;
178 case S_RET: {
179 struct inst k = {0x0200, 0xFF};
180 eret(def, k);
181 break;
184 case S_INC:
185 case S_DEC:
186 case S_CLEAR:
187 def.mask = 0x7F;
188 eone(def);
189 break;
191 case S_CALL:
192 case S_GOTO: {
193 struct expr e;
194 clrexpr(&e);
195 waddrmode = 1;
196 expr(&e, 0);
197 waddrmode = 0;
198 outrwp(&e, def.op, 0x7FF, /*jump=*/1);
199 break;
202 case S_XCH:
203 def.mask = 0x7F;
204 exch(def);
205 break;
207 case S_PUSHAF:
208 case S_POPAF:
209 epupo(def);
210 break;
212 case S_LDT16:
213 case S_STT16:
214 def.mask = 0x7E;
215 eone(def);
216 break;
218 case S_SWAP:
219 case S_PCADD:
220 eopta(def);
221 break;
223 case S_SWAPC:
224 def.mask = 0x3F;
225 eswapc(opWithFlags, def, /*N offset*/6);
226 break;
228 case S_COMP:
229 case S_NADD: {
230 struct inst am = {op, 0x7F};
231 struct inst ma = {op | 0x80, 0x7F};
232 espec(am, ma);
233 break;
236 /* Simple instructions consisting of only one opcode and no args */
237 case S_RETI:
238 case S_NOP:
239 case S_ENGINT:
240 case S_DISGINT:
241 case S_STOPSYS:
242 case S_STOPEXE:
243 case S_RESET:
244 case S_WDRESET:
245 case S_MUL:
246 case S_LDSPTL: /* undocumented */
247 case S_LDSPTH: /* undocumented */
248 outaw(op);
249 break;
254 * Machine specific initialization
257 VOID
258 minit(void)
261 * Byte Order
263 hilo = 0;
266 * Address Space
268 exprmasks(3);
270 /* Set the target in case it was not automatically
271 * configured from the executable filename.
273 set_sdas_target(TARGET_ID_PDK14);