1
// Inferno utils/8l/span.c
2
// http://code.google.com/p/inferno-os/source/browse/utils/8l/span.c
4
// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
5
// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
6
// Portions Copyright © 1997-1999 Vita Nuova Limited
7
// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
8
// Portions Copyright © 2004,2006 Bruce Ellis
9
// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
10
// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
11
// Portions Copyright © 2009 The Go Authors. All rights reserved.
13
// Permission is hereby granted, free of charge, to any person obtaining a copy
14
// of this software and associated documentation files (the "Software"), to deal
15
// in the Software without restriction, including without limitation the rights
16
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17
// copies of the Software, and to permit persons to whom the Software is
18
// furnished to do so, subject to the following conditions:
20
// The above copyright notice and this permission notice shall be included in
21
// all copies or substantial portions of the Software.
23
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
31
// Instruction layout.
37
#include "../cmd/8l/8.out.h"
38
#include "../pkg/runtime/stack.h"
42
MaxAlign = 32, // max data alignment
46
extern char *anames6[];
48
typedef struct Optab Optab;
83
Ycs, Yss, Yds, Yes, Yfs, Ygs,
84
Ygdtr, Yidtr, Yldtr, Ymsw, Ytask,
85
Ycr0, Ycr1, Ycr2, Ycr3, Ycr4, Ycr5, Ycr6, Ycr7,
86
Ydr0, Ydr1, Ydr2, Ydr3, Ydr4, Ydr5, Ydr6, Ydr7,
87
Ytr0, Ytr1, Ytr2, Ytr3, Ytr4, Ytr5, Ytr6, Ytr7,
130
Zibm_r, /* mmx1,mmx2/mem64,imm8 */
136
Pe = 0x66, /* operand escape */
137
Pm = 0x0f, /* 2byte opcode escape */
138
Pq = 0xff, /* both escape */
139
Pb = 0xfe, /* byte operands */
140
Pf2 = 0xf2, /* xmm escape 1 */
141
Pf3 = 0xf3, /* xmm escape 2 */
144
static uchar ycover[Ymax*Ymax];
145
static char reg[D_NONE];
146
static void asmins(Link *ctxt, Prog *p);
148
static uchar ynone[] =
150
Ynone, Ynone, Zlit, 1,
153
static uchar ytext[] =
155
Ymb, Yi32, Zpseudo,1,
158
static uchar ynop[] =
160
Ynone, Ynone, Zpseudo,0,
161
Ynone, Yiauto, Zpseudo,0,
162
Ynone, Yml, Zpseudo,0,
163
Ynone, Yrf, Zpseudo,0,
164
Yiauto, Ynone, Zpseudo,0,
165
Ynone, Yxr, Zpseudo,0,
166
Yml, Ynone, Zpseudo,0,
167
Yrf, Ynone, Zpseudo,0,
168
Yxr, Ynone, Zpseudo,1,
171
static uchar yfuncdata[] =
173
Yi32, Ym, Zpseudo, 0,
176
static uchar ypcdata[] =
178
Yi32, Yi32, Zpseudo, 0,
181
static uchar yxorb[] =
184
Yi32, Ymb, Zibo_m, 2,
189
static uchar yxorl[] =
193
Yi32, Yml, Zilo_m, 2,
198
static uchar yaddl[] =
202
Yi32, Yml, Zilo_m, 2,
207
static uchar yincb[] =
212
static uchar yincl[] =
218
static uchar ycmpb[] =
221
Ymb, Yi32, Zm_ibo, 2,
226
static uchar ycmpl[] =
230
Yml, Yi32, Zm_ilo, 2,
235
static uchar yshb[] =
238
Yi32, Ymb, Zibo_m, 2,
242
static uchar yshl[] =
245
Yi32, Yml, Zibo_m, 2,
250
static uchar ytestb[] =
253
Yi32, Ymb, Zibo_m, 2,
258
static uchar ytestl[] =
261
Yi32, Yml, Zilo_m, 2,
266
static uchar ymovb[] =
270
Yi32, Yrb, Zib_rp, 1,
271
Yi32, Ymb, Zibo_m, 2,
274
static uchar ymovw[] =
279
// Yi0, Yml, Zibo_m, 2, // shorter but slower AND $0,dst
280
Yi32, Yrl, Zil_rp, 1,
281
Yi32, Yml, Zilo_m, 2,
282
Yiauto, Yrl, Zaut_r, 1,
285
static uchar ymovl[] =
290
// Yi0, Yml, Zibo_m, 2, // shorter but slower AND $0,dst
291
Yi32, Yrl, Zil_rp, 1,
292
Yi32, Yml, Zilo_m, 2,
293
Yml, Yxr, Zm_r_xm, 2, // XMM MOVD (32 bit)
294
Yxr, Yml, Zr_m_xm, 2, // XMM MOVD (32 bit)
295
Yiauto, Yrl, Zaut_r, 1,
298
static uchar ymovq[] =
300
Yml, Yxr, Zm_r_xm, 2,
303
static uchar ym_rl[] =
308
static uchar yrl_m[] =
313
static uchar ymb_rl[] =
318
static uchar yml_rl[] =
323
static uchar yrb_mb[] =
328
static uchar yrl_ml[] =
333
static uchar yml_mb[] =
339
static uchar yxchg[] =
347
static uchar ydivl[] =
352
static uchar ydivb[] =
357
static uchar yimul[] =
361
Yi32, Yrl, Zil_rr, 1,
364
static uchar ybyte[] =
366
Yi32, Ynone, Zbyte, 1,
371
Yi32, Ynone, Zib_, 1,
372
Ynone, Ynone, Zlit, 1,
375
static uchar yint[] =
377
Yi32, Ynone, Zib_, 1,
380
static uchar ypushl[] =
385
Yi32, Ynone, Zil_, 1,
388
static uchar ypopl[] =
394
static uchar ybswap[] =
399
static uchar yscond[] =
404
static uchar yjcond[] =
411
static uchar yloop[] =
413
Ynone, Ybr, Zloop, 1,
416
static uchar ycall[] =
418
Ynone, Yml, Zcallindreg, 0,
419
Yrx, Yrx, Zcallindreg, 2,
420
Ynone, Ycol, Zcallind, 2,
421
Ynone, Ybr, Zcall, 0,
422
Ynone, Yi32, Zcallcon, 1,
425
static uchar yduff[] =
427
Ynone, Yi32, Zcall, 1,
430
static uchar yjmp[] =
434
Ynone, Yi32, Zjmpcon, 1,
438
static uchar yfmvd[] =
446
static uchar yfmvdp[] =
452
static uchar yfmvf[] =
458
static uchar yfmvx[] =
463
static uchar yfmvp[] =
468
static uchar yfcmv[] =
473
static uchar yfadd[] =
480
static uchar yfaddp[] =
485
static uchar yfxch[] =
491
static uchar ycompp[] =
493
Yf0, Yrf, Zo_m, 2, /* botch is really f0,f1 */
496
static uchar ystsw[] =
502
static uchar ystcw[] =
508
static uchar ysvrs[] =
514
static uchar ymskb[] =
516
Yxr, Yrl, Zm_r_xm, 2,
517
Ymr, Yrl, Zm_r_xm, 1,
522
Yxm, Yxr, Zm_r_xm, 1,
525
static uchar yxcvm1[] =
527
Yxm, Yxr, Zm_r_xm, 2,
528
Yxm, Ymr, Zm_r_xm, 2,
531
static uchar yxcvm2[] =
533
Yxm, Yxr, Zm_r_xm, 2,
534
Ymm, Yxr, Zm_r_xm, 2,
537
static uchar yxmq[] =
539
Yxm, Yxr, Zm_r_xm, 2,
544
Yxr, Yxr, Zm_r_xm, 1,
547
static uchar yxr_ml[] =
549
Yxr, Yml, Zr_m_xm, 1,
552
static uchar yxcmp[] =
554
Yxm, Yxr, Zm_r_xm, 1,
557
static uchar yxcmpi[] =
559
Yxm, Yxr, Zm_r_i_xm, 2,
562
static uchar yxmov[] =
564
Yxm, Yxr, Zm_r_xm, 1,
565
Yxr, Yxm, Zr_m_xm, 1,
568
static uchar yxcvfl[] =
570
Yxm, Yrl, Zm_r_xm, 1,
573
static uchar yxcvlf[] =
575
Yml, Yxr, Zm_r_xm, 1,
579
static uchar yxcvfq[] =
581
Yxm, Yrl, Zm_r_xm, 2,
584
static uchar yxcvqf[] =
586
Yml, Yxr, Zm_r_xm, 2,
590
static uchar yxrrl[] =
595
static uchar yprefetch[] =
600
static uchar yaes[] =
602
Yxm, Yxr, Zlitm_r, 2,
605
static uchar yinsrd[] =
610
static uchar ymshufb[] =
616
static Optab optab[] =
617
/* as, ytab, andproto, opcode */
620
{ AAAA, ynone, Px, 0x37 },
621
{ AAAD, ynone, Px, 0xd5,0x0a },
622
{ AAAM, ynone, Px, 0xd4,0x0a },
623
{ AAAS, ynone, Px, 0x3f },
624
{ AADCB, yxorb, Pb, 0x14,0x80,(02),0x10,0x10 },
625
{ AADCL, yxorl, Px, 0x83,(02),0x15,0x81,(02),0x11,0x13 },
626
{ AADCW, yxorl, Pe, 0x83,(02),0x15,0x81,(02),0x11,0x13 },
627
{ AADDB, yxorb, Px, 0x04,0x80,(00),0x00,0x02 },
628
{ AADDL, yaddl, Px, 0x83,(00),0x05,0x81,(00),0x01,0x03 },
629
{ AADDW, yaddl, Pe, 0x83,(00),0x05,0x81,(00),0x01,0x03 },
631
{ AANDB, yxorb, Pb, 0x24,0x80,(04),0x20,0x22 },
632
{ AANDL, yxorl, Px, 0x83,(04),0x25,0x81,(04),0x21,0x23 },
633
{ AANDW, yxorl, Pe, 0x83,(04),0x25,0x81,(04),0x21,0x23 },
634
{ AARPL, yrl_ml, Px, 0x63 },
635
{ ABOUNDL, yrl_m, Px, 0x62 },
636
{ ABOUNDW, yrl_m, Pe, 0x62 },
637
{ ABSFL, yml_rl, Pm, 0xbc },
638
{ ABSFW, yml_rl, Pq, 0xbc },
639
{ ABSRL, yml_rl, Pm, 0xbd },
640
{ ABSRW, yml_rl, Pq, 0xbd },
641
{ ABTL, yml_rl, Pm, 0xa3 },
642
{ ABTW, yml_rl, Pq, 0xa3 },
643
{ ABTCL, yml_rl, Pm, 0xbb },
644
{ ABTCW, yml_rl, Pq, 0xbb },
645
{ ABTRL, yml_rl, Pm, 0xb3 },
646
{ ABTRW, yml_rl, Pq, 0xb3 },
647
{ ABTSL, yml_rl, Pm, 0xab },
648
{ ABTSW, yml_rl, Pq, 0xab },
649
{ ABYTE, ybyte, Px, 1 },
650
{ ACALL, ycall, Px, 0xff,(02),0xff,(0x15),0xe8 },
651
{ ACLC, ynone, Px, 0xf8 },
652
{ ACLD, ynone, Px, 0xfc },
653
{ ACLI, ynone, Px, 0xfa },
654
{ ACLTS, ynone, Pm, 0x06 },
655
{ ACMC, ynone, Px, 0xf5 },
656
{ ACMPB, ycmpb, Pb, 0x3c,0x80,(07),0x38,0x3a },
657
{ ACMPL, ycmpl, Px, 0x83,(07),0x3d,0x81,(07),0x39,0x3b },
658
{ ACMPW, ycmpl, Pe, 0x83,(07),0x3d,0x81,(07),0x39,0x3b },
659
{ ACMPSB, ynone, Pb, 0xa6 },
660
{ ACMPSL, ynone, Px, 0xa7 },
661
{ ACMPSW, ynone, Pe, 0xa7 },
662
{ ADAA, ynone, Px, 0x27 },
663
{ ADAS, ynone, Px, 0x2f },
665
{ ADECB, yincb, Pb, 0xfe,(01) },
666
{ ADECL, yincl, Px, 0x48,0xff,(01) },
667
{ ADECW, yincl, Pe, 0x48,0xff,(01) },
668
{ ADIVB, ydivb, Pb, 0xf6,(06) },
669
{ ADIVL, ydivl, Px, 0xf7,(06) },
670
{ ADIVW, ydivl, Pe, 0xf7,(06) },
671
{ AENTER }, /* botch */
675
{ AHLT, ynone, Px, 0xf4 },
676
{ AIDIVB, ydivb, Pb, 0xf6,(07) },
677
{ AIDIVL, ydivl, Px, 0xf7,(07) },
678
{ AIDIVW, ydivl, Pe, 0xf7,(07) },
679
{ AIMULB, ydivb, Pb, 0xf6,(05) },
680
{ AIMULL, yimul, Px, 0xf7,(05),0x6b,0x69 },
681
{ AIMULW, yimul, Pe, 0xf7,(05),0x6b,0x69 },
682
{ AINB, yin, Pb, 0xe4,0xec },
683
{ AINL, yin, Px, 0xe5,0xed },
684
{ AINW, yin, Pe, 0xe5,0xed },
685
{ AINCB, yincb, Pb, 0xfe,(00) },
686
{ AINCL, yincl, Px, 0x40,0xff,(00) },
687
{ AINCW, yincl, Pe, 0x40,0xff,(00) },
688
{ AINSB, ynone, Pb, 0x6c },
689
{ AINSL, ynone, Px, 0x6d },
690
{ AINSW, ynone, Pe, 0x6d },
691
{ AINT, yint, Px, 0xcd },
692
{ AINTO, ynone, Px, 0xce },
693
{ AIRETL, ynone, Px, 0xcf },
694
{ AIRETW, ynone, Pe, 0xcf },
695
{ AJCC, yjcond, Px, 0x73,0x83,(00) },
696
{ AJCS, yjcond, Px, 0x72,0x82 },
697
{ AJCXZL, yloop, Px, 0xe3 },
698
{ AJCXZW, yloop, Px, 0xe3 },
699
{ AJEQ, yjcond, Px, 0x74,0x84 },
700
{ AJGE, yjcond, Px, 0x7d,0x8d },
701
{ AJGT, yjcond, Px, 0x7f,0x8f },
702
{ AJHI, yjcond, Px, 0x77,0x87 },
703
{ AJLE, yjcond, Px, 0x7e,0x8e },
704
{ AJLS, yjcond, Px, 0x76,0x86 },
705
{ AJLT, yjcond, Px, 0x7c,0x8c },
706
{ AJMI, yjcond, Px, 0x78,0x88 },
707
{ AJMP, yjmp, Px, 0xff,(04),0xeb,0xe9 },
708
{ AJNE, yjcond, Px, 0x75,0x85 },
709
{ AJOC, yjcond, Px, 0x71,0x81,(00) },
710
{ AJOS, yjcond, Px, 0x70,0x80,(00) },
711
{ AJPC, yjcond, Px, 0x7b,0x8b },
712
{ AJPL, yjcond, Px, 0x79,0x89 },
713
{ AJPS, yjcond, Px, 0x7a,0x8a },
714
{ ALAHF, ynone, Px, 0x9f },
715
{ ALARL, yml_rl, Pm, 0x02 },
716
{ ALARW, yml_rl, Pq, 0x02 },
717
{ ALEAL, ym_rl, Px, 0x8d },
718
{ ALEAW, ym_rl, Pe, 0x8d },
719
{ ALEAVEL, ynone, Px, 0xc9 },
720
{ ALEAVEW, ynone, Pe, 0xc9 },
721
{ ALOCK, ynone, Px, 0xf0 },
722
{ ALODSB, ynone, Pb, 0xac },
723
{ ALODSL, ynone, Px, 0xad },
724
{ ALODSW, ynone, Pe, 0xad },
725
{ ALONG, ybyte, Px, 4 },
726
{ ALOOP, yloop, Px, 0xe2 },
727
{ ALOOPEQ, yloop, Px, 0xe1 },
728
{ ALOOPNE, yloop, Px, 0xe0 },
729
{ ALSLL, yml_rl, Pm, 0x03 },
730
{ ALSLW, yml_rl, Pq, 0x03 },
731
{ AMOVB, ymovb, Pb, 0x88,0x8a,0xb0,0xc6,(00) },
732
{ AMOVL, ymovl, Px, 0x89,0x8b,0x31,0x83,(04),0xb8,0xc7,(00),Pe,0x6e,Pe,0x7e,0 },
733
{ AMOVW, ymovw, Pe, 0x89,0x8b,0x31,0x83,(04),0xb8,0xc7,(00),0 },
734
{ AMOVQ, ymovq, Pf3, 0x7e },
735
{ AMOVBLSX, ymb_rl, Pm, 0xbe },
736
{ AMOVBLZX, ymb_rl, Pm, 0xb6 },
737
{ AMOVBWSX, ymb_rl, Pq, 0xbe },
738
{ AMOVBWZX, ymb_rl, Pq, 0xb6 },
739
{ AMOVWLSX, yml_rl, Pm, 0xbf },
740
{ AMOVWLZX, yml_rl, Pm, 0xb7 },
741
{ AMOVSB, ynone, Pb, 0xa4 },
742
{ AMOVSL, ynone, Px, 0xa5 },
743
{ AMOVSW, ynone, Pe, 0xa5 },
744
{ AMULB, ydivb, Pb, 0xf6,(04) },
745
{ AMULL, ydivl, Px, 0xf7,(04) },
746
{ AMULW, ydivl, Pe, 0xf7,(04) },
748
{ ANEGB, yscond, Px, 0xf6,(03) },
749
{ ANEGL, yscond, Px, 0xf7,(03) },
750
{ ANEGW, yscond, Pe, 0xf7,(03) },
751
{ ANOP, ynop, Px,0,0 },
752
{ ANOTB, yscond, Px, 0xf6,(02) },
753
{ ANOTL, yscond, Px, 0xf7,(02) },
754
{ ANOTW, yscond, Pe, 0xf7,(02) },
755
{ AORB, yxorb, Pb, 0x0c,0x80,(01),0x08,0x0a },
756
{ AORL, yxorl, Px, 0x83,(01),0x0d,0x81,(01),0x09,0x0b },
757
{ AORW, yxorl, Pe, 0x83,(01),0x0d,0x81,(01),0x09,0x0b },
758
{ AOUTB, yin, Pb, 0xe6,0xee },
759
{ AOUTL, yin, Px, 0xe7,0xef },
760
{ AOUTW, yin, Pe, 0xe7,0xef },
761
{ AOUTSB, ynone, Pb, 0x6e },
762
{ AOUTSL, ynone, Px, 0x6f },
763
{ AOUTSW, ynone, Pe, 0x6f },
764
{ APAUSE, ynone, Px, 0xf3,0x90 },
765
{ APOPAL, ynone, Px, 0x61 },
766
{ APOPAW, ynone, Pe, 0x61 },
767
{ APOPFL, ynone, Px, 0x9d },
768
{ APOPFW, ynone, Pe, 0x9d },
769
{ APOPL, ypopl, Px, 0x58,0x8f,(00) },
770
{ APOPW, ypopl, Pe, 0x58,0x8f,(00) },
771
{ APUSHAL, ynone, Px, 0x60 },
772
{ APUSHAW, ynone, Pe, 0x60 },
773
{ APUSHFL, ynone, Px, 0x9c },
774
{ APUSHFW, ynone, Pe, 0x9c },
775
{ APUSHL, ypushl, Px, 0x50,0xff,(06),0x6a,0x68 },
776
{ APUSHW, ypushl, Pe, 0x50,0xff,(06),0x6a,0x68 },
777
{ ARCLB, yshb, Pb, 0xd0,(02),0xc0,(02),0xd2,(02) },
778
{ ARCLL, yshl, Px, 0xd1,(02),0xc1,(02),0xd3,(02),0xd3,(02) },
779
{ ARCLW, yshl, Pe, 0xd1,(02),0xc1,(02),0xd3,(02),0xd3,(02) },
780
{ ARCRB, yshb, Pb, 0xd0,(03),0xc0,(03),0xd2,(03) },
781
{ ARCRL, yshl, Px, 0xd1,(03),0xc1,(03),0xd3,(03),0xd3,(03) },
782
{ ARCRW, yshl, Pe, 0xd1,(03),0xc1,(03),0xd3,(03),0xd3,(03) },
783
{ AREP, ynone, Px, 0xf3 },
784
{ AREPN, ynone, Px, 0xf2 },
785
{ ARET, ynone, Px, 0xc3 },
786
{ AROLB, yshb, Pb, 0xd0,(00),0xc0,(00),0xd2,(00) },
787
{ AROLL, yshl, Px, 0xd1,(00),0xc1,(00),0xd3,(00),0xd3,(00) },
788
{ AROLW, yshl, Pe, 0xd1,(00),0xc1,(00),0xd3,(00),0xd3,(00) },
789
{ ARORB, yshb, Pb, 0xd0,(01),0xc0,(01),0xd2,(01) },
790
{ ARORL, yshl, Px, 0xd1,(01),0xc1,(01),0xd3,(01),0xd3,(01) },
791
{ ARORW, yshl, Pe, 0xd1,(01),0xc1,(01),0xd3,(01),0xd3,(01) },
792
{ ASAHF, ynone, Px, 0x9e },
793
{ ASALB, yshb, Pb, 0xd0,(04),0xc0,(04),0xd2,(04) },
794
{ ASALL, yshl, Px, 0xd1,(04),0xc1,(04),0xd3,(04),0xd3,(04) },
795
{ ASALW, yshl, Pe, 0xd1,(04),0xc1,(04),0xd3,(04),0xd3,(04) },
796
{ ASARB, yshb, Pb, 0xd0,(07),0xc0,(07),0xd2,(07) },
797
{ ASARL, yshl, Px, 0xd1,(07),0xc1,(07),0xd3,(07),0xd3,(07) },
798
{ ASARW, yshl, Pe, 0xd1,(07),0xc1,(07),0xd3,(07),0xd3,(07) },
799
{ ASBBB, yxorb, Pb, 0x1c,0x80,(03),0x18,0x1a },
800
{ ASBBL, yxorl, Px, 0x83,(03),0x1d,0x81,(03),0x19,0x1b },
801
{ ASBBW, yxorl, Pe, 0x83,(03),0x1d,0x81,(03),0x19,0x1b },
802
{ ASCASB, ynone, Pb, 0xae },
803
{ ASCASL, ynone, Px, 0xaf },
804
{ ASCASW, ynone, Pe, 0xaf },
805
{ ASETCC, yscond, Pm, 0x93,(00) },
806
{ ASETCS, yscond, Pm, 0x92,(00) },
807
{ ASETEQ, yscond, Pm, 0x94,(00) },
808
{ ASETGE, yscond, Pm, 0x9d,(00) },
809
{ ASETGT, yscond, Pm, 0x9f,(00) },
810
{ ASETHI, yscond, Pm, 0x97,(00) },
811
{ ASETLE, yscond, Pm, 0x9e,(00) },
812
{ ASETLS, yscond, Pm, 0x96,(00) },
813
{ ASETLT, yscond, Pm, 0x9c,(00) },
814
{ ASETMI, yscond, Pm, 0x98,(00) },
815
{ ASETNE, yscond, Pm, 0x95,(00) },
816
{ ASETOC, yscond, Pm, 0x91,(00) },
817
{ ASETOS, yscond, Pm, 0x90,(00) },
818
{ ASETPC, yscond, Pm, 0x96,(00) },
819
{ ASETPL, yscond, Pm, 0x99,(00) },
820
{ ASETPS, yscond, Pm, 0x9a,(00) },
821
{ ACDQ, ynone, Px, 0x99 },
822
{ ACWD, ynone, Pe, 0x99 },
823
{ ASHLB, yshb, Pb, 0xd0,(04),0xc0,(04),0xd2,(04) },
824
{ ASHLL, yshl, Px, 0xd1,(04),0xc1,(04),0xd3,(04),0xd3,(04) },
825
{ ASHLW, yshl, Pe, 0xd1,(04),0xc1,(04),0xd3,(04),0xd3,(04) },
826
{ ASHRB, yshb, Pb, 0xd0,(05),0xc0,(05),0xd2,(05) },
827
{ ASHRL, yshl, Px, 0xd1,(05),0xc1,(05),0xd3,(05),0xd3,(05) },
828
{ ASHRW, yshl, Pe, 0xd1,(05),0xc1,(05),0xd3,(05),0xd3,(05) },
829
{ ASTC, ynone, Px, 0xf9 },
830
{ ASTD, ynone, Px, 0xfd },
831
{ ASTI, ynone, Px, 0xfb },
832
{ ASTOSB, ynone, Pb, 0xaa },
833
{ ASTOSL, ynone, Px, 0xab },
834
{ ASTOSW, ynone, Pe, 0xab },
835
{ ASUBB, yxorb, Pb, 0x2c,0x80,(05),0x28,0x2a },
836
{ ASUBL, yaddl, Px, 0x83,(05),0x2d,0x81,(05),0x29,0x2b },
837
{ ASUBW, yaddl, Pe, 0x83,(05),0x2d,0x81,(05),0x29,0x2b },
838
{ ASYSCALL, ynone, Px, 0xcd,100 },
839
{ ATESTB, ytestb, Pb, 0xa8,0xf6,(00),0x84,0x84 },
840
{ ATESTL, ytestl, Px, 0xa9,0xf7,(00),0x85,0x85 },
841
{ ATESTW, ytestl, Pe, 0xa9,0xf7,(00),0x85,0x85 },
842
{ ATEXT, ytext, Px },
843
{ AVERR, ydivl, Pm, 0x00,(04) },
844
{ AVERW, ydivl, Pm, 0x00,(05) },
845
{ AWAIT, ynone, Px, 0x9b },
846
{ AWORD, ybyte, Px, 2 },
847
{ AXCHGB, yml_mb, Pb, 0x86,0x86 },
848
{ AXCHGL, yxchg, Px, 0x90,0x90,0x87,0x87 },
849
{ AXCHGW, yxchg, Pe, 0x90,0x90,0x87,0x87 },
850
{ AXLAT, ynone, Px, 0xd7 },
851
{ AXORB, yxorb, Pb, 0x34,0x80,(06),0x30,0x32 },
852
{ AXORL, yxorl, Px, 0x83,(06),0x35,0x81,(06),0x31,0x33 },
853
{ AXORW, yxorl, Pe, 0x83,(06),0x35,0x81,(06),0x31,0x33 },
855
{ AFMOVB, yfmvx, Px, 0xdf,(04) },
856
{ AFMOVBP, yfmvp, Px, 0xdf,(06) },
857
{ AFMOVD, yfmvd, Px, 0xdd,(00),0xdd,(02),0xd9,(00),0xdd,(02) },
858
{ AFMOVDP, yfmvdp, Px, 0xdd,(03),0xdd,(03) },
859
{ AFMOVF, yfmvf, Px, 0xd9,(00),0xd9,(02) },
860
{ AFMOVFP, yfmvp, Px, 0xd9,(03) },
861
{ AFMOVL, yfmvf, Px, 0xdb,(00),0xdb,(02) },
862
{ AFMOVLP, yfmvp, Px, 0xdb,(03) },
863
{ AFMOVV, yfmvx, Px, 0xdf,(05) },
864
{ AFMOVVP, yfmvp, Px, 0xdf,(07) },
865
{ AFMOVW, yfmvf, Px, 0xdf,(00),0xdf,(02) },
866
{ AFMOVWP, yfmvp, Px, 0xdf,(03) },
867
{ AFMOVX, yfmvx, Px, 0xdb,(05) },
868
{ AFMOVXP, yfmvp, Px, 0xdb,(07) },
872
{ AFCOMD, yfadd, Px, 0xdc,(02),0xd8,(02),0xdc,(02) }, /* botch */
873
{ AFCOMDP, yfadd, Px, 0xdc,(03),0xd8,(03),0xdc,(03) }, /* botch */
874
{ AFCOMDPP, ycompp, Px, 0xde,(03) },
875
{ AFCOMF, yfmvx, Px, 0xd8,(02) },
876
{ AFCOMFP, yfmvx, Px, 0xd8,(03) },
877
{ AFCOMI, yfmvx, Px, 0xdb,(06) },
878
{ AFCOMIP, yfmvx, Px, 0xdf,(06) },
879
{ AFCOML, yfmvx, Px, 0xda,(02) },
880
{ AFCOMLP, yfmvx, Px, 0xda,(03) },
881
{ AFCOMW, yfmvx, Px, 0xde,(02) },
882
{ AFCOMWP, yfmvx, Px, 0xde,(03) },
884
{ AFUCOM, ycompp, Px, 0xdd,(04) },
885
{ AFUCOMI, ycompp, Px, 0xdb,(05) },
886
{ AFUCOMIP, ycompp, Px, 0xdf,(05) },
887
{ AFUCOMP, ycompp, Px, 0xdd,(05) },
888
{ AFUCOMPP, ycompp, Px, 0xda,(13) },
890
{ AFADDDP, yfaddp, Px, 0xde,(00) },
891
{ AFADDW, yfmvx, Px, 0xde,(00) },
892
{ AFADDL, yfmvx, Px, 0xda,(00) },
893
{ AFADDF, yfmvx, Px, 0xd8,(00) },
894
{ AFADDD, yfadd, Px, 0xdc,(00),0xd8,(00),0xdc,(00) },
896
{ AFMULDP, yfaddp, Px, 0xde,(01) },
897
{ AFMULW, yfmvx, Px, 0xde,(01) },
898
{ AFMULL, yfmvx, Px, 0xda,(01) },
899
{ AFMULF, yfmvx, Px, 0xd8,(01) },
900
{ AFMULD, yfadd, Px, 0xdc,(01),0xd8,(01),0xdc,(01) },
902
{ AFSUBDP, yfaddp, Px, 0xde,(05) },
903
{ AFSUBW, yfmvx, Px, 0xde,(04) },
904
{ AFSUBL, yfmvx, Px, 0xda,(04) },
905
{ AFSUBF, yfmvx, Px, 0xd8,(04) },
906
{ AFSUBD, yfadd, Px, 0xdc,(04),0xd8,(04),0xdc,(05) },
908
{ AFSUBRDP, yfaddp, Px, 0xde,(04) },
909
{ AFSUBRW, yfmvx, Px, 0xde,(05) },
910
{ AFSUBRL, yfmvx, Px, 0xda,(05) },
911
{ AFSUBRF, yfmvx, Px, 0xd8,(05) },
912
{ AFSUBRD, yfadd, Px, 0xdc,(05),0xd8,(05),0xdc,(04) },
914
{ AFDIVDP, yfaddp, Px, 0xde,(07) },
915
{ AFDIVW, yfmvx, Px, 0xde,(06) },
916
{ AFDIVL, yfmvx, Px, 0xda,(06) },
917
{ AFDIVF, yfmvx, Px, 0xd8,(06) },
918
{ AFDIVD, yfadd, Px, 0xdc,(06),0xd8,(06),0xdc,(07) },
920
{ AFDIVRDP, yfaddp, Px, 0xde,(06) },
921
{ AFDIVRW, yfmvx, Px, 0xde,(07) },
922
{ AFDIVRL, yfmvx, Px, 0xda,(07) },
923
{ AFDIVRF, yfmvx, Px, 0xd8,(07) },
924
{ AFDIVRD, yfadd, Px, 0xdc,(07),0xd8,(07),0xdc,(06) },
926
{ AFXCHD, yfxch, Px, 0xd9,(01),0xd9,(01) },
928
{ AFLDCW, ystcw, Px, 0xd9,(05),0xd9,(05) },
929
{ AFLDENV, ystcw, Px, 0xd9,(04),0xd9,(04) },
930
{ AFRSTOR, ysvrs, Px, 0xdd,(04),0xdd,(04) },
931
{ AFSAVE, ysvrs, Px, 0xdd,(06),0xdd,(06) },
932
{ AFSTCW, ystcw, Px, 0xd9,(07),0xd9,(07) },
933
{ AFSTENV, ystcw, Px, 0xd9,(06),0xd9,(06) },
934
{ AFSTSW, ystsw, Px, 0xdd,(07),0xdf,0xe0 },
935
{ AF2XM1, ynone, Px, 0xd9, 0xf0 },
936
{ AFABS, ynone, Px, 0xd9, 0xe1 },
937
{ AFCHS, ynone, Px, 0xd9, 0xe0 },
938
{ AFCLEX, ynone, Px, 0xdb, 0xe2 },
939
{ AFCOS, ynone, Px, 0xd9, 0xff },
940
{ AFDECSTP, ynone, Px, 0xd9, 0xf6 },
941
{ AFINCSTP, ynone, Px, 0xd9, 0xf7 },
942
{ AFINIT, ynone, Px, 0xdb, 0xe3 },
943
{ AFLD1, ynone, Px, 0xd9, 0xe8 },
944
{ AFLDL2E, ynone, Px, 0xd9, 0xea },
945
{ AFLDL2T, ynone, Px, 0xd9, 0xe9 },
946
{ AFLDLG2, ynone, Px, 0xd9, 0xec },
947
{ AFLDLN2, ynone, Px, 0xd9, 0xed },
948
{ AFLDPI, ynone, Px, 0xd9, 0xeb },
949
{ AFLDZ, ynone, Px, 0xd9, 0xee },
950
{ AFNOP, ynone, Px, 0xd9, 0xd0 },
951
{ AFPATAN, ynone, Px, 0xd9, 0xf3 },
952
{ AFPREM, ynone, Px, 0xd9, 0xf8 },
953
{ AFPREM1, ynone, Px, 0xd9, 0xf5 },
954
{ AFPTAN, ynone, Px, 0xd9, 0xf2 },
955
{ AFRNDINT, ynone, Px, 0xd9, 0xfc },
956
{ AFSCALE, ynone, Px, 0xd9, 0xfd },
957
{ AFSIN, ynone, Px, 0xd9, 0xfe },
958
{ AFSINCOS, ynone, Px, 0xd9, 0xfb },
959
{ AFSQRT, ynone, Px, 0xd9, 0xfa },
960
{ AFTST, ynone, Px, 0xd9, 0xe4 },
961
{ AFXAM, ynone, Px, 0xd9, 0xe5 },
962
{ AFXTRACT, ynone, Px, 0xd9, 0xf4 },
963
{ AFYL2X, ynone, Px, 0xd9, 0xf1 },
964
{ AFYL2XP1, ynone, Px, 0xd9, 0xf9 },
969
{ ACMPXCHGB, yrb_mb, Pm, 0xb0 },
970
{ ACMPXCHGL, yrl_ml, Pm, 0xb1 },
971
{ ACMPXCHGW, yrl_ml, Pm, 0xb1 },
972
{ ACMPXCHG8B, yscond, Pm, 0xc7,(01) },
974
{ ACPUID, ynone, Pm, 0xa2 },
975
{ ARDTSC, ynone, Pm, 0x31 },
977
{ AXADDB, yrb_mb, Pb, 0x0f,0xc0 },
978
{ AXADDL, yrl_ml, Pm, 0xc1 },
979
{ AXADDW, yrl_ml, Pe, 0x0f,0xc1 },
981
{ ACMOVLCC, yml_rl, Pm, 0x43 },
982
{ ACMOVLCS, yml_rl, Pm, 0x42 },
983
{ ACMOVLEQ, yml_rl, Pm, 0x44 },
984
{ ACMOVLGE, yml_rl, Pm, 0x4d },
985
{ ACMOVLGT, yml_rl, Pm, 0x4f },
986
{ ACMOVLHI, yml_rl, Pm, 0x47 },
987
{ ACMOVLLE, yml_rl, Pm, 0x4e },
988
{ ACMOVLLS, yml_rl, Pm, 0x46 },
989
{ ACMOVLLT, yml_rl, Pm, 0x4c },
990
{ ACMOVLMI, yml_rl, Pm, 0x48 },
991
{ ACMOVLNE, yml_rl, Pm, 0x45 },
992
{ ACMOVLOC, yml_rl, Pm, 0x41 },
993
{ ACMOVLOS, yml_rl, Pm, 0x40 },
994
{ ACMOVLPC, yml_rl, Pm, 0x4b },
995
{ ACMOVLPL, yml_rl, Pm, 0x49 },
996
{ ACMOVLPS, yml_rl, Pm, 0x4a },
997
{ ACMOVWCC, yml_rl, Pq, 0x43 },
998
{ ACMOVWCS, yml_rl, Pq, 0x42 },
999
{ ACMOVWEQ, yml_rl, Pq, 0x44 },
1000
{ ACMOVWGE, yml_rl, Pq, 0x4d },
1001
{ ACMOVWGT, yml_rl, Pq, 0x4f },
1002
{ ACMOVWHI, yml_rl, Pq, 0x47 },
1003
{ ACMOVWLE, yml_rl, Pq, 0x4e },
1004
{ ACMOVWLS, yml_rl, Pq, 0x46 },
1005
{ ACMOVWLT, yml_rl, Pq, 0x4c },
1006
{ ACMOVWMI, yml_rl, Pq, 0x48 },
1007
{ ACMOVWNE, yml_rl, Pq, 0x45 },
1008
{ ACMOVWOC, yml_rl, Pq, 0x41 },
1009
{ ACMOVWOS, yml_rl, Pq, 0x40 },
1010
{ ACMOVWPC, yml_rl, Pq, 0x4b },
1011
{ ACMOVWPL, yml_rl, Pq, 0x49 },
1012
{ ACMOVWPS, yml_rl, Pq, 0x4a },
1014
{ AFCMOVCC, yfcmv, Px, 0xdb,(00) },
1015
{ AFCMOVCS, yfcmv, Px, 0xda,(00) },
1016
{ AFCMOVEQ, yfcmv, Px, 0xda,(01) },
1017
{ AFCMOVHI, yfcmv, Px, 0xdb,(02) },
1018
{ AFCMOVLS, yfcmv, Px, 0xda,(02) },
1019
{ AFCMOVNE, yfcmv, Px, 0xdb,(01) },
1020
{ AFCMOVNU, yfcmv, Px, 0xdb,(03) },
1021
{ AFCMOVUN, yfcmv, Px, 0xda,(03) },
1023
{ ALFENCE, ynone, Pm, 0xae,0xe8 },
1024
{ AMFENCE, ynone, Pm, 0xae,0xf0 },
1025
{ ASFENCE, ynone, Pm, 0xae,0xf8 },
1027
{ AEMMS, ynone, Pm, 0x77 },
1029
{ APREFETCHT0, yprefetch, Pm, 0x18,(01) },
1030
{ APREFETCHT1, yprefetch, Pm, 0x18,(02) },
1031
{ APREFETCHT2, yprefetch, Pm, 0x18,(03) },
1032
{ APREFETCHNTA, yprefetch, Pm, 0x18,(00) },
1034
{ ABSWAPL, ybswap, Pm, 0xc8 },
1036
{ AUNDEF, ynone, Px, 0x0f, 0x0b },
1038
{ AADDPD, yxm, Pq, 0x58 },
1039
{ AADDPS, yxm, Pm, 0x58 },
1040
{ AADDSD, yxm, Pf2, 0x58 },
1041
{ AADDSS, yxm, Pf3, 0x58 },
1042
{ AANDNPD, yxm, Pq, 0x55 },
1043
{ AANDNPS, yxm, Pm, 0x55 },
1044
{ AANDPD, yxm, Pq, 0x54 },
1045
{ AANDPS, yxm, Pq, 0x54 },
1046
{ ACMPPD, yxcmpi, Px, Pe,0xc2 },
1047
{ ACMPPS, yxcmpi, Pm, 0xc2,0 },
1048
{ ACMPSD, yxcmpi, Px, Pf2,0xc2 },
1049
{ ACMPSS, yxcmpi, Px, Pf3,0xc2 },
1050
{ ACOMISD, yxcmp, Pe, 0x2f },
1051
{ ACOMISS, yxcmp, Pm, 0x2f },
1052
{ ACVTPL2PD, yxcvm2, Px, Pf3,0xe6,Pe,0x2a },
1053
{ ACVTPL2PS, yxcvm2, Pm, 0x5b,0,0x2a,0, },
1054
{ ACVTPD2PL, yxcvm1, Px, Pf2,0xe6,Pe,0x2d },
1055
{ ACVTPD2PS, yxm, Pe, 0x5a },
1056
{ ACVTPS2PL, yxcvm1, Px, Pe,0x5b,Pm,0x2d },
1057
{ ACVTPS2PD, yxm, Pm, 0x5a },
1058
{ ACVTSD2SL, yxcvfl, Pf2, 0x2d },
1059
{ ACVTSD2SS, yxm, Pf2, 0x5a },
1060
{ ACVTSL2SD, yxcvlf, Pf2, 0x2a },
1061
{ ACVTSL2SS, yxcvlf, Pf3, 0x2a },
1062
{ ACVTSS2SD, yxm, Pf3, 0x5a },
1063
{ ACVTSS2SL, yxcvfl, Pf3, 0x2d },
1064
{ ACVTTPD2PL, yxcvm1, Px, Pe,0xe6,Pe,0x2c },
1065
{ ACVTTPS2PL, yxcvm1, Px, Pf3,0x5b,Pm,0x2c },
1066
{ ACVTTSD2SL, yxcvfl, Pf2, 0x2c },
1067
{ ACVTTSS2SL, yxcvfl, Pf3, 0x2c },
1068
{ ADIVPD, yxm, Pe, 0x5e },
1069
{ ADIVPS, yxm, Pm, 0x5e },
1070
{ ADIVSD, yxm, Pf2, 0x5e },
1071
{ ADIVSS, yxm, Pf3, 0x5e },
1072
{ AMASKMOVOU, yxr, Pe, 0xf7 },
1073
{ AMAXPD, yxm, Pe, 0x5f },
1074
{ AMAXPS, yxm, Pm, 0x5f },
1075
{ AMAXSD, yxm, Pf2, 0x5f },
1076
{ AMAXSS, yxm, Pf3, 0x5f },
1077
{ AMINPD, yxm, Pe, 0x5d },
1078
{ AMINPS, yxm, Pm, 0x5d },
1079
{ AMINSD, yxm, Pf2, 0x5d },
1080
{ AMINSS, yxm, Pf3, 0x5d },
1081
{ AMOVAPD, yxmov, Pe, 0x28,0x29 },
1082
{ AMOVAPS, yxmov, Pm, 0x28,0x29 },
1083
{ AMOVO, yxmov, Pe, 0x6f,0x7f },
1084
{ AMOVOU, yxmov, Pf3, 0x6f,0x7f },
1085
{ AMOVHLPS, yxr, Pm, 0x12 },
1086
{ AMOVHPD, yxmov, Pe, 0x16,0x17 },
1087
{ AMOVHPS, yxmov, Pm, 0x16,0x17 },
1088
{ AMOVLHPS, yxr, Pm, 0x16 },
1089
{ AMOVLPD, yxmov, Pe, 0x12,0x13 },
1090
{ AMOVLPS, yxmov, Pm, 0x12,0x13 },
1091
{ AMOVMSKPD, yxrrl, Pq, 0x50 },
1092
{ AMOVMSKPS, yxrrl, Pm, 0x50 },
1093
{ AMOVNTO, yxr_ml, Pe, 0xe7 },
1094
{ AMOVNTPD, yxr_ml, Pe, 0x2b },
1095
{ AMOVNTPS, yxr_ml, Pm, 0x2b },
1096
{ AMOVSD, yxmov, Pf2, 0x10,0x11 },
1097
{ AMOVSS, yxmov, Pf3, 0x10,0x11 },
1098
{ AMOVUPD, yxmov, Pe, 0x10,0x11 },
1099
{ AMOVUPS, yxmov, Pm, 0x10,0x11 },
1100
{ AMULPD, yxm, Pe, 0x59 },
1101
{ AMULPS, yxm, Ym, 0x59 },
1102
{ AMULSD, yxm, Pf2, 0x59 },
1103
{ AMULSS, yxm, Pf3, 0x59 },
1104
{ AORPD, yxm, Pq, 0x56 },
1105
{ AORPS, yxm, Pm, 0x56 },
1106
{ APADDQ, yxm, Pe, 0xd4 },
1107
{ APAND, yxm, Pe, 0xdb },
1108
{ APCMPEQB, yxmq, Pe ,0x74 },
1109
{ APMAXSW, yxm, Pe, 0xee },
1110
{ APMAXUB, yxm, Pe, 0xde },
1111
{ APMINSW, yxm, Pe, 0xea },
1112
{ APMINUB, yxm, Pe, 0xda },
1113
{ APMOVMSKB, ymskb, Px, Pe,0xd7,0xd7 },
1114
{ APSADBW, yxm, Pq, 0xf6 },
1115
{ APSUBB, yxm, Pe, 0xf8 },
1116
{ APSUBL, yxm, Pe, 0xfa },
1117
{ APSUBQ, yxm, Pe, 0xfb },
1118
{ APSUBSB, yxm, Pe, 0xe8 },
1119
{ APSUBSW, yxm, Pe, 0xe9 },
1120
{ APSUBUSB, yxm, Pe, 0xd8 },
1121
{ APSUBUSW, yxm, Pe, 0xd9 },
1122
{ APSUBW, yxm, Pe, 0xf9 },
1123
{ APUNPCKHQDQ, yxm, Pe, 0x6d },
1124
{ APUNPCKLQDQ, yxm, Pe, 0x6c },
1125
{ APXOR, yxm, Pe, 0xef },
1126
{ ARCPPS, yxm, Pm, 0x53 },
1127
{ ARCPSS, yxm, Pf3, 0x53 },
1128
{ ARSQRTPS, yxm, Pm, 0x52 },
1129
{ ARSQRTSS, yxm, Pf3, 0x52 },
1130
{ ASQRTPD, yxm, Pe, 0x51 },
1131
{ ASQRTPS, yxm, Pm, 0x51 },
1132
{ ASQRTSD, yxm, Pf2, 0x51 },
1133
{ ASQRTSS, yxm, Pf3, 0x51 },
1134
{ ASUBPD, yxm, Pe, 0x5c },
1135
{ ASUBPS, yxm, Pm, 0x5c },
1136
{ ASUBSD, yxm, Pf2, 0x5c },
1137
{ ASUBSS, yxm, Pf3, 0x5c },
1138
{ AUCOMISD, yxcmp, Pe, 0x2e },
1139
{ AUCOMISS, yxcmp, Pm, 0x2e },
1140
{ AUNPCKHPD, yxm, Pe, 0x15 },
1141
{ AUNPCKHPS, yxm, Pm, 0x15 },
1142
{ AUNPCKLPD, yxm, Pe, 0x14 },
1143
{ AUNPCKLPS, yxm, Pm, 0x14 },
1144
{ AXORPD, yxm, Pe, 0x57 },
1145
{ AXORPS, yxm, Pm, 0x57 },
1147
{ AAESENC, yaes, Pq, 0x38,0xdc,(0) },
1148
{ APINSRD, yinsrd, Pq, 0x3a, 0x22, (00) },
1149
{ APSHUFB, ymshufb,Pq, 0x38, 0x00 },
1151
{ AUSEFIELD, ynop, Px, 0,0 },
1153
{ AFUNCDATA, yfuncdata, Px, 0,0 },
1154
{ APCDATA, ypcdata, Px, 0,0 },
1158
{ ADUFFCOPY, yduff, Px, 0xe8 },
1159
{ ADUFFZERO, yduff, Px, 0xe8 },
1164
static int32 vaddr(Link*, Addr*, Reloc*);
1166
// single-instruction no-ops of various lengths.
1167
// constructed by hand and disassembled with gdb to verify.
1168
// see http://www.agner.org/optimize/optimizing_assembly.pdf for discussion.
1169
static uchar nop[][16] = {
1173
{0x0F, 0x1F, 0x40, 0x00},
1174
{0x0F, 0x1F, 0x44, 0x00, 0x00},
1175
{0x66, 0x0F, 0x1F, 0x44, 0x00, 0x00},
1176
{0x0F, 0x1F, 0x80, 0x00, 0x00, 0x00, 0x00},
1177
{0x0F, 0x1F, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00},
1178
{0x66, 0x0F, 0x1F, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00},
1179
// Native Client rejects the repeated 0x66 prefix.
1180
// {0x66, 0x66, 0x0F, 0x1F, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00},
1184
fillnop(uchar *p, int n)
1192
memmove(p, nop[m-1], m);
1199
naclpad(Link *ctxt, LSym *s, int32 c, int32 pad)
1201
symgrow(ctxt, s, c+pad);
1202
fillnop(s->p+c, pad);
1206
static void instinit(void);
1209
span8(Link *ctxt, LSym *s)
1218
if(s->text == nil || s->text->link == nil)
1224
for(p = s->text; p != nil; p = p->link) {
1226
if(p->to.type == D_BRANCH)
1229
if((q = p->pcond) != nil)
1233
if(p->as == AADJSP) {
1235
v = -p->from.offset;
1248
for(p = s->text; p != nil; p = p->link) {
1249
p->back = 2; // use short branches first time through
1250
if((q = p->pcond) != nil && (q->back & 2))
1251
p->back |= 1; // backward jump
1253
if(p->as == AADJSP) {
1255
v = -p->from.offset;
1271
memset(s->r, 0, s->nr*sizeof s->r[0]);
1275
for(p = s->text; p != nil; p = p->link) {
1276
if(ctxt->headtype == Hnacl && p->isize > 0) {
1277
static LSym *deferreturn;
1279
if(deferreturn == nil)
1280
deferreturn = linklookup(ctxt, "runtime.deferreturn", 0);
1282
// pad everything to avoid crossing 32-byte boundary
1283
if((c>>5) != ((c+p->isize-1)>>5))
1284
c = naclpad(ctxt, s, c, -c&31);
1285
// pad call deferreturn to start at 32-byte boundary
1286
// so that subtracting 5 in jmpdefer will jump back
1287
// to that boundary and rerun the call.
1288
if(p->as == ACALL && p->to.sym == deferreturn)
1289
c = naclpad(ctxt, s, c, -c&31);
1290
// pad call to end at 32-byte boundary
1292
c = naclpad(ctxt, s, c, -(c+p->isize)&31);
1294
// the linker treats REP and STOSQ as different instructions
1295
// but in fact the REP is a prefix on the STOSQ.
1296
// make sure REP has room for 2 more bytes, so that
1297
// padding will not be inserted before the next instruction.
1298
if(p->as == AREP && (c>>5) != ((c+3-1)>>5))
1299
c = naclpad(ctxt, s, c, -c&31);
1302
// various instructions follow; the longest is 4 bytes.
1303
// give ourselves 8 bytes so as to avoid surprises.
1304
if(p->as == ALOCK && (c>>5) != ((c+8-1)>>5))
1305
c = naclpad(ctxt, s, c, -c&31);
1310
// process forward jumps to p
1311
for(q = p->comefrom; q != nil; q = q->forwd) {
1312
v = p->pc - (q->pc + q->mark);
1313
if(q->back & 2) { // short
1323
bp = s->p + q->pc + q->mark - 4;
1334
m = ctxt->andptr-ctxt->and;
1339
symgrow(ctxt, s, p->pc+m);
1340
memmove(s->p+p->pc, ctxt->and, m);
1345
ctxt->diag("span must be looping");
1346
sysfatal("bad code");
1350
if(ctxt->headtype == Hnacl)
1351
c = naclpad(ctxt, s, c, -c&31);
1352
c += -c&(FuncAlign-1);
1355
if(0 /* debug['a'] > 1 */) {
1356
print("span1 %s %lld (%d tries)\n %.6ux", s->name, s->size, n, 0);
1357
for(i=0; i<s->np; i++) {
1358
print(" %.2ux", s->p[i]);
1360
print("\n %.6ux", i+1);
1365
for(i=0; i<s->nr; i++) {
1369
print(" rel %#.4ux/%d %s%+lld\n", r->off, r->siz, r->sym->name, r->add);
1379
for(i=1; optab[i].as; i++)
1380
if(i != optab[i].as)
1381
sysfatal("phase error in optab: at %A found %A", i, optab[i].as);
1383
for(i=0; i<Ymax; i++)
1384
ycover[i*Ymax + i] = 1;
1386
ycover[Yi0*Ymax + Yi8] = 1;
1387
ycover[Yi1*Ymax + Yi8] = 1;
1389
ycover[Yi0*Ymax + Yi32] = 1;
1390
ycover[Yi1*Ymax + Yi32] = 1;
1391
ycover[Yi8*Ymax + Yi32] = 1;
1393
ycover[Yal*Ymax + Yrb] = 1;
1394
ycover[Ycl*Ymax + Yrb] = 1;
1395
ycover[Yax*Ymax + Yrb] = 1;
1396
ycover[Ycx*Ymax + Yrb] = 1;
1397
ycover[Yrx*Ymax + Yrb] = 1;
1399
ycover[Yax*Ymax + Yrx] = 1;
1400
ycover[Ycx*Ymax + Yrx] = 1;
1402
ycover[Yax*Ymax + Yrl] = 1;
1403
ycover[Ycx*Ymax + Yrl] = 1;
1404
ycover[Yrx*Ymax + Yrl] = 1;
1406
ycover[Yf0*Ymax + Yrf] = 1;
1408
ycover[Yal*Ymax + Ymb] = 1;
1409
ycover[Ycl*Ymax + Ymb] = 1;
1410
ycover[Yax*Ymax + Ymb] = 1;
1411
ycover[Ycx*Ymax + Ymb] = 1;
1412
ycover[Yrx*Ymax + Ymb] = 1;
1413
ycover[Yrb*Ymax + Ymb] = 1;
1414
ycover[Ym*Ymax + Ymb] = 1;
1416
ycover[Yax*Ymax + Yml] = 1;
1417
ycover[Ycx*Ymax + Yml] = 1;
1418
ycover[Yrx*Ymax + Yml] = 1;
1419
ycover[Yrl*Ymax + Yml] = 1;
1420
ycover[Ym*Ymax + Yml] = 1;
1422
ycover[Yax*Ymax + Ymm] = 1;
1423
ycover[Ycx*Ymax + Ymm] = 1;
1424
ycover[Yrx*Ymax + Ymm] = 1;
1425
ycover[Yrl*Ymax + Ymm] = 1;
1426
ycover[Ym*Ymax + Ymm] = 1;
1427
ycover[Ymr*Ymax + Ymm] = 1;
1429
ycover[Ym*Ymax + Yxm] = 1;
1430
ycover[Yxr*Ymax + Yxm] = 1;
1432
for(i=0; i<D_NONE; i++) {
1434
if(i >= D_AL && i <= D_BH)
1435
reg[i] = (i-D_AL) & 7;
1436
if(i >= D_AX && i <= D_DI)
1437
reg[i] = (i-D_AX) & 7;
1438
if(i >= D_F0 && i <= D_F0+7)
1439
reg[i] = (i-D_F0) & 7;
1440
if(i >= D_X0 && i <= D_X0+7)
1441
reg[i] = (i-D_X0) & 7;
1446
prefixof(Link *ctxt, Addr *a)
1460
// NOTE: Systems listed here should be only systems that
1461
// support direct TLS references like 8(TLS) implemented as
1462
// direct references from FS or GS. Systems that require
1463
// the initial-exec model, where you load the TLS base into
1464
// a register and then index from that register, do not reach
1465
// this code and should not be listed.
1466
switch(ctxt->headtype) {
1468
sysfatal("unknown TLS base register for %s", headstr(ctxt->headtype));
1485
if((a->type >= D_INDIR && a->type < 2*D_INDIR) || a->index != D_NONE) {
1486
if(a->index != D_NONE && a->scale == 0) {
1487
if(a->type == D_ADDR) {
1498
//if(a->type == D_INDIR+D_ADDR)
1499
// print("*Ycol\n");
1559
case D_CS: return Ycs;
1560
case D_SS: return Yss;
1561
case D_DS: return Yds;
1562
case D_ES: return Yes;
1563
case D_FS: return Yfs;
1564
case D_GS: return Ygs;
1565
case D_TLS: return Ytls;
1567
case D_GDTR: return Ygdtr;
1568
case D_IDTR: return Yidtr;
1569
case D_LDTR: return Yldtr;
1570
case D_MSW: return Ymsw;
1571
case D_TASK: return Ytask;
1573
case D_CR+0: return Ycr0;
1574
case D_CR+1: return Ycr1;
1575
case D_CR+2: return Ycr2;
1576
case D_CR+3: return Ycr3;
1577
case D_CR+4: return Ycr4;
1578
case D_CR+5: return Ycr5;
1579
case D_CR+6: return Ycr6;
1580
case D_CR+7: return Ycr7;
1582
case D_DR+0: return Ydr0;
1583
case D_DR+1: return Ydr1;
1584
case D_DR+2: return Ydr2;
1585
case D_DR+3: return Ydr3;
1586
case D_DR+4: return Ydr4;
1587
case D_DR+5: return Ydr5;
1588
case D_DR+6: return Ydr6;
1589
case D_DR+7: return Ydr7;
1591
case D_TR+0: return Ytr0;
1592
case D_TR+1: return Ytr1;
1593
case D_TR+2: return Ytr2;
1594
case D_TR+3: return Ytr3;
1595
case D_TR+4: return Ytr4;
1596
case D_TR+5: return Ytr5;
1597
case D_TR+6: return Ytr6;
1598
case D_TR+7: return Ytr7;
1615
if(v >= -128 && v <= 127)
1627
asmidx(Link *ctxt, int scale, int index, int base)
1646
i = reg[index] << 3;
1668
case D_NONE: /* must be mod=00 */
1682
*ctxt->andptr++ = i;
1685
ctxt->diag("asmidx: bad address %d,%d,%d", scale, index, base);
1686
*ctxt->andptr++ = 0;
1691
put4(Link *ctxt, int32 v)
1693
ctxt->andptr[0] = v;
1694
ctxt->andptr[1] = v>>8;
1695
ctxt->andptr[2] = v>>16;
1696
ctxt->andptr[3] = v>>24;
1701
relput4(Link *ctxt, Prog *p, Addr *a)
1706
v = vaddr(ctxt, a, &rel);
1709
ctxt->diag("bad reloc");
1710
r = addrel(ctxt->cursym);
1712
r->off = p->pc + ctxt->andptr - ctxt->and;
1718
vaddr(Link *ctxt, Addr *a, Reloc *r)
1725
memset(r, 0, sizeof *r);
1737
ctxt->diag("need reloc for %D", a);
1738
sysfatal("bad code");
1751
ctxt->diag("need reloc for %D", a);
1752
sysfatal("bad code");
1756
r->off = -1; // caller must fill in
1765
asmand(Link *ctxt, Addr *a, int r)
1774
if(a->index != D_NONE && a->index != D_TLS) {
1775
if(t < D_INDIR || t >= 2*D_INDIR) {
1782
v = vaddr(ctxt, a, &rel);
1793
*ctxt->andptr++ = (0 << 6) | (4 << 0) | (r << 3);
1794
asmidx(ctxt, a->scale, a->index, t);
1797
if(v == 0 && rel.siz == 0 && t != D_BP) {
1798
*ctxt->andptr++ = (0 << 6) | (4 << 0) | (r << 3);
1799
asmidx(ctxt, a->scale, a->index, t);
1802
if(v >= -128 && v < 128 && rel.siz == 0) {
1803
*ctxt->andptr++ = (1 << 6) | (4 << 0) | (r << 3);
1804
asmidx(ctxt, a->scale, a->index, t);
1805
*ctxt->andptr++ = v;
1808
*ctxt->andptr++ = (2 << 6) | (4 << 0) | (r << 3);
1809
asmidx(ctxt, a->scale, a->index, t);
1812
if(t >= D_AL && t <= D_F7 || t >= D_X0 && t <= D_X7) {
1815
*ctxt->andptr++ = (3 << 6) | (reg[t] << 0) | (r << 3);
1820
if(t < D_INDIR || t >= 2*D_INDIR) {
1827
v = vaddr(ctxt, a, &rel);
1838
v = vaddr(ctxt, a, &rel);
1840
if(t == D_NONE || (D_CS <= t && t <= D_GS) || t == D_TLS) {
1841
*ctxt->andptr++ = (0 << 6) | (5 << 0) | (r << 3);
1845
if(v == 0 && rel.siz == 0) {
1846
*ctxt->andptr++ = (0 << 6) | (4 << 0) | (r << 3);
1847
asmidx(ctxt, scale, D_NONE, t);
1850
if(v >= -128 && v < 128 && rel.siz == 0) {
1851
*ctxt->andptr++ = (1 << 6) | (4 << 0) | (r << 3);
1852
asmidx(ctxt, scale, D_NONE, t);
1853
*ctxt->andptr++ = v;
1856
*ctxt->andptr++ = (2 << 6) | (4 << 0) | (r << 3);
1857
asmidx(ctxt, scale, D_NONE, t);
1860
if(t >= D_AX && t <= D_DI) {
1861
if(a->index == D_TLS) {
1862
memset(&rel, 0, sizeof rel);
1863
rel.type = R_TLS_IE;
1869
if(v == 0 && rel.siz == 0 && t != D_BP) {
1870
*ctxt->andptr++ = (0 << 6) | (reg[t] << 0) | (r << 3);
1873
if(v >= -128 && v < 128 && rel.siz == 0) {
1874
ctxt->andptr[0] = (1 << 6) | (reg[t] << 0) | (r << 3);
1875
ctxt->andptr[1] = v;
1879
*ctxt->andptr++ = (2 << 6) | (reg[t] << 0) | (r << 3);
1889
ctxt->diag("bad rel");
1892
r = addrel(ctxt->cursym);
1894
r->off = ctxt->curp->pc + ctxt->andptr - ctxt->and;
1901
ctxt->diag("asmand: bad address %D", a);
1906
static uchar ymovtab[] =
1909
APUSHL, Ycs, Ynone, 0, 0x0e,E,0,0,
1910
APUSHL, Yss, Ynone, 0, 0x16,E,0,0,
1911
APUSHL, Yds, Ynone, 0, 0x1e,E,0,0,
1912
APUSHL, Yes, Ynone, 0, 0x06,E,0,0,
1913
APUSHL, Yfs, Ynone, 0, 0x0f,0xa0,E,0,
1914
APUSHL, Ygs, Ynone, 0, 0x0f,0xa8,E,0,
1916
APUSHW, Ycs, Ynone, 0, Pe,0x0e,E,0,
1917
APUSHW, Yss, Ynone, 0, Pe,0x16,E,0,
1918
APUSHW, Yds, Ynone, 0, Pe,0x1e,E,0,
1919
APUSHW, Yes, Ynone, 0, Pe,0x06,E,0,
1920
APUSHW, Yfs, Ynone, 0, Pe,0x0f,0xa0,E,
1921
APUSHW, Ygs, Ynone, 0, Pe,0x0f,0xa8,E,
1924
APOPL, Ynone, Yds, 0, 0x1f,E,0,0,
1925
APOPL, Ynone, Yes, 0, 0x07,E,0,0,
1926
APOPL, Ynone, Yss, 0, 0x17,E,0,0,
1927
APOPL, Ynone, Yfs, 0, 0x0f,0xa1,E,0,
1928
APOPL, Ynone, Ygs, 0, 0x0f,0xa9,E,0,
1930
APOPW, Ynone, Yds, 0, Pe,0x1f,E,0,
1931
APOPW, Ynone, Yes, 0, Pe,0x07,E,0,
1932
APOPW, Ynone, Yss, 0, Pe,0x17,E,0,
1933
APOPW, Ynone, Yfs, 0, Pe,0x0f,0xa1,E,
1934
APOPW, Ynone, Ygs, 0, Pe,0x0f,0xa9,E,
1937
AMOVW, Yes, Yml, 1, 0x8c,0,0,0,
1938
AMOVW, Ycs, Yml, 1, 0x8c,1,0,0,
1939
AMOVW, Yss, Yml, 1, 0x8c,2,0,0,
1940
AMOVW, Yds, Yml, 1, 0x8c,3,0,0,
1941
AMOVW, Yfs, Yml, 1, 0x8c,4,0,0,
1942
AMOVW, Ygs, Yml, 1, 0x8c,5,0,0,
1944
AMOVW, Yml, Yes, 2, 0x8e,0,0,0,
1945
AMOVW, Yml, Ycs, 2, 0x8e,1,0,0,
1946
AMOVW, Yml, Yss, 2, 0x8e,2,0,0,
1947
AMOVW, Yml, Yds, 2, 0x8e,3,0,0,
1948
AMOVW, Yml, Yfs, 2, 0x8e,4,0,0,
1949
AMOVW, Yml, Ygs, 2, 0x8e,5,0,0,
1952
AMOVL, Ycr0, Yml, 3, 0x0f,0x20,0,0,
1953
AMOVL, Ycr2, Yml, 3, 0x0f,0x20,2,0,
1954
AMOVL, Ycr3, Yml, 3, 0x0f,0x20,3,0,
1955
AMOVL, Ycr4, Yml, 3, 0x0f,0x20,4,0,
1957
AMOVL, Yml, Ycr0, 4, 0x0f,0x22,0,0,
1958
AMOVL, Yml, Ycr2, 4, 0x0f,0x22,2,0,
1959
AMOVL, Yml, Ycr3, 4, 0x0f,0x22,3,0,
1960
AMOVL, Yml, Ycr4, 4, 0x0f,0x22,4,0,
1963
AMOVL, Ydr0, Yml, 3, 0x0f,0x21,0,0,
1964
AMOVL, Ydr6, Yml, 3, 0x0f,0x21,6,0,
1965
AMOVL, Ydr7, Yml, 3, 0x0f,0x21,7,0,
1967
AMOVL, Yml, Ydr0, 4, 0x0f,0x23,0,0,
1968
AMOVL, Yml, Ydr6, 4, 0x0f,0x23,6,0,
1969
AMOVL, Yml, Ydr7, 4, 0x0f,0x23,7,0,
1972
AMOVL, Ytr6, Yml, 3, 0x0f,0x24,6,0,
1973
AMOVL, Ytr7, Yml, 3, 0x0f,0x24,7,0,
1975
AMOVL, Yml, Ytr6, 4, 0x0f,0x26,6,E,
1976
AMOVL, Yml, Ytr7, 4, 0x0f,0x26,7,E,
1978
/* lgdt, sgdt, lidt, sidt */
1979
AMOVL, Ym, Ygdtr, 4, 0x0f,0x01,2,0,
1980
AMOVL, Ygdtr, Ym, 3, 0x0f,0x01,0,0,
1981
AMOVL, Ym, Yidtr, 4, 0x0f,0x01,3,0,
1982
AMOVL, Yidtr, Ym, 3, 0x0f,0x01,1,0,
1985
AMOVW, Yml, Yldtr, 4, 0x0f,0x00,2,0,
1986
AMOVW, Yldtr, Yml, 3, 0x0f,0x00,0,0,
1989
AMOVW, Yml, Ymsw, 4, 0x0f,0x01,6,0,
1990
AMOVW, Ymsw, Yml, 3, 0x0f,0x01,4,0,
1993
AMOVW, Yml, Ytask, 4, 0x0f,0x00,3,0,
1994
AMOVW, Ytask, Yml, 3, 0x0f,0x00,1,0,
1996
/* load full pointer */
1997
AMOVL, Yml, Ycol, 5, 0,0,0,0,
1998
AMOVW, Yml, Ycol, 5, Pe,0,0,0,
2001
ASHLL, Ycol, Yml, 6, 0xa4,0xa5,0,0,
2002
ASHRL, Ycol, Yml, 6, 0xac,0xad,0,0,
2005
AIMULW, Yml, Yrl, 7, Pq,0xaf,0,0,
2006
AIMULL, Yml, Yrl, 7, Pm,0xaf,0,0,
2008
/* load TLS base pointer */
2009
AMOVL, Ytls, Yrl, 8, 0,0,0,0,
2014
// byteswapreg returns a byte-addressable register (AX, BX, CX, DX)
2015
// which is not referenced in a->type.
2016
// If a is empty, it returns BX to account for MULB-like instructions
2017
// that might use DX and AX.
2019
byteswapreg(Link *ctxt, Addr *a)
2021
int cana, canb, canc, cand;
2023
cana = canb = canc = cand = 1;
2077
ctxt->diag("impossible byte register");
2078
sysfatal("bad code");
2083
subreg(Prog *p, int from, int to)
2086
if(0 /* debug['Q'] */)
2087
print("\n%P s/%R/%R/\n", p, from, to);
2089
if(p->from.type == from) {
2093
if(p->to.type == from) {
2098
if(p->from.index == from) {
2102
if(p->to.index == from) {
2108
if(p->from.type == from) {
2109
p->from.type = to+D_INDIR;
2112
if(p->to.type == from) {
2113
p->to.type = to+D_INDIR;
2117
if(0 /* debug['Q'] */)
2122
mediaop(Link *ctxt, Optab *o, int op, int osize, int z)
2131
*ctxt->andptr++ = op;
2132
*ctxt->andptr++ = Pm;
2137
if(ctxt->andptr == ctxt->and || ctxt->andptr[-1] != Pm)
2138
*ctxt->andptr++ = Pm;
2141
*ctxt->andptr++ = op;
2146
doasm(Link *ctxt, Prog *p)
2151
int z, op, ft, tt, breg;
2156
ctxt->curp = p; // TODO
2158
pre = prefixof(ctxt, &p->from);
2160
*ctxt->andptr++ = pre;
2161
pre = prefixof(ctxt, &p->to);
2163
*ctxt->andptr++ = pre;
2166
p->ft = oclass(&p->from);
2168
p->tt = oclass(&p->to);
2175
ctxt->diag("asmins: noproto %P", p);
2178
for(z=0; *t; z+=t[3],t+=4)
2186
case Pq: /* 16 bit escape and opcode escape */
2187
*ctxt->andptr++ = Pe;
2188
*ctxt->andptr++ = Pm;
2191
case Pf2: /* xmm opcode escape */
2193
*ctxt->andptr++ = o->prefix;
2194
*ctxt->andptr++ = Pm;
2197
case Pm: /* opcode escape */
2198
*ctxt->andptr++ = Pm;
2201
case Pe: /* 16 bit escape */
2202
*ctxt->andptr++ = Pe;
2205
case Pb: /* botch */
2212
ctxt->diag("asmins: unknown z %d %P", t[2], p);
2219
for(; op = o->op[z]; z++)
2220
*ctxt->andptr++ = op;
2224
for(; op = o->op[z]; z++)
2225
*ctxt->andptr++ = op;
2226
asmand(ctxt, &p->from, reg[p->to.type]);
2230
*ctxt->andptr++ = op;
2231
asmand(ctxt, &p->from, reg[p->to.type]);
2235
*ctxt->andptr++ = op;
2236
*ctxt->andptr++ = o->op[z+1];
2237
asmand(ctxt, &p->from, reg[p->to.type]);
2241
mediaop(ctxt, o, op, t[3], z);
2242
asmand(ctxt, &p->from, reg[p->to.type]);
2246
mediaop(ctxt, o, op, t[3], z);
2247
asmand(ctxt, &p->from, reg[p->to.type]);
2248
*ctxt->andptr++ = p->to.offset;
2252
while ((op = o->op[z++]) != 0)
2253
*ctxt->andptr++ = op;
2254
asmand(ctxt, &p->from, reg[p->to.type]);
2255
*ctxt->andptr++ = p->to.offset;
2259
*ctxt->andptr++ = 0x8d; /* leal */
2260
if(p->from.type != D_ADDR)
2261
ctxt->diag("asmins: Zaut sb type ADDR");
2262
p->from.type = p->from.index;
2263
p->from.index = D_NONE;
2265
asmand(ctxt, &p->from, reg[p->to.type]);
2266
p->from.index = p->from.type;
2267
p->from.type = D_ADDR;
2272
*ctxt->andptr++ = op;
2273
asmand(ctxt, &p->from, o->op[z+1]);
2277
*ctxt->andptr++ = op;
2278
asmand(ctxt, &p->to, reg[p->from.type]);
2282
mediaop(ctxt, o, op, t[3], z);
2283
asmand(ctxt, &p->to, reg[p->from.type]);
2287
mediaop(ctxt, o, op, t[3], z);
2288
asmand(ctxt, &p->to, reg[p->from.type]);
2289
*ctxt->andptr++ = p->from.offset;
2294
*ctxt->andptr++ = op;
2295
asmand(ctxt, &p->to, o->op[z+1]);
2299
*ctxt->andptr++ = op;
2300
asmand(ctxt, &p->from, o->op[z+1]);
2301
*ctxt->andptr++ = vaddr(ctxt, &p->to, nil);
2305
*ctxt->andptr++ = op;
2306
asmand(ctxt, &p->to, o->op[z+1]);
2307
*ctxt->andptr++ = vaddr(ctxt, &p->from, nil);
2316
v = vaddr(ctxt, a, nil);
2317
*ctxt->andptr++ = op;
2318
*ctxt->andptr++ = v;
2322
*ctxt->andptr++ = op + reg[p->to.type];
2323
*ctxt->andptr++ = vaddr(ctxt, &p->from, nil);
2327
*ctxt->andptr++ = op + reg[p->to.type];
2328
if(o->prefix == Pe) {
2329
v = vaddr(ctxt, &p->from, nil);
2330
*ctxt->andptr++ = v;
2331
*ctxt->andptr++ = v>>8;
2334
relput4(ctxt, p, &p->from);
2338
*ctxt->andptr++ = op;
2339
asmand(ctxt, &p->to, reg[p->to.type]);
2340
*ctxt->andptr++ = vaddr(ctxt, &p->from, nil);
2349
*ctxt->andptr++ = op;
2350
if(o->prefix == Pe) {
2351
v = vaddr(ctxt, a, nil);
2352
*ctxt->andptr++ = v;
2353
*ctxt->andptr++ = v>>8;
2356
relput4(ctxt, p, a);
2361
*ctxt->andptr++ = op;
2362
if(t[2] == Zilo_m) {
2364
asmand(ctxt, &p->to, o->op[z+1]);
2367
asmand(ctxt, &p->from, o->op[z+1]);
2369
if(o->prefix == Pe) {
2370
v = vaddr(ctxt, a, nil);
2371
*ctxt->andptr++ = v;
2372
*ctxt->andptr++ = v>>8;
2375
relput4(ctxt, p, a);
2379
*ctxt->andptr++ = op;
2380
asmand(ctxt, &p->to, reg[p->to.type]);
2381
if(o->prefix == Pe) {
2382
v = vaddr(ctxt, &p->from, nil);
2383
*ctxt->andptr++ = v;
2384
*ctxt->andptr++ = v>>8;
2387
relput4(ctxt, p, &p->from);
2391
*ctxt->andptr++ = op + reg[p->to.type];
2395
*ctxt->andptr++ = op + reg[p->from.type];
2399
*ctxt->andptr++ = op;
2400
asmand(ctxt, &p->to, reg[p->to.type]);
2404
if(p->to.sym == nil) {
2405
ctxt->diag("call without target");
2406
sysfatal("bad code");
2408
*ctxt->andptr++ = op;
2409
r = addrel(ctxt->cursym);
2410
r->off = p->pc + ctxt->andptr - ctxt->and;
2414
r->add = p->to.offset;
2421
if(p->to.sym != nil) {
2423
ctxt->diag("branch to ATEXT");
2424
sysfatal("bad code");
2426
*ctxt->andptr++ = o->op[z+1];
2427
r = addrel(ctxt->cursym);
2428
r->off = p->pc + ctxt->andptr - ctxt->and;
2436
// Assumes q is in this function.
2437
// Fill in backward jump now.
2440
ctxt->diag("jmp/branch/loop without target");
2441
sysfatal("bad code");
2444
v = q->pc - (p->pc + 2);
2447
*ctxt->andptr++ = 0x67;
2448
*ctxt->andptr++ = op;
2449
*ctxt->andptr++ = v;
2450
} else if(t[2] == Zloop) {
2451
ctxt->diag("loop too far: %P", p);
2455
*ctxt->andptr++ = 0x0f;
2458
*ctxt->andptr++ = o->op[z+1];
2459
*ctxt->andptr++ = v;
2460
*ctxt->andptr++ = v>>8;
2461
*ctxt->andptr++ = v>>16;
2462
*ctxt->andptr++ = v>>24;
2467
// Annotate target; will fill in later.
2468
p->forwd = q->comefrom;
2470
if(p->back & 2) { // short
2472
*ctxt->andptr++ = 0x67;
2473
*ctxt->andptr++ = op;
2474
*ctxt->andptr++ = 0;
2475
} else if(t[2] == Zloop) {
2476
ctxt->diag("loop too far: %P", p);
2479
*ctxt->andptr++ = 0x0f;
2480
*ctxt->andptr++ = o->op[z+1];
2481
*ctxt->andptr++ = 0;
2482
*ctxt->andptr++ = 0;
2483
*ctxt->andptr++ = 0;
2484
*ctxt->andptr++ = 0;
2490
if(t[2] == Zcallcon)
2491
*ctxt->andptr++ = op;
2493
*ctxt->andptr++ = o->op[z+1];
2494
r = addrel(ctxt->cursym);
2495
r->off = p->pc + ctxt->andptr - ctxt->and;
2498
r->add = p->to.offset;
2503
*ctxt->andptr++ = op;
2504
*ctxt->andptr++ = o->op[z+1];
2505
r = addrel(ctxt->cursym);
2506
r->off = p->pc + ctxt->andptr - ctxt->and;
2509
r->add = p->to.offset;
2515
r = addrel(ctxt->cursym);
2517
r->type = R_CALLIND;
2522
v = vaddr(ctxt, &p->from, &rel);
2525
r = addrel(ctxt->cursym);
2527
r->off = p->pc + ctxt->andptr - ctxt->and;
2529
*ctxt->andptr++ = v;
2531
*ctxt->andptr++ = v>>8;
2533
*ctxt->andptr++ = v>>16;
2534
*ctxt->andptr++ = v>>24;
2545
for(t=ymovtab; *t; t+=8)
2552
* here, the assembly has failed.
2553
* if its a byte instruction that has
2554
* unaddressable registers, try to
2555
* exchange registers and reissue the
2556
* instruction with the operands renamed.
2560
if(z >= D_BP && z <= D_DI) {
2561
if((breg = byteswapreg(ctxt, &p->to)) != D_AX) {
2562
*ctxt->andptr++ = 0x87; /* xchg lhs,bx */
2563
asmand(ctxt, &p->from, reg[breg]);
2564
subreg(&pp, z, breg);
2566
*ctxt->andptr++ = 0x87; /* xchg lhs,bx */
2567
asmand(ctxt, &p->from, reg[breg]);
2569
*ctxt->andptr++ = 0x90 + reg[z]; /* xchg lsh,ax */
2570
subreg(&pp, z, D_AX);
2572
*ctxt->andptr++ = 0x90 + reg[z]; /* xchg lsh,ax */
2577
if(z >= D_BP && z <= D_DI) {
2578
if((breg = byteswapreg(ctxt, &p->from)) != D_AX) {
2579
*ctxt->andptr++ = 0x87; /* xchg rhs,bx */
2580
asmand(ctxt, &p->to, reg[breg]);
2581
subreg(&pp, z, breg);
2583
*ctxt->andptr++ = 0x87; /* xchg rhs,bx */
2584
asmand(ctxt, &p->to, reg[breg]);
2586
*ctxt->andptr++ = 0x90 + reg[z]; /* xchg rsh,ax */
2587
subreg(&pp, z, D_AX);
2589
*ctxt->andptr++ = 0x90 + reg[z]; /* xchg rsh,ax */
2593
ctxt->diag("doasm: notfound t2=%ux from=%ux to=%ux %P", t[2], p->from.type, p->to.type, p);
2599
ctxt->diag("asmins: unknown mov %d %P", t[3], p);
2603
for(z=4; t[z]!=E; z++)
2604
*ctxt->andptr++ = t[z];
2608
*ctxt->andptr++ = t[4];
2609
asmand(ctxt, &p->to, t[5]);
2613
*ctxt->andptr++ = t[4];
2614
asmand(ctxt, &p->from, t[5]);
2617
case 3: /* r,m - 2op */
2618
*ctxt->andptr++ = t[4];
2619
*ctxt->andptr++ = t[5];
2620
asmand(ctxt, &p->to, t[6]);
2623
case 4: /* m,r - 2op */
2624
*ctxt->andptr++ = t[4];
2625
*ctxt->andptr++ = t[5];
2626
asmand(ctxt, &p->from, t[6]);
2629
case 5: /* load full pointer, trash heap */
2631
*ctxt->andptr++ = t[4];
2632
switch(p->to.index) {
2636
*ctxt->andptr++ = 0xc5;
2639
*ctxt->andptr++ = 0x0f;
2640
*ctxt->andptr++ = 0xb2;
2643
*ctxt->andptr++ = 0xc4;
2646
*ctxt->andptr++ = 0x0f;
2647
*ctxt->andptr++ = 0xb4;
2650
*ctxt->andptr++ = 0x0f;
2651
*ctxt->andptr++ = 0xb5;
2654
asmand(ctxt, &p->from, reg[p->to.type]);
2657
case 6: /* double shift */
2663
*ctxt->andptr++ = 0x0f;
2664
*ctxt->andptr++ = t[4];
2665
asmand(ctxt, &p->to, reg[p->from.index]);
2666
*ctxt->andptr++ = p->from.offset;
2670
*ctxt->andptr++ = 0x0f;
2671
*ctxt->andptr++ = t[5];
2672
asmand(ctxt, &p->to, reg[p->from.index]);
2677
case 7: /* imul rm,r */
2679
*ctxt->andptr++ = Pe;
2680
*ctxt->andptr++ = Pm;
2682
*ctxt->andptr++ = t[4];
2683
*ctxt->andptr++ = t[5];
2684
asmand(ctxt, &p->from, reg[p->to.type]);
2687
case 8: /* mov tls, r */
2688
// NOTE: The systems listed here are the ones that use the "TLS initial exec" model,
2689
// where you load the TLS base register into a register and then index off that
2690
// register to access the actual TLS variables. Systems that allow direct TLS access
2691
// are handled in prefixof above and should not be listed here.
2692
switch(ctxt->headtype) {
2694
sysfatal("unknown TLS base location for %s", headstr(ctxt->headtype));
2698
// ELF TLS base is 0(GS).
2700
pp.from.type = D_INDIR+D_GS;
2702
pp.from.index = D_NONE;
2704
*ctxt->andptr++ = 0x65; // GS
2705
*ctxt->andptr++ = 0x8B;
2706
asmand(ctxt, &pp.from, reg[p->to.type]);
2710
if(ctxt->plan9tos == nil)
2711
ctxt->plan9tos = linklookup(ctxt, "_tos", 0);
2712
memset(&pp.from, 0, sizeof pp.from);
2713
pp.from.type = D_EXTERN;
2714
pp.from.sym = ctxt->plan9tos;
2716
pp.from.index = D_NONE;
2717
*ctxt->andptr++ = 0x8B;
2718
asmand(ctxt, &pp.from, reg[p->to.type]);
2722
// Windows TLS base is always 0x14(FS).
2724
pp.from.type = D_INDIR+D_FS;
2725
pp.from.offset = 0x14;
2726
pp.from.index = D_NONE;
2728
*ctxt->andptr++ = 0x64; // FS
2729
*ctxt->andptr++ = 0x8B;
2730
asmand(ctxt, &pp.from, reg[p->to.type]);
2737
static uchar naclret[] = {
2739
// 0x8b, 0x7d, 0x00, // MOVL (BP), DI - catch return to invalid address, for debugging
2740
0x83, 0xe5, 0xe0, // ANDL $~31, BP
2741
0xff, 0xe5, // JMP BP
2745
asmins(Link *ctxt, Prog *p)
2749
ctxt->andptr = ctxt->and;
2751
if(p->as == AUSEFIELD) {
2752
r = addrel(ctxt->cursym);
2754
r->sym = p->from.sym;
2755
r->type = R_USEFIELD;
2760
if(ctxt->headtype == Hnacl) {
2763
memmove(ctxt->andptr, naclret, sizeof naclret);
2764
ctxt->andptr += sizeof naclret;
2768
if(D_AX <= p->to.type && p->to.type <= D_DI) {
2769
*ctxt->andptr++ = 0x83;
2770
*ctxt->andptr++ = 0xe0 | (p->to.type - D_AX);
2771
*ctxt->andptr++ = 0xe0;
2775
*ctxt->andptr++ = 0xf4;
2781
if(ctxt->andptr > ctxt->and+sizeof ctxt->and) {
2782
print("and[] is too short - %ld byte instruction\n", ctxt->andptr - ctxt->and);
2783
sysfatal("bad code");