~ubuntu-branches/ubuntu/utopic/golang/utopic

« back to all changes in this revision

Viewing changes to src/cmd/8l/span.c

  • Committer: Package Import Robot
  • Author(s): James Page
  • Date: 2013-08-20 14:06:23 UTC
  • mfrom: (14.1.23 saucy-proposed)
  • Revision ID: package-import@ubuntu.com-20130820140623-b414jfxi3m0qkmrq
Tags: 2:1.1.2-2ubuntu1
* Merge from Debian unstable (LP: #1211749, #1202027). Remaining changes:
  - 016-armhf-elf-header.patch: Use correct ELF header for armhf binaries.
  - d/control,control.cross: Update Breaks/Replaces for Ubuntu
    versions to ensure smooth upgrades, regenerate control file.

Show diffs side-by-side

added added

removed removed

Lines of Context:
32
32
 
33
33
#include        "l.h"
34
34
#include        "../ld/lib.h"
 
35
#include        "../ld/elf.h"
35
36
 
36
37
static int32    vaddr(Adr*, Reloc*);
37
38
 
194
195
 
195
196
        for(i=1; optab[i].as; i++)
196
197
                if(i != optab[i].as) {
197
 
                        diag("phase error in optab: %d", i);
 
198
                        diag("phase error in optab: at %A found %A", i, optab[i].as);
198
199
                        errorexit();
199
200
                }
200
201
        maxop = i;
238
239
        ycover[Yrl*Ymax + Yml] = 1;
239
240
        ycover[Ym*Ymax + Yml] = 1;
240
241
 
 
242
        ycover[Yax*Ymax + Ymm] = 1;
 
243
        ycover[Ycx*Ymax + Ymm] = 1;
 
244
        ycover[Yrx*Ymax + Ymm] = 1;
 
245
        ycover[Yrl*Ymax + Ymm] = 1;
 
246
        ycover[Ym*Ymax + Ymm] = 1;
 
247
        ycover[Ymr*Ymax + Ymm] = 1;
 
248
 
 
249
        ycover[Ym*Ymax + Yxm] = 1;
 
250
        ycover[Yxr*Ymax + Yxm] = 1;
 
251
 
241
252
        for(i=0; i<D_NONE; i++) {
242
253
                reg[i] = -1;
243
254
                if(i >= D_AL && i <= D_BH)
246
257
                        reg[i] = (i-D_AX) & 7;
247
258
                if(i >= D_F0 && i <= D_F0+7)
248
259
                        reg[i] = (i-D_F0) & 7;
 
260
                if(i >= D_X0 && i <= D_X0+7)
 
261
                        reg[i] = (i-D_X0) & 7;
249
262
        }
250
263
}
251
264
 
333
346
        case D_F0+7:
334
347
                return  Yrf;
335
348
 
 
349
        case D_X0+0:
 
350
        case D_X0+1:
 
351
        case D_X0+2:
 
352
        case D_X0+3:
 
353
        case D_X0+4:
 
354
        case D_X0+5:
 
355
        case D_X0+6:
 
356
        case D_X0+7:
 
357
                return  Yxr;
 
358
 
336
359
        case D_NONE:
337
360
                return Ynone;
338
361
 
537
560
        return v;
538
561
}
539
562
 
 
563
static int
 
564
istls(Adr *a)
 
565
{
 
566
        if(HEADTYPE == Hlinux)
 
567
                return a->index == D_GS;
 
568
        return a->type == D_INDIR+D_GS;
 
569
}
 
570
 
540
571
void
541
572
asmand(Adr *a, int r)
542
573
{
547
578
        v = a->offset;
548
579
        t = a->type;
549
580
        rel.siz = 0;
550
 
        if(a->index != D_NONE) {
 
581
        if(a->index != D_NONE && a->index != D_FS && a->index != D_GS) {
551
582
                if(t < D_INDIR || t >= 2*D_INDIR) {
552
583
                        switch(t) {
553
584
                        default:
585
616
                asmidx(a->scale, a->index, t);
586
617
                goto putrelv;
587
618
        }
588
 
        if(t >= D_AL && t <= D_F0+7) {
 
619
        if(t >= D_AL && t <= D_F7 || t >= D_X0 && t <= D_X7) {
589
620
                if(v)
590
621
                        goto bad;
591
622
                *andptr++ = (3 << 6) | (reg[t] << 0) | (r << 3);
636
667
                        *andptr++ = (0 << 6) | (reg[t] << 0) | (r << 3);
637
668
                        return;
638
669
                }
639
 
                if(v >= -128 && v < 128 && rel.siz == 0) {
 
670
                if(v >= -128 && v < 128 && rel.siz == 0 && a->index != D_FS && a->index != D_GS) {
640
671
                        andptr[0] = (1 << 6) | (reg[t] << 0) | (r << 3);
641
672
                        andptr[1] = v;
642
673
                        andptr += 2;
658
689
                r = addrel(cursym);
659
690
                *r = rel;
660
691
                r->off = curp->pc + andptr - and;
 
692
        } else if(iself && linkmode == LinkExternal && istls(a) && HEADTYPE != Hopenbsd) {
 
693
                Reloc *r;
 
694
                Sym *s;
 
695
 
 
696
                r = addrel(cursym);
 
697
                r->off = curp->pc + andptr - and;
 
698
                r->add = 0;
 
699
                r->xadd = 0;
 
700
                r->siz = 4;
 
701
                r->type = D_TLS;
 
702
                if(a->offset == tlsoffset+0)
 
703
                        s = lookup("runtime.g", 0);
 
704
                else
 
705
                        s = lookup("runtime.m", 0);
 
706
                s->type = STLSBSS;
 
707
                s->reachable = 1;
 
708
                s->hide = 1;
 
709
                s->size = PtrSize;
 
710
                r->sym = s;
 
711
                r->xsym = s;
 
712
                v = 0;
661
713
        }
 
714
 
662
715
        put4(v);
663
716
        return;
664
717
 
772
825
        0
773
826
};
774
827
 
 
828
// byteswapreg returns a byte-addressable register (AX, BX, CX, DX)
 
829
// which is not referenced in a->type.
 
830
// If a is empty, it returns BX to account for MULB-like instructions
 
831
// that might use DX and AX.
775
832
int
776
 
isax(Adr *a)
 
833
byteswapreg(Adr *a)
777
834
{
 
835
        int cana, canb, canc, cand;
 
836
 
 
837
        cana = canb = canc = cand = 1;
778
838
 
779
839
        switch(a->type) {
 
840
        case D_NONE:
 
841
                cana = cand = 0;
 
842
                break;
780
843
        case D_AX:
781
844
        case D_AL:
782
845
        case D_AH:
783
846
        case D_INDIR+D_AX:
784
 
                return 1;
785
 
        }
786
 
        if(a->index == D_AX)
787
 
                return 1;
 
847
                cana = 0;
 
848
                break;
 
849
        case D_BX:
 
850
        case D_BL:
 
851
        case D_BH:
 
852
        case D_INDIR+D_BX:
 
853
                canb = 0;
 
854
                break;
 
855
        case D_CX:
 
856
        case D_CL:
 
857
        case D_CH:
 
858
        case D_INDIR+D_CX:
 
859
                canc = 0;
 
860
                break;
 
861
        case D_DX:
 
862
        case D_DL:
 
863
        case D_DH:
 
864
        case D_INDIR+D_DX:
 
865
                cand = 0;
 
866
                break;
 
867
        }
 
868
        switch(a->index) {
 
869
        case D_AX:
 
870
                cana = 0;
 
871
                break;
 
872
        case D_BX:
 
873
                canb = 0;
 
874
                break;
 
875
        case D_CX:
 
876
                canc = 0;
 
877
                break;
 
878
        case D_DX:
 
879
                cand = 0;
 
880
                break;
 
881
        }
 
882
        if(cana)
 
883
                return D_AX;
 
884
        if(canb)
 
885
                return D_BX;
 
886
        if(canc)
 
887
                return D_CX;
 
888
        if(cand)
 
889
                return D_DX;
 
890
 
 
891
        diag("impossible byte register");
 
892
        errorexit();
788
893
        return 0;
789
894
}
790
895
 
827
932
                print("%P\n", p);
828
933
}
829
934
 
 
935
static int
 
936
mediaop(Optab *o, int op, int osize, int z)
 
937
{
 
938
        switch(op){
 
939
        case Pm:
 
940
        case Pe:
 
941
        case Pf2:
 
942
        case Pf3:
 
943
                if(osize != 1){
 
944
                        if(op != Pm)
 
945
                                *andptr++ = op;
 
946
                        *andptr++ = Pm;
 
947
                        op = o->op[++z];
 
948
                        break;
 
949
                }
 
950
        default:
 
951
                if(andptr == and || andptr[-1] != Pm)
 
952
                        *andptr++ = Pm;
 
953
                break;
 
954
        }
 
955
        *andptr++ = op;
 
956
        return z;
 
957
}
 
958
 
830
959
void
831
960
doasm(Prog *p)
832
961
{
833
962
        Optab *o;
834
963
        Prog *q, pp;
835
964
        uchar *t;
836
 
        int z, op, ft, tt;
 
965
        int z, op, ft, tt, breg;
837
966
        int32 v, pre;
838
967
        Reloc rel, *r;
839
968
        Adr *a;
873
1002
                *andptr++ = Pm;
874
1003
                break;
875
1004
 
 
1005
        case Pf2:       /* xmm opcode escape */
 
1006
        case Pf3:
 
1007
                *andptr++ = o->prefix;
 
1008
                *andptr++ = Pm;
 
1009
                break;
 
1010
 
876
1011
        case Pm:        /* opcode escape */
877
1012
                *andptr++ = Pm;
878
1013
                break;
899
1034
                        *andptr++ = op;
900
1035
                break;
901
1036
 
 
1037
        case Zlitm_r:
 
1038
                for(; op = o->op[z]; z++)
 
1039
                        *andptr++ = op;
 
1040
                asmand(&p->from, reg[p->to.type]);
 
1041
                break;
 
1042
 
902
1043
        case Zm_r:
903
1044
                *andptr++ = op;
904
1045
                asmand(&p->from, reg[p->to.type]);
905
1046
                break;
906
1047
 
 
1048
        case Zm2_r:
 
1049
                *andptr++ = op;
 
1050
                *andptr++ = o->op[z+1];
 
1051
                asmand(&p->from, reg[p->to.type]);
 
1052
                break;
 
1053
 
 
1054
        case Zm_r_xm:
 
1055
                mediaop(o, op, t[3], z);
 
1056
                asmand(&p->from, reg[p->to.type]);
 
1057
                break;
 
1058
 
 
1059
        case Zm_r_i_xm:
 
1060
                mediaop(o, op, t[3], z);
 
1061
                asmand(&p->from, reg[p->to.type]);
 
1062
                *andptr++ = p->to.offset;
 
1063
                break;
 
1064
 
 
1065
        case Zibm_r:
 
1066
                while ((op = o->op[z++]) != 0)
 
1067
                        *andptr++ = op;
 
1068
                asmand(&p->from, reg[p->to.type]);
 
1069
                *andptr++ = p->to.offset;
 
1070
                break;
 
1071
 
907
1072
        case Zaut_r:
908
1073
                *andptr++ = 0x8d;       /* leal */
909
1074
                if(p->from.type != D_ADDR)
927
1092
                asmand(&p->to, reg[p->from.type]);
928
1093
                break;
929
1094
 
 
1095
        case Zr_m_xm:
 
1096
                mediaop(o, op, t[3], z);
 
1097
                asmand(&p->to, reg[p->from.type]);
 
1098
                break;
 
1099
 
 
1100
        case Zr_m_i_xm:
 
1101
                mediaop(o, op, t[3], z);
 
1102
                asmand(&p->to, reg[p->from.type]);
 
1103
                *andptr++ = p->from.offset;
 
1104
                break;
 
1105
 
930
1106
        case Zo_m:
931
1107
                *andptr++ = op;
932
1108
                asmand(&p->to, o->op[z+1]);
1198
1374
        pp = *p;
1199
1375
        z = p->from.type;
1200
1376
        if(z >= D_BP && z <= D_DI) {
1201
 
                if(isax(&p->to)) {
 
1377
                if((breg = byteswapreg(&p->to)) != D_AX) {
1202
1378
                        *andptr++ = 0x87;                       /* xchg lhs,bx */
1203
 
                        asmand(&p->from, reg[D_BX]);
1204
 
                        subreg(&pp, z, D_BX);
 
1379
                        asmand(&p->from, reg[breg]);
 
1380
                        subreg(&pp, z, breg);
1205
1381
                        doasm(&pp);
1206
1382
                        *andptr++ = 0x87;                       /* xchg lhs,bx */
1207
 
                        asmand(&p->from, reg[D_BX]);
 
1383
                        asmand(&p->from, reg[breg]);
1208
1384
                } else {
1209
1385
                        *andptr++ = 0x90 + reg[z];              /* xchg lsh,ax */
1210
1386
                        subreg(&pp, z, D_AX);
1215
1391
        }
1216
1392
        z = p->to.type;
1217
1393
        if(z >= D_BP && z <= D_DI) {
1218
 
                if(isax(&p->from)) {
 
1394
                if((breg = byteswapreg(&p->from)) != D_AX) {
1219
1395
                        *andptr++ = 0x87;                       /* xchg rhs,bx */
1220
 
                        asmand(&p->to, reg[D_BX]);
1221
 
                        subreg(&pp, z, D_BX);
 
1396
                        asmand(&p->to, reg[breg]);
 
1397
                        subreg(&pp, z, breg);
1222
1398
                        doasm(&pp);
1223
1399
                        *andptr++ = 0x87;                       /* xchg rhs,bx */
1224
 
                        asmand(&p->to, reg[D_BX]);
 
1400
                        asmand(&p->to, reg[breg]);
1225
1401
                } else {
1226
1402
                        *andptr++ = 0x90 + reg[z];              /* xchg rsh,ax */
1227
1403
                        subreg(&pp, z, D_AX);