home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / INFO / CROSSASM / 68ASMSIM.ZIP / asmsrc / build.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-04-09  |  19.4 KB  |  885 lines

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