* added compilers lcc and bcc (linux86)
[mascara-docs.git] / compilers / linux86-0.16.17 / bcc / preserve.c
blob779efc2e04a544a2a40377a06ca8f977fd03aa9c
1 /* preserve.c - preserve opererands or registers in use for bcc */
3 /* Copyright (C) 1992 Bruce Evans */
5 #include "bcc.h"
6 #include "gencode.h"
7 #include "reg.h"
8 #include "type.h"
9 #include "scan.h"
11 /* change stack ptr without changing condition codes */
13 PUBLIC void changesp(newsp, absflag)
14 offset_T newsp;
15 bool_pt absflag;
17 if (newsp != sp || ((bool_t) absflag && switchnow != NULL))
19 #ifdef FRAMEPOINTER
20 if (newsp != framep || (!(bool_t) absflag && switchnow != NULL))
22 int off;
23 outleasp();
24 if (!(bool_t) absflag && switchnow != NULL)
25 outswoffset(off = newsp);
26 else
27 outoffset(off = newsp - framep);
28 #ifndef NO_DEL_PUSH
29 if (optimise && !callersaves && off < 0)
31 outstr("+");
32 outstr(funcname);
33 outstr(".off");
35 #endif
36 outindframereg();
37 outnl();
39 else
40 regtransfer(FRAMEREG, STACKREG);
41 sp = newsp;
42 if (framep == 0)
43 bugerror("no frame pointer");
44 #else
45 # ifdef I8088
46 outleasp();
47 outoffset(newsp - sp);
48 outindstackreg();
49 outnl();
50 # else
51 modstk(newsp); /* this should preserve CC */
52 # endif
53 #endif /* FRAMEPOINTER */
57 /* load source to any while preserving target */
59 PUBLIC void loadpres(source, target)
60 struct symstruct *source;
61 struct symstruct *target;
63 store_t regmark;
65 if (target->storage & ALLDATREGS)
67 if (source->type->scalar & CHAR)
69 push(target);
70 load(source, DREG);
72 else
73 load(source, getindexreg());
75 else
77 regmark = reguse;
78 reguse |= target->storage;
79 loadany(source);
80 reguse = regmark;
84 /* change stack ptr */
86 PUBLIC void modstk(newsp)
87 offset_T newsp;
89 if (newsp != sp)
91 #ifdef FRAMEPOINTER
92 if (newsp != framep || framep == 0 || switchnow != NULL)
93 addconst(newsp - sp, STACKREG);
94 else
95 regtransfer(FRAMEREG, STACKREG);
96 #else
97 # ifdef I8088
98 addconst(newsp - sp, STACKREG);
99 # else
100 outleasp();
101 outoffset(newsp - sp);
102 outncspregname();
103 # endif
104 #endif
105 sp = newsp;
109 /* preserve target without changing source */
111 PUBLIC void pres2(source, target)
112 struct symstruct *source;
113 struct symstruct *target;
115 if (target->storage & allregs)
117 if (target->storage & (allregs - allindregs) /* XXX */ ||
118 (target->indcount == 0 &&
119 target->type->scalar & (DLONG | RSCALAR)))
120 push(target); /* XXX - perhaps not float */
121 else if (((target->storage | reguse) & allindregs) == allindregs)
123 loadpres(target, source);
124 push(target);
126 else
127 reguse |= target->storage;
131 /* preserve source */
133 PUBLIC void preserve(source)
134 struct symstruct *source;
136 if (source->storage & allregs)
138 if (source->storage & (allregs - allindregs) /* XXX */ ||
139 ((source->storage | reguse) & allindregs) == allindregs)
140 push(source);
141 else
142 reguse |= source->storage;
146 /* preserve lvalue target without changing source or target */
148 PUBLIC store_pt preslval(source, target)
149 struct symstruct *source;
150 struct symstruct *target;
152 store_pt regpushed;
154 if (target->indcount == 0)
155 reguse &= ~target->storage;
156 else
157 reguse = (target->storage | reguse) & allindregs;
158 if (!((source->type->scalar | target->type->scalar) & (DLONG | RSCALAR))
159 || reguse != allindregs)
160 return 0; /* XXX - perhaps not float */
161 reguse = source->storage | target->storage; /* free one other than s/t */
162 pushreg(regpushed = getindexreg());
163 reguse = ~(store_t) regpushed & allindregs;
164 return regpushed;
167 PUBLIC void recovlist(reglist)
168 store_pt reglist;
170 poplist(reglist);
171 reguse |= (store_t) reglist;
174 #ifdef I8088
175 PRIVATE smalin_t regoffset[] = {0, 0, 0, 1, 2, 3, 0, 0, 0, 4, 5};
176 /* CONSTANT, BREG, ax = DREG, bx = INDREG0, si = INDREG1, di = INDREG2 */
177 /* LOCAL, GLOBAL, STACKREG, cx = DATREG1, dx = DATREG2 */
178 #endif
179 #ifdef MC6809
180 PRIVATE smalin_t regoffset[] = {0, 0, 0, 1, 3, 2};
181 /* CONSTANT, BREG, DREG, XREG = INDREG0, UREG = INDREG1, YREG = INDREG2 */
182 #endif
184 PUBLIC void savereturn(savelist, saveoffset)
185 store_pt savelist;
186 offset_T saveoffset;
188 store_t reg;
189 smalin_t *regoffptr;
190 offset_T spoffset;
192 if (savelist == 0)
193 return;
194 #ifdef MC6809 /* must check this */
195 if (savelist == XREG || savelist == INDREG1)
196 saveoffset -= accregsize; /* patch for DREG/YREG not saved */
197 #endif
198 for (reg = 1, regoffptr = regoffset; reg != 0; ++regoffptr, reg <<= 1)
199 if (reg & savelist)
201 outstore();
202 spoffset = saveoffset + *regoffptr * maxregsize;
203 #ifdef I8088
204 # ifdef FRAMEPOINTER
205 if (switchnow != NULL)
206 outswoffset(spoffset);
207 else
208 outoffset(spoffset - framep);
209 outindframereg();
210 # else
211 outoffset(spoffset - sp);
212 outindstackreg();
213 # endif
214 outncregname(reg);
215 #endif
216 #ifdef MC6809
217 if (reg == YREG)
218 bumplc();
219 outregname(reg);
220 outtab();
221 outoffset(spoffset - sp);
222 outncspregname();
223 #endif