1 /* intpseudo.c */
2 /*****************************************************************************/
3 /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
4 /* */
5 /* AS */
6 /* */
7 /* Commonly Used Intel-Style Pseudo Instructions */
8 /* */
9 /*****************************************************************************/
10
11 /*****************************************************************************
12 * Includes
13 *****************************************************************************/
14
15 #include "stdinc.h"
16 #include <ctype.h>
17 #include <string.h>
18 #include <assert.h>
19 #include <math.h>
20
21 #include "bpemu.h"
22 #include "endian.h"
23 #include "strutil.h"
24 #include "asmdef.h"
25 #include "asmsub.h"
26 #include "asmpars.h"
27 #include "asmitree.h"
28 #include "errmsg.h"
29 #include "ieeefloat.h"
30
31 #include "intpseudo.h"
32
33 /*****************************************************************************
34 * Local Types
35 *****************************************************************************/
36
37 struct sLayoutCtx;
38
39 typedef Boolean (*TLayoutFunc)(
40 #ifdef __PROTOS__
41 const tStrComp *pArg, struct sLayoutCtx *pCtx
42 #endif
43 );
44
45 typedef enum
46 {
47 DSNone, DSConstant, DSSpace
48 } tDSFlag;
49
50 struct sCurrCodeFill
51 {
52 LongInt FullWordCnt;
53 int LastWordFill;
54 };
55 typedef struct sCurrCodeFill tCurrCodeFill;
56
57 struct sLayoutCtx
58 {
59 tDSFlag DSFlag;
60 TLayoutFunc LayoutFunc;
61 int BaseElemLenBits, FullWordSize, ElemsPerFullWord;
62 Boolean (*Put4I)(Byte b, struct sLayoutCtx *pCtx);
63 Boolean (*Put8I)(Byte b, struct sLayoutCtx *pCtx);
64 Boolean (*Put16I)(Word w, struct sLayoutCtx *pCtx);
65 Boolean (*Put16F)(Double f, struct sLayoutCtx *pCtx);
66 Boolean (*Put32I)(LongWord l, struct sLayoutCtx *pCtx);
67 Boolean (*Put32F)(Double f, struct sLayoutCtx *pCtx);
68 Boolean (*Put64I)(LargeWord q, struct sLayoutCtx *pCtx);
69 Boolean (*Put64F)(Double f, struct sLayoutCtx *pCtx);
70 Boolean (*Put80F)(Double t, struct sLayoutCtx *pCtx);
71 Boolean (*Replicate)(const tCurrCodeFill *pStartPos, const tCurrCodeFill *pEndPos, struct sLayoutCtx *pCtx);
72 tCurrCodeFill CurrCodeFill, FillIncPerElem;
73 const tStrComp *pCurrComp;
74 int LoHiMap;
75 };
76 typedef struct sLayoutCtx tLayoutCtx;
77
78 /*****************************************************************************
79 * Local Functions
80 *****************************************************************************/
81
_DumpCodeFill(const char * pTitle,const tCurrCodeFill * pFill)82 void _DumpCodeFill(const char *pTitle, const tCurrCodeFill *pFill)
83 {
84 fprintf(stderr, "%s %u %d\n", pTitle, (unsigned)pFill->FullWordCnt, pFill->LastWordFill);
85 }
86
87 /*!------------------------------------------------------------------------
88 * \fn Boolean SetDSFlag(struct sLayoutCtx *pCtx, tDSFlag Flag)
89 * \brief check set data disposition/reservation flag in context
90 * \param pCtx context
91 * \param Flag operation to be set
92 * \return True if operation could be set or was alreday set
93 * ------------------------------------------------------------------------ */
94
SetDSFlag(struct sLayoutCtx * pCtx,tDSFlag Flag)95 static Boolean SetDSFlag(struct sLayoutCtx *pCtx, tDSFlag Flag)
96 {
97 if ((pCtx->DSFlag != DSNone) && (pCtx->DSFlag != Flag))
98 {
99 WrStrErrorPos(ErrNum_MixDBDS, pCtx->pCurrComp);
100 return False;
101 }
102 pCtx->DSFlag = Flag;
103 return True;
104 }
105
106 /*!------------------------------------------------------------------------
107 * \fn IncMaxCodeLen(struct sLayoutCtx *pCtx, LongWord NumFullWords)
108 * \brief assure xAsmCode has space for at moleast n more full words
109 * \param pCtxcontext
110 * \param NumFullWords # of additional words intended to write
111 * \return True if success
112 * ------------------------------------------------------------------------ */
113
IncMaxCodeLen(struct sLayoutCtx * pCtx,LongWord NumFullWords)114 static Boolean IncMaxCodeLen(struct sLayoutCtx *pCtx, LongWord NumFullWords)
115 {
116 if (SetMaxCodeLen((pCtx->CurrCodeFill.FullWordCnt + NumFullWords) * pCtx->FullWordSize))
117 {
118 WrStrErrorPos(ErrNum_CodeOverflow, pCtx->pCurrComp);
119 return False;
120 }
121 else
122 return True;
123 }
124
ByteInWord(Byte b,int Pos)125 static LargeWord ByteInWord(Byte b, int Pos)
126 {
127 return ((LargeWord)b) << (Pos << 3);
128 }
129
NibbleInByte(Byte n,int Pos)130 static Byte NibbleInByte(Byte n, int Pos)
131 {
132 return (n & 15) << (Pos << 2);
133 }
134
NibbleInWord(Byte n,int Pos)135 static Word NibbleInWord(Byte n, int Pos)
136 {
137 return ((Word)(n & 15)) << (Pos << 2);
138 }
139
ByteFromWord(LargeWord w,int Pos)140 static Byte ByteFromWord(LargeWord w, int Pos)
141 {
142 return (w >> (Pos << 3)) & 0xff;
143 }
144
NibbleFromByte(Byte b,int Pos)145 static Byte NibbleFromByte(Byte b, int Pos)
146 {
147 return (b >> (Pos << 2)) & 0x0f;
148 }
149
NibbleFromWord(Word w,int Pos)150 static Byte NibbleFromWord(Word w, int Pos)
151 {
152 return (w >> (Pos << 2)) & 0x0f;
153 }
154
155 /*!------------------------------------------------------------------------
156 * \fn SubCodeFill
157 * \brief perform 'c = a - b' on tCurrCodeFill structures
158 * \param c result
159 * \param b, c arguments
160 * ------------------------------------------------------------------------ */
161
SubCodeFill(tCurrCodeFill * c,const tCurrCodeFill * a,const tCurrCodeFill * b,struct sLayoutCtx * pCtx)162 static void SubCodeFill(tCurrCodeFill *c, const tCurrCodeFill *a, const tCurrCodeFill *b, struct sLayoutCtx *pCtx)
163 {
164 c->FullWordCnt = a->FullWordCnt - b->FullWordCnt;
165 if ((c->LastWordFill = a->LastWordFill - b->LastWordFill) < 0)
166 {
167 c->LastWordFill += pCtx->ElemsPerFullWord;
168 c->FullWordCnt--;
169 }
170 }
171
172 /*!------------------------------------------------------------------------
173 * \fn MultCodeFill(tCurrCodeFill *b, LongWord a, struct sLayoutCtx *pCtx)
174 * \brief perform 'b *= a' on tCurrCodeFill structures
175 * \param b what to multiply
176 * \param a scaling factor
177 * ------------------------------------------------------------------------ */
178
MultCodeFill(tCurrCodeFill * b,LongWord a,struct sLayoutCtx * pCtx)179 static void MultCodeFill(tCurrCodeFill *b, LongWord a, struct sLayoutCtx *pCtx)
180 {
181 b->FullWordCnt *= a;
182 b->LastWordFill *= a;
183 if (pCtx->ElemsPerFullWord > 1)
184 {
185 LongWord div = b->LastWordFill / pCtx->ElemsPerFullWord,
186 mod = b->LastWordFill % pCtx->ElemsPerFullWord;
187 b->FullWordCnt += div;
188 b->LastWordFill = mod;
189 }
190 }
191
192 /*!------------------------------------------------------------------------
193 * \fn IncCodeFill(tCurrCodeFill *a, struct sLayoutCtx *pCtx)
194 * \brief advance tCurrCodeFill pointer by one base element
195 * \param a pointer to increment
196 * \param pCtx context
197 * ------------------------------------------------------------------------ */
198
IncCodeFill(tCurrCodeFill * a,struct sLayoutCtx * pCtx)199 static void IncCodeFill(tCurrCodeFill *a, struct sLayoutCtx *pCtx)
200 {
201 if (++a->LastWordFill >= pCtx->ElemsPerFullWord)
202 {
203 a->LastWordFill -= pCtx->ElemsPerFullWord;
204 a->FullWordCnt++;
205 }
206 }
207
208 /*!------------------------------------------------------------------------
209 * \fn IncCurrCodeFill(struct sLayoutCtx *pCtx)
210 * \brief advance CodeFill pointer in context and reserve memory
211 * \param pCtx context
212 * \return True if success
213 * ------------------------------------------------------------------------ */
214
IncCurrCodeFill(struct sLayoutCtx * pCtx)215 static Boolean IncCurrCodeFill(struct sLayoutCtx *pCtx)
216 {
217 LongInt OldFullWordCnt = pCtx->CurrCodeFill.FullWordCnt;
218
219 IncCodeFill(&pCtx->CurrCodeFill, pCtx);
220 if (OldFullWordCnt == pCtx->CurrCodeFill.FullWordCnt)
221 return True;
222 else if (!IncMaxCodeLen(pCtx, 1))
223 return False;
224 else
225 {
226 WAsmCode[pCtx->CurrCodeFill.FullWordCnt] = 0;
227 return True;
228 }
229 }
230
231 /*!------------------------------------------------------------------------
232 * \fn IncCodeFillBy(tCurrCodeFill *a, const tCurrCodeFill *inc, struct sLayoutCtx *pCtx)
233 * \brief perform 'a += inc' on tCurrCodeFill structures
234 * \param a what to advance
235 * \param inc by what to advance
236 * \param pCtx context
237 * ------------------------------------------------------------------------ */
238
IncCodeFillBy(tCurrCodeFill * a,const tCurrCodeFill * inc,struct sLayoutCtx * pCtx)239 static void IncCodeFillBy(tCurrCodeFill *a, const tCurrCodeFill *inc, struct sLayoutCtx *pCtx)
240 {
241 a->LastWordFill += inc->LastWordFill;
242 if ((pCtx->ElemsPerFullWord > 1) && (a->LastWordFill >= pCtx->ElemsPerFullWord))
243 {
244 a->LastWordFill -= pCtx->ElemsPerFullWord;
245 a->FullWordCnt++;
246 }
247 a->FullWordCnt += inc->FullWordCnt;
248 }
249
250 /*****************************************************************************
251 * Function: LayoutNibble
252 * Purpose: parse argument, interprete as nibble,
253 * and put into result buffer
254 * Result: TRUE if no errors occured
255 *****************************************************************************/
256
Put4I_To_8(Byte b,struct sLayoutCtx * pCtx)257 static Boolean Put4I_To_8(Byte b, struct sLayoutCtx *pCtx)
258 {
259 tCurrCodeFill Pos = pCtx->CurrCodeFill;
260 if (!IncCurrCodeFill(pCtx))
261 return False;
262 if (!Pos.LastWordFill)
263 BAsmCode[Pos.FullWordCnt] = NibbleInByte(b, Pos.LastWordFill ^ pCtx->LoHiMap);
264 else
265 BAsmCode[Pos.FullWordCnt] |= NibbleInByte(b, Pos.LastWordFill ^ pCtx->LoHiMap);
266 return True;
267 }
268
Replicate4_To_8(const tCurrCodeFill * pStartPos,const tCurrCodeFill * pEndPos,struct sLayoutCtx * pCtx)269 static Boolean Replicate4_To_8(const tCurrCodeFill *pStartPos, const tCurrCodeFill *pEndPos, struct sLayoutCtx *pCtx)
270 {
271 Byte b;
272 tCurrCodeFill CurrPos;
273
274 CurrPos = *pStartPos;
275 while ((CurrPos.FullWordCnt != pEndPos->FullWordCnt) || (CurrPos.LastWordFill != pEndPos->LastWordFill))
276 {
277 b = NibbleFromByte(BAsmCode[CurrPos.FullWordCnt], CurrPos.LastWordFill ^ pCtx->LoHiMap);
278 if (!Put4I_To_8(b, pCtx))
279 return False;
280 IncCodeFill(&CurrPos, pCtx);
281 }
282
283 return True;
284 }
285
Put4I_To_16(Byte b,struct sLayoutCtx * pCtx)286 static Boolean Put4I_To_16(Byte b, struct sLayoutCtx *pCtx)
287 {
288 tCurrCodeFill Pos = pCtx->CurrCodeFill;
289 if (!IncCurrCodeFill(pCtx))
290 return False;
291 if (!Pos.LastWordFill)
292 WAsmCode[Pos.FullWordCnt] = NibbleInWord(b, Pos.LastWordFill ^ pCtx->LoHiMap);
293 else
294 WAsmCode[Pos.FullWordCnt] |= NibbleInWord(b, Pos.LastWordFill ^ pCtx->LoHiMap);
295 return True;
296 }
297
Replicate4_To_16(const tCurrCodeFill * pStartPos,const tCurrCodeFill * pEndPos,struct sLayoutCtx * pCtx)298 static Boolean Replicate4_To_16(const tCurrCodeFill *pStartPos, const tCurrCodeFill *pEndPos, struct sLayoutCtx *pCtx)
299 {
300 Byte b;
301 tCurrCodeFill CurrPos;
302
303 CurrPos = *pStartPos;
304 while ((CurrPos.FullWordCnt != pEndPos->FullWordCnt) || (CurrPos.LastWordFill != pEndPos->LastWordFill))
305 {
306 b = NibbleFromWord(WAsmCode[CurrPos.FullWordCnt], CurrPos.LastWordFill ^ pCtx->LoHiMap);
307 if (!Put4I_To_16(b, pCtx))
308 return False;
309 IncCodeFill(&CurrPos, pCtx);
310 }
311
312 return True;
313 }
314
LayoutNibble(const tStrComp * pExpr,struct sLayoutCtx * pCtx)315 static Boolean LayoutNibble(const tStrComp *pExpr, struct sLayoutCtx *pCtx)
316 {
317 Boolean Result = False;
318 TempResult t;
319
320 EvalStrExpression(pExpr, &t);
321 switch (t.Typ)
322 {
323 case TempInt:
324 if (mFirstPassUnknown(t.Flags)) t.Contents.Int &= 0xf;
325 if (!mSymbolQuestionable(t.Flags) && !RangeCheck(t.Contents.Int, Int4)) WrStrErrorPos(ErrNum_OverRange, pExpr);
326 else
327 {
328 if (!pCtx->Put4I(t.Contents.Int, pCtx))
329 return Result;
330 Result = True;
331 }
332 break;
333 case TempFloat:
334 WrStrErrorPos(ErrNum_IntButFloat, pExpr);
335 break;
336 case TempString:
337 WrStrErrorPos(ErrNum_IntButString, pExpr);
338 break;
339 default:
340 break;
341 }
342
343 return Result;
344 }
345
346 /*****************************************************************************
347 * Function: LayoutByte
348 * Purpose: parse argument, interprete as byte,
349 * and put into result buffer
350 * Result: TRUE if no errors occured
351 *****************************************************************************/
352
Put8I_To_8(Byte b,struct sLayoutCtx * pCtx)353 static Boolean Put8I_To_8(Byte b, struct sLayoutCtx *pCtx)
354 {
355 if (!IncMaxCodeLen(pCtx, 1))
356 return False;
357 BAsmCode[pCtx->CurrCodeFill.FullWordCnt++] = b;
358 return True;
359 }
360
Put8I_To_16(Byte b,struct sLayoutCtx * pCtx)361 static Boolean Put8I_To_16(Byte b, struct sLayoutCtx *pCtx)
362 {
363 tCurrCodeFill Pos = pCtx->CurrCodeFill;
364 if (!IncCurrCodeFill(pCtx))
365 return False;
366 if (!Pos.LastWordFill)
367 WAsmCode[Pos.FullWordCnt] = ByteInWord(b, Pos.LastWordFill ^ pCtx->LoHiMap);
368 else
369 WAsmCode[Pos.FullWordCnt] |= ByteInWord(b, Pos.LastWordFill ^ pCtx->LoHiMap);
370 return True;
371 }
372
Replicate8ToN_To_8(const tCurrCodeFill * pStartPos,const tCurrCodeFill * pEndPos,struct sLayoutCtx * pCtx)373 static Boolean Replicate8ToN_To_8(const tCurrCodeFill *pStartPos, const tCurrCodeFill *pEndPos, struct sLayoutCtx *pCtx)
374 {
375 tCurrCodeFill Pos;
376
377 if (!IncMaxCodeLen(pCtx, pEndPos->FullWordCnt - pStartPos->FullWordCnt))
378 return False;
379
380 for (Pos = *pStartPos; Pos.FullWordCnt < pEndPos->FullWordCnt; Pos.FullWordCnt += pCtx->BaseElemLenBits / 8)
381 {
382 memcpy(&BAsmCode[pCtx->CurrCodeFill.FullWordCnt], &BAsmCode[Pos.FullWordCnt], pCtx->BaseElemLenBits / 8);
383 pCtx->CurrCodeFill.FullWordCnt += pCtx->BaseElemLenBits / 8;
384 }
385 if (Pos.FullWordCnt != pEndPos->FullWordCnt)
386 {
387 WrXError(ErrNum_InternalError, "DUP replication inconsistency");
388 return False;
389 }
390
391 return True;
392 }
393
Replicate8_To_16(const tCurrCodeFill * pStartPos,const tCurrCodeFill * pEndPos,struct sLayoutCtx * pCtx)394 static Boolean Replicate8_To_16(const tCurrCodeFill *pStartPos, const tCurrCodeFill *pEndPos, struct sLayoutCtx *pCtx)
395 {
396 Byte b;
397 tCurrCodeFill CurrPos;
398
399 CurrPos = *pStartPos;
400 while ((CurrPos.FullWordCnt != pEndPos->FullWordCnt) || (CurrPos.LastWordFill != pEndPos->LastWordFill))
401 {
402 b = ByteFromWord(WAsmCode[CurrPos.FullWordCnt], CurrPos.LastWordFill ^ pCtx->LoHiMap);
403 if (!Put8I_To_16(b, pCtx))
404 return False;
405 IncCodeFill(&CurrPos, pCtx);
406 }
407
408 return True;
409 }
410
LayoutByte(const tStrComp * pExpr,struct sLayoutCtx * pCtx)411 static Boolean LayoutByte(const tStrComp *pExpr, struct sLayoutCtx *pCtx)
412 {
413 Boolean Result = False;
414 TempResult t;
415
416 EvalStrExpression(pExpr, &t);
417 switch (t.Typ)
418 {
419 case TempInt:
420 ToInt:
421 if (mFirstPassUnknown(t.Flags)) t.Contents.Int &= 0xff;
422 if (!mSymbolQuestionable(t.Flags) && !RangeCheck(t.Contents.Int, Int8)) WrStrErrorPos(ErrNum_OverRange, pExpr);
423 else
424 {
425 if (!pCtx->Put8I(t.Contents.Int, pCtx))
426 return Result;
427 Result = True;
428 }
429 break;
430 case TempFloat:
431 WrStrErrorPos(ErrNum_StringOrIntButFloat, pExpr);
432 break;
433 case TempString:
434 {
435 unsigned z;
436
437 if (MultiCharToInt(&t, 1))
438 goto ToInt;
439
440 TranslateString(t.Contents.Ascii.Contents, t.Contents.Ascii.Length);
441
442 for (z = 0; z < t.Contents.Ascii.Length; z++)
443 if (!pCtx->Put8I(t.Contents.Ascii.Contents[z], pCtx))
444 return Result;
445
446 Result = True;
447 break;
448 }
449 default:
450 break;
451 }
452
453 return Result;
454 }
455
456 /*****************************************************************************
457 * Function: LayoutWord
458 * Purpose: parse argument, interprete as 16-bit word,
459 * and put into result buffer
460 * Result: TRUE if no errors occured
461 *****************************************************************************/
462
Put16I_To_8(Word w,struct sLayoutCtx * pCtx)463 static Boolean Put16I_To_8(Word w, struct sLayoutCtx *pCtx)
464 {
465 if (!IncMaxCodeLen(pCtx, 2))
466 return False;
467 BAsmCode[pCtx->CurrCodeFill.FullWordCnt + (0 ^ pCtx->LoHiMap)] = Lo(w);
468 BAsmCode[pCtx->CurrCodeFill.FullWordCnt + (1 ^ pCtx->LoHiMap)] = Hi(w);
469 pCtx->CurrCodeFill.FullWordCnt += 2;
470 return True;
471 }
472
Put16F_To_8(Double t,struct sLayoutCtx * pCtx)473 static Boolean Put16F_To_8(Double t, struct sLayoutCtx *pCtx)
474 {
475 if (!IncMaxCodeLen(pCtx, 2))
476 return False;
477 if (!Double_2_ieee2(t, BAsmCode + pCtx->CurrCodeFill.FullWordCnt, !!pCtx->LoHiMap))
478 {
479 WrError(ErrNum_OverRange);
480 return False;
481 }
482 pCtx->CurrCodeFill.FullWordCnt += 2;
483 return True;
484 }
485
Put16I_To_16(Word w,struct sLayoutCtx * pCtx)486 static Boolean Put16I_To_16(Word w, struct sLayoutCtx *pCtx)
487 {
488 if (!IncMaxCodeLen(pCtx, 1))
489 return False;
490 WAsmCode[pCtx->CurrCodeFill.FullWordCnt++] = w;
491 return True;
492 }
493
Put16F_To_16(Double t,struct sLayoutCtx * pCtx)494 static Boolean Put16F_To_16(Double t, struct sLayoutCtx *pCtx)
495 {
496 Byte Tmp[2];
497
498 if (!IncMaxCodeLen(pCtx, 1))
499 return False;
500
501 Double_2_ieee2(t, Tmp, !!pCtx->LoHiMap);
502 WAsmCode[pCtx->CurrCodeFill.FullWordCnt + 0] = ByteInWord(Tmp[0], 0 ^ pCtx->LoHiMap) | ByteInWord(Tmp[1], 1 ^ pCtx->LoHiMap);
503 pCtx->CurrCodeFill.FullWordCnt += 1;
504 return True;
505 }
506
Replicate16ToN_To_16(const tCurrCodeFill * pStartPos,const tCurrCodeFill * pEndPos,struct sLayoutCtx * pCtx)507 static Boolean Replicate16ToN_To_16(const tCurrCodeFill *pStartPos, const tCurrCodeFill *pEndPos, struct sLayoutCtx *pCtx)
508 {
509 tCurrCodeFill Pos;
510
511 if (!IncMaxCodeLen(pCtx, pEndPos->FullWordCnt - pStartPos->FullWordCnt))
512 return False;
513
514 for (Pos = *pStartPos; Pos.FullWordCnt < pEndPos->FullWordCnt; Pos.FullWordCnt += pCtx->BaseElemLenBits / 16)
515 {
516 memcpy(&WAsmCode[pCtx->CurrCodeFill.FullWordCnt], &WAsmCode[Pos.FullWordCnt], pCtx->BaseElemLenBits / 8);
517 pCtx->CurrCodeFill.FullWordCnt += pCtx->BaseElemLenBits / 16;
518 }
519 if (Pos.FullWordCnt != pEndPos->FullWordCnt)
520 {
521 WrXError(ErrNum_InternalError, "DUP replication inconsistency");
522 return False;
523 }
524
525 return True;
526 }
527
LayoutWord(const tStrComp * pExpr,struct sLayoutCtx * pCtx)528 static Boolean LayoutWord(const tStrComp *pExpr, struct sLayoutCtx *pCtx)
529 {
530 Boolean Result = False;
531 TempResult t;
532
533 EvalStrExpression(pExpr, &t);
534 Result = True;
535 switch (t.Typ)
536 {
537 case TempInt:
538 ToInt:
539 if (mFirstPassUnknown(t.Flags)) t.Contents.Int &= 0xffff;
540 if (!mSymbolQuestionable(t.Flags) && !RangeCheck(t.Contents.Int, Int16)) WrStrErrorPos(ErrNum_OverRange, pExpr);
541 else
542 {
543 if (!pCtx->Put16I(t.Contents.Int, pCtx))
544 return Result;
545 Result = True;
546 }
547 break;
548 case TempFloat:
549 if (!FloatRangeCheck(t.Contents.Float, Float16)) WrStrErrorPos(ErrNum_OverRange, pExpr);
550 else
551 {
552 if (!pCtx->Put16F(t.Contents.Float, pCtx))
553 return Result;
554 Result = True;
555 }
556 break;
557 case TempString:
558 {
559 unsigned z;
560
561 if (MultiCharToInt(&t, 2))
562 goto ToInt;
563
564 TranslateString(t.Contents.Ascii.Contents, t.Contents.Ascii.Length);
565
566 for (z = 0; z < t.Contents.Ascii.Length; z++)
567 if (!pCtx->Put16I(t.Contents.Ascii.Contents[z], pCtx))
568 return Result;
569
570 Result = True;
571 break;
572 }
573 default:
574 break;
575 }
576
577 return Result;
578 }
579
580 /*****************************************************************************
581 * Function: LayoutDoubleWord
582 * Purpose: parse argument, interprete as 32-bit word or
583 single precision float, and put into result buffer
584 * Result: TRUE if no errors occured
585 *****************************************************************************/
586
Put32I_To_8(LongWord l,struct sLayoutCtx * pCtx)587 static Boolean Put32I_To_8(LongWord l, struct sLayoutCtx *pCtx)
588 {
589 if (!IncMaxCodeLen(pCtx, 4))
590 return False;
591 BAsmCode[pCtx->CurrCodeFill.FullWordCnt + (0 ^ pCtx->LoHiMap)] = (l ) & 0xff;
592 BAsmCode[pCtx->CurrCodeFill.FullWordCnt + (1 ^ pCtx->LoHiMap)] = (l >> 8) & 0xff;
593 BAsmCode[pCtx->CurrCodeFill.FullWordCnt + (2 ^ pCtx->LoHiMap)] = (l >> 16) & 0xff;
594 BAsmCode[pCtx->CurrCodeFill.FullWordCnt + (3 ^ pCtx->LoHiMap)] = (l >> 24) & 0xff;
595 pCtx->CurrCodeFill.FullWordCnt += 4;
596 return True;
597 }
598
Put32F_To_8(Double t,struct sLayoutCtx * pCtx)599 static Boolean Put32F_To_8(Double t, struct sLayoutCtx *pCtx)
600 {
601 if (!IncMaxCodeLen(pCtx, 4))
602 return False;
603 Double_2_ieee4(t, BAsmCode + pCtx->CurrCodeFill.FullWordCnt, !!pCtx->LoHiMap);
604 pCtx->CurrCodeFill.FullWordCnt += 4;
605 return True;
606 }
607
Put32I_To_16(LongWord l,struct sLayoutCtx * pCtx)608 static Boolean Put32I_To_16(LongWord l, struct sLayoutCtx *pCtx)
609 {
610 if (!IncMaxCodeLen(pCtx, 2))
611 return False;
612 WAsmCode[pCtx->CurrCodeFill.FullWordCnt + (0 ^ pCtx->LoHiMap)] = LoWord(l);
613 WAsmCode[pCtx->CurrCodeFill.FullWordCnt + (1 ^ pCtx->LoHiMap)] = HiWord(l);
614 pCtx->CurrCodeFill.FullWordCnt += 2;
615 return True;
616 }
617
Put32F_To_16(Double t,struct sLayoutCtx * pCtx)618 static Boolean Put32F_To_16(Double t, struct sLayoutCtx *pCtx)
619 {
620 Byte Tmp[4];
621
622 if (!IncMaxCodeLen(pCtx, 2))
623 return False;
624 Double_2_ieee4(t, Tmp, !!pCtx->LoHiMap);
625 WAsmCode[pCtx->CurrCodeFill.FullWordCnt + 0] = ByteInWord(Tmp[0], 0 ^ pCtx->LoHiMap) | ByteInWord(Tmp[1], 1 ^ pCtx->LoHiMap);
626 WAsmCode[pCtx->CurrCodeFill.FullWordCnt + 1] = ByteInWord(Tmp[2], 0 ^ pCtx->LoHiMap) | ByteInWord(Tmp[3], 1 ^ pCtx->LoHiMap);
627 pCtx->CurrCodeFill.FullWordCnt += 2;
628 return True;
629 }
630
LayoutDoubleWord(const tStrComp * pExpr,struct sLayoutCtx * pCtx)631 static Boolean LayoutDoubleWord(const tStrComp *pExpr, struct sLayoutCtx *pCtx)
632 {
633 TempResult erg;
634 Boolean Result = False;
635 Word Cnt = 0;
636
637 EvalStrExpression(pExpr, &erg);
638 Result = False;
639 switch (erg.Typ)
640 {
641 case TempNone:
642 break;
643 case TempInt:
644 ToInt:
645 if (mFirstPassUnknown(erg.Flags)) erg.Contents.Int &= 0xfffffffful;
646 if (!mSymbolQuestionable(erg.Flags) && !RangeCheck(erg.Contents.Int, Int32)) WrStrErrorPos(ErrNum_OverRange, pExpr);
647 else
648 {
649 if (!pCtx->Put32I(erg.Contents.Int, pCtx))
650 return Result;
651 Cnt = 4;
652 Result = True;
653 }
654 break;
655 case TempFloat:
656 if (!FloatRangeCheck(erg.Contents.Float, Float32)) WrStrErrorPos(ErrNum_OverRange, pExpr);
657 else
658 {
659 if (!pCtx->Put32F(erg.Contents.Float, pCtx))
660 return Result;
661 Cnt = 4;
662 Result = True;
663 }
664 break;
665 case TempString:
666 {
667 unsigned z;
668
669 if (MultiCharToInt(&erg, 4))
670 goto ToInt;
671
672 TranslateString(erg.Contents.Ascii.Contents, erg.Contents.Ascii.Length);
673
674 for (z = 0; z < erg.Contents.Ascii.Length; z++)
675 if (!pCtx->Put32I(erg.Contents.Ascii.Contents[z], pCtx))
676 return Result;
677
678 Cnt = erg.Contents.Ascii.Length * 4;
679 Result = True;
680 break;
681 }
682 case TempReg:
683 WrStrErrorPos(ErrNum_StringOrIntOrFloatButReg, pExpr);
684 break;
685 case TempAll:
686 assert(0);
687 }
688
689 if (Result && Cnt)
690 {
691 if (BigEndian)
692 DSwap(BAsmCode + pCtx->CurrCodeFill.FullWordCnt - Cnt, Cnt);
693 }
694
695 return Result;
696 }
697
698
699 /*****************************************************************************
700 * Function: LayoutQuadWord
701 * Purpose: parse argument, interprete as 64-bit word or
702 double precision float, and put into result buffer
703 * Result: TRUE if no errors occured
704 *****************************************************************************/
705
Put64I_To_8(LargeWord l,struct sLayoutCtx * pCtx)706 static Boolean Put64I_To_8(LargeWord l, struct sLayoutCtx *pCtx)
707 {
708 if (!IncMaxCodeLen(pCtx, 8))
709 return False;
710 BAsmCode[pCtx->CurrCodeFill.FullWordCnt + (0 ^ pCtx->LoHiMap)] = (l ) & 0xff;
711 BAsmCode[pCtx->CurrCodeFill.FullWordCnt + (1 ^ pCtx->LoHiMap)] = (l >> 8) & 0xff;
712 BAsmCode[pCtx->CurrCodeFill.FullWordCnt + (2 ^ pCtx->LoHiMap)] = (l >> 16) & 0xff;
713 BAsmCode[pCtx->CurrCodeFill.FullWordCnt + (3 ^ pCtx->LoHiMap)] = (l >> 24) & 0xff;
714 #ifdef HAS64
715 BAsmCode[pCtx->CurrCodeFill.FullWordCnt + (4 ^ pCtx->LoHiMap)] = (l >> 32) & 0xff;
716 BAsmCode[pCtx->CurrCodeFill.FullWordCnt + (5 ^ pCtx->LoHiMap)] = (l >> 40) & 0xff;
717 BAsmCode[pCtx->CurrCodeFill.FullWordCnt + (6 ^ pCtx->LoHiMap)] = (l >> 48) & 0xff;
718 BAsmCode[pCtx->CurrCodeFill.FullWordCnt + (7 ^ pCtx->LoHiMap)] = (l >> 56) & 0xff;
719 #else
720 /* TempResult is TempInt, so sign-extend */
721 BAsmCode[pCtx->CurrCodeFill.FullWordCnt + (4 ^ pCtx->LoHiMap)] =
722 BAsmCode[pCtx->CurrCodeFill.FullWordCnt + (5 ^ pCtx->LoHiMap)] =
723 BAsmCode[pCtx->CurrCodeFill.FullWordCnt + (6 ^ pCtx->LoHiMap)] =
724 BAsmCode[pCtx->CurrCodeFill.FullWordCnt + (7 ^ pCtx->LoHiMap)] = (l & 0x80000000ul) ? 0xff : 0x00;
725 #endif
726 pCtx->CurrCodeFill.FullWordCnt += 8;
727 return True;
728 }
729
Put64F_To_8(Double t,struct sLayoutCtx * pCtx)730 static Boolean Put64F_To_8(Double t, struct sLayoutCtx *pCtx)
731 {
732 if (!IncMaxCodeLen(pCtx, 8))
733 return False;
734 Double_2_ieee8(t, BAsmCode + pCtx->CurrCodeFill.FullWordCnt, !!pCtx->LoHiMap);
735 pCtx->CurrCodeFill.FullWordCnt += 8;
736 return True;
737 }
738
Put64I_To_16(LargeWord l,struct sLayoutCtx * pCtx)739 static Boolean Put64I_To_16(LargeWord l, struct sLayoutCtx *pCtx)
740 {
741 if (!IncMaxCodeLen(pCtx, 4))
742 return False;
743 WAsmCode[pCtx->CurrCodeFill.FullWordCnt + (0 ^ pCtx->LoHiMap)] = (l ) & 0xffff;
744 WAsmCode[pCtx->CurrCodeFill.FullWordCnt + (1 ^ pCtx->LoHiMap)] = (l >> 16) & 0xffff;
745 #ifdef HAS64
746 WAsmCode[pCtx->CurrCodeFill.FullWordCnt + (2 ^ pCtx->LoHiMap)] = (l >> 32) & 0xffff;
747 WAsmCode[pCtx->CurrCodeFill.FullWordCnt + (3 ^ pCtx->LoHiMap)] = (l >> 48) & 0xffff;
748 #else
749 /* TempResult is TempInt, so sign-extend */
750 WAsmCode[pCtx->CurrCodeFill.FullWordCnt + (2 ^ pCtx->LoHiMap)] =
751 WAsmCode[pCtx->CurrCodeFill.FullWordCnt + (3 ^ pCtx->LoHiMap)] = (l & 0x80000000ul) ? 0xffff : 0x0000;
752 #endif
753 pCtx->CurrCodeFill.FullWordCnt += 4;
754 return True;
755 }
756
Put64F_To_16(Double t,struct sLayoutCtx * pCtx)757 static Boolean Put64F_To_16(Double t, struct sLayoutCtx *pCtx)
758 {
759 Byte Tmp[8];
760 int LoHiMap = pCtx->LoHiMap & 1;
761
762 if (!IncMaxCodeLen(pCtx, 4))
763 return False;
764 Double_2_ieee8(t, Tmp, !!pCtx->LoHiMap);
765 WAsmCode[pCtx->CurrCodeFill.FullWordCnt + 0] = ByteInWord(Tmp[0], 0 ^ LoHiMap) | ByteInWord(Tmp[1], 1 ^ LoHiMap);
766 WAsmCode[pCtx->CurrCodeFill.FullWordCnt + 1] = ByteInWord(Tmp[2], 0 ^ LoHiMap) | ByteInWord(Tmp[3], 1 ^ LoHiMap);
767 WAsmCode[pCtx->CurrCodeFill.FullWordCnt + 2] = ByteInWord(Tmp[4], 0 ^ LoHiMap) | ByteInWord(Tmp[5], 1 ^ LoHiMap);
768 WAsmCode[pCtx->CurrCodeFill.FullWordCnt + 3] = ByteInWord(Tmp[6], 0 ^ LoHiMap) | ByteInWord(Tmp[7], 1 ^ LoHiMap);
769 pCtx->CurrCodeFill.FullWordCnt += 4;
770 return True;
771 }
772
LayoutQuadWord(const tStrComp * pExpr,struct sLayoutCtx * pCtx)773 static Boolean LayoutQuadWord(const tStrComp *pExpr, struct sLayoutCtx *pCtx)
774 {
775 Boolean Result = False;
776 TempResult erg;
777 Word Cnt = 0;
778
779 EvalStrExpression(pExpr, &erg);
780 Result = False;
781 switch(erg.Typ)
782 {
783 case TempNone:
784 break;
785 case TempInt:
786 ToInt:
787 if (!pCtx->Put64I(erg.Contents.Int, pCtx))
788 return Result;
789 Cnt = 8;
790 Result = True;
791 break;
792 case TempFloat:
793 if (!pCtx->Put64F(erg.Contents.Float, pCtx))
794 return Result;
795 Cnt = 8;
796 Result = True;
797 break;
798 case TempString:
799 {
800 unsigned z;
801
802 if (MultiCharToInt(&erg, 8))
803 goto ToInt;
804
805 TranslateString(erg.Contents.Ascii.Contents, erg.Contents.Ascii.Length);
806
807 for (z = 0; z < erg.Contents.Ascii.Length; z++)
808 if (!pCtx->Put64I(erg.Contents.Ascii.Contents[z], pCtx))
809 return Result;
810
811 Cnt = erg.Contents.Ascii.Length * 8;
812 Result = True;
813 break;
814 }
815 case TempReg:
816 WrStrErrorPos(ErrNum_StringOrIntOrFloatButReg, pExpr);
817 break;
818 case TempAll:
819 assert(0);
820 }
821
822 if (Result)
823 {
824 if (BigEndian)
825 QSwap(BAsmCode + pCtx->CurrCodeFill.FullWordCnt - Cnt, Cnt);
826 }
827 return Result;
828 }
829
830 /*****************************************************************************
831 * Function: LayoutTenBytes
832 * Purpose: parse argument, interprete extended precision float,
833 * and put into result buffer
834 * Result: TRUE if no errors occured
835 *****************************************************************************/
836
Put80F_To_8(Double t,struct sLayoutCtx * pCtx)837 static Boolean Put80F_To_8(Double t, struct sLayoutCtx *pCtx)
838 {
839 if (!IncMaxCodeLen(pCtx, 10))
840 return False;
841 Double_2_ieee10(t, BAsmCode + pCtx->CurrCodeFill.FullWordCnt, !!pCtx->LoHiMap);
842 pCtx->CurrCodeFill.FullWordCnt += 10;
843 return True;
844 }
845
Put80F_To_16(Double t,struct sLayoutCtx * pCtx)846 static Boolean Put80F_To_16(Double t, struct sLayoutCtx *pCtx)
847 {
848 Byte Tmp[10];
849 int LoHiMap = pCtx->LoHiMap & 1;
850
851 if (!IncMaxCodeLen(pCtx, 5))
852 return False;
853 Double_2_ieee10(t, Tmp, !!pCtx->LoHiMap);
854 WAsmCode[pCtx->CurrCodeFill.FullWordCnt + 0] = ByteInWord(Tmp[0], 0 ^ LoHiMap) | ByteInWord(Tmp[1], 1 ^ LoHiMap);
855 WAsmCode[pCtx->CurrCodeFill.FullWordCnt + 1] = ByteInWord(Tmp[2], 0 ^ LoHiMap) | ByteInWord(Tmp[3], 1 ^ LoHiMap);
856 WAsmCode[pCtx->CurrCodeFill.FullWordCnt + 2] = ByteInWord(Tmp[4], 0 ^ LoHiMap) | ByteInWord(Tmp[5], 1 ^ LoHiMap);
857 WAsmCode[pCtx->CurrCodeFill.FullWordCnt + 3] = ByteInWord(Tmp[6], 0 ^ LoHiMap) | ByteInWord(Tmp[7], 1 ^ LoHiMap);
858 WAsmCode[pCtx->CurrCodeFill.FullWordCnt + 4] = ByteInWord(Tmp[8], 0 ^ LoHiMap) | ByteInWord(Tmp[9], 1 ^ LoHiMap);
859 pCtx->CurrCodeFill.FullWordCnt += 5;
860 return True;
861 }
862
LayoutTenBytes(const tStrComp * pExpr,struct sLayoutCtx * pCtx)863 static Boolean LayoutTenBytes(const tStrComp *pExpr, struct sLayoutCtx *pCtx)
864 {
865 Boolean Result = False;
866 TempResult erg;
867 Word Cnt;
868
869 EvalStrExpression(pExpr, &erg);
870 Result = False;
871 switch(erg.Typ)
872 {
873 case TempNone:
874 break;
875 case TempInt:
876 ToInt:
877 erg.Contents.Float = erg.Contents.Int;
878 erg.Typ = TempFloat;
879 /* fall-through */
880 case TempFloat:
881 if (!pCtx->Put80F(erg.Contents.Float, pCtx))
882 return Result;
883 Cnt = 10;
884 Result = True;
885 break;
886 case TempString:
887 {
888 unsigned z;
889
890 if (MultiCharToInt(&erg, 4))
891 goto ToInt;
892
893 TranslateString(erg.Contents.Ascii.Contents, erg.Contents.Ascii.Length);
894
895 for (z = 0; z < erg.Contents.Ascii.Length; z++)
896 if (!pCtx->Put80F(erg.Contents.Ascii.Contents[z], pCtx))
897 return Result;
898
899 Cnt = erg.Contents.Ascii.Length * 10;
900 Result = True;
901 break;
902 }
903 case TempReg:
904 WrStrErrorPos(ErrNum_StringOrIntOrFloatButReg, pExpr);
905 break;
906 case TempAll:
907 assert(0);
908 }
909
910 if (Result)
911 {
912 if (BigEndian)
913 TSwap(BAsmCode + pCtx->CurrCodeFill.FullWordCnt - Cnt, Cnt);
914 }
915 return Result;
916 }
917
918 /*****************************************************************************
919 * Global Functions
920 *****************************************************************************/
921
922 /*****************************************************************************
923 * Function: DecodeIntelPseudo
924 * Purpose: handle Intel-style pseudo instructions
925 * Result: TRUE if mnemonic was handled
926 *****************************************************************************/
927
DecodeIntelPseudo_ValidSymChar(char ch)928 static Boolean DecodeIntelPseudo_ValidSymChar(char ch)
929 {
930 ch = as_toupper(ch);
931
932 return (((ch >= 'A') && (ch <= 'Z'))
933 || ((ch >= '0') && (ch <= '9'))
934 || (ch == '_')
935 || (ch == '.'));
936 }
937
DecodeIntelPseudo_HandleQuote(int * pDepth,Byte * pQuote,char Ch)938 static void DecodeIntelPseudo_HandleQuote(int *pDepth, Byte *pQuote, char Ch)
939 {
940 switch (Ch)
941 {
942 case '(':
943 if (!(*pQuote))
944 (*pDepth)++;
945 break;
946 case ')':
947 if (!(*pQuote))
948 (*pDepth)--;
949 break;
950 case '\'':
951 if (!((*pQuote) & 2))
952 (*pQuote) ^= 1;
953 break;
954 case '"':
955 if (!((*pQuote) & 1))
956 (*pQuote) ^= 2;
957 break;
958 }
959 }
960
DecodeIntelPseudo_LayoutMult(const tStrComp * pArg,struct sLayoutCtx * pCtx)961 static Boolean DecodeIntelPseudo_LayoutMult(const tStrComp *pArg, struct sLayoutCtx *pCtx)
962 {
963 int z, Depth, Len;
964 Boolean OK, LastValid, Result;
965 Byte Quote;
966 const char *pDupFnd, *pRun;
967 const tStrComp *pSaveComp;
968
969 pSaveComp = pCtx->pCurrComp;
970 pCtx->pCurrComp = pArg;
971
972 /* search for DUP: exclude parts in parentheses,
973 and parts in quotation marks */
974
975 Depth = Quote = 0;
976 LastValid = FALSE;
977 pDupFnd = NULL; Len = strlen(pArg->Str);
978 for (pRun = pArg->Str; pRun < pArg->Str + Len - 2; pRun++)
979 {
980 DecodeIntelPseudo_HandleQuote(&Depth, &Quote, *pRun);
981 if ((!Depth) && (!Quote))
982 {
983 if ((!LastValid)
984 && (!DecodeIntelPseudo_ValidSymChar(pRun[3]))
985 && (!as_strncasecmp(pRun, "DUP", 3)))
986 {
987 pDupFnd = pRun;
988 break;
989 }
990 }
991 LastValid = DecodeIntelPseudo_ValidSymChar(*pRun);
992 }
993
994 /* found DUP: */
995
996 if (pDupFnd)
997 {
998 LongInt DupCnt;
999 char *pSep, *pRun;
1000 String CopyStr;
1001 tStrComp Copy, DupArg, RemArg, ThisRemArg;
1002 tCurrCodeFill DUPStartFill, DUPEndFill;
1003 tSymbolFlags Flags;
1004
1005 /* operate on copy */
1006
1007 StrCompMkTemp(&Copy, CopyStr);
1008 StrCompCopy(&Copy, pArg);
1009 pSep = Copy.Str + (pDupFnd - pArg->Str);
1010
1011 /* evaluate count */
1012
1013 StrCompSplitRef(&DupArg, &RemArg, &Copy, pSep);
1014 DupCnt = EvalStrIntExpressionWithFlags(&DupArg, Int32, &OK, &Flags);
1015 if (mFirstPassUnknown(Flags))
1016 {
1017 WrStrErrorPos(ErrNum_FirstPassCalc, &DupArg); return False;
1018 }
1019 if (!OK)
1020 {
1021 Result = False;
1022 goto func_exit;
1023 }
1024
1025 /* catch invalid counts */
1026
1027 if (DupCnt <= 0)
1028 {
1029 if (DupCnt < 0)
1030 WrStrErrorPos(ErrNum_NegDUP, &DupArg);
1031 Result = True;
1032 goto func_exit;
1033 }
1034
1035 /* split into parts and evaluate */
1036
1037 StrCompIncRefLeft(&RemArg, 2);
1038 KillPrefBlanksStrCompRef(&RemArg);
1039 Len = strlen(RemArg.Str);
1040 if ((Len >= 2) && (*RemArg.Str == '(') && (RemArg.Str[Len - 1] == ')'))
1041 {
1042 StrCompIncRefLeft(&RemArg, 1);
1043 StrCompShorten(&RemArg, 1);
1044 Len -= 2;
1045 }
1046 DUPStartFill = pCtx->CurrCodeFill;
1047 do
1048 {
1049 pSep = NULL; Quote = Depth = 0;
1050 for (pRun = RemArg.Str; *pRun; pRun++)
1051 {
1052 DecodeIntelPseudo_HandleQuote(&Depth, &Quote, *pRun);
1053 if ((!Depth) && (!Quote) && (*pRun == ','))
1054 {
1055 pSep = pRun;
1056 break;
1057 }
1058 }
1059 if (pSep)
1060 StrCompSplitRef(&RemArg, &ThisRemArg, &RemArg, pSep);
1061 KillPrefBlanksStrCompRef(&RemArg);
1062 KillPostBlanksStrComp(&RemArg);
1063 if (!DecodeIntelPseudo_LayoutMult(&RemArg, pCtx))
1064 {
1065 Result = False;
1066 goto func_exit;
1067 }
1068 if (pSep)
1069 RemArg = ThisRemArg;
1070 }
1071 while (pSep);
1072 DUPEndFill = pCtx->CurrCodeFill;
1073
1074 /* replicate result (data or reserve) */
1075
1076 switch (pCtx->DSFlag)
1077 {
1078 case DSConstant:
1079 for (z = 1; z <= DupCnt - 1; z++)
1080 if (!pCtx->Replicate(&DUPStartFill, &DUPEndFill, pCtx))
1081 {
1082 Result = False;
1083 goto func_exit;
1084 }
1085 break;
1086 case DSSpace:
1087 {
1088 tCurrCodeFill Diff;
1089
1090 SubCodeFill(&Diff, &DUPEndFill, &DUPStartFill, pCtx);
1091 MultCodeFill(&Diff, DupCnt - 1, pCtx);
1092 IncCodeFillBy(&pCtx->CurrCodeFill, &Diff, pCtx);
1093 break;
1094 }
1095 default:
1096 Result = False;
1097 goto func_exit;
1098 }
1099
1100 Result = True;
1101 }
1102
1103 /* no DUP: simple expression. Differentiate space reservation & data disposition */
1104
1105 else if (!strcmp(pArg->Str, "?"))
1106 {
1107 Result = SetDSFlag(pCtx, DSSpace);
1108 if (Result)
1109 IncCodeFillBy(&pCtx->CurrCodeFill, &pCtx->FillIncPerElem, pCtx);
1110 }
1111
1112 else
1113 Result = SetDSFlag(pCtx, DSConstant) && pCtx->LayoutFunc(pArg, pCtx);
1114
1115 func_exit:
1116 pCtx->pCurrComp = pSaveComp;
1117 return Result;
1118 }
1119
1120 /*!------------------------------------------------------------------------
1121 * \fn DecodeIntelDx(tLayoutCtx *pLayoutCtx)
1122 * \brief Intel-style constant disposition
1123 * \param pLayoutCtx layout infos & context
1124 * ------------------------------------------------------------------------ */
1125
DecodeIntelDx(tLayoutCtx * pLayoutCtx)1126 static void DecodeIntelDx(tLayoutCtx *pLayoutCtx)
1127 {
1128 tStrComp *pArg;
1129 Boolean OK;
1130
1131 pLayoutCtx->DSFlag = DSNone;
1132 pLayoutCtx->FullWordSize = Grans[ActPC];
1133 pLayoutCtx->ElemsPerFullWord = (8 * pLayoutCtx->FullWordSize) / pLayoutCtx->BaseElemLenBits;
1134 if (pLayoutCtx->ElemsPerFullWord > 1)
1135 {
1136 pLayoutCtx->FillIncPerElem.FullWordCnt = 0;
1137 pLayoutCtx->FillIncPerElem.LastWordFill = 1;
1138 }
1139 else
1140 {
1141 pLayoutCtx->FillIncPerElem.FullWordCnt = pLayoutCtx->BaseElemLenBits / (8 * pLayoutCtx->FullWordSize);
1142 pLayoutCtx->FillIncPerElem.LastWordFill = 0;
1143 }
1144
1145 OK = True;
1146 forallargs(pArg, OK)
1147 {
1148 if (!*pArg->Str)
1149 {
1150 OK = FALSE;
1151 WrStrErrorPos(ErrNum_EmptyArgument, pArg);
1152 }
1153 else
1154 OK = DecodeIntelPseudo_LayoutMult(pArg, pLayoutCtx);
1155 }
1156
1157 /* Finalize: add optional padding if fractions of full words
1158 remain unused & set code length */
1159
1160 if (OK)
1161 {
1162 if (pLayoutCtx->CurrCodeFill.LastWordFill)
1163 {
1164 WrError(ErrNum_PaddingAdded);
1165 pLayoutCtx->CurrCodeFill.LastWordFill = 0;
1166 pLayoutCtx->CurrCodeFill.FullWordCnt++;
1167 }
1168 CodeLen = pLayoutCtx->CurrCodeFill.FullWordCnt;
1169 }
1170
1171 DontPrint = (pLayoutCtx->DSFlag == DSSpace);
1172 if (DontPrint)
1173 {
1174 BookKeeping();
1175 if (!CodeLen && OK) WrError(ErrNum_NullResMem);
1176 }
1177 if (OK && (pLayoutCtx->FullWordSize == 1))
1178 ActListGran = 1;
1179 }
1180
1181 /*!------------------------------------------------------------------------
1182 * \fn DecodeIntelDN(Word BigEndian)
1183 * \brief Intel-style constant disposition - nibbles
1184 * \param BigEndian endianess
1185 * ------------------------------------------------------------------------ */
1186
DecodeIntelDN(Word BigEndian)1187 void DecodeIntelDN(Word BigEndian)
1188 {
1189 tLayoutCtx LayoutCtx;
1190
1191 memset(&LayoutCtx, 0, sizeof(LayoutCtx));
1192 LayoutCtx.LayoutFunc = LayoutNibble;
1193 LayoutCtx.BaseElemLenBits = 4;
1194 switch (Grans[ActPC])
1195 {
1196 case 1:
1197 LayoutCtx.Put4I = Put4I_To_8;
1198 LayoutCtx.LoHiMap = BigEndian ? 1 : 0;
1199 LayoutCtx.Replicate = Replicate4_To_8;
1200 break;
1201 case 2:
1202 LayoutCtx.Put4I = Put4I_To_16;
1203 LayoutCtx.LoHiMap = BigEndian ? 3 : 0;
1204 LayoutCtx.Replicate = Replicate4_To_16;
1205 break;
1206 }
1207 DecodeIntelDx(&LayoutCtx);
1208 }
1209
1210 /*!------------------------------------------------------------------------
1211 * \fn DecodeIntelDB(Word BigEndian)
1212 * \brief Intel-style constant disposition - bytes
1213 * \param BigEndian endianess
1214 * ------------------------------------------------------------------------ */
1215
DecodeIntelDB(Word BigEndian)1216 void DecodeIntelDB(Word BigEndian)
1217 {
1218 tLayoutCtx LayoutCtx;
1219
1220 memset(&LayoutCtx, 0, sizeof(LayoutCtx));
1221 LayoutCtx.LayoutFunc = LayoutByte;
1222 LayoutCtx.BaseElemLenBits = 8;
1223 switch (Grans[ActPC])
1224 {
1225 case 1:
1226 LayoutCtx.Put8I = Put8I_To_8;
1227 LayoutCtx.Replicate = Replicate8ToN_To_8;
1228 break;
1229 case 2:
1230 LayoutCtx.Put8I = Put8I_To_16;
1231 LayoutCtx.LoHiMap = BigEndian ? 1 : 0;
1232 LayoutCtx.Replicate = Replicate8_To_16;
1233 break;
1234 }
1235 if (*LabPart.Str)
1236 SetSymbolOrStructElemSize(&LabPart, eSymbolSize8Bit);
1237 DecodeIntelDx(&LayoutCtx);
1238 }
1239
1240 /*!------------------------------------------------------------------------
1241 * \fn DecodeIntelDW(Word BigEndian)
1242 * \brief Intel-style constant disposition - words
1243 * \param BigEndian endianess
1244 * ------------------------------------------------------------------------ */
1245
DecodeIntelDW(Word BigEndian)1246 void DecodeIntelDW(Word BigEndian)
1247 {
1248 tLayoutCtx LayoutCtx;
1249
1250 memset(&LayoutCtx, 0, sizeof(LayoutCtx));
1251 LayoutCtx.LayoutFunc = LayoutWord;
1252 LayoutCtx.BaseElemLenBits = 16;
1253 switch (Grans[ActPC])
1254 {
1255 case 1:
1256 LayoutCtx.Put16I = Put16I_To_8;
1257 LayoutCtx.Put16F = Put16F_To_8;
1258 LayoutCtx.LoHiMap = BigEndian ? 1 : 0;
1259 LayoutCtx.Replicate = Replicate8ToN_To_8;
1260 break;
1261 case 2:
1262 LayoutCtx.Put16I = Put16I_To_16;
1263 LayoutCtx.Put16F = Put16F_To_16;
1264 LayoutCtx.Replicate = Replicate16ToN_To_16;
1265 break;
1266 }
1267 if (*LabPart.Str)
1268 SetSymbolOrStructElemSize(&LabPart, eSymbolSize16Bit);
1269 DecodeIntelDx(&LayoutCtx);
1270 }
1271
1272 /*!------------------------------------------------------------------------
1273 * \fn DecodeIntelDD(Word BigEndian)
1274 * \brief Intel-style constant disposition - 32-bit words
1275 * \param BigEndian endianess
1276 * ------------------------------------------------------------------------ */
1277
DecodeIntelDD(Word BigEndian)1278 void DecodeIntelDD(Word BigEndian)
1279 {
1280 tLayoutCtx LayoutCtx;
1281
1282 memset(&LayoutCtx, 0, sizeof(LayoutCtx));
1283 LayoutCtx.LayoutFunc = LayoutDoubleWord;
1284 LayoutCtx.BaseElemLenBits = 32;
1285 switch (Grans[ActPC])
1286 {
1287 case 1:
1288 LayoutCtx.Put32I = Put32I_To_8;
1289 LayoutCtx.Put32F = Put32F_To_8;
1290 LayoutCtx.LoHiMap = BigEndian ? 3 : 0;
1291 LayoutCtx.Replicate = Replicate8ToN_To_8;
1292 break;
1293 case 2:
1294 LayoutCtx.Put32I = Put32I_To_16;
1295 LayoutCtx.Put32F = Put32F_To_16;
1296 LayoutCtx.LoHiMap = BigEndian ? 1 : 0;
1297 LayoutCtx.Replicate = Replicate16ToN_To_16;
1298 break;
1299 }
1300 if (*LabPart.Str)
1301 SetSymbolOrStructElemSize(&LabPart, eSymbolSize32Bit);
1302 DecodeIntelDx(&LayoutCtx);
1303 }
1304
1305 /*!------------------------------------------------------------------------
1306 * \fn DecodeIntelDQ(Word BigEndian)
1307 * \brief Intel-style constant disposition - 64-bit words
1308 * \param BigEndian endianess
1309 * ------------------------------------------------------------------------ */
1310
DecodeIntelDQ(Word BigEndian)1311 void DecodeIntelDQ(Word BigEndian)
1312 {
1313 tLayoutCtx LayoutCtx;
1314
1315 memset(&LayoutCtx, 0, sizeof(LayoutCtx));
1316 LayoutCtx.LayoutFunc = LayoutQuadWord;
1317 LayoutCtx.BaseElemLenBits = 64;
1318 switch (Grans[ActPC])
1319 {
1320 case 1:
1321 LayoutCtx.Put64I = Put64I_To_8;
1322 LayoutCtx.Put64F = Put64F_To_8;
1323 LayoutCtx.LoHiMap = BigEndian ? 7 : 0;
1324 LayoutCtx.Replicate = Replicate8ToN_To_8;
1325 break;
1326 case 2:
1327 LayoutCtx.Put64I = Put64I_To_16;
1328 LayoutCtx.Put64F = Put64F_To_16;
1329 LayoutCtx.LoHiMap = BigEndian ? 3 : 0;
1330 LayoutCtx.Replicate = Replicate16ToN_To_16;
1331 break;
1332 }
1333 if (*LabPart.Str)
1334 SetSymbolOrStructElemSize(&LabPart, eSymbolSize64Bit);
1335 DecodeIntelDx(&LayoutCtx);
1336 }
1337
1338 /*!------------------------------------------------------------------------
1339 * \fn DecodeIntelDT(Word BigEndian)
1340 * \brief Intel-style constant disposition - 80-bit words
1341 * \param BigEndian endianess
1342 * ------------------------------------------------------------------------ */
1343
DecodeIntelDT(Word BigEndian)1344 void DecodeIntelDT(Word BigEndian)
1345 {
1346 tLayoutCtx LayoutCtx;
1347
1348 memset(&LayoutCtx, 0, sizeof(LayoutCtx));
1349 LayoutCtx.LayoutFunc = LayoutTenBytes;
1350 LayoutCtx.BaseElemLenBits = 80;
1351 switch (Grans[ActPC])
1352 {
1353 case 1:
1354 LayoutCtx.Put80F = Put80F_To_8;
1355 LayoutCtx.LoHiMap = BigEndian ? 1 : 0;
1356 LayoutCtx.Replicate = Replicate8ToN_To_8;
1357 break;
1358 case 2:
1359 LayoutCtx.Put80F = Put80F_To_16;
1360 LayoutCtx.LoHiMap = BigEndian ? 1 : 0;
1361 LayoutCtx.Replicate = Replicate16ToN_To_16;
1362 break;
1363 }
1364 if (*LabPart.Str)
1365 SetSymbolOrStructElemSize(&LabPart, eSymbolSize80Bit);
1366 DecodeIntelDx(&LayoutCtx);
1367 }
1368
1369 /*!------------------------------------------------------------------------
1370 * \fn DecodeIntelDS(Word Code)
1371 * \brief Intel-style memory reservation
1372 * ------------------------------------------------------------------------ */
1373
DecodeIntelDS(Word Code)1374 void DecodeIntelDS(Word Code)
1375 {
1376 UNUSED(Code);
1377
1378 if (ChkArgCnt(1, 1))
1379 {
1380 tSymbolFlags Flags;
1381 Boolean OK;
1382 LongInt HVal = EvalStrIntExpressionWithFlags(&ArgStr[1], Int32, &OK, &Flags);
1383
1384 if (mFirstPassUnknown(Flags)) WrError(ErrNum_FirstPassCalc);
1385 else if (OK)
1386 {
1387 DontPrint = True;
1388 CodeLen = HVal;
1389 if (!HVal)
1390 WrError(ErrNum_NullResMem);
1391 BookKeeping();
1392 }
1393 }
1394 }
1395
1396 /*!------------------------------------------------------------------------
1397 * \fn DecodeIntelPseudo(Boolean BigEndian)
1398 * \brief decode Intel-style pseudo instructions
1399 * \param BigEndian target endianess
1400 * \return True if instruction found
1401 * ------------------------------------------------------------------------ */
1402
DecodeIntelPseudo(Boolean BigEndian)1403 Boolean DecodeIntelPseudo(Boolean BigEndian)
1404 {
1405 static PInstTable InstTables[2] = { NULL, NULL };
1406 int Idx = !!BigEndian;
1407
1408 if (!InstTables[Idx])
1409 {
1410 PInstTable InstTable = CreateInstTable(17);
1411 AddInstTable(InstTable, "DN", BigEndian, DecodeIntelDN);
1412 AddInstTable(InstTable, "DB", BigEndian, DecodeIntelDB);
1413 AddInstTable(InstTable, "DW", BigEndian, DecodeIntelDW);
1414 AddInstTable(InstTable, "DD", BigEndian, DecodeIntelDD);
1415 AddInstTable(InstTable, "DQ", BigEndian, DecodeIntelDQ);
1416 AddInstTable(InstTable, "DT", BigEndian, DecodeIntelDT);
1417 AddInstTable(InstTable, "DS", 0, DecodeIntelDS);
1418 InstTables[Idx] = InstTable;
1419 }
1420 return LookupInstTable(InstTables[Idx], OpPart.Str);
1421 }
1422
1423