14 xdefine("etext", STEXT, 0L);
16 for(p = firstp; p != P; p = p->link) {
20 if(p->to.type == D_BRANCH)
23 if((q = p->pcond) != P)
31 p->as = p->mode != 64? AADDL: AADDQ;
33 p->as = p->mode != 64? ASUBL: ASUBQ;
45 Bprint(&bso, "%5.2f span\n", cputime());
48 for(p = firstp; p != P; p = p->link) {
51 if(p->to.type == D_BRANCH)
64 Bprint(&bso, "%5.2f span %d\n", cputime(), n);
67 print("span must be looping\n");
72 for(p = firstp; p != P; p = p->link) {
75 if(p->to.type == D_BRANCH || p->back & 0100) {
93 INITDAT = rnd(c, INITRND);
99 xdefine("etext", STEXT, c);
101 Bprint(&bso, "etext = %llux\n", c);
103 for(p = textp; p != P; p = p->pcond)
104 p->from.sym->value = p->pc;
105 textsize = c - INITTEXT;
109 xdefine(char *p, int t, vlong v)
114 if(s->type == 0 || s->type == SXREF) {
118 if(s->type == STEXT && s->value == 0)
123 putsymb(char *s, int t, vlong v, int ver)
137 cput(t+0x80); /* 0x80 is variable length */
139 if(t == 'Z' || t == 'z') {
141 for(i=1; s[i] != 0 || s[i+1] != 0; i += 2) {
154 symsize += l + 1 + i + 1;
157 if(t == 'z' || t == 'Z') {
158 Bprint(&bso, "%c %.8llux ", t, v);
159 for(i=1; s[i] != 0 || s[i+1] != 0; i+=2) {
160 f = ((s[i]&0xff) << 8) | (s[i+1]&0xff);
161 Bprint(&bso, "/%x", f);
167 Bprint(&bso, "%c %.8llux %s<%d>\n", t, v, s, ver);
169 Bprint(&bso, "%c %.8llux %s\n", t, v, s);
181 s = lookup("etext", 0);
183 putsymb(s->name, 'T', s->value, s->version);
185 for(h=0; h<NHASH; h++)
186 for(s=hash[h]; s!=S; s=s->link)
189 putsymb(s->name, 'D', s->value, s->version);
193 putsymb(s->name, 'D', s->value+INITDAT, s->version);
197 putsymb(s->name, 'B', s->value+INITDAT, s->version);
201 putsymb(s->name, 'f', s->value, s->version);
205 for(p=textp; p!=P; p=p->pcond) {
210 /* filenames first */
211 for(a=p->to.autom; a; a=a->link)
212 if(a->type == D_FILE)
213 putsymb(a->asym->name, 'z', a->aoffset, 0);
215 if(a->type == D_FILE1)
216 putsymb(a->asym->name, 'Z', a->aoffset, 0);
218 putsymb(s->name, 'T', s->value, s->version);
220 /* frame, auto and param after */
221 putsymb(".frame", 'm', p->to.offset+8, 0);
223 for(a=p->to.autom; a; a=a->link)
224 if(a->type == D_AUTO)
225 putsymb(a->asym->name, 'a', -a->aoffset, 0);
227 if(a->type == D_PARAM)
228 putsymb(a->asym->name, 'p', a->aoffset, 0);
230 if(debug['v'] || debug['n'])
231 Bprint(&bso, "symsize = %lud\n", symsize);
244 for(p = firstp; p != P; p = p->link) {
245 if(p->line == oldlc || p->as == ATEXT || p->as == ANOP) {
249 Bprint(&bso, "%6llux %P\n",
254 Bprint(&bso, "\t\t%6ld", lcsize);
255 v = (p->pc - oldpc) / MINLC;
260 cput(s+128); /* 129-255 +pc */
262 Bprint(&bso, " pc+%ld*%d(%ld)", s, MINLC, s+128);
268 oldpc = p->pc + MINLC;
269 if(s > 64 || s < -64) {
270 cput(0); /* 0 vv +lc */
277 Bprint(&bso, " lc+%ld(%d,%ld)\n",
280 Bprint(&bso, " lc%ld(%d,%ld)\n",
282 Bprint(&bso, "%6llux %P\n",
289 cput(0+s); /* 1-64 +lc */
291 Bprint(&bso, " lc+%ld(%ld)\n", s, 0+s);
292 Bprint(&bso, "%6llux %P\n",
296 cput(64-s); /* 65-128 -lc */
298 Bprint(&bso, " lc%ld(%ld)\n", s, 64-s);
299 Bprint(&bso, "%6llux %P\n",
310 if(debug['v'] || debug['L'])
311 Bprint(&bso, "lcsize = %ld\n", lcsize);
321 if(a->type >= D_INDIR || a->index != D_NONE) {
322 if(a->index != D_NONE && a->scale == 0) {
323 if(a->type == D_ADDR) {
327 return Yi32; /* TO DO: Yi64 */
380 case D_R8: /* not really Yrl */
439 case D_CS: return Ycs;
440 case D_SS: return Yss;
441 case D_DS: return Yds;
442 case D_ES: return Yes;
443 case D_FS: return Yfs;
444 case D_GS: return Ygs;
446 case D_GDTR: return Ygdtr;
447 case D_IDTR: return Yidtr;
448 case D_LDTR: return Yldtr;
449 case D_MSW: return Ymsw;
450 case D_TASK: return Ytask;
452 case D_CR+0: return Ycr0;
453 case D_CR+1: return Ycr1;
454 case D_CR+2: return Ycr2;
455 case D_CR+3: return Ycr3;
456 case D_CR+4: return Ycr4;
457 case D_CR+5: return Ycr5;
458 case D_CR+6: return Ycr6;
459 case D_CR+7: return Ycr7;
460 case D_CR+8: return Ycr8;
462 case D_DR+0: return Ydr0;
463 case D_DR+1: return Ydr1;
464 case D_DR+2: return Ydr2;
465 case D_DR+3: return Ydr3;
466 case D_DR+4: return Ydr4;
467 case D_DR+5: return Ydr5;
468 case D_DR+6: return Ydr6;
469 case D_DR+7: return Ydr7;
471 case D_TR+0: return Ytr0;
472 case D_TR+1: return Ytr1;
473 case D_TR+2: return Ytr2;
474 case D_TR+3: return Ytr3;
475 case D_TR+4: return Ytr4;
476 case D_TR+5: return Ytr5;
477 case D_TR+6: return Ytr6;
478 case D_TR+7: return Ytr7;
494 if(v >= -128 && v <= 127)
498 return Ys32; /* can sign extend */
500 return Yi32; /* unsigned */
503 return Yi32; /* TO DO: D_ADDR as Yi64 */
512 asmidx(Adr *a, int base)
541 i = reg[a->index] << 3;
563 case D_NONE: /* must be mod=00 */
590 diag("asmidx: bad address %D", a);
598 if(dlm && curp != P && reloca != nil){
599 dynreloc(reloca->sym, curp->pc + andptr - &and[0], 1);
612 if(dlm && curp != P && reloca != nil){
613 dynreloc(reloca->sym, curp->pc + andptr - &and[0], 1); /* TO DO */
650 if((uvlong)s->value < (uvlong)INITTEXT)
651 v += INITTEXT; /* TO DO */
655 v += INITDAT + s->value;
663 asmandsz(Adr *a, int r, int rex, int m64)
672 if(a->index != D_NONE) {
675 rexflag |= (regrex[a->index] & Rxx) | (regrex[t] & Rxb) | rex;
677 *andptr++ = (0 << 6) | (4 << 0) | (r << 3);
682 if(v == 0 && t != D_BP && t != D_R13) {
683 *andptr++ = (0 << 6) | (4 << 0) | (r << 3);
687 if(v >= -128 && v < 128) {
688 *andptr++ = (1 << 6) | (4 << 0) | (r << 3);
693 *andptr++ = (2 << 6) | (4 << 0) | (r << 3);
703 aa.type = D_NONE+D_INDIR;
707 aa.type = D_SP+D_INDIR;
710 aa.offset = vaddr(a);
713 asmandsz(&aa, r, rex, m64);
716 if(t >= D_AL && t <= D_X0+15) {
719 *andptr++ = (3 << 6) | (reg[t] << 0) | (r << 3);
720 rexflag |= (regrex[t] & (0x40 | Rxb)) | rex;
725 rexflag |= (regrex[t] & Rxb) | rex;
728 *andptr++ = (0 << 6) | (5 << 0) | (r << 3);
733 *andptr++ = (0 << 6) | (4 << 0) | (r << 3); /* sib present */
734 *andptr++ = (0 << 6) | (4 << 3) | (5 << 0); /* DS:d32 */
738 if(t == D_SP || t == D_R12) {
740 *andptr++ = (0 << 6) | (reg[t] << 0) | (r << 3);
744 if(v >= -128 && v < 128) {
745 *andptr++ = (1 << 6) | (reg[t] << 0) | (r << 3);
750 *andptr++ = (2 << 6) | (reg[t] << 0) | (r << 3);
755 if(t >= D_AX && t <= D_R15) {
756 if(v == 0 && t != D_BP && t != D_R13) {
757 *andptr++ = (0 << 6) | (reg[t] << 0) | (r << 3);
760 if(v >= -128 && v < 128) {
761 andptr[0] = (1 << 6) | (reg[t] << 0) | (r << 3);
766 *andptr++ = (2 << 6) | (reg[t] << 0) | (r << 3);
777 aa.type = D_NONE+D_INDIR;
781 aa.type = D_SP+D_INDIR;
786 aa.offset = vaddr(a);
787 asmandsz(&aa, r, rex, m64);
790 diag("asmand: bad address %D", a);
795 asmand(Adr *a, Adr *ra)
797 asmandsz(a, reg[ra->type], regrex[ra->type], 0);
801 asmando(Adr *a, int o)
803 asmandsz(a, o, 0, 0);
809 if(a->index == D_NONE && (a->type >= D_AX && a->type <= D_R15))
810 a->type = D_AL + (a->type-D_AX);
817 {APUSHL, Ycs, Ynone, 0, 0x0e,E,0,0},
818 {APUSHL, Yss, Ynone, 0, 0x16,E,0,0},
819 {APUSHL, Yds, Ynone, 0, 0x1e,E,0,0},
820 {APUSHL, Yes, Ynone, 0, 0x06,E,0,0},
821 {APUSHL, Yfs, Ynone, 0, 0x0f,0xa0,E,0},
822 {APUSHL, Ygs, Ynone, 0, 0x0f,0xa8,E,0},
823 {APUSHQ, Yfs, Ynone, 0, 0x0f,0xa0,E,0},
824 {APUSHQ, Ygs, Ynone, 0, 0x0f,0xa8,E,0},
826 {APUSHW, Ycs, Ynone, 0, Pe,0x0e,E,0},
827 {APUSHW, Yss, Ynone, 0, Pe,0x16,E,0},
828 {APUSHW, Yds, Ynone, 0, Pe,0x1e,E,0},
829 {APUSHW, Yes, Ynone, 0, Pe,0x06,E,0},
830 {APUSHW, Yfs, Ynone, 0, Pe,0x0f,0xa0,E},
831 {APUSHW, Ygs, Ynone, 0, Pe,0x0f,0xa8,E},
834 {APOPL, Ynone, Yds, 0, 0x1f,E,0,0},
835 {APOPL, Ynone, Yes, 0, 0x07,E,0,0},
836 {APOPL, Ynone, Yss, 0, 0x17,E,0,0},
837 {APOPL, Ynone, Yfs, 0, 0x0f,0xa1,E,0},
838 {APOPL, Ynone, Ygs, 0, 0x0f,0xa9,E,0},
839 {APOPQ, Ynone, Yfs, 0, 0x0f,0xa1,E,0},
840 {APOPQ, Ynone, Ygs, 0, 0x0f,0xa9,E,0},
842 {APOPW, Ynone, Yds, 0, Pe,0x1f,E,0},
843 {APOPW, Ynone, Yes, 0, Pe,0x07,E,0},
844 {APOPW, Ynone, Yss, 0, Pe,0x17,E,0},
845 {APOPW, Ynone, Yfs, 0, Pe,0x0f,0xa1,E},
846 {APOPW, Ynone, Ygs, 0, Pe,0x0f,0xa9,E},
849 {AMOVW, Yes, Yml, 1, 0x8c,0,0,0},
850 {AMOVW, Ycs, Yml, 1, 0x8c,1,0,0},
851 {AMOVW, Yss, Yml, 1, 0x8c,2,0,0},
852 {AMOVW, Yds, Yml, 1, 0x8c,3,0,0},
853 {AMOVW, Yfs, Yml, 1, 0x8c,4,0,0},
854 {AMOVW, Ygs, Yml, 1, 0x8c,5,0,0},
856 {AMOVW, Yml, Yes, 2, 0x8e,0,0,0},
857 {AMOVW, Yml, Ycs, 2, 0x8e,1,0,0},
858 {AMOVW, Yml, Yss, 2, 0x8e,2,0,0},
859 {AMOVW, Yml, Yds, 2, 0x8e,3,0,0},
860 {AMOVW, Yml, Yfs, 2, 0x8e,4,0,0},
861 {AMOVW, Yml, Ygs, 2, 0x8e,5,0,0},
864 {AMOVL, Ycr0, Yml, 3, 0x0f,0x20,0,0},
865 {AMOVL, Ycr2, Yml, 3, 0x0f,0x20,2,0},
866 {AMOVL, Ycr3, Yml, 3, 0x0f,0x20,3,0},
867 {AMOVL, Ycr4, Yml, 3, 0x0f,0x20,4,0},
868 {AMOVL, Ycr8, Yml, 3, 0x0f,0x20,8,0},
869 {AMOVQ, Ycr0, Yml, 3, 0x0f,0x20,0,0},
870 {AMOVQ, Ycr2, Yml, 3, 0x0f,0x20,2,0},
871 {AMOVQ, Ycr3, Yml, 3, 0x0f,0x20,3,0},
872 {AMOVQ, Ycr4, Yml, 3, 0x0f,0x20,4,0},
873 {AMOVQ, Ycr8, Yml, 3, 0x0f,0x20,8,0},
875 {AMOVL, Yml, Ycr0, 4, 0x0f,0x22,0,0},
876 {AMOVL, Yml, Ycr2, 4, 0x0f,0x22,2,0},
877 {AMOVL, Yml, Ycr3, 4, 0x0f,0x22,3,0},
878 {AMOVL, Yml, Ycr4, 4, 0x0f,0x22,4,0},
879 {AMOVL, Yml, Ycr8, 4, 0x0f,0x22,8,0},
880 {AMOVQ, Yml, Ycr0, 4, 0x0f,0x22,0,0},
881 {AMOVQ, Yml, Ycr2, 4, 0x0f,0x22,2,0},
882 {AMOVQ, Yml, Ycr3, 4, 0x0f,0x22,3,0},
883 {AMOVQ, Yml, Ycr4, 4, 0x0f,0x22,4,0},
884 {AMOVQ, Yml, Ycr8, 4, 0x0f,0x22,8,0},
887 {AMOVL, Ydr0, Yml, 3, 0x0f,0x21,0,0},
888 {AMOVL, Ydr1, Yml, 3, 0x0f,0x21,1,0},
889 {AMOVL, Ydr2, Yml, 3, 0x0f,0x21,2,0},
890 {AMOVL, Ydr3, Yml, 3, 0x0f,0x21,3,0},
891 {AMOVL, Ydr6, Yml, 3, 0x0f,0x21,6,0},
892 {AMOVL, Ydr7, Yml, 3, 0x0f,0x21,7,0},
893 {AMOVQ, Ydr0, Yml, 3, 0x0f,0x21,0,0},
894 {AMOVQ, Ydr1, Yml, 3, 0x0f,0x21,1,0},
895 {AMOVQ, Ydr2, Yml, 3, 0x0f,0x21,2,0},
896 {AMOVQ, Ydr3, Yml, 3, 0x0f,0x21,3,0},
897 {AMOVQ, Ydr6, Yml, 3, 0x0f,0x21,6,0},
898 {AMOVQ, Ydr7, Yml, 3, 0x0f,0x21,7,0},
900 {AMOVL, Yml, Ydr0, 4, 0x0f,0x23,0,0},
901 {AMOVL, Yml, Ydr1, 4, 0x0f,0x23,1,0},
902 {AMOVL, Yml, Ydr2, 4, 0x0f,0x23,2,0},
903 {AMOVL, Yml, Ydr3, 4, 0x0f,0x23,3,0},
904 {AMOVL, Yml, Ydr6, 4, 0x0f,0x23,6,0},
905 {AMOVL, Yml, Ydr7, 4, 0x0f,0x23,7,0},
906 {AMOVQ, Yml, Ydr0, 4, 0x0f,0x23,0,0},
907 {AMOVQ, Yml, Ydr1, 4, 0x0f,0x23,1,0},
908 {AMOVQ, Yml, Ydr2, 4, 0x0f,0x23,2,0},
909 {AMOVQ, Yml, Ydr3, 4, 0x0f,0x23,3,0},
910 {AMOVQ, Yml, Ydr6, 4, 0x0f,0x23,6,0},
911 {AMOVQ, Yml, Ydr7, 4, 0x0f,0x23,7,0},
914 {AMOVL, Ytr6, Yml, 3, 0x0f,0x24,6,0},
915 {AMOVL, Ytr7, Yml, 3, 0x0f,0x24,7,0},
917 {AMOVL, Yml, Ytr6, 4, 0x0f,0x26,6,E},
918 {AMOVL, Yml, Ytr7, 4, 0x0f,0x26,7,E},
920 /* lgdt, sgdt, lidt, sidt */
921 {AMOVL, Ym, Ygdtr, 4, 0x0f,0x01,2,0},
922 {AMOVL, Ygdtr, Ym, 3, 0x0f,0x01,0,0},
923 {AMOVL, Ym, Yidtr, 4, 0x0f,0x01,3,0},
924 {AMOVL, Yidtr, Ym, 3, 0x0f,0x01,1,0},
925 {AMOVQ, Ym, Ygdtr, 4, 0x0f,0x01,2,0},
926 {AMOVQ, Ygdtr, Ym, 3, 0x0f,0x01,0,0},
927 {AMOVQ, Ym, Yidtr, 4, 0x0f,0x01,3,0},
928 {AMOVQ, Yidtr, Ym, 3, 0x0f,0x01,1,0},
931 {AMOVW, Yml, Yldtr, 4, 0x0f,0x00,2,0},
932 {AMOVW, Yldtr, Yml, 3, 0x0f,0x00,0,0},
935 {AMOVW, Yml, Ymsw, 4, 0x0f,0x01,6,0},
936 {AMOVW, Ymsw, Yml, 3, 0x0f,0x01,4,0},
939 {AMOVW, Yml, Ytask, 4, 0x0f,0x00,3,0},
940 {AMOVW, Ytask, Yml, 3, 0x0f,0x00,1,0},
942 /* load full pointer */
943 {AMOVL, Yml, Ycol, 5, 0,0,0,0},
944 {AMOVW, Yml, Ycol, 5, Pe,0,0,0},
947 {ASHLL, Ycol, Yml, 6, 0xa4,0xa5,0,0},
948 {ASHRL, Ycol, Yml, 6, 0xac,0xad,0,0},
949 {ASHLQ, Ycol, Yml, 6, Pw,0xa4,0xa5,0},
950 {ASHRQ, Ycol, Yml, 6, Pw,0xac,0xad,0},
951 {ASHLW, Ycol, Yml, 6, Pe,0xa4,0xa5,0},
952 {ASHRW, Ycol, Yml, 6, Pe,0xac,0xad,0},
973 subreg(Prog *p, int from, int to)
977 print("\n%P s/%R/%R/\n", p, from, to);
979 if(p->from.type == from)
981 if(p->to.type == from)
984 if(p->from.index == from)
986 if(p->to.index == from)
990 if(p->from.type == from)
991 p->from.type = to+D_INDIR;
992 if(p->to.type == from)
993 p->to.type = to+D_INDIR;
1000 mediaop(Optab *o, int op, int osize, int z)
1015 if(andptr == and || andptr[-1] != Pm)
1030 int z, op, ft, tt, xo, l;
1035 diag("asmins: missing op %P", p);
1038 ft = oclass(&p->from) * Ymax;
1039 tt = oclass(&p->to) * Ymax;
1042 diag("asmins: noproto %P", p);
1045 xo = o->op[0] == 0x0f;
1046 for(z=0; *t; z+=t[3]+xo,t+=4)
1054 case Pq: /* 16 bit escape and opcode escape */
1059 case Pf2: /* xmm opcode escape */
1061 *andptr++ = o->prefix;
1065 case Pm: /* opcode escape */
1069 case Pe: /* 16 bit escape */
1073 case Pw: /* 64-bit escape */
1075 diag("asmins: illegal 64: %P", p);
1079 case Pb: /* botch */
1084 case P32: /* 32 bit but illegal if 64-bit mode */
1086 diag("asmins: illegal in 64-bit mode: %P", p);
1089 case Py: /* 64-bit only, no prefix */
1091 diag("asmins: illegal in %d-bit mode: %P", p->mode, p);
1094 v = vaddr(&p->from);
1102 diag("asmins: unknown z %d %P", t[2], p);
1109 for(; op = o->op[z]; z++)
1118 asmand(&p->from, &p->to);
1122 mediaop(o, op, t[3], z);
1123 asmand(&p->from, &p->to);
1128 mediaop(o, op, t[3], z);
1129 asmand(&p->from, &p->to);
1133 mediaop(o, op, t[3], z);
1134 asmand(&p->from, &p->to);
1135 *andptr++ = p->to.offset;
1141 asmand(&p->from, &p->to);
1147 asmand(&p->from, &p->to);
1148 *andptr++ = p->to.offset;
1152 *andptr++ = 0x8d; /* leal */
1153 if(p->from.type != D_ADDR)
1154 diag("asmins: Zaut sb type ADDR");
1155 p->from.type = p->from.index;
1156 p->from.index = D_NONE;
1157 asmand(&p->from, &p->to);
1158 p->from.index = p->from.type;
1159 p->from.type = D_ADDR;
1164 asmando(&p->from, o->op[z+1]);
1169 asmand(&p->to, &p->from);
1173 mediaop(o, op, t[3], z);
1174 asmand(&p->to, &p->from);
1179 mediaop(o, op, t[3], z);
1180 asmand(&p->to, &p->from);
1184 mediaop(o, op, t[3], z);
1185 asmand(&p->to, &p->from);
1186 *andptr++ = p->from.offset;
1191 asmando(&p->to, o->op[z+1]);
1196 asmandsz(&p->to, o->op[z+1], 0, 1);
1202 asmando(&p->from, o->op[z+1]);
1208 asmando(&p->to, o->op[z+1]);
1213 z = mediaop(o, op, t[3], z);
1214 asmando(&p->to, o->op[z+1]);
1226 rexflag |= regrex[p->to.type] & (Rxb|0x40);
1227 *andptr++ = op + reg[p->to.type];
1232 rexflag |= regrex[p->to.type] & Rxb;
1233 *andptr++ = op + reg[p->to.type];
1234 if(o->prefix == Pe) {
1244 if(p->from.type != D_NONE){
1254 //print("zero: %llux %P\n", v, p);
1255 rexflag &= ~(0x40|Rxw);
1256 rexflag |= regrex[p->to.type] & Rxb;
1257 *andptr++ = 0xb8 + reg[p->to.type];
1259 }else if(l == -1 && (v&((uvlong)1<<31))!=0){ /* sign extend */
1261 //print("sign: %llux %P\n", v, p);
1265 }else{ /* need all 8 */
1266 //print("all: %llux %P\n", v, p);
1267 rexflag |= regrex[p->to.type] & Rxb;
1268 *andptr++ = op + reg[p->to.type];
1275 asmand(&p->to, &p->to);
1283 if(o->prefix == Pe) {
1294 asmando(&p->from, o->op[z+1]);
1295 if(o->prefix == Pe) {
1305 asmando(&p->to, o->op[z+1]);
1306 if(o->prefix == Pe) {
1316 asmand(&p->to, &p->to);
1317 if(o->prefix == Pe) {
1326 rexflag |= regrex[p->to.type] & (Rxb|0x40);
1327 *andptr++ = op + reg[p->to.type];
1331 rexflag |= regrex[p->from.type] & (Rxb|0x40);
1332 *andptr++ = op + reg[p->from.type];
1337 asmand(&p->to, &p->to);
1343 v = q->pc - p->pc - 2;
1344 if(v >= -128 && v <= 127) {
1350 *andptr++ = o->op[z+1];
1362 v = q->pc - p->pc - 5;
1363 if(dlm && curp != P && p->to.sym->type == SUNDEF){
1364 /* v = 0 - p->pc - 5; */
1366 ckoff(p->to.sym, v);
1367 v += p->to.sym->value;
1368 dynreloc(p->to.sym, p->pc+1, 0);
1381 v = q->pc - p->pc - 2;
1382 if(v >= -128 && v <= 127) {
1387 *andptr++ = o->op[z+1];
1399 v = q->pc - p->pc - 2;
1400 if(v < -128 || v > 127)
1401 diag("loop too far: %P", p);
1427 for(mo=ymovtab; mo->as; mo++)
1429 if(ycover[ft+mo->ft])
1430 if(ycover[tt+mo->tt]){
1437 * here, the assembly has failed.
1438 * if its a byte instruction that has
1439 * unaddressable registers, try to
1440 * exchange registers and reissue the
1441 * instruction with the operands renamed.
1445 if(z >= D_BP && z <= D_DI) {
1447 *andptr++ = 0x87; /* xchg lhs,bx */
1448 asmando(&p->from, reg[D_BX]);
1449 subreg(&pp, z, D_BX);
1451 *andptr++ = 0x87; /* xchg lhs,bx */
1452 asmando(&p->from, reg[D_BX]);
1454 *andptr++ = 0x90 + reg[z]; /* xchg lsh,ax */
1455 subreg(&pp, z, D_AX);
1457 *andptr++ = 0x90 + reg[z]; /* xchg lsh,ax */
1462 if(z >= D_BP && z <= D_DI) {
1463 if(isax(&p->from)) {
1464 *andptr++ = 0x87; /* xchg rhs,bx */
1465 asmando(&p->to, reg[D_BX]);
1466 subreg(&pp, z, D_BX);
1468 *andptr++ = 0x87; /* xchg rhs,bx */
1469 asmando(&p->to, reg[D_BX]);
1471 *andptr++ = 0x90 + reg[z]; /* xchg rsh,ax */
1472 subreg(&pp, z, D_AX);
1474 *andptr++ = 0x90 + reg[z]; /* xchg rsh,ax */
1479 diag("doasm: notfound from=%ux to=%ux %P", p->from.type, p->to.type, p);
1485 diag("asmins: unknown mov %d %P", mo->code, p);
1489 for(z=0; t[z]!=E; z++)
1495 asmando(&p->to, t[1]);
1500 asmando(&p->from, t[1]);
1503 case 3: /* r,m - 2op */
1506 asmando(&p->to, t[2]);
1507 rexflag |= regrex[p->from.type] & (Rxr|0x40);
1510 case 4: /* m,r - 2op */
1513 asmando(&p->from, t[2]);
1514 rexflag |= regrex[p->to.type] & (Rxr|0x40);
1517 case 5: /* load full pointer, trash heap */
1520 switch(p->to.index) {
1542 asmand(&p->from, &p->to);
1545 case 6: /* double shift */
1548 diag("asmins: illegal 64: %P", p);
1551 }else if(t[0] == Pe){
1562 asmandsz(&p->to, reg[p->from.index], regrex[p->from.index], 0);
1563 *andptr++ = p->from.offset;
1569 asmandsz(&p->to, reg[p->from.index], regrex[p->from.index], 0);
1587 * as befits the whole approach of the architecture,
1588 * the rex prefix must appear before the first opcode byte
1589 * (and thus after any 66/67/f2/f3/26/2e/3e prefix bytes, but
1590 * before the 0f opcode escape!), or it might be ignored.
1591 * note that the handbook often misleadingly shows 66/f2/f3 in `opcode'.
1594 diag("asmins: illegal in mode %d: %P", p->mode, p);
1596 for(np = 0; np < n; np++) {
1598 if(c != 0xf2 && c != 0xf3 && (c < 0x64 || c > 0x67) && c != 0x2e && c != 0x3e && c != 0x26)
1601 memmove(and+np+1, and+np, n-np);
1602 and[np] = 0x40 | rexflag;
1614 int modemap[4] = { 0, 1, -1, 2, };
1616 typedef struct Reloc Reloc;
1639 r->m = nm = malloc(r->t*sizeof(uchar));
1640 r->a = na = malloc(r->t*sizeof(ulong));
1641 memmove(nm, m, t*sizeof(uchar));
1642 memmove(na, a, t*sizeof(ulong));
1648 dynreloc(Sym *s, ulong v, int abs)
1655 if(s->type == SUNDEF)
1656 k = abs ? ABSU : RELU;
1658 k = abs ? ABSD : RELD;
1659 /* Bprint(&bso, "R %s a=%ld(%lx) %d\n", s->name, v, v, k); */
1667 for(i = n; i > 0; i--){
1668 if(v < a[i-1]){ /* happens occasionally for data */
1703 off = seek(cout, 0, 1);
1708 for(i = 0; i < NHASH; i++)
1709 for(s = hash[i]; s != S; s = s->link)
1710 if(s->type == SUNDEF){
1723 for(i = 0; i < n; i++){
1726 diag("bad relocation order");
1755 Bprint(&bso, "import table entries = %d\n", imports);
1756 Bprint(&bso, "export table entries = %d\n", exports);