home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_300 / 363_01 / build.c < prev    next >
C/C++ Source or Header  |  1991-12-17  |  27KB  |  917 lines

  1. /***********************************************************************
  2.  *
  3.  *      BUILD.C
  4.  *      Instruction Building Routines for 68020 Assembler
  5.  *
  6.  * Description: The functions in this file build instructions, that is, they
  7.  *      assemble the instruction word and its extension words given the
  8.  *      skeleton bit mask for the instruction and opDescriptors for its
  9.  *      operand(s). The instructions that each routine builds are noted above
  10.  *      it in a comment. All the functions share the same calling sequence
  11.  *      which is as follows: 
  12.  *
  13.  *          general_name(int mask, int size, opdescriptor *source,
  14.  *                                      opdescriptor *dest, int *errorPtr);
  15.  *
  16.  *      The mask argument is the skeleton mask for the instruction, i.e., the
  17.  *      instruction word before the addressing information has been filled in.
  18.  *      The size argument contains the size code that was specified with the
  19.  *      instruction (using the definitions in ASM.H) or 0 if no size code was
  20.  *      specified. Arguments source and dest are pointers to opDescriptors for
  21.  *      the two operands (only source is valid in some cases). The last
  22.  *      argument is used to return a status via the standard mechanism.
  23.  *
  24.  *      Author: Paul McKee
  25.  *      ECE492    North Carolina State University,  12/13/86
  26.  *
  27.  *      Modified A.E. Romer. Version 1.0
  28.  *          16 March 1991   ANSI functions, braces layout.
  29.  *               May 1991   68020-specific addressing modes added.
  30.  *          24 Sept. 1991   MOVEQ range is now -128 to 255
  31.  *                          
  32.  ************************************************************************/
  33.  
  34.  
  35. #include <stdio.h>
  36. #include "asm.h"
  37.  
  38. extern long loc;
  39. extern char pass2;
  40. extern char noOperand;      /* TRUE if the instruction has no operand.
  41.                              * Used by listLine. */
  42.  
  43. #define     MOVQ_LO     -128        /* lower and higher limits for MOVEQ */
  44. #define     MOVQ_HI     255         /* data range */
  45.  
  46.  
  47. /***********************************************************************
  48.  *
  49.  *  Function move builds the MOVE and MOVEA instructions
  50.  *
  51.  ***********************************************************************/
  52.  
  53. int move(int mask, int size, opDescriptor *source, opDescriptor *dest, 
  54.                                                                 int *errorPtr)
  55.     {
  56.     unsigned short moveMask;
  57.     char destCode;
  58.  
  59.     /* Check whether the instruction can be assembled as MOVEQ */
  60.     if (source->mode == Immediate && source->backRef
  61.                             && size == LONG && dest->mode == DnDirect
  62.                             && source->data >= MOVQ_LO
  63.                             && source->data <= MOVQ_HI)
  64.         {
  65.         moveq(0x7000, size, source, dest, errorPtr);
  66.         return NORMAL;
  67.         }
  68.  
  69.     /* Otherwise assemble it as plain MOVE */
  70.     moveMask = mask | effAddr(source);
  71.     destCode = (char) (effAddr(dest) & 0xff);
  72.     moveMask |= (destCode & 0x38) << 3 | (destCode & 7) << 9;
  73.     if (pass2)
  74.         output((long) (moveMask), WORD);
  75.     loc += 2;
  76.     extWords(source, size, errorPtr);
  77.     extWords(dest, size, errorPtr);
  78.  
  79.     return NORMAL;
  80.     }
  81.  
  82. /***********************************************************************
  83.  *
  84.  *  Function zeroOp builds the following instructions:
  85.  *   ILLEGAL
  86.  *   NOP
  87.  *   RESET
  88.  *   RTE
  89.  *   RTR
  90.  *   RTS
  91.  *   TRAPV
  92.  *
  93.  ***********************************************************************/
  94.  
  95. int zeroOp(int mask, int size, opDescriptor *source, opDescriptor *dest, 
  96.                                                             int *errorPtr)
  97.     {
  98.     if (pass2)
  99.         {
  100.         output((long) (mask), WORD);
  101.         noOperand = TRUE;
  102.         }
  103.     loc += 2;
  104.  
  105.     return NORMAL;
  106.     }
  107.  
  108. /***********************************************************************
  109.  *
  110.  *  Function oneOp builds the following instructions:
  111.  *   ASd  <ea>
  112.  *   CLR
  113.  *   JMP
  114.  *   JSR
  115.  *   LSd  <ea>
  116.  *   MOVE <ea>,CCR
  117.  *   MOVE <ea>,SR
  118.  *   NBCD
  119.  *   NEG
  120.  *   NEGX
  121.  *   NOT
  122.  *   PEA
  123.  *   ROd  <ea>
  124.  *   ROXd <ea>
  125.  *   TAS
  126.  *   TST
  127.  *
  128.  ***********************************************************************/
  129.  
  130. int oneOp(int mask, int size, opDescriptor *source, opDescriptor *dest, 
  131.                                                             int *errorPtr)
  132.     {
  133.     if (pass2)
  134.         output((long) (mask | effAddr(source)), WORD);
  135.     loc += 2;
  136.     extWords(source, size, errorPtr);
  137.  
  138.     return NORMAL;
  139.     }
  140.  
  141.  
  142. /***********************************************************************
  143.  *
  144.  *  Function arithReg builds the following instructions:
  145.  *   ADD <ea>,Dn
  146.  *   ADDA
  147.  *   AND <ea>,Dn
  148.  *   CHK
  149.  *   CMP
  150.  *   CMPA
  151.  *   DIVS
  152.  *   DIVU
  153.  *   LEA
  154.  *   MULS
  155.  *   MULU
  156.  *   OR <ea>,Dn
  157.  *   SUB <ea>,Dn
  158.  *   SUBA
  159.  *
  160.  ***********************************************************************/
  161.  
  162. int arithReg(int mask, int size, opDescriptor *source, opDescriptor *dest, 
  163.                                                             int *errorPtr)
  164.     {
  165.     if (pass2)
  166.         output((long) (mask | effAddr(source) | (dest->reg << 9)), WORD);
  167.     loc += 2;
  168.     extWords(source, size, errorPtr);
  169.  
  170.     return NORMAL;
  171.     }
  172.  
  173. /***********************************************************************
  174.  *
  175.  *  Function arithAddr builds the following instructions:
  176.  *   ADD Dn,<ea>
  177.  *   AND Dn,<ea>
  178.  *   BCHG Dn,<ea>
  179.  *   BCLR Dn,<ea>
  180.  *   BSET Dn,<ea>
  181.  *   BTST Dn,<ea>
  182.  *   EOR
  183.  *   OR Dn,<ea>
  184.  *   SUB Dn,<ea>
  185.  *
  186.  ***********************************************************************/
  187.  
  188.  
  189. int arithAddr(int mask, int size, opDescriptor *source, opDescriptor *dest, 
  190.                                                             int *errorPtr)
  191.     {
  192.     if (pass2)
  193.         output((long) (mask | effAddr(dest) | (source->reg << 9)), WORD);
  194.     loc += 2;
  195.     extWords(dest, size, errorPtr);
  196.  
  197.     return NORMAL;
  198.     }
  199.  
  200.  
  201. /***********************************************************************
  202.  *
  203.  *  Function immedInst builds the following instructions:
  204.  *   ADDI
  205.  *   ANDI
  206.  *   CMPI
  207.  *   EORI
  208.  *   ORI
  209.  *   SUBI
  210.  *
  211.  ***********************************************************************/
  212.  
  213.  
  214. int immedInst(int mask, int size, opDescriptor *source, opDescriptor *dest, 
  215.                                                             int *errorPtr)
  216.     {
  217.     unsigned short type;
  218.  
  219.     /* Check whether the instruction is an immediate ADD or SUB 
  220.            that can be assembled as ADDQ or SUBQ */
  221.     /* Check the mask to determine the operation */
  222.     type = mask & 0xFF00;
  223.     if ((type == 0x0600 || type == 0x0400)
  224.                 && source->backRef && source->data >= 1 && source->data <= 8)
  225.         if (type == 0x0600)
  226.             {
  227.             /* Assemble as ADDQ */
  228.             quickMath(0x5000 | (mask & 0x00C0), size, source, dest, errorPtr);
  229.             return NORMAL;
  230.             }
  231.         else
  232.             {
  233.             /* Assemble as SUBQ */
  234.             quickMath(0x5100 | (mask & 0x00C0), size, source, dest, errorPtr);
  235.             return NORMAL;
  236.             }
  237.  
  238.     /* Otherwise assemble as an ordinary instruction */
  239.     if (pass2)
  240.         output((long) (mask | effAddr(dest)), WORD);
  241.     loc += 2;
  242.     extWords(source, size, errorPtr);
  243.     extWords(dest, size, errorPtr);
  244.  
  245.     return NORMAL;
  246.     }
  247.  
  248.  
  249. /***********************************************************************
  250.  *
  251.  *  Function quickMath builds the following instructions:
  252.  *   ADDQ
  253.  *   SUBQ
  254.  *
  255.  ***********************************************************************/
  256.  
  257.  
  258. int quickMath(int mask, int size, opDescriptor *source, opDescriptor *dest, 
  259.                                                             int *errorPtr)
  260.     {
  261.     int status;
  262.  
  263.     if (pass2)
  264.         {
  265.         output((long) (mask | effAddr(dest) | ((source->data & 7) << 9)), 
  266.                                                                     WORD);
  267.         if (source->data < 1 || source->data > 8)
  268.             NEWERROR(*errorPtr, INV_QUICK_CONST);
  269.         }
  270.     loc += 2;
  271.     extWords(dest, size, errorPtr);
  272.  
  273.     return NORMAL;
  274.     }
  275.  
  276.  
  277. /***********************************************************************
  278.  *
  279.  *  Function movep builds the MOVEP instruction.
  280.  *
  281.  ***********************************************************************/
  282.  
  283.  
  284. int movep(int mask, int size, opDescriptor *source, opDescriptor *dest, 
  285.                                                             int *errorPtr)
  286.     {
  287.     if (pass2)
  288.         if (source->mode == DnDirect)
  289.             {
  290.             /* Convert plain address register indirect to address
  291.                register indirect with displacement of 0 */
  292.             if (dest->mode == AnInd)
  293.                 {
  294.                 dest->mode = AnIndDisp;
  295.                 dest->data = 0;
  296.                 }
  297.             output((long) (mask | (source->reg << 9) | (dest->reg)), WORD);
  298.             loc += 2;
  299.             extWords(dest, size, errorPtr);
  300.             }
  301.         else
  302.             {
  303.             /* Convert plain address register indirect to address
  304.                register indirect with displacement of 0 */
  305.             if (source->mode == AnInd) {
  306.                 source->mode = AnIndDisp;
  307.                 source->data = 0;
  308.                 }
  309.             output((long) (mask | (dest->reg << 9) | (source->reg)), WORD);
  310.             loc += 2;
  311.             extWords(source, size, errorPtr);
  312.             }
  313.     else
  314.         loc += 4;
  315.  
  316.     return NORMAL;
  317.     }
  318.  
  319.  
  320. /***********************************************************************
  321.  *
  322.  *  Function moves builds the MOVES instruction.
  323.  *
  324.  ***********************************************************************/
  325.  
  326.  
  327. int moves(int mask, int size, opDescriptor *source, opDescriptor *dest, 
  328.                                                             int *errorPtr)
  329.     {
  330.     if (pass2)
  331.         if (source->mode & (DnDirect | AnDirect))
  332.             {
  333.             output((long) (mask | effAddr(dest)), WORD);
  334.             loc += 2;
  335.             if (source->mode == DnDirect)
  336.                 output((long) (0x0800 | (source->reg << 12)), WORD);
  337.             else
  338.                 output((long) (0x8800 | (source->reg << 12)), WORD);
  339.             loc += 2;
  340.             }
  341.         else
  342.             {
  343.             output((long) mask | effAddr(source), WORD);
  344.             loc += 2;
  345.             if (dest->mode == DnDirect)
  346.                 output((long) (dest->reg << 12), WORD);
  347.             else
  348.                 output((long) (0x8000 | (dest->reg << 12)), WORD);
  349.             loc += 2;
  350.             }
  351.     else
  352.         loc += 4;
  353.     extWords((source->mode & (DnDirect | AnDirect)) ? dest : source,
  354.                                                              size, errorPtr);
  355.  
  356.     return NORMAL;
  357.     }
  358.  
  359.  
  360. /***********************************************************************
  361.  *
  362.  *  Function moveReg builds the following instructions:
  363.  *   MOVE from CCR
  364.  *   MOVE from SR
  365.  *
  366.  ***********************************************************************/
  367.  
  368.  
  369. int moveReg(int mask, int size, opDescriptor *source, opDescriptor *dest, 
  370.                         int *errorPtr)
  371.     {
  372.     if (pass2)
  373.         output((long) (mask | effAddr(dest)), WORD);
  374.     loc += 2;
  375.     extWords(dest, size, errorPtr);
  376.  
  377.     return NORMAL;
  378.     }
  379.  
  380.  
  381. /***********************************************************************
  382.  *
  383.  *  Function staticBit builds the following instructions:
  384.  *   BCHG #n,<ea>
  385.  *   BCLR #n,<ea>
  386.  *   BSET #n,<ea>
  387.  *   BTST #n,<ea>
  388.  *
  389.  ***********************************************************************/
  390.  
  391.  
  392. int staticBit(int mask, int size, opDescriptor *source, opDescriptor *dest, 
  393.                         int *errorPtr)
  394.     {
  395.     if (pass2)
  396.         {
  397.         output((long) (mask | effAddr(dest)), WORD);
  398.         loc += 2;
  399.         output(source->data & 0xFF, WORD);
  400.         loc += 2;
  401.         }
  402.     else
  403.         loc += 4;
  404.     extWords(dest, size, errorPtr);
  405.  
  406.     return NORMAL;
  407.     }
  408.  
  409.  
  410. /***********************************************************************
  411.  *
  412.  *  Function movec builds the MOVEC instruction.
  413.  *
  414.  ***********************************************************************/
  415.  
  416.  
  417. int movec(int mask, int size, opDescriptor *source, opDescriptor *dest, 
  418.                                                             int *errorPtr)
  419.     {
  420.     unsigned short mask2;
  421.     opDescriptor *regOp;
  422.     long    controlMode;
  423.  
  424.     if (pass2)
  425.         {
  426.         output((long) (mask), WORD);
  427.         loc += 2;
  428.         if (mask & 1)
  429.             {
  430.             regOp = source;
  431.             controlMode = dest->mode;
  432.             }
  433.         else
  434.             {
  435.             regOp = dest;
  436.             controlMode = source->mode;
  437.             }
  438.         mask2 = regOp->reg << 12;
  439.         if (regOp->mode == AnDirect)
  440.             mask2 |= 0x8000;
  441.         if (controlMode == SFCDirect)
  442.             mask2 |= 0x000;
  443.         else if (controlMode == DFCDirect)
  444.             mask2 |= 0x001;
  445.         else if (controlMode == USPDirect)
  446.             mask2 |= 0x800;
  447.         else if (controlMode == VBRDirect)
  448.             mask2 |= 0x801;
  449.         output((long) (mask2), WORD);
  450.         loc += 2;
  451.         }
  452.     else
  453.         loc += 4;
  454.  
  455.     return NORMAL;
  456.     }
  457.  
  458.  
  459. /***********************************************************************
  460.  *
  461.  *  Function trap builds the TRAP instruction.
  462.  *
  463.  ***********************************************************************/
  464.  
  465.  
  466. int trap(int mask, int size, opDescriptor *source, opDescriptor *dest, 
  467.                                                             int *errorPtr)
  468.     {
  469.     if (pass2)
  470.         {
  471.         output(mask | (source->data & 0xF), WORD);
  472.         if (source->data < 0 || source->data > 15)
  473.             NEWERROR(*errorPtr, INV_VECTOR_NUM);
  474.         }
  475.     loc += 2;
  476.  
  477.     return NORMAL;
  478.     }
  479.  
  480.  
  481. /***********************************************************************
  482.  *
  483.  *  Function branch builds the following instructions:
  484.  *   BCC (BHS)   BGT     BLT         BRA
  485.  *   BCS (BLO)   BHI     BMI         BSR
  486.  *   BEQ         BLE     BNE         BVC
  487.  *   BGE         BLS     BPL         BVS
  488.  *
  489.  ***********************************************************************/
  490.  
  491.  
  492. int branch(int mask, int size, opDescriptor *source, opDescriptor *dest, 
  493.                                                             int *errorPtr)
  494.     {
  495.     long disp;
  496.  
  497.     disp = source->data - loc - 2;
  498.     
  499.     if (source->backRef)
  500.         switch (size)
  501.             {
  502.             case SHORT:
  503.                 if (pass2)
  504.                     output((long) (mask | (disp & 0xff)), WORD);
  505.                 loc += 2;
  506.                 if ((disp < -128 || disp > 127))
  507.                     NEWERROR(*errorPtr, INV_BRANCH_DISP);
  508.                 break;
  509.             case LONG:
  510.                 if (pass2)
  511.                     output((long) (mask | 0xff), WORD);
  512.                 loc += 2;
  513.                 if (pass2)
  514.                     output(disp, LONG);
  515.                 loc += 4;
  516.                 if (disp >= -32768 && disp <= 32767)
  517.                     NEWERROR(*errorPtr, EXCESSIVE_SIZE);
  518.                 break;
  519.             default:                                /* no size specified */
  520.                 if ((disp >= -128 && disp < 127))   /* 8-bit displacement */
  521.                     {
  522.                     if (pass2)
  523.                         output((long) (mask | (disp & 0xff)), WORD);
  524.                     loc += 2;
  525.                     }
  526.                 else if (disp >= -32768 && disp <= 32767)   /* 16-bit displ. */
  527.                     {
  528.                     if (pass2)
  529.                         output((long) (mask), WORD);
  530.                     loc += 2;
  531.                     if (pass2)
  532.                         output((long) (disp), WORD);
  533.                     loc += 2;
  534.                     }
  535.                 else            /* 32-bit displacement */
  536.                     {
  537.                     if (pass2)
  538.                         output((long) (mask | 0xff), WORD);
  539.                     loc += 2;
  540.                     if (pass2)
  541.                         output(disp, LONG);
  542.                     loc += 4;
  543.                     break;
  544.                     }
  545.             }
  546.         else                /* source->backRef == 0 */
  547.             {
  548.             switch (size)
  549.                 {
  550.                 case SHORT:
  551.                     if (pass2)
  552.                         {
  553.                         if (disp == 0)
  554.                             {
  555.                             output( (long) 0, WORD);
  556.                             NEWERROR(*errorPtr, INV_SHORT_BRANCH);
  557.                             }
  558.                         else
  559.                             {
  560.                             output((long) (mask | (disp & 0xff)), WORD);
  561.                             if (disp < -128 || disp > 127)
  562.                                 NEWERROR(*errorPtr, INV_BRANCH_DISP);
  563.                             }
  564.                         }
  565.                     loc += 2;
  566.                     break;
  567.                 case LONG:
  568.                     if (pass2)
  569.                         output((long) (mask | 0xff), WORD);
  570.                     loc += 2;
  571.                     if (pass2)
  572.                         {
  573.                         output(disp, LONG);
  574.                         if (disp >= -32768 && disp <= 32767)
  575.                             NEWERROR(*errorPtr, EXCESSIVE_SIZE);
  576.                         }
  577.                     loc += 4;
  578.                     break;
  579.                 default:                        /* size not specified,
  580.                                                  * 16-bit displacement default */
  581.                     if (pass2)
  582.                         output( (long) mask, WORD);
  583.                     loc += 2;
  584.                     if (pass2)
  585.                         {
  586.                         output(disp & 0xffff, WORD);
  587.                         if (disp >= -128 && disp <= 127)
  588.                             NEWERROR(*errorPtr, EXCESSIVE_SIZE);
  589.                         if (disp < -32768 || disp > 32767)
  590.                             NEWERROR(*errorPtr, INV_BRANCH_DISP);
  591.                         }
  592.                     loc += 2;
  593.                     break;
  594.                 }
  595.             }
  596.     return NORMAL;
  597.     }
  598.  
  599.  
  600. /***********************************************************************
  601.  *
  602.  *  Function moveq builds the MOVEQ instruction.
  603.  *
  604.  ***********************************************************************/
  605.  
  606.  
  607. int moveq(int mask, int size, opDescriptor *source, opDescriptor *dest, 
  608.                                                             int *errorPtr)
  609.     {
  610.     if (pass2)
  611.         {
  612.         output(mask | (dest->reg << 9) | (source->data & 0xFF), WORD);
  613.         if (source->data < MOVQ_LO || source->data > MOVQ_HI)
  614.             NEWERROR(*errorPtr, INV_MOVEQ_CONST);
  615.         }
  616.     loc += 2;
  617.  
  618.     return NORMAL;
  619.     }
  620.  
  621.  
  622. /***********************************************************************
  623.  *
  624.  *  Function immedToCCR builds the following instructions:
  625.  *   ANDI to CCR
  626.  *   EORI to CCR
  627.  *   ORI to CCR
  628.  *
  629.  ***********************************************************************/
  630.  
  631.  
  632. int immedToCCR(int mask, int size, opDescriptor *source, opDescriptor *dest, 
  633.                                                             int *errorPtr)
  634.     {
  635.     if (pass2)
  636.         {
  637.         output((long) (mask), WORD);
  638.         loc += 2;
  639.         output(source->data & 0xFF, WORD);
  640.         loc += 2;
  641.         if ((source->data & 0xFF) != source->data)
  642.             NEWERROR(*errorPtr, INV_8_BIT_DATA);
  643.         }
  644.     else
  645.         loc += 4;
  646.  
  647.     return NORMAL;
  648.     }
  649.  
  650.  
  651. /***********************************************************************
  652.  *
  653.  *  Function immedWord builds the following instructions:
  654.  *   ANDI to SR
  655.  *   EORI to SR
  656.  *   ORI to SR
  657.  *   RTD
  658.  *   STOP
  659.  *
  660.  ***********************************************************************/
  661.  
  662.  
  663. int immedWord(int mask, int size, opDescriptor *source, opDescriptor *dest, 
  664.                                                             int *errorPtr)
  665.     {
  666.     if (pass2)
  667.         {
  668.         output((long) (mask), WORD);
  669.         loc += 2;
  670.         output(source->data & 0xFFFF, WORD);
  671.         loc += 2;
  672.         if (source->data < -32768 || source->data > 65535)
  673.             NEWERROR(*errorPtr, INV_16_BIT_DATA);
  674.         }
  675.     else
  676.         loc += 4;
  677.  
  678.     return NORMAL;
  679.     }
  680.  
  681.  
  682. /***********************************************************************
  683.  *
  684.  *  Function dbcc builds the following instructions:
  685.  *   DBCC (DBHS)  DBGE   DBLS        DBPL
  686.  *   DBCS (DBLO)  DBGT   DBLT        DBT
  687.  *   DBEQ         DBHI   DBMI        DBVC
  688.  *   DBF (DBRA)   DBLE   DBNE        DBVS
  689.  *
  690.  ***********************************************************************/
  691.  
  692.  
  693. int dbcc(int mask, int size, opDescriptor *source, opDescriptor *dest, 
  694.                                                             int *errorPtr)
  695.     {
  696.     short disp;
  697.  
  698.     disp = (short int) (dest->data - loc - 2);
  699.     if (pass2)
  700.         {
  701.         output((long) (mask | source->reg), WORD);
  702.         loc += 2;
  703.         output((long) (disp), WORD);
  704.         loc += 2;
  705.         if (disp < -32768 || disp > 32767)
  706.             NEWERROR(*errorPtr, INV_BRANCH_DISP);
  707.         }
  708.     else
  709.         loc += 4;
  710.  
  711.     return NORMAL;
  712.     }
  713.  
  714.  
  715. /***********************************************************************
  716.  *
  717.  *  Function scc builds the following instructions:
  718.  *   SCC (SHS)   SGE     SLS        SPL
  719.  *   SCS (SLO)   SGT     SLT        ST
  720.  *   SEQ         SHI     SMI        SVC
  721.  *   SF      SLE     SNE        SVS
  722.  *
  723.  ***********************************************************************/
  724.  
  725.  
  726. int scc(int mask, int size, opDescriptor *source, opDescriptor *dest, 
  727.                                                             int *errorPtr)
  728.     {
  729.     if (pass2)
  730.         output((long) (mask | effAddr(source)), WORD);
  731.     loc += 2;
  732.     extWords(source, size, errorPtr);
  733.  
  734.     return NORMAL;
  735.     }
  736.  
  737.  
  738. /***********************************************************************
  739.  *
  740.  *  Function shiftReg builds the following instructions:
  741.  *   ASd    Dx,Dy
  742.  *   LSd    Dx,Dy
  743.  *   ROd    Dx,Dy
  744.  *   ROXd   Dx,Dy
  745.  *   ASd    #<data>,Dy
  746.  *   LSd    #<data>,Dy
  747.  *   ROd    #<data>,Dy
  748.  *   ROXd   #<data>,Dy
  749.  *
  750.  ***********************************************************************/
  751.  
  752.  
  753. int shiftReg(int mask, int size, opDescriptor *source, opDescriptor *dest, 
  754.                                                             int *errorPtr)
  755.     {
  756.     if (pass2)
  757.         {
  758.         mask |= dest->reg;
  759.         if (source->mode == Immediate)
  760.             {
  761.             mask |= (source->data & 7) << 9;
  762.             if (source->data < 1 || source->data > 8)
  763.                 NEWERROR(*errorPtr, INV_SHIFT_COUNT);
  764.             }
  765.         else
  766.             mask |= source->reg << 9;
  767.         output((long) (mask), WORD);
  768.         }
  769.     loc += 2;
  770.  
  771.     return NORMAL;
  772.     }
  773.  
  774.  
  775. /***********************************************************************
  776.  *
  777.  *  Function exg builds the EXG instruction.
  778.  *
  779.  ***********************************************************************/
  780.  
  781.  
  782. int exg(int mask, int size, opDescriptor *source, opDescriptor *dest, 
  783.                                                             int *errorPtr)
  784.     {
  785.     if (pass2)
  786.         {
  787.         /* Are a data register and an address register being exchanged? */
  788.         if (source->mode != dest->mode)
  789.             /* If so, the address register goes in bottom three bits */
  790.             if (source->mode == AnDirect)
  791.                 mask |= source->reg | (dest->reg << 9);
  792.             else
  793.                 mask |= dest->reg | (source->reg << 9);
  794.         else
  795.             /* Otherwise it doesn't matter which way they go */
  796.             mask |= dest->reg | (source->reg << 9);
  797.         output((long) (mask), WORD);
  798.         }
  799.     loc += 2;
  800.  
  801.     return NORMAL;
  802.     }
  803.  
  804.  
  805. /***********************************************************************
  806.  *
  807.  *  Function twoReg builds the following instructions:
  808.  *   ABCD
  809.  *   ADDX
  810.  *   CMPM
  811.  *   SBCD
  812.  *   SUBX
  813.  *
  814.  ***********************************************************************/
  815.  
  816.  
  817. int twoReg(int mask, int size, opDescriptor *source, opDescriptor *dest, 
  818.                                                             int *errorPtr)
  819.     {
  820.     if (pass2)
  821.         output((long) (mask | (dest->reg << 9) | source->reg), WORD);
  822.     loc += 2;
  823.  
  824.     return NORMAL;
  825.     }
  826.  
  827.  
  828. /***********************************************************************
  829.  *
  830.  *  Function oneReg builds the following instructions:
  831.  *   EXT
  832.  *   EXTB
  833.  *   SWAP
  834.  *   UNLK
  835.  *
  836.  ***********************************************************************/
  837.  
  838.  
  839. int oneReg(int mask, int size, opDescriptor *source, opDescriptor *dest, 
  840.                                                             int *errorPtr)
  841.     {
  842.     if (pass2)
  843.         output((long) (mask | source->reg), WORD);
  844.     loc += 2;
  845.  
  846.     return NORMAL;
  847.     }
  848.  
  849.  
  850. /***********************************************************************
  851.  *
  852.  *  Function moveUSP builds the following instructions:
  853.  *   MOVE   USP,An
  854.  *   MOVE   An,USP
  855.  *
  856.  ***********************************************************************/
  857.  
  858.  
  859. int moveUSP(int mask, int size, opDescriptor *source, opDescriptor *dest, 
  860.                                                             int *errorPtr)
  861.     {
  862.     if (pass2)
  863.         {
  864.         if (source->mode == AnDirect)
  865.             output((long) (mask | source->reg), WORD);
  866.         else
  867.             output((long) (mask | dest->reg), WORD);
  868.         }
  869.     loc += 2;
  870.  
  871.     return NORMAL;
  872.     }
  873.  
  874.  
  875. /***********************************************************************
  876.  *
  877.  *  Function link builds the LINK instruction
  878.  *
  879.  ***********************************************************************/
  880.  
  881.  
  882. int link(int mask, int size, opDescriptor *source, opDescriptor *dest, 
  883.                                                             int *errorPtr)
  884.     {
  885.     if (pass2)
  886.         {
  887.         output((long) (mask | source->reg), WORD);
  888.         loc += 2;
  889.         output(dest->data, WORD);
  890.         loc += 2;
  891.         if (dest->data < -32768 || dest->data > 32767)
  892.             NEWERROR(*errorPtr, INV_16_BIT_DATA);
  893.         }
  894.     else
  895.         loc += 4;
  896.  
  897.     return NORMAL;
  898.     }
  899.  
  900.  
  901. /***********************************************************************
  902.  *
  903.  *  Function noOp builds the error message for an unimplemented
  904.  *  instruction
  905.  *
  906.  ***********************************************************************/
  907.  
  908. int noOp(int mask, int size, opDescriptor *source, opDescriptor *dest, 
  909.                                                             int *errorPtr)
  910.     {
  911.     if (pass2)
  912.         {
  913.         NEWERROR(*errorPtr, UNIMPLEMENTED);
  914.         }
  915.     return NORMAL;
  916.     }
  917.