Skip to content

Commit 9dd81d6

Browse files
TocarIPbradfitz
authored andcommitted
cmd/internal/obj/x86: Add initial VEX support.
Support VZEROUPPER, VMOVNTDQ, VMOVDQU, VMOVDQA. Use MOVHD* for names, where HD stands for HexaDeca (16). Change-Id: I9b1ea52e7ef0714a3d2aeb31ec1823fe509a047e Reviewed-on: https://go-review.googlesource.com/14127 Run-TryBot: Brad Fitzpatrick <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Brad Fitzpatrick <[email protected]>
1 parent 27ee719 commit 9dd81d6

File tree

4 files changed

+102
-16
lines changed

4 files changed

+102
-16
lines changed

src/cmd/internal/obj/link.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -512,6 +512,7 @@ type Link struct {
512512
Blitrl *Prog
513513
Elitrl *Prog
514514
Rexflag int
515+
Vexflag int
515516
Rep int
516517
Repn int
517518
Lock int

src/cmd/internal/obj/x86/a.out.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -742,6 +742,11 @@ const (
742742
APSHUFD
743743
APCLMULQDQ
744744

745+
AVZEROUPPER
746+
AMOVHDU
747+
AMOVNTHD
748+
AMOVHDA
749+
745750
// from 386
746751
AJCXZW
747752
AFCMOVCC

src/cmd/internal/obj/x86/anames.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -683,6 +683,10 @@ var Anames = []string{
683683
"ROUNDSD",
684684
"PSHUFD",
685685
"PCLMULQDQ",
686+
"VZEROUPPER",
687+
"MOVHDU",
688+
"MOVNTHD",
689+
"MOVHDA",
686690
"JCXZW",
687691
"FCMOVCC",
688692
"FCMOVCS",

src/cmd/internal/obj/x86/asm6.go

Lines changed: 92 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@ const (
181181
Zm_r
182182
Zm2_r
183183
Zm_r_xm
184+
Zm_r_xm_vex
184185
Zm_r_i_xm
185186
Zm_r_3d
186187
Zm_r_xm_nr
@@ -193,6 +194,7 @@ const (
193194
Zpseudo
194195
Zr_m
195196
Zr_m_xm
197+
Zr_m_xm_vex
196198
Zrp_
197199
Z_ib
198200
Z_il
@@ -206,21 +208,23 @@ const (
206208
)
207209

208210
const (
209-
Px = 0
210-
Px1 = 1 // symbolic; exact value doesn't matter
211-
P32 = 0x32 /* 32-bit only */
212-
Pe = 0x66 /* operand escape */
213-
Pm = 0x0f /* 2byte opcode escape */
214-
Pq = 0xff /* both escapes: 66 0f */
215-
Pb = 0xfe /* byte operands */
216-
Pf2 = 0xf2 /* xmm escape 1: f2 0f */
217-
Pf3 = 0xf3 /* xmm escape 2: f3 0f */
218-
Pq3 = 0x67 /* xmm escape 3: 66 48 0f */
219-
Pw = 0x48 /* Rex.w */
220-
Pw8 = 0x90 // symbolic; exact value doesn't matter
221-
Py = 0x80 /* defaults to 64-bit mode */
222-
Py1 = 0x81 // symbolic; exact value doesn't matter
223-
Py3 = 0x83 // symbolic; exact value doesn't matter
211+
Px = 0
212+
Px1 = 1 // symbolic; exact value doesn't matter
213+
P32 = 0x32 /* 32-bit only */
214+
Pe = 0x66 /* operand escape */
215+
Pm = 0x0f /* 2byte opcode escape */
216+
Pq = 0xff /* both escapes: 66 0f */
217+
Pb = 0xfe /* byte operands */
218+
Pf2 = 0xf2 /* xmm escape 1: f2 0f */
219+
Pf3 = 0xf3 /* xmm escape 2: f3 0f */
220+
Pq3 = 0x67 /* xmm escape 3: 66 48 0f */
221+
Pvex1 = 0xc5 /* 66 escape, vex encoding */
222+
Pvex2 = 0xc6 /* f3 escape, vex encoding */
223+
Pw = 0x48 /* Rex.w */
224+
Pw8 = 0x90 // symbolic; exact value doesn't matter
225+
Py = 0x80 /* defaults to 64-bit mode */
226+
Py1 = 0x81 // symbolic; exact value doesn't matter
227+
Py3 = 0x83 // symbolic; exact value doesn't matter
224228

225229
Rxw = 1 << 3 /* =1, 64-bit operand size */
226230
Rxr = 1 << 2 /* extend modrm reg */
@@ -622,6 +626,10 @@ var yxr_ml = []ytab{
622626
{Yxr, Ynone, Yml, Zr_m_xm, 1},
623627
}
624628

629+
var yxr_ml_vex = []ytab{
630+
{Yxr, Ynone, Yml, Zr_m_xm_vex, 1},
631+
}
632+
625633
var ymr = []ytab{
626634
{Ymr, Ynone, Ymr, Zm_r, 1},
627635
}
@@ -638,6 +646,11 @@ var yxcmpi = []ytab{
638646
{Yxm, Yxr, Yi8, Zm_r_i_xm, 2},
639647
}
640648

649+
var yxmov_vex = []ytab{
650+
{Yxm, Ynone, Yxr, Zm_r_xm_vex, 1},
651+
{Yxr, Ynone, Yxm, Zr_m_xm_vex, 1},
652+
}
653+
641654
var yxmov = []ytab{
642655
{Yxm, Ynone, Yxr, Zm_r_xm, 1},
643656
{Yxr, Ynone, Yxm, Zr_m_xm, 1},
@@ -1480,6 +1493,10 @@ var optab =
14801493
{AROUNDSS, yaes2, Pq, [23]uint8{0x3a, 0x0a, 0}},
14811494
{APSHUFD, yxshuf, Pq, [23]uint8{0x70, 0}},
14821495
{APCLMULQDQ, yxshuf, Pq, [23]uint8{0x3a, 0x44, 0}},
1496+
{AVZEROUPPER, ynone, Px, [23]uint8{0xc5, 0xf8, 0x77}},
1497+
{AMOVHDU, yxmov_vex, Pvex2, [23]uint8{0x6f, 0x7f}},
1498+
{AMOVNTHD, yxr_ml_vex, Pvex1, [23]uint8{0xe7}},
1499+
{AMOVHDA, yxmov_vex, Pvex1, [23]uint8{0x6f, 0x7f}},
14831500
{obj.AUSEFIELD, ynop, Px, [23]uint8{0, 0}},
14841501
{obj.ATYPE, nil, 0, [23]uint8{}},
14851502
{obj.AFUNCDATA, yfuncdata, Px, [23]uint8{0, 0}},
@@ -2911,6 +2928,50 @@ var bpduff2 = []byte{
29112928
0x48, 0x8b, 0x6d, 0x00, // MOVQ 0(BP), BP
29122929
}
29132930

2931+
func vexprefix(ctxt *obj.Link, to *obj.Addr, from *obj.Addr, pref uint8) {
2932+
rexR := regrex[to.Reg]
2933+
rexB := regrex[from.Reg]
2934+
rexX := regrex[from.Index]
2935+
var prefBit uint8
2936+
if pref == Pvex1 {
2937+
prefBit = 1
2938+
} else if pref == Pvex2 {
2939+
prefBit = 2
2940+
} // TODO add Pvex0,Pvex3
2941+
2942+
if rexX == 0 && rexB == 0 { // 2-byte vex prefix
2943+
ctxt.Andptr[0] = 0xc5
2944+
ctxt.Andptr = ctxt.Andptr[1:]
2945+
2946+
if rexR != 0 {
2947+
ctxt.Andptr[0] = 0x7c
2948+
} else {
2949+
ctxt.Andptr[0] = 0xfc
2950+
}
2951+
ctxt.Andptr[0] |= prefBit
2952+
ctxt.Andptr = ctxt.Andptr[1:]
2953+
} else {
2954+
ctxt.Andptr[0] = 0xc4
2955+
ctxt.Andptr = ctxt.Andptr[1:]
2956+
2957+
ctxt.Andptr[0] = 0x1 // TODO handle different prefix
2958+
if rexR == 0 {
2959+
ctxt.Andptr[0] |= 0x80
2960+
}
2961+
if rexX == 0 {
2962+
ctxt.Andptr[0] |= 0x40
2963+
}
2964+
if rexB == 0 {
2965+
ctxt.Andptr[0] |= 0x20
2966+
}
2967+
ctxt.Andptr = ctxt.Andptr[1:]
2968+
2969+
ctxt.Andptr[0] = 0x7c
2970+
ctxt.Andptr[0] |= prefBit
2971+
ctxt.Andptr = ctxt.Andptr[1:]
2972+
}
2973+
}
2974+
29142975
func doasm(ctxt *obj.Link, p *obj.Prog) {
29152976
ctxt.Curp = p // TODO
29162977

@@ -3144,6 +3205,13 @@ func doasm(ctxt *obj.Link, p *obj.Prog) {
31443205
mediaop(ctxt, o, op, int(yt.zoffset), z)
31453206
asmand(ctxt, p, &p.From, &p.To)
31463207

3208+
case Zm_r_xm_vex:
3209+
ctxt.Vexflag = 1
3210+
vexprefix(ctxt, &p.To, &p.From, o.prefix)
3211+
ctxt.Andptr[0] = byte(op)
3212+
ctxt.Andptr = ctxt.Andptr[1:]
3213+
asmand(ctxt, p, &p.From, &p.To)
3214+
31473215
case Zm_r_xm_nr:
31483216
ctxt.Rexflag = 0
31493217
mediaop(ctxt, o, op, int(yt.zoffset), z)
@@ -3199,6 +3267,13 @@ func doasm(ctxt *obj.Link, p *obj.Prog) {
31993267
ctxt.Andptr = ctxt.Andptr[1:]
32003268
asmand(ctxt, p, &p.To, &p.From)
32013269

3270+
case Zr_m_xm_vex:
3271+
ctxt.Vexflag = 1
3272+
vexprefix(ctxt, &p.From, &p.To, o.prefix)
3273+
ctxt.Andptr[0] = byte(op)
3274+
ctxt.Andptr = ctxt.Andptr[1:]
3275+
asmand(ctxt, p, &p.To, &p.From)
3276+
32023277
case Zr_m_xm:
32033278
mediaop(ctxt, o, op, int(yt.zoffset), z)
32043279
asmand(ctxt, p, &p.To, &p.From)
@@ -4307,10 +4382,11 @@ func asmins(ctxt *obj.Link, p *obj.Prog) {
43074382
}
43084383

43094384
ctxt.Rexflag = 0
4385+
ctxt.Vexflag = 0
43104386
and0 := ctxt.Andptr
43114387
ctxt.Asmode = int(p.Mode)
43124388
doasm(ctxt, p)
4313-
if ctxt.Rexflag != 0 {
4389+
if ctxt.Rexflag != 0 && ctxt.Vexflag == 0 {
43144390
/*
43154391
* as befits the whole approach of the architecture,
43164392
* the rex prefix must appear before the first opcode byte

0 commit comments

Comments
 (0)