3 Copyright (c) 1998-2000 by Florian Klaempfl
5 Type checking and register allocation for math nodes
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 firstmoddiv(var p
: ptree
);
30 procedure firstshlshr(var p
: ptree
);
31 procedure firstunaryminus(var p
: ptree
);
32 procedure firstnot(var p
: ptree
);
38 globtype
,systems
,tokens
,
39 cobjects
,verbose
,globals
,
40 symconst
,symtable
,aasm
,types
,
41 htypechk
,pass_1
,cpubase
,
47 { for isbinaryoverloaded function }
50 {*****************************************************************************
52 *****************************************************************************}
54 procedure firstmoddiv(var p
: ptree
);
62 set_varstate(p
^.left
,true);
64 set_varstate(p
^.right
,true);
68 if isbinaryoverloaded(p
) then
71 { check for division by zero }
74 if is_constintnode(p
^.right
) and (rv
=0) then
76 Message(parser_e_division_by_zero
);
81 if is_constintnode(p
^.left
) and is_constintnode(p
^.right
) then
84 modn
: t
:=genordinalconstnode(lv
mod rv
,s32bitdef
);
85 divn
: t
:=genordinalconstnode(lv
div rv
,s32bitdef
);
92 { if one operand is a cardinal and the other is a positive constant, convert the }
93 { constant to a cardinal as well so we don't have to do a 64bit division (JM) }
94 if (p
^.left
^.resulttype
^.deftype
=orddef
) and (p
^.right
^.resulttype
^.deftype
=orddef
) then
95 if (porddef(p
^.right
^.resulttype
)^.typ
= u32bit
) and
96 is_constintnode(p
^.left
) and
97 (p
^.left
^.value
>= 0) then
99 p
^.left
:= gentypeconvnode(p
^.left
,u32bitdef
);
102 else if (porddef(p
^.left
^.resulttype
)^.typ
= u32bit
) and
103 is_constintnode(p
^.right
) and
104 (p
^.right
^.value
>= 0) then
106 p
^.right
:= gentypeconvnode(p
^.right
,u32bitdef
);
110 if (p
^.left
^.resulttype
^.deftype
=orddef
) and (p
^.right
^.resulttype
^.deftype
=orddef
) and
111 (is_64bitint(p
^.left
^.resulttype
) or is_64bitint(p
^.right
^.resulttype
) or
112 { when mixing cardinals and signed numbers, convert everythign to 64bit (JM) }
113 ((porddef(p
^.right
^.resulttype
)^.typ
= u32bit
) and
114 is_signed(p
^.left
^.resulttype
)) or
115 ((porddef(p
^.left
^.resulttype
)^.typ
= u32bit
) and
116 is_signed(p
^.right
^.resulttype
))) then
118 rd
:=p
^.right
^.resulttype
;
119 ld
:=p
^.left
^.resulttype
;
120 { issue warning if necessary }
121 if not (is_64bitint(p
^.left
^.resulttype
) or is_64bitint(p
^.right
^.resulttype
)) then
122 CGMessage(type_w_mixed_signed_unsigned
);
123 if is_signed(rd
) or is_signed(ld
) then
125 if (porddef(ld
)^.typ
<>s64bit
) then
127 p
^.left
:=gentypeconvnode(p
^.left
,cs64bitdef
);
130 if (porddef(rd
)^.typ
<>s64bit
) then
132 p
^.right
:=gentypeconvnode(p
^.right
,cs64bitdef
);
135 calcregisters(p
,2,0,0);
139 if (porddef(ld
)^.typ
<>u64bit
) then
141 p
^.left
:=gentypeconvnode(p
^.left
,cu64bitdef
);
144 if (porddef(rd
)^.typ
<>u64bit
) then
146 p
^.right
:=gentypeconvnode(p
^.right
,cu64bitdef
);
149 calcregisters(p
,2,0,0);
151 p
^.resulttype
:=p
^.left
^.resulttype
;
155 if not(p
^.right
^.resulttype
^.deftype
=orddef
) or
156 not(porddef(p
^.right
^.resulttype
)^.typ
in [s32bit
,u32bit
]) then
157 p
^.right
:=gentypeconvnode(p
^.right
,s32bitdef
);
159 if not(p
^.left
^.resulttype
^.deftype
=orddef
) or
160 not(porddef(p
^.left
^.resulttype
)^.typ
in [s32bit
,u32bit
]) then
161 p
^.left
:=gentypeconvnode(p
^.left
,s32bitdef
);
166 { the resulttype depends on the right side, because the left becomes }
168 p
^.resulttype
:=p
^.right
^.resulttype
;
174 if p
^.left
^.registers32
<=p
^.right
^.registers32
then
177 p
^.location
.loc
:=LOC_REGISTER
;
181 {*****************************************************************************
183 *****************************************************************************}
185 procedure firstshlshr(var p
: ptree
);
191 set_varstate(p
^.left
,true);
193 set_varstate(p
^.right
,true);
197 if isbinaryoverloaded(p
) then
200 if is_constintnode(p
^.left
) and is_constintnode(p
^.right
) then
203 shrn
: t
:=genordinalconstnode(p
^.left
^.value
shr p
^.right
^.value
,s32bitdef
);
204 shln
: t
:=genordinalconstnode(p
^.left
^.value
shl p
^.right
^.value
,s32bitdef
);
211 { 64 bit ints have their own shift handling }
212 if not(is_64bitint(p
^.left
^.resulttype
)) then
214 if porddef(p
^.left
^.resulttype
)^.typ
<> u32bit
then
215 p
^.left
:=gentypeconvnode(p
^.left
,s32bitdef
);
218 p
^.resulttype
:=p
^.left
^.resulttype
;
222 p
^.resulttype
:=p
^.left
^.resulttype
;
226 p
^.right
:=gentypeconvnode(p
^.right
,s32bitdef
);
232 if (p
^.right
^.treetype
<>ordconstn
) then
234 calcregisters(p
,regs
,0,0);
236 p
^.location
.loc
:=LOC_REGISTER
;
240 {*****************************************************************************
242 *****************************************************************************}
244 procedure firstunaryminus(var p
: ptree
);
250 set_varstate(p
^.left
,true);
251 p
^.registers32
:=p
^.left
^.registers32
;
252 p
^.registersfpu
:=p
^.left
^.registersfpu
;
254 p
^.registersmmx
:=p
^.left
^.registersmmx
;
256 p
^.resulttype
:=p
^.left
^.resulttype
;
259 if is_constintnode(p
^.left
) then
261 t
:=genordinalconstnode(-p
^.left
^.value
,s32bitdef
);
267 { nasm can not cope with negativ reals !! }
268 if is_constrealnode(p
^.left
)
270 and not(aktoutputformat
in [as_i386_nasmcoff
,as_i386_nasmelf
,as_i386_nasmobj
])
274 t
:=genrealconstnode(-p
^.left
^.value_real
,bestrealdef
^);
280 if (p
^.left
^.resulttype
^.deftype
=floatdef
) then
282 if pfloatdef(p
^.left
^.resulttype
)^.typ
=f32bit
then
284 if (p
^.left
^.location
.loc
<>LOC_REGISTER
) and
285 (p
^.registers32
<1) then
287 p
^.location
.loc
:=LOC_REGISTER
;
290 p
^.location
.loc
:=LOC_FPU
;
293 else if (cs_mmx
in aktlocalswitches
) and
294 is_mmx_able_array(p
^.left
^.resulttype
) then
296 if (p
^.left
^.location
.loc
<>LOC_MMXREGISTER
) and
297 (p
^.registersmmx
<1) then
299 { if saturation is on, p^.left^.resulttype isn't
301 if (cs_mmx_saturation in aktlocalswitches^) and
302 (porddef(parraydef(p^.resulttype)^.definition)^.typ in
303 [s32bit,u32bit]) then
304 CGMessage(type_e_mismatch);
308 else if is_64bitint(p
^.left
^.resulttype
) then
311 p
^.registersfpu
:=p
^.left
^.registersfpu
;
313 p
^.registersmmx
:=p
^.left
^.registersmmx
;
315 p
^.registers32
:=p
^.left
^.registers32
;
318 if (p
^.left
^.location
.loc
<>LOC_REGISTER
) and
319 (p
^.registers32
<2) then
321 p
^.location
.loc
:=LOC_REGISTER
;
322 p
^.resulttype
:=p
^.left
^.resulttype
;
324 else if (p
^.left
^.resulttype
^.deftype
=orddef
) then
326 p
^.left
:=gentypeconvnode(p
^.left
,s32bitdef
);
328 p
^.registersfpu
:=p
^.left
^.registersfpu
;
330 p
^.registersmmx
:=p
^.left
^.registersmmx
;
332 p
^.registers32
:=p
^.left
^.registers32
;
335 if (p
^.left
^.location
.loc
<>LOC_REGISTER
) and
336 (p
^.registers32
<1) then
338 p
^.location
.loc
:=LOC_REGISTER
;
339 p
^.resulttype
:=p
^.left
^.resulttype
;
343 if assigned(overloaded_operators
[_minus
]) then
344 minusdef
:=overloaded_operators
[_minus
]^.definition
347 while assigned(minusdef
) do
349 if is_equal(pparaitem(minusdef
^.para
^.first
)^.paratype
.def
,p
^.left
^.resulttype
) and
350 (pparaitem(minusdef
^.para
^.first
)^.next
=nil) then
352 t
:=gencallnode(overloaded_operators
[_minus
],nil);
353 t
^.left
:=gencallparanode(p
^.left
,nil);
359 minusdef
:=minusdef
^.nextoverloaded
;
361 CGMessage(type_e_mismatch
);
366 {*****************************************************************************
368 *****************************************************************************}
370 procedure firstnot(var p
: ptree
);
376 set_varstate(p
^.left
,true);
380 if (p
^.left
^.treetype
=ordconstn
) then
382 if is_boolean(p
^.left
^.resulttype
) then
383 t
:=genordinalconstnode(byte(not(boolean(p
^.left
^.value
))),p
^.left
^.resulttype
)
385 t
:=genordinalconstnode(not(p
^.left
^.value
),p
^.left
^.resulttype
);
391 p
^.resulttype
:=p
^.left
^.resulttype
;
392 p
^.location
.loc
:=p
^.left
^.location
.loc
;
394 p
^.registersmmx
:=p
^.left
^.registersmmx
;
396 if is_boolean(p
^.resulttype
) then
398 p
^.registers32
:=p
^.left
^.registers32
;
399 if (p
^.location
.loc
in [LOC_REFERENCE
,LOC_MEM
,LOC_CREGISTER
]) then
401 p
^.location
.loc
:=LOC_REGISTER
;
402 if (p
^.registers32
<1) then
405 { before loading it into flags we need to load it into
406 a register thus 1 register is need PM }
408 if p
^.left
^.location
.loc
<>LOC_JUMP
then
409 p
^.location
.loc
:=LOC_FLAGS
;
414 if (cs_mmx
in aktlocalswitches
) and
415 is_mmx_able_array(p
^.left
^.resulttype
) then
417 if (p
^.left
^.location
.loc
<>LOC_MMXREGISTER
) and
418 (p
^.registersmmx
<1) then
423 if is_64bitint(p
^.left
^.resulttype
) then
425 p
^.registers32
:=p
^.left
^.registers32
;
426 if (p
^.location
.loc
in [LOC_REFERENCE
,LOC_MEM
,LOC_CREGISTER
]) then
428 p
^.location
.loc
:=LOC_REGISTER
;
429 if (p
^.registers32
<2) then
433 else if is_integer(p
^.left
^.resulttype
) then
435 p
^.left
:=gentypeconvnode(p
^.left
,s32bitdef
);
440 p
^.resulttype
:=p
^.left
^.resulttype
;
441 p
^.registers32
:=p
^.left
^.registers32
;
443 p
^.registersmmx
:=p
^.left
^.registersmmx
;
446 if (p
^.left
^.location
.loc
<>LOC_REGISTER
) and
447 (p
^.registers32
<1) then
449 p
^.location
.loc
:=LOC_REGISTER
;
453 if assigned(overloaded_operators
[_op_not
]) then
454 notdef
:=overloaded_operators
[_op_not
]^.definition
457 while assigned(notdef
) do
459 if is_equal(pparaitem(notdef
^.para
^.first
)^.paratype
.def
,p
^.left
^.resulttype
) and
460 (pparaitem(notdef
^.para
^.first
)^.next
=nil) then
462 t
:=gencallnode(overloaded_operators
[_op_not
],nil);
463 t
^.left
:=gencallparanode(p
^.left
,nil);
469 notdef
:=notdef
^.nextoverloaded
;
471 CGMessage(type_e_mismatch
);
474 p
^.registersfpu
:=p
^.left
^.registersfpu
;
482 Revision 1.1 2002/02/19 08:24:04 sasu
485 Revision 1.1.2.3 2000/12/16 15:54:00 jonas
486 * 'resulttype of cardinal shl/shr x' is cardinal instead of longint
488 Revision 1.1.2.2 2000/12/15 13:55:46 jonas
489 * fixed bug in division of qwords (introduced by previous patch)
491 Revision 1.1.2.1 2000/12/13 12:25:40 jonas
492 + also added 64bit conversion when using cardinals and signed
493 expressions for div (in tcmat this time :)
494 * removed automatic type conversion back to dword of 64bit results
496 Revision 1.1 2000/07/13 06:29:59 michael
499 Revision 1.31 2000/06/05 20:41:18 pierre
500 + support for NOT overloading
501 + unsupported overloaded operators generate errors
503 Revision 1.30 2000/06/02 21:13:56 pierre
504 * use is_equal instead of direct def equality in unary minus overload
506 Revision 1.29 2000/02/17 14:53:43 florian
507 * some updates for the newcg
509 Revision 1.28 2000/02/09 13:23:08 peter
512 Revision 1.27 2000/01/07 01:14:46 peter
513 * updated copyright to 2000
515 Revision 1.26 1999/12/11 18:53:31 jonas
516 * fixed type conversions of results of operations with cardinals
517 (between -dcardinalmulfix)
519 Revision 1.25 1999/11/30 10:40:58 peter
522 Revision 1.24 1999/11/26 13:51:29 pierre
523 * fix for overloading of shr shl mod and div
525 Revision 1.23 1999/11/18 15:34:50 pierre
526 * Notes/Hints for local syms changed to
527 Set_varstate function
529 Revision 1.22 1999/11/06 14:34:30 peter
530 * truncated log to 20 revs
532 Revision 1.21 1999/10/26 12:30:46 peter
533 * const parameter is now checked
534 * better and generic check if a node can be used for assigning
536 * procvar equal works now (it never had worked at least from 0.99.8)
537 * defcoll changed to linkedlist with pparaitem so it can easily be
538 walked both directions
540 Revision 1.20 1999/08/23 23:37:01 pierre
541 * firstnot register counting error corrected
543 Revision 1.19 1999/08/04 13:03:15 jonas
544 * all tokens now start with an underscore
547 Revision 1.18 1999/08/04 00:23:43 florian
548 * renamed i386asm and i386base to cpuasm and cpubase
550 Revision 1.17 1999/08/03 22:03:34 peter
551 * moved bitmask constants to sets
552 * some other type/const renamings