1 /* longop.c - software operations on longs for bcc */
3 /* Copyright (C) 1992 Bruce Evans */
12 /*-----------------------------------------------------------------------------
13 longop(operation code, source leaf, target leaf)
14 handles all binary operations on longs
15 source and target must already have been converted to long,
16 (except source is int for shifts) and not more than singly indirect
17 hence they must be direct (in an index reg paired with DREG),
18 or singly indirect (local, global, or from an index reg)
19 -----------------------------------------------------------------------------*/
21 PUBLIC
void longop(op
, source
, target
)
23 struct symstruct
*source
;
24 struct symstruct
*target
;
32 pushlist(reglist
= (regmark
= reguse
) & (OPREG
| OPWORKREG
));
36 scalar
= target
->type
->scalar
;
37 if ((op_t
) op
== SLOP
|| (op_t
) op
== SROP
)
40 scalar
|= source
->type
->scalar
;
41 if ((source
->indcount
== 0 && !shiftflag
) ||
42 source
->type
->scalar
& CHAR
||
43 source
->storage
& (BREG
| DREG
| OPREG
| OPWORKREG
))
45 pres2(source
, target
);
51 if (source
->storage
== CONSTANT
&& shiftflag
)
53 if (scalar
& UNSIGNED
)
54 target
->type
= ultype
;
55 if ((op_t
) op
== SLOP
)
56 source
->offset
.offv
= lslconst(source
->offset
.offv
,
59 source
->offset
.offv
= lsrconst(source
->offset
.offv
,
60 target
->storage
, scalar
& UNSIGNED
);
61 if (source
->offset
.offv
== 0)
65 /* This is ugly! But it works. I should be able to stop it being used
66 * by removing the char demotion. */
67 if (source
->type
->scalar
& CHAR
&&
68 !(source
->storage
& (BREG
|DREG
|DATREG1B
))) {
69 load(source
, DATREG1B
);
70 outop2str("xor\tch,ch"); outnl();
71 source
->storage
= DATREG1
;
74 load(source
, OPWORKREG
);
111 if (scalar
& UNSIGNED
)
114 target
->type
= ultype
;
119 if ((reguse
= regmark
) & OPREG
&& op
!= EQOP
)
120 load(target
, getindexreg());
125 changesp(spmark
, FALSE
);
133 /*-----------------------------------------------------------------------------
134 long1op(operation code, target leaf)
135 handles all unary operations on longs except inc/dec
136 target must be not more than singly indirect
137 hence it must be direct (in an index reg paired with DREG),
138 or singly indirect (local, global, or from an index reg)
139 -----------------------------------------------------------------------------*/
141 PUBLIC
void long1op(op
, target
)
143 struct symstruct
*target
;
145 pushlist(reguse
& OPREG
);
149 else if (op
== NEGOP
)
157 load(target
, getindexreg());
158 poplist(reguse
& OPREG
);
162 PUBLIC
void outlongendian()
167 #if DYNAMIC_LONG_ORDER
170 #if DYNAMIC_LONG_ORDER || LONG_BIG_ENDIAN
173 #if DYNAMIC_LONG_ORDER
176 #if DYNAMIC_LONG_ORDER || LONG_BIG_ENDIAN == 0