1 /* preserve.c - preserve opererands or registers in use for bcc */
3 /* Copyright (C) 1992 Bruce Evans */
11 /* change stack ptr without changing condition codes */
13 PUBLIC
void changesp(newsp
, absflag
)
17 if (newsp
!= sp
|| ((bool_t
) absflag
&& switchnow
!= NULL
))
20 if (newsp
!= framep
|| (!(bool_t
) absflag
&& switchnow
!= NULL
))
24 if (!(bool_t
) absflag
&& switchnow
!= NULL
)
25 outswoffset(off
= newsp
);
27 outoffset(off
= newsp
- framep
);
29 if (optimise
&& !callersaves
&& off
< 0)
40 regtransfer(FRAMEREG
, STACKREG
);
43 bugerror("no frame pointer");
47 outoffset(newsp
- sp
);
51 modstk(newsp
); /* this should preserve CC */
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
;
65 if (target
->storage
& ALLDATREGS
)
67 if (source
->type
->scalar
& CHAR
)
73 load(source
, getindexreg());
78 reguse
|= target
->storage
;
84 /* change stack ptr */
86 PUBLIC
void modstk(newsp
)
92 if (newsp
!= framep
|| framep
== 0 || switchnow
!= NULL
)
93 addconst(newsp
- sp
, STACKREG
);
95 regtransfer(FRAMEREG
, STACKREG
);
98 addconst(newsp
- sp
, STACKREG
);
101 outoffset(newsp
- sp
);
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
);
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
)
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
;
154 if (target
->indcount
== 0)
155 reguse
&= ~target
->storage
;
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
;
167 PUBLIC
void recovlist(reglist
)
171 reguse
|= (store_t
) reglist
;
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 */
180 PRIVATE smalin_t regoffset
[] = {0, 0, 0, 1, 3, 2};
181 /* CONSTANT, BREG, DREG, XREG = INDREG0, UREG = INDREG1, YREG = INDREG2 */
184 PUBLIC
void savereturn(savelist
, saveoffset
)
194 #ifdef MC6809 /* must check this */
195 if (savelist
== XREG
|| savelist
== INDREG1
)
196 saveoffset
-= accregsize
; /* patch for DREG/YREG not saved */
198 for (reg
= 1, regoffptr
= regoffset
; reg
!= 0; ++regoffptr
, reg
<<= 1)
202 spoffset
= saveoffset
+ *regoffptr
* maxregsize
;
205 if (switchnow
!= NULL
)
206 outswoffset(spoffset
);
208 outoffset(spoffset
- framep
);
211 outoffset(spoffset
- sp
);
221 outoffset(spoffset
- sp
);