Pristine Ack-5.5
[Ack-5.5.git] / lang / pc / comp / tmpvar.C
1 /* T E M P O R A R Y   V A R I A B L E S */
2
3 /*      Code for the allocation and de-allocation of temporary variables,
4         allowing re-use.
5         The routines use "ProcScope" instead of "CurrentScope", because
6         "CurrentScope" also reflects WITH statements, and these scopes do not
7         have local variables.
8 */
9
10 #include        "debug.h"
11
12 #include        <alloc.h>
13 #include        <em_arith.h>
14 #include        <em_label.h>
15 #include        <em_reg.h>
16
17 #include        "def.h"
18 #include        "main.h"
19 #include        "scope.h"
20 #include        "type.h"
21
22 struct tmpvar   {
23         struct tmpvar   *next;
24         arith           t_offset;       /* offset from LocalBase */
25 };
26
27 /* ALLOCDEF "tmpvar" 10 */
28
29 static struct tmpvar    *TmpInts,       /* for integer temporaries */
30                         *TmpPtrs;       /* for pointer temporaries */
31 static struct scope     *ProcScope;     /* scope of procedure in which the
32                                            temporaries are allocated
33                                         */
34
35 TmpOpen(sc)
36         struct scope *sc;
37 {
38         /*      Initialize for temporaries in scope "sc".
39         */
40         ProcScope = sc;
41 }
42
43 arith
44 TmpSpace(sz, al)
45         arith sz;
46 {
47         register struct scope *sc = ProcScope;
48
49         sc->sc_off = - WA(align(sz - sc->sc_off, al));
50         return sc->sc_off;
51 }
52
53 STATIC arith
54 NewTmp(plist, sz, al, regtype, priority)
55         struct tmpvar **plist;
56         arith sz;
57 {
58         register arith offset;
59         register struct tmpvar *tmp;
60
61         if( !*plist )   {
62                 offset = TmpSpace(sz, al);
63                 if( !options['n'] ) C_ms_reg(offset, sz, regtype, priority);
64         }
65         else    {
66                 tmp = *plist;
67                 offset = tmp->t_offset;
68                 *plist = tmp->next;
69                 free_tmpvar(tmp);
70         }
71         return offset;
72 }
73
74 arith
75 NewInt(reg_prior)
76 {
77         return NewTmp(&TmpInts, int_size, int_align, reg_any, reg_prior);
78 }
79
80 arith
81 NewPtr(reg_prior)
82 {
83    return NewTmp(&TmpPtrs, pointer_size, pointer_align, reg_pointer, reg_prior);
84 }
85
86 STATIC
87 FreeTmp(plist, off)
88         struct tmpvar **plist;
89         arith off;
90 {
91         register struct tmpvar *tmp = new_tmpvar();
92
93         tmp->next = *plist;
94         tmp->t_offset = off;
95         *plist = tmp;
96 }
97
98 FreeInt(off)
99         arith off;
100 {
101         FreeTmp(&TmpInts, off);
102 }
103
104 FreePtr(off)
105         arith off;
106 {
107         FreeTmp(&TmpPtrs, off);
108 }
109
110 TmpClose()
111 {
112         register struct tmpvar *tmp, *tmp1;
113
114         tmp = TmpInts;
115         while( tmp )    {
116                 tmp1 = tmp;
117                 tmp = tmp->next;
118                 free_tmpvar(tmp1);
119         }
120         tmp = TmpPtrs;
121         while( tmp )    {
122                 tmp1 = tmp;
123                 tmp = tmp->next;
124                 free_tmpvar(tmp1);
125         }
126         TmpInts = TmpPtrs = 0;
127 }