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