3 Copyright (c) 1998-2000 by Florian Klaempfl
5 Type checking and register allocation for add node
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program 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.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 ****************************************************************************
29 procedure firstadd(var p
: ptree
);
30 function isbinaryoverloaded(var p
: ptree
) : boolean;
36 globtype
,systems
,tokens
,
37 cobjects
,verbose
,globals
,
38 symconst
,symtable
,aasm
,types
,
48 function isbinaryoverloaded(var p
: ptree
) : boolean;
56 isbinaryoverloaded
:=false;
57 { overloaded operator ? }
58 { load easier access variables }
59 rd
:=p
^.right
^.resulttype
;
60 ld
:=p
^.left
^.resulttype
;
61 if isbinaryoperatoroverloadable(ld
,rd
,voiddef
,p
^.treetype
) then
63 isbinaryoverloaded
:=true;
64 {!!!!!!!!! handle paras }
66 { the nil as symtable signs firstcalln that this is
67 an overloaded operator }
107 t
:=gencallnode(overloaded_operators
[optoken
],nil);
108 { we have to convert p^.left and p^.right into
110 if t
^.symtableprocentry
=nil then
112 CGMessage(parser_e_operator_not_overloaded
);
117 inc(t
^.symtableprocentry
^.refs
);
118 t
^.left
:=gencallparanode(p
^.left
,nil);
119 t
^.left
:=gencallparanode(p
^.right
,t
^.left
);
120 if p
^.treetype
=unequaln
then
121 t
:=gensinglenode(notn
,t
);
129 {*****************************************************************************
131 *****************************************************************************}
137 procedure firstadd(var p
: ptree
);
139 procedure make_bool_equal_size(var p
:ptree
);
141 if porddef(p
^.left
^.resulttype
)^.typ
>porddef(p
^.right
^.resulttype
)^.typ
then
143 p
^.right
:=gentypeconvnode(p
^.right
,porddef(p
^.left
^.resulttype
));
144 p
^.right
^.convtyp
:=tc_bool_2_int
;
145 p
^.right
^.explizit
:=true;
149 if porddef(p
^.left
^.resulttype
)^.typ
<porddef(p
^.right
^.resulttype
)^.typ
then
151 p
^.left
:=gentypeconvnode(p
^.left
,porddef(p
^.right
^.resulttype
));
152 p
^.left
^.convtyp
:=tc_bool_2_int
;
153 p
^.left
^.explizit
:=true;
167 concatstrings
: boolean;
169 { to evalute const sets }
170 resultset
: pconstset
;
178 { first do the two subtrees }
184 { convert array constructors to sets, because there is no other operator
185 possible for array constructors }
186 if is_array_constructor(p
^.left
^.resulttype
) then
188 arrayconstructor_to_set(p
^.left
);
191 if is_array_constructor(p
^.right
^.resulttype
) then
193 arrayconstructor_to_set(p
^.right
);
196 { both left and right need to be valid }
197 set_varstate(p
^.left
,true);
198 set_varstate(p
^.right
,true);
200 { load easier access variables }
201 lt
:=p
^.left
^.treetype
;
202 rt
:=p
^.right
^.treetype
;
203 { always use pt instead of p^.treetype, becayse p may be replaced }
204 { with a typeconversion node! (JM) }
206 rd
:=p
^.right
^.resulttype
;
207 ld
:=p
^.left
^.resulttype
;
210 if isbinaryoverloaded(p
) then
214 { convert int consts to real consts, if the }
215 { other operand is a real const }
216 if (rt
=realconstn
) and is_constintnode(p
^.left
) then
218 t
:=genrealconstnode(p
^.left
^.value
,p
^.right
^.resulttype
);
219 disposetree(p
^.left
);
223 if (lt
=realconstn
) and is_constintnode(p
^.right
) then
225 t
:=genrealconstnode(p
^.right
^.value
,p
^.left
^.resulttype
);
226 disposetree(p
^.right
);
231 { both are int constants, also allow operations on two equal enums
232 in fpc mode (Needed for conversion of C code) }
233 if ((lt
=ordconstn
) and (rt
=ordconstn
)) and
234 ((is_constintnode(p
^.left
) and is_constintnode(p
^.right
)) or
235 (is_constboolnode(p
^.left
) and is_constboolnode(p
^.right
) and
236 (pt
in [ltn
,lten
,gtn
,gten
,equaln
,unequaln
,andn
,xorn
,orn
]))) then
238 { return a boolean for boolean operations (and,xor,or) }
239 if is_constboolnode(p
^.left
) then
246 addn
: t
:=genordinalconstnode(lv
+rv
,resdef
);
247 subn
: t
:=genordinalconstnode(lv
-rv
,resdef
);
248 muln
: t
:=genordinalconstnode(lv
*rv
,resdef
);
249 xorn
: t
:=genordinalconstnode(lv
xor rv
,resdef
);
250 orn
: t
:=genordinalconstnode(lv
or rv
,resdef
);
251 andn
: t
:=genordinalconstnode(lv
and rv
,resdef
);
252 ltn
: t
:=genordinalconstnode(ord(lv
<rv
),booldef
);
253 lten
: t
:=genordinalconstnode(ord(lv
<=rv
),booldef
);
254 gtn
: t
:=genordinalconstnode(ord(lv
>rv
),booldef
);
255 gten
: t
:=genordinalconstnode(ord(lv
>=rv
),booldef
);
256 equaln
: t
:=genordinalconstnode(ord(lv
=rv
),booldef
);
257 unequaln
: t
:=genordinalconstnode(ord(lv
<>rv
),booldef
);
259 { int/int becomes a real }
262 Message(parser_e_invalid_float_operation
);
263 t
:=genrealconstnode(0,bestrealdef
^);
266 t
:=genrealconstnode(int(lv
)/int(rv
),bestrealdef
^);
270 CGMessage(type_e_mismatch
);
278 { both real constants ? }
279 if (lt
=realconstn
) and (rt
=realconstn
) then
281 lvd
:=p
^.left
^.value_real
;
282 rvd
:=p
^.right
^.value_real
;
284 addn
: t
:=genrealconstnode(lvd
+rvd
,bestrealdef
^);
285 subn
: t
:=genrealconstnode(lvd
-rvd
,bestrealdef
^);
286 muln
: t
:=genrealconstnode(lvd
*rvd
,bestrealdef
^);
291 Message(parser_e_invalid_float_operation
);
292 t
:=genrealconstnode(0,bestrealdef
^);
295 t
:=genrealconstnode(1.0,bestrealdef
^)
297 t
:=genrealconstnode(exp(ln(lvd
)*rvd
),bestrealdef
^);
303 Message(parser_e_invalid_float_operation
);
304 t
:=genrealconstnode(0,bestrealdef
^);
307 t
:=genrealconstnode(lvd
/rvd
,bestrealdef
^);
309 ltn
: t
:=genordinalconstnode(ord(lvd
<rvd
),booldef
);
310 lten
: t
:=genordinalconstnode(ord(lvd
<=rvd
),booldef
);
311 gtn
: t
:=genordinalconstnode(ord(lvd
>rvd
),booldef
);
312 gten
: t
:=genordinalconstnode(ord(lvd
>=rvd
),booldef
);
313 equaln
: t
:=genordinalconstnode(ord(lvd
=rvd
),booldef
);
314 unequaln
: t
:=genordinalconstnode(ord(lvd
<>rvd
),booldef
);
316 CGMessage(type_e_mismatch
);
324 { concating strings ? }
325 concatstrings
:=false;
328 if (lt
=ordconstn
) and (rt
=ordconstn
) and
329 is_char(ld
) and is_char(rd
) then
331 s1
:=strpnew(char(byte(p
^.left
^.value
)));
332 s2
:=strpnew(char(byte(p
^.right
^.value
)));
338 if (lt
=stringconstn
) and (rt
=ordconstn
) and is_char(rd
) then
340 s1
:=getpcharcopy(p
^.left
);
342 s2
:=strpnew(char(byte(p
^.right
^.value
)));
347 if (lt
=ordconstn
) and (rt
=stringconstn
) and is_char(ld
) then
349 s1
:=strpnew(char(byte(p
^.left
^.value
)));
351 s2
:=getpcharcopy(p
^.right
);
352 l2
:=p
^.right
^.length
;
355 else if (lt
=stringconstn
) and (rt
=stringconstn
) then
357 s1
:=getpcharcopy(p
^.left
);
359 s2
:=getpcharcopy(p
^.right
);
360 l2
:=p
^.right
^.length
;
364 { I will need to translate all this to ansistrings !!! }
365 if concatstrings
then
369 t
:=genpcharconstnode(concatansistrings(s1
,s2
,l1
,l2
),l1
+l2
);
371 t
:=genordinalconstnode(byte(compareansistrings(s1
,s2
,l1
,l2
)<0),booldef
);
373 t
:=genordinalconstnode(byte(compareansistrings(s1
,s2
,l1
,l2
)<=0),booldef
);
375 t
:=genordinalconstnode(byte(compareansistrings(s1
,s2
,l1
,l2
)>0),booldef
);
377 t
:=genordinalconstnode(byte(compareansistrings(s1
,s2
,l1
,l2
)>=0),booldef
);
379 t
:=genordinalconstnode(byte(compareansistrings(s1
,s2
,l1
,l2
)=0),booldef
);
381 t
:=genordinalconstnode(byte(compareansistrings(s1
,s2
,l1
,l2
)<>0),booldef
);
383 ansistringdispose(s1
,l1
);
384 ansistringdispose(s2
,l2
);
391 { if both are orddefs then check sub types }
392 if (ld
^.deftype
=orddef
) and (rd
^.deftype
=orddef
) then
395 if is_boolean(ld
) and is_boolean(rd
) then
401 make_bool_equal_size(p
);
402 calcregisters(p
,0,0,0);
403 p
^.location
.loc
:=LOC_JUMP
;
405 xorn
,ltn
,lten
,gtn
,gten
:
407 make_bool_equal_size(p
);
408 if (p
^.left
^.location
.loc
in [LOC_JUMP
,LOC_FLAGS
]) and
409 (p
^.left
^.location
.loc
in [LOC_JUMP
,LOC_FLAGS
]) then
410 calcregisters(p
,2,0,0)
412 calcregisters(p
,1,0,0);
417 make_bool_equal_size(p
);
418 { Remove any compares with constants }
419 if (p
^.left
^.treetype
=ordconstn
) then
422 b
:=(p
^.left
^.value
<>0);
424 disposetree(p
^.left
);
427 if (not(b
) and (ot
=equaln
)) or
428 (b
and (ot
=unequaln
)) then
430 p
:=gensinglenode(notn
,p
);
435 if (p
^.right
^.treetype
=ordconstn
) then
438 b
:=(p
^.right
^.value
<>0);
440 disposetree(p
^.right
);
443 if (not(b
) and (ot
=equaln
)) or
444 (b
and (ot
=unequaln
)) then
446 p
:=gensinglenode(notn
,p
);
451 if (p
^.left
^.location
.loc
in [LOC_JUMP
,LOC_FLAGS
]) and
452 (p
^.left
^.location
.loc
in [LOC_JUMP
,LOC_FLAGS
]) then
453 calcregisters(p
,2,0,0)
455 calcregisters(p
,1,0,0);
458 CGMessage(type_e_mismatch
);
461 { these one can't be in flags! }
463 Yes they can, secondadd converts the loc_flags to a register.
464 The typeconversions below are simply removed by firsttypeconv()
465 because the resulttype of p^.left = p^.left^.resulttype
468 if pt in [xorn,unequaln,equaln] then
470 if p^.left^.location.loc=LOC_FLAGS then
472 p^.left:=gentypeconvnode(p^.left,porddef(p^.left^.resulttype));
473 p^.left^.convtyp:=tc_bool_2_int;
474 p^.left^.explizit:=true;
477 if p^.right^.location.loc=LOC_FLAGS then
479 p^.right:=gentypeconvnode(p^.right,porddef(p^.right^.resulttype));
480 p^.right^.convtyp:=tc_bool_2_int;
481 p^.right^.explizit:=true;
484 { readjust registers }
485 calcregisters(p,1,0,0);
491 { Both are chars? only convert to shortstrings for addn }
492 if is_char(rd
) and is_char(ld
) then
496 p
^.left
:=gentypeconvnode(p
^.left
,cshortstringdef
);
497 p
^.right
:=gentypeconvnode(p
^.right
,cshortstringdef
);
500 { here we call STRCOPY }
501 procinfo
^.flags
:=procinfo
^.flags
or pi_do_call
;
502 calcregisters(p
,0,0,0);
503 p
^.location
.loc
:=LOC_MEM
;
506 calcregisters(p
,1,0,0);
509 { is there a 64 bit type ? }
510 else if ((porddef(rd
)^.typ
=s64bit
) or (porddef(ld
)^.typ
=s64bit
)) and
511 { the / operator is handled later }
514 if (porddef(ld
)^.typ
<>s64bit
) then
516 p
^.left
:=gentypeconvnode(p
^.left
,cs64bitdef
);
519 if (porddef(rd
)^.typ
<>s64bit
) then
521 p
^.right
:=gentypeconvnode(p
^.right
,cs64bitdef
);
524 calcregisters(p
,2,0,0);
527 else if ((porddef(rd
)^.typ
=u64bit
) or (porddef(ld
)^.typ
=u64bit
)) and
528 { the / operator is handled later }
531 if (porddef(ld
)^.typ
<>u64bit
) then
533 p
^.left
:=gentypeconvnode(p
^.left
,cu64bitdef
);
536 if (porddef(rd
)^.typ
<>u64bit
) then
538 p
^.right
:=gentypeconvnode(p
^.right
,cu64bitdef
);
541 calcregisters(p
,2,0,0);
545 { is there a cardinal? }
546 if ((porddef(rd
)^.typ
=u32bit
) or (porddef(ld
)^.typ
=u32bit
)) and
547 { the / operator is handled later }
552 { convert positive constants to u32bit }
553 not(is_constintnode(p
^.left
) and
554 (p
^.left
^.value
>= 0)) and
555 { range/overflow checking on mixed signed/cardinal expressions }
556 { is only possible if you convert everything to 64bit (JM) }
557 ((aktlocalswitches
* [cs_check_overflow
,cs_check_range
] <> []) and
558 (pt
in [addn
,subn
,muln
])) then
560 { perform the operation in 64bit }
561 CGMessage(type_w_mixed_signed_unsigned
);
562 p
^.left
:= gentypeconvnode(p
^.left
,cs64bitdef
);
564 p
^.right
:= gentypeconvnode(p
^.right
,cs64bitdef
);
570 not(is_constintnode(p
^.left
) and
571 (p
^.left
^.value
>= 0)) and
572 (cs_check_range
in aktlocalswitches
) then
573 CGMessage(type_w_mixed_signed_unsigned2
);
574 p
^.left
:= gentypeconvnode(p
^.left
,u32bitdef
);
579 { convert positive constants to u32bit }
580 not(is_constintnode(p
^.right
) and
581 (p
^.right
^.value
>= 0)) and
582 ((aktlocalswitches
* [cs_check_overflow
,cs_check_range
] <> []) and
583 (pt
in [addn
,subn
,muln
])) then
585 { perform the operation in 64bit }
586 CGMessage(type_w_mixed_signed_unsigned
);
587 p
^.left
:= gentypeconvnode(p
^.left
,cs64bitdef
);
589 p
^.right
:= gentypeconvnode(p
^.right
,cs64bitdef
);
595 not(is_constintnode(p
^.right
) and
596 (p
^.right
^.value
>= 0)) and
597 (cs_check_range
in aktlocalswitches
) then
598 CGMessage(type_w_mixed_signed_unsigned2
);
599 p
^.right
:= gentypeconvnode(p
^.right
,u32bitdef
);
603 { did we convert things to 64bit? }
604 if porddef(p
^.left
^.resulttype
)^.typ
= s64bit
then
605 calcregisters(p
,2,0,0)
608 calcregisters(p
,1,0,0);
609 { for unsigned mul we need an extra register }
618 { left side a setdef, must be before string processing,
619 else array constructor can be seen as array of char (PFV) }
620 if (ld
^.deftype
=setdef
) {or is_array_constructor(ld)} then
622 { trying to add a set element? }
623 if (pt
=addn
) and (rd
^.deftype
<>setdef
) then
625 if (rt
=setelementn
) then
627 if not(is_equal(psetdef(ld
)^.elementtype
.def
,rd
)) then
628 CGMessage(type_e_set_element_are_not_comp
);
631 CGMessage(type_e_mismatch
)
635 if not(pt
in [addn
,subn
,symdifn
,muln
,equaln
,unequaln
636 {$IfNDef NoSetInclusion}
638 {$EndIf NoSetInclusion}
640 CGMessage(type_e_set_operation_unknown
);
641 { right def must be a also be set }
642 if (rd
^.deftype
<>setdef
) or not(is_equal(rd
,ld
)) then
643 CGMessage(type_e_set_element_are_not_comp
);
646 { ranges require normsets }
647 if (psetdef(ld
)^.settype
=smallset
) and
649 assigned(p
^.right
^.right
) then
651 { generate a temporary normset def, it'll be destroyed
652 when the symtable is unloaded }
653 tempdef
:=new(psetdef
,init(psetdef(ld
)^.elementtype
.def
,255));
654 p
^.left
:=gentypeconvnode(p
^.left
,tempdef
);
656 ld
:=p
^.left
^.resulttype
;
659 { if the destination is not a smallset then insert a typeconv
660 which loads a smallset into a normal set }
661 if (psetdef(ld
)^.settype
<>smallset
) and
662 (psetdef(rd
)^.settype
=smallset
) then
664 if (p
^.right
^.treetype
=setconstn
) then
666 t
:=gensetconstnode(p
^.right
^.value_set
,psetdef(p
^.left
^.resulttype
));
667 t
^.left
:=p
^.right
^.left
;
672 p
^.right
:=gentypeconvnode(p
^.right
,psetdef(p
^.left
^.resulttype
));
676 { do constant evaluation }
677 if (p
^.right
^.treetype
=setconstn
) and
678 not assigned(p
^.right
^.left
) and
679 (p
^.left
^.treetype
=setconstn
) and
680 not assigned(p
^.left
^.left
) then
687 p
^.right
^.value_set
^[i
] or p
^.left
^.value_set
^[i
];
688 t
:=gensetconstnode(resultset
,psetdef(ld
));
693 p
^.right
^.value_set
^[i
] and p
^.left
^.value_set
^[i
];
694 t
:=gensetconstnode(resultset
,psetdef(ld
));
699 p
^.left
^.value_set
^[i
] and not(p
^.right
^.value_set
^[i
]);
700 t
:=gensetconstnode(resultset
,psetdef(ld
));
705 p
^.left
^.value_set
^[i
] xor p
^.right
^.value_set
^[i
];
706 t
:=gensetconstnode(resultset
,psetdef(ld
));
711 if p
^.right
^.value_set
^[i
]=p
^.left
^.value_set
^[i
] then
716 t
:=genordinalconstnode(ord(b
),booldef
);
721 if p
^.right
^.value_set
^[i
]<>p
^.left
^.value_set
^[i
] then
726 t
:=genordinalconstnode(ord(b
),booldef
);
728 {$IfNDef NoSetInclusion}
732 If (p
^.right
^.value_set
^[i
] And p
^.left
^.value_set
^[i
]) <>
733 p
^.left
^.value_set
^[i
] Then
738 t
:= genordinalconstnode(ord(b
),booldef
);
743 If (p
^.left
^.value_set
^[i
] And p
^.right
^.value_set
^[i
]) <>
744 p
^.right
^.value_set
^[i
] Then
749 t
:= genordinalconstnode(ord(b
),booldef
);
751 {$EndIf NoSetInclusion}
760 if psetdef(ld
)^.settype
=smallset
then
762 { are we adding set elements ? }
763 if p
^.right
^.treetype
=setelementn
then
764 calcregisters(p
,2,0,0)
766 calcregisters(p
,1,0,0);
767 p
^.location
.loc
:=LOC_REGISTER
;
771 calcregisters(p
,0,0,0);
772 { here we call SET... }
773 procinfo
^.flags
:=procinfo
^.flags
or pi_do_call
;
774 p
^.location
.loc
:=LOC_MEM
;
779 { compare pchar to char arrays by addresses
781 if (is_pchar(ld
) and is_chararray(rd
)) or
782 (is_pchar(rd
) and is_chararray(ld
)) then
784 if is_chararray(rd
) then
786 p
^.right
:=gentypeconvnode(p
^.right
,ld
);
791 p
^.left
:=gentypeconvnode(p
^.left
,rd
);
794 p
^.location
.loc
:=LOC_REGISTER
;
795 calcregisters(p
,1,0,0);
799 { is one of the operands a string?,
800 chararrays are also handled as strings (after conversion) }
801 if (rd
^.deftype
=stringdef
) or (ld
^.deftype
=stringdef
) or
802 ((is_chararray(rd
) or is_char(rd
)) and
803 (is_chararray(ld
) or is_char(ld
))) then
805 if is_widestring(rd
) or is_widestring(ld
) then
807 if not(is_widestring(rd
)) then
808 p
^.right
:=gentypeconvnode(p
^.right
,cwidestringdef
);
809 if not(is_widestring(ld
)) then
810 p
^.left
:=gentypeconvnode(p
^.left
,cwidestringdef
);
811 p
^.resulttype
:=cwidestringdef
;
812 { this is only for add, the comparisaion is handled later }
813 p
^.location
.loc
:=LOC_REGISTER
;
815 else if is_ansistring(rd
) or is_ansistring(ld
) then
817 if not(is_ansistring(rd
)) then
818 p
^.right
:=gentypeconvnode(p
^.right
,cansistringdef
);
819 if not(is_ansistring(ld
)) then
820 p
^.left
:=gentypeconvnode(p
^.left
,cansistringdef
);
821 { we use ansistrings so no fast exit here }
822 procinfo
^.no_fast_exit
:=true;
823 p
^.resulttype
:=cansistringdef
;
824 { this is only for add, the comparisaion is handled later }
825 p
^.location
.loc
:=LOC_REGISTER
;
827 else if is_longstring(rd
) or is_longstring(ld
) then
829 if not(is_longstring(rd
)) then
830 p
^.right
:=gentypeconvnode(p
^.right
,clongstringdef
);
831 if not(is_longstring(ld
)) then
832 p
^.left
:=gentypeconvnode(p
^.left
,clongstringdef
);
833 p
^.resulttype
:=clongstringdef
;
834 { this is only for add, the comparisaion is handled later }
835 p
^.location
.loc
:=LOC_MEM
;
839 if not(is_shortstring(rd
))
840 {$ifdef newoptimizations2}
842 { shortstring + char handled seperately (JM) }
843 and (not(cs_optimize
in aktglobalswitches
) or
844 (pt
<> addn
) or not(is_char(rd
)))
846 {$endif newoptimizations2}
848 p
^.right
:=gentypeconvnode(p
^.right
,cshortstringdef
);
849 if not(is_shortstring(ld
)) then
850 p
^.left
:=gentypeconvnode(p
^.left
,cshortstringdef
);
851 p
^.resulttype
:=cshortstringdef
;
852 { this is only for add, the comparisaion is handled later }
853 p
^.location
.loc
:=LOC_MEM
;
855 { only if there is a type cast we need to do again }
857 if p
^.left
^.treetype
=typeconvn
then
859 if p
^.right
^.treetype
=typeconvn
then
861 { here we call STRCONCAT or STRCMP or STRCOPY }
862 procinfo
^.flags
:=procinfo
^.flags
or pi_do_call
;
863 if p
^.location
.loc
=LOC_MEM
then
864 calcregisters(p
,0,0,0)
866 calcregisters(p
,1,0,0);
867 {$ifdef newoptimizations}
869 { not always necessary, only if it is not a constant char and }
870 { not a regvar, but don't know how to check this here (JM) }
874 {$endif newoptimizations}
879 { is one a real float ? }
880 if (rd
^.deftype
=floatdef
) or (ld
^.deftype
=floatdef
) then
882 { if one is a fixed, then convert to f32bit }
883 if ((rd
^.deftype
=floatdef
) and (pfloatdef(rd
)^.typ
=f32bit
)) or
884 ((ld
^.deftype
=floatdef
) and (pfloatdef(ld
)^.typ
=f32bit
)) then
886 if not is_integer(rd
) or (pt
<>muln
) then
887 p
^.right
:=gentypeconvnode(p
^.right
,s32fixeddef
);
888 if not is_integer(ld
) or (pt
<>muln
) then
889 p
^.left
:=gentypeconvnode(p
^.left
,s32fixeddef
);
892 calcregisters(p
,1,0,0);
893 p
^.location
.loc
:=LOC_REGISTER
;
896 { convert both to bestreal }
898 p
^.right
:=gentypeconvnode(p
^.right
,bestrealdef
^);
899 p
^.left
:=gentypeconvnode(p
^.left
,bestrealdef
^);
902 calcregisters(p
,0,1,0);
903 p
^.location
.loc
:=LOC_FPU
;
909 { pointer comperation and subtraction }
910 if (rd
^.deftype
=pointerdef
) and (ld
^.deftype
=pointerdef
) then
912 p
^.location
.loc
:=LOC_REGISTER
;
913 { p^.right:=gentypeconvnode(p^.right,ld); }
914 { firstpass(p^.right); }
915 calcregisters(p
,1,0,0);
919 if is_equal(p
^.right
^.resulttype
,voidpointerdef
) then
921 p
^.right
:=gentypeconvnode(p
^.right
,ld
);
924 else if is_equal(p
^.left
^.resulttype
,voidpointerdef
) then
926 p
^.left
:=gentypeconvnode(p
^.left
,rd
);
929 else if not(is_equal(ld
,rd
)) then
930 CGMessage(type_e_mismatch
);
934 if is_equal(p
^.right
^.resulttype
,voidpointerdef
) then
936 p
^.right
:=gentypeconvnode(p
^.right
,ld
);
939 else if is_equal(p
^.left
^.resulttype
,voidpointerdef
) then
941 p
^.left
:=gentypeconvnode(p
^.left
,rd
);
944 else if not(is_equal(ld
,rd
)) then
945 CGMessage(type_e_mismatch
);
946 if not(cs_extsyntax
in aktmoduleswitches
) then
947 CGMessage(type_e_mismatch
);
951 if not(is_equal(ld
,rd
)) then
952 CGMessage(type_e_mismatch
);
953 if not(cs_extsyntax
in aktmoduleswitches
) then
954 CGMessage(type_e_mismatch
);
955 p
^.resulttype
:=s32bitdef
;
958 else CGMessage(type_e_mismatch
);
964 if (rd
^.deftype
=objectdef
) and (ld
^.deftype
=objectdef
) and
965 pobjectdef(rd
)^.is_class
and pobjectdef(ld
)^.is_class
then
967 p
^.location
.loc
:=LOC_REGISTER
;
968 if pobjectdef(rd
)^.is_related(pobjectdef(ld
)) then
969 p
^.right
:=gentypeconvnode(p
^.right
,ld
)
971 p
^.left
:=gentypeconvnode(p
^.left
,rd
);
974 calcregisters(p
,1,0,0);
977 else CGMessage(type_e_mismatch
);
983 if (rd
^.deftype
=classrefdef
) and (ld
^.deftype
=classrefdef
) then
985 p
^.location
.loc
:=LOC_REGISTER
;
986 if pobjectdef(pclassrefdef(rd
)^.pointertype
.def
)^.is_related(pobjectdef(
987 pclassrefdef(ld
)^.pointertype
.def
)) then
988 p
^.right
:=gentypeconvnode(p
^.right
,ld
)
990 p
^.left
:=gentypeconvnode(p
^.left
,rd
);
993 calcregisters(p
,1,0,0);
996 else CGMessage(type_e_mismatch
);
1002 { allows comperasion with nil pointer }
1003 if (rd
^.deftype
=objectdef
) and
1004 pobjectdef(rd
)^.is_class
then
1006 p
^.location
.loc
:=LOC_REGISTER
;
1007 p
^.left
:=gentypeconvnode(p
^.left
,rd
);
1009 calcregisters(p
,1,0,0);
1012 else CGMessage(type_e_mismatch
);
1018 if (ld
^.deftype
=objectdef
) and
1019 pobjectdef(ld
)^.is_class
then
1021 p
^.location
.loc
:=LOC_REGISTER
;
1022 p
^.right
:=gentypeconvnode(p
^.right
,ld
);
1023 firstpass(p
^.right
);
1024 calcregisters(p
,1,0,0);
1027 else CGMessage(type_e_mismatch
);
1033 if (rd
^.deftype
=classrefdef
) then
1035 p
^.left
:=gentypeconvnode(p
^.left
,rd
);
1037 calcregisters(p
,1,0,0);
1040 else CGMessage(type_e_mismatch
);
1046 if (ld
^.deftype
=classrefdef
) then
1048 p
^.right
:=gentypeconvnode(p
^.right
,ld
);
1049 firstpass(p
^.right
);
1050 calcregisters(p
,1,0,0);
1054 CGMessage(type_e_mismatch
);
1060 { support procvar=nil,procvar<>nil }
1061 if ((ld
^.deftype
=procvardef
) and (rt
=niln
)) or
1062 ((rd
^.deftype
=procvardef
) and (lt
=niln
)) then
1064 calcregisters(p
,1,0,0);
1065 p
^.location
.loc
:=LOC_REGISTER
;
1069 CGMessage(type_e_mismatch
);
1075 {$ifdef SUPPORT_MMX}
1076 if (cs_mmx
in aktlocalswitches
) and is_mmx_able_array(ld
) and
1077 is_mmx_able_array(rd
) and is_equal(ld
,rd
) then
1079 firstpass(p
^.right
);
1082 addn
,subn
,xorn
,orn
,andn
:
1084 { mul is a little bit restricted }
1086 if not(mmx_type(p
^.left
^.resulttype
) in
1087 [mmxu16bit
,mmxs16bit
,mmxfixed16
]) then
1088 CGMessage(type_e_mismatch
);
1090 CGMessage(type_e_mismatch
);
1092 p
^.location
.loc
:=LOC_MMXREGISTER
;
1093 calcregisters(p
,0,0,1);
1097 {$endif SUPPORT_MMX}
1099 { this is a little bit dangerous, also the left type }
1100 { should be checked! This broke the mmx support }
1101 if (rd
^.deftype
=pointerdef
) or
1102 is_zero_based_array(rd
) then
1104 if is_zero_based_array(rd
) then
1106 p
^.resulttype
:=new(ppointerdef
,init(parraydef(rd
)^.elementtype
));
1107 p
^.right
:=gentypeconvnode(p
^.right
,p
^.resulttype
);
1108 firstpass(p
^.right
);
1110 p
^.location
.loc
:=LOC_REGISTER
;
1111 p
^.left
:=gentypeconvnode(p
^.left
,s32bitdef
);
1113 calcregisters(p
,1,0,0);
1116 if not(cs_extsyntax
in aktmoduleswitches
) or
1117 (not(is_pchar(ld
)) and not(m_add_pointer
in aktmodeswitches
)) then
1118 CGMessage(type_e_mismatch
);
1119 { Dirty hack, to support multiple firstpasses (PFV) }
1120 if (p
^.resulttype
=nil) and
1121 (rd
^.deftype
=pointerdef
) and
1122 (ppointerdef(rd
)^.pointertype
.def
^.size
>1) then
1124 p
^.left
:=gennode(muln
,p
^.left
,genordinalconstnode(ppointerdef(rd
)^.pointertype
.def
^.size
,s32bitdef
));
1129 CGMessage(type_e_mismatch
);
1134 if (ld
^.deftype
=pointerdef
) or
1135 is_zero_based_array(ld
) then
1137 if is_zero_based_array(ld
) then
1139 p
^.resulttype
:=new(ppointerdef
,init(parraydef(ld
)^.elementtype
));
1140 p
^.left
:=gentypeconvnode(p
^.left
,p
^.resulttype
);
1143 p
^.location
.loc
:=LOC_REGISTER
;
1144 p
^.right
:=gentypeconvnode(p
^.right
,s32bitdef
);
1145 firstpass(p
^.right
);
1146 calcregisters(p
,1,0,0);
1149 if not(cs_extsyntax
in aktmoduleswitches
) or
1150 (not(is_pchar(ld
)) and not(m_add_pointer
in aktmodeswitches
)) then
1151 CGMessage(type_e_mismatch
);
1152 { Dirty hack, to support multiple firstpasses (PFV) }
1153 if (p
^.resulttype
=nil) and
1154 (ld
^.deftype
=pointerdef
) and
1155 (ppointerdef(ld
)^.pointertype
.def
^.size
>1) then
1157 p
^.right
:=gennode(muln
,p
^.right
,
1158 genordinalconstnode(ppointerdef(ld
)^.pointertype
.def
^.size
,s32bitdef
));
1159 firstpass(p
^.right
);
1163 CGMessage(type_e_mismatch
);
1169 if (rd
^.deftype
=procvardef
) and (ld
^.deftype
=procvardef
) and is_equal(rd
,ld
) then
1171 calcregisters(p
,1,0,0);
1172 p
^.location
.loc
:=LOC_REGISTER
;
1176 CGMessage(type_e_mismatch
);
1182 if (ld
^.deftype
=enumdef
) and (rd
^.deftype
=enumdef
) then
1184 if not(is_equal(ld
,rd
)) then
1186 p
^.right
:=gentypeconvnode(p
^.right
,ld
);
1187 firstpass(p
^.right
);
1189 calcregisters(p
,1,0,0);
1192 ltn
,lten
,gtn
,gten
: ;
1193 else CGMessage(type_e_mismatch
);
1198 { the general solution is to convert to 32 bit int }
1199 if not convdone
then
1201 { but an int/int gives real/real! }
1204 CGMessage(type_h_use_div_for_int
);
1205 p
^.right
:=gentypeconvnode(p
^.right
,bestrealdef
^);
1206 p
^.left
:=gentypeconvnode(p
^.left
,bestrealdef
^);
1208 firstpass(p
^.right
);
1209 { maybe we need an integer register to save }
1211 if ((p
^.left
^.location
.loc
<>LOC_FPU
) or
1212 (p
^.right
^.location
.loc
<>LOC_FPU
)) and
1213 (p
^.left
^.registers32
=p
^.right
^.registers32
) then
1214 calcregisters(p
,1,1,0)
1216 calcregisters(p
,0,1,0);
1217 p
^.location
.loc
:=LOC_FPU
;
1221 p
^.right
:=gentypeconvnode(p
^.right
,s32bitdef
);
1222 p
^.left
:=gentypeconvnode(p
^.left
,s32bitdef
);
1224 firstpass(p
^.right
);
1225 calcregisters(p
,1,0,0);
1226 p
^.location
.loc
:=LOC_REGISTER
;
1230 if codegenerror
then
1233 { determines result type for comparions }
1234 { here the is a problem with multiple passes }
1235 { example length(s)+1 gets internal 'longint' type first }
1236 { if it is a arg it is converted to 'LONGINT' }
1237 { but a second first pass will reset this to 'longint' }
1239 ltn
,lten
,gtn
,gten
,equaln
,unequaln
:
1241 if (not assigned(p
^.resulttype
)) or
1242 (p
^.resulttype
^.deftype
=stringdef
) then
1243 p
^.resulttype
:=booldef
;
1244 if is_64bitint(p
^.left
^.resulttype
) then
1245 p
^.location
.loc
:=LOC_JUMP
1247 p
^.location
.loc
:=LOC_FLAGS
;
1251 if not assigned(p
^.resulttype
) then
1252 p
^.resulttype
:=p
^.left
^.resulttype
;
1253 p
^.location
.loc
:=LOC_REGISTER
;
1257 if not assigned(p
^.resulttype
) then
1259 { for strings, return is always a 255 char string }
1260 if is_shortstring(p
^.left
^.resulttype
) then
1261 p
^.resulttype
:=cshortstringdef
1263 p
^.resulttype
:=p
^.left
^.resulttype
;
1267 if not assigned(p
^.resulttype
) then
1268 p
^.resulttype
:=p
^.left
^.resulttype
;
1276 Revision 1.1 2002/02/19 08:23:59 sasu
1279 Revision 1.1.2.8 2000/12/16 15:54:51 jonas
1280 + warning when there is a chance to get a range check error because of
1281 automatic type conversion to u32bit
1283 Revision 1.1.2.7 2000/12/13 12:25:40 jonas
1284 + also added 64bit conversion when using cardinals and signed
1285 expressions for div (in tcmat this time :)
1286 * removed automatic type conversion back to dword of 64bit results
1288 Revision 1.1.2.6 2000/12/11 14:14:10 jonas
1289 * no longer use left type for conversion mentioned in previous commit,
1290 since it may not be 32bit. Always use u32bitdef instead.
1292 Revision 1.1.2.5 2000/12/11 11:47:41 jonas
1293 * automatically typecast result of 64bit evaluations of 32bit operations
1294 (when using range checking or when dividing) back to 32bits.
1296 Revision 1.1.2.4 2000/12/08 17:03:23 jonas
1297 + added full range checking for 64bit types
1298 * fixed web bug 1144
1300 Revision 1.1.2.3 2000/09/10 20:19:03 peter
1301 * fixed crash with smallset -> normalset conversion
1303 Revision 1.1.2.2 2000/07/27 09:17:38 jonas
1304 * removed obsolete typeconversion (it got removed by the compiler in
1305 firsttypeconv anyway)
1307 Revision 1.1.2.1 2000/07/19 05:55:33 michael
1308 + Applied patch from Pierre
1310 Revision 1.1 2000/07/13 06:29:58 michael
1313 Revision 1.79 2000/06/02 21:24:48 pierre
1314 * operator overloading now uses isbinaryoperatoracceptable
1315 and is unaryoperatoracceptable
1317 Revision 1.78 2000/05/31 06:58:41 florian
1318 * forgot to commit a fix for the enumeration subrange problem, yesterday
1320 Revision 1.77 2000/05/11 17:53:40 peter
1321 * small fix for previous commit
1323 Revision 1.76 2000/05/11 16:47:37 peter
1324 * fixed check for overloaded operator with array and chararray check
1326 Revision 1.75 2000/04/25 14:43:36 jonas
1327 - disabled "string_var := string_var + ... " and "string_var + char_var"
1328 optimizations (were only active with -dnewoptimizations) because of
1329 several internal issues
1331 Revision 1.74 2000/04/21 12:35:05 jonas
1332 + special code for string + char, between -dnewoptimizations
1334 Revision 1.73 2000/03/28 21:14:18 pierre
1337 Revision 1.72 2000/03/20 10:16:51 florian
1338 * fixed <dword>/<dword>, <int64>/<int64> and <qword>/<qword>
1340 Revision 1.71 2000/03/18 15:01:19 jonas
1341 * moved a $maxfpuregisters directive a bit up because it was being
1344 Revision 1.70 2000/02/19 10:12:48 florian
1345 * fixed one more internalerror 10
1347 Revision 1.69 2000/02/17 14:53:42 florian
1348 * some updates for the newcg
1350 Revision 1.68 2000/02/14 22:34:28 florian
1351 * fixed another internalerror
1353 Revision 1.67 2000/02/13 22:46:28 florian
1354 * fixed an internalerror with writeln
1355 * fixed arrayconstructor_to_set to force the generation of better code
1356 and added a more strict type checking
1358 Revision 1.66 2000/02/13 14:21:51 jonas
1359 * modifications to make the compiler functional when compiled with
1362 Revision 1.65 2000/02/09 13:23:06 peter
1365 Revision 1.64 2000/02/04 08:47:10 florian
1366 * better register variable allocation in -Or mode
1368 Revision 1.63 2000/01/07 01:14:43 peter
1369 * updated copyright to 2000
1371 Revision 1.62 2000/01/04 20:10:20 florian
1374 Revision 1.61 1999/12/11 18:53:31 jonas
1375 * fixed type conversions of results of operations with cardinals
1376 (between -dcardinalmulfix)
1378 Revision 1.60 1999/12/09 23:18:04 pierre
1379 * no_fast_exit if procedure contains implicit termination code
1381 Revision 1.59 1999/12/01 12:42:33 peter
1383 * removed some notes about unused vars
1385 Revision 1.58 1999/11/30 10:40:56 peter
1388 Revision 1.57 1999/11/26 13:51:29 pierre
1389 * fix for overloading of shr shl mod and div
1391 Revision 1.56 1999/11/18 15:34:48 pierre
1392 * Notes/Hints for local syms changed to
1393 Set_varstate function
1395 Revision 1.55 1999/11/17 17:05:06 pierre
1396 * Notes/hints changes
1398 Revision 1.54 1999/11/16 23:45:28 pierre
1399 * global var token was changed by overload code (form bug 707)
1401 Revision 1.53 1999/11/15 21:53:42 peter
1402 * fixed constant eval for bool xor/or/and bool
1404 Revision 1.52 1999/11/15 17:53:00 pierre
1405 + one field added for ttoken record for operator
1406 linking the id to the corresponding operator token that
1407 can now now all be overloaded
1408 * overloaded operators are resetted to nil in InitSymtable
1409 (bug when trying to compile a uint that overloads operators twice)
1411 Revision 1.51 1999/11/06 14:34:29 peter
1412 * truncated log to 20 revs
1414 Revision 1.50 1999/09/27 23:45:00 peter
1415 * procinfo is now a pointer
1416 * support for result setting in sub procedure
1418 Revision 1.49 1999/09/16 13:39:14 peter
1419 * arrayconstructor 2 set conversion is now called always in the
1420 beginning of firstadd
1422 Revision 1.48 1999/09/15 20:35:45 florian
1423 * small fix to operator overloading when in MMX mode
1424 + the compiler uses now fldz and fld1 if possible
1425 + some fixes to floating point registers
1426 + some math. functions (arctan, ln, sin, cos, sqrt, sqr, pi) are now inlined
1429 Revision 1.47 1999/09/13 16:28:05 peter
1430 * typo in previous commit open_array -> chararray :(
1432 Revision 1.46 1999/09/10 15:40:46 peter
1433 * fixed array check for operators, becuase array can also be a set
1435 Revision 1.45 1999/09/08 16:05:29 peter
1436 * pointer add/sub is now as expected and the same results as inc/dec