~ubuntu-branches/ubuntu/dapper/fpc/dapper

« back to all changes in this revision

Viewing changes to compiler/cg68kinl.pas

  • Committer: Bazaar Package Importer
  • Author(s): Carlos Laviola
  • Date: 2004-08-12 16:29:37 UTC
  • mfrom: (1.2.1 upstream) (2.1.1 warty)
  • Revision ID: james.westby@ubuntu.com-20040812162937-moo8ulvysp1ln771
Tags: 1.9.4-5
fp-compiler: needs ld, adding dependency on binutils.  (Closes: #265265)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
{
2
 
    $Id: cg68kinl.pas,v 1.1 2000/07/13 06:29:46 michael Exp $
3
 
    Copyright (c) 1998-2000 by Florian Klaempfl
4
 
 
5
 
    Generate m68k inline nodes
6
 
 
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.
11
 
 
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.
16
 
 
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.
20
 
 
21
 
 ****************************************************************************
22
 
}
23
 
unit cg68kinl;
24
 
interface
25
 
 
26
 
    uses
27
 
      tree;
28
 
 
29
 
    procedure secondinline(var p : ptree);
30
 
 
31
 
 
32
 
implementation
33
 
 
34
 
    uses
35
 
      globtype,systems,symconst,
36
 
      cobjects,verbose,globals,
37
 
      aasm,types,symtable,
38
 
      hcodegen,temp_gen,pass_2,
39
 
      cpubase,cga68k,tgen68k,cg68kld,cg68kcal;
40
 
 
41
 
 
42
 
{*****************************************************************************
43
 
                                Helpers
44
 
*****************************************************************************}
45
 
 
46
 
    { reverts the parameter list }
47
 
    var nb_para : integer;
48
 
 
49
 
    function reversparameter(p : ptree) : ptree;
50
 
 
51
 
       var
52
 
         hp1,hp2 : ptree;
53
 
 
54
 
      begin
55
 
         hp1:=nil;
56
 
         nb_para := 0;
57
 
         while assigned(p) do
58
 
           begin
59
 
              { pull out }
60
 
              hp2:=p;
61
 
              p:=p^.right;
62
 
              inc(nb_para);
63
 
              { pull in }
64
 
              hp2^.right:=hp1;
65
 
              hp1:=hp2;
66
 
           end;
67
 
         reversparameter:=hp1;
68
 
       end;
69
 
 
70
 
 
71
 
{*****************************************************************************
72
 
                             SecondInLine
73
 
*****************************************************************************}
74
 
 
75
 
    procedure secondinline(var p : ptree);
76
 
       const
77
 
         { tfloattype = (f32bit,s32real,s64real,s80real,s64bit); }
78
 
         float_name: array[tfloattype] of string[8]=
79
 
           ('FIXED','SINGLE','REAL','EXTENDED','COMP','FIXED16');
80
 
         addqconstsubop:array[in_inc_x..in_dec_x] of tasmop=(A_ADDQ,A_SUBQ);
81
 
         addconstsubop:array[in_inc_x..in_dec_x] of tasmop=(A_ADD,A_SUB);
82
 
         addsubop:array[in_inc_x..in_dec_x] of tasmop=(A_ADD,A_SUB);
83
 
       var
84
 
         aktfile : treference;
85
 
         ft : tfiletype;
86
 
         opsize : topsize;
87
 
         asmop : tasmop;
88
 
         pushed : tpushed;
89
 
         {inc/dec}
90
 
         addconstant : boolean;
91
 
         addvalue : longint;
92
 
 
93
 
 
94
 
      procedure handlereadwrite(doread,doln : boolean);
95
 
      { produces code for READ(LN) and WRITE(LN) }
96
 
 
97
 
        procedure loadstream;
98
 
          const
99
 
            io:array[0..1] of string[7]=('_OUTPUT','_INPUT');
100
 
          var
101
 
            r : preference;
102
 
          begin
103
 
            new(r);
104
 
            reset_reference(r^);
105
 
            r^.symbol:=stringdup(
106
 
            'U_'+upper(target_info.system_unit)+io[byte(doread)]);
107
 
            exprasmlist^.concat(new(paicpu,op_ref_reg(A_LEA,S_L,r,R_A0)))
108
 
          end;
109
 
 
110
 
        var
111
 
           node,hp    : ptree;
112
 
           typedtyp,
113
 
           pararesult : pdef;
114
 
           has_length : boolean;
115
 
           dummycoll  : tdefcoll;
116
 
           iolabel    : pasmlabel;
117
 
           npara      : longint;
118
 
 
119
 
        begin
120
 
           { I/O check }
121
 
           if (cs_check_io in aktlocalswitches) and
122
 
              not(po_iocheck in aktprocsym^.definition^.procoptions) then
123
 
             begin
124
 
                getlabel(iolabel);
125
 
                emitl(A_LABEL,iolabel);
126
 
             end
127
 
           else
128
 
             iolabel:=nil;
129
 
           { for write of real with the length specified }
130
 
           has_length:=false;
131
 
           hp:=nil;
132
 
           { reserve temporary pointer to data variable }
133
 
           aktfile.symbol:=nil;
134
 
           gettempofsizereference(4,aktfile);
135
 
           { first state text data }
136
 
           ft:=ft_text;
137
 
           { and state a parameter ? }
138
 
           if p^.left=nil then
139
 
             begin
140
 
                { the following instructions are for "writeln;" }
141
 
                loadstream;
142
 
                { save @aktfile in temporary variable }
143
 
                exprasmlist^.concat(new(paicpu,op_reg_ref(A_MOVE,S_L,R_A0,newreference(aktfile))));
144
 
             end
145
 
           else
146
 
             begin
147
 
                { revers paramters }
148
 
                node:=reversparameter(p^.left);
149
 
 
150
 
                p^.left := node;
151
 
                npara := nb_para;
152
 
                { calculate data variable }
153
 
                { is first parameter a file type ? }
154
 
                if node^.left^.resulttype^.deftype=filedef then
155
 
                  begin
156
 
                     ft:=pfiledef(node^.left^.resulttype)^.filetype;
157
 
                     if ft=ft_typed then
158
 
                       typedtyp:=pfiledef(node^.left^.resulttype)^.typed_as;
159
 
                     secondpass(node^.left);
160
 
                     if codegenerror then
161
 
                       exit;
162
 
 
163
 
                     { save reference in temporary variables }
164
 
                     if node^.left^.location.loc<>LOC_REFERENCE then
165
 
                       begin
166
 
                          CGMessage(cg_e_illegal_expression);
167
 
                          exit;
168
 
                       end;
169
 
 
170
 
                     exprasmlist^.concat(new(paicpu,op_ref_reg(A_LEA,S_L,newreference(node^.left^.location.reference),R_A0)));
171
 
 
172
 
                     { skip to the next parameter }
173
 
                     node:=node^.right;
174
 
                  end
175
 
                else
176
 
                  begin
177
 
                  { load stdin/stdout stream }
178
 
                     loadstream;
179
 
                  end;
180
 
 
181
 
                { save @aktfile in temporary variable }
182
 
                exprasmlist^.concat(new(paicpu,op_reg_ref(A_MOVE,S_L,R_A0,newreference(aktfile))));
183
 
                if doread then
184
 
                { parameter by READ gives call by reference }
185
 
                  dummycoll.paratyp:=vs_var
186
 
                { an WRITE Call by "Const" }
187
 
                else
188
 
                  dummycoll.paratyp:=vs_const;
189
 
 
190
 
                { because of secondcallparan, which otherwise attaches }
191
 
                if ft=ft_typed then
192
 
                  { this is to avoid copy of simple const parameters }
193
 
                  {dummycoll.data:=new(pformaldef,init)}
194
 
                  dummycoll.data:=cformaldef
195
 
                else
196
 
                  { I think, this isn't a good solution (FK) }
197
 
                  dummycoll.data:=nil;
198
 
 
199
 
                while assigned(node) do
200
 
                  begin
201
 
                     pushusedregisters(pushed,$ff);
202
 
                     hp:=node;
203
 
                     node:=node^.right;
204
 
                     hp^.right:=nil;
205
 
                     if hp^.is_colon_para then
206
 
                       CGMessage(parser_e_illegal_colon_qualifier);
207
 
                     if ft=ft_typed then
208
 
                       never_copy_const_param:=true;
209
 
                     secondcallparan(hp,@dummycoll,false);
210
 
                     if ft=ft_typed then
211
 
                       never_copy_const_param:=false;
212
 
                     hp^.right:=node;
213
 
                     if codegenerror then
214
 
                       exit;
215
 
 
216
 
                     emit_push_mem(aktfile);
217
 
                     if (ft=ft_typed) then
218
 
                       begin
219
 
                          { OK let's try this }
220
 
                          { first we must only allow the right type }
221
 
                          { we have to call blockread or blockwrite }
222
 
                          { but the real problem is that            }
223
 
                          { reset and rewrite should have set       }
224
 
                          { the type size                           }
225
 
                          { as recordsize for that file !!!!        }
226
 
                          { how can we make that                    }
227
 
                          { I think that is only possible by adding }
228
 
                          { reset and rewrite to the inline list a call        }
229
 
                          { allways read only one record by element }
230
 
                            push_int(typedtyp^.size);
231
 
                            if doread then
232
 
                              emitcall('FPC_TYPED_READ',true)
233
 
                            else
234
 
                              emitcall('FPC_TYPED_WRITE',true);
235
 
                       end
236
 
                     else
237
 
                       begin
238
 
                          { save current position }
239
 
                          pararesult:=hp^.left^.resulttype;
240
 
                          { handle possible field width  }
241
 
                          { of course only for write(ln) }
242
 
                          if not doread then
243
 
                            begin
244
 
                               { handle total width parameter }
245
 
                              if assigned(node) and node^.is_colon_para then
246
 
                                begin
247
 
                                   hp:=node;
248
 
                                   node:=node^.right;
249
 
                                   hp^.right:=nil;
250
 
                                   secondcallparan(hp,@dummycoll,false);
251
 
                                   hp^.right:=node;
252
 
                                   if codegenerror then
253
 
                                     exit;
254
 
                                   has_length:=true;
255
 
                                end
256
 
                              else
257
 
                                if pararesult^.deftype<>floatdef then
258
 
                                  push_int(0)
259
 
                                else
260
 
                                  push_int(-32767);
261
 
                            { a second colon para for a float ? }
262
 
                              if assigned(node) and node^.is_colon_para then
263
 
                                begin
264
 
                                   hp:=node;
265
 
                                   node:=node^.right;
266
 
                                   hp^.right:=nil;
267
 
                                   secondcallparan(hp,@dummycoll,false);
268
 
                                   hp^.right:=node;
269
 
                                   if pararesult^.deftype<>floatdef then
270
 
                                     CGMessage(parser_e_illegal_colon_qualifier);
271
 
                                   if codegenerror then
272
 
                                     exit;
273
 
                                end
274
 
                              else
275
 
                                begin
276
 
                                  if pararesult^.deftype=floatdef then
277
 
                                    push_int(-1);
278
 
                                end
279
 
                            end;
280
 
                          case pararesult^.deftype of
281
 
                       stringdef : begin
282
 
                                     if doread then
283
 
                                       begin
284
 
                                       { push maximum string length }
285
 
                                       push_int(pstringdef(pararesult)^.len);
286
 
                                       case pstringdef(pararesult)^.string_typ of
287
 
                                        st_shortstring:
288
 
                                          emitcall ('FPC_READ_TEXT_STRING',true);
289
 
                                        st_ansistring:
290
 
                                          emitcall ('FPC_READ_TEXT_ANSISTRING',true);
291
 
                                        st_longstring:
292
 
                                          emitcall ('FPC_READ_TEXT_LONGSTRING',true);
293
 
                                        st_widestring:
294
 
                                          emitcall ('FPC_READ_TEXT_ANSISTRING',true);
295
 
                                        end
296
 
                                       end
297
 
                                     else
298
 
                                       Case pstringdef(Pararesult)^.string_typ of
299
 
                                        st_shortstring:
300
 
                                          emitcall ('FPC_WRITE_TEXT_STRING',true);
301
 
                                        st_ansistring:
302
 
                                          emitcall ('FPC_WRITE_TEXT_ANSISTRING',true);
303
 
                                        st_longstring:
304
 
                                          emitcall ('FPC_WRITE_TEXT_LONGSTRING',true);
305
 
                                        st_widestring:
306
 
                                          emitcall ('FPC_WRITE_TEXT_ANSISTRING',true);
307
 
                                        end;
308
 
                                   end;
309
 
                      pointerdef : begin
310
 
                                     if is_equal(ppointerdef(pararesult)^.definition,cchardef) then
311
 
                                       begin
312
 
                                         if doread then
313
 
                                           emitcall('FPC_READ_TEXT_PCHAR_AS_POINTER',true)
314
 
                                         else
315
 
                                           emitcall('FPC_WRITE_TEXT_PCHAR_AS_POINTER',true);
316
 
                                       end;
317
 
                                   end;
318
 
                        arraydef : begin
319
 
                                     if (parraydef(pararesult)^.lowrange=0) and
320
 
                                        is_equal(parraydef(pararesult)^.definition,cchardef) then
321
 
                                       begin
322
 
                                         if doread then
323
 
                                           emitcall('FPC_READ_TEXT_PCHAR_AS_ARRAY',true)
324
 
                                         else
325
 
                                           emitcall('FPC_WRITE_TEXT_PCHAR_AS_ARRAY',true);
326
 
                                       end;
327
 
                                   end;
328
 
                        floatdef : begin
329
 
                                     if doread then
330
 
                                       emitcall('FPC_READ_TEXT_'+float_name[pfloatdef(pararesult)^.typ],true)
331
 
                                     else
332
 
                                       emitcall('FPC_WRITE_TEXT_'+float_name[pfloatdef(pararesult)^.typ],true);
333
 
                                   end;
334
 
                          orddef : begin
335
 
                                     case porddef(pararesult)^.typ of
336
 
                                          u8bit : if doread then
337
 
                                                    emitcall('FPC_READ_TEXT_BYTE',true);
338
 
                                          s8bit : if doread then
339
 
                                                    emitcall('FPC_READ_TEXT_SHORTINT',true);
340
 
                                         u16bit : if doread then
341
 
                                                    emitcall('FPC_READ_TEXT_WORD',true);
342
 
                                         s16bit : if doread then
343
 
                                                    emitcall('FPC_READ_TEXT_INTEGER',true);
344
 
                                         s32bit : if doread then
345
 
                                                    emitcall('FPC_READ_TEXT_LONGINT',true)
346
 
                                                  else
347
 
                                                    emitcall('FPC_WRITE_TEXT_LONGINT',true);
348
 
                                         u32bit : if doread then
349
 
                                                    emitcall('FPC_READ_TEXT_CARDINAL',true)
350
 
                                                  else
351
 
                                                    emitcall('FPC_WRITE_TEXT_CARDINAL',true);
352
 
                                          uchar : if doread then
353
 
                                                    emitcall('FPC_READ_TEXT_CHAR',true)
354
 
                                                  else
355
 
                                                    emitcall('FPC_WRITE_TEXT_CHAR',true);
356
 
                                       bool8bit,
357
 
                                      bool16bit,
358
 
                                      bool32bit : if  doread then
359
 
                                                    CGMessage(parser_e_illegal_parameter_list)
360
 
                                                  else
361
 
                                                    emitcall('FPC_WRITE_TEXT_BOOLEAN',true);
362
 
                                     end;
363
 
                                   end;
364
 
                          end;
365
 
                       end;
366
 
                   { load ESI in methods again }
367
 
                     popusedregisters(pushed);
368
 
                     maybe_loada5;
369
 
                  end;
370
 
             end;
371
 
         { Insert end of writing for textfiles }
372
 
           if ft=ft_text then
373
 
             begin
374
 
               pushusedregisters(pushed,$ff);
375
 
               emit_push_mem(aktfile);
376
 
               if doread then
377
 
                begin
378
 
                  if doln then
379
 
                    emitcall('FPC_READLN_END',true)
380
 
                  else
381
 
                    emitcall('FPC_READ_END',true);
382
 
                end
383
 
               else
384
 
                begin
385
 
                  if doln then
386
 
                    emitcall('FPC_WRITELN_END',true)
387
 
                  else
388
 
                    emitcall('FPC_WRITE_END',true);
389
 
                end;
390
 
               popusedregisters(pushed);
391
 
               maybe_loada5;
392
 
             end;
393
 
         { Insert IOCheck if set }
394
 
           if assigned(iolabel) then
395
 
             begin
396
 
                { registers are saved in the procedure }
397
 
                exprasmlist^.concat(new(paicpu,op_csymbol(A_PEA,S_L,newcsymbol(iolabel^.name,0))));
398
 
                emitcall('FPC_IOCHECK',true);
399
 
             end;
400
 
         { Freeup all used temps }
401
 
           ungetiftemp(aktfile);
402
 
           if assigned(p^.left) then
403
 
             begin
404
 
                p^.left:=reversparameter(p^.left);
405
 
                if npara<>nb_para then
406
 
                  CGMessage(cg_f_internal_error_in_secondinline);
407
 
                hp:=p^.left;
408
 
                while assigned(hp) do
409
 
                  begin
410
 
                     if assigned(hp^.left) then
411
 
                       if (hp^.left^.location.loc in [LOC_MEM,LOC_REFERENCE]) then
412
 
                         ungetiftemp(hp^.left^.location.reference);
413
 
                     hp:=hp^.right;
414
 
                  end;
415
 
             end;
416
 
        end;
417
 
 
418
 
      procedure handle_str;
419
 
 
420
 
        var
421
 
           hp,node : ptree;
422
 
           dummycoll : tdefcoll;
423
 
           is_real,has_length : boolean;
424
 
 
425
 
          begin
426
 
           pushusedregisters(pushed,$ff);
427
 
           node:=p^.left;
428
 
           is_real:=false;
429
 
           has_length:=false;
430
 
           while assigned(node^.right) do node:=node^.right;
431
 
           { if a real parameter somewhere then call REALSTR }
432
 
           if (node^.left^.resulttype^.deftype=floatdef) then
433
 
             is_real:=true;
434
 
 
435
 
           node:=p^.left;
436
 
           { we have at least two args }
437
 
           { with at max 2 colon_para in between }
438
 
 
439
 
           { first arg longint or float }
440
 
           hp:=node;
441
 
           node:=node^.right;
442
 
           hp^.right:=nil;
443
 
           dummycoll.data:=hp^.resulttype;
444
 
           { string arg }
445
 
 
446
 
           dummycoll.paratyp:=vs_var;
447
 
           secondcallparan(hp,@dummycoll,false);
448
 
           if codegenerror then
449
 
             exit;
450
 
 
451
 
           dummycoll.paratyp:=vs_const;
452
 
           disposetree(hp);
453
 
           p^.left:=nil;
454
 
 
455
 
           { second arg }
456
 
           hp:=node;
457
 
           node:=node^.right;
458
 
           hp^.right:=nil;
459
 
           { frac  para }
460
 
           if hp^.is_colon_para and assigned(node) and
461
 
              node^.is_colon_para then
462
 
             begin
463
 
                dummycoll.data:=hp^.resulttype;
464
 
                secondcallparan(hp,@dummycoll,false);
465
 
                if codegenerror then
466
 
                  exit;
467
 
                disposetree(hp);
468
 
                hp:=node;
469
 
                node:=node^.right;
470
 
                hp^.right:=nil;
471
 
                has_length:=true;
472
 
             end
473
 
           else
474
 
             if is_real then
475
 
             push_int(-1);
476
 
 
477
 
           { third arg, length only if is_real }
478
 
           if hp^.is_colon_para then
479
 
             begin
480
 
                dummycoll.data:=hp^.resulttype;
481
 
                secondcallparan(hp,@dummycoll,false);
482
 
                if codegenerror then
483
 
                  exit;
484
 
                disposetree(hp);
485
 
                hp:=node;
486
 
                node:=node^.right;
487
 
                hp^.right:=nil;
488
 
             end
489
 
           else
490
 
             if is_real then
491
 
               push_int(-32767)
492
 
             else
493
 
               push_int(-1);
494
 
 
495
 
           { last arg longint or real }
496
 
           secondcallparan(hp,@dummycoll,false);
497
 
           if codegenerror then
498
 
             exit;
499
 
 
500
 
           disposetree(hp);
501
 
 
502
 
           if is_real then
503
 
             emitcall('FPC_STR_'+float_name[pfloatdef(hp^.resulttype)^.typ],true)
504
 
           else if porddef(hp^.resulttype)^.typ=u32bit then
505
 
             emitcall('FPC_STR_CARDINAL',true)
506
 
           else
507
 
             emitcall('FPC_STR_LONGINT',true);
508
 
           popusedregisters(pushed);
509
 
        end;
510
 
 
511
 
      var
512
 
         r : preference;
513
 
         l : longint;
514
 
         ispushed : boolean;
515
 
         hregister : tregister;
516
 
         otlabel,oflabel,filenamestring : pasmlabel;
517
 
         oldpushedparasize : longint;
518
 
      begin
519
 
      { save & reset pushedparasize }
520
 
         oldpushedparasize:=pushedparasize;
521
 
         pushedparasize:=0;
522
 
         case p^.inlinenumber of
523
 
            in_assert_x_y:
524
 
              begin
525
 
               { !!!!!!!!! }
526
 
              end;
527
 
            in_lo_word,
528
 
            in_hi_word :
529
 
              begin
530
 
                       secondpass(p^.left);
531
 
                       p^.location.loc:=LOC_REGISTER;
532
 
                       if p^.left^.location.loc<>LOC_REGISTER then
533
 
                         begin
534
 
                            if p^.left^.location.loc=LOC_CREGISTER then
535
 
                              begin
536
 
                                 p^.location.register:=getregister32;
537
 
                                 emit_reg_reg(A_MOVE,S_W,p^.left^.location.register,
538
 
                                   p^.location.register);
539
 
                              end
540
 
                            else
541
 
                              begin
542
 
                                 del_reference(p^.left^.location.reference);
543
 
                                 p^.location.register:=getregister32;
544
 
                                 exprasmlist^.concat(new(paicpu,op_ref_reg(A_MOVE,S_W,
545
 
                                  newreference(p^.left^.location.reference),
546
 
                                  p^.location.register)));
547
 
                              end;
548
 
                         end
549
 
                       else p^.location.register:=p^.left^.location.register;
550
 
                       if p^.inlinenumber=in_hi_word then
551
 
                         exprasmlist^.concat(new(paicpu,op_const_reg(A_LSR,S_W,8,p^.location.register)));
552
 
                       p^.location.register:=p^.location.register;
553
 
              end;
554
 
            in_high_x :
555
 
              begin
556
 
                 if is_open_array(p^.left^.resulttype) then
557
 
                   begin
558
 
                      secondpass(p^.left);
559
 
                      del_reference(p^.left^.location.reference);
560
 
                      p^.location.register:=getregister32;
561
 
                      new(r);
562
 
                      reset_reference(r^);
563
 
                      r^.base:=highframepointer;
564
 
                      r^.offset:=highoffset+4;
565
 
                      exprasmlist^.concat(new(paicpu,op_ref_reg(A_MOVE,S_L,
566
 
                        r,p^.location.register)));
567
 
                   end
568
 
              end;
569
 
            in_sizeof_x,
570
 
            in_typeof_x :
571
 
              begin
572
 
               { sizeof(openarray) handling }
573
 
                 if (p^.inlinenumber=in_sizeof_x) and
574
 
                    is_open_array(p^.left^.resulttype) then
575
 
                  begin
576
 
                  { sizeof(openarray)=high(openarray)+1 }
577
 
                    secondpass(p^.left);
578
 
                    del_reference(p^.left^.location.reference);
579
 
                    p^.location.register:=getregister32;
580
 
                    new(r);
581
 
                    reset_reference(r^);
582
 
                    r^.base:=highframepointer;
583
 
                    r^.offset:=highoffset+4;
584
 
                    exprasmlist^.concat(new(paicpu,op_ref_reg(A_MOVE,S_L,
585
 
                      r,p^.location.register)));
586
 
                    exprasmlist^.concat(new(paicpu,op_const_reg(A_ADD,S_L,
587
 
                      1,p^.location.register)));
588
 
                    if parraydef(p^.left^.resulttype)^.elesize<>1 then
589
 
                      exprasmlist^.concat(new(paicpu,op_const_reg(A_MULS,S_L,
590
 
                        parraydef(p^.left^.resulttype)^.elesize,p^.location.register)));
591
 
                  end
592
 
                 else
593
 
                  begin
594
 
                    { for both cases load vmt }
595
 
                    if p^.left^.treetype=typen then
596
 
                      begin
597
 
                        exprasmlist^.concat(new(paicpu,op_csymbol_reg(A_LEA,
598
 
                          S_L,newcsymbol(pobjectdef(p^.left^.resulttype)^.vmt_mangledname,0),
599
 
                          R_A0)));
600
 
                        p^.location.register:=getregister32;
601
 
                        emit_reg_reg(A_MOVE,S_L,R_A0,p^.location.register);
602
 
                      end
603
 
                    else
604
 
                      begin
605
 
                        secondpass(p^.left);
606
 
                        del_reference(p^.left^.location.reference);
607
 
                        p^.location.loc:=LOC_REGISTER;
608
 
                        p^.location.register:=getregister32;
609
 
                        { load VMT pointer }
610
 
                        inc(p^.left^.location.reference.offset,
611
 
                          pobjectdef(p^.left^.resulttype)^.vmt_offset);
612
 
                        exprasmlist^.concat(new(paicpu,op_ref_reg(A_MOVE,S_L,
613
 
                          newreference(p^.left^.location.reference),
614
 
                          p^.location.register)));
615
 
                      end;
616
 
                    { in sizeof load size }
617
 
                    if p^.inlinenumber=in_sizeof_x then
618
 
                      begin
619
 
                         new(r);
620
 
                         reset_reference(r^);
621
 
                        { load the address in A0 }
622
 
                        { because now supposedly p^.location.register is an }
623
 
                        { address.                                          }
624
 
                        emit_reg_reg(A_MOVE, S_L, p^.location.register, R_A0);
625
 
                        r^.base:=R_A0;
626
 
                        exprasmlist^.concat(new(paicpu,op_ref_reg(A_MOVE,S_L,r,
627
 
                          p^.location.register)));
628
 
                      end;
629
 
                  end;
630
 
              end;
631
 
            in_lo_long,
632
 
            in_hi_long : begin
633
 
                       secondpass(p^.left);
634
 
                       p^.location.loc:=LOC_REGISTER;
635
 
                       if p^.left^.location.loc<>LOC_REGISTER then
636
 
                         begin
637
 
                            if p^.left^.location.loc=LOC_CREGISTER then
638
 
                              begin
639
 
                                 p^.location.register:=getregister32;
640
 
                                 emit_reg_reg(A_MOVE,S_L,p^.left^.location.register,
641
 
                                   p^.location.register);
642
 
                              end
643
 
                            else
644
 
                              begin
645
 
                                 del_reference(p^.left^.location.reference);
646
 
                                 p^.location.register:=getregister32;
647
 
                                 exprasmlist^.concat(new(paicpu,op_ref_reg(A_MOVE,S_L,
648
 
                                  newreference(p^.left^.location.reference),
649
 
                                  p^.location.register)));
650
 
                              end;
651
 
                         end
652
 
                       else p^.location.register:=p^.left^.location.register;
653
 
                       if p^.inlinenumber=in_hi_long then
654
 
                         begin
655
 
                           exprasmlist^.concat(new(paicpu,op_const_reg(A_MOVEQ, S_L, 16, R_D1)));
656
 
                           exprasmlist^.concat(new(paicpu,op_reg_reg(A_LSR,S_L,R_D1,p^.location.register)));
657
 
                         end;
658
 
                       p^.location.register:=p^.location.register;
659
 
                    end;
660
 
            in_length_string :
661
 
              begin
662
 
                 secondpass(p^.left);
663
 
                 set_location(p^.location,p^.left^.location);
664
 
                 { length in ansi strings is at offset -8 }
665
 
                 if is_ansistring(p^.left^.resulttype) then
666
 
                   dec(p^.location.reference.offset,8);
667
 
              end;
668
 
            in_pred_x,
669
 
            in_succ_x:
670
 
              begin
671
 
                 secondpass(p^.left);
672
 
                 if p^.inlinenumber=in_pred_x then
673
 
                   asmop:=A_SUB
674
 
                 else
675
 
                   asmop:=A_ADD;
676
 
                 case p^.resulttype^.size of
677
 
                   4 : opsize:=S_L;
678
 
                   2 : opsize:=S_W;
679
 
                   1 : opsize:=S_B;
680
 
                 else
681
 
                    internalerror(10080);
682
 
                 end;
683
 
                 p^.location.loc:=LOC_REGISTER;
684
 
                 if p^.left^.location.loc<>LOC_REGISTER then
685
 
                   begin
686
 
                      p^.location.register:=getregister32;
687
 
                      if p^.left^.location.loc=LOC_CREGISTER then
688
 
                        emit_reg_reg(A_MOVE,opsize,p^.left^.location.register,
689
 
                          p^.location.register)
690
 
                      else
691
 
                      if p^.left^.location.loc=LOC_FLAGS then
692
 
                        exprasmlist^.concat(new(paicpu,op_reg(flag_2_set[p^.left^.location.resflags],S_NO,
693
 
                                  p^.location.register)))
694
 
                      else
695
 
                        begin
696
 
                           del_reference(p^.left^.location.reference);
697
 
                           exprasmlist^.concat(new(paicpu,op_ref_reg(A_MOVE,opsize,newreference(p^.left^.location.reference),
698
 
                             p^.location.register)));
699
 
                        end;
700
 
                   end
701
 
                 else p^.location.register:=p^.left^.location.register;
702
 
                 exprasmlist^.concat(new(paicpu,op_const_reg(asmop,opsize,1,
703
 
                   p^.location.register)))
704
 
                 { here we should insert bounds check ? }
705
 
                 { and direct call to bounds will crash the program }
706
 
                 { if we are at the limit }
707
 
                 { we could also simply say that pred(first)=first and succ(last)=last }
708
 
                 { could this be usefull I don't think so (PM)
709
 
                 emitoverflowcheck;}
710
 
              end;
711
 
            in_dec_x,
712
 
            in_inc_x :
713
 
              begin
714
 
              { set defaults }
715
 
                addvalue:=1;
716
 
                addconstant:=true;
717
 
              { load first parameter, must be a reference }
718
 
                secondpass(p^.left^.left);
719
 
                case p^.left^.left^.resulttype^.deftype of
720
 
                  orddef,
721
 
                 enumdef : begin
722
 
                             case p^.left^.left^.resulttype^.size of
723
 
                              1 : opsize:=S_B;
724
 
                              2 : opsize:=S_W;
725
 
                              4 : opsize:=S_L;
726
 
                             end;
727
 
                           end;
728
 
              pointerdef : begin
729
 
                             opsize:=S_L;
730
 
                             addvalue:=ppointerdef(p^.left^.left^.resulttype)^.definition^.size;
731
 
                           end;
732
 
                else
733
 
                 internalerror(10081);
734
 
                end;
735
 
              { second argument specified?, must be a s32bit in register }
736
 
                if assigned(p^.left^.right) then
737
 
                 begin
738
 
                   secondpass(p^.left^.right^.left);
739
 
                 { when constant, just multiply the addvalue }
740
 
                   if is_constintnode(p^.left^.right^.left) then
741
 
                    addvalue:=addvalue*get_ordinal_value(p^.left^.right^.left)
742
 
                   else
743
 
                    begin
744
 
                      case p^.left^.right^.left^.location.loc of
745
 
                   LOC_REGISTER,
746
 
                  LOC_CREGISTER : hregister:=p^.left^.right^.left^.location.register;
747
 
                        LOC_MEM,
748
 
                  LOC_REFERENCE : begin
749
 
                                    hregister:=getregister32;
750
 
                                    exprasmlist^.concat(new(paicpu,op_ref_reg(A_MOVE,S_L,
751
 
                                      newreference(p^.left^.right^.left^.location.reference),hregister)));
752
 
                                  end;
753
 
                       else
754
 
                        internalerror(10082);
755
 
                       end;
756
 
                    { insert multiply with addvalue if its >1 }
757
 
                      if addvalue>1 then
758
 
                       exprasmlist^.concat(new(paicpu,op_const_reg(A_MULS,opsize,
759
 
                         addvalue,hregister)));
760
 
                      addconstant:=false;
761
 
                    end;
762
 
                 end;
763
 
              { write the add instruction }
764
 
                if addconstant then
765
 
                 begin
766
 
                   if (addvalue > 0) and (addvalue < 9) then
767
 
                    exprasmlist^.concat(new(paicpu,op_const_ref(addqconstsubop[p^.inlinenumber],opsize,
768
 
                      addvalue,newreference(p^.left^.left^.location.reference))))
769
 
                   else
770
 
                    exprasmlist^.concat(new(paicpu,op_const_ref(addconstsubop[p^.inlinenumber],opsize,
771
 
                      addvalue,newreference(p^.left^.left^.location.reference))));
772
 
                 end
773
 
                else
774
 
                 begin
775
 
                   exprasmlist^.concat(new(paicpu,op_reg_ref(addsubop[p^.inlinenumber],opsize,
776
 
                      hregister,newreference(p^.left^.left^.location.reference))));
777
 
                   ungetregister32(hregister);
778
 
                 end;
779
 
                emitoverflowcheck(p^.left^.left);
780
 
              end;
781
 
            in_assigned_x :
782
 
              begin
783
 
                secondpass(p^.left^.left);
784
 
                p^.location.loc:=LOC_FLAGS;
785
 
                if (p^.left^.left^.location.loc=LOC_REGISTER) or
786
 
                   (p^.left^.left^.location.loc=LOC_CREGISTER) then
787
 
                 begin
788
 
                   exprasmlist^.concat(new(paicpu,op_reg(A_TST,S_L,
789
 
                    p^.left^.left^.location.register)));
790
 
                   ungetregister32(p^.left^.left^.location.register);
791
 
                 end
792
 
                else
793
 
                 begin
794
 
                   exprasmlist^.concat(new(paicpu,op_ref(A_TST,S_L,
795
 
                   newreference(p^.left^.left^.location.reference))));
796
 
                   del_reference(p^.left^.left^.location.reference);
797
 
                 end;
798
 
                p^.location.resflags:=F_NE;
799
 
              end;
800
 
             in_reset_typedfile,in_rewrite_typedfile :
801
 
               begin
802
 
                  pushusedregisters(pushed,$ffff);
803
 
                  exprasmlist^.concat(new(paicpu,op_const_reg(A_MOVE,S_L,
804
 
                    pfiledef(p^.left^.resulttype)^.typed_as^.size,R_SPPUSH)));
805
 
                  secondload(p^.left);
806
 
                  emitpushreferenceaddr(exprasmlist,p^.left^.location.reference);
807
 
                  if p^.inlinenumber=in_reset_typedfile then
808
 
                    emitcall('FPC_RESET_TYPED',true)
809
 
                  else
810
 
                    emitcall('FPC_REWRITE_TYPED',true);
811
 
                  popusedregisters(pushed);
812
 
               end;
813
 
            in_write_x :
814
 
              handlereadwrite(false,false);
815
 
            in_writeln_x :
816
 
              handlereadwrite(false,true);
817
 
            in_read_x :
818
 
              handlereadwrite(true,false);
819
 
            in_readln_x :
820
 
              handlereadwrite(true,true);
821
 
            in_str_x_string :
822
 
              begin
823
 
                 handle_str;
824
 
                 maybe_loada5;
825
 
              end;
826
 
            in_include_x_y,
827
 
            in_exclude_x_y:
828
 
              begin
829
 
                 CGMessage(cg_e_include_not_implemented);
830
 
{ !!!!!!!  }
831
 
(*               secondpass(p^.left^.left);
832
 
                 if p^.left^.right^.left^.treetype=ordconstn then
833
 
                   begin
834
 
                      { calculate bit position }
835
 
                      l:=1 shl (p^.left^.right^.left^.value mod 32);
836
 
 
837
 
                      { determine operator }
838
 
                      if p^.inlinenumber=in_include_x_y then
839
 
                        asmop:=A_OR
840
 
                      else
841
 
                        begin
842
 
                           asmop:=A_AND;
843
 
                           l:=not(l);
844
 
                        end;
845
 
                      if (p^.left^.left^.location.loc=LOC_REFERENCE) then
846
 
                        begin
847
 
                           inc(p^.left^.left^.location.reference.offset,(p^.left^.right^.left^.value div 32)*4);
848
 
                           exprasmlist^.concat(new(paicpu,op_const_ref(asmop,S_L,
849
 
                             l,newreference(p^.left^.left^.location.reference))));
850
 
                           del_reference(p^.left^.left^.location.reference);
851
 
                        end
852
 
                      else
853
 
                        { LOC_CREGISTER }
854
 
                        exprasmlist^.concat(new(paicpu,op_const_reg(asmop,S_L,
855
 
                          l,p^.left^.left^.location.register)));
856
 
                   end
857
 
                 else
858
 
                   begin
859
 
                      { generate code for the element to set }
860
 
                      ispushed:=maybe_push(p^.left^.right^.left^.registers32,p^.left^.left);
861
 
                      secondpass(p^.left^.right^.left);
862
 
                      if ispushed then
863
 
                        restore(p^.left^.left);
864
 
                      { determine asm operator }
865
 
                      if p^.inlinenumber=in_include_x_y then
866
 
                        asmop:=A_BTS
867
 
                      else
868
 
                        asmop:=A_BTR;
869
 
                      if psetdef(p^.left^.resulttype)^.settype=smallset then
870
 
                        begin
871
 
                           if p^.left^.right^.left^.location.loc in [LOC_CREGISTER,LOC_REGISTER] then
872
 
                             hregister:=p^.left^.right^.left^.location.register
873
 
                           else
874
 
                             begin
875
 
                                hregister:=R_EDI;
876
 
                                exprasmlist^.concat(new(paicpu,op_ref_reg(A_MOV,S_L,
877
 
                                  newreference(p^.left^.right^.left^.location.reference),R_EDI)));
878
 
                             end;
879
 
                          if (p^.left^.left^.location.loc=LOC_REFERENCE) then
880
 
                            exprasmlist^.concat(new(paicpu,op_reg_ref(asmop,S_L,R_EDI,
881
 
                              newreference(p^.left^.right^.left^.location.reference))))
882
 
                          else
883
 
                            exprasmlist^.concat(new(paicpu,op_reg_reg(asmop,S_L,R_EDI,
884
 
                              p^.left^.right^.left^.location.register)));
885
 
                        end
886
 
                      else
887
 
                        begin
888
 
                           internalerror(10083);
889
 
                        end;
890
 
                   end;
891
 
                   *)
892
 
               end;
893
 
 
894
 
         else
895
 
           internalerror(9);
896
 
         end;
897
 
         pushedparasize:=oldpushedparasize;
898
 
      end;
899
 
 
900
 
end.
901
 
{
902
 
  $Log: cg68kinl.pas,v $
903
 
  Revision 1.1  2000/07/13 06:29:46  michael
904
 
  + Initial import
905
 
 
906
 
  Revision 1.22  2000/02/09 13:22:49  peter
907
 
    * log truncated
908
 
 
909
 
  Revision 1.21  2000/01/07 01:14:22  peter
910
 
    * updated copyright to 2000
911
 
 
912
 
  Revision 1.20  1999/12/20 21:42:35  pierre
913
 
    + dllversion global variable
914
 
    * FPC_USE_CPREFIX code removed, not necessary anymore
915
 
      as we use .edata direct writing by default now.
916
 
 
917
 
  Revision 1.19  1999/11/20 01:22:18  pierre
918
 
    + cond FPC_USE_CPREFIX (needs also some RTL changes)
919
 
      this allows to use unit global vars as DLL exports
920
 
      (the underline prefix seems needed by dlltool)
921
 
 
922
 
  Revision 1.18  1999/09/16 23:05:51  florian
923
 
    * m68k compiler is again compilable (only gas writer, no assembler reader)
924
 
 
925
 
  Revision 1.17  1999/08/25 11:59:50  jonas
926
 
    * changed pai386, paippc and paiapha (same for tai*) to paicpu (taicpu)
927
 
 
928
 
}
929