home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Tools / Languages / Harvest C 1.3 / Source Code / LocAM.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-06-15  |  12.1 KB  |  604 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 implements operations on LocAM records.
  35.  * 
  36.  */
  37.  
  38. #include "conditcomp.h"
  39. #include <stdio.h>
  40. #include <string.h>
  41. #include "structs.h"
  42.  
  43.  
  44. #pragma segment LocAM
  45.  
  46. #include "CodeGen.h"
  47.  
  48. static LocAMVia_t               LocPile;
  49. static LocAMVia_t               StorageLocPile;
  50.  
  51. struct LocAM_S {
  52.     enum AddressingMode68           AM;
  53.     enum OperandState68             status;
  54. #ifdef INLINEASM
  55.     struct ea P__H                 *OtherFormat;
  56. #endif
  57.     SpillSlotVia_t                  slot;
  58.     struct TwoShorts                FieldBits;
  59.     enum Size68                     SZ;
  60.     char                            AReg;
  61.     char                            DReg;
  62.     char                            FReg;    /* Are all three of these reg
  63.                          * number fields necessary ? */
  64.     char                            isFLOAT;
  65.     unsigned long                   Constant;    /* Is there any instance
  66.                          * wherein the Label AND the
  67.                          * Constant are both used ? */
  68.     LabSYMVia_t                     Label;
  69.     LocAMVia_t                      next;
  70. };
  71.  
  72. LocAMVia_t
  73. RawLocation(void)
  74. {
  75.     LocAMVia_t                      raw;
  76.     raw = Ealloc(sizeof(LocAM_t));
  77.     Via(raw)->AM = 0;
  78.     Via(raw)->status = M68os_valid;
  79. #ifdef INLINEASM
  80.     Via(raw)->OtherFormat = NULL;
  81. #endif
  82.     Via(raw)->DReg = NOREG68;
  83.     Via(raw)->AReg = NOREG68;
  84.     Via(raw)->FReg = NOREG68;
  85.     Via(raw)->isFLOAT = 0;
  86.     Via(raw)->SZ = M68sz_none;
  87.     Via(raw)->slot = NULL;
  88.     Via(raw)->Constant = 0;
  89.     Via(raw)->Label = NULL;
  90.     Via(raw)->next = LocPile;
  91.     LocPile = raw;
  92.     return raw;
  93. }
  94.  
  95. enum AddressingMode68
  96. GetLocAM(LocAMVia_t loc)
  97. {
  98.     assert(loc);
  99.     return Via(loc)->AM;
  100. }
  101.  
  102. int
  103. isConstantLoc(LocAMVia_t loc)
  104. {
  105.     if (Via(loc)->AM == M68am_Immediate) return 1;
  106.     return 0;
  107. }
  108.  
  109. enum Size68
  110. GetLocSZ(LocAMVia_t loc)
  111. {
  112.     assert(loc);
  113.     return Via(loc)->SZ;
  114. }
  115.  
  116. enum OperandState68
  117. GetLocStatus(LocAMVia_t loc)
  118. {
  119.     assert(loc);
  120.     return Via(loc)->status;
  121. }
  122.  
  123. void
  124. SetLocStatus(LocAMVia_t loc, enum OperandState68 s)
  125. {
  126.     assert(loc);
  127.     Via(loc)->status = s;
  128. }
  129.  
  130. SpillSlotVia_t
  131. GetLocSlot(LocAMVia_t loc)
  132. {
  133.     assert(loc);
  134.     return Via(loc)->slot;
  135. }
  136.  
  137. void
  138. SetLocSlot(LocAMVia_t loc, SpillSlotVia_t s)
  139. {
  140.     assert(loc);
  141.     Via(loc)->slot = s;
  142. }
  143.  
  144. char
  145. GetLocAReg(LocAMVia_t loc)
  146. {
  147.     assert(loc);
  148.     return Via(loc)->AReg;
  149. }
  150.  
  151. void
  152. SetLocAReg(LocAMVia_t loc, char a)
  153. {
  154.     assert(loc);
  155.     Via(loc)->AReg = a;
  156. }
  157.  
  158. char
  159. GetLocDReg(LocAMVia_t loc)
  160. {
  161.     assert(loc);
  162.     return Via(loc)->DReg;
  163. }
  164.  
  165. char
  166. GetLocFReg(LocAMVia_t loc)
  167. {
  168.     assert(loc);
  169.     return Via(loc)->FReg;
  170. }
  171.  
  172. LabSYMVia_t
  173. GetLocLabel(LocAMVia_t loc)
  174. {
  175.     assert(loc);
  176.     return Via(loc)->Label;
  177. }
  178.  
  179. unsigned long
  180. GetLocConstant(LocAMVia_t loc)
  181. {
  182.     assert(loc);
  183.     return Via(loc)->Constant;
  184. }
  185.  
  186. void
  187. SetLocConstant(LocAMVia_t loc, unsigned long c)
  188. {
  189.     assert(loc);
  190.     Via(loc)->Constant = c;
  191. }
  192.  
  193. int
  194. LocIsFloat(LocAMVia_t loc)
  195. {
  196.     assert(loc);
  197.     return Via(loc)->isFLOAT;
  198. }
  199.  
  200. void
  201. SetLocIsFloat(LocAMVia_t loc, int val)
  202. {
  203.     assert(loc);
  204.     Via(loc)->isFLOAT = val;
  205. }
  206.  
  207.  
  208. struct TwoShorts
  209. GetLocFieldBits(LocAMVia_t loc)
  210. {
  211.     assert(loc);
  212.     return Via(loc)->FieldBits;
  213. }
  214.  
  215. void
  216. SetLocAM(LocAMVia_t loc, enum AddressingMode68 AM)
  217. {
  218.     assert(loc);
  219.     Via(loc)->AM = AM;
  220. }
  221.  
  222. void
  223. SetLocSZ(LocAMVia_t loc, enum Size68 SZ)
  224. {
  225.     assert(loc);
  226.     Via(loc)->SZ = SZ;
  227. }
  228.  
  229. int
  230. SameLocation(LocAMVia_t a, LocAMVia_t b)
  231. {
  232.     /* Compares two locations */
  233.     /* If the AM, [DAF]Reg, SZ, Constant, and Label all match... */
  234.     if (!(a && b)) {
  235.     return 0;
  236.     }
  237.     if (a == b)
  238.     return 1;
  239.  
  240.     if (Via(a)->AM != Via(b)->AM) {
  241.     return 0;
  242.     }
  243.     switch (Via(a)->AM) {
  244.     case M68am_DReg:
  245.     if (Via(a)->DReg == Via(b)->DReg) {
  246.         return 1;
  247.     } else {
  248.         return 0;
  249.     }
  250.     break;
  251.     case M68am_Label:
  252.     if (Via(a)->Label == Via(b)->Label) {
  253.         return 1;
  254.     } else {
  255.         return 0;
  256.     }
  257.     break;
  258.     default:            /* Some AReg mode... */
  259.     if (Via(a)->AReg == Via(b)->AReg) {
  260.         if (Via(a)->Constant == Via(b)->Constant) {
  261.         return 1;
  262.         } else {
  263.         return 0;
  264.         }
  265.     } else {
  266.         return 0;
  267.     }
  268.     break;
  269.     }
  270.     return 0;
  271. }
  272.  
  273. /* Location builders */
  274.  
  275. LocAMVia_t
  276. BuildFRegLocation(int reg)
  277. {
  278.     LocAMVia_t                      result;
  279.     result = NULL;
  280.     if (reg >= 0 && reg <= 7) {
  281.     result = RawLocation();
  282.     Via(result)->AM = M68am_FReg;
  283.     Via(result)->SZ = M68sz_double;
  284.     Via(result)->FReg = reg;
  285.     Via(result)->status = M68os_valid;
  286.     } else {
  287.     Gen68Error("Illegal register number for Freg");
  288.     }
  289.     return result;
  290. }
  291.  
  292. LocAMVia_t
  293. BuildDRegLocation(int reg)
  294. {
  295.     LocAMVia_t                      result;
  296.     result = NULL;
  297.     if (reg >= 0 && reg <= 7) {
  298.     result = RawLocation();
  299.     Via(result)->AM = M68am_DReg;
  300.     Via(result)->DReg = reg;
  301.     Via(result)->status = M68os_valid;
  302.     } else {
  303.     Gen68Error("Illegal register number for Dreg");
  304.     }
  305.     return result;
  306. }
  307.  
  308. LocAMVia_t
  309. BuildAbsolute(long constant)
  310. {
  311.     LocAMVia_t                      result;
  312.     result = RawLocation();
  313.     Via(result)->AM = M68am_AbsLong;
  314.     Via(result)->Constant = constant;
  315.     Via(result)->SZ = M68sz_none;
  316.     return result;
  317. }
  318.  
  319. LocAMVia_t
  320. BuildImmediate(int constant, enum Size68 SZ)
  321. {
  322.     LocAMVia_t                      result;
  323.     result = RawLocation();
  324.     Via(result)->AM = M68am_Immediate;
  325.     Via(result)->Constant = constant;
  326.     Via(result)->SZ = SZ;
  327.     return result;
  328. }
  329.  
  330. LocAMVia_t
  331. BuildLargeGlobal(LabSYMVia_t displ)
  332. {
  333.     LocAMVia_t                      result;
  334.     result = RawLocation();
  335.     Via(result)->AM = M68am_LargeGlobal;
  336.     Via(result)->Label = displ;
  337.     Via(result)->status = M68os_valid;    /* irrelevant */
  338.     return result;
  339. }
  340.  
  341. LocAMVia_t
  342. BuildARegLabelDisplace(int reg, LabSYMVia_t displ)
  343. {
  344.     LocAMVia_t                      result;
  345.     result = NULL;
  346.     if (reg >= 0 && reg <= 7) {
  347.     result = RawLocation();
  348.     Via(result)->AM = M68am_ARegLabelDisplace;
  349.     Via(result)->Label = displ;
  350.     Via(result)->AReg = reg;
  351.     Via(result)->status = M68os_valid;
  352.     } else {
  353.     Gen68Error("Illegal register number for Areg");
  354.     }
  355.     return result;
  356. }
  357.  
  358. LocAMVia_t
  359. BuildARegDisplaceField(int reg, int displ, struct TwoShorts bits)
  360. {
  361.     LocAMVia_t                      result;
  362.     result = NULL;
  363.     if (reg >= 0 && reg <= 7) {
  364.     result = RawLocation();
  365.     Via(result)->AM = M68am_ARegDisplaceFIELD;
  366.     Via(result)->Constant = displ;
  367.     Via(result)->FieldBits = bits;
  368.     Via(result)->AReg = reg;
  369.     Via(result)->status = M68os_valid;
  370.     } else {
  371.     Gen68Error("Illegal register number for Areg");
  372.     }
  373.     return result;
  374. }
  375.  
  376. LocAMVia_t
  377. BuildARegDisplace(int reg, int displ)
  378. {
  379.     LocAMVia_t                      result;
  380.     result = NULL;
  381.     if (reg >= 0 && reg <= 7) {
  382.     result = RawLocation();
  383.     Via(result)->AM = M68am_ARegDisplace;
  384.     Via(result)->Constant = displ;
  385.     Via(result)->AReg = reg;
  386.     Via(result)->status = M68os_valid;
  387.     } else {
  388.     Gen68Error("Illegal register number for Areg");
  389.     }
  390.     return result;
  391. }
  392.  
  393. LocAMVia_t
  394. BuildARegPreDec(int reg)
  395. {
  396.     LocAMVia_t                      result;
  397.     result = NULL;
  398.     if (reg >= 0 && reg <= 7) {
  399.     result = RawLocation();
  400.     Via(result)->AM = M68am_ARegPreDec;
  401.     Via(result)->AReg = reg;
  402.     Via(result)->status = M68os_valid;
  403.     } else {
  404.     Gen68Error("Illegal register number for Areg");
  405.     }
  406.     return result;
  407. }
  408.  
  409. LocAMVia_t
  410. BuildARegPostInc(int reg)
  411. {
  412.     LocAMVia_t                      result;
  413.     result = NULL;
  414.     if (reg >= 0 && reg <= 7) {
  415.     result = RawLocation();
  416.     Via(result)->AM = M68am_ARegPostInc;
  417.     Via(result)->AReg = reg;
  418.     Via(result)->status = M68os_valid;
  419.     } else {
  420.     Gen68Error("Illegal register number for Areg");
  421.     }
  422.     return result;
  423. }
  424.  
  425. LocAMVia_t
  426. BuildARegIndirect(int reg)
  427. {
  428.     LocAMVia_t                      result;
  429.     result = NULL;
  430.     if (reg >= 0 && reg <= 7) {
  431.     result = RawLocation();
  432.     Via(result)->AM = M68am_ARegIndirect;
  433.     Via(result)->AReg = reg;
  434.     Via(result)->status = M68os_valid;
  435.     } else {
  436.     Gen68Error("Illegal register number for Areg");
  437.     }
  438.     return result;
  439. }
  440.  
  441. LocAMVia_t
  442. BuildARegDirect(int reg)
  443. {
  444.     LocAMVia_t                      result;
  445.     result = NULL;
  446.     if (reg >= 0 && reg <= 7) {
  447.     result = RawLocation();
  448.     Via(result)->AM = M68am_ARegDirect;
  449.     Via(result)->AReg = reg;
  450.     Via(result)->status = M68os_valid;
  451.     Via(result)->SZ = M68sz_long;    /* A default, since all pointers are
  452.                      * 4 bytes. */
  453.     } else {
  454.     Gen68Error("Illegal register number for Areg");
  455.     }
  456.     return result;
  457. }
  458.  
  459. LocAMVia_t
  460. BuildAutoLoc(int offset, int size)
  461. /*
  462.  * Builds a location record addressing an offset from the frame pointer,
  463.  * specified by the offset given.
  464.  */
  465. {
  466.     LocAMVia_t                      result;
  467.     result = NULL;
  468.     result = RawLocation();
  469.     Via(result)->AM = M68am_ARegDisplace;
  470.     Via(result)->AReg = FRAME;
  471.     Via(result)->Constant = offset;
  472.     Via(result)->SZ = size;
  473.     return result;
  474. }
  475.  
  476. LocAMVia_t
  477. BuildPCLabelDisplace(LabSYMVia_t name)
  478. {
  479.     LocAMVia_t                      result;
  480.     result = RawLocation();
  481.     Via(result)->AM = M68am_PCLabelDisplace;
  482.     Via(result)->SZ = M68sz_long;
  483.     Via(result)->Label = name;
  484.     return result;
  485. }
  486.  
  487. LocAMVia_t
  488. BuildImmedLabelLoc(LabSYMVia_t name)
  489. /*
  490.  * Given a label record, builds a location record referencing that label as
  491.  * an immediate, and returns it. Generally this loc references a string
  492.  * literal.
  493.  */
  494. {
  495.     LocAMVia_t                      result;
  496.     result = RawLocation();
  497.     Via(result)->AM = M68am_Immediate;
  498.     Via(result)->SZ = M68sz_long;
  499.     Via(result)->Label = name;
  500.     return result;
  501. }
  502.  
  503. LocAMVia_t
  504. BuildLabelOffset(LabSYMVia_t name, long c)
  505. /*
  506.  * Given a label record, builds a location record referencing that label as
  507.  * an address.  Possibly dangerous for the Mac version.
  508.  */
  509. {
  510.     LocAMVia_t                      result;
  511.     result = RawLocation();
  512.     Via(result)->AM = M68am_LabelOffset;
  513.     Via(result)->Label = name;
  514.     Via(result)->Constant = c;
  515.     return result;
  516. }
  517.  
  518. LocAMVia_t
  519. BuildLabelLoc(LabSYMVia_t name)
  520. /*
  521.  * Given a label record, builds a location record referencing that label as
  522.  * an address.  Possibly dangerous for the Mac version.
  523.  */
  524. {
  525.     LocAMVia_t                      result;
  526.     result = RawLocation();
  527.     Via(result)->AM = M68am_Label;
  528.     Via(result)->Label = name;
  529.     return result;
  530. }
  531.  
  532. void
  533. KillLocation(LocAMVia_t loc)
  534. {
  535.     if (loc) {
  536. #ifdef INLINEASM
  537.     if (Via(loc)->OtherFormat)
  538.         Efree(Via(loc)->OtherFormat);
  539. #endif
  540.     Efree(loc);
  541.     }
  542. }
  543.  
  544. void
  545. KillSomeLocations(void)
  546. {
  547.     LocAMVia_t                      cur;
  548.     LocAMVia_t                      nxt;
  549.     cur = LocPile;
  550.     while (cur) {
  551.     nxt = Via(cur)->next;
  552.     KillLocation(cur);
  553.     cur = nxt;
  554.     }
  555.     LocPile = NULL;
  556. }
  557.  
  558. static void
  559. KillGlobalLocations(void)
  560. {
  561.     LocAMVia_t                      cur;
  562.     LocAMVia_t                      nxt;
  563.     cur = StorageLocPile;
  564.     while (cur) {
  565.     nxt = Via(cur)->next;
  566.     KillLocation(cur);
  567.     cur = nxt;
  568.     }
  569.     StorageLocPile = NULL;
  570. }
  571.  
  572. void
  573. KillAllLocations(void)
  574. {
  575.     KillSomeLocations();
  576.     KillGlobalLocations();
  577. }
  578.  
  579. void
  580. InitLocAM(void)
  581. {
  582.     LocPile = NULL;
  583.     StorageLocPile = NULL;
  584. }
  585.  
  586. void
  587. MakeLocGlobal(LocAMVia_t loc)
  588. {
  589.     /* Move loc from LocPile to StorageLocPile */
  590.     LocAMVia_t                      tmp, prev = NULL;
  591.     tmp = LocPile;
  592.     while (tmp != LocPile) {
  593.     prev = tmp;
  594.     tmp = Via(tmp)->next;
  595.     }
  596.     if (prev) {
  597.     Via(prev)->next = Via(tmp)->next;
  598.     } else {
  599.     LocPile = Via(LocPile)->next;
  600.     }
  601.     Via(tmp)->next = StorageLocPile;
  602.     StorageLocPile = tmp;
  603. }
  604.