home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Tools / Languages / Harvest C 1.3 / Source Code / genside.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-06-15  |  28.7 KB  |  839 lines  |  [TEXT/ALFA]

  1. /*
  2.     Harvest C
  3.     Copyright 1992 Eric W. Sink.  All rights reserved.
  4.     
  5.     This file is part of Harvest C.
  6.     
  7.     Harvest C is free software; you can redistribute it and/or modify
  8.     it under the terms of the GNU Generic Public License as published by
  9.     the Free Software Foundation; either version 2, or (at your option)
  10.     any later version.
  11.     
  12.     Harvest C is distributed in the hope that it will be useful,
  13.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.     GNU General Public License for more details.
  16.     
  17.     You should have received a copy of the GNU General Public License
  18.     along with Harvest C; see the file COPYING.  If not, write to
  19.     the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  20.     
  21.     Harvest C is not in any way a product of the Free Software Foundation.
  22.     Harvest C is not GNU software.
  23.     Harvest C is not public domain.
  24.  
  25.     This file may have other copyrights which are applicable as well.
  26.  
  27. */
  28.  
  29. /*
  30.  * Harvest C
  31.  * 
  32.  * Copyright 1991 Eric W. Sink   All rights reserved.
  33.  * 
  34.  * This file contains routines for 68k code generation.  These routines handle
  35.  * expressions with side effects.
  36.  * 
  37.  * 
  38.  */
  39.  
  40.  
  41. #include "conditcomp.h"
  42. #include <stdio.h>
  43. #include <string.h>
  44. #include "structs.h"
  45. #include "CHarvestDoc.h"
  46. #include "CHarvestOptions.h"
  47.  
  48. extern CHarvestDoc *gProject;
  49.  
  50. #pragma segment GenSide
  51.  
  52.  
  53. LocAMVia_t
  54. GenAssign(ParseTreeVia_t left, ParseTreeVia_t right, InstListVia_t Codes)
  55. /* General routine for generating an assignment node. */
  56. {
  57.     /*
  58.      * An example of a correct code generation routine.  Never assume the
  59.      * sizes of the types of the arguments, without checking.  Call FreeTemp
  60.      * on all Loc records not returned from the routine.
  61.      */
  62.  
  63.     LocAMVia_t                      rightoperand;
  64.     LocAMVia_t                      result;
  65.     rightoperand = GenExpression(right, Codes);
  66.     result = GenExpression(left, Codes);
  67.  
  68.     GenDeConflictize(&rightoperand, &result, Codes);
  69.  
  70.     if (GetLocAM(result) == M68am_ARegDisplaceFIELD) {
  71.     unsigned long                   bitmask;
  72.     LocAMVia_t                      prev;
  73.     prev = TempDataReg(Codes);
  74.     Genmove(M68sz_long, result, prev, Codes);
  75.     /* Construct a mask, and AND immed */
  76.     bitmask = ~MakeMask(result);
  77.     GenInst(M68op_AND, GetLocSZ(result),
  78.         BuildImmediate(bitmask, M68sz_long), prev, Codes);
  79.  
  80.     rightoperand = DictateTempDReg(rightoperand, Codes);
  81.     ShiftLeft(rightoperand, GetLocFieldBits(result).StartBit, Codes);
  82.     GenInst(M68op_OR, GetLocSZ(result), rightoperand, prev, Codes);
  83.     Genmove(M68sz_long, prev, result, Codes);
  84.     FreeTemp(prev);
  85.     } else {
  86.     Genmove(GetLocSZ(result), rightoperand, result, Codes);
  87.     }
  88.     FreeTemp(rightoperand);
  89.     return result;
  90. }
  91.  
  92. LabSYMVia_t                     LibLabelULMODT;
  93. LabSYMVia_t                     LibLabelLMODT;
  94. LabSYMVia_t                     LibLabelULMULT;
  95. LabSYMVia_t                     LibLabelULDIVT;
  96. LabSYMVia_t                     LibLabelLDIVT;
  97. LabSYMVia_t                     LibLabelXTOI;
  98.  
  99. void
  100. SetupLibLabels(void)
  101. {
  102.     LibLabelULMODT = MakeSysLabel("ULMODT");
  103.     LibLabelLMODT = MakeSysLabel("LMODT");
  104.     LibLabelULMULT = MakeSysLabel("ULMULT");
  105.     LibLabelULDIVT = MakeSysLabel("ULDIVT");
  106.     LibLabelLDIVT = MakeSysLabel("LDIVT");
  107.     LibLabelXTOI = MakeSysLabel("_XTOI");
  108. }
  109.  
  110. LocAMVia_t
  111. GenModAssign(ParseTreeVia_t left, ParseTreeVia_t right, InstListVia_t Codes)
  112. {
  113.     /* Integer only. */
  114.     LocAMVia_t                      leftop;
  115.     LocAMVia_t                      rightop;
  116.     LocAMVia_t                      lefttemp;
  117.     lefttemp = leftop = GenExpression(left, Codes);
  118.     rightop = GenExpression(right, Codes);
  119.     if (isUnsignedType(GetTreeTP(left))) {
  120.     if (GetTPSize(GetTreeTP(left)) > 2) {
  121.         /*
  122.          * All these various methods for handling long math should be
  123.          * better structured, and copied to all other places where this
  124.          * occurs.
  125.          */
  126.         if (!gProject->itsOptions->useMC68020) {
  127.         leftop = GenLibraryCall(leftop, rightop,
  128.                     LibLabelULMODT, Codes);
  129.         Genmove(M68_TypeSize(GetTreeTP(left)), leftop, lefttemp, Codes);
  130.         } else {
  131.         /*
  132.          * Currently we do long mod with libraries, even in 68020
  133.          * mode.  There must be a better way...
  134.          */
  135.         leftop = GenLibraryCall(leftop, rightop,
  136.                     LibLabelULMODT, Codes);
  137.         Genmove(M68_TypeSize(GetTreeTP(left)), leftop, lefttemp, Codes);
  138.         }
  139.     } else {
  140.         leftop = DictateTempDReg(leftop, Codes);
  141.         rightop = DictateTempDReg(rightop, Codes);
  142.         GenInst(M68op_DIVU, M68sz_none, rightop, leftop, Codes);
  143.         GenInst(M68op_SWAP, M68sz_none, leftop, NULL, Codes);
  144.         GenInst(M68op_EXT, M68sz_long, leftop, NULL, Codes);
  145.         Genmove(M68_TypeSize(GetTreeTP(left)), leftop, lefttemp, Codes);
  146.     }
  147.     } else {
  148.     if (GetTPSize(GetTreeTP(left)) > 2) {
  149.         if (!gProject->itsOptions->useMC68020) {
  150.         leftop = GenLibraryCall(leftop, rightop,
  151.                     LibLabelLMODT, Codes);
  152.         Genmove(M68_TypeSize(GetTreeTP(left)), leftop, lefttemp, Codes);
  153.         } else {
  154.         /*
  155.          * We currently do long mod with library even in 68020 mode.
  156.          */
  157.         leftop = GenLibraryCall(leftop, rightop,
  158.                     LibLabelLMODT, Codes);
  159.         Genmove(M68_TypeSize(GetTreeTP(left)), leftop, lefttemp, Codes);
  160.         }
  161.     } else {
  162.         leftop = DictateTempDReg(leftop, Codes);
  163.         rightop = DictateTempDReg(rightop, Codes);
  164.         GenInst(M68op_DIVS, M68sz_none, rightop, leftop, Codes);
  165.         GenInst(M68op_SWAP, M68sz_none, leftop, NULL, Codes);
  166.         GenInst(M68op_EXT, M68sz_long, leftop, NULL, Codes);
  167.         Genmove(M68_TypeSize(GetTreeTP(left)), leftop, lefttemp, Codes);
  168.     }
  169.     }
  170.     FreeTemp(rightop);
  171.     FreeTemp(leftop);
  172.     return lefttemp;
  173. }
  174.  
  175. LocAMVia_t
  176. GenMulDivAssign(Opcode_t OP, ParseTreeVia_t left, ParseTreeVia_t right, InstListVia_t Codes)
  177. {
  178.     LocAMVia_t                      leftop;
  179.     LocAMVia_t                      rightop;
  180.     LocAMVia_t                      lefttemp;
  181.     lefttemp = leftop = GenExpression(left, Codes);
  182.     rightop = GenExpression(right, Codes);
  183.     if (isFloatingType(GetTreeTP(left))) {
  184.     leftop = DictateTempFloat(leftop, Codes);
  185.     if (gProject->itsOptions->useMC68881) {
  186.         if (isShortFloatingType(GetTreeTP(left))) {
  187.         switch (OP) {
  188.         case M68op_MULS:
  189.             GenInst(M68op_FSGLMUL, M68sz_single, rightop, leftop, Codes);
  190.             break;
  191.         case M68op_DIVS:
  192.             GenInst(M68op_FSGLDIV, M68sz_single, rightop, leftop, Codes);
  193.             break;
  194.         }
  195.         } else {
  196.         switch (OP) {
  197.         case M68op_MULS:
  198.             GenInst(M68op_FMUL, GetLocSZ(rightop), rightop, leftop, Codes);
  199.             break;
  200.         case M68op_DIVS:
  201.             GenInst(M68op_FDIV, GetLocSZ(rightop), rightop, leftop, Codes);
  202.             break;
  203.         }
  204.         }
  205.         Genmove(GetLocSZ(lefttemp), leftop, lefttemp, Codes);
  206.     } else {
  207.         LocAMVia_t                      ftemp;
  208.         ftemp = TempFloatReg(Codes);
  209.         if (isShortFloatingType(GetTreeTP(left))) {
  210.         GenSANECall(FFSGL + FOZ2X, leftop, ftemp, Codes);
  211.         switch (OP) {
  212.         case M68op_MULS:
  213.             GenSANECall(FFSGL + FOMUL, rightop, ftemp, Codes);
  214.             break;
  215.         case M68op_DIVS:
  216.             GenSANECall(FFSGL + FODIV, rightop, ftemp, Codes);
  217.             break;
  218.         }
  219.         GenSANECall(FFSGL + FOX2Z, ftemp, leftop, Codes);
  220.         } else if (isExtendedFloatingType(GetTreeTP(left))) {
  221.         GenSANECall(FFEXT + FOZ2X, leftop, ftemp, Codes);
  222.         switch (OP) {
  223.         case M68op_MULS:
  224.             GenSANECall(FFEXT + FOMUL, rightop, ftemp, Codes);
  225.             break;
  226.         case M68op_DIVS:
  227.             GenSANECall(FFEXT + FODIV, rightop, ftemp, Codes);
  228.             break;
  229.         }
  230.         GenSANECall(FFEXT + FOX2Z, ftemp, leftop, Codes);
  231.         } else {
  232.         GenSANECall(FFDBL + FOZ2X, leftop, ftemp, Codes);
  233.         switch (OP) {
  234.         case M68op_MULS:
  235.             GenSANECall(FFDBL + FOMUL, rightop, ftemp, Codes);
  236.             break;
  237.         case M68op_DIVS:
  238.             GenSANECall(FFDBL + FODIV, rightop, ftemp, Codes);
  239.             break;
  240.         }
  241.         GenSANECall(FFDBL + FOX2Z, ftemp, leftop, Codes);
  242.         }
  243.         GenSANECall(FFEXT + FOZ2X, ftemp, lefttemp, Codes);
  244.     }
  245.     } else if (isBitFieldType(GetTreeTP(left))) {
  246.     unsigned long                   bitmask;
  247.     unsigned long                   mask2;
  248.     LocAMVia_t                      prev;
  249.     LocAMVia_t                      val2;
  250.     prev = TempDataReg(Codes);
  251.     Genmove(M68sz_long, leftop, prev, Codes);
  252.     /* Construct a mask, and AND immed */
  253.     bitmask = MakeMask(leftop);
  254.     mask2 = ~bitmask;
  255.     GenInst(M68op_AND, GetLocSZ(leftop),
  256.         BuildImmediate(bitmask, M68sz_long), prev, Codes);
  257.  
  258.     ShiftRight(prev, GetLocFieldBits(leftop).StartBit, Codes);
  259.     if (GetTPSize(GetTreeTP(right)) > 2) {
  260.         if (!gProject->itsOptions->useMC68020) {
  261.         switch (OP) {
  262.         case M68op_MULS:
  263.             prev = GenLibraryCall(prev, rightop,
  264.                       LibLabelULMULT, Codes);
  265.             break;
  266.         case M68op_DIVS:
  267.             prev = GenLibraryCall(prev, rightop,
  268.                       LibLabelULDIVT, Codes);
  269.             break;
  270.         }
  271.         } else {
  272.         switch (OP) {
  273.         case M68op_MULS:
  274.             GenInst(M68op_MULU, M68sz_long, rightop, prev, Codes);
  275.             break;
  276.         case M68op_DIVS:
  277.             GenInst(M68op_DIVU, M68sz_long, rightop, prev, Codes);
  278.             break;
  279.         }
  280.         }
  281.     }
  282.     ShiftLeft(prev, GetLocFieldBits(leftop).StartBit, Codes);
  283.     val2 = TempDataReg(Codes);
  284.     Genmove(M68sz_long, leftop, val2, Codes);
  285.     /* Construct a mask, and AND immed */
  286.     GenInst(M68op_AND, GetLocSZ(leftop),
  287.         BuildImmediate(mask2, M68sz_long), val2, Codes);
  288.     GenInst(M68op_OR, GetLocSZ(leftop), prev, val2, Codes);
  289.     Genmove(M68sz_long, val2, leftop, Codes);
  290.     FreeTemp(prev);
  291.     FreeTemp(val2);
  292.     } else if (isUnsignedType(GetTreeTP(left))) {
  293.     if (GetTPSize(GetTreeTP(left)) > 2) {
  294.         if (!gProject->itsOptions->useMC68020) {
  295.         switch (OP) {
  296.         case M68op_MULS:
  297.             leftop = GenLibraryCall(leftop, rightop,
  298.                         LibLabelULMULT, Codes);
  299.             break;
  300.         case M68op_DIVS:
  301.             leftop = GenLibraryCall(leftop, rightop,
  302.                         LibLabelULDIVT, Codes);
  303.             break;
  304.         }
  305.         Genmove(M68_TypeSize(GetTreeTP(left)), leftop, lefttemp, Codes);
  306.         } else {
  307.         leftop = DictateTempDReg(leftop, Codes);
  308.         rightop = DictateTempDReg(rightop, Codes);
  309.         switch (OP) {
  310.         case M68op_MULS:
  311.             GenInst(M68op_MULU, M68sz_long, rightop, leftop, Codes);
  312.             break;
  313.         case M68op_DIVS:
  314.             GenInst(M68op_DIVU, M68sz_long, rightop, leftop, Codes);
  315.             break;
  316.         }
  317.         Genmove(M68_TypeSize(GetTreeTP(left)), leftop, lefttemp, Codes);
  318.         }
  319.     } else {
  320.         leftop = DictateTempDReg(leftop, Codes);
  321.         rightop = DictateTempDReg(rightop, Codes);
  322.         switch (OP) {
  323.         case M68op_MULS:
  324.         GenInst(M68op_MULU, M68sz_none, rightop, leftop, Codes);
  325.         break;
  326.         case M68op_DIVS:
  327.         GenInst(M68op_DIVU, M68sz_none, rightop, leftop, Codes);
  328.         break;
  329.         }
  330.         Genmove(M68_TypeSize(GetTreeTP(left)), leftop, lefttemp, Codes);
  331.     }
  332.     } else {
  333.     if (GetTPSize(GetTreeTP(left)) > 2) {
  334.         if (!gProject->itsOptions->useMC68020) {
  335.         switch (OP) {
  336.         case M68op_MULS:
  337.             leftop = GenLibraryCall(leftop, rightop,
  338.                         LibLabelULMULT, Codes);
  339.             break;
  340.         case M68op_DIVS:
  341.             leftop = GenLibraryCall(leftop, rightop,
  342.                         LibLabelLDIVT, Codes);
  343.             break;
  344.         }
  345.         Genmove(M68_TypeSize(GetTreeTP(left)), leftop, lefttemp, Codes);
  346.         } else {
  347.         leftop = DictateTempDReg(leftop, Codes);
  348.         rightop = DictateTempDReg(rightop, Codes);
  349.         GenInst(OP, M68sz_long, rightop, leftop, Codes);
  350.         Genmove(M68_TypeSize(GetTreeTP(left)), leftop, lefttemp, Codes);
  351.         }
  352.     } else {
  353.         leftop = DictateTempDReg(leftop, Codes);
  354.         rightop = DictateTempDReg(rightop, Codes);
  355.         GenInst(OP, M68sz_none, rightop, leftop, Codes);
  356.         Genmove(M68_TypeSize(GetTreeTP(left)), leftop, lefttemp, Codes);
  357.     }
  358.     }
  359.     FreeTemp(rightop);
  360.     FreeTemp(leftop);
  361.     return lefttemp;
  362. }
  363.  
  364. LocAMVia_t
  365. GenOPAssignDREG(Opcode_t OP, ParseTreeVia_t left, ParseTreeVia_t right, InstListVia_t Codes)
  366. {
  367.     LocAMVia_t                      leftop;
  368.     LocAMVia_t                      lefttemp;
  369.     LocAMVia_t                      rightop;
  370.     /*
  371.      * This routine, used only for shifts and xor, should accomodate signed
  372.      * and unsigned in the same manner. Of course, floats are illegal here.
  373.      * Also, long and short operands should be handled the same here too. So,
  374.      * there is only one case.
  375.      */
  376.     lefttemp = leftop = GenExpression(left, Codes);
  377.     rightop = GenExpression(right, Codes);
  378.     if (GetLocAM(leftop) == M68am_ARegDisplaceFIELD) {
  379.     unsigned long                   bitmask;
  380.     unsigned long                   mask2;
  381.     LocAMVia_t                      prev;
  382.     LocAMVia_t                      val2;
  383.     prev = TempDataReg(Codes);
  384.     Genmove(M68sz_long, leftop, prev, Codes);
  385.     /* Construct a mask, and AND immed */
  386.     bitmask = MakeMask(leftop);
  387.     mask2 = ~bitmask;
  388.     GenInst(M68op_AND, GetLocSZ(leftop),
  389.         BuildImmediate(bitmask, M68sz_long), prev, Codes);
  390.  
  391.     ShiftRight(prev, GetLocFieldBits(leftop).StartBit, Codes);
  392.     GenInst(OP, GetLocSZ(leftop), rightop, prev, Codes);
  393.     ShiftLeft(prev, GetLocFieldBits(leftop).StartBit, Codes);
  394.     val2 = TempDataReg(Codes);
  395.     Genmove(M68sz_long, leftop, val2, Codes);
  396.     GenInst(M68op_AND, GetLocSZ(leftop),
  397.         BuildImmediate(mask2, M68sz_long), val2, Codes);
  398.     GenInst(M68op_OR, GetLocSZ(leftop), prev, val2, Codes);
  399.     Genmove(M68sz_long, val2, leftop, Codes);
  400.     FreeTemp(prev);
  401.     FreeTemp(val2);
  402.     } else {
  403.     leftop = DictateTempDReg(leftop, Codes);
  404.     rightop = DictateTempDReg(rightop, Codes);
  405.     GenInst(OP, M68_TypeSize(GetTreeTP(left)), rightop, leftop, Codes);
  406.     Genmove(M68_TypeSize(GetTreeTP(left)), leftop, lefttemp, Codes);
  407.     FreeTemp(leftop);
  408.     }
  409.     FreeTemp(rightop);
  410.     return lefttemp;
  411. }
  412.  
  413. LocAMVia_t
  414. GenOPAssign(Opcode_t OP, ParseTreeVia_t left, ParseTreeVia_t right, InstListVia_t Codes)
  415. {
  416.     LocAMVia_t                      leftop;
  417.     LocAMVia_t                      rightop;
  418.     if (isFloatingType(GetTreeTP(left))) {
  419.     leftop = GenExpression(left, Codes);
  420.     rightop = GenExpression(right, Codes);
  421.     rightop = DictateTempFloat(rightop, Codes);
  422.     if (gProject->itsOptions->useMC68881) {
  423.         switch (OP) {
  424.         case M68op_ADD:
  425.         GenInst(M68op_FADD, GetLocSZ(rightop), rightop, leftop, Codes);
  426.         break;
  427.         case M68op_SUB:
  428.         GenInst(M68op_FSUB, GetLocSZ(rightop), rightop, leftop, Codes);
  429.         break;
  430.         }
  431.     } else {
  432.         LocAMVia_t                      ftemp;
  433.         ftemp = TempFloatReg(Codes);
  434.         if (isShortFloatingType(GetTreeTP(left))) {
  435.         GenSANECall(FFSGL + FOZ2X, leftop, ftemp, Codes);
  436.         switch (OP) {
  437.         case M68op_ADD:
  438.             GenSANECall(FFSGL + FOADD, rightop, ftemp, Codes);
  439.             break;
  440.         case M68op_SUB:
  441.             GenSANECall(FFSGL + FOSUB, rightop, ftemp, Codes);
  442.             break;
  443.         }
  444.         GenSANECall(FFSGL + FOX2Z, ftemp, leftop, Codes);
  445.         } else if (isExtendedFloatingType(GetTreeTP(left))) {
  446.         GenSANECall(FFEXT + FOZ2X, leftop, ftemp, Codes);
  447.         switch (OP) {
  448.         case M68op_ADD:
  449.             GenSANECall(FFEXT + FOADD, rightop, ftemp, Codes);
  450.             break;
  451.         case M68op_SUB:
  452.             GenSANECall(FFEXT + FOSUB, rightop, ftemp, Codes);
  453.             break;
  454.         }
  455.         GenSANECall(FFEXT + FOX2Z, ftemp, leftop, Codes);
  456.         } else {
  457.         GenSANECall(FFDBL + FOZ2X, leftop, ftemp, Codes);
  458.         switch (OP) {
  459.         case M68op_ADD:
  460.             GenSANECall(FFDBL + FOADD, rightop, ftemp, Codes);
  461.             break;
  462.         case M68op_SUB:
  463.             GenSANECall(FFDBL + FOSUB, rightop, ftemp, Codes);
  464.             break;
  465.         }
  466.         GenSANECall(FFDBL + FOX2Z, ftemp, leftop, Codes);
  467.         }
  468.     }
  469.     } else {
  470.     /* signed/unsigned and long/short should be identical here. */
  471.     leftop = GenExpression(left, Codes);
  472.     rightop = GenExpression(right, Codes);
  473.     if (GetLocAM(leftop) == M68am_ARegDisplaceFIELD) {
  474.         unsigned long                   bitmask;
  475.         unsigned long                   mask2;
  476.         LocAMVia_t                      prev;
  477.         LocAMVia_t                      val2;
  478.         prev = TempDataReg(Codes);
  479.         Genmove(M68sz_long, leftop, prev, Codes);
  480.         /* Construct a mask, and AND immed */
  481.         bitmask = MakeMask(leftop);
  482.         mask2 = ~bitmask;
  483.         GenInst(M68op_AND, GetLocSZ(leftop),
  484.             BuildImmediate(bitmask, M68sz_long), prev, Codes);
  485.  
  486.         ShiftRight(prev, GetLocFieldBits(leftop).StartBit, Codes);
  487.         GenInst(OP, GetLocSZ(leftop), rightop, prev, Codes);
  488.         ShiftLeft(prev, GetLocFieldBits(leftop).StartBit, Codes);
  489.         val2 = TempDataReg(Codes);
  490.         Genmove(M68sz_long, leftop, val2, Codes);
  491.         /* Construct a mask, and AND immed */
  492.         GenInst(M68op_AND, GetLocSZ(leftop),
  493.             BuildImmediate(mask2, M68sz_long), val2, Codes);
  494.         GenInst(M68op_OR, GetLocSZ(leftop), prev, val2, Codes);
  495.         Genmove(M68sz_long, val2, leftop, Codes);
  496.         FreeTemp(prev);
  497.         FreeTemp(val2);
  498.     } else {
  499.         rightop = DictateTempDReg(rightop, Codes);
  500.         GenInst(OP, GetLocSZ(leftop), rightop, leftop, Codes);
  501.     }
  502.     }
  503.     FreeTemp(rightop);
  504.     return leftop;
  505. }
  506.  
  507. LocAMVia_t
  508. GenPreInc(ParseTreeVia_t expr, InstListVia_t Codes)
  509. {
  510.     LocAMVia_t                      object;
  511.     object = GenExpression(expr, Codes);
  512.     if (isPointerType(GetTreeTP(expr))) {
  513.     GenInst(M68op_ADD, M68_TypeSize(GetTreeTP(expr)),
  514.         BuildImmediate(GetTPSize(GetTPBase(GetTreeTP(expr))), GetTPSize(GetTreeTP(expr))), object, Codes);
  515.     } else if (isFloatingType(GetTreeTP(expr))) {
  516.     /*
  517.      * Generate an integer constant of 1, do a type convert (just like in
  518.      * CompareZero), and add it directly to object.
  519.      */
  520.     ParseTreeVia_t                  oneExpr;
  521.     LocAMVia_t                      oneLoc;
  522.     oneExpr = BuildTreeNode(PTF_intconstant, NULL, NULL, NULL);
  523.     SetTreeTP(oneExpr, BuildTypeRecord(0, TRC_int, SGN_signed));
  524.     Via(oneExpr)->data.number = 1;
  525.     oneExpr = TypeConvert(oneExpr, BuildTypeRecord(0, TRC_longdouble,
  526.                                SGN_unknown));
  527.     oneLoc = GenExpression(oneExpr, Codes);
  528.     FreeTree(oneExpr);
  529.     if (gProject->itsOptions->useMC68881) {
  530.         GenInst(M68op_FADD, GetLocSZ(object), oneLoc, object, Codes);
  531.     } else {
  532.         LocAMVia_t                      ftemp;
  533.         ftemp = TempFloatReg(Codes);
  534.         if (isExtendedFloatingType(GetTreeTP(expr))) {
  535.         GenSANECall(FFEXT + FOZ2X, object, ftemp, Codes);
  536.         GenSANECall(FFLNG + FOADD, oneLoc, ftemp, Codes);
  537.         GenSANECall(FFEXT + FOX2Z, ftemp, object, Codes);
  538.         } else if (isLongFloatingType(GetTreeTP(expr))) {
  539.         GenSANECall(FFDBL + FOZ2X, object, ftemp, Codes);
  540.         GenSANECall(FFLNG + FOADD, oneLoc, ftemp, Codes);
  541.         GenSANECall(FFDBL + FOX2Z, ftemp, object, Codes);
  542.         } else {
  543.         GenSANECall(FFSGL + FOZ2X, object, ftemp, Codes);
  544.         GenSANECall(FFLNG + FOADD, oneLoc, ftemp, Codes);
  545.         GenSANECall(FFSGL + FOX2Z, ftemp, object, Codes);
  546.         }
  547.     }
  548.     } else {
  549.     if (GetLocAM(object) == M68am_ARegDisplaceFIELD) {
  550.         unsigned long                   bitmask;
  551.         unsigned long                   mask2;
  552.         LocAMVia_t                      prev;
  553.         LocAMVia_t                      val2;
  554.         prev = TempDataReg(Codes);
  555.         Genmove(M68sz_long, object, prev, Codes);
  556.         /* Construct a mask, and AND immed */
  557.         bitmask = MakeMask(object);
  558.         mask2 = ~bitmask;
  559.         GenInst(M68op_AND, GetLocSZ(object),
  560.             BuildImmediate(bitmask, M68sz_long), prev, Codes);
  561.  
  562.         ShiftRight(prev, GetLocFieldBits(object).StartBit, Codes);
  563.         GenInst(M68op_ADDQ, GetTPSize(GetTreeTP(expr)),
  564.         BuildImmediate(1, GetTPSize(GetTreeTP(expr))), prev, Codes);
  565.         ShiftLeft(prev, GetLocFieldBits(object).StartBit, Codes);
  566.         val2 = TempDataReg(Codes);
  567.         Genmove(M68sz_long, object, val2, Codes);
  568.         GenInst(M68op_AND, GetLocSZ(object),
  569.             BuildImmediate(mask2, M68sz_long), val2, Codes);
  570.         GenInst(M68op_OR, GetLocSZ(object), prev, val2, Codes);
  571.         Genmove(M68sz_long, val2, object, Codes);
  572.         FreeTemp(prev);
  573.         FreeTemp(val2);
  574.     } else {
  575.         GenInst(M68op_ADDQ, GetTPSize(GetTreeTP(expr)),
  576.           BuildImmediate(1, GetTPSize(GetTreeTP(expr))), object, Codes);
  577.     }
  578.     }
  579.     return object;
  580. }
  581.  
  582. LocAMVia_t
  583. GenPreDec(ParseTreeVia_t expr, InstListVia_t Codes)
  584. {
  585.     LocAMVia_t                      object;
  586.     object = GenExpression(expr, Codes);
  587.     if (isPointerType(GetTreeTP(expr))) {
  588.     GenInst(M68op_SUB, GetTPSize(GetTreeTP(expr)),
  589.         BuildImmediate(GetTPSize(GetTPBase(GetTreeTP(expr))),
  590.                    GetTPSize(GetTreeTP(expr))), object, Codes);
  591.     } else if (isFloatingType(GetTreeTP(expr))) {
  592.     /*
  593.      * Generate an integer constant of 1, do a type convert (just like in
  594.      * CompareZero), and sub it directly to object.
  595.      */
  596.     ParseTreeVia_t                  oneExpr;
  597.     LocAMVia_t                      oneLoc;
  598.     oneExpr = BuildTreeNode(PTF_intconstant, NULL, NULL, NULL);
  599.     SetTreeTP(oneExpr, BuildTypeRecord(0, TRC_int, SGN_signed));
  600.     Via(oneExpr)->data.number = 1;
  601.     oneExpr = TypeConvert(oneExpr, BuildTypeRecord(0, TRC_longdouble,
  602.                                SGN_unknown));
  603.     oneLoc = GenExpression(oneExpr, Codes);
  604.     FreeTree(oneExpr);
  605.     if (gProject->itsOptions->useMC68881) {
  606.         GenInst(M68op_FSUB, GetLocSZ(object), oneLoc, object, Codes);
  607.     } else {
  608.         LocAMVia_t                      ftemp;
  609.         ftemp = TempFloatReg(Codes);
  610.         if (isExtendedFloatingType(GetTreeTP(expr))) {
  611.         GenSANECall(FFEXT + FOZ2X, object, ftemp, Codes);
  612.         GenSANECall(FFLNG + FOSUB, oneLoc, ftemp, Codes);
  613.         GenSANECall(FFEXT + FOX2Z, ftemp, object, Codes);
  614.         } else if (isLongFloatingType(GetTreeTP(expr))) {
  615.         GenSANECall(FFDBL + FOZ2X, object, ftemp, Codes);
  616.         GenSANECall(FFLNG + FOSUB, oneLoc, ftemp, Codes);
  617.         GenSANECall(FFDBL + FOX2Z, ftemp, object, Codes);
  618.         } else {
  619.         GenSANECall(FFSGL + FOZ2X, object, ftemp, Codes);
  620.         GenSANECall(FFLNG + FOSUB, oneLoc, ftemp, Codes);
  621.         GenSANECall(FFSGL + FOX2Z, ftemp, object, Codes);
  622.         }
  623.     }
  624.     } else {
  625.     if (GetLocAM(object) == M68am_ARegDisplaceFIELD) {
  626.         unsigned long                   bitmask;
  627.         unsigned long                   mask2;
  628.         LocAMVia_t                      prev;
  629.         LocAMVia_t                      val2;
  630.         prev = TempDataReg(Codes);
  631.         Genmove(M68sz_long, object, prev, Codes);
  632.         /* Construct a mask, and AND immed */
  633.         bitmask = MakeMask(object);
  634.         mask2 = ~bitmask;
  635.         GenInst(M68op_AND, GetLocSZ(object),
  636.             BuildImmediate(bitmask, M68sz_long), prev, Codes);
  637.  
  638.         ShiftRight(prev, GetLocFieldBits(object).StartBit, Codes);
  639.         GenInst(M68op_SUBQ, GetTPSize(GetTreeTP(expr)),
  640.         BuildImmediate(1, GetTPSize(GetTreeTP(expr))), prev, Codes);
  641.         ShiftLeft(prev, GetLocFieldBits(object).StartBit, Codes);
  642.         val2 = TempDataReg(Codes);
  643.         Genmove(M68sz_long, object, val2, Codes);
  644.         GenInst(M68op_AND, GetLocSZ(object),
  645.             BuildImmediate(mask2, M68sz_long), val2, Codes);
  646.         GenInst(M68op_OR, GetLocSZ(object), prev, val2, Codes);
  647.         Genmove(M68sz_long, val2, object, Codes);
  648.         FreeTemp(prev);
  649.         FreeTemp(val2);
  650.     } else {
  651.         GenInst(M68op_SUBQ, GetTPSize(GetTreeTP(expr)),
  652.           BuildImmediate(1, GetTPSize(GetTreeTP(expr))), object, Codes);
  653.     }
  654.     }
  655.     return object;
  656. }
  657.  
  658. LocAMVia_t
  659. GenPostInc(ParseTreeVia_t expr, InstListVia_t Codes)
  660. {
  661.     LocAMVia_t                      result;
  662.     LocAMVia_t                      object;
  663.     object = GenExpression(expr, Codes);
  664.     if (isPointerType(GetTreeTP(expr))) {
  665.     /*
  666.      * What we really care about with this call to Dictate... is that
  667.      * result is NOT the same mode as object.  We want to modify the
  668.      * object, but not the result.
  669.      */
  670.     result = TempAddrReg(Codes);
  671.     Genmove(M68sz_long, object, result, Codes);
  672.     GenInst(M68op_ADD, GetTPSize(GetTreeTP(expr)),
  673.         BuildImmediate(GetTPSize(GetTPBase(GetTreeTP(expr))),
  674.                    GetTPSize(GetTreeTP(expr))), object, Codes);
  675.     FreeTemp(object);
  676.     } else if (isFloatingType(GetTreeTP(expr))) {
  677.     /*
  678.      * Generate an integer constant of 1, do a type convert (just like in
  679.      * CompareZero), and add it to object after moving its pre value to a
  680.      * float reg.
  681.      */
  682.     ParseTreeVia_t                  oneExpr;
  683.     LocAMVia_t                      oneLoc;
  684.     result = TempFloatReg(Codes);
  685.     Genmove(GetLocSZ(object), object, result, Codes);
  686.     oneExpr = BuildTreeNode(PTF_intconstant, NULL, NULL, NULL);
  687.     SetTreeTP(oneExpr, BuildTypeRecord(0, TRC_int, SGN_signed));
  688.     Via(oneExpr)->data.number = 1;
  689.     oneExpr = TypeConvert(oneExpr, BuildTypeRecord(0, TRC_longdouble,
  690.                                SGN_unknown));
  691.     oneLoc = GenExpression(oneExpr, Codes);
  692.     FreeTree(oneExpr);
  693.     if (gProject->itsOptions->useMC68881) {
  694.         GenInst(M68op_FADD, GetLocSZ(object), oneLoc, object, Codes);
  695.     } else {
  696.         LocAMVia_t                      ftemp;
  697.         ftemp = TempFloatReg(Codes);
  698.         if (isExtendedFloatingType(GetTreeTP(expr))) {
  699.         GenSANECall(FFEXT + FOZ2X, object, ftemp, Codes);
  700.         GenSANECall(FFLNG + FOADD, oneLoc, ftemp, Codes);
  701.         GenSANECall(FFEXT + FOX2Z, ftemp, object, Codes);
  702.         } else if (isLongFloatingType(GetTreeTP(expr))) {
  703.         GenSANECall(FFDBL + FOZ2X, object, ftemp, Codes);
  704.         GenSANECall(FFLNG + FOADD, oneLoc, ftemp, Codes);
  705.         GenSANECall(FFDBL + FOX2Z, ftemp, object, Codes);
  706.         } else {
  707.         GenSANECall(FFSGL + FOZ2X, object, ftemp, Codes);
  708.         GenSANECall(FFLNG + FOADD, oneLoc, ftemp, Codes);
  709.         GenSANECall(FFSGL + FOX2Z, ftemp, object, Codes);
  710.         }
  711.     }
  712.     } else {
  713.     result = TempDataReg(Codes);
  714.     if (GetLocAM(object) == M68am_ARegDisplaceFIELD) {
  715.         unsigned long                   bitmask;
  716.         unsigned long                   mask2;
  717.         LocAMVia_t                      prev;
  718.         LocAMVia_t                      val2;
  719.         prev = TempDataReg(Codes);
  720.         Genmove(M68sz_long, object, prev, Codes);
  721.         /* Construct a mask, and AND immed */
  722.         bitmask = MakeMask(object);
  723.         mask2 = ~bitmask;
  724.         GenInst(M68op_AND, GetLocSZ(object),
  725.             BuildImmediate(bitmask, M68sz_long), prev, Codes);
  726.  
  727.         ShiftRight(prev, GetLocFieldBits(object).StartBit, Codes);
  728.         Genmove(GetLocSZ(object), prev, result, Codes);
  729.         GenInst(M68op_ADDQ, GetTPSize(GetTreeTP(expr)),
  730.         BuildImmediate(1, GetTPSize(GetTreeTP(expr))), prev, Codes);
  731.         ShiftLeft(prev, GetLocFieldBits(object).StartBit, Codes);
  732.         val2 = TempDataReg(Codes);
  733.         Genmove(M68sz_long, object, val2, Codes);
  734.         GenInst(M68op_AND, GetLocSZ(object),
  735.             BuildImmediate(mask2, M68sz_long), val2, Codes);
  736.         GenInst(M68op_OR, GetLocSZ(object), prev, val2, Codes);
  737.         Genmove(M68sz_long, val2, object, Codes);
  738.         FreeTemp(prev);
  739.         FreeTemp(val2);
  740.     } else {
  741.         Genmove(GetLocSZ(object), object, result, Codes);
  742.         GenInst(M68op_ADDQ, GetTPSize(GetTreeTP(expr)),
  743.           BuildImmediate(1, GetTPSize(GetTreeTP(expr))), object, Codes);
  744.     }
  745.     FreeTemp(object);
  746.     }
  747.     SetLocSZ(result, M68_TypeSize(GetTreeTP(expr)));
  748.     return result;
  749. }
  750.  
  751. LocAMVia_t
  752. GenPostDec(ParseTreeVia_t expr, InstListVia_t Codes)
  753. {
  754.     LocAMVia_t                      result;
  755.     LocAMVia_t                      object;
  756.     object = GenExpression(expr, Codes);
  757.     if (isPointerType(GetTreeTP(expr))) {
  758.     result = TempAddrReg(Codes);
  759.     Genmove(GetLocSZ(object), object, result, Codes);
  760.     GenInst(M68op_SUB, GetTPSize(GetTreeTP(expr)),
  761.         BuildImmediate(GetTPSize(GetTPBase(GetTreeTP(expr))),
  762.                    GetTPSize(GetTreeTP(expr))), object, Codes);
  763.     FreeTemp(object);
  764.     } else if (isFloatingType(GetTreeTP(expr))) {
  765.     /*
  766.      * Generate an integer constant of 1, do a type convert (just like in
  767.      * CompareZero), and sub it to object after moving its pre value to a
  768.      * float reg.
  769.      */
  770.     ParseTreeVia_t                  oneExpr;
  771.     LocAMVia_t                      oneLoc;
  772.     result = TempFloatReg(Codes);
  773.     Genmove(GetLocSZ(object), object, result, Codes);
  774.     oneExpr = BuildTreeNode(PTF_intconstant, NULL, NULL, NULL);
  775.     SetTreeTP(oneExpr, BuildTypeRecord(0, TRC_int, SGN_signed));
  776.     Via(oneExpr)->data.number = 1;
  777.     oneExpr = TypeConvert(oneExpr, BuildTypeRecord(0, TRC_longdouble,
  778.                                SGN_unknown));
  779.     oneLoc = GenExpression(oneExpr, Codes);
  780.     FreeTree(oneExpr);
  781.     if (gProject->itsOptions->useMC68881) {
  782.         GenInst(M68op_FSUB, GetLocSZ(object), oneLoc, object, Codes);
  783.     } else {
  784.         LocAMVia_t                      ftemp;
  785.         ftemp = TempFloatReg(Codes);
  786.         if (isExtendedFloatingType(GetTreeTP(expr))) {
  787.         assert(0);
  788.         GenSANECall(FFDBL + FOZ2X, object, ftemp, Codes);
  789.         GenSANECall(FFLNG + FOSUB, oneLoc, ftemp, Codes);
  790.         GenSANECall(FFEXT + FOX2Z, ftemp, object, Codes);
  791.         } else if (isLongFloatingType(GetTreeTP(expr))) {
  792.         GenSANECall(FFDBL + FOZ2X, object, ftemp, Codes);
  793.         GenSANECall(FFLNG + FOSUB, oneLoc, ftemp, Codes);
  794.         GenSANECall(FFDBL + FOX2Z, ftemp, object, Codes);
  795.         } else {
  796.         GenSANECall(FFSGL + FOZ2X, object, ftemp, Codes);
  797.         GenSANECall(FFLNG + FOSUB, oneLoc, ftemp, Codes);
  798.         GenSANECall(FFSGL + FOX2Z, ftemp, object, Codes);
  799.         }
  800.     }
  801.     } else {
  802.     result = TempDataReg(Codes);
  803.     if (GetLocAM(object) == M68am_ARegDisplaceFIELD) {
  804.         unsigned long                   bitmask;
  805.         unsigned long                   mask2;
  806.         LocAMVia_t                      prev;
  807.         LocAMVia_t                      val2;
  808.         prev = TempDataReg(Codes);
  809.         Genmove(M68sz_long, object, prev, Codes);
  810.         /* Construct a mask, and AND immed */
  811.         bitmask = MakeMask(object);
  812.         mask2 = ~bitmask;
  813.         GenInst(M68op_AND, GetLocSZ(object),
  814.             BuildImmediate(bitmask, M68sz_long), prev, Codes);
  815.  
  816.         ShiftRight(prev, GetLocFieldBits(object).StartBit, Codes);
  817.         Genmove(GetLocSZ(object), prev, result, Codes);
  818.         GenInst(M68op_SUBQ, GetTPSize(GetTreeTP(expr)),
  819.         BuildImmediate(1, GetTPSize(GetTreeTP(expr))), prev, Codes);
  820.         ShiftLeft(prev, GetLocFieldBits(object).StartBit, Codes);
  821.         val2 = TempDataReg(Codes);
  822.         Genmove(M68sz_long, object, val2, Codes);
  823.         GenInst(M68op_AND, GetLocSZ(object),
  824.             BuildImmediate(mask2, M68sz_long), val2, Codes);
  825.         GenInst(M68op_OR, GetLocSZ(object), prev, val2, Codes);
  826.         Genmove(M68sz_long, val2, object, Codes);
  827.         FreeTemp(prev);
  828.         FreeTemp(val2);
  829.     } else {
  830.         Genmove(GetLocSZ(object), object, result, Codes);
  831.         GenInst(M68op_SUBQ, GetTPSize(GetTreeTP(expr)),
  832.           BuildImmediate(1, GetTPSize(GetTreeTP(expr))), object, Codes);
  833.     }
  834.     FreeTemp(object);
  835.     }
  836.     SetLocSZ(result, M68_TypeSize(GetTreeTP(expr)));
  837.     return result;
  838. }
  839.