3 Copyright (c) 1998-2000 by Florian Klaempfl
5 Generate m68k assembler for load/assignment 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 ****************************************************************************
30 { this is for open arrays and strings }
31 { but be careful, this data is in the }
32 { generated code destroyed quick, and also }
33 { the next call of secondload destroys this }
35 { So be careful using the informations }
36 { provided by this variables }
37 highframepointer
: tregister
;
40 procedure secondload(var p
: ptree
);
41 procedure secondassignment(var p
: ptree
);
42 procedure secondfuncret(var p
: ptree
);
43 procedure secondarrayconstruct(var p
: ptree
);
49 cobjects
,verbose
,globals
,symconst
,
51 hcodegen
,temp_gen
,pass_2
,
55 {*****************************************************************************
57 *****************************************************************************}
59 procedure secondload(var p
: ptree
);
62 hregister
: tregister
;
64 symtabletype
: tsymtabletype
;
69 reset_reference(p
^.location
.reference
);
70 case p
^.symtableentry
^.typ
of
71 { this is only for toasm and toaddr }
74 stringdispose(p
^.location
.reference
.symbol
);
75 p
^.location
.reference
.symbol
:=stringdup(p
^.symtableentry
^.mangledname
);
80 symtabletype
:=p
^.symtable
^.symtabletype
;
81 { in case it is a register variable: }
82 { we simply set the location to the }
84 if pvarsym(p
^.symtableentry
)^.reg
<>R_NO
then
86 p
^.location
.loc
:=LOC_CREGISTER
;
87 p
^.location
.register:=pvarsym(p
^.symtableentry
)^.reg
;
88 unused
:=unused
-[pvarsym(p
^.symtableentry
)^.reg
];
92 { --------------------- LOCAL AND TEMP VARIABLES ------------- }
93 if (symtabletype
=parasymtable
) or (symtabletype
=localsymtable
) then
96 p
^.location
.reference
.base
:=procinfo
^.framepointer
;
97 p
^.location
.reference
.offset
:=pvarsym(p
^.symtableentry
)^.address
;
99 if (symtabletype
=localsymtable
) then
100 p
^.location
.reference
.offset
:=-p
^.location
.reference
.offset
;
102 if (symtabletype
in [localsymtable
,inlinelocalsymtable
]) then
103 p
^.location
.reference
.offset
:=-p
^.location
.reference
.offset
;
105 if (lexlevel
>(p
^.symtable
^.symtablelevel
)) then
107 hregister
:=getaddressreg
;
111 reset_reference(hp
^);
112 hp
^.offset
:=procinfo
^.framepointer_offset
;
113 hp
^.base
:=procinfo
^.framepointer
;
115 exprasmlist
^.concat(new(paicpu
,op_ref_reg(A_MOVE
,S_L
,hp
,hregister
)));
119 while i
>(p
^.symtable
^.symtablelevel
) do
123 reset_reference(hp
^);
127 exprasmlist
^.concat(new(paicpu
,op_ref_reg(A_MOVE
,S_L
,hp
,hregister
)));
130 p
^.location
.reference
.base
:=hregister
;
133 { --------------------- END OF LOCAL AND TEMP VARS ---------------- }
136 unitsymtable
,globalsymtable
,
137 staticsymtable
: begin
138 stringdispose(p
^.location
.reference
.symbol
);
139 p
^.location
.reference
.symbol
:=stringdup(p
^.symtableentry
^.mangledname
);
141 objectsymtable
: begin
142 if sp_static
in pvarsym(p
^.symtableentry
)^.symoptions
then
144 stringdispose(p
^.location
.reference
.symbol
);
145 p
^.location
.reference
.symbol
:=stringdup(p
^.symtableentry
^.mangledname
);
149 p
^.location
.reference
.base
:=R_A5
;
150 p
^.location
.reference
.offset
:=pvarsym(p
^.symtableentry
)^.address
;
154 hregister
:=getaddressreg
;
155 p
^.location
.reference
.base
:=hregister
;
158 reset_reference(hp
^);
159 hp
^.offset
:=p
^.symtable
^.datasize
;
160 hp
^.base
:=procinfo
^.framepointer
;
162 exprasmlist
^.concat(new(paicpu
,op_ref_reg(A_MOVE
,S_L
,hp
,hregister
)));
164 p
^.location
.reference
.offset
:=
165 pvarsym(p
^.symtableentry
)^.address
;
169 { in case call by reference, then calculate: }
170 if (pvarsym(p
^.symtableentry
)^.varspez
=vs_var
) or
171 is_open_array(pvarsym(p
^.symtableentry
)^.definition
) or
172 is_array_of_const(pvarsym(p
^.symtableentry
)^.definition
) or
173 ((pvarsym(p
^.symtableentry
)^.varspez
=vs_const
) and
174 push_addr_param(pvarsym(p
^.symtableentry
)^.definition
)) then
177 if hregister
=R_NO
then
178 hregister
:=getaddressreg
;
179 { ADDED FOR OPEN ARRAY SUPPORT. }
180 if (p
^.location
.reference
.base
=procinfo
^.framepointer
) then
182 highframepointer
:=p
^.location
.reference
.base
;
183 highoffset
:=p
^.location
.reference
.offset
;
187 highframepointer
:=R_A1
;
188 highoffset
:=p
^.location
.reference
.offset
;
189 exprasmlist
^.concat(new(paicpu
,op_reg_reg(A_MOVE
,S_L
,
190 p
^.location
.reference
.base
,R_A1
)));
192 exprasmlist
^.concat(new(paicpu
,op_ref_reg(A_MOVE
,S_L
,newreference(p
^.location
.reference
),
195 clear_reference(p
^.location
.reference
);
196 p
^.location
.reference
.base
:=hregister
;
198 { should be dereferenced later (FK)
199 if (pvarsym(p^.symtableentry)^.definition^.deftype=objectdef) and
200 ((pobjectdef(pvarsym(p^.symtableentry)^.definition)^.options and oo_is_class)<>0) then
203 if hregister=R_NO then
204 hregister:=getaddressreg;
205 exprasmlist^.concat(new(paicpu,op_ref_reg(A_MOVE,S_L,newreference(p^.location.reference),
207 clear_reference(p^.location.reference);
208 p^.location.reference.base:=hregister;
215 {!!!!! Be aware, work on virtual methods too }
216 stringdispose(p
^.location
.reference
.symbol
);
217 p
^.location
.reference
.symbol
:=
218 stringdup(pprocsym(p
^.symtableentry
)^.definition
^.mangledname
);
222 stringdispose(p
^.location
.reference
.symbol
);
223 p
^.location
.reference
.symbol
:=stringdup(p
^.symtableentry
^.mangledname
);
225 else internalerror(4);
230 {*****************************************************************************
232 *****************************************************************************}
234 procedure secondassignment(var p
: ptree
);
238 withresult
: boolean;
239 otlabel
,hlabel
,oflabel
: pasmlabel
;
240 hregister
: tregister
;
248 getlabel(falselabel
);
250 { calculate left sides }
254 loc
:=p
^.left
^.location
.loc
;
255 { lets try to optimize this (PM) }
256 { define a dest_loc that is the location }
257 { and a ptree to verify that it is the right }
258 { place to insert it }
259 {$ifdef test_dest_loc}
260 if (aktexprlevel
<4) then
262 dest_loc_known
:=true;
263 dest_loc
:=p
^.left
^.location
;
264 dest_loc_tree
:=p
^.right
;
266 {$endif test_dest_loc}
268 pushed
:=maybe_push(p
^.right
^.registers32
,p
^.left
);
269 secondpass(p
^.right
);
270 if pushed
then restore(p
^.left
);
274 {$ifdef test_dest_loc}
275 dest_loc_known
:=false;
283 {$endif test_dest_loc}
284 if p
^.left
^.resulttype
^.deftype
=stringdef
then
286 { we do not need destination anymore }
287 del_reference(p
^.left
^.location
.reference
);
288 { only source if withresult is set }
289 if not(withresult
) then
290 del_reference(p
^.right
^.location
.reference
);
292 ungetiftemp(p
^.right
^.location
.reference
);
294 else case p
^.right
^.location
.loc
of
297 { handle ordinal constants trimmed }
298 if (p
^.right
^.treetype
in [ordconstn
,fixconstn
]) or
299 (loc
=LOC_CREGISTER
) then
301 case p
^.left
^.resulttype
^.size
of
306 if loc
=LOC_CREGISTER
then
307 exprasmlist
^.concat(new(paicpu
,op_ref_reg(A_MOVE
,opsize
,
308 newreference(p
^.right
^.location
.reference
),
309 p
^.left
^.location
.register)))
311 exprasmlist
^.concat(new(paicpu
,op_const_ref(A_MOVE
,opsize
,
312 p
^.right
^.location
.reference
.offset
,
313 newreference(p
^.left
^.location
.reference
))));
314 {exprasmlist^.concat(new(paicpu,op_const_loc(A_MOV,opsize,
315 p^.right^.location.reference.offset,
316 p^.left^.location)));}
320 concatcopy(p
^.right
^.location
.reference
,
321 p
^.left
^.location
.reference
,p
^.left
^.resulttype
^.size
,
323 ungetiftemp(p
^.right
^.location
.reference
);
327 LOC_CREGISTER
: begin
328 case p
^.right
^.resulttype
^.size
of
333 { simplified with op_reg_loc }
334 if loc
=LOC_CREGISTER
then
335 exprasmlist
^.concat(new(paicpu
,op_reg_reg(A_MOVE
,opsize
,
336 p
^.right
^.location
.register,
337 p
^.left
^.location
.register)))
339 exprasmlist
^.concat(new(paicpu
,op_reg_ref(A_MOVE
,opsize
,
340 p
^.right
^.location
.register,
341 newreference(p
^.left
^.location
.reference
))));
342 {exprasmlist^.concat(new(paicpu,op_reg_loc(A_MOV,opsize,
343 p^.right^.location.register,
344 p^.left^.location))); }
348 if loc
<>LOC_REFERENCE
then
351 floatstore(pfloatdef(p
^.left
^.resulttype
)^.typ
,
352 p
^.right
^.location
,p
^.left
^.location
.reference
);
356 emitl(A_LABEL
,truelabel
);
357 if loc
=LOC_CREGISTER
then
358 exprasmlist
^.concat(new(paicpu
,op_const_reg(A_MOVE
,S_B
,
359 1,p
^.left
^.location
.register)))
361 exprasmlist
^.concat(new(paicpu
,op_const_ref(A_MOVE
,S_B
,
362 1,newreference(p
^.left
^.location
.reference
))));
363 {exprasmlist^.concat(new(paicpu,op_const_loc(A_MOV,S_B,
364 1,p^.left^.location)));}
366 emitl(A_LABEL
,falselabel
);
367 if loc
=LOC_CREGISTER
then
368 exprasmlist
^.concat(new(paicpu
,op_reg(A_CLR
,S_B
,
369 p
^.left
^.location
.register)))
371 exprasmlist
^.concat(new(paicpu
,op_const_ref(A_MOVE
,S_B
,
372 0,newreference(p
^.left
^.location
.reference
))));
373 emitl(A_LABEL
,hlabel
);
376 if loc
=LOC_CREGISTER
then
378 exprasmlist
^.concat(new(paicpu
,op_reg(flag_2_set
[p
^.right
^.location
.resflags
],S_B
,
379 p
^.left
^.location
.register)));
380 exprasmlist
^.concat(new(paicpu
,op_reg(A_NEG
,S_B
,p
^.left
^.location
.register)));
384 exprasmlist
^.concat(new(paicpu
,op_ref(flag_2_set
[p
^.right
^.location
.resflags
],S_B
,
385 newreference(p
^.left
^.location
.reference
))));
386 exprasmlist
^.concat(new(paicpu
,op_ref(A_NEG
,S_B
,newreference(p
^.left
^.location
.reference
))));
396 {*****************************************************************************
398 *****************************************************************************}
400 procedure secondfuncret(var p
: ptree
);
407 clear_reference(p
^.location
.reference
);
411 if @procinfo
<>pprocinfo(p
^.funcretprocinfo
) then
415 hp
:=new_reference(procinfo
^.framepointer
,
416 procinfo
^.framepointer_offset
);
417 exprasmlist
^.concat(new(paicpu
,op_ref_reg(A_MOVE
,S_L
,hp
,hr
)));
419 pp
:=procinfo
^.parent
;
420 { walk up the stack frame }
421 while pp
<>pprocinfo(p
^.funcretprocinfo
) do
423 hp
:=new_reference(hr
,
424 pp
^.framepointer_offset
);
425 exprasmlist
^.concat(new(paicpu
,op_ref_reg(A_MOVE
,S_L
,hp
,hr
)));
428 p
^.location
.reference
.base
:=hr
;
431 p
^.location
.reference
.base
:=procinfo
^.framepointer
;
432 p
^.location
.reference
.offset
:=procinfo
^.retoffset
;
433 if ret_in_param(p
^.retdef
) then
436 { this was wrong !! PM }
438 exprasmlist
^.concat(new(paicpu
,op_ref_reg(A_MOVE
,S_L
,newreference(p
^.location
.reference
),hr
)));
439 p
^.location
.reference
.base
:=hr
;
440 p
^.location
.reference
.offset
:=0;
444 {*****************************************************************************
446 *****************************************************************************}
467 procedure secondarrayconstruct(var p
: ptree
);
474 Revision 1.1 2002/02/19 08:21:49 sasu
477 Revision 1.1 2000/07/13 06:29:46 michael
480 Revision 1.13 2000/02/09 13:22:49 peter
483 Revision 1.12 2000/01/07 01:14:22 peter
484 * updated copyright to 2000
486 Revision 1.11 1999/12/22 01:01:47 peter
487 - removed freelabel()
488 * added undefined label detection in internal assembler, this prevents
489 a lot of ld crashes and wrong .o files
490 * .o files aren't written anymore if errors have occured
491 * inlining of assembler labels is now correct
493 Revision 1.10 1999/11/10 00:06:08 pierre
494 * adapted to procinfo as pointer
496 Revision 1.9 1999/09/16 23:05:51 florian
497 * m68k compiler is again compilable (only gas writer, no assembler reader)
499 Revision 1.8 1999/09/16 11:34:54 pierre