// Reports errors via ctxt.
func avx2gatherValid(ctxt *obj.Link, p *obj.Prog) bool {
// If any pair of the index, mask, or destination registers
- // are the same, this instruction results a #UD fault.
+ // are the same, illegal instruction trap (#UD) is triggered.
index := regIndex(p.GetFrom3().Index)
mask := regIndex(p.From.Reg)
dest := regIndex(p.To.Reg)
ab.Put1(byte(pre))
}
- // TODO(rsc): This special case is for SHRQ $3, AX:DX,
- // which encodes as SHRQ $32(DX*0), AX.
- // Similarly SHRQ CX, AX:DX is really SHRQ CX(DX*0), AX.
- // Change encoding generated by assemblers and compilers and remove.
- if (p.From.Type == obj.TYPE_CONST || p.From.Type == obj.TYPE_REG) && p.From.Index != REG_NONE && p.From.Scale == 0 {
- p.SetFrom3(obj.Addr{
- Type: obj.TYPE_REG,
- Reg: p.From.Index,
- })
- p.From.Index = 0
- }
-
- // TODO(rsc): This special case is for PINSRQ etc, CMPSD etc.
- // Change encoding generated by assemblers and compilers (if any) and remove.
+ // Сhecks to warn about instruction/arguments combinations that
+ // will unconditionally trigger illegal instruction trap (#UD).
switch p.As {
- case AIMUL3Q, APEXTRW, APINSRW, APINSRD, APINSRQ, APSHUFHW, APSHUFL, APSHUFW, ASHUFPD, ASHUFPS, AAESKEYGENASSIST, APSHUFD, APCLMULQDQ:
- if p.From3Type() == obj.TYPE_NONE {
- p.SetFrom3(p.From)
- p.From = obj.Addr{}
- p.From.Type = obj.TYPE_CONST
- p.From.Offset = p.To.Offset
- p.To.Offset = 0
- }
- case ACMPSD, ACMPSS, ACMPPS, ACMPPD:
- if p.From3Type() == obj.TYPE_NONE {
- p.SetFrom3(p.To)
- p.To = obj.Addr{}
- p.To.Type = obj.TYPE_CONST
- p.To.Offset = p.GetFrom3().Offset
- p.GetFrom3().Offset = 0
- }
-
case AVGATHERDPD,
AVGATHERQPD,
AVGATHERDPS,