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

« back to all changes in this revision

Viewing changes to compiler/i386/n386set.pas

  • Committer: Bazaar Package Importer
  • Author(s): Carlos Laviola
  • Date: 2005-05-30 11:59:10 UTC
  • mfrom: (1.2.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20050530115910-x5pbzm4qqta4i94h
Tags: 2.0.0-2
debian/fp-compiler.postinst.in: forgot to reapply the patch that
correctly creates the slave link to pc(1).  (Closes: #310907)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
{
2
 
    $Id: n386set.pas,v 1.74 2004/05/22 23:34:28 peter Exp $
 
2
    $Id: n386set.pas,v 1.78 2005/02/14 17:13:10 peter Exp $
3
3
    Copyright (c) 1998-2002 by Florian Klaempfl
4
4
 
5
5
    Generate i386 assembler for in set/case nodes
27
27
interface
28
28
 
29
29
    uses
 
30
      globtype,
30
31
      node,nset,pass_1,ncgset;
31
32
 
32
33
    type
33
34
      ti386casenode = class(tcgcasenode)
34
 
         procedure optimizevalues(var max_linear_list:longint;var max_dist:cardinal);override;
 
35
         procedure optimizevalues(var max_linear_list:aint;var max_dist:aword);override;
35
36
         function  has_jumptable : boolean;override;
36
 
         procedure genjumptable(hp : pcaserecord;min_,max_ : longint);override;
37
 
         procedure genlinearlist(hp : pcaserecord);override;
 
37
         procedure genjumptable(hp : pcaselabel;min_,max_ : aint);override;
 
38
         procedure genlinearlist(hp : pcaselabel);override;
38
39
      end;
39
40
 
40
41
 
41
42
implementation
42
43
 
43
44
    uses
44
 
      globtype,systems,
 
45
      systems,
45
46
      verbose,globals,
46
47
      symconst,symdef,defutil,
47
48
      aasmbase,aasmtai,aasmcpu,
56
57
                            TI386CASENODE
57
58
*****************************************************************************}
58
59
 
59
 
    procedure ti386casenode.optimizevalues(var max_linear_list:longint;var max_dist:cardinal);
 
60
    procedure ti386casenode.optimizevalues(var max_linear_list:aint;var max_dist:aword);
60
61
      begin
61
62
        { a jump table crashes the pipeline! }
62
63
        if aktoptprocessor=Class386 then
76
77
      end;
77
78
 
78
79
 
79
 
    procedure ti386casenode.genjumptable(hp : pcaserecord;min_,max_ : longint);
 
80
    procedure ti386casenode.genjumptable(hp : pcaselabel;min_,max_ : aint);
80
81
      var
81
82
        table : tasmlabel;
82
83
        last : TConstExprInt;
84
85
        href : treference;
85
86
        jumpsegment : TAAsmOutput;
86
87
 
87
 
        procedure genitem(t : pcaserecord);
 
88
        procedure genitem(t : pcaselabel);
88
89
          var
89
 
            i : longint;
 
90
            i : aint;
90
91
          begin
91
92
            if assigned(t^.less) then
92
93
              genitem(t^.less);
93
94
            { fill possible hole }
94
95
            for i:=last+1 to t^._low-1 do
95
 
              jumpSegment.concat(Tai_const_symbol.Create(elselabel));
 
96
              jumpSegment.concat(Tai_const.Create_sym(elselabel));
96
97
            for i:=t^._low to t^._high do
97
 
              jumpSegment.concat(Tai_const_symbol.Create(t^.statement));
 
98
              jumpSegment.concat(Tai_const.Create_sym(blocklabel(t^.blockid)));
98
99
            last:=t^._high;
99
100
            if assigned(t^.greater) then
100
101
              genitem(t^.greater);
101
102
          end;
102
103
 
103
104
      begin
104
 
        if (cs_create_smart in aktmoduleswitches) then
 
105
        if (cs_create_smart in aktmoduleswitches) or
 
106
           (af_smartlink_sections in target_asm.flags) then
105
107
          jumpsegment:=current_procinfo.aktlocaldata
106
108
        else
107
109
          jumpsegment:=datasegment;
108
110
        if not(jumptable_no_range) then
109
111
          begin
110
112
             { case expr less than min_ => goto elselabel }
111
 
             cg.a_cmp_const_reg_label(exprasmlist,opsize,jmp_lt,aword(min_),hregister,elselabel);
 
113
             cg.a_cmp_const_reg_label(exprasmlist,opsize,jmp_lt,aint(min_),hregister,elselabel);
112
114
             { case expr greater than max_ => goto elselabel }
113
 
             cg.a_cmp_const_reg_label(exprasmlist,opsize,jmp_gt,aword(max_),hregister,elselabel);
 
115
             cg.a_cmp_const_reg_label(exprasmlist,opsize,jmp_gt,aint(max_),hregister,elselabel);
114
116
          end;
115
117
        objectlibrary.getlabel(table);
116
118
        { make it a 32bit register }
118
120
        cg.a_load_reg_reg(exprasmlist,opsize,OS_INT,hregister,indexreg);
119
121
        { create reference }
120
122
        reference_reset_symbol(href,table,0);
121
 
        href.offset:=(-longint(min_))*4;
 
123
        href.offset:=(-aint(min_))*4;
122
124
        href.index:=indexreg;
123
125
        href.scalefactor:=4;
124
126
        emit_ref(A_JMP,S_NO,href);
131
133
      end;
132
134
 
133
135
 
134
 
    procedure ti386casenode.genlinearlist(hp : pcaserecord);
 
136
    procedure ti386casenode.genlinearlist(hp : pcaselabel);
135
137
      var
136
138
        first : boolean;
137
139
        lastrange : boolean;
138
140
        last : TConstExprInt;
139
141
        cond_lt,cond_le : tresflags;
140
142
 
141
 
        procedure genitem(t : pcaserecord);
 
143
        procedure genitem(t : pcaselabel);
142
144
          begin
143
145
             if assigned(t^.less) then
144
146
               genitem(t^.less);
145
147
             { need we to test the first value }
146
148
             if first and (t^._low>get_min_value(left.resulttype.def)) then
147
149
               begin
148
 
                 cg.a_cmp_const_reg_label(exprasmlist,opsize,jmp_lt,aword(t^._low),hregister,elselabel);
 
150
                 cg.a_cmp_const_reg_label(exprasmlist,opsize,jmp_lt,aint(t^._low),hregister,elselabel);
149
151
               end;
150
152
             if t^._low=t^._high then
151
153
               begin
152
154
                  if t^._low-last=0 then
153
 
                    cg.a_cmp_const_reg_label(exprasmlist, opsize, OC_EQ,0,hregister,t^.statement)
 
155
                    cg.a_cmp_const_reg_label(exprasmlist, opsize, OC_EQ,0,hregister,blocklabel(t^.blockid))
154
156
                  else
155
157
                    begin
156
 
                      cg.a_op_const_reg(exprasmlist, OP_SUB, opsize, aword(t^._low-last), hregister);
157
 
                      cg.a_jmp_flags(exprasmlist,F_E,t^.statement);
 
158
                      cg.a_op_const_reg(exprasmlist, OP_SUB, opsize, aint(t^._low-last), hregister);
 
159
                      cg.a_jmp_flags(exprasmlist,F_E,blocklabel(t^.blockid));
158
160
                    end;
159
161
                  last:=t^._low;
160
162
                  lastrange:=false;
168
170
                    begin
169
171
                       { have we to ajust the first value ? }
170
172
                       if (t^._low>get_min_value(left.resulttype.def)) then
171
 
                         cg.a_op_const_reg(exprasmlist, OP_SUB, opsize, longint(t^._low), hregister);
 
173
                         cg.a_op_const_reg(exprasmlist, OP_SUB, opsize, aint(t^._low), hregister);
172
174
                    end
173
175
                  else
174
176
                    begin
176
178
                      { present label then the lower limit can be checked    }
177
179
                      { immediately. else check the range in between:       }
178
180
 
179
 
                      cg.a_op_const_reg(exprasmlist, OP_SUB, opsize, longint(t^._low-last), hregister);
 
181
                      cg.a_op_const_reg(exprasmlist, OP_SUB, opsize, aint(t^._low-last), hregister);
180
182
                      { no jump necessary here if the new range starts at }
181
183
                      { at the value following the previous one           }
182
184
                      if ((t^._low-last) <> 1) or
185
187
                    end;
186
188
                  {we need to use A_SUB, because A_DEC does not set the correct flags, therefor
187
189
                   using a_op_const_reg(OP_SUB) is not possible }
188
 
                  emit_const_reg(A_SUB,TCGSize2OpSize[opsize],longint(t^._high-t^._low),hregister);
189
 
                  cg.a_jmp_flags(exprasmlist,cond_le,t^.statement);
 
190
                  emit_const_reg(A_SUB,TCGSize2OpSize[opsize],aint(t^._high-t^._low),hregister);
 
191
                  cg.a_jmp_flags(exprasmlist,cond_le,blocklabel(t^.blockid));
190
192
                  last:=t^._high;
191
193
                  lastrange:=true;
192
194
               end;
224
226
end.
225
227
{
226
228
  $Log: n386set.pas,v $
227
 
  Revision 1.74  2004/05/22 23:34:28  peter
228
 
  tai_regalloc.allocation changed to ratype to notify rgobj of register size changes
229
 
 
230
 
  Revision 1.73  2004/02/27 10:21:05  florian
231
 
    * top_symbol killed
232
 
    + refaddr to treference added
233
 
    + refsymbol to treference added
234
 
    * top_local stuff moved to an extra record to save memory
235
 
    + aint introduced
236
 
    * tppufile.get/putint64/aint implemented
237
 
 
238
 
  Revision 1.72  2004/02/22 12:04:04  florian
239
 
    + nx86set added
240
 
    * some more x86-64 fixes
241
 
 
242
 
  Revision 1.71  2004/02/03 22:32:54  peter
243
 
    * renamed xNNbittype to xNNinttype
244
 
    * renamed registers32 to registersint
245
 
    * replace some s32bit,u32bit with torddef([su]inttype).def.typ
246
 
 
247
 
  Revision 1.70  2003/11/07 15:58:32  florian
248
 
    * Florian's culmutative nr. 1; contains:
249
 
      - invalid calling conventions for a certain cpu are rejected
250
 
      - arm softfloat calling conventions
251
 
      - -Sp for cpu dependend code generation
252
 
      - several arm fixes
253
 
      - remaining code for value open array paras on heap
254
 
 
255
 
  Revision 1.69  2003/10/10 17:48:14  peter
256
 
    * old trgobj moved to x86/rgcpu and renamed to trgx86fpu
257
 
    * tregisteralloctor renamed to trgobj
258
 
    * removed rgobj from a lot of units
259
 
    * moved location_* and reference_* to cgobj
260
 
    * first things for mmx register allocation
261
 
 
262
 
  Revision 1.68  2003/10/09 21:31:37  daniel
263
 
    * Register allocator splitted, ans abstract now
264
 
 
265
 
  Revision 1.67  2003/10/01 20:34:49  peter
266
 
    * procinfo unit contains tprocinfo
267
 
    * cginfo renamed to cgbase
268
 
    * moved cgmessage to verbose
269
 
    * fixed ppc and sparc compiles
270
 
 
271
 
  Revision 1.66  2003/09/28 21:48:20  peter
272
 
    * fix register leaks
273
 
 
274
 
  Revision 1.65  2003/09/07 22:09:35  peter
275
 
    * preparations for different default calling conventions
276
 
    * various RA fixes
277
 
 
278
 
  Revision 1.64  2003/09/05 11:21:39  marco
279
 
   * applied Peter's patch. Now cycles.
280
 
 
281
 
  Revision 1.63  2003/09/03 15:55:01  peter
282
 
    * NEWRA branch merged
283
 
 
284
 
  Revision 1.62.2.1  2003/08/29 17:29:00  peter
285
 
    * next batch of updates
286
 
 
287
 
  Revision 1.62  2003/06/12 22:10:44  jonas
288
 
    * t386innode.pass_2 already doesn't call a helper anymore since a long
289
 
      time
290
 
 
291
 
  Revision 1.61  2003/06/03 21:11:09  peter
292
 
    * cg.a_load_* get a from and to size specifier
293
 
    * makeregsize only accepts newregister
294
 
    * i386 uses generic tcgnotnode,tcgunaryminus
295
 
 
296
 
  Revision 1.60  2003/06/01 21:38:06  peter
297
 
    * getregisterfpu size parameter added
298
 
    * op_const_reg size parameter added
299
 
    * sparc updates
300
 
 
301
 
  Revision 1.59  2003/05/31 15:04:31  peter
302
 
    * load_loc_reg update
303
 
 
304
 
  Revision 1.58  2003/05/22 21:32:29  peter
305
 
    * removed some unit dependencies
306
 
 
307
 
  Revision 1.57  2003/04/27 11:21:35  peter
308
 
    * aktprocdef renamed to current_procdef
309
 
    * procinfo renamed to current_procinfo
310
 
    * procinfo will now be stored in current_module so it can be
311
 
      cleaned up properly
312
 
    * gen_main_procsym changed to create_main_proc and release_main_proc
313
 
      to also generate a tprocinfo structure
314
 
    * fixed unit implicit initfinal
315
 
 
316
 
  Revision 1.56  2003/04/25 08:25:26  daniel
317
 
    * Ifdefs around a lot of calls to cleartempgen
318
 
    * Fixed registers that are allocated but not freed in several nodes
319
 
    * Tweak to register allocator to cause less spills
320
 
    * 8-bit registers now interfere with esi,edi and ebp
321
 
      Compiler can now compile rtl successfully when using new register
322
 
      allocator
323
 
 
324
 
  Revision 1.55  2003/04/23 09:51:16  daniel
325
 
    * Removed usage of edi in a lot of places when new register allocator used
326
 
    + Added newra versions of g_concatcopy and secondadd_float
327
 
 
328
 
  Revision 1.54  2003/04/22 23:50:23  peter
329
 
    * firstpass uses expectloc
330
 
    * checks if there are differences between the expectloc and
331
 
      location.loc from secondpass in EXTDEBUG
332
 
 
333
 
  Revision 1.53  2003/04/22 14:33:38  peter
334
 
    * removed some notes/hints
335
 
 
336
 
  Revision 1.52  2003/04/22 10:09:35  daniel
337
 
    + Implemented the actual register allocator
338
 
    + Scratch registers unavailable when new register allocator used
339
 
    + maybe_save/maybe_restore unavailable when new register allocator used
340
 
 
341
 
  Revision 1.51  2003/03/13 19:52:23  jonas
342
 
    * and more new register allocator fixes (in the i386 code generator this
343
 
      time). At least now the ppc cross compiler can compile the linux
344
 
      system unit again, but I haven't tested it.
345
 
 
346
 
  Revision 1.50  2003/02/26 23:06:13  daniel
347
 
    * Fixed an illegal use of makeregsize
348
 
 
349
 
  Revision 1.49  2003/02/19 22:39:56  daniel
350
 
    * Fixed a few issues
351
 
 
352
 
  Revision 1.48  2003/02/19 22:00:15  daniel
353
 
    * Code generator converted to new register notation
354
 
    - Horribily outdated todo.txt removed
355
 
 
356
 
  Revision 1.47  2003/01/13 14:54:34  daniel
357
 
    * Further work to convert codegenerator register convention;
358
 
      internalerror bug fixed.
359
 
 
360
 
  Revision 1.46  2003/01/08 18:43:57  daniel
361
 
   * Tregister changed into a record
362
 
 
363
 
  Revision 1.45  2002/11/25 17:43:27  peter
364
 
    * splitted defbase in defutil,symutil,defcmp
365
 
    * merged isconvertable and is_equal into compare_defs(_ext)
366
 
    * made operator search faster by walking the list only once
367
 
 
368
 
  Revision 1.44  2002/10/03 21:34:45  carl
369
 
    * range check error fixes
370
 
 
371
 
  Revision 1.43  2002/09/17 18:54:05  jonas
372
 
    * a_load_reg_reg() now has two size parameters: source and dest. This
373
 
      allows some optimizations on architectures that don't encode the
374
 
      register size in the register name.
375
 
 
376
 
  Revision 1.42  2002/09/16 18:08:26  peter
377
 
    * fix last optimization in genlinearlist, detected by bug tw1066
378
 
    * use generic casenode.pass2 routine and override genlinearlist
379
 
    * add jumptable support to generic casenode, by default there is
380
 
      no jumptable support
381
 
 
382
 
  Revision 1.41  2002/09/09 13:57:45  jonas
383
 
    * small optimization to case genlist() case statements
384
 
 
385
 
  Revision 1.40  2002/08/17 09:23:46  florian
386
 
    * first part of procinfo rewrite
387
 
 
388
 
  Revision 1.39  2002/08/12 15:08:42  carl
389
 
    + stab register indexes for powerpc (moved from gdb to cpubase)
390
 
    + tprocessor enumeration moved to cpuinfo
391
 
    + linker in target_info is now a class
392
 
    * many many updates for m68k (will soon start to compile)
393
 
    - removed some ifdef or correct them for correct cpu
394
 
 
395
 
  Revision 1.38  2002/08/11 14:32:30  peter
396
 
    * renamed current_library to objectlibrary
397
 
 
398
 
  Revision 1.37  2002/08/11 13:24:17  peter
399
 
    * saving of asmsymbols in ppu supported
400
 
    * asmsymbollist global is removed and moved into a new class
401
 
      tasmlibrarydata that will hold the info of a .a file which
402
 
      corresponds with a single module. Added librarydata to tmodule
403
 
      to keep the library info stored for the module. In the future the
404
 
      objectfiles will also be stored to the tasmlibrarydata class
405
 
    * all getlabel/newasmsymbol and friends are moved to the new class
406
 
 
407
 
  Revision 1.36  2002/07/23 14:31:00  daniel
408
 
  * Added internal error when asked to generate code for 'if expr in []'
409
 
 
410
 
  Revision 1.35  2002/07/20 11:58:04  florian
411
 
    * types.pas renamed to defbase.pas because D6 contains a types
412
 
      unit so this would conflicts if D6 programms are compiled
413
 
    + Willamette/SSE2 instructions to assembler added
414
 
 
415
 
  Revision 1.34  2002/07/11 14:41:34  florian
416
 
    * start of the new generic parameter handling
417
 
 
418
 
  Revision 1.33  2002/07/06 20:27:26  carl
419
 
  + generic set handling
420
 
 
421
 
  Revision 1.32  2002/07/01 18:46:33  peter
422
 
    * internal linker
423
 
    * reorganized aasm layer
424
 
 
425
 
  Revision 1.31  2002/05/18 13:34:25  peter
426
 
    * readded missing revisions
427
 
 
428
 
  Revision 1.30  2002/05/16 19:46:52  carl
429
 
  + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
430
 
  + try to fix temp allocation (still in ifdef)
431
 
  + generic constructor calls
432
 
  + start of tassembler / tmodulebase class cleanup
433
 
 
434
 
  Revision 1.28  2002/05/13 19:54:38  peter
435
 
    * removed n386ld and n386util units
436
 
    * maybe_save/maybe_restore added instead of the old maybe_push
437
 
 
438
 
  Revision 1.27  2002/05/12 16:53:17  peter
439
 
    * moved entry and exitcode to ncgutil and cgobj
440
 
    * foreach gets extra argument for passing local data to the
441
 
      iterator function
442
 
    * -CR checks also class typecasts at runtime by changing them
443
 
      into as
444
 
    * fixed compiler to cycle with the -CR option
445
 
    * fixed stabs with elf writer, finally the global variables can
446
 
      be watched
447
 
    * removed a lot of routines from cga unit and replaced them by
448
 
      calls to cgobj
449
 
    * u32bit-s32bit updates for and,or,xor nodes. When one element is
450
 
      u32bit then the other is typecasted also to u32bit without giving
451
 
      a rangecheck warning/error.
452
 
    * fixed pascal calling method with reversing also the high tree in
453
 
      the parast, detected by tcalcst3 test
454
 
 
455
 
  Revision 1.26  2002/04/25 20:16:40  peter
456
 
    * moved more routines from cga/n386util
457
 
 
458
 
  Revision 1.25  2002/04/21 19:02:07  peter
459
 
    * removed newn and disposen nodes, the code is now directly
460
 
      inlined from pexpr
461
 
    * -an option that will write the secondpass nodes to the .s file, this
462
 
      requires EXTDEBUG define to actually write the info
463
 
    * fixed various internal errors and crashes due recent code changes
464
 
 
465
 
  Revision 1.24  2002/04/21 15:37:26  carl
466
 
  * changeregsize -> rg.makeregsize
467
 
 
468
 
  Revision 1.23  2002/04/19 15:39:35  peter
469
 
    * removed some more routines from cga
470
 
    * moved location_force_reg/mem to ncgutil
471
 
    * moved arrayconstructnode secondpass to ncgld
472
 
 
473
 
  Revision 1.22  2002/04/15 19:44:21  peter
474
 
    * fixed stackcheck that would be called recursively when a stack
475
 
      error was found
476
 
    * generic changeregsize(reg,size) for i386 register resizing
477
 
    * removed some more routines from cga unit
478
 
    * fixed returnvalue handling
479
 
    * fixed default stacksize of linux and go32v2, 8kb was a bit small :-)
480
 
 
481
 
  Revision 1.21  2002/04/02 17:11:36  peter
482
 
    * tlocation,treference update
483
 
    * LOC_CONSTANT added for better constant handling
484
 
    * secondadd splitted in multiple routines
485
 
    * location_force_reg added for loading a location to a register
486
 
      of a specified size
487
 
    * secondassignment parses now first the right and then the left node
488
 
      (this is compatible with Kylix). This saves a lot of push/pop especially
489
 
      with string operations
490
 
    * adapted some routines to use the new cg methods
491
 
 
492
 
  Revision 1.20  2002/03/31 20:26:39  jonas
493
 
    + a_loadfpu_* and a_loadmm_* methods in tcg
494
 
    * register allocation is now handled by a class and is mostly processor
495
 
      independent (+rgobj.pas and i386/rgcpu.pas)
496
 
    * temp allocation is now handled by a class (+tgobj.pas, -i386\tgcpu.pas)
497
 
    * some small improvements and fixes to the optimizer
498
 
    * some register allocation fixes
499
 
    * some fpuvaroffset fixes in the unary minus node
500
 
    * push/popusedregisters is now called rg.save/restoreusedregisters and
501
 
      (for i386) uses temps instead of push/pop's when using -Op3 (that code is
502
 
      also better optimizable)
503
 
    * fixed and optimized register saving/restoring for new/dispose nodes
504
 
    * LOC_FPU locations now also require their "register" field to be set to
505
 
      R_ST, not R_ST0 (the latter is used for LOC_CFPUREGISTER locations only)
506
 
    - list field removed of the tnode class because it's not used currently
507
 
      and can cause hard-to-find bugs
 
229
  Revision 1.78  2005/02/14 17:13:10  peter
 
230
    * truncate log
508
231
 
509
232
}