~ubuntu-branches/ubuntu/feisty/fpc/feisty

« back to all changes in this revision

Viewing changes to compiler/x86/nx86add.pas

  • Committer: Bazaar Package Importer
  • Author(s): Torsten Werner
  • Date: 2007-01-27 20:08:50 UTC
  • mfrom: (1.2.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20070127200850-9mrptaqqjsx9nwa7
Tags: 2.0.4-5
* Fixed Build-Depends.
* Add myself to Uploaders in debian/control.
* Make sure that the sources are really patched before building them.
* Build unit 'libc' on powerpc too.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
{
2
 
    $Id: nx86add.pas,v 1.17 2005/02/14 17:13:10 peter Exp $
3
2
    Copyright (c) 2000-2002 by Florian Klaempfl
4
3
 
5
4
    Common code generation for add nodes on the i386 and x86
52
51
        procedure second_cmpsmallset;override;
53
52
        procedure second_cmp64bit;override;
54
53
        procedure second_cmpordinal;override;
 
54
{$ifdef SUPPORT_MMX}
 
55
        procedure second_opmmxset;override;
 
56
        procedure second_opmmx;override;
 
57
{$endif SUPPORT_MMX}
55
58
      end;
56
59
 
57
60
 
62
65
      verbose,cutils,
63
66
      cpuinfo,
64
67
      aasmbase,aasmtai,aasmcpu,
65
 
      symconst,
 
68
      symconst,symdef,
66
69
      cgobj,cgx86,cga,cgutils,
67
70
      paramgr,tgobj,ncgutil,
68
71
      ncon,nset,
212
215
      begin
213
216
        if (right.location.loc<>LOC_FPUREGISTER) then
214
217
         begin
215
 
           cg.a_loadfpu_loc_reg(exprasmlist,right.location,NR_ST);
216
 
           if (right.location.loc <> LOC_CFPUREGISTER) then
217
 
             location_freetemp(exprasmlist,left.location);
 
218
           location_force_fpureg(exprasmlist,right.location,false);
218
219
           if (left.location.loc<>LOC_FPUREGISTER) then
219
 
            begin
220
 
              cg.a_loadfpu_loc_reg(exprasmlist,left.location,NR_ST);
221
 
              if (left.location.loc <> LOC_CFPUREGISTER) then
222
 
                location_freetemp(exprasmlist,left.location);
223
 
            end
 
220
             location_force_fpureg(exprasmlist,left.location,false)
224
221
           else
225
 
            begin
226
 
              { left was on the stack => swap }
227
 
              toggleflag(nf_swaped);
228
 
            end;
 
222
             { left was on the stack => swap }
 
223
             toggleflag(nf_swaped);
229
224
         end
230
225
        { the nominator in st0 }
231
226
        else if (left.location.loc<>LOC_FPUREGISTER) then
232
 
         begin
233
 
           cg.a_loadfpu_loc_reg(exprasmlist,left.location,NR_ST);
234
 
           if (left.location.loc <> LOC_CFPUREGISTER) then
235
 
             location_freetemp(exprasmlist,left.location);
236
 
         end
 
227
          location_force_fpureg(exprasmlist,left.location,false)
237
228
        else
238
229
         begin
239
230
           { fpu operands are always in the wrong order on the stack }
436
427
 
437
428
 
438
429
{*****************************************************************************
 
430
                                AddMMX
 
431
*****************************************************************************}
 
432
 
 
433
{$ifdef SUPPORT_MMX}
 
434
    procedure tx86addnode.second_opmmx;
 
435
      var
 
436
        op         : TAsmOp;
 
437
        cmpop      : boolean;
 
438
        mmxbase    : tmmxtype;
 
439
        hreg,
 
440
        hregister  : tregister;
 
441
      begin
 
442
        pass_left_right;
 
443
 
 
444
        cmpop:=false;
 
445
        mmxbase:=mmx_type(left.resulttype.def);
 
446
        location_reset(location,LOC_MMXREGISTER,def_cgsize(resulttype.def));
 
447
        case nodetype of
 
448
          addn :
 
449
            begin
 
450
              if (cs_mmx_saturation in aktlocalswitches) then
 
451
                begin
 
452
                   case mmxbase of
 
453
                      mmxs8bit:
 
454
                        op:=A_PADDSB;
 
455
                      mmxu8bit:
 
456
                        op:=A_PADDUSB;
 
457
                      mmxs16bit,mmxfixed16:
 
458
                        op:=A_PADDSW;
 
459
                      mmxu16bit:
 
460
                        op:=A_PADDUSW;
 
461
                   end;
 
462
                end
 
463
              else
 
464
                begin
 
465
                   case mmxbase of
 
466
                      mmxs8bit,mmxu8bit:
 
467
                        op:=A_PADDB;
 
468
                      mmxs16bit,mmxu16bit,mmxfixed16:
 
469
                        op:=A_PADDW;
 
470
                      mmxs32bit,mmxu32bit:
 
471
                        op:=A_PADDD;
 
472
                   end;
 
473
                end;
 
474
            end;
 
475
          muln :
 
476
            begin
 
477
               case mmxbase of
 
478
                  mmxs16bit,mmxu16bit:
 
479
                    op:=A_PMULLW;
 
480
                  mmxfixed16:
 
481
                    op:=A_PMULHW;
 
482
               end;
 
483
            end;
 
484
          subn :
 
485
            begin
 
486
              if (cs_mmx_saturation in aktlocalswitches) then
 
487
                begin
 
488
                   case mmxbase of
 
489
                      mmxs8bit:
 
490
                        op:=A_PSUBSB;
 
491
                      mmxu8bit:
 
492
                        op:=A_PSUBUSB;
 
493
                      mmxs16bit,mmxfixed16:
 
494
                        op:=A_PSUBSB;
 
495
                      mmxu16bit:
 
496
                        op:=A_PSUBUSW;
 
497
                   end;
 
498
                end
 
499
              else
 
500
                begin
 
501
                   case mmxbase of
 
502
                      mmxs8bit,mmxu8bit:
 
503
                        op:=A_PSUBB;
 
504
                      mmxs16bit,mmxu16bit,mmxfixed16:
 
505
                        op:=A_PSUBW;
 
506
                      mmxs32bit,mmxu32bit:
 
507
                        op:=A_PSUBD;
 
508
                   end;
 
509
                end;
 
510
            end;
 
511
          xorn:
 
512
            op:=A_PXOR;
 
513
          orn:
 
514
            op:=A_POR;
 
515
          andn:
 
516
            op:=A_PAND;
 
517
          else
 
518
            internalerror(2003042214);
 
519
        end;
 
520
 
 
521
        { left and right no register?  }
 
522
        { then one must be demanded    }
 
523
        if (left.location.loc<>LOC_MMXREGISTER) then
 
524
         begin
 
525
           if (right.location.loc=LOC_MMXREGISTER) then
 
526
            begin
 
527
              location_swap(left.location,right.location);
 
528
              toggleflag(nf_swaped);
 
529
            end
 
530
           else
 
531
            begin
 
532
              { register variable ? }
 
533
              if (left.location.loc=LOC_CMMXREGISTER) then
 
534
               begin
 
535
                 hregister:=tcgx86(cg).getmmxregister(exprasmlist);
 
536
                 emit_reg_reg(A_MOVQ,S_NO,left.location.register,hregister);
 
537
               end
 
538
              else
 
539
               begin
 
540
                 if not(left.location.loc in [LOC_REFERENCE,LOC_CREFERENCE]) then
 
541
                  internalerror(200203245);
 
542
 
 
543
                 hregister:=tcgx86(cg).getmmxregister(exprasmlist);
 
544
                 emit_ref_reg(A_MOVQ,S_NO,left.location.reference,hregister);
 
545
               end;
 
546
 
 
547
              location_reset(left.location,LOC_MMXREGISTER,OS_NO);
 
548
              left.location.register:=hregister;
 
549
            end;
 
550
         end;
 
551
 
 
552
        { at this point, left.location.loc should be LOC_MMXREGISTER }
 
553
        if right.location.loc<>LOC_MMXREGISTER then
 
554
         begin
 
555
           if (nodetype=subn) and (nf_swaped in flags) then
 
556
            begin
 
557
              hreg:=tcgx86(cg).getmmxregister(exprasmlist);
 
558
              if right.location.loc=LOC_CMMXREGISTER then
 
559
               begin
 
560
                 emit_reg_reg(A_MOVQ,S_NO,right.location.register,hreg);
 
561
                 emit_reg_reg(op,S_NO,left.location.register,hreg);
 
562
               end
 
563
              else
 
564
               begin
 
565
                 if not(left.location.loc in [LOC_REFERENCE,LOC_CREFERENCE]) then
 
566
                  internalerror(200203247);
 
567
                 emit_ref_reg(A_MOVQ,S_NO,right.location.reference,hreg);
 
568
                 emit_reg_reg(op,S_NO,left.location.register,hreg);
 
569
               end;
 
570
               location.register:=hreg;
 
571
            end
 
572
           else
 
573
            begin
 
574
              if (right.location.loc=LOC_CMMXREGISTER) then
 
575
                emit_reg_reg(op,S_NO,right.location.register,left.location.register)
 
576
              else
 
577
               begin
 
578
                 if not(right.location.loc in [LOC_REFERENCE,LOC_CREFERENCE]) then
 
579
                  internalerror(200203246);
 
580
                 emit_ref_reg(op,S_NO,right.location.reference,left.location.register);
 
581
               end;
 
582
              location.register:=left.location.register;
 
583
            end;
 
584
          end
 
585
        else
 
586
          begin
 
587
            { right.location=LOC_MMXREGISTER }
 
588
            if (nodetype=subn) and (nf_swaped in flags) then
 
589
             begin
 
590
               emit_reg_reg(op,S_NO,left.location.register,right.location.register);
 
591
               location_swap(left.location,right.location);
 
592
               toggleflag(nf_swaped);
 
593
             end
 
594
            else
 
595
             begin
 
596
               emit_reg_reg(op,S_NO,right.location.register,left.location.register);
 
597
             end;
 
598
            location.register:=left.location.register;
 
599
          end;
 
600
 
 
601
        location_freetemp(exprasmlist,right.location);
 
602
        if cmpop then
 
603
          location_freetemp(exprasmlist,left.location);
 
604
      end;
 
605
{$endif SUPPORT_MMX}
 
606
 
 
607
 
 
608
{*****************************************************************************
 
609
                                   addmmxset
 
610
*****************************************************************************}
 
611
 
 
612
{$ifdef SUPPORT_MMX}
 
613
    procedure tx86addnode.second_opmmxset;
 
614
 
 
615
    var opsize : TCGSize;
 
616
        op     : TAsmOp;
 
617
        cmpop,
 
618
        noswap : boolean;
 
619
    begin
 
620
      pass_left_right;
 
621
 
 
622
      cmpop:=false;
 
623
      noswap:=false;
 
624
      opsize:=OS_32;
 
625
      case nodetype of
 
626
        addn:
 
627
          begin
 
628
            { are we adding set elements ? }
 
629
            if right.nodetype=setelementn then
 
630
              begin
 
631
                { adding elements is not commutative }
 
632
{                if nf_swaped in flags then
 
633
                  swapleftright;}
 
634
                { bts requires both elements to be registers }
 
635
{                location_force_reg(exprasmlist,left.location,opsize_2_cgsize[opsize],false);
 
636
                location_force_reg(exprasmlist,right.location,opsize_2_cgsize[opsize],true);
 
637
                op:=A_BTS;
 
638
                noswap:=true;}
 
639
              end
 
640
            else
 
641
              op:=A_POR;
 
642
          end;
 
643
        symdifn :
 
644
          op:=A_PXOR;
 
645
        muln:
 
646
          op:=A_PAND;
 
647
        subn:
 
648
          op:=A_PANDN;
 
649
        equaln,
 
650
        unequaln :
 
651
          begin
 
652
            op:=A_PCMPEQD;
 
653
            cmpop:=true;
 
654
          end;
 
655
        lten,gten:
 
656
          begin
 
657
            if (not(nf_swaped in flags) and (nodetype = lten)) or
 
658
               ((nf_swaped in flags) and (nodetype = gten)) then
 
659
              swapleftright;
 
660
            location_force_reg(exprasmlist,left.location,opsize,true);
 
661
            emit_op_right_left(A_AND,opsize);
 
662
            op:=A_PCMPEQD;
 
663
            cmpop:=true;
 
664
            { warning: ugly hack, we need a JE so change the node to equaln }
 
665
            nodetype:=equaln;
 
666
          end;
 
667
          xorn :
 
668
            op:=A_PXOR;
 
669
          orn :
 
670
            op:=A_POR;
 
671
          andn :
 
672
            op:=A_PAND;
 
673
          else
 
674
            internalerror(2003042215);
 
675
        end;
 
676
        { left must be a register }
 
677
        left_must_be_reg(opsize,noswap);
 
678
{        emit_generic_code(op,opsize,true,extra_not,false);}
 
679
        location_freetemp(exprasmlist,right.location);
 
680
        if cmpop then
 
681
          location_freetemp(exprasmlist,left.location);
 
682
      end;
 
683
{$endif SUPPORT_MMX}
 
684
 
 
685
 
 
686
 
 
687
{*****************************************************************************
439
688
                                AddFloat
440
689
*****************************************************************************}
441
690
 
476
725
          end
477
726
        else
478
727
          begin
 
728
            if not(nf_swaped in flags) then
 
729
              if right.location.loc in [LOC_FPUREGISTER,LOC_CFPUREGISTER] then
 
730
                location_force_mem(exprasmlist,right.location);
 
731
 
479
732
            location_force_mmregscalar(exprasmlist,left.location,false);
480
733
            location.register:=left.location.register;
481
734
            { force floating point reg. location to be written to memory,
802
1055
begin
803
1056
   caddnode:=tx86addnode;
804
1057
end.
805
 
{
806
 
  $Log: nx86add.pas,v $
807
 
  Revision 1.17  2005/02/14 17:13:10  peter
808
 
    * truncate log
809
 
 
810
 
  Revision 1.16  2005/02/06 00:05:56  florian
811
 
    + x86_64 pic draft
812
 
 
813
 
}