1 /* code17c4x.c */
2 /*****************************************************************************/
3 /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
4 /* */
5 /* AS-Portierung */
6 /* */
7 /* Codegenerator PIC17C4x */
8 /* */
9 /*****************************************************************************/
10
11 #include "stdinc.h"
12 #include <string.h>
13 #include <ctype.h>
14
15 #include "bpemu.h"
16 #include "strutil.h"
17 #include "chunks.h"
18 #include "asmdef.h"
19 #include "asmsub.h"
20 #include "asmitree.h"
21 #include "asmpars.h"
22 #include "codepseudo.h"
23 #include "fourpseudo.h"
24 #include "codevars.h"
25 #include "errmsg.h"
26
27 #include "code17c4x.h"
28
29 /*---------------------------------------------------------------------------*/
30
31 static CPUVar CPU17C42;
32
33 /*---------------------------------------------------------------------------*/
34
DecodeFixed(Word Code)35 static void DecodeFixed(Word Code)
36 {
37 if (ChkArgCnt(0, 0))
38 {
39 CodeLen = 1;
40 WAsmCode[0] = Code;
41 }
42 }
43
DecodeLitt(Word Code)44 static void DecodeLitt(Word Code)
45 {
46 if (ChkArgCnt(1, 1))
47 {
48 Boolean OK;
49 Word AdrWord = EvalStrIntExpression(&ArgStr[1], Int8, &OK);
50 if (OK)
51 {
52 WAsmCode[0] = Code + (AdrWord & 0xff);
53 CodeLen = 1;
54 }
55 }
56 }
57
DecodeAri(Word Code)58 static void DecodeAri(Word Code)
59 {
60 Word DefaultDir = (Code >> 7) & 0x100;
61
62 Code &= 0x7fff;
63 if (ChkArgCnt(1, 2))
64 {
65 tEvalResult EvalResult;
66 Word AdrWord = EvalStrIntExpressionWithResult(&ArgStr[1], Int8, &EvalResult);
67
68 if (EvalResult.OK)
69 {
70 ChkSpace(SegData, EvalResult.AddrSpaceMask);
71 WAsmCode[0] = Code + (AdrWord & 0xff);
72 if (ArgCnt == 1)
73 {
74 CodeLen = 1;
75 WAsmCode[0] += DefaultDir;
76 }
77 else if (as_strcasecmp(ArgStr[2].Str, "W") == 0)
78 CodeLen = 1;
79 else if (as_strcasecmp(ArgStr[2].Str, "F") == 0)
80 {
81 CodeLen = 1;
82 WAsmCode[0] += 0x100;
83 }
84 else
85 {
86 AdrWord = EvalStrIntExpressionWithResult(&ArgStr[2], UInt1, &EvalResult);
87 if (EvalResult.OK)
88 {
89 CodeLen = 1;
90 WAsmCode[0] += (AdrWord << 8);
91 }
92 }
93 }
94 }
95 }
96
DecodeBit(Word Code)97 static void DecodeBit(Word Code)
98 {
99 if (ChkArgCnt(2, 2))
100 {
101 tEvalResult EvalResult;
102 Word AdrWord = EvalStrIntExpressionWithResult(&ArgStr[2], UInt3, &EvalResult);
103 if (EvalResult.OK)
104 {
105 WAsmCode[0] = EvalStrIntExpressionWithResult(&ArgStr[1], Int8, &EvalResult);
106 if (EvalResult.OK)
107 {
108 CodeLen = 1;
109 WAsmCode[0] += Code + (AdrWord << 8);
110 ChkSpace(SegData, EvalResult.AddrSpaceMask);
111 }
112 }
113 }
114 }
115
DecodeF(Word Code)116 static void DecodeF(Word Code)
117 {
118 if (ChkArgCnt(1, 1))
119 {
120 tEvalResult EvalResult;
121 Word AdrWord = EvalStrIntExpressionWithResult(&ArgStr[1], Int8, &EvalResult);
122 if (EvalResult.OK)
123 {
124 CodeLen = 1;
125 WAsmCode[0] = Code + AdrWord;
126 ChkSpace(SegData, EvalResult.AddrSpaceMask);
127 }
128 }
129 }
130
DecodeMOVFP_MOVPF(Word Code)131 static void DecodeMOVFP_MOVPF(Word Code)
132 {
133 if (ChkArgCnt(2, 2))
134 {
135 tStrComp *pArg1 = (Code & 0x2000) ? &ArgStr[2] : &ArgStr[1],
136 *pArg2 = (Code & 0x2000) ? &ArgStr[1] : &ArgStr[2];
137 Boolean OK;
138 Word AdrWord;
139
140 AdrWord = EvalStrIntExpression(pArg1, UInt5, &OK);
141 if (OK)
142 {
143 WAsmCode[0] = EvalStrIntExpression(pArg2, Int8, &OK);
144 if (OK)
145 {
146 WAsmCode[0] = Code + Lo(WAsmCode[0]) + (AdrWord << 8);
147 CodeLen = 1;
148 }
149 }
150 }
151 }
152
DecodeTABLRD_TABLWT(Word Code)153 static void DecodeTABLRD_TABLWT(Word Code)
154 {
155 if (ChkArgCnt(3, 3))
156 {
157 Boolean OK;
158
159 WAsmCode[0] = Lo(EvalStrIntExpression(&ArgStr[3], Int8, &OK));
160 if (OK)
161 {
162 Word AdrWord = EvalStrIntExpression(&ArgStr[2], UInt1, &OK);
163 if (OK)
164 {
165 WAsmCode[0] += AdrWord << 8;
166 AdrWord = EvalStrIntExpression(&ArgStr[1], UInt1, &OK);
167 if (OK)
168 {
169 WAsmCode[0] += Code + (AdrWord << 9);
170 CodeLen = 1;
171 }
172 }
173 }
174 }
175 }
176
DecodeTLRD_TLWT(Word Code)177 static void DecodeTLRD_TLWT(Word Code)
178 {
179 if (ChkArgCnt(2, 2))
180 {
181 Boolean OK;
182
183 WAsmCode[0] = Lo(EvalStrIntExpression(&ArgStr[2], Int8, &OK));
184 if (OK)
185 {
186 Word AdrWord = EvalStrIntExpression(&ArgStr[1], UInt1, &OK);
187 if (OK)
188 {
189 WAsmCode[0] += (AdrWord << 9) + Code;
190 CodeLen = 1;
191 }
192 }
193 }
194 return;
195 }
196
DecodeCALL_GOTO(Word Code)197 static void DecodeCALL_GOTO(Word Code)
198 {
199 if (ChkArgCnt(1, 1))
200 {
201 Boolean OK;
202 Word AdrWord;
203 tSymbolFlags Flags;
204
205 AdrWord = EvalStrIntExpressionWithFlags(&ArgStr[1], UInt16, &OK, &Flags);
206 if (OK && ChkSamePage(ProgCounter(), AdrWord, 13, Flags))
207 {
208 WAsmCode[0] = Code + (AdrWord & 0x1fff);
209 CodeLen = 1;
210 }
211 }
212 }
213
DecodeLCALL(Word Code)214 static void DecodeLCALL(Word Code)
215 {
216 UNUSED(Code);
217
218 if (ChkArgCnt(1, 1))
219 {
220 Boolean OK;
221
222 Word AdrWord = EvalStrIntExpression(&ArgStr[1], UInt16, &OK);
223 if (OK)
224 {
225 CodeLen = 3;
226 WAsmCode[0] = 0xb000 + Hi(AdrWord);
227 WAsmCode[1] = 0x0103;
228 WAsmCode[2] = 0xb700 + Lo(AdrWord);
229 }
230 }
231 }
232
DecodeSFR(Word Code)233 static void DecodeSFR(Word Code)
234 {
235 UNUSED(Code);
236
237 CodeEquate(SegData, 0, 0xff);
238 }
239
DecodeDATA_17C4x(Word Code)240 static void DecodeDATA_17C4x(Word Code)
241 {
242 UNUSED(Code);
243
244 DecodeDATA(Int16, Int8);
245 }
246
DecodeZERO(Word Code)247 static void DecodeZERO(Word Code)
248 {
249 Word Size;
250 Boolean ValOK;
251 tSymbolFlags Flags;
252
253 UNUSED(Code);
254
255 if (ChkArgCnt(1, 1))
256 {
257 Size = EvalStrIntExpressionWithFlags(&ArgStr[1], Int16, &ValOK, &Flags);
258 if (mFirstPassUnknown(Flags)) WrError(ErrNum_FirstPassCalc);
259 if (ValOK && !mFirstPassUnknown(Flags))
260 {
261 if (SetMaxCodeLen(Size << 1)) WrError(ErrNum_CodeOverflow);
262 else
263 {
264 CodeLen = Size;
265 memset(WAsmCode, 0, 2 * Size);
266 }
267 }
268 }
269 }
270
271 /*---------------------------------------------------------------------------*/
272
AddFixed(const char * NName,Word NCode)273 static void AddFixed(const char *NName, Word NCode)
274 {
275 AddInstTable(InstTable, NName, NCode, DecodeFixed);
276 }
277
AddLitt(const char * NName,Word NCode)278 static void AddLitt(const char *NName, Word NCode)
279 {
280 AddInstTable(InstTable, NName, NCode, DecodeLitt);
281 }
282
AddAri(const char * NName,Word NDef,Word NCode)283 static void AddAri(const char *NName, Word NDef, Word NCode)
284 {
285 AddInstTable(InstTable, NName, NCode | (NDef << 15), DecodeAri);
286 }
287
AddBit(const char * NName,Word NCode)288 static void AddBit(const char *NName, Word NCode)
289 {
290 AddInstTable(InstTable, NName, NCode, DecodeBit);
291 }
292
AddF(const char * NName,Word NCode)293 static void AddF(const char *NName, Word NCode)
294 {
295 AddInstTable(InstTable, NName, NCode, DecodeF);
296 }
297
InitFields(void)298 static void InitFields(void)
299 {
300 InstTable = CreateInstTable(203);
301 AddInstTable(InstTable, "MOVFP", 0x6000, DecodeMOVFP_MOVPF);
302 AddInstTable(InstTable, "MOVPF", 0x4000, DecodeMOVFP_MOVPF);
303 AddInstTable(InstTable, "TABLRD", 0xa800, DecodeTABLRD_TABLWT);
304 AddInstTable(InstTable, "TABLWT", 0xac00, DecodeTABLRD_TABLWT);
305 AddInstTable(InstTable, "TLRD", 0xa000, DecodeTLRD_TLWT);
306 AddInstTable(InstTable, "TLWT", 0xa400, DecodeTLRD_TLWT);
307 AddInstTable(InstTable, "CALL", 0xe000, DecodeCALL_GOTO);
308 AddInstTable(InstTable, "GOTO", 0xc000, DecodeCALL_GOTO);
309 AddInstTable(InstTable, "LCALL", 0, DecodeLCALL);
310 AddInstTable(InstTable, "SFR", 0, DecodeSFR);
311 AddInstTable(InstTable, "RES", 0, DecodeRES);
312 AddInstTable(InstTable, "DATA", 0, DecodeDATA_17C4x);
313 AddInstTable(InstTable, "ZERO", 0, DecodeZERO);
314
315 AddFixed("RETFIE", 0x0005);
316 AddFixed("RETURN", 0x0002);
317 AddFixed("CLRWDT", 0x0004);
318 AddFixed("NOP" , 0x0000);
319 AddFixed("SLEEP" , 0x0003);
320
321 AddLitt("MOVLB", 0xb800);
322 AddLitt("ADDLW", 0xb100);
323 AddLitt("ANDLW", 0xb500);
324 AddLitt("IORLW", 0xb300);
325 AddLitt("MOVLW", 0xb000);
326 AddLitt("SUBLW", 0xb200);
327 AddLitt("XORLW", 0xb400);
328 AddLitt("RETLW", 0xb600);
329
330 AddAri("ADDWF" , 0, 0x0e00);
331 AddAri("ADDWFC", 0, 0x1000);
332 AddAri("ANDWF" , 0, 0x0a00);
333 AddAri("CLRF" , 1, 0x2800);
334 AddAri("COMF" , 1, 0x1200);
335 AddAri("DAW" , 1, 0x2e00);
336 AddAri("DECF" , 1, 0x0600);
337 AddAri("INCF" , 1, 0x1400);
338 AddAri("IORWF" , 0, 0x0800);
339 AddAri("NEGW" , 1, 0x2c00);
340 AddAri("RLCF" , 1, 0x1a00);
341 AddAri("RLNCF" , 1, 0x2200);
342 AddAri("RRCF" , 1, 0x1800);
343 AddAri("RRNCF" , 1, 0x2000);
344 AddAri("SETF" , 1, 0x2a00);
345 AddAri("SUBWF" , 0, 0x0400);
346 AddAri("SUBWFB", 0, 0x0200);
347 AddAri("SWAPF" , 1, 0x1c00);
348 AddAri("XORWF" , 0, 0x0c00);
349 AddAri("DECFSZ", 1, 0x1600);
350 AddAri("DCFSNZ", 1, 0x2600);
351 AddAri("INCFSZ", 1, 0x1e00);
352 AddAri("INFSNZ", 1, 0x2400);
353
354 AddBit("BCF" , 0x8800);
355 AddBit("BSF" , 0x8000);
356 AddBit("BTFSC", 0x9800);
357 AddBit("BTFSS", 0x9000);
358 AddBit("BTG" , 0x3800);
359
360 AddF("MOVWF" , 0x0100);
361 AddF("CPFSEQ", 0x3100);
362 AddF("CPFSGT", 0x3200);
363 AddF("CPFSLT", 0x3000);
364 AddF("TSTFSZ", 0x3300);
365 }
366
DeinitFields(void)367 static void DeinitFields(void)
368 {
369 DestroyInstTable(InstTable);
370 }
371
372 /*---------------------------------------------------------------------------*/
373
MakeCode_17c4x(void)374 static void MakeCode_17c4x(void)
375 {
376 CodeLen = 0;
377 DontPrint = False;
378
379 /* zu ignorierendes */
380
381 if (Memo(""))
382 return;
383
384 if (!LookupInstTable(InstTable, OpPart.Str))
385 WrStrErrorPos(ErrNum_UnknownInstruction, &OpPart);
386 }
387
IsDef_17c4x(void)388 static Boolean IsDef_17c4x(void)
389 {
390 return Memo("SFR");
391 }
392
SwitchFrom_17c4x(void)393 static void SwitchFrom_17c4x(void)
394 {
395 DeinitFields();
396 }
397
SwitchTo_17c4x(void)398 static void SwitchTo_17c4x(void)
399 {
400 TurnWords = False;
401 ConstMode = ConstModeMoto;
402
403 PCSymbol = "*";
404 HeaderID = 0x72;
405 NOPCode = 0x0000;
406 DivideChars = ",";
407 HasAttrs = False;
408
409 ValidSegs = (1 << SegCode) + (1 << SegData);
410 Grans[SegCode] = 2; ListGrans[SegCode] = 2; SegInits[SegCode] = 0;
411 SegLimits[SegCode] = 0xffff;
412 Grans[SegData] = 1; ListGrans[SegData] = 1; SegInits[SegData] = 0;
413 SegLimits[SegData] = 0xff;
414
415 MakeCode = MakeCode_17c4x;
416 IsDef = IsDef_17c4x;
417 SwitchFrom = SwitchFrom_17c4x;
418 InitFields();
419 }
420
code17c4x_init(void)421 void code17c4x_init(void)
422 {
423 CPU17C42 = AddCPU("17C42", SwitchTo_17c4x);
424 }
425