From 818eff0367528dea7b0d05d601d6dbf7fc41c699 Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Wed, 4 Mar 2015 22:56:49 -0500 Subject: [PATCH] cmd/internal/obj/i386: delete Now unused. Change-Id: I0ba27e58721ad66cc3068346d6d31ba0ac37ad64 Reviewed-on: https://go-review.googlesource.com/6893 Reviewed-by: Rob Pike Reviewed-by: Minux Ma --- src/cmd/internal/obj/i386/8.out.go | 594 ----- src/cmd/internal/obj/i386/anames8.go | 507 ---- src/cmd/internal/obj/i386/asm8.go | 3462 -------------------------- src/cmd/internal/obj/i386/list8.go | 161 -- src/cmd/internal/obj/i386/obj8.go | 942 ------- src/cmd/internal/obj/i386/util.go | 12 - 6 files changed, 5678 deletions(-) delete mode 100644 src/cmd/internal/obj/i386/8.out.go delete mode 100644 src/cmd/internal/obj/i386/anames8.go delete mode 100644 src/cmd/internal/obj/i386/asm8.go delete mode 100644 src/cmd/internal/obj/i386/list8.go delete mode 100644 src/cmd/internal/obj/i386/obj8.go delete mode 100644 src/cmd/internal/obj/i386/util.go diff --git a/src/cmd/internal/obj/i386/8.out.go b/src/cmd/internal/obj/i386/8.out.go deleted file mode 100644 index 6e4fca186a8..00000000000 --- a/src/cmd/internal/obj/i386/8.out.go +++ /dev/null @@ -1,594 +0,0 @@ -// Inferno utils/8c/8.out.h -// http://code.google.com/p/inferno-os/source/browse/utils/8c/8.out.h -// -// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. -// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) -// Portions Copyright © 1997-1999 Vita Nuova Limited -// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com) -// Portions Copyright © 2004,2006 Bruce Ellis -// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) -// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others -// Portions Copyright © 2009 The Go Authors. All rights reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -package i386 - -import "cmd/internal/obj" - -const ( - AAAA = obj.ABase386 + obj.A_ARCHSPECIFIC + iota - AAAD - AAAM - AAAS - AADCB - AADCL - AADCW - AADDB - AADDL - AADDW - AADJSP - AANDB - AANDL - AANDW - AARPL - ABOUNDL - ABOUNDW - ABSFL - ABSFW - ABSRL - ABSRW - ABTL - ABTW - ABTCL - ABTCW - ABTRL - ABTRW - ABTSL - ABTSW - ABYTE - ACLC - ACLD - ACLI - ACLTS - ACMC - ACMPB - ACMPL - ACMPW - ACMPSB - ACMPSL - ACMPSW - ADAA - ADAS - ADECB - ADECL - ADECW - ADIVB - ADIVL - ADIVW - AENTER - AHLT - AIDIVB - AIDIVL - AIDIVW - AIMULB - AIMULL - AIMULW - AINB - AINL - AINW - AINCB - AINCL - AINCW - AINSB - AINSL - AINSW - AINT - AINTO - AIRETL - AIRETW - AJCC - AJCS - AJCXZL - AJCXZW - AJEQ - AJGE - AJGT - AJHI - AJLE - AJLS - AJLT - AJMI - AJNE - AJOC - AJOS - AJPC - AJPL - AJPS - ALAHF - ALARL - ALARW - ALEAL - ALEAW - ALEAVEL - ALEAVEW - ALOCK - ALODSB - ALODSL - ALODSW - ALONG - ALOOP - ALOOPEQ - ALOOPNE - ALSLL - ALSLW - AMOVB - AMOVL - AMOVW - AMOVQ - AMOVBLSX - AMOVBLZX - AMOVBWSX - AMOVBWZX - AMOVWLSX - AMOVWLZX - AMOVSB - AMOVSL - AMOVSW - AMULB - AMULL - AMULW - ANEGB - ANEGL - ANEGW - ANOTB - ANOTL - ANOTW - AORB - AORL - AORW - AOUTB - AOUTL - AOUTW - AOUTSB - AOUTSL - AOUTSW - APAUSE - APOPAL - APOPAW - APOPFL - APOPFW - APOPL - APOPW - APUSHAL - APUSHAW - APUSHFL - APUSHFW - APUSHL - APUSHW - ARCLB - ARCLL - ARCLW - ARCRB - ARCRL - ARCRW - AREP - AREPN - AROLB - AROLL - AROLW - ARORB - ARORL - ARORW - ASAHF - ASALB - ASALL - ASALW - ASARB - ASARL - ASARW - ASBBB - ASBBL - ASBBW - ASCASB - ASCASL - ASCASW - ASETCC - ASETCS - ASETEQ - ASETGE - ASETGT - ASETHI - ASETLE - ASETLS - ASETLT - ASETMI - ASETNE - ASETOC - ASETOS - ASETPC - ASETPL - ASETPS - ACDQ - ACWD - ASHLB - ASHLL - ASHLW - ASHRB - ASHRL - ASHRW - ASTC - ASTD - ASTI - ASTOSB - ASTOSL - ASTOSW - ASUBB - ASUBL - ASUBW - ASYSCALL - ATESTB - ATESTL - ATESTW - AVERR - AVERW - AWAIT - AWORD - AXCHGB - AXCHGL - AXCHGW - AXLAT - AXORB - AXORL - AXORW - AFMOVB - AFMOVBP - AFMOVD - AFMOVDP - AFMOVF - AFMOVFP - AFMOVL - AFMOVLP - AFMOVV - AFMOVVP - AFMOVW - AFMOVWP - AFMOVX - AFMOVXP - AFCOMB - AFCOMBP - AFCOMD - AFCOMDP - AFCOMDPP - AFCOMF - AFCOMFP - AFCOMI - AFCOMIP - AFCOML - AFCOMLP - AFCOMW - AFCOMWP - AFUCOM - AFUCOMI - AFUCOMIP - AFUCOMP - AFUCOMPP - AFADDDP - AFADDW - AFADDL - AFADDF - AFADDD - AFMULDP - AFMULW - AFMULL - AFMULF - AFMULD - AFSUBDP - AFSUBW - AFSUBL - AFSUBF - AFSUBD - AFSUBRDP - AFSUBRW - AFSUBRL - AFSUBRF - AFSUBRD - AFDIVDP - AFDIVW - AFDIVL - AFDIVF - AFDIVD - AFDIVRDP - AFDIVRW - AFDIVRL - AFDIVRF - AFDIVRD - AFXCHD - AFFREE - AFLDCW - AFLDENV - AFRSTOR - AFSAVE - AFSTCW - AFSTENV - AFSTSW - AF2XM1 - AFABS - AFCHS - AFCLEX - AFCOS - AFDECSTP - AFINCSTP - AFINIT - AFLD1 - AFLDL2E - AFLDL2T - AFLDLG2 - AFLDLN2 - AFLDPI - AFLDZ - AFNOP - AFPATAN - AFPREM - AFPREM1 - AFPTAN - AFRNDINT - AFSCALE - AFSIN - AFSINCOS - AFSQRT - AFTST - AFXAM - AFXTRACT - AFYL2X - AFYL2XP1 - ACMPXCHGB - ACMPXCHGL - ACMPXCHGW - ACMPXCHG8B - ACPUID - ARDTSC - AXADDB - AXADDL - AXADDW - ACMOVLCC - ACMOVLCS - ACMOVLEQ - ACMOVLGE - ACMOVLGT - ACMOVLHI - ACMOVLLE - ACMOVLLS - ACMOVLLT - ACMOVLMI - ACMOVLNE - ACMOVLOC - ACMOVLOS - ACMOVLPC - ACMOVLPL - ACMOVLPS - ACMOVWCC - ACMOVWCS - ACMOVWEQ - ACMOVWGE - ACMOVWGT - ACMOVWHI - ACMOVWLE - ACMOVWLS - ACMOVWLT - ACMOVWMI - ACMOVWNE - ACMOVWOC - ACMOVWOS - ACMOVWPC - ACMOVWPL - ACMOVWPS - AFCMOVCC - AFCMOVCS - AFCMOVEQ - AFCMOVHI - AFCMOVLS - AFCMOVNE - AFCMOVNU - AFCMOVUN - ALFENCE - AMFENCE - ASFENCE - AEMMS - APREFETCHT0 - APREFETCHT1 - APREFETCHT2 - APREFETCHNTA - ABSWAPL - AADDPD - AADDPS - AADDSD - AADDSS - AANDNPD - AANDNPS - AANDPD - AANDPS - ACMPPD - ACMPPS - ACMPSD - ACMPSS - ACOMISD - ACOMISS - ACVTPL2PD - ACVTPL2PS - ACVTPD2PL - ACVTPD2PS - ACVTPS2PL - ACVTPS2PD - ACVTSD2SL - ACVTSD2SS - ACVTSL2SD - ACVTSL2SS - ACVTSS2SD - ACVTSS2SL - ACVTTPD2PL - ACVTTPS2PL - ACVTTSD2SL - ACVTTSS2SL - ADIVPD - ADIVPS - ADIVSD - ADIVSS - AMASKMOVOU - AMAXPD - AMAXPS - AMAXSD - AMAXSS - AMINPD - AMINPS - AMINSD - AMINSS - AMOVAPD - AMOVAPS - AMOVO - AMOVOU - AMOVHLPS - AMOVHPD - AMOVHPS - AMOVLHPS - AMOVLPD - AMOVLPS - AMOVMSKPD - AMOVMSKPS - AMOVNTO - AMOVNTPD - AMOVNTPS - AMOVSD - AMOVSS - AMOVUPD - AMOVUPS - AMULPD - AMULPS - AMULSD - AMULSS - AORPD - AORPS - APADDQ - APAND - APCMPEQB - APMAXSW - APMAXUB - APMINSW - APMINUB - APMOVMSKB - APSADBW - APSUBB - APSUBL - APSUBQ - APSUBSB - APSUBSW - APSUBUSB - APSUBUSW - APSUBW - APUNPCKHQDQ - APUNPCKLQDQ - APXOR - ARCPPS - ARCPSS - ARSQRTPS - ARSQRTSS - ASQRTPD - ASQRTPS - ASQRTSD - ASQRTSS - ASUBPD - ASUBPS - ASUBSD - ASUBSS - AUCOMISD - AUCOMISS - AUNPCKHPD - AUNPCKHPS - AUNPCKLPD - AUNPCKLPS - AXORPD - AXORPS - APSHUFHW - APSHUFL - APSHUFLW - AAESENC - APINSRD - APSHUFB - ALAST -) - -const ( - REG_NONE = 0 - REG_AL = obj.RBase386 + 0 + iota - 1 - REG_CL - REG_DL - REG_BL - REG_AH = obj.RBase386 + 4 + iota - 5 - REG_CH - REG_DH - REG_BH - REG_AX = obj.RBase386 + 8 + iota - 9 - REG_CX - REG_DX - REG_BX - REG_SP - REG_BP - REG_SI - REG_DI - REG_F0 = obj.RBase386 + 16 - REG_F7 = obj.RBase386 + REG_F0 + 7 - REG_CS = obj.RBase386 + 24 + iota - 19 - REG_SS - REG_DS - REG_ES - REG_FS - REG_GS - REG_GDTR - REG_IDTR - REG_LDTR - REG_MSW - REG_TASK - REG_CR = obj.RBase386 + 35 - REG_DR = obj.RBase386 + 43 - REG_TR = obj.RBase386 + 51 - REG_X0 = obj.RBase386 + 59 + iota - 33 - REG_X1 - REG_X2 - REG_X3 - REG_X4 - REG_X5 - REG_X6 - REG_X7 - REG_TLS = obj.RBase386 + 67 - MAXREG = obj.RBase386 + 68 - T_TYPE = 1 << 0 - T_INDEX = 1 << 1 - T_OFFSET = 1 << 2 - T_FCONST = 1 << 3 - T_SYM = 1 << 4 - T_SCONST = 1 << 5 - T_OFFSET2 = 1 << 6 - T_GOTYPE = 1 << 7 - REGARG = -1 - REGRET = REG_AX - FREGRET = REG_F0 - REGSP = REG_SP - REGTMP = REG_DI - REGCTXT = REG_DX -) diff --git a/src/cmd/internal/obj/i386/anames8.go b/src/cmd/internal/obj/i386/anames8.go deleted file mode 100644 index 60245634cac..00000000000 --- a/src/cmd/internal/obj/i386/anames8.go +++ /dev/null @@ -1,507 +0,0 @@ -package i386 - -import "cmd/internal/obj" - -/* - * this is the ranlib header - */ -var Anames = []string{ - obj.A_ARCHSPECIFIC: "AAA", - "AAD", - "AAM", - "AAS", - "ADCB", - "ADCL", - "ADCW", - "ADDB", - "ADDL", - "ADDW", - "ADJSP", - "ANDB", - "ANDL", - "ANDW", - "ARPL", - "BOUNDL", - "BOUNDW", - "BSFL", - "BSFW", - "BSRL", - "BSRW", - "BTL", - "BTW", - "BTCL", - "BTCW", - "BTRL", - "BTRW", - "BTSL", - "BTSW", - "BYTE", - "CLC", - "CLD", - "CLI", - "CLTS", - "CMC", - "CMPB", - "CMPL", - "CMPW", - "CMPSB", - "CMPSL", - "CMPSW", - "DAA", - "DAS", - "DECB", - "DECL", - "DECW", - "DIVB", - "DIVL", - "DIVW", - "ENTER", - "HLT", - "IDIVB", - "IDIVL", - "IDIVW", - "IMULB", - "IMULL", - "IMULW", - "INB", - "INL", - "INW", - "INCB", - "INCL", - "INCW", - "INSB", - "INSL", - "INSW", - "INT", - "INTO", - "IRETL", - "IRETW", - "JCC", - "JCS", - "JCXZL", - "JCXZW", - "JEQ", - "JGE", - "JGT", - "JHI", - "JLE", - "JLS", - "JLT", - "JMI", - "JNE", - "JOC", - "JOS", - "JPC", - "JPL", - "JPS", - "LAHF", - "LARL", - "LARW", - "LEAL", - "LEAW", - "LEAVEL", - "LEAVEW", - "LOCK", - "LODSB", - "LODSL", - "LODSW", - "LONG", - "LOOP", - "LOOPEQ", - "LOOPNE", - "LSLL", - "LSLW", - "MOVB", - "MOVL", - "MOVW", - "MOVQ", - "MOVBLSX", - "MOVBLZX", - "MOVBWSX", - "MOVBWZX", - "MOVWLSX", - "MOVWLZX", - "MOVSB", - "MOVSL", - "MOVSW", - "MULB", - "MULL", - "MULW", - "NEGB", - "NEGL", - "NEGW", - "NOTB", - "NOTL", - "NOTW", - "ORB", - "ORL", - "ORW", - "OUTB", - "OUTL", - "OUTW", - "OUTSB", - "OUTSL", - "OUTSW", - "PAUSE", - "POPAL", - "POPAW", - "POPFL", - "POPFW", - "POPL", - "POPW", - "PUSHAL", - "PUSHAW", - "PUSHFL", - "PUSHFW", - "PUSHL", - "PUSHW", - "RCLB", - "RCLL", - "RCLW", - "RCRB", - "RCRL", - "RCRW", - "REP", - "REPN", - "ROLB", - "ROLL", - "ROLW", - "RORB", - "RORL", - "RORW", - "SAHF", - "SALB", - "SALL", - "SALW", - "SARB", - "SARL", - "SARW", - "SBBB", - "SBBL", - "SBBW", - "SCASB", - "SCASL", - "SCASW", - "SETCC", - "SETCS", - "SETEQ", - "SETGE", - "SETGT", - "SETHI", - "SETLE", - "SETLS", - "SETLT", - "SETMI", - "SETNE", - "SETOC", - "SETOS", - "SETPC", - "SETPL", - "SETPS", - "CDQ", - "CWD", - "SHLB", - "SHLL", - "SHLW", - "SHRB", - "SHRL", - "SHRW", - "STC", - "STD", - "STI", - "STOSB", - "STOSL", - "STOSW", - "SUBB", - "SUBL", - "SUBW", - "SYSCALL", - "TESTB", - "TESTL", - "TESTW", - "VERR", - "VERW", - "WAIT", - "WORD", - "XCHGB", - "XCHGL", - "XCHGW", - "XLAT", - "XORB", - "XORL", - "XORW", - "FMOVB", - "FMOVBP", - "FMOVD", - "FMOVDP", - "FMOVF", - "FMOVFP", - "FMOVL", - "FMOVLP", - "FMOVV", - "FMOVVP", - "FMOVW", - "FMOVWP", - "FMOVX", - "FMOVXP", - "FCOMB", - "FCOMBP", - "FCOMD", - "FCOMDP", - "FCOMDPP", - "FCOMF", - "FCOMFP", - "FCOMI", - "FCOMIP", - "FCOML", - "FCOMLP", - "FCOMW", - "FCOMWP", - "FUCOM", - "FUCOMI", - "FUCOMIP", - "FUCOMP", - "FUCOMPP", - "FADDDP", - "FADDW", - "FADDL", - "FADDF", - "FADDD", - "FMULDP", - "FMULW", - "FMULL", - "FMULF", - "FMULD", - "FSUBDP", - "FSUBW", - "FSUBL", - "FSUBF", - "FSUBD", - "FSUBRDP", - "FSUBRW", - "FSUBRL", - "FSUBRF", - "FSUBRD", - "FDIVDP", - "FDIVW", - "FDIVL", - "FDIVF", - "FDIVD", - "FDIVRDP", - "FDIVRW", - "FDIVRL", - "FDIVRF", - "FDIVRD", - "FXCHD", - "FFREE", - "FLDCW", - "FLDENV", - "FRSTOR", - "FSAVE", - "FSTCW", - "FSTENV", - "FSTSW", - "F2XM1", - "FABS", - "FCHS", - "FCLEX", - "FCOS", - "FDECSTP", - "FINCSTP", - "FINIT", - "FLD1", - "FLDL2E", - "FLDL2T", - "FLDLG2", - "FLDLN2", - "FLDPI", - "FLDZ", - "FNOP", - "FPATAN", - "FPREM", - "FPREM1", - "FPTAN", - "FRNDINT", - "FSCALE", - "FSIN", - "FSINCOS", - "FSQRT", - "FTST", - "FXAM", - "FXTRACT", - "FYL2X", - "FYL2XP1", - "CMPXCHGB", - "CMPXCHGL", - "CMPXCHGW", - "CMPXCHG8B", - "CPUID", - "RDTSC", - "XADDB", - "XADDL", - "XADDW", - "CMOVLCC", - "CMOVLCS", - "CMOVLEQ", - "CMOVLGE", - "CMOVLGT", - "CMOVLHI", - "CMOVLLE", - "CMOVLLS", - "CMOVLLT", - "CMOVLMI", - "CMOVLNE", - "CMOVLOC", - "CMOVLOS", - "CMOVLPC", - "CMOVLPL", - "CMOVLPS", - "CMOVWCC", - "CMOVWCS", - "CMOVWEQ", - "CMOVWGE", - "CMOVWGT", - "CMOVWHI", - "CMOVWLE", - "CMOVWLS", - "CMOVWLT", - "CMOVWMI", - "CMOVWNE", - "CMOVWOC", - "CMOVWOS", - "CMOVWPC", - "CMOVWPL", - "CMOVWPS", - "FCMOVCC", - "FCMOVCS", - "FCMOVEQ", - "FCMOVHI", - "FCMOVLS", - "FCMOVNE", - "FCMOVNU", - "FCMOVUN", - "LFENCE", - "MFENCE", - "SFENCE", - "EMMS", - "PREFETCHT0", - "PREFETCHT1", - "PREFETCHT2", - "PREFETCHNTA", - "BSWAPL", - "ADDPD", - "ADDPS", - "ADDSD", - "ADDSS", - "ANDNPD", - "ANDNPS", - "ANDPD", - "ANDPS", - "CMPPD", - "CMPPS", - "CMPSD", - "CMPSS", - "COMISD", - "COMISS", - "CVTPL2PD", - "CVTPL2PS", - "CVTPD2PL", - "CVTPD2PS", - "CVTPS2PL", - "CVTPS2PD", - "CVTSD2SL", - "CVTSD2SS", - "CVTSL2SD", - "CVTSL2SS", - "CVTSS2SD", - "CVTSS2SL", - "CVTTPD2PL", - "CVTTPS2PL", - "CVTTSD2SL", - "CVTTSS2SL", - "DIVPD", - "DIVPS", - "DIVSD", - "DIVSS", - "MASKMOVOU", - "MAXPD", - "MAXPS", - "MAXSD", - "MAXSS", - "MINPD", - "MINPS", - "MINSD", - "MINSS", - "MOVAPD", - "MOVAPS", - "MOVO", - "MOVOU", - "MOVHLPS", - "MOVHPD", - "MOVHPS", - "MOVLHPS", - "MOVLPD", - "MOVLPS", - "MOVMSKPD", - "MOVMSKPS", - "MOVNTO", - "MOVNTPD", - "MOVNTPS", - "MOVSD", - "MOVSS", - "MOVUPD", - "MOVUPS", - "MULPD", - "MULPS", - "MULSD", - "MULSS", - "ORPD", - "ORPS", - "PADDQ", - "PAND", - "PCMPEQB", - "PMAXSW", - "PMAXUB", - "PMINSW", - "PMINUB", - "PMOVMSKB", - "PSADBW", - "PSUBB", - "PSUBL", - "PSUBQ", - "PSUBSB", - "PSUBSW", - "PSUBUSB", - "PSUBUSW", - "PSUBW", - "PUNPCKHQDQ", - "PUNPCKLQDQ", - "PXOR", - "RCPPS", - "RCPSS", - "RSQRTPS", - "RSQRTSS", - "SQRTPD", - "SQRTPS", - "SQRTSD", - "SQRTSS", - "SUBPD", - "SUBPS", - "SUBSD", - "SUBSS", - "UCOMISD", - "UCOMISS", - "UNPCKHPD", - "UNPCKHPS", - "UNPCKLPD", - "UNPCKLPS", - "XORPD", - "XORPS", - "PSHUFHW", - "PSHUFL", - "PSHUFLW", - "AESENC", - "PINSRD", - "PSHUFB", - "LAST", -} diff --git a/src/cmd/internal/obj/i386/asm8.go b/src/cmd/internal/obj/i386/asm8.go deleted file mode 100644 index 8ad2304f279..00000000000 --- a/src/cmd/internal/obj/i386/asm8.go +++ /dev/null @@ -1,3462 +0,0 @@ -// Inferno utils/8l/span.c -// http://code.google.com/p/inferno-os/source/browse/utils/8l/span.c -// -// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. -// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) -// Portions Copyright © 1997-1999 Vita Nuova Limited -// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com) -// Portions Copyright © 2004,2006 Bruce Ellis -// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) -// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others -// Portions Copyright © 2009 The Go Authors. All rights reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -package i386 - -import ( - "cmd/internal/obj" - "fmt" - "log" - "strings" -) - -// Instruction layout. - -const ( - MaxAlign = 32 - FuncAlign = 16 -) - -type Optab struct { - as int16 - ytab []ytab - prefix uint8 - op [13]uint8 -} - -type ytab struct { - from uint8 - to uint8 - zcase uint8 - zoffset uint8 -} - -var opindex [(ALAST + 1) & obj.AMask]*Optab - -const ( - Yxxx = 0 + iota - Ynone - Yi0 - Yi1 - Yi8 - Yi32 - Yiauto - Yal - Ycl - Yax - Ycx - Yrb - Yrl - Yrf - Yf0 - Yrx - Ymb - Yml - Ym - Ybr - Ycol - Ytextsize - Ytls - Ycs - Yss - Yds - Yes - Yfs - Ygs - Ygdtr - Yidtr - Yldtr - Ymsw - Ytask - Ycr0 - Ycr1 - Ycr2 - Ycr3 - Ycr4 - Ycr5 - Ycr6 - Ycr7 - Ydr0 - Ydr1 - Ydr2 - Ydr3 - Ydr4 - Ydr5 - Ydr6 - Ydr7 - Ytr0 - Ytr1 - Ytr2 - Ytr3 - Ytr4 - Ytr5 - Ytr6 - Ytr7 - Ymr - Ymm - Yxr - Yxm - Ymax - Zxxx = 0 + iota - 63 - Zlit - Zlitm_r - Z_rp - Zbr - Zcall - Zcallcon - Zcallind - Zcallindreg - Zib_ - Zib_rp - Zibo_m - Zil_ - Zil_rp - Zilo_m - Zjmp - Zjmpcon - Zloop - Zm_o - Zm_r - Zm2_r - Zm_r_xm - Zm_r_i_xm - Zaut_r - Zo_m - Zpseudo - Zr_m - Zr_m_xm - Zr_m_i_xm - Zrp_ - Z_ib - Z_il - Zm_ibo - Zm_ilo - Zib_rr - Zil_rr - Zclr - Zibm_r - Zbyte - Zmov - Zmax - Px = 0 - Pe = 0x66 - Pm = 0x0f - Pq = 0xff - Pb = 0xfe - Pf2 = 0xf2 - Pf3 = 0xf3 -) - -var ycover [Ymax * Ymax]uint8 - -var reg [MAXREG]int - -var ynone = []ytab{ - {Ynone, Ynone, Zlit, 1}, -} - -var ytext = []ytab{ - {Ymb, Ytextsize, Zpseudo, 1}, -} - -var ynop = []ytab{ - {Ynone, Ynone, Zpseudo, 0}, - {Ynone, Yiauto, Zpseudo, 0}, - {Ynone, Yml, Zpseudo, 0}, - {Ynone, Yrf, Zpseudo, 0}, - {Yiauto, Ynone, Zpseudo, 0}, - {Ynone, Yxr, Zpseudo, 0}, - {Yml, Ynone, Zpseudo, 0}, - {Yrf, Ynone, Zpseudo, 0}, - {Yxr, Ynone, Zpseudo, 1}, -} - -var yfuncdata = []ytab{ - {Yi32, Ym, Zpseudo, 0}, -} - -var ypcdata = []ytab{ - {Yi32, Yi32, Zpseudo, 0}, -} - -var yxorb = []ytab{ - {Yi32, Yal, Zib_, 1}, - {Yi32, Ymb, Zibo_m, 2}, - {Yrb, Ymb, Zr_m, 1}, - {Ymb, Yrb, Zm_r, 1}, -} - -var yxorl = []ytab{ - {Yi8, Yml, Zibo_m, 2}, - {Yi32, Yax, Zil_, 1}, - {Yi32, Yml, Zilo_m, 2}, - {Yrl, Yml, Zr_m, 1}, - {Yml, Yrl, Zm_r, 1}, -} - -var yaddl = []ytab{ - {Yi8, Yml, Zibo_m, 2}, - {Yi32, Yax, Zil_, 1}, - {Yi32, Yml, Zilo_m, 2}, - {Yrl, Yml, Zr_m, 1}, - {Yml, Yrl, Zm_r, 1}, -} - -var yincb = []ytab{ - {Ynone, Ymb, Zo_m, 2}, -} - -var yincl = []ytab{ - {Ynone, Yrl, Z_rp, 1}, - {Ynone, Yml, Zo_m, 2}, -} - -var ycmpb = []ytab{ - {Yal, Yi32, Z_ib, 1}, - {Ymb, Yi32, Zm_ibo, 2}, - {Ymb, Yrb, Zm_r, 1}, - {Yrb, Ymb, Zr_m, 1}, -} - -var ycmpl = []ytab{ - {Yml, Yi8, Zm_ibo, 2}, - {Yax, Yi32, Z_il, 1}, - {Yml, Yi32, Zm_ilo, 2}, - {Yml, Yrl, Zm_r, 1}, - {Yrl, Yml, Zr_m, 1}, -} - -var yshb = []ytab{ - {Yi1, Ymb, Zo_m, 2}, - {Yi32, Ymb, Zibo_m, 2}, - {Ycx, Ymb, Zo_m, 2}, -} - -var yshl = []ytab{ - {Yi1, Yml, Zo_m, 2}, - {Yi32, Yml, Zibo_m, 2}, - {Ycl, Yml, Zo_m, 2}, - {Ycx, Yml, Zo_m, 2}, -} - -var ytestb = []ytab{ - {Yi32, Yal, Zib_, 1}, - {Yi32, Ymb, Zibo_m, 2}, - {Yrb, Ymb, Zr_m, 1}, - {Ymb, Yrb, Zm_r, 1}, -} - -var ytestl = []ytab{ - {Yi32, Yax, Zil_, 1}, - {Yi32, Yml, Zilo_m, 2}, - {Yrl, Yml, Zr_m, 1}, - {Yml, Yrl, Zm_r, 1}, -} - -var ymovb = []ytab{ - {Yrb, Ymb, Zr_m, 1}, - {Ymb, Yrb, Zm_r, 1}, - {Yi32, Yrb, Zib_rp, 1}, - {Yi32, Ymb, Zibo_m, 2}, -} - -var ymovw = []ytab{ - {Yrl, Yml, Zr_m, 1}, - {Yml, Yrl, Zm_r, 1}, - {Yi0, Yrl, Zclr, 1 + 2}, - // Yi0, Yml, Zibo_m, 2, // shorter but slower AND $0,dst - {Yi32, Yrl, Zil_rp, 1}, - {Yi32, Yml, Zilo_m, 2}, - {Yiauto, Yrl, Zaut_r, 1}, -} - -var ymovl = []ytab{ - {Yrl, Yml, Zr_m, 1}, - {Yml, Yrl, Zm_r, 1}, - {Yi0, Yrl, Zclr, 1 + 2}, - // Yi0, Yml, Zibo_m, 2, // shorter but slower AND $0,dst - {Yi32, Yrl, Zil_rp, 1}, - {Yi32, Yml, Zilo_m, 2}, - {Yml, Yxr, Zm_r_xm, 2}, // XMM MOVD (32 bit) - {Yxr, Yml, Zr_m_xm, 2}, // XMM MOVD (32 bit) - {Yiauto, Yrl, Zaut_r, 1}, -} - -var ymovq = []ytab{ - {Yml, Yxr, Zm_r_xm, 2}, -} - -var ym_rl = []ytab{ - {Ym, Yrl, Zm_r, 1}, -} - -var yrl_m = []ytab{ - {Yrl, Ym, Zr_m, 1}, -} - -var ymb_rl = []ytab{ - {Ymb, Yrl, Zm_r, 1}, -} - -var yml_rl = []ytab{ - {Yml, Yrl, Zm_r, 1}, -} - -var yrb_mb = []ytab{ - {Yrb, Ymb, Zr_m, 1}, -} - -var yrl_ml = []ytab{ - {Yrl, Yml, Zr_m, 1}, -} - -var yml_mb = []ytab{ - {Yrb, Ymb, Zr_m, 1}, - {Ymb, Yrb, Zm_r, 1}, -} - -var yxchg = []ytab{ - {Yax, Yrl, Z_rp, 1}, - {Yrl, Yax, Zrp_, 1}, - {Yrl, Yml, Zr_m, 1}, - {Yml, Yrl, Zm_r, 1}, -} - -var ydivl = []ytab{ - {Yml, Ynone, Zm_o, 2}, -} - -var ydivb = []ytab{ - {Ymb, Ynone, Zm_o, 2}, -} - -var yimul = []ytab{ - {Yml, Ynone, Zm_o, 2}, - {Yi8, Yrl, Zib_rr, 1}, - {Yi32, Yrl, Zil_rr, 1}, -} - -var ybyte = []ytab{ - {Yi32, Ynone, Zbyte, 1}, -} - -var yin = []ytab{ - {Yi32, Ynone, Zib_, 1}, - {Ynone, Ynone, Zlit, 1}, -} - -var yint = []ytab{ - {Yi32, Ynone, Zib_, 1}, -} - -var ypushl = []ytab{ - {Yrl, Ynone, Zrp_, 1}, - {Ym, Ynone, Zm_o, 2}, - {Yi8, Ynone, Zib_, 1}, - {Yi32, Ynone, Zil_, 1}, -} - -var ypopl = []ytab{ - {Ynone, Yrl, Z_rp, 1}, - {Ynone, Ym, Zo_m, 2}, -} - -var ybswap = []ytab{ - {Ynone, Yrl, Z_rp, 1}, -} - -var yscond = []ytab{ - {Ynone, Ymb, Zo_m, 2}, -} - -var yjcond = []ytab{ - {Ynone, Ybr, Zbr, 0}, - {Yi0, Ybr, Zbr, 0}, - {Yi1, Ybr, Zbr, 1}, -} - -var yloop = []ytab{ - {Ynone, Ybr, Zloop, 1}, -} - -var ycall = []ytab{ - {Ynone, Yml, Zcallindreg, 0}, - {Yrx, Yrx, Zcallindreg, 2}, - {Ynone, Ycol, Zcallind, 2}, - {Ynone, Ybr, Zcall, 0}, - {Ynone, Yi32, Zcallcon, 1}, -} - -var yduff = []ytab{ - {Ynone, Yi32, Zcall, 1}, -} - -var yjmp = []ytab{ - {Ynone, Yml, Zo_m, 2}, - {Ynone, Ybr, Zjmp, 0}, - {Ynone, Yi32, Zjmpcon, 1}, -} - -var yfmvd = []ytab{ - {Ym, Yf0, Zm_o, 2}, - {Yf0, Ym, Zo_m, 2}, - {Yrf, Yf0, Zm_o, 2}, - {Yf0, Yrf, Zo_m, 2}, -} - -var yfmvdp = []ytab{ - {Yf0, Ym, Zo_m, 2}, - {Yf0, Yrf, Zo_m, 2}, -} - -var yfmvf = []ytab{ - {Ym, Yf0, Zm_o, 2}, - {Yf0, Ym, Zo_m, 2}, -} - -var yfmvx = []ytab{ - {Ym, Yf0, Zm_o, 2}, -} - -var yfmvp = []ytab{ - {Yf0, Ym, Zo_m, 2}, -} - -var yfcmv = []ytab{ - {Yrf, Yf0, Zm_o, 2}, -} - -var yfadd = []ytab{ - {Ym, Yf0, Zm_o, 2}, - {Yrf, Yf0, Zm_o, 2}, - {Yf0, Yrf, Zo_m, 2}, -} - -var yfaddp = []ytab{ - {Yf0, Yrf, Zo_m, 2}, -} - -var yfxch = []ytab{ - {Yf0, Yrf, Zo_m, 2}, - {Yrf, Yf0, Zm_o, 2}, -} - -var ycompp = []ytab{ - {Yf0, Yrf, Zo_m, 2}, /* botch is really f0,f1 */ -} - -var ystsw = []ytab{ - {Ynone, Ym, Zo_m, 2}, - {Ynone, Yax, Zlit, 1}, -} - -var ystcw = []ytab{ - {Ynone, Ym, Zo_m, 2}, - {Ym, Ynone, Zm_o, 2}, -} - -var ysvrs = []ytab{ - {Ynone, Ym, Zo_m, 2}, - {Ym, Ynone, Zm_o, 2}, -} - -var ymskb = []ytab{ - {Yxr, Yrl, Zm_r_xm, 2}, - {Ymr, Yrl, Zm_r_xm, 1}, -} - -var yxm = []ytab{ - {Yxm, Yxr, Zm_r_xm, 1}, -} - -var yxcvm1 = []ytab{ - {Yxm, Yxr, Zm_r_xm, 2}, - {Yxm, Ymr, Zm_r_xm, 2}, -} - -var yxcvm2 = []ytab{ - {Yxm, Yxr, Zm_r_xm, 2}, - {Ymm, Yxr, Zm_r_xm, 2}, -} - -var yxmq = []ytab{ - {Yxm, Yxr, Zm_r_xm, 2}, -} - -var yxr = []ytab{ - {Yxr, Yxr, Zm_r_xm, 1}, -} - -var yxr_ml = []ytab{ - {Yxr, Yml, Zr_m_xm, 1}, -} - -var yxcmp = []ytab{ - {Yxm, Yxr, Zm_r_xm, 1}, -} - -var yxcmpi = []ytab{ - {Yxm, Yxr, Zm_r_i_xm, 2}, -} - -var yxmov = []ytab{ - {Yxm, Yxr, Zm_r_xm, 1}, - {Yxr, Yxm, Zr_m_xm, 1}, -} - -var yxcvfl = []ytab{ - {Yxm, Yrl, Zm_r_xm, 1}, -} - -var yxcvlf = []ytab{ - {Yml, Yxr, Zm_r_xm, 1}, -} - -/* -var yxcvfq = []ytab{ - {Yxm, Yrl, Zm_r_xm, 2}, -} - -var yxcvqf = []ytab{ - {Yml, Yxr, Zm_r_xm, 2}, -} -*/ - -var yxrrl = []ytab{ - {Yxr, Yrl, Zm_r, 1}, -} - -var yprefetch = []ytab{ - {Ym, Ynone, Zm_o, 2}, -} - -var yaes = []ytab{ - {Yxm, Yxr, Zlitm_r, 2}, -} - -var yinsrd = []ytab{ - {Yml, Yxr, Zibm_r, 2}, -} - -var ymshufb = []ytab{ - {Yxm, Yxr, Zm2_r, 2}, -} - -var yxshuf = []ytab{ - {Yxm, Yxr, Zibm_r, 2}, -} - -var optab = []Optab{ /* as, ytab, andproto, opcode */ - Optab{obj.AXXX, nil, 0, [13]uint8{}}, - Optab{AAAA, ynone, Px, [13]uint8{0x37}}, - Optab{AAAD, ynone, Px, [13]uint8{0xd5, 0x0a}}, - Optab{AAAM, ynone, Px, [13]uint8{0xd4, 0x0a}}, - Optab{AAAS, ynone, Px, [13]uint8{0x3f}}, - Optab{AADCB, yxorb, Pb, [13]uint8{0x14, 0x80, 02, 0x10, 0x10}}, - Optab{AADCL, yxorl, Px, [13]uint8{0x83, 02, 0x15, 0x81, 02, 0x11, 0x13}}, - Optab{AADCW, yxorl, Pe, [13]uint8{0x83, 02, 0x15, 0x81, 02, 0x11, 0x13}}, - Optab{AADDB, yxorb, Px, [13]uint8{0x04, 0x80, 00, 0x00, 0x02}}, - Optab{AADDL, yaddl, Px, [13]uint8{0x83, 00, 0x05, 0x81, 00, 0x01, 0x03}}, - Optab{AADDW, yaddl, Pe, [13]uint8{0x83, 00, 0x05, 0x81, 00, 0x01, 0x03}}, - Optab{AADJSP, nil, 0, [13]uint8{}}, - Optab{AANDB, yxorb, Pb, [13]uint8{0x24, 0x80, 04, 0x20, 0x22}}, - Optab{AANDL, yxorl, Px, [13]uint8{0x83, 04, 0x25, 0x81, 04, 0x21, 0x23}}, - Optab{AANDW, yxorl, Pe, [13]uint8{0x83, 04, 0x25, 0x81, 04, 0x21, 0x23}}, - Optab{AARPL, yrl_ml, Px, [13]uint8{0x63}}, - Optab{ABOUNDL, yrl_m, Px, [13]uint8{0x62}}, - Optab{ABOUNDW, yrl_m, Pe, [13]uint8{0x62}}, - Optab{ABSFL, yml_rl, Pm, [13]uint8{0xbc}}, - Optab{ABSFW, yml_rl, Pq, [13]uint8{0xbc}}, - Optab{ABSRL, yml_rl, Pm, [13]uint8{0xbd}}, - Optab{ABSRW, yml_rl, Pq, [13]uint8{0xbd}}, - Optab{ABTL, yml_rl, Pm, [13]uint8{0xa3}}, - Optab{ABTW, yml_rl, Pq, [13]uint8{0xa3}}, - Optab{ABTCL, yml_rl, Pm, [13]uint8{0xbb}}, - Optab{ABTCW, yml_rl, Pq, [13]uint8{0xbb}}, - Optab{ABTRL, yml_rl, Pm, [13]uint8{0xb3}}, - Optab{ABTRW, yml_rl, Pq, [13]uint8{0xb3}}, - Optab{ABTSL, yml_rl, Pm, [13]uint8{0xab}}, - Optab{ABTSW, yml_rl, Pq, [13]uint8{0xab}}, - Optab{ABYTE, ybyte, Px, [13]uint8{1}}, - Optab{obj.ACALL, ycall, Px, [13]uint8{0xff, 02, 0xff, 0x15, 0xe8}}, - Optab{ACLC, ynone, Px, [13]uint8{0xf8}}, - Optab{ACLD, ynone, Px, [13]uint8{0xfc}}, - Optab{ACLI, ynone, Px, [13]uint8{0xfa}}, - Optab{ACLTS, ynone, Pm, [13]uint8{0x06}}, - Optab{ACMC, ynone, Px, [13]uint8{0xf5}}, - Optab{ACMPB, ycmpb, Pb, [13]uint8{0x3c, 0x80, 07, 0x38, 0x3a}}, - Optab{ACMPL, ycmpl, Px, [13]uint8{0x83, 07, 0x3d, 0x81, 07, 0x39, 0x3b}}, - Optab{ACMPW, ycmpl, Pe, [13]uint8{0x83, 07, 0x3d, 0x81, 07, 0x39, 0x3b}}, - Optab{ACMPSB, ynone, Pb, [13]uint8{0xa6}}, - Optab{ACMPSL, ynone, Px, [13]uint8{0xa7}}, - Optab{ACMPSW, ynone, Pe, [13]uint8{0xa7}}, - Optab{ADAA, ynone, Px, [13]uint8{0x27}}, - Optab{ADAS, ynone, Px, [13]uint8{0x2f}}, - Optab{obj.ADATA, nil, 0, [13]uint8{}}, - Optab{ADECB, yincb, Pb, [13]uint8{0xfe, 01}}, - Optab{ADECL, yincl, Px, [13]uint8{0x48, 0xff, 01}}, - Optab{ADECW, yincl, Pe, [13]uint8{0x48, 0xff, 01}}, - Optab{ADIVB, ydivb, Pb, [13]uint8{0xf6, 06}}, - Optab{ADIVL, ydivl, Px, [13]uint8{0xf7, 06}}, - Optab{ADIVW, ydivl, Pe, [13]uint8{0xf7, 06}}, - Optab{AENTER, nil, 0, [13]uint8{}}, /* botch */ - Optab{obj.AGLOBL, nil, 0, [13]uint8{}}, - Optab{AHLT, ynone, Px, [13]uint8{0xf4}}, - Optab{AIDIVB, ydivb, Pb, [13]uint8{0xf6, 07}}, - Optab{AIDIVL, ydivl, Px, [13]uint8{0xf7, 07}}, - Optab{AIDIVW, ydivl, Pe, [13]uint8{0xf7, 07}}, - Optab{AIMULB, ydivb, Pb, [13]uint8{0xf6, 05}}, - Optab{AIMULL, yimul, Px, [13]uint8{0xf7, 05, 0x6b, 0x69}}, - Optab{AIMULW, yimul, Pe, [13]uint8{0xf7, 05, 0x6b, 0x69}}, - Optab{AINB, yin, Pb, [13]uint8{0xe4, 0xec}}, - Optab{AINL, yin, Px, [13]uint8{0xe5, 0xed}}, - Optab{AINW, yin, Pe, [13]uint8{0xe5, 0xed}}, - Optab{AINCB, yincb, Pb, [13]uint8{0xfe, 00}}, - Optab{AINCL, yincl, Px, [13]uint8{0x40, 0xff, 00}}, - Optab{AINCW, yincl, Pe, [13]uint8{0x40, 0xff, 00}}, - Optab{AINSB, ynone, Pb, [13]uint8{0x6c}}, - Optab{AINSL, ynone, Px, [13]uint8{0x6d}}, - Optab{AINSW, ynone, Pe, [13]uint8{0x6d}}, - Optab{AINT, yint, Px, [13]uint8{0xcd}}, - Optab{AINTO, ynone, Px, [13]uint8{0xce}}, - Optab{AIRETL, ynone, Px, [13]uint8{0xcf}}, - Optab{AIRETW, ynone, Pe, [13]uint8{0xcf}}, - Optab{AJCC, yjcond, Px, [13]uint8{0x73, 0x83, 00}}, - Optab{AJCS, yjcond, Px, [13]uint8{0x72, 0x82}}, - Optab{AJCXZL, yloop, Px, [13]uint8{0xe3}}, - Optab{AJCXZW, yloop, Px, [13]uint8{0xe3}}, - Optab{AJEQ, yjcond, Px, [13]uint8{0x74, 0x84}}, - Optab{AJGE, yjcond, Px, [13]uint8{0x7d, 0x8d}}, - Optab{AJGT, yjcond, Px, [13]uint8{0x7f, 0x8f}}, - Optab{AJHI, yjcond, Px, [13]uint8{0x77, 0x87}}, - Optab{AJLE, yjcond, Px, [13]uint8{0x7e, 0x8e}}, - Optab{AJLS, yjcond, Px, [13]uint8{0x76, 0x86}}, - Optab{AJLT, yjcond, Px, [13]uint8{0x7c, 0x8c}}, - Optab{AJMI, yjcond, Px, [13]uint8{0x78, 0x88}}, - Optab{obj.AJMP, yjmp, Px, [13]uint8{0xff, 04, 0xeb, 0xe9}}, - Optab{AJNE, yjcond, Px, [13]uint8{0x75, 0x85}}, - Optab{AJOC, yjcond, Px, [13]uint8{0x71, 0x81, 00}}, - Optab{AJOS, yjcond, Px, [13]uint8{0x70, 0x80, 00}}, - Optab{AJPC, yjcond, Px, [13]uint8{0x7b, 0x8b}}, - Optab{AJPL, yjcond, Px, [13]uint8{0x79, 0x89}}, - Optab{AJPS, yjcond, Px, [13]uint8{0x7a, 0x8a}}, - Optab{ALAHF, ynone, Px, [13]uint8{0x9f}}, - Optab{ALARL, yml_rl, Pm, [13]uint8{0x02}}, - Optab{ALARW, yml_rl, Pq, [13]uint8{0x02}}, - Optab{ALEAL, ym_rl, Px, [13]uint8{0x8d}}, - Optab{ALEAW, ym_rl, Pe, [13]uint8{0x8d}}, - Optab{ALEAVEL, ynone, Px, [13]uint8{0xc9}}, - Optab{ALEAVEW, ynone, Pe, [13]uint8{0xc9}}, - Optab{ALOCK, ynone, Px, [13]uint8{0xf0}}, - Optab{ALODSB, ynone, Pb, [13]uint8{0xac}}, - Optab{ALODSL, ynone, Px, [13]uint8{0xad}}, - Optab{ALODSW, ynone, Pe, [13]uint8{0xad}}, - Optab{ALONG, ybyte, Px, [13]uint8{4}}, - Optab{ALOOP, yloop, Px, [13]uint8{0xe2}}, - Optab{ALOOPEQ, yloop, Px, [13]uint8{0xe1}}, - Optab{ALOOPNE, yloop, Px, [13]uint8{0xe0}}, - Optab{ALSLL, yml_rl, Pm, [13]uint8{0x03}}, - Optab{ALSLW, yml_rl, Pq, [13]uint8{0x03}}, - Optab{AMOVB, ymovb, Pb, [13]uint8{0x88, 0x8a, 0xb0, 0xc6, 00}}, - Optab{AMOVL, ymovl, Px, [13]uint8{0x89, 0x8b, 0x31, 0x83, 04, 0xb8, 0xc7, 00, Pe, 0x6e, Pe, 0x7e, 0}}, - Optab{AMOVW, ymovw, Pe, [13]uint8{0x89, 0x8b, 0x31, 0x83, 04, 0xb8, 0xc7, 00, 0}}, - Optab{AMOVQ, ymovq, Pf3, [13]uint8{0x7e}}, - Optab{AMOVBLSX, ymb_rl, Pm, [13]uint8{0xbe}}, - Optab{AMOVBLZX, ymb_rl, Pm, [13]uint8{0xb6}}, - Optab{AMOVBWSX, ymb_rl, Pq, [13]uint8{0xbe}}, - Optab{AMOVBWZX, ymb_rl, Pq, [13]uint8{0xb6}}, - Optab{AMOVWLSX, yml_rl, Pm, [13]uint8{0xbf}}, - Optab{AMOVWLZX, yml_rl, Pm, [13]uint8{0xb7}}, - Optab{AMOVSB, ynone, Pb, [13]uint8{0xa4}}, - Optab{AMOVSL, ynone, Px, [13]uint8{0xa5}}, - Optab{AMOVSW, ynone, Pe, [13]uint8{0xa5}}, - Optab{AMULB, ydivb, Pb, [13]uint8{0xf6, 04}}, - Optab{AMULL, ydivl, Px, [13]uint8{0xf7, 04}}, - Optab{AMULW, ydivl, Pe, [13]uint8{0xf7, 04}}, - Optab{ANEGB, yscond, Px, [13]uint8{0xf6, 03}}, - Optab{ANEGL, yscond, Px, [13]uint8{0xf7, 03}}, // TODO(rsc): yscond is wrong here. - Optab{ANEGW, yscond, Pe, [13]uint8{0xf7, 03}}, // TODO(rsc): yscond is wrong here. - Optab{obj.ANOP, ynop, Px, [13]uint8{0, 0}}, - Optab{ANOTB, yscond, Px, [13]uint8{0xf6, 02}}, - Optab{ANOTL, yscond, Px, [13]uint8{0xf7, 02}}, // TODO(rsc): yscond is wrong here. - Optab{ANOTW, yscond, Pe, [13]uint8{0xf7, 02}}, // TODO(rsc): yscond is wrong here. - Optab{AORB, yxorb, Pb, [13]uint8{0x0c, 0x80, 01, 0x08, 0x0a}}, - Optab{AORL, yxorl, Px, [13]uint8{0x83, 01, 0x0d, 0x81, 01, 0x09, 0x0b}}, - Optab{AORW, yxorl, Pe, [13]uint8{0x83, 01, 0x0d, 0x81, 01, 0x09, 0x0b}}, - Optab{AOUTB, yin, Pb, [13]uint8{0xe6, 0xee}}, - Optab{AOUTL, yin, Px, [13]uint8{0xe7, 0xef}}, - Optab{AOUTW, yin, Pe, [13]uint8{0xe7, 0xef}}, - Optab{AOUTSB, ynone, Pb, [13]uint8{0x6e}}, - Optab{AOUTSL, ynone, Px, [13]uint8{0x6f}}, - Optab{AOUTSW, ynone, Pe, [13]uint8{0x6f}}, - Optab{APAUSE, ynone, Px, [13]uint8{0xf3, 0x90}}, - Optab{APOPAL, ynone, Px, [13]uint8{0x61}}, - Optab{APOPAW, ynone, Pe, [13]uint8{0x61}}, - Optab{APOPFL, ynone, Px, [13]uint8{0x9d}}, - Optab{APOPFW, ynone, Pe, [13]uint8{0x9d}}, - Optab{APOPL, ypopl, Px, [13]uint8{0x58, 0x8f, 00}}, - Optab{APOPW, ypopl, Pe, [13]uint8{0x58, 0x8f, 00}}, - Optab{APUSHAL, ynone, Px, [13]uint8{0x60}}, - Optab{APUSHAW, ynone, Pe, [13]uint8{0x60}}, - Optab{APUSHFL, ynone, Px, [13]uint8{0x9c}}, - Optab{APUSHFW, ynone, Pe, [13]uint8{0x9c}}, - Optab{APUSHL, ypushl, Px, [13]uint8{0x50, 0xff, 06, 0x6a, 0x68}}, - Optab{APUSHW, ypushl, Pe, [13]uint8{0x50, 0xff, 06, 0x6a, 0x68}}, - Optab{ARCLB, yshb, Pb, [13]uint8{0xd0, 02, 0xc0, 02, 0xd2, 02}}, - Optab{ARCLL, yshl, Px, [13]uint8{0xd1, 02, 0xc1, 02, 0xd3, 02, 0xd3, 02}}, - Optab{ARCLW, yshl, Pe, [13]uint8{0xd1, 02, 0xc1, 02, 0xd3, 02, 0xd3, 02}}, - Optab{ARCRB, yshb, Pb, [13]uint8{0xd0, 03, 0xc0, 03, 0xd2, 03}}, - Optab{ARCRL, yshl, Px, [13]uint8{0xd1, 03, 0xc1, 03, 0xd3, 03, 0xd3, 03}}, - Optab{ARCRW, yshl, Pe, [13]uint8{0xd1, 03, 0xc1, 03, 0xd3, 03, 0xd3, 03}}, - Optab{AREP, ynone, Px, [13]uint8{0xf3}}, - Optab{AREPN, ynone, Px, [13]uint8{0xf2}}, - Optab{obj.ARET, ynone, Px, [13]uint8{0xc3}}, - Optab{AROLB, yshb, Pb, [13]uint8{0xd0, 00, 0xc0, 00, 0xd2, 00}}, - Optab{AROLL, yshl, Px, [13]uint8{0xd1, 00, 0xc1, 00, 0xd3, 00, 0xd3, 00}}, - Optab{AROLW, yshl, Pe, [13]uint8{0xd1, 00, 0xc1, 00, 0xd3, 00, 0xd3, 00}}, - Optab{ARORB, yshb, Pb, [13]uint8{0xd0, 01, 0xc0, 01, 0xd2, 01}}, - Optab{ARORL, yshl, Px, [13]uint8{0xd1, 01, 0xc1, 01, 0xd3, 01, 0xd3, 01}}, - Optab{ARORW, yshl, Pe, [13]uint8{0xd1, 01, 0xc1, 01, 0xd3, 01, 0xd3, 01}}, - Optab{ASAHF, ynone, Px, [13]uint8{0x9e}}, - Optab{ASALB, yshb, Pb, [13]uint8{0xd0, 04, 0xc0, 04, 0xd2, 04}}, - Optab{ASALL, yshl, Px, [13]uint8{0xd1, 04, 0xc1, 04, 0xd3, 04, 0xd3, 04}}, - Optab{ASALW, yshl, Pe, [13]uint8{0xd1, 04, 0xc1, 04, 0xd3, 04, 0xd3, 04}}, - Optab{ASARB, yshb, Pb, [13]uint8{0xd0, 07, 0xc0, 07, 0xd2, 07}}, - Optab{ASARL, yshl, Px, [13]uint8{0xd1, 07, 0xc1, 07, 0xd3, 07, 0xd3, 07}}, - Optab{ASARW, yshl, Pe, [13]uint8{0xd1, 07, 0xc1, 07, 0xd3, 07, 0xd3, 07}}, - Optab{ASBBB, yxorb, Pb, [13]uint8{0x1c, 0x80, 03, 0x18, 0x1a}}, - Optab{ASBBL, yxorl, Px, [13]uint8{0x83, 03, 0x1d, 0x81, 03, 0x19, 0x1b}}, - Optab{ASBBW, yxorl, Pe, [13]uint8{0x83, 03, 0x1d, 0x81, 03, 0x19, 0x1b}}, - Optab{ASCASB, ynone, Pb, [13]uint8{0xae}}, - Optab{ASCASL, ynone, Px, [13]uint8{0xaf}}, - Optab{ASCASW, ynone, Pe, [13]uint8{0xaf}}, - Optab{ASETCC, yscond, Pm, [13]uint8{0x93, 00}}, - Optab{ASETCS, yscond, Pm, [13]uint8{0x92, 00}}, - Optab{ASETEQ, yscond, Pm, [13]uint8{0x94, 00}}, - Optab{ASETGE, yscond, Pm, [13]uint8{0x9d, 00}}, - Optab{ASETGT, yscond, Pm, [13]uint8{0x9f, 00}}, - Optab{ASETHI, yscond, Pm, [13]uint8{0x97, 00}}, - Optab{ASETLE, yscond, Pm, [13]uint8{0x9e, 00}}, - Optab{ASETLS, yscond, Pm, [13]uint8{0x96, 00}}, - Optab{ASETLT, yscond, Pm, [13]uint8{0x9c, 00}}, - Optab{ASETMI, yscond, Pm, [13]uint8{0x98, 00}}, - Optab{ASETNE, yscond, Pm, [13]uint8{0x95, 00}}, - Optab{ASETOC, yscond, Pm, [13]uint8{0x91, 00}}, - Optab{ASETOS, yscond, Pm, [13]uint8{0x90, 00}}, - Optab{ASETPC, yscond, Pm, [13]uint8{0x9b, 00}}, - Optab{ASETPL, yscond, Pm, [13]uint8{0x99, 00}}, - Optab{ASETPS, yscond, Pm, [13]uint8{0x9a, 00}}, - Optab{ACDQ, ynone, Px, [13]uint8{0x99}}, - Optab{ACWD, ynone, Pe, [13]uint8{0x99}}, - Optab{ASHLB, yshb, Pb, [13]uint8{0xd0, 04, 0xc0, 04, 0xd2, 04}}, - Optab{ASHLL, yshl, Px, [13]uint8{0xd1, 04, 0xc1, 04, 0xd3, 04, 0xd3, 04}}, - Optab{ASHLW, yshl, Pe, [13]uint8{0xd1, 04, 0xc1, 04, 0xd3, 04, 0xd3, 04}}, - Optab{ASHRB, yshb, Pb, [13]uint8{0xd0, 05, 0xc0, 05, 0xd2, 05}}, - Optab{ASHRL, yshl, Px, [13]uint8{0xd1, 05, 0xc1, 05, 0xd3, 05, 0xd3, 05}}, - Optab{ASHRW, yshl, Pe, [13]uint8{0xd1, 05, 0xc1, 05, 0xd3, 05, 0xd3, 05}}, - Optab{ASTC, ynone, Px, [13]uint8{0xf9}}, - Optab{ASTD, ynone, Px, [13]uint8{0xfd}}, - Optab{ASTI, ynone, Px, [13]uint8{0xfb}}, - Optab{ASTOSB, ynone, Pb, [13]uint8{0xaa}}, - Optab{ASTOSL, ynone, Px, [13]uint8{0xab}}, - Optab{ASTOSW, ynone, Pe, [13]uint8{0xab}}, - Optab{ASUBB, yxorb, Pb, [13]uint8{0x2c, 0x80, 05, 0x28, 0x2a}}, - Optab{ASUBL, yaddl, Px, [13]uint8{0x83, 05, 0x2d, 0x81, 05, 0x29, 0x2b}}, - Optab{ASUBW, yaddl, Pe, [13]uint8{0x83, 05, 0x2d, 0x81, 05, 0x29, 0x2b}}, - Optab{ASYSCALL, ynone, Px, [13]uint8{0xcd, 100}}, - Optab{ATESTB, ytestb, Pb, [13]uint8{0xa8, 0xf6, 00, 0x84, 0x84}}, - Optab{ATESTL, ytestl, Px, [13]uint8{0xa9, 0xf7, 00, 0x85, 0x85}}, - Optab{ATESTW, ytestl, Pe, [13]uint8{0xa9, 0xf7, 00, 0x85, 0x85}}, - Optab{obj.ATEXT, ytext, Px, [13]uint8{}}, - Optab{AVERR, ydivl, Pm, [13]uint8{0x00, 04}}, - Optab{AVERW, ydivl, Pm, [13]uint8{0x00, 05}}, - Optab{AWAIT, ynone, Px, [13]uint8{0x9b}}, - Optab{AWORD, ybyte, Px, [13]uint8{2}}, - Optab{AXCHGB, yml_mb, Pb, [13]uint8{0x86, 0x86}}, - Optab{AXCHGL, yxchg, Px, [13]uint8{0x90, 0x90, 0x87, 0x87}}, - Optab{AXCHGW, yxchg, Pe, [13]uint8{0x90, 0x90, 0x87, 0x87}}, - Optab{AXLAT, ynone, Px, [13]uint8{0xd7}}, - Optab{AXORB, yxorb, Pb, [13]uint8{0x34, 0x80, 06, 0x30, 0x32}}, - Optab{AXORL, yxorl, Px, [13]uint8{0x83, 06, 0x35, 0x81, 06, 0x31, 0x33}}, - Optab{AXORW, yxorl, Pe, [13]uint8{0x83, 06, 0x35, 0x81, 06, 0x31, 0x33}}, - Optab{AFMOVB, yfmvx, Px, [13]uint8{0xdf, 04}}, - Optab{AFMOVBP, yfmvp, Px, [13]uint8{0xdf, 06}}, - Optab{AFMOVD, yfmvd, Px, [13]uint8{0xdd, 00, 0xdd, 02, 0xd9, 00, 0xdd, 02}}, - Optab{AFMOVDP, yfmvdp, Px, [13]uint8{0xdd, 03, 0xdd, 03}}, - Optab{AFMOVF, yfmvf, Px, [13]uint8{0xd9, 00, 0xd9, 02}}, - Optab{AFMOVFP, yfmvp, Px, [13]uint8{0xd9, 03}}, - Optab{AFMOVL, yfmvf, Px, [13]uint8{0xdb, 00, 0xdb, 02}}, - Optab{AFMOVLP, yfmvp, Px, [13]uint8{0xdb, 03}}, - Optab{AFMOVV, yfmvx, Px, [13]uint8{0xdf, 05}}, - Optab{AFMOVVP, yfmvp, Px, [13]uint8{0xdf, 07}}, - Optab{AFMOVW, yfmvf, Px, [13]uint8{0xdf, 00, 0xdf, 02}}, - Optab{AFMOVWP, yfmvp, Px, [13]uint8{0xdf, 03}}, - Optab{AFMOVX, yfmvx, Px, [13]uint8{0xdb, 05}}, - Optab{AFMOVXP, yfmvp, Px, [13]uint8{0xdb, 07}}, - Optab{AFCOMB, nil, 0, [13]uint8{}}, - Optab{AFCOMBP, nil, 0, [13]uint8{}}, - Optab{AFCOMD, yfadd, Px, [13]uint8{0xdc, 02, 0xd8, 02, 0xdc, 02}}, /* botch */ - Optab{AFCOMDP, yfadd, Px, [13]uint8{0xdc, 03, 0xd8, 03, 0xdc, 03}}, /* botch */ - Optab{AFCOMDPP, ycompp, Px, [13]uint8{0xde, 03}}, - Optab{AFCOMF, yfmvx, Px, [13]uint8{0xd8, 02}}, - Optab{AFCOMFP, yfmvx, Px, [13]uint8{0xd8, 03}}, - Optab{AFCOMI, yfmvx, Px, [13]uint8{0xdb, 06}}, - Optab{AFCOMIP, yfmvx, Px, [13]uint8{0xdf, 06}}, - Optab{AFCOML, yfmvx, Px, [13]uint8{0xda, 02}}, - Optab{AFCOMLP, yfmvx, Px, [13]uint8{0xda, 03}}, - Optab{AFCOMW, yfmvx, Px, [13]uint8{0xde, 02}}, - Optab{AFCOMWP, yfmvx, Px, [13]uint8{0xde, 03}}, - Optab{AFUCOM, ycompp, Px, [13]uint8{0xdd, 04}}, - Optab{AFUCOMI, ycompp, Px, [13]uint8{0xdb, 05}}, - Optab{AFUCOMIP, ycompp, Px, [13]uint8{0xdf, 05}}, - Optab{AFUCOMP, ycompp, Px, [13]uint8{0xdd, 05}}, - Optab{AFUCOMPP, ycompp, Px, [13]uint8{0xda, 13}}, - Optab{AFADDDP, yfaddp, Px, [13]uint8{0xde, 00}}, - Optab{AFADDW, yfmvx, Px, [13]uint8{0xde, 00}}, - Optab{AFADDL, yfmvx, Px, [13]uint8{0xda, 00}}, - Optab{AFADDF, yfmvx, Px, [13]uint8{0xd8, 00}}, - Optab{AFADDD, yfadd, Px, [13]uint8{0xdc, 00, 0xd8, 00, 0xdc, 00}}, - Optab{AFMULDP, yfaddp, Px, [13]uint8{0xde, 01}}, - Optab{AFMULW, yfmvx, Px, [13]uint8{0xde, 01}}, - Optab{AFMULL, yfmvx, Px, [13]uint8{0xda, 01}}, - Optab{AFMULF, yfmvx, Px, [13]uint8{0xd8, 01}}, - Optab{AFMULD, yfadd, Px, [13]uint8{0xdc, 01, 0xd8, 01, 0xdc, 01}}, - Optab{AFSUBDP, yfaddp, Px, [13]uint8{0xde, 05}}, - Optab{AFSUBW, yfmvx, Px, [13]uint8{0xde, 04}}, - Optab{AFSUBL, yfmvx, Px, [13]uint8{0xda, 04}}, - Optab{AFSUBF, yfmvx, Px, [13]uint8{0xd8, 04}}, - Optab{AFSUBD, yfadd, Px, [13]uint8{0xdc, 04, 0xd8, 04, 0xdc, 05}}, - Optab{AFSUBRDP, yfaddp, Px, [13]uint8{0xde, 04}}, - Optab{AFSUBRW, yfmvx, Px, [13]uint8{0xde, 05}}, - Optab{AFSUBRL, yfmvx, Px, [13]uint8{0xda, 05}}, - Optab{AFSUBRF, yfmvx, Px, [13]uint8{0xd8, 05}}, - Optab{AFSUBRD, yfadd, Px, [13]uint8{0xdc, 05, 0xd8, 05, 0xdc, 04}}, - Optab{AFDIVDP, yfaddp, Px, [13]uint8{0xde, 07}}, - Optab{AFDIVW, yfmvx, Px, [13]uint8{0xde, 06}}, - Optab{AFDIVL, yfmvx, Px, [13]uint8{0xda, 06}}, - Optab{AFDIVF, yfmvx, Px, [13]uint8{0xd8, 06}}, - Optab{AFDIVD, yfadd, Px, [13]uint8{0xdc, 06, 0xd8, 06, 0xdc, 07}}, - Optab{AFDIVRDP, yfaddp, Px, [13]uint8{0xde, 06}}, - Optab{AFDIVRW, yfmvx, Px, [13]uint8{0xde, 07}}, - Optab{AFDIVRL, yfmvx, Px, [13]uint8{0xda, 07}}, - Optab{AFDIVRF, yfmvx, Px, [13]uint8{0xd8, 07}}, - Optab{AFDIVRD, yfadd, Px, [13]uint8{0xdc, 07, 0xd8, 07, 0xdc, 06}}, - Optab{AFXCHD, yfxch, Px, [13]uint8{0xd9, 01, 0xd9, 01}}, - Optab{AFFREE, nil, 0, [13]uint8{}}, - Optab{AFLDCW, ystcw, Px, [13]uint8{0xd9, 05, 0xd9, 05}}, - Optab{AFLDENV, ystcw, Px, [13]uint8{0xd9, 04, 0xd9, 04}}, - Optab{AFRSTOR, ysvrs, Px, [13]uint8{0xdd, 04, 0xdd, 04}}, - Optab{AFSAVE, ysvrs, Px, [13]uint8{0xdd, 06, 0xdd, 06}}, - Optab{AFSTCW, ystcw, Px, [13]uint8{0xd9, 07, 0xd9, 07}}, - Optab{AFSTENV, ystcw, Px, [13]uint8{0xd9, 06, 0xd9, 06}}, - Optab{AFSTSW, ystsw, Px, [13]uint8{0xdd, 07, 0xdf, 0xe0}}, - Optab{AF2XM1, ynone, Px, [13]uint8{0xd9, 0xf0}}, - Optab{AFABS, ynone, Px, [13]uint8{0xd9, 0xe1}}, - Optab{AFCHS, ynone, Px, [13]uint8{0xd9, 0xe0}}, - Optab{AFCLEX, ynone, Px, [13]uint8{0xdb, 0xe2}}, - Optab{AFCOS, ynone, Px, [13]uint8{0xd9, 0xff}}, - Optab{AFDECSTP, ynone, Px, [13]uint8{0xd9, 0xf6}}, - Optab{AFINCSTP, ynone, Px, [13]uint8{0xd9, 0xf7}}, - Optab{AFINIT, ynone, Px, [13]uint8{0xdb, 0xe3}}, - Optab{AFLD1, ynone, Px, [13]uint8{0xd9, 0xe8}}, - Optab{AFLDL2E, ynone, Px, [13]uint8{0xd9, 0xea}}, - Optab{AFLDL2T, ynone, Px, [13]uint8{0xd9, 0xe9}}, - Optab{AFLDLG2, ynone, Px, [13]uint8{0xd9, 0xec}}, - Optab{AFLDLN2, ynone, Px, [13]uint8{0xd9, 0xed}}, - Optab{AFLDPI, ynone, Px, [13]uint8{0xd9, 0xeb}}, - Optab{AFLDZ, ynone, Px, [13]uint8{0xd9, 0xee}}, - Optab{AFNOP, ynone, Px, [13]uint8{0xd9, 0xd0}}, - Optab{AFPATAN, ynone, Px, [13]uint8{0xd9, 0xf3}}, - Optab{AFPREM, ynone, Px, [13]uint8{0xd9, 0xf8}}, - Optab{AFPREM1, ynone, Px, [13]uint8{0xd9, 0xf5}}, - Optab{AFPTAN, ynone, Px, [13]uint8{0xd9, 0xf2}}, - Optab{AFRNDINT, ynone, Px, [13]uint8{0xd9, 0xfc}}, - Optab{AFSCALE, ynone, Px, [13]uint8{0xd9, 0xfd}}, - Optab{AFSIN, ynone, Px, [13]uint8{0xd9, 0xfe}}, - Optab{AFSINCOS, ynone, Px, [13]uint8{0xd9, 0xfb}}, - Optab{AFSQRT, ynone, Px, [13]uint8{0xd9, 0xfa}}, - Optab{AFTST, ynone, Px, [13]uint8{0xd9, 0xe4}}, - Optab{AFXAM, ynone, Px, [13]uint8{0xd9, 0xe5}}, - Optab{AFXTRACT, ynone, Px, [13]uint8{0xd9, 0xf4}}, - Optab{AFYL2X, ynone, Px, [13]uint8{0xd9, 0xf1}}, - Optab{AFYL2XP1, ynone, Px, [13]uint8{0xd9, 0xf9}}, - Optab{obj.AEND, nil, 0, [13]uint8{}}, - Optab{ACMPXCHGB, yrb_mb, Pm, [13]uint8{0xb0}}, - Optab{ACMPXCHGL, yrl_ml, Pm, [13]uint8{0xb1}}, - Optab{ACMPXCHGW, yrl_ml, Pm, [13]uint8{0xb1}}, - Optab{ACMPXCHG8B, yscond, Pm, [13]uint8{0xc7, 01}}, // TODO(rsc): yscond is wrong here. - - Optab{ACPUID, ynone, Pm, [13]uint8{0xa2}}, - Optab{ARDTSC, ynone, Pm, [13]uint8{0x31}}, - Optab{AXADDB, yrb_mb, Pb, [13]uint8{0x0f, 0xc0}}, - Optab{AXADDL, yrl_ml, Pm, [13]uint8{0xc1}}, - Optab{AXADDW, yrl_ml, Pe, [13]uint8{0x0f, 0xc1}}, - Optab{ACMOVLCC, yml_rl, Pm, [13]uint8{0x43}}, - Optab{ACMOVLCS, yml_rl, Pm, [13]uint8{0x42}}, - Optab{ACMOVLEQ, yml_rl, Pm, [13]uint8{0x44}}, - Optab{ACMOVLGE, yml_rl, Pm, [13]uint8{0x4d}}, - Optab{ACMOVLGT, yml_rl, Pm, [13]uint8{0x4f}}, - Optab{ACMOVLHI, yml_rl, Pm, [13]uint8{0x47}}, - Optab{ACMOVLLE, yml_rl, Pm, [13]uint8{0x4e}}, - Optab{ACMOVLLS, yml_rl, Pm, [13]uint8{0x46}}, - Optab{ACMOVLLT, yml_rl, Pm, [13]uint8{0x4c}}, - Optab{ACMOVLMI, yml_rl, Pm, [13]uint8{0x48}}, - Optab{ACMOVLNE, yml_rl, Pm, [13]uint8{0x45}}, - Optab{ACMOVLOC, yml_rl, Pm, [13]uint8{0x41}}, - Optab{ACMOVLOS, yml_rl, Pm, [13]uint8{0x40}}, - Optab{ACMOVLPC, yml_rl, Pm, [13]uint8{0x4b}}, - Optab{ACMOVLPL, yml_rl, Pm, [13]uint8{0x49}}, - Optab{ACMOVLPS, yml_rl, Pm, [13]uint8{0x4a}}, - Optab{ACMOVWCC, yml_rl, Pq, [13]uint8{0x43}}, - Optab{ACMOVWCS, yml_rl, Pq, [13]uint8{0x42}}, - Optab{ACMOVWEQ, yml_rl, Pq, [13]uint8{0x44}}, - Optab{ACMOVWGE, yml_rl, Pq, [13]uint8{0x4d}}, - Optab{ACMOVWGT, yml_rl, Pq, [13]uint8{0x4f}}, - Optab{ACMOVWHI, yml_rl, Pq, [13]uint8{0x47}}, - Optab{ACMOVWLE, yml_rl, Pq, [13]uint8{0x4e}}, - Optab{ACMOVWLS, yml_rl, Pq, [13]uint8{0x46}}, - Optab{ACMOVWLT, yml_rl, Pq, [13]uint8{0x4c}}, - Optab{ACMOVWMI, yml_rl, Pq, [13]uint8{0x48}}, - Optab{ACMOVWNE, yml_rl, Pq, [13]uint8{0x45}}, - Optab{ACMOVWOC, yml_rl, Pq, [13]uint8{0x41}}, - Optab{ACMOVWOS, yml_rl, Pq, [13]uint8{0x40}}, - Optab{ACMOVWPC, yml_rl, Pq, [13]uint8{0x4b}}, - Optab{ACMOVWPL, yml_rl, Pq, [13]uint8{0x49}}, - Optab{ACMOVWPS, yml_rl, Pq, [13]uint8{0x4a}}, - Optab{AFCMOVCC, yfcmv, Px, [13]uint8{0xdb, 00}}, - Optab{AFCMOVCS, yfcmv, Px, [13]uint8{0xda, 00}}, - Optab{AFCMOVEQ, yfcmv, Px, [13]uint8{0xda, 01}}, - Optab{AFCMOVHI, yfcmv, Px, [13]uint8{0xdb, 02}}, - Optab{AFCMOVLS, yfcmv, Px, [13]uint8{0xda, 02}}, - Optab{AFCMOVNE, yfcmv, Px, [13]uint8{0xdb, 01}}, - Optab{AFCMOVNU, yfcmv, Px, [13]uint8{0xdb, 03}}, - Optab{AFCMOVUN, yfcmv, Px, [13]uint8{0xda, 03}}, - Optab{ALFENCE, ynone, Pm, [13]uint8{0xae, 0xe8}}, - Optab{AMFENCE, ynone, Pm, [13]uint8{0xae, 0xf0}}, - Optab{ASFENCE, ynone, Pm, [13]uint8{0xae, 0xf8}}, - Optab{AEMMS, ynone, Pm, [13]uint8{0x77}}, - Optab{APREFETCHT0, yprefetch, Pm, [13]uint8{0x18, 01}}, - Optab{APREFETCHT1, yprefetch, Pm, [13]uint8{0x18, 02}}, - Optab{APREFETCHT2, yprefetch, Pm, [13]uint8{0x18, 03}}, - Optab{APREFETCHNTA, yprefetch, Pm, [13]uint8{0x18, 00}}, - Optab{ABSWAPL, ybswap, Pm, [13]uint8{0xc8}}, - Optab{obj.AUNDEF, ynone, Px, [13]uint8{0x0f, 0x0b}}, - Optab{AADDPD, yxm, Pq, [13]uint8{0x58}}, - Optab{AADDPS, yxm, Pm, [13]uint8{0x58}}, - Optab{AADDSD, yxm, Pf2, [13]uint8{0x58}}, - Optab{AADDSS, yxm, Pf3, [13]uint8{0x58}}, - Optab{AANDNPD, yxm, Pq, [13]uint8{0x55}}, - Optab{AANDNPS, yxm, Pm, [13]uint8{0x55}}, - Optab{AANDPD, yxm, Pq, [13]uint8{0x54}}, - Optab{AANDPS, yxm, Pq, [13]uint8{0x54}}, - Optab{ACMPPD, yxcmpi, Px, [13]uint8{Pe, 0xc2}}, - Optab{ACMPPS, yxcmpi, Pm, [13]uint8{0xc2, 0}}, - Optab{ACMPSD, yxcmpi, Px, [13]uint8{Pf2, 0xc2}}, - Optab{ACMPSS, yxcmpi, Px, [13]uint8{Pf3, 0xc2}}, - Optab{ACOMISD, yxcmp, Pe, [13]uint8{0x2f}}, - Optab{ACOMISS, yxcmp, Pm, [13]uint8{0x2f}}, - Optab{ACVTPL2PD, yxcvm2, Px, [13]uint8{Pf3, 0xe6, Pe, 0x2a}}, - Optab{ACVTPL2PS, yxcvm2, Pm, [13]uint8{0x5b, 0, 0x2a, 0}}, - Optab{ACVTPD2PL, yxcvm1, Px, [13]uint8{Pf2, 0xe6, Pe, 0x2d}}, - Optab{ACVTPD2PS, yxm, Pe, [13]uint8{0x5a}}, - Optab{ACVTPS2PL, yxcvm1, Px, [13]uint8{Pe, 0x5b, Pm, 0x2d}}, - Optab{ACVTPS2PD, yxm, Pm, [13]uint8{0x5a}}, - Optab{ACVTSD2SL, yxcvfl, Pf2, [13]uint8{0x2d}}, - Optab{ACVTSD2SS, yxm, Pf2, [13]uint8{0x5a}}, - Optab{ACVTSL2SD, yxcvlf, Pf2, [13]uint8{0x2a}}, - Optab{ACVTSL2SS, yxcvlf, Pf3, [13]uint8{0x2a}}, - Optab{ACVTSS2SD, yxm, Pf3, [13]uint8{0x5a}}, - Optab{ACVTSS2SL, yxcvfl, Pf3, [13]uint8{0x2d}}, - Optab{ACVTTPD2PL, yxcvm1, Px, [13]uint8{Pe, 0xe6, Pe, 0x2c}}, - Optab{ACVTTPS2PL, yxcvm1, Px, [13]uint8{Pf3, 0x5b, Pm, 0x2c}}, - Optab{ACVTTSD2SL, yxcvfl, Pf2, [13]uint8{0x2c}}, - Optab{ACVTTSS2SL, yxcvfl, Pf3, [13]uint8{0x2c}}, - Optab{ADIVPD, yxm, Pe, [13]uint8{0x5e}}, - Optab{ADIVPS, yxm, Pm, [13]uint8{0x5e}}, - Optab{ADIVSD, yxm, Pf2, [13]uint8{0x5e}}, - Optab{ADIVSS, yxm, Pf3, [13]uint8{0x5e}}, - Optab{AMASKMOVOU, yxr, Pe, [13]uint8{0xf7}}, - Optab{AMAXPD, yxm, Pe, [13]uint8{0x5f}}, - Optab{AMAXPS, yxm, Pm, [13]uint8{0x5f}}, - Optab{AMAXSD, yxm, Pf2, [13]uint8{0x5f}}, - Optab{AMAXSS, yxm, Pf3, [13]uint8{0x5f}}, - Optab{AMINPD, yxm, Pe, [13]uint8{0x5d}}, - Optab{AMINPS, yxm, Pm, [13]uint8{0x5d}}, - Optab{AMINSD, yxm, Pf2, [13]uint8{0x5d}}, - Optab{AMINSS, yxm, Pf3, [13]uint8{0x5d}}, - Optab{AMOVAPD, yxmov, Pe, [13]uint8{0x28, 0x29}}, - Optab{AMOVAPS, yxmov, Pm, [13]uint8{0x28, 0x29}}, - Optab{AMOVO, yxmov, Pe, [13]uint8{0x6f, 0x7f}}, - Optab{AMOVOU, yxmov, Pf3, [13]uint8{0x6f, 0x7f}}, - Optab{AMOVHLPS, yxr, Pm, [13]uint8{0x12}}, - Optab{AMOVHPD, yxmov, Pe, [13]uint8{0x16, 0x17}}, - Optab{AMOVHPS, yxmov, Pm, [13]uint8{0x16, 0x17}}, - Optab{AMOVLHPS, yxr, Pm, [13]uint8{0x16}}, - Optab{AMOVLPD, yxmov, Pe, [13]uint8{0x12, 0x13}}, - Optab{AMOVLPS, yxmov, Pm, [13]uint8{0x12, 0x13}}, - Optab{AMOVMSKPD, yxrrl, Pq, [13]uint8{0x50}}, - Optab{AMOVMSKPS, yxrrl, Pm, [13]uint8{0x50}}, - Optab{AMOVNTO, yxr_ml, Pe, [13]uint8{0xe7}}, - Optab{AMOVNTPD, yxr_ml, Pe, [13]uint8{0x2b}}, - Optab{AMOVNTPS, yxr_ml, Pm, [13]uint8{0x2b}}, - Optab{AMOVSD, yxmov, Pf2, [13]uint8{0x10, 0x11}}, - Optab{AMOVSS, yxmov, Pf3, [13]uint8{0x10, 0x11}}, - Optab{AMOVUPD, yxmov, Pe, [13]uint8{0x10, 0x11}}, - Optab{AMOVUPS, yxmov, Pm, [13]uint8{0x10, 0x11}}, - Optab{AMULPD, yxm, Pe, [13]uint8{0x59}}, - Optab{AMULPS, yxm, Ym, [13]uint8{0x59}}, - Optab{AMULSD, yxm, Pf2, [13]uint8{0x59}}, - Optab{AMULSS, yxm, Pf3, [13]uint8{0x59}}, - Optab{AORPD, yxm, Pq, [13]uint8{0x56}}, - Optab{AORPS, yxm, Pm, [13]uint8{0x56}}, - Optab{APADDQ, yxm, Pe, [13]uint8{0xd4}}, - Optab{APAND, yxm, Pe, [13]uint8{0xdb}}, - Optab{APCMPEQB, yxmq, Pe, [13]uint8{0x74}}, - Optab{APMAXSW, yxm, Pe, [13]uint8{0xee}}, - Optab{APMAXUB, yxm, Pe, [13]uint8{0xde}}, - Optab{APMINSW, yxm, Pe, [13]uint8{0xea}}, - Optab{APMINUB, yxm, Pe, [13]uint8{0xda}}, - Optab{APMOVMSKB, ymskb, Px, [13]uint8{Pe, 0xd7, 0xd7}}, - Optab{APSADBW, yxm, Pq, [13]uint8{0xf6}}, - Optab{APSUBB, yxm, Pe, [13]uint8{0xf8}}, - Optab{APSUBL, yxm, Pe, [13]uint8{0xfa}}, - Optab{APSUBQ, yxm, Pe, [13]uint8{0xfb}}, - Optab{APSUBSB, yxm, Pe, [13]uint8{0xe8}}, - Optab{APSUBSW, yxm, Pe, [13]uint8{0xe9}}, - Optab{APSUBUSB, yxm, Pe, [13]uint8{0xd8}}, - Optab{APSUBUSW, yxm, Pe, [13]uint8{0xd9}}, - Optab{APSUBW, yxm, Pe, [13]uint8{0xf9}}, - Optab{APUNPCKHQDQ, yxm, Pe, [13]uint8{0x6d}}, - Optab{APUNPCKLQDQ, yxm, Pe, [13]uint8{0x6c}}, - Optab{APXOR, yxm, Pe, [13]uint8{0xef}}, - Optab{ARCPPS, yxm, Pm, [13]uint8{0x53}}, - Optab{ARCPSS, yxm, Pf3, [13]uint8{0x53}}, - Optab{ARSQRTPS, yxm, Pm, [13]uint8{0x52}}, - Optab{ARSQRTSS, yxm, Pf3, [13]uint8{0x52}}, - Optab{ASQRTPD, yxm, Pe, [13]uint8{0x51}}, - Optab{ASQRTPS, yxm, Pm, [13]uint8{0x51}}, - Optab{ASQRTSD, yxm, Pf2, [13]uint8{0x51}}, - Optab{ASQRTSS, yxm, Pf3, [13]uint8{0x51}}, - Optab{ASUBPD, yxm, Pe, [13]uint8{0x5c}}, - Optab{ASUBPS, yxm, Pm, [13]uint8{0x5c}}, - Optab{ASUBSD, yxm, Pf2, [13]uint8{0x5c}}, - Optab{ASUBSS, yxm, Pf3, [13]uint8{0x5c}}, - Optab{AUCOMISD, yxcmp, Pe, [13]uint8{0x2e}}, - Optab{AUCOMISS, yxcmp, Pm, [13]uint8{0x2e}}, - Optab{AUNPCKHPD, yxm, Pe, [13]uint8{0x15}}, - Optab{AUNPCKHPS, yxm, Pm, [13]uint8{0x15}}, - Optab{AUNPCKLPD, yxm, Pe, [13]uint8{0x14}}, - Optab{AUNPCKLPS, yxm, Pm, [13]uint8{0x14}}, - Optab{AXORPD, yxm, Pe, [13]uint8{0x57}}, - Optab{AXORPS, yxm, Pm, [13]uint8{0x57}}, - Optab{APSHUFHW, yxshuf, Pf3, [13]uint8{0x70, 00}}, - Optab{APSHUFL, yxshuf, Pq, [13]uint8{0x70, 00}}, - Optab{APSHUFLW, yxshuf, Pf2, [13]uint8{0x70, 00}}, - Optab{AAESENC, yaes, Pq, [13]uint8{0x38, 0xdc, 0}}, - Optab{APINSRD, yinsrd, Pq, [13]uint8{0x3a, 0x22, 00}}, - Optab{APSHUFB, ymshufb, Pq, [13]uint8{0x38, 0x00}}, - Optab{obj.AUSEFIELD, ynop, Px, [13]uint8{0, 0}}, - Optab{obj.ATYPE, nil, 0, [13]uint8{}}, - Optab{obj.AFUNCDATA, yfuncdata, Px, [13]uint8{0, 0}}, - Optab{obj.APCDATA, ypcdata, Px, [13]uint8{0, 0}}, - Optab{obj.ACHECKNIL, nil, 0, [13]uint8{}}, - Optab{obj.AVARDEF, nil, 0, [13]uint8{}}, - Optab{obj.AVARKILL, nil, 0, [13]uint8{}}, - Optab{obj.ADUFFCOPY, yduff, Px, [13]uint8{0xe8}}, - Optab{obj.ADUFFZERO, yduff, Px, [13]uint8{0xe8}}, - Optab{0, nil, 0, [13]uint8{}}, -} - -// single-instruction no-ops of various lengths. -// constructed by hand and disassembled with gdb to verify. -// see http://www.agner.org/optimize/optimizing_assembly.pdf for discussion. -var nop = [][16]uint8{ - [16]uint8{0x90}, - [16]uint8{0x66, 0x90}, - [16]uint8{0x0F, 0x1F, 0x00}, - [16]uint8{0x0F, 0x1F, 0x40, 0x00}, - [16]uint8{0x0F, 0x1F, 0x44, 0x00, 0x00}, - [16]uint8{0x66, 0x0F, 0x1F, 0x44, 0x00, 0x00}, - [16]uint8{0x0F, 0x1F, 0x80, 0x00, 0x00, 0x00, 0x00}, - [16]uint8{0x0F, 0x1F, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00}, - [16]uint8{0x66, 0x0F, 0x1F, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00}, -} - -// Native Client rejects the repeated 0x66 prefix. -// {0x66, 0x66, 0x0F, 0x1F, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00}, -func fillnop(p []byte, n int) { - var m int - - for n > 0 { - m = n - if m > len(nop) { - m = len(nop) - } - copy(p[:m], nop[m-1][:m]) - p = p[m:] - n -= m - } -} - -func naclpad(ctxt *obj.Link, s *obj.LSym, c int32, pad int32) int32 { - obj.Symgrow(ctxt, s, int64(c)+int64(pad)) - fillnop(s.P[c:], int(pad)) - return c + pad -} - -func span8(ctxt *obj.Link, s *obj.LSym) { - ctxt.Cursym = s - - if s.Text == nil || s.Text.Link == nil { - return - } - - if ycover[0] == 0 { - instinit() - } - - var v int32 - for p := s.Text; p != nil; p = p.Link { - if p.To.Type == obj.TYPE_BRANCH { - if p.Pcond == nil { - p.Pcond = p - } - } - if p.As == AADJSP { - p.To.Type = obj.TYPE_REG - p.To.Reg = REG_SP - v = int32(-p.From.Offset) - p.From.Offset = int64(v) - p.As = AADDL - if v < 0 { - p.As = ASUBL - v = -v - p.From.Offset = int64(v) - } - - if v == 0 { - p.As = obj.ANOP - } - } - } - - var q *obj.Prog - for p := s.Text; p != nil; p = p.Link { - p.Back = 2 // use short branches first time through - q = p.Pcond - if q != nil && (q.Back&2 != 0) { - p.Back |= 1 // backward jump - } - - if p.As == AADJSP { - p.To.Type = obj.TYPE_REG - p.To.Reg = REG_SP - v = int32(-p.From.Offset) - p.From.Offset = int64(v) - p.As = AADDL - if v < 0 { - p.As = ASUBL - v = -v - p.From.Offset = int64(v) - } - - if v == 0 { - p.As = obj.ANOP - } - } - } - - n := 0 - var bp []byte - var c int32 - var i int - var loop int32 - var m int - var p *obj.Prog - for { - loop = 0 - for i = 0; i < len(s.R); i++ { - s.R[i] = obj.Reloc{} - } - s.R = s.R[:0] - s.P = s.P[:0] - c = 0 - for p = s.Text; p != nil; p = p.Link { - if ctxt.Headtype == obj.Hnacl && p.Isize > 0 { - var deferreturn *obj.LSym - - if deferreturn == nil { - deferreturn = obj.Linklookup(ctxt, "runtime.deferreturn", 0) - } - - // pad everything to avoid crossing 32-byte boundary - if c>>5 != (c+int32(p.Isize)-1)>>5 { - c = naclpad(ctxt, s, c, -c&31) - } - - // pad call deferreturn to start at 32-byte boundary - // so that subtracting 5 in jmpdefer will jump back - // to that boundary and rerun the call. - if p.As == obj.ACALL && p.To.Sym == deferreturn { - c = naclpad(ctxt, s, c, -c&31) - } - - // pad call to end at 32-byte boundary - if p.As == obj.ACALL { - c = naclpad(ctxt, s, c, -(c+int32(p.Isize))&31) - } - - // the linker treats REP and STOSQ as different instructions - // but in fact the REP is a prefix on the STOSQ. - // make sure REP has room for 2 more bytes, so that - // padding will not be inserted before the next instruction. - if p.As == AREP && c>>5 != (c+3-1)>>5 { - c = naclpad(ctxt, s, c, -c&31) - } - - // same for LOCK. - // various instructions follow; the longest is 4 bytes. - // give ourselves 8 bytes so as to avoid surprises. - if p.As == ALOCK && c>>5 != (c+8-1)>>5 { - c = naclpad(ctxt, s, c, -c&31) - } - } - - p.Pc = int64(c) - - // process forward jumps to p - for q = p.Comefrom; q != nil; q = q.Forwd { - v = int32(p.Pc - (q.Pc + int64(q.Mark))) - if q.Back&2 != 0 { // short - if v > 127 { - loop++ - q.Back ^= 2 - } - - if q.As == AJCXZW { - s.P[q.Pc+2] = byte(v) - } else { - s.P[q.Pc+1] = byte(v) - } - } else { - bp = s.P[q.Pc+int64(q.Mark)-4:] - bp[0] = byte(v) - bp = bp[1:] - bp[0] = byte(v >> 8) - bp = bp[1:] - bp[0] = byte(v >> 16) - bp = bp[1:] - bp[0] = byte(v >> 24) - } - } - - p.Comefrom = nil - - p.Pc = int64(c) - asmins(ctxt, p) - m = -cap(ctxt.Andptr) + cap(ctxt.And[:]) - if int(p.Isize) != m { - p.Isize = uint8(m) - loop++ - } - - obj.Symgrow(ctxt, s, p.Pc+int64(m)) - copy(s.P[p.Pc:][:m], ctxt.And[:m]) - p.Mark = uint16(m) - c += int32(m) - } - - n++ - if n > 20 { - ctxt.Diag("span must be looping") - log.Fatalf("bad code") - } - if loop == 0 { - break - } - } - - if ctxt.Headtype == obj.Hnacl { - c = naclpad(ctxt, s, c, -c&31) - } - c += -c & (FuncAlign - 1) - s.Size = int64(c) - - if false { /* debug['a'] > 1 */ - fmt.Printf("span1 %s %d (%d tries)\n %.6x", s.Name, s.Size, n, 0) - var i int - for i = 0; i < len(s.P); i++ { - fmt.Printf(" %.2x", s.P[i]) - if i%16 == 15 { - fmt.Printf("\n %.6x", uint(i+1)) - } - } - - if i%16 != 0 { - fmt.Printf("\n") - } - - for i := 0; i < len(s.R); i++ { - r := &s.R[i] - fmt.Printf(" rel %#.4x/%d %s%+d\n", uint32(r.Off), r.Siz, r.Sym.Name, r.Add) - } - } -} - -func instinit() { - - for i := 1; optab[i].as != 0; i++ { - c := optab[i].as & obj.AMask - if opindex[c] != nil { - log.Fatalf("phase error in optab: %d (%v)", i, obj.Aconv(int(optab[i].as))) - } - opindex[c] = &optab[i] - } - - for i := 0; i < Ymax; i++ { - ycover[i*Ymax+i] = 1 - } - - ycover[Yi0*Ymax+Yi8] = 1 - ycover[Yi1*Ymax+Yi8] = 1 - - ycover[Yi0*Ymax+Yi32] = 1 - ycover[Yi1*Ymax+Yi32] = 1 - ycover[Yi8*Ymax+Yi32] = 1 - - ycover[Yal*Ymax+Yrb] = 1 - ycover[Ycl*Ymax+Yrb] = 1 - ycover[Yax*Ymax+Yrb] = 1 - ycover[Ycx*Ymax+Yrb] = 1 - ycover[Yrx*Ymax+Yrb] = 1 - - ycover[Yax*Ymax+Yrx] = 1 - ycover[Ycx*Ymax+Yrx] = 1 - - ycover[Yax*Ymax+Yrl] = 1 - ycover[Ycx*Ymax+Yrl] = 1 - ycover[Yrx*Ymax+Yrl] = 1 - - ycover[Yf0*Ymax+Yrf] = 1 - - ycover[Yal*Ymax+Ymb] = 1 - ycover[Ycl*Ymax+Ymb] = 1 - ycover[Yax*Ymax+Ymb] = 1 - ycover[Ycx*Ymax+Ymb] = 1 - ycover[Yrx*Ymax+Ymb] = 1 - ycover[Yrb*Ymax+Ymb] = 1 - ycover[Ym*Ymax+Ymb] = 1 - - ycover[Yax*Ymax+Yml] = 1 - ycover[Ycx*Ymax+Yml] = 1 - ycover[Yrx*Ymax+Yml] = 1 - ycover[Yrl*Ymax+Yml] = 1 - ycover[Ym*Ymax+Yml] = 1 - - ycover[Yax*Ymax+Ymm] = 1 - ycover[Ycx*Ymax+Ymm] = 1 - ycover[Yrx*Ymax+Ymm] = 1 - ycover[Yrl*Ymax+Ymm] = 1 - ycover[Ym*Ymax+Ymm] = 1 - ycover[Ymr*Ymax+Ymm] = 1 - - ycover[Ym*Ymax+Yxm] = 1 - ycover[Yxr*Ymax+Yxm] = 1 - - for i := 0; i < MAXREG; i++ { - reg[i] = -1 - if i >= REG_AL && i <= REG_BH { - reg[i] = (i - REG_AL) & 7 - } - if i >= REG_AX && i <= REG_DI { - reg[i] = (i - REG_AX) & 7 - } - if i >= REG_F0 && i <= REG_F0+7 { - reg[i] = (i - REG_F0) & 7 - } - if i >= REG_X0 && i <= REG_X0+7 { - reg[i] = (i - REG_X0) & 7 - } - } -} - -func prefixof(ctxt *obj.Link, a *obj.Addr) int { - if a.Type == obj.TYPE_MEM && a.Name == obj.NAME_NONE { - switch a.Reg { - case REG_CS: - return 0x2e - - case REG_DS: - return 0x3e - - case REG_ES: - return 0x26 - - case REG_FS: - return 0x64 - - case REG_GS: - return 0x65 - - // NOTE: Systems listed here should be only systems that - // support direct TLS references like 8(TLS) implemented as - // direct references from FS or GS. Systems that require - // the initial-exec model, where you load the TLS base into - // a register and then index from that register, do not reach - // this code and should not be listed. - case REG_TLS: - switch ctxt.Headtype { - default: - log.Fatalf("unknown TLS base register for %s", obj.Headstr(ctxt.Headtype)) - - case obj.Hdarwin, - obj.Hdragonfly, - obj.Hfreebsd, - obj.Hnetbsd, - obj.Hopenbsd: - return 0x65 // GS - } - } - } - - return 0 -} - -func oclass(ctxt *obj.Link, p *obj.Prog, a *obj.Addr) int { - // 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 and remove. - if (a.Type == obj.TYPE_CONST || a.Type == obj.TYPE_REG) && a.Index != REG_NONE && a.Scale == 0 { - return Ycol - } - - switch a.Type { - case obj.TYPE_NONE: - return Ynone - - case obj.TYPE_BRANCH: - return Ybr - - // TODO(rsc): Why this is also Ycol is a mystery. Should split the two meanings. - case obj.TYPE_INDIR: - if a.Name != obj.NAME_NONE && a.Reg == REG_NONE && a.Index == REG_NONE && a.Scale == 0 { - return Ycol - } - return Yxxx - - case obj.TYPE_MEM: - return Ym - - case obj.TYPE_ADDR: - switch a.Name { - case obj.NAME_EXTERN, - obj.NAME_STATIC: - return Yi32 - - case obj.NAME_AUTO, - obj.NAME_PARAM: - return Yiauto - } - - // DUFFZERO/DUFFCOPY encoding forgot to set a->index - // and got Yi32 in an earlier version of this code. - // Keep doing that until we fix yduff etc. - if a.Sym != nil && strings.HasPrefix(a.Sym.Name, "runtime.duff") { - return Yi32 - } - - if a.Sym != nil || a.Name != obj.NAME_NONE { - ctxt.Diag("unexpected addr: %v", obj.Dconv(p, a)) - } - fallthrough - - // fall through - - case obj.TYPE_CONST: - if a.Sym != nil { - ctxt.Diag("TYPE_CONST with symbol: %v", obj.Dconv(p, a)) - } - - v := int32(a.Offset) - if v == 0 { - return Yi0 - } - if v == 1 { - return Yi1 - } - if v >= -128 && v <= 127 { - return Yi8 - } - return Yi32 - - case obj.TYPE_TEXTSIZE: - return Ytextsize - } - - if a.Type != obj.TYPE_REG { - ctxt.Diag("unexpected addr1: type=%d %v", a.Type, obj.Dconv(p, a)) - return Yxxx - } - - switch a.Reg { - case REG_AL: - return Yal - - case REG_AX: - return Yax - - case REG_CL, - REG_DL, - REG_BL, - REG_AH, - REG_CH, - REG_DH, - REG_BH: - return Yrb - - case REG_CX: - return Ycx - - case REG_DX, - REG_BX: - return Yrx - - case REG_SP, - REG_BP, - REG_SI, - REG_DI: - return Yrl - - case REG_F0 + 0: - return Yf0 - - case REG_F0 + 1, - REG_F0 + 2, - REG_F0 + 3, - REG_F0 + 4, - REG_F0 + 5, - REG_F0 + 6, - REG_F0 + 7: - return Yrf - - case REG_X0 + 0, - REG_X0 + 1, - REG_X0 + 2, - REG_X0 + 3, - REG_X0 + 4, - REG_X0 + 5, - REG_X0 + 6, - REG_X0 + 7: - return Yxr - - case REG_CS: - return Ycs - case REG_SS: - return Yss - case REG_DS: - return Yds - case REG_ES: - return Yes - case REG_FS: - return Yfs - case REG_GS: - return Ygs - case REG_TLS: - return Ytls - - case REG_GDTR: - return Ygdtr - case REG_IDTR: - return Yidtr - case REG_LDTR: - return Yldtr - case REG_MSW: - return Ymsw - case REG_TASK: - return Ytask - - case REG_CR + 0: - return Ycr0 - case REG_CR + 1: - return Ycr1 - case REG_CR + 2: - return Ycr2 - case REG_CR + 3: - return Ycr3 - case REG_CR + 4: - return Ycr4 - case REG_CR + 5: - return Ycr5 - case REG_CR + 6: - return Ycr6 - case REG_CR + 7: - return Ycr7 - - case REG_DR + 0: - return Ydr0 - case REG_DR + 1: - return Ydr1 - case REG_DR + 2: - return Ydr2 - case REG_DR + 3: - return Ydr3 - case REG_DR + 4: - return Ydr4 - case REG_DR + 5: - return Ydr5 - case REG_DR + 6: - return Ydr6 - case REG_DR + 7: - return Ydr7 - - case REG_TR + 0: - return Ytr0 - case REG_TR + 1: - return Ytr1 - case REG_TR + 2: - return Ytr2 - case REG_TR + 3: - return Ytr3 - case REG_TR + 4: - return Ytr4 - case REG_TR + 5: - return Ytr5 - case REG_TR + 6: - return Ytr6 - case REG_TR + 7: - return Ytr7 - } - - return Yxxx -} - -func asmidx(ctxt *obj.Link, scale int, index int, base int) { - var i int - - switch index { - default: - goto bad - - case obj.TYPE_NONE: - i = 4 << 3 - goto bas - - case REG_AX, - REG_CX, - REG_DX, - REG_BX, - REG_BP, - REG_SI, - REG_DI: - i = reg[index] << 3 - } - - switch scale { - default: - goto bad - - case 1: - break - - case 2: - i |= 1 << 6 - - case 4: - i |= 2 << 6 - - case 8: - i |= 3 << 6 - } - -bas: - switch base { - default: - goto bad - - case REG_NONE: /* must be mod=00 */ - i |= 5 - - case REG_AX, - REG_CX, - REG_DX, - REG_BX, - REG_SP, - REG_BP, - REG_SI, - REG_DI: - i |= reg[base] - } - - ctxt.Andptr[0] = byte(i) - ctxt.Andptr = ctxt.Andptr[1:] - return - -bad: - ctxt.Diag("asmidx: bad address %d,%d,%d", scale, index, base) - ctxt.Andptr[0] = 0 - ctxt.Andptr = ctxt.Andptr[1:] - return -} - -func put4(ctxt *obj.Link, v int32) { - ctxt.Andptr[0] = byte(v) - ctxt.Andptr[1] = byte(v >> 8) - ctxt.Andptr[2] = byte(v >> 16) - ctxt.Andptr[3] = byte(v >> 24) - ctxt.Andptr = ctxt.Andptr[4:] -} - -func relput4(ctxt *obj.Link, p *obj.Prog, a *obj.Addr) { - var rel obj.Reloc - - v := int64(vaddr(ctxt, p, a, &rel)) - if rel.Siz != 0 { - if rel.Siz != 4 { - ctxt.Diag("bad reloc") - } - r := obj.Addrel(ctxt.Cursym) - *r = rel - r.Off = int32(p.Pc + int64(-cap(ctxt.Andptr)+cap(ctxt.And[:]))) - } - - put4(ctxt, int32(v)) -} - -func vaddr(ctxt *obj.Link, p *obj.Prog, a *obj.Addr, r *obj.Reloc) int32 { - if r != nil { - *r = obj.Reloc{} - } - - switch a.Name { - case obj.NAME_STATIC, - obj.NAME_EXTERN: - s := a.Sym - if s != nil { - if r == nil { - ctxt.Diag("need reloc for %v", obj.Dconv(p, a)) - log.Fatalf("bad code") - } - - r.Type = obj.R_ADDR - r.Siz = 4 - r.Off = -1 - r.Sym = s - r.Add = a.Offset - return 0 - } - - return int32(a.Offset) - } - - if (a.Type == obj.TYPE_MEM || a.Type == obj.TYPE_ADDR) && a.Reg == REG_TLS { - if r == nil { - ctxt.Diag("need reloc for %v", obj.Dconv(p, a)) - log.Fatalf("bad code") - } - - r.Type = obj.R_TLS_LE - r.Siz = 4 - r.Off = -1 // caller must fill in - r.Add = a.Offset - return 0 - } - - return int32(a.Offset) -} - -func asmand(ctxt *obj.Link, p *obj.Prog, a *obj.Addr, r int) { - var base int - var rel obj.Reloc - - v := int32(a.Offset) - rel.Siz = 0 - - switch a.Type { - case obj.TYPE_ADDR: - if a.Name == obj.NAME_NONE { - ctxt.Diag("unexpected TYPE_ADDR with NAME_NONE") - } - if a.Index == REG_TLS { - ctxt.Diag("unexpected TYPE_ADDR with index==REG_TLS") - } - goto bad - - case obj.TYPE_REG: - if (a.Reg < REG_AL || REG_F7 < a.Reg) && (a.Reg < REG_X0 || REG_X0+7 < a.Reg) { - goto bad - } - if v != 0 { - goto bad - } - ctxt.Andptr[0] = byte(3<<6 | reg[a.Reg]<<0 | r<<3) - ctxt.Andptr = ctxt.Andptr[1:] - return - } - - if a.Type != obj.TYPE_MEM { - goto bad - } - - if a.Index != REG_NONE && a.Index != REG_TLS { - base := int(a.Reg) - switch a.Name { - case obj.NAME_EXTERN, - obj.NAME_STATIC: - base = REG_NONE - v = vaddr(ctxt, p, a, &rel) - - case obj.NAME_AUTO, - obj.NAME_PARAM: - base = REG_SP - } - - if base == REG_NONE { - ctxt.Andptr[0] = byte(0<<6 | 4<<0 | r<<3) - ctxt.Andptr = ctxt.Andptr[1:] - asmidx(ctxt, int(a.Scale), int(a.Index), base) - goto putrelv - } - - if v == 0 && rel.Siz == 0 && base != REG_BP { - ctxt.Andptr[0] = byte(0<<6 | 4<<0 | r<<3) - ctxt.Andptr = ctxt.Andptr[1:] - asmidx(ctxt, int(a.Scale), int(a.Index), base) - return - } - - if v >= -128 && v < 128 && rel.Siz == 0 { - ctxt.Andptr[0] = byte(1<<6 | 4<<0 | r<<3) - ctxt.Andptr = ctxt.Andptr[1:] - asmidx(ctxt, int(a.Scale), int(a.Index), base) - ctxt.Andptr[0] = byte(v) - ctxt.Andptr = ctxt.Andptr[1:] - return - } - - ctxt.Andptr[0] = byte(2<<6 | 4<<0 | r<<3) - ctxt.Andptr = ctxt.Andptr[1:] - asmidx(ctxt, int(a.Scale), int(a.Index), base) - goto putrelv - } - - base = int(a.Reg) - switch a.Name { - case obj.NAME_STATIC, - obj.NAME_EXTERN: - base = REG_NONE - v = vaddr(ctxt, p, a, &rel) - - case obj.NAME_AUTO, - obj.NAME_PARAM: - base = REG_SP - } - - if base == REG_TLS { - v = vaddr(ctxt, p, a, &rel) - } - - if base == REG_NONE || (REG_CS <= base && base <= REG_GS) || base == REG_TLS { - ctxt.Andptr[0] = byte(0<<6 | 5<<0 | r<<3) - ctxt.Andptr = ctxt.Andptr[1:] - goto putrelv - } - - if base == REG_SP { - if v == 0 && rel.Siz == 0 { - ctxt.Andptr[0] = byte(0<<6 | 4<<0 | r<<3) - ctxt.Andptr = ctxt.Andptr[1:] - asmidx(ctxt, int(a.Scale), REG_NONE, base) - return - } - - if v >= -128 && v < 128 && rel.Siz == 0 { - ctxt.Andptr[0] = byte(1<<6 | 4<<0 | r<<3) - ctxt.Andptr = ctxt.Andptr[1:] - asmidx(ctxt, int(a.Scale), REG_NONE, base) - ctxt.Andptr[0] = byte(v) - ctxt.Andptr = ctxt.Andptr[1:] - return - } - - ctxt.Andptr[0] = byte(2<<6 | 4<<0 | r<<3) - ctxt.Andptr = ctxt.Andptr[1:] - asmidx(ctxt, int(a.Scale), REG_NONE, base) - goto putrelv - } - - if REG_AX <= base && base <= REG_DI { - if a.Index == REG_TLS { - rel = obj.Reloc{} - rel.Type = obj.R_TLS_IE - rel.Siz = 4 - rel.Sym = nil - rel.Add = int64(v) - v = 0 - } - - if v == 0 && rel.Siz == 0 && base != REG_BP { - ctxt.Andptr[0] = byte(0<<6 | reg[base]<<0 | r<<3) - ctxt.Andptr = ctxt.Andptr[1:] - return - } - - if v >= -128 && v < 128 && rel.Siz == 0 { - ctxt.Andptr[0] = byte(1<<6 | reg[base]<<0 | r<<3) - ctxt.Andptr[1] = byte(v) - ctxt.Andptr = ctxt.Andptr[2:] - return - } - - ctxt.Andptr[0] = byte(2<<6 | reg[base]<<0 | r<<3) - ctxt.Andptr = ctxt.Andptr[1:] - goto putrelv - } - - goto bad - -putrelv: - if rel.Siz != 0 { - if rel.Siz != 4 { - ctxt.Diag("bad rel") - goto bad - } - - r := obj.Addrel(ctxt.Cursym) - *r = rel - r.Off = int32(ctxt.Curp.Pc + int64(-cap(ctxt.Andptr)+cap(ctxt.And[:]))) - } - - put4(ctxt, v) - return - -bad: - ctxt.Diag("asmand: bad address %v", obj.Dconv(p, a)) - return -} - -const ( - E = 0xff -) - -var ymovtab = []uint8{ - /* push */ - APUSHL & obj.AMask, - Ycs, - Ynone, - 0, - 0x0e, - E, - 0, - 0, - APUSHL & obj.AMask, - Yss, - Ynone, - 0, - 0x16, - E, - 0, - 0, - APUSHL & obj.AMask, - Yds, - Ynone, - 0, - 0x1e, - E, - 0, - 0, - APUSHL & obj.AMask, - Yes, - Ynone, - 0, - 0x06, - E, - 0, - 0, - APUSHL & obj.AMask, - Yfs, - Ynone, - 0, - 0x0f, - 0xa0, - E, - 0, - APUSHL & obj.AMask, - Ygs, - Ynone, - 0, - 0x0f, - 0xa8, - E, - 0, - APUSHW & obj.AMask, - Ycs, - Ynone, - 0, - Pe, - 0x0e, - E, - 0, - APUSHW & obj.AMask, - Yss, - Ynone, - 0, - Pe, - 0x16, - E, - 0, - APUSHW & obj.AMask, - Yds, - Ynone, - 0, - Pe, - 0x1e, - E, - 0, - APUSHW & obj.AMask, - Yes, - Ynone, - 0, - Pe, - 0x06, - E, - 0, - APUSHW & obj.AMask, - Yfs, - Ynone, - 0, - Pe, - 0x0f, - 0xa0, - E, - APUSHW & obj.AMask, - Ygs, - Ynone, - 0, - Pe, - 0x0f, - 0xa8, - E, - - /* pop */ - APOPL & obj.AMask, - Ynone, - Yds, - 0, - 0x1f, - E, - 0, - 0, - APOPL & obj.AMask, - Ynone, - Yes, - 0, - 0x07, - E, - 0, - 0, - APOPL & obj.AMask, - Ynone, - Yss, - 0, - 0x17, - E, - 0, - 0, - APOPL & obj.AMask, - Ynone, - Yfs, - 0, - 0x0f, - 0xa1, - E, - 0, - APOPL & obj.AMask, - Ynone, - Ygs, - 0, - 0x0f, - 0xa9, - E, - 0, - APOPW & obj.AMask, - Ynone, - Yds, - 0, - Pe, - 0x1f, - E, - 0, - APOPW & obj.AMask, - Ynone, - Yes, - 0, - Pe, - 0x07, - E, - 0, - APOPW & obj.AMask, - Ynone, - Yss, - 0, - Pe, - 0x17, - E, - 0, - APOPW & obj.AMask, - Ynone, - Yfs, - 0, - Pe, - 0x0f, - 0xa1, - E, - APOPW & obj.AMask, - Ynone, - Ygs, - 0, - Pe, - 0x0f, - 0xa9, - E, - - /* mov seg */ - AMOVW & obj.AMask, - Yes, - Yml, - 1, - 0x8c, - 0, - 0, - 0, - AMOVW & obj.AMask, - Ycs, - Yml, - 1, - 0x8c, - 1, - 0, - 0, - AMOVW & obj.AMask, - Yss, - Yml, - 1, - 0x8c, - 2, - 0, - 0, - AMOVW & obj.AMask, - Yds, - Yml, - 1, - 0x8c, - 3, - 0, - 0, - AMOVW & obj.AMask, - Yfs, - Yml, - 1, - 0x8c, - 4, - 0, - 0, - AMOVW & obj.AMask, - Ygs, - Yml, - 1, - 0x8c, - 5, - 0, - 0, - AMOVW & obj.AMask, - Yml, - Yes, - 2, - 0x8e, - 0, - 0, - 0, - AMOVW & obj.AMask, - Yml, - Ycs, - 2, - 0x8e, - 1, - 0, - 0, - AMOVW & obj.AMask, - Yml, - Yss, - 2, - 0x8e, - 2, - 0, - 0, - AMOVW & obj.AMask, - Yml, - Yds, - 2, - 0x8e, - 3, - 0, - 0, - AMOVW & obj.AMask, - Yml, - Yfs, - 2, - 0x8e, - 4, - 0, - 0, - AMOVW & obj.AMask, - Yml, - Ygs, - 2, - 0x8e, - 5, - 0, - 0, - - /* mov cr */ - AMOVL & obj.AMask, - Ycr0, - Yml, - 3, - 0x0f, - 0x20, - 0, - 0, - AMOVL & obj.AMask, - Ycr2, - Yml, - 3, - 0x0f, - 0x20, - 2, - 0, - AMOVL & obj.AMask, - Ycr3, - Yml, - 3, - 0x0f, - 0x20, - 3, - 0, - AMOVL & obj.AMask, - Ycr4, - Yml, - 3, - 0x0f, - 0x20, - 4, - 0, - AMOVL & obj.AMask, - Yml, - Ycr0, - 4, - 0x0f, - 0x22, - 0, - 0, - AMOVL & obj.AMask, - Yml, - Ycr2, - 4, - 0x0f, - 0x22, - 2, - 0, - AMOVL & obj.AMask, - Yml, - Ycr3, - 4, - 0x0f, - 0x22, - 3, - 0, - AMOVL & obj.AMask, - Yml, - Ycr4, - 4, - 0x0f, - 0x22, - 4, - 0, - - /* mov dr */ - AMOVL & obj.AMask, - Ydr0, - Yml, - 3, - 0x0f, - 0x21, - 0, - 0, - AMOVL & obj.AMask, - Ydr6, - Yml, - 3, - 0x0f, - 0x21, - 6, - 0, - AMOVL & obj.AMask, - Ydr7, - Yml, - 3, - 0x0f, - 0x21, - 7, - 0, - AMOVL & obj.AMask, - Yml, - Ydr0, - 4, - 0x0f, - 0x23, - 0, - 0, - AMOVL & obj.AMask, - Yml, - Ydr6, - 4, - 0x0f, - 0x23, - 6, - 0, - AMOVL & obj.AMask, - Yml, - Ydr7, - 4, - 0x0f, - 0x23, - 7, - 0, - - /* mov tr */ - AMOVL & obj.AMask, - Ytr6, - Yml, - 3, - 0x0f, - 0x24, - 6, - 0, - AMOVL & obj.AMask, - Ytr7, - Yml, - 3, - 0x0f, - 0x24, - 7, - 0, - AMOVL & obj.AMask, - Yml, - Ytr6, - 4, - 0x0f, - 0x26, - 6, - E, - AMOVL & obj.AMask, - Yml, - Ytr7, - 4, - 0x0f, - 0x26, - 7, - E, - - /* lgdt, sgdt, lidt, sidt */ - AMOVL & obj.AMask, - Ym, - Ygdtr, - 4, - 0x0f, - 0x01, - 2, - 0, - AMOVL & obj.AMask, - Ygdtr, - Ym, - 3, - 0x0f, - 0x01, - 0, - 0, - AMOVL & obj.AMask, - Ym, - Yidtr, - 4, - 0x0f, - 0x01, - 3, - 0, - AMOVL & obj.AMask, - Yidtr, - Ym, - 3, - 0x0f, - 0x01, - 1, - 0, - - /* lldt, sldt */ - AMOVW & obj.AMask, - Yml, - Yldtr, - 4, - 0x0f, - 0x00, - 2, - 0, - AMOVW & obj.AMask, - Yldtr, - Yml, - 3, - 0x0f, - 0x00, - 0, - 0, - - /* lmsw, smsw */ - AMOVW & obj.AMask, - Yml, - Ymsw, - 4, - 0x0f, - 0x01, - 6, - 0, - AMOVW & obj.AMask, - Ymsw, - Yml, - 3, - 0x0f, - 0x01, - 4, - 0, - - /* ltr, str */ - AMOVW & obj.AMask, - Yml, - Ytask, - 4, - 0x0f, - 0x00, - 3, - 0, - AMOVW & obj.AMask, - Ytask, - Yml, - 3, - 0x0f, - 0x00, - 1, - 0, - - /* load full pointer */ - AMOVL & obj.AMask, - Yml, - Ycol, - 5, - 0, - 0, - 0, - 0, - AMOVW & obj.AMask, - Yml, - Ycol, - 5, - Pe, - 0, - 0, - 0, - - /* double shift */ - ASHLL & obj.AMask, - Ycol, - Yml, - 6, - 0xa4, - 0xa5, - 0, - 0, - ASHRL & obj.AMask, - Ycol, - Yml, - 6, - 0xac, - 0xad, - 0, - 0, - - /* extra imul */ - AIMULW & obj.AMask, - Yml, - Yrl, - 7, - Pq, - 0xaf, - 0, - 0, - AIMULL & obj.AMask, - Yml, - Yrl, - 7, - Pm, - 0xaf, - 0, - 0, - - /* load TLS base pointer */ - AMOVL & obj.AMask, - Ytls, - Yrl, - 8, - 0, - 0, - 0, - 0, - 0, -} - -// byteswapreg returns a byte-addressable register (AX, BX, CX, DX) -// which is not referenced in a. -// If a is empty, it returns BX to account for MULB-like instructions -// that might use DX and AX. -func byteswapreg(ctxt *obj.Link, a *obj.Addr) int { - cand := 1 - canc := cand - canb := canc - cana := canb - - if a.Type == obj.TYPE_NONE { - cand = 0 - cana = cand - } - - if a.Type == obj.TYPE_REG || ((a.Type == obj.TYPE_MEM || a.Type == obj.TYPE_ADDR) && a.Name == obj.NAME_NONE) { - switch a.Reg { - case REG_NONE: - cand = 0 - cana = cand - - case REG_AX, - REG_AL, - REG_AH: - cana = 0 - - case REG_BX, - REG_BL, - REG_BH: - canb = 0 - - case REG_CX, - REG_CL, - REG_CH: - canc = 0 - - case REG_DX, - REG_DL, - REG_DH: - cand = 0 - } - } - - if a.Type == obj.TYPE_MEM || a.Type == obj.TYPE_ADDR { - switch a.Index { - case REG_AX: - cana = 0 - - case REG_BX: - canb = 0 - - case REG_CX: - canc = 0 - - case REG_DX: - cand = 0 - } - } - - if cana != 0 { - return REG_AX - } - if canb != 0 { - return REG_BX - } - if canc != 0 { - return REG_CX - } - if cand != 0 { - return REG_DX - } - - ctxt.Diag("impossible byte register") - log.Fatalf("bad code") - return 0 -} - -func subreg(p *obj.Prog, from int, to int) { - if false { /* debug['Q'] */ - fmt.Printf("\n%v\ts/%v/%v/\n", p, Rconv(from), Rconv(to)) - } - - if int(p.From.Reg) == from { - p.From.Reg = int16(to) - p.Ft = 0 - } - - if int(p.To.Reg) == from { - p.To.Reg = int16(to) - p.Tt = 0 - } - - if int(p.From.Index) == from { - p.From.Index = int16(to) - p.Ft = 0 - } - - if int(p.To.Index) == from { - p.To.Index = int16(to) - p.Tt = 0 - } - - if false { /* debug['Q'] */ - fmt.Printf("%v\n", p) - } -} - -func mediaop(ctxt *obj.Link, o *Optab, op int, osize int, z int) int { - switch op { - case Pm, - Pe, - Pf2, - Pf3: - if osize != 1 { - if op != Pm { - ctxt.Andptr[0] = byte(op) - ctxt.Andptr = ctxt.Andptr[1:] - } - ctxt.Andptr[0] = Pm - ctxt.Andptr = ctxt.Andptr[1:] - z++ - op = int(o.op[z]) - break - } - fallthrough - - default: - if -cap(ctxt.Andptr) == -cap(ctxt.And) || ctxt.And[-cap(ctxt.Andptr)+cap(ctxt.And[:])-1] != Pm { - ctxt.Andptr[0] = Pm - ctxt.Andptr = ctxt.Andptr[1:] - } - } - - ctxt.Andptr[0] = byte(op) - ctxt.Andptr = ctxt.Andptr[1:] - return z -} - -func doasm(ctxt *obj.Link, p *obj.Prog) { - ctxt.Curp = p // TODO - - pre := int32(prefixof(ctxt, &p.From)) - - if pre != 0 { - ctxt.Andptr[0] = byte(pre) - ctxt.Andptr = ctxt.Andptr[1:] - } - pre = int32(prefixof(ctxt, &p.To)) - if pre != 0 { - ctxt.Andptr[0] = byte(pre) - ctxt.Andptr = ctxt.Andptr[1:] - } - - if p.Ft == 0 { - p.Ft = uint8(oclass(ctxt, p, &p.From)) - } - if p.Tt == 0 { - p.Tt = uint8(oclass(ctxt, p, &p.To)) - } - - ft := int(p.Ft) * Ymax - tt := int(p.Tt) * Ymax - o := opindex[p.As&obj.AMask] - - z := 0 - var a *obj.Addr - var op int - var q *obj.Prog - var r *obj.Reloc - var rel obj.Reloc - var v int32 - var yt ytab - for _, yt = range o.ytab { - if ycover[ft+int(yt.from)] != 0 && ycover[tt+int(yt.to)] != 0 { - switch o.prefix { - case Pq: /* 16 bit escape and opcode escape */ - ctxt.Andptr[0] = Pe - ctxt.Andptr = ctxt.Andptr[1:] - - ctxt.Andptr[0] = Pm - ctxt.Andptr = ctxt.Andptr[1:] - - case Pf2, /* xmm opcode escape */ - Pf3: - ctxt.Andptr[0] = byte(o.prefix) - ctxt.Andptr = ctxt.Andptr[1:] - - ctxt.Andptr[0] = Pm - ctxt.Andptr = ctxt.Andptr[1:] - - case Pm: /* opcode escape */ - ctxt.Andptr[0] = Pm - ctxt.Andptr = ctxt.Andptr[1:] - - case Pe: /* 16 bit escape */ - ctxt.Andptr[0] = Pe - ctxt.Andptr = ctxt.Andptr[1:] - - case Pb: /* botch */ - break - } - - op = int(o.op[z]) - switch yt.zcase { - default: - ctxt.Diag("asmins: unknown z %d %v", yt.zcase, p) - return - - case Zpseudo: - break - - case Zlit: - for ; ; z++ { - op = int(o.op[z]) - if op == 0 { - break - } - ctxt.Andptr[0] = byte(op) - ctxt.Andptr = ctxt.Andptr[1:] - } - - case Zlitm_r: - for ; ; z++ { - op = int(o.op[z]) - if op == 0 { - break - } - ctxt.Andptr[0] = byte(op) - ctxt.Andptr = ctxt.Andptr[1:] - } - asmand(ctxt, p, &p.From, reg[p.To.Reg]) - - case Zm_r: - ctxt.Andptr[0] = byte(op) - ctxt.Andptr = ctxt.Andptr[1:] - asmand(ctxt, p, &p.From, reg[p.To.Reg]) - - case Zm2_r: - ctxt.Andptr[0] = byte(op) - ctxt.Andptr = ctxt.Andptr[1:] - ctxt.Andptr[0] = byte(o.op[z+1]) - ctxt.Andptr = ctxt.Andptr[1:] - asmand(ctxt, p, &p.From, reg[p.To.Reg]) - - case Zm_r_xm: - mediaop(ctxt, o, op, int(yt.zoffset), z) - asmand(ctxt, p, &p.From, reg[p.To.Reg]) - - case Zm_r_i_xm: - mediaop(ctxt, o, op, int(yt.zoffset), z) - asmand(ctxt, p, &p.From, reg[p.To.Reg]) - ctxt.Andptr[0] = byte(p.To.Offset) - ctxt.Andptr = ctxt.Andptr[1:] - - case Zibm_r: - for { - tmp2 := z - z++ - op = int(o.op[tmp2]) - if op == 0 { - break - } - ctxt.Andptr[0] = byte(op) - ctxt.Andptr = ctxt.Andptr[1:] - } - asmand(ctxt, p, &p.From, reg[p.To.Reg]) - ctxt.Andptr[0] = byte(p.To.Offset) - ctxt.Andptr = ctxt.Andptr[1:] - - case Zaut_r: - ctxt.Andptr[0] = 0x8d - ctxt.Andptr = ctxt.Andptr[1:] /* leal */ - if p.From.Type != obj.TYPE_ADDR { - ctxt.Diag("asmins: Zaut sb type ADDR") - } - p.From.Type = obj.TYPE_MEM - p.Ft = 0 - asmand(ctxt, p, &p.From, reg[p.To.Reg]) - p.From.Type = obj.TYPE_ADDR - p.Ft = 0 - - case Zm_o: - ctxt.Andptr[0] = byte(op) - ctxt.Andptr = ctxt.Andptr[1:] - asmand(ctxt, p, &p.From, int(o.op[z+1])) - - case Zr_m: - ctxt.Andptr[0] = byte(op) - ctxt.Andptr = ctxt.Andptr[1:] - asmand(ctxt, p, &p.To, reg[p.From.Reg]) - - case Zr_m_xm: - mediaop(ctxt, o, op, int(yt.zoffset), z) - asmand(ctxt, p, &p.To, reg[p.From.Reg]) - - case Zr_m_i_xm: - mediaop(ctxt, o, op, int(yt.zoffset), z) - asmand(ctxt, p, &p.To, reg[p.From.Reg]) - ctxt.Andptr[0] = byte(p.From.Offset) - ctxt.Andptr = ctxt.Andptr[1:] - - case Zcallindreg: - r = obj.Addrel(ctxt.Cursym) - r.Off = int32(p.Pc) - r.Type = obj.R_CALLIND - r.Siz = 0 - fallthrough - - // fallthrough - case Zo_m: - ctxt.Andptr[0] = byte(op) - ctxt.Andptr = ctxt.Andptr[1:] - - asmand(ctxt, p, &p.To, int(o.op[z+1])) - - case Zm_ibo: - ctxt.Andptr[0] = byte(op) - ctxt.Andptr = ctxt.Andptr[1:] - asmand(ctxt, p, &p.From, int(o.op[z+1])) - ctxt.Andptr[0] = byte(vaddr(ctxt, p, &p.To, nil)) - ctxt.Andptr = ctxt.Andptr[1:] - - case Zibo_m: - ctxt.Andptr[0] = byte(op) - ctxt.Andptr = ctxt.Andptr[1:] - asmand(ctxt, p, &p.To, int(o.op[z+1])) - ctxt.Andptr[0] = byte(vaddr(ctxt, p, &p.From, nil)) - ctxt.Andptr = ctxt.Andptr[1:] - - case Z_ib, - Zib_: - if yt.zcase == Zib_ { - a = &p.From - } else { - a = &p.To - } - v = vaddr(ctxt, p, a, nil) - ctxt.Andptr[0] = byte(op) - ctxt.Andptr = ctxt.Andptr[1:] - ctxt.Andptr[0] = byte(v) - ctxt.Andptr = ctxt.Andptr[1:] - - case Zib_rp: - ctxt.Andptr[0] = byte(op + reg[p.To.Reg]) - ctxt.Andptr = ctxt.Andptr[1:] - ctxt.Andptr[0] = byte(vaddr(ctxt, p, &p.From, nil)) - ctxt.Andptr = ctxt.Andptr[1:] - - case Zil_rp: - ctxt.Andptr[0] = byte(op + reg[p.To.Reg]) - ctxt.Andptr = ctxt.Andptr[1:] - if o.prefix == Pe { - v = vaddr(ctxt, p, &p.From, nil) - ctxt.Andptr[0] = byte(v) - ctxt.Andptr = ctxt.Andptr[1:] - ctxt.Andptr[0] = byte(v >> 8) - ctxt.Andptr = ctxt.Andptr[1:] - } else { - relput4(ctxt, p, &p.From) - } - - case Zib_rr: - ctxt.Andptr[0] = byte(op) - ctxt.Andptr = ctxt.Andptr[1:] - asmand(ctxt, p, &p.To, reg[p.To.Reg]) - ctxt.Andptr[0] = byte(vaddr(ctxt, p, &p.From, nil)) - ctxt.Andptr = ctxt.Andptr[1:] - - case Z_il, - Zil_: - if yt.zcase == Zil_ { - a = &p.From - } else { - a = &p.To - } - ctxt.Andptr[0] = byte(op) - ctxt.Andptr = ctxt.Andptr[1:] - if o.prefix == Pe { - v = vaddr(ctxt, p, a, nil) - ctxt.Andptr[0] = byte(v) - ctxt.Andptr = ctxt.Andptr[1:] - ctxt.Andptr[0] = byte(v >> 8) - ctxt.Andptr = ctxt.Andptr[1:] - } else { - relput4(ctxt, p, a) - } - - case Zm_ilo, - Zilo_m: - ctxt.Andptr[0] = byte(op) - ctxt.Andptr = ctxt.Andptr[1:] - if yt.zcase == Zilo_m { - a = &p.From - asmand(ctxt, p, &p.To, int(o.op[z+1])) - } else { - a = &p.To - asmand(ctxt, p, &p.From, int(o.op[z+1])) - } - - if o.prefix == Pe { - v = vaddr(ctxt, p, a, nil) - ctxt.Andptr[0] = byte(v) - ctxt.Andptr = ctxt.Andptr[1:] - ctxt.Andptr[0] = byte(v >> 8) - ctxt.Andptr = ctxt.Andptr[1:] - } else { - relput4(ctxt, p, a) - } - - case Zil_rr: - ctxt.Andptr[0] = byte(op) - ctxt.Andptr = ctxt.Andptr[1:] - asmand(ctxt, p, &p.To, reg[p.To.Reg]) - if o.prefix == Pe { - v = vaddr(ctxt, p, &p.From, nil) - ctxt.Andptr[0] = byte(v) - ctxt.Andptr = ctxt.Andptr[1:] - ctxt.Andptr[0] = byte(v >> 8) - ctxt.Andptr = ctxt.Andptr[1:] - } else { - relput4(ctxt, p, &p.From) - } - - case Z_rp: - ctxt.Andptr[0] = byte(op + reg[p.To.Reg]) - ctxt.Andptr = ctxt.Andptr[1:] - - case Zrp_: - ctxt.Andptr[0] = byte(op + reg[p.From.Reg]) - ctxt.Andptr = ctxt.Andptr[1:] - - case Zclr: - ctxt.Andptr[0] = byte(op) - ctxt.Andptr = ctxt.Andptr[1:] - asmand(ctxt, p, &p.To, reg[p.To.Reg]) - - case Zcall: - if p.To.Sym == nil { - ctxt.Diag("call without target") - log.Fatalf("bad code") - } - - ctxt.Andptr[0] = byte(op) - ctxt.Andptr = ctxt.Andptr[1:] - r = obj.Addrel(ctxt.Cursym) - r.Off = int32(p.Pc + int64(-cap(ctxt.Andptr)+cap(ctxt.And[:]))) - r.Type = obj.R_CALL - r.Siz = 4 - r.Sym = p.To.Sym - r.Add = p.To.Offset - put4(ctxt, 0) - - case Zbr, - Zjmp, - Zloop: - if p.To.Sym != nil { - if yt.zcase != Zjmp { - ctxt.Diag("branch to ATEXT") - log.Fatalf("bad code") - } - - ctxt.Andptr[0] = byte(o.op[z+1]) - ctxt.Andptr = ctxt.Andptr[1:] - r = obj.Addrel(ctxt.Cursym) - r.Off = int32(p.Pc + int64(-cap(ctxt.Andptr)+cap(ctxt.And[:]))) - r.Sym = p.To.Sym - r.Type = obj.R_PCREL - r.Siz = 4 - put4(ctxt, 0) - break - } - - // Assumes q is in this function. - // Fill in backward jump now. - q = p.Pcond - - if q == nil { - ctxt.Diag("jmp/branch/loop without target") - log.Fatalf("bad code") - } - - if p.Back&1 != 0 { - v = int32(q.Pc - (p.Pc + 2)) - if v >= -128 { - if p.As == AJCXZW { - ctxt.Andptr[0] = 0x67 - ctxt.Andptr = ctxt.Andptr[1:] - } - ctxt.Andptr[0] = byte(op) - ctxt.Andptr = ctxt.Andptr[1:] - ctxt.Andptr[0] = byte(v) - ctxt.Andptr = ctxt.Andptr[1:] - } else if yt.zcase == Zloop { - ctxt.Diag("loop too far: %v", p) - } else { - v -= 5 - 2 - if yt.zcase == Zbr { - ctxt.Andptr[0] = 0x0f - ctxt.Andptr = ctxt.Andptr[1:] - v-- - } - - ctxt.Andptr[0] = byte(o.op[z+1]) - ctxt.Andptr = ctxt.Andptr[1:] - ctxt.Andptr[0] = byte(v) - ctxt.Andptr = ctxt.Andptr[1:] - ctxt.Andptr[0] = byte(v >> 8) - ctxt.Andptr = ctxt.Andptr[1:] - ctxt.Andptr[0] = byte(v >> 16) - ctxt.Andptr = ctxt.Andptr[1:] - ctxt.Andptr[0] = byte(v >> 24) - ctxt.Andptr = ctxt.Andptr[1:] - } - - break - } - - // Annotate target; will fill in later. - p.Forwd = q.Comefrom - - q.Comefrom = p - if p.Back&2 != 0 { // short - if p.As == AJCXZW { - ctxt.Andptr[0] = 0x67 - ctxt.Andptr = ctxt.Andptr[1:] - } - ctxt.Andptr[0] = byte(op) - ctxt.Andptr = ctxt.Andptr[1:] - ctxt.Andptr[0] = 0 - ctxt.Andptr = ctxt.Andptr[1:] - } else if yt.zcase == Zloop { - ctxt.Diag("loop too far: %v", p) - } else { - if yt.zcase == Zbr { - ctxt.Andptr[0] = 0x0f - ctxt.Andptr = ctxt.Andptr[1:] - } - ctxt.Andptr[0] = byte(o.op[z+1]) - ctxt.Andptr = ctxt.Andptr[1:] - ctxt.Andptr[0] = 0 - ctxt.Andptr = ctxt.Andptr[1:] - ctxt.Andptr[0] = 0 - ctxt.Andptr = ctxt.Andptr[1:] - ctxt.Andptr[0] = 0 - ctxt.Andptr = ctxt.Andptr[1:] - ctxt.Andptr[0] = 0 - ctxt.Andptr = ctxt.Andptr[1:] - } - - case Zcallcon, - Zjmpcon: - if yt.zcase == Zcallcon { - ctxt.Andptr[0] = byte(op) - ctxt.Andptr = ctxt.Andptr[1:] - } else { - ctxt.Andptr[0] = byte(o.op[z+1]) - ctxt.Andptr = ctxt.Andptr[1:] - } - r = obj.Addrel(ctxt.Cursym) - r.Off = int32(p.Pc + int64(-cap(ctxt.Andptr)+cap(ctxt.And[:]))) - r.Type = obj.R_PCREL - r.Siz = 4 - r.Add = p.To.Offset - put4(ctxt, 0) - - case Zcallind: - ctxt.Andptr[0] = byte(op) - ctxt.Andptr = ctxt.Andptr[1:] - ctxt.Andptr[0] = byte(o.op[z+1]) - ctxt.Andptr = ctxt.Andptr[1:] - r = obj.Addrel(ctxt.Cursym) - r.Off = int32(p.Pc + int64(-cap(ctxt.Andptr)+cap(ctxt.And[:]))) - r.Type = obj.R_ADDR - r.Siz = 4 - r.Add = p.To.Offset - r.Sym = p.To.Sym - put4(ctxt, 0) - - case Zbyte: - v = vaddr(ctxt, p, &p.From, &rel) - if rel.Siz != 0 { - rel.Siz = uint8(op) - r = obj.Addrel(ctxt.Cursym) - *r = rel - r.Off = int32(p.Pc + int64(-cap(ctxt.Andptr)+cap(ctxt.And[:]))) - } - - ctxt.Andptr[0] = byte(v) - ctxt.Andptr = ctxt.Andptr[1:] - if op > 1 { - ctxt.Andptr[0] = byte(v >> 8) - ctxt.Andptr = ctxt.Andptr[1:] - if op > 2 { - ctxt.Andptr[0] = byte(v >> 16) - ctxt.Andptr = ctxt.Andptr[1:] - ctxt.Andptr[0] = byte(v >> 24) - ctxt.Andptr = ctxt.Andptr[1:] - } - } - - case Zmov: - goto domov - } - - return - } - z += int(yt.zoffset) - } - goto domov - -domov: - var pp obj.Prog - for t := []byte(ymovtab); t[0] != 0; t = t[8:] { - if p.As&obj.AMask == int16(t[0]) { - if ycover[ft+int(t[1])] != 0 { - if ycover[tt+int(t[2])] != 0 { - switch t[3] { - default: - ctxt.Diag("asmins: unknown mov %d %v", t[3], p) - - case 0: /* lit */ - for z = 4; t[z] != E; z++ { - ctxt.Andptr[0] = t[z] - ctxt.Andptr = ctxt.Andptr[1:] - } - - case 1: /* r,m */ - ctxt.Andptr[0] = t[4] - ctxt.Andptr = ctxt.Andptr[1:] - - asmand(ctxt, p, &p.To, int(t[5])) - - case 2: /* m,r */ - ctxt.Andptr[0] = t[4] - ctxt.Andptr = ctxt.Andptr[1:] - - asmand(ctxt, p, &p.From, int(t[5])) - - case 3: /* r,m - 2op */ - ctxt.Andptr[0] = t[4] - ctxt.Andptr = ctxt.Andptr[1:] - - ctxt.Andptr[0] = t[5] - ctxt.Andptr = ctxt.Andptr[1:] - asmand(ctxt, p, &p.To, int(t[6])) - - case 4: /* m,r - 2op */ - ctxt.Andptr[0] = t[4] - ctxt.Andptr = ctxt.Andptr[1:] - - ctxt.Andptr[0] = t[5] - ctxt.Andptr = ctxt.Andptr[1:] - asmand(ctxt, p, &p.From, int(t[6])) - - case 5: /* load full pointer, trash heap */ - if t[4] != 0 { - ctxt.Andptr[0] = t[4] - ctxt.Andptr = ctxt.Andptr[1:] - } - switch p.To.Index { - default: - goto bad - - case REG_DS: - ctxt.Andptr[0] = 0xc5 - ctxt.Andptr = ctxt.Andptr[1:] - - case REG_SS: - ctxt.Andptr[0] = 0x0f - ctxt.Andptr = ctxt.Andptr[1:] - ctxt.Andptr[0] = 0xb2 - ctxt.Andptr = ctxt.Andptr[1:] - - case REG_ES: - ctxt.Andptr[0] = 0xc4 - ctxt.Andptr = ctxt.Andptr[1:] - - case REG_FS: - ctxt.Andptr[0] = 0x0f - ctxt.Andptr = ctxt.Andptr[1:] - ctxt.Andptr[0] = 0xb4 - ctxt.Andptr = ctxt.Andptr[1:] - - case REG_GS: - ctxt.Andptr[0] = 0x0f - ctxt.Andptr = ctxt.Andptr[1:] - ctxt.Andptr[0] = 0xb5 - ctxt.Andptr = ctxt.Andptr[1:] - } - - asmand(ctxt, p, &p.From, reg[p.To.Reg]) - - case 6: /* double shift */ - switch p.From.Type { - default: - goto bad - - case obj.TYPE_CONST: - ctxt.Andptr[0] = 0x0f - ctxt.Andptr = ctxt.Andptr[1:] - ctxt.Andptr[0] = t[4] - ctxt.Andptr = ctxt.Andptr[1:] - asmand(ctxt, p, &p.To, reg[p.From.Index]) - ctxt.Andptr[0] = byte(p.From.Offset) - ctxt.Andptr = ctxt.Andptr[1:] - - case obj.TYPE_REG: - switch p.From.Reg { - default: - goto bad - - case REG_CL, - REG_CX: - ctxt.Andptr[0] = 0x0f - ctxt.Andptr = ctxt.Andptr[1:] - ctxt.Andptr[0] = t[5] - ctxt.Andptr = ctxt.Andptr[1:] - asmand(ctxt, p, &p.To, reg[p.From.Index]) - } - } - - case 7: /* imul rm,r */ - if t[4] == Pq { - ctxt.Andptr[0] = Pe - ctxt.Andptr = ctxt.Andptr[1:] - ctxt.Andptr[0] = Pm - ctxt.Andptr = ctxt.Andptr[1:] - } else { - ctxt.Andptr[0] = t[4] - ctxt.Andptr = ctxt.Andptr[1:] - } - ctxt.Andptr[0] = t[5] - ctxt.Andptr = ctxt.Andptr[1:] - asmand(ctxt, p, &p.From, reg[p.To.Reg]) - - // NOTE: The systems listed here are the ones that use the "TLS initial exec" model, - // where you load the TLS base register into a register and then index off that - // register to access the actual TLS variables. Systems that allow direct TLS access - // are handled in prefixof above and should not be listed here. - case 8: /* mov tls, r */ - switch ctxt.Headtype { - default: - log.Fatalf("unknown TLS base location for %s", obj.Headstr(ctxt.Headtype)) - - // ELF TLS base is 0(GS). - case obj.Hlinux, - obj.Hnacl: - pp.From = p.From - - pp.From.Type = obj.TYPE_MEM - pp.From.Reg = REG_GS - pp.From.Offset = 0 - pp.From.Index = REG_NONE - pp.From.Scale = 0 - ctxt.Andptr[0] = 0x65 - ctxt.Andptr = ctxt.Andptr[1:] // GS - ctxt.Andptr[0] = 0x8B - ctxt.Andptr = ctxt.Andptr[1:] - asmand(ctxt, p, &pp.From, reg[p.To.Reg]) - - case obj.Hplan9: - if ctxt.Plan9privates == nil { - ctxt.Plan9privates = obj.Linklookup(ctxt, "_privates", 0) - } - pp.From = obj.Addr{} - pp.From.Type = obj.TYPE_MEM - pp.From.Name = obj.NAME_EXTERN - pp.From.Sym = ctxt.Plan9privates - pp.From.Offset = 0 - pp.From.Index = REG_NONE - ctxt.Andptr[0] = 0x8B - ctxt.Andptr = ctxt.Andptr[1:] - asmand(ctxt, p, &pp.From, reg[p.To.Reg]) - - // Windows TLS base is always 0x14(FS). - case obj.Hwindows: - pp.From = p.From - - pp.From.Type = obj.TYPE_MEM - pp.From.Reg = REG_FS - pp.From.Offset = 0x14 - pp.From.Index = REG_NONE - pp.From.Scale = 0 - ctxt.Andptr[0] = 0x64 - ctxt.Andptr = ctxt.Andptr[1:] // FS - ctxt.Andptr[0] = 0x8B - ctxt.Andptr = ctxt.Andptr[1:] - asmand(ctxt, p, &pp.From, reg[p.To.Reg]) - } - } - return - } - } - } - } - - /* - * here, the assembly has failed. - * if its a byte instruction that has - * unaddressable registers, try to - * exchange registers and reissue the - * instruction with the operands renamed. - */ -bad: - pp = *p - - z = int(p.From.Reg) - if p.From.Type == obj.TYPE_REG && z >= REG_BP && z <= REG_DI { - breg := byteswapreg(ctxt, &p.To) - if breg != REG_AX { - ctxt.Andptr[0] = 0x87 - ctxt.Andptr = ctxt.Andptr[1:] /* xchg lhs,bx */ - asmand(ctxt, p, &p.From, reg[breg]) - subreg(&pp, z, breg) - doasm(ctxt, &pp) - ctxt.Andptr[0] = 0x87 - ctxt.Andptr = ctxt.Andptr[1:] /* xchg lhs,bx */ - asmand(ctxt, p, &p.From, reg[breg]) - } else { - ctxt.Andptr[0] = byte(0x90 + reg[z]) - ctxt.Andptr = ctxt.Andptr[1:] /* xchg lsh,ax */ - subreg(&pp, z, REG_AX) - doasm(ctxt, &pp) - ctxt.Andptr[0] = byte(0x90 + reg[z]) - ctxt.Andptr = ctxt.Andptr[1:] /* xchg lsh,ax */ - } - - return - } - - z = int(p.To.Reg) - if p.To.Type == obj.TYPE_REG && z >= REG_BP && z <= REG_DI { - breg := byteswapreg(ctxt, &p.From) - if breg != REG_AX { - ctxt.Andptr[0] = 0x87 - ctxt.Andptr = ctxt.Andptr[1:] /* xchg rhs,bx */ - asmand(ctxt, p, &p.To, reg[breg]) - subreg(&pp, z, breg) - doasm(ctxt, &pp) - ctxt.Andptr[0] = 0x87 - ctxt.Andptr = ctxt.Andptr[1:] /* xchg rhs,bx */ - asmand(ctxt, p, &p.To, reg[breg]) - } else { - ctxt.Andptr[0] = byte(0x90 + reg[z]) - ctxt.Andptr = ctxt.Andptr[1:] /* xchg rsh,ax */ - subreg(&pp, z, REG_AX) - doasm(ctxt, &pp) - ctxt.Andptr[0] = byte(0x90 + reg[z]) - ctxt.Andptr = ctxt.Andptr[1:] /* xchg rsh,ax */ - } - - return - } - - ctxt.Diag("doasm: notfound t2=%d from=%d to=%d %v", yt.zcase, p.Ft, p.Tt, p) - return -} - -var naclret = []uint8{ - 0x5d, // POPL BP - // 0x8b, 0x7d, 0x00, // MOVL (BP), DI - catch return to invalid address, for debugging - 0x83, - 0xe5, - 0xe0, // ANDL $~31, BP - 0xff, - 0xe5, // JMP BP -} - -func asmins(ctxt *obj.Link, p *obj.Prog) { - ctxt.Andptr = ctxt.And[:] - - if p.As == obj.AUSEFIELD { - r := obj.Addrel(ctxt.Cursym) - r.Off = 0 - r.Sym = p.From.Sym - r.Type = obj.R_USEFIELD - r.Siz = 0 - return - } - - if ctxt.Headtype == obj.Hnacl { - switch p.As { - case obj.ARET: - copy(ctxt.Andptr, naclret) - ctxt.Andptr = ctxt.Andptr[len(naclret):] - return - - case obj.ACALL, - obj.AJMP: - if p.To.Type == obj.TYPE_REG && REG_AX <= p.To.Reg && p.To.Reg <= REG_DI { - ctxt.Andptr[0] = 0x83 - ctxt.Andptr = ctxt.Andptr[1:] - ctxt.Andptr[0] = byte(0xe0 | (p.To.Reg - REG_AX)) - ctxt.Andptr = ctxt.Andptr[1:] - ctxt.Andptr[0] = 0xe0 - ctxt.Andptr = ctxt.Andptr[1:] - } - - case AINT: - ctxt.Andptr[0] = 0xf4 - ctxt.Andptr = ctxt.Andptr[1:] - return - } - } - - doasm(ctxt, p) - if -cap(ctxt.Andptr) > -cap(ctxt.And[len(ctxt.And):]) { - fmt.Printf("and[] is too short - %d byte instruction\n", -cap(ctxt.Andptr)+cap(ctxt.And[:])) - log.Fatalf("bad code") - } -} diff --git a/src/cmd/internal/obj/i386/list8.go b/src/cmd/internal/obj/i386/list8.go deleted file mode 100644 index 104b97c755c..00000000000 --- a/src/cmd/internal/obj/i386/list8.go +++ /dev/null @@ -1,161 +0,0 @@ -// Inferno utils/8c/list.c -// http://code.google.com/p/inferno-os/source/browse/utils/8c/list.c -// -// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. -// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) -// Portions Copyright © 1997-1999 Vita Nuova Limited -// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com) -// Portions Copyright © 2004,2006 Bruce Ellis -// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) -// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others -// Portions Copyright © 2009 The Go Authors. All rights reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -package i386 - -import ( - "cmd/internal/obj" - "fmt" -) - -const ( - STRINGSZ = 1000 -) - -var bigP *obj.Prog - -func Pconv(p *obj.Prog) string { - var str string - - switch p.As { - case obj.ADATA: - str = fmt.Sprintf("%.5d (%v)\t%v\t%v/%d,%v", - p.Pc, p.Line(), obj.Aconv(int(p.As)), obj.Dconv(p, &p.From), p.From3.Offset, obj.Dconv(p, &p.To)) - - case obj.ATEXT: - if p.From3.Offset != 0 { - str = fmt.Sprintf("%.5d (%v)\t%v\t%v,%d,%v", - p.Pc, p.Line(), obj.Aconv(int(p.As)), obj.Dconv(p, &p.From), p.From3.Offset, obj.Dconv(p, &p.To)) - break - } - - str = fmt.Sprintf("%.5d (%v)\t%v\t%v,%v", - p.Pc, p.Line(), obj.Aconv(int(p.As)), obj.Dconv(p, &p.From), obj.Dconv(p, &p.To)) - - default: - str = fmt.Sprintf("%.5d (%v)\t%v\t%v,%v", - p.Pc, p.Line(), obj.Aconv(int(p.As)), obj.Dconv(p, &p.From), obj.Dconv(p, &p.To)) - - // TODO(rsc): This special case is for SHRQ $32, AX:DX, which encodes as - // SHRQ $32(DX*0), AX - // Remove. - if (p.From.Type == obj.TYPE_REG || p.From.Type == obj.TYPE_CONST) && p.From.Index != 0 { - str += fmt.Sprintf(":%v", Rconv(int(p.From.Index))) - } - } - - var fp string - fp += str - return fp -} - -var Register = []string{ - "AL", /* [REG_AL] */ - "CL", - "DL", - "BL", - "AH", - "CH", - "DH", - "BH", - "AX", /* [REG_AX] */ - "CX", - "DX", - "BX", - "SP", - "BP", - "SI", - "DI", - "F0", /* [REG_F0] */ - "F1", - "F2", - "F3", - "F4", - "F5", - "F6", - "F7", - "CS", /* [REG_CS] */ - "SS", - "DS", - "ES", - "FS", - "GS", - "GDTR", /* [REG_GDTR] */ - "IDTR", /* [REG_IDTR] */ - "LDTR", /* [REG_LDTR] */ - "MSW", /* [REG_MSW] */ - "TASK", /* [REG_TASK] */ - "CR0", /* [REG_CR] */ - "CR1", - "CR2", - "CR3", - "CR4", - "CR5", - "CR6", - "CR7", - "DR0", /* [REG_DR] */ - "DR1", - "DR2", - "DR3", - "DR4", - "DR5", - "DR6", - "DR7", - "TR0", /* [REG_TR] */ - "TR1", - "TR2", - "TR3", - "TR4", - "TR5", - "TR6", - "TR7", - "X0", /* [REG_X0] */ - "X1", - "X2", - "X3", - "X4", - "X5", - "X6", - "X7", - "TLS", /* [REG_TLS] */ - "MAXREG", /* [MAXREG] */ -} - -func init() { - obj.RegisterRegister(obj.RBase386, obj.RBase386+len(Register), Rconv) - obj.RegisterOpcode(obj.ABase386, Anames) -} - -func Rconv(r int) string { - if r >= REG_AL && r-REG_AL < len(Register) { - return Register[r-REG_AL] - } - return fmt.Sprintf("Rgok(%d)", r-obj.RBase386) -} diff --git a/src/cmd/internal/obj/i386/obj8.go b/src/cmd/internal/obj/i386/obj8.go deleted file mode 100644 index c925cff0e91..00000000000 --- a/src/cmd/internal/obj/i386/obj8.go +++ /dev/null @@ -1,942 +0,0 @@ -// Inferno utils/8l/pass.c -// http://code.google.com/p/inferno-os/source/browse/utils/8l/pass.c -// -// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. -// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) -// Portions Copyright © 1997-1999 Vita Nuova Limited -// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com) -// Portions Copyright © 2004,2006 Bruce Ellis -// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) -// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others -// Portions Copyright © 2009 The Go Authors. All rights reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -package i386 - -import ( - "cmd/internal/obj" - "encoding/binary" - "fmt" - "log" - "math" -) - -func canuselocaltls(ctxt *obj.Link) bool { - switch ctxt.Headtype { - case obj.Hlinux, - obj.Hnacl, - obj.Hplan9, - obj.Hwindows: - return false - } - - return true -} - -func progedit(ctxt *obj.Link, p *obj.Prog) { - // See obj6.c for discussion of TLS. - if canuselocaltls(ctxt) { - // Reduce TLS initial exec model to TLS local exec model. - // Sequences like - // MOVL TLS, BX - // ... off(BX)(TLS*1) ... - // become - // NOP - // ... off(TLS) ... - if p.As == AMOVL && p.From.Type == obj.TYPE_REG && p.From.Reg == REG_TLS && p.To.Type == obj.TYPE_REG && REG_AX <= p.To.Reg && p.To.Reg <= REG_DI { - p.As = obj.ANOP - p.From.Type = obj.TYPE_NONE - p.To.Type = obj.TYPE_NONE - } - - if p.From.Type == obj.TYPE_MEM && p.From.Index == REG_TLS && REG_AX <= p.From.Reg && p.From.Reg <= REG_DI { - p.From.Type = obj.TYPE_MEM - p.From.Reg = REG_TLS - p.From.Scale = 0 - p.From.Index = REG_NONE - } - - if p.To.Type == obj.TYPE_MEM && p.To.Index == REG_TLS && REG_AX <= p.To.Reg && p.To.Reg <= REG_DI { - p.To.Type = obj.TYPE_MEM - p.To.Reg = REG_TLS - p.To.Scale = 0 - p.To.Index = REG_NONE - } - } else { - // As a courtesy to the C compilers, rewrite TLS local exec load as TLS initial exec load. - // The instruction - // MOVL off(TLS), BX - // becomes the sequence - // MOVL TLS, BX - // MOVL off(BX)(TLS*1), BX - // This allows the C compilers to emit references to m and g using the direct off(TLS) form. - if p.As == AMOVL && p.From.Type == obj.TYPE_MEM && p.From.Reg == REG_TLS && p.To.Type == obj.TYPE_REG && REG_AX <= p.To.Reg && p.To.Reg <= REG_DI { - q := obj.Appendp(ctxt, p) - q.As = p.As - q.From.Type = obj.TYPE_MEM - q.From.Reg = p.To.Reg - q.From.Index = REG_TLS - q.From.Scale = 2 // TODO: use 1 - q.To = p.To - p.From.Type = obj.TYPE_REG - p.From.Reg = REG_TLS - p.From.Index = REG_NONE - p.From.Offset = 0 - } - } - - // TODO: Remove. - if ctxt.Headtype == obj.Hplan9 { - if p.From.Scale == 1 && p.From.Index == REG_TLS { - p.From.Scale = 2 - } - if p.To.Scale == 1 && p.To.Index == REG_TLS { - p.To.Scale = 2 - } - } - - // Rewrite CALL/JMP/RET to symbol as TYPE_BRANCH. - switch p.As { - case obj.ACALL, - obj.AJMP, - obj.ARET: - if p.To.Type == obj.TYPE_MEM && (p.To.Name == obj.NAME_EXTERN || p.To.Name == obj.NAME_STATIC) && p.To.Sym != nil { - p.To.Type = obj.TYPE_BRANCH - } - } - - // Rewrite float constants to values stored in memory. - switch p.As { - // Convert AMOVSS $(0), Xx to AXORPS Xx, Xx - case AMOVSS: - if p.From.Type == obj.TYPE_FCONST { - if p.From.U.Dval == 0 { - if p.To.Type == obj.TYPE_REG && REG_X0 <= p.To.Reg && p.To.Reg <= REG_X7 { - p.As = AXORPS - p.From = p.To - break - } - } - } - fallthrough - - // fallthrough - - case AFMOVF, - AFADDF, - AFSUBF, - AFSUBRF, - AFMULF, - AFDIVF, - AFDIVRF, - AFCOMF, - AFCOMFP, - AADDSS, - ASUBSS, - AMULSS, - ADIVSS, - ACOMISS, - AUCOMISS: - if p.From.Type == obj.TYPE_FCONST { - f32 := float32(p.From.U.Dval) - i32 := math.Float32bits(f32) - literal := fmt.Sprintf("$f32.%08x", i32) - s := obj.Linklookup(ctxt, literal, 0) - if s.Type == 0 { - s.Type = obj.SRODATA - obj.Adduint32(ctxt, s, i32) - s.Reachable = 0 - } - - p.From.Type = obj.TYPE_MEM - p.From.Name = obj.NAME_EXTERN - p.From.Sym = s - p.From.Offset = 0 - } - - // Convert AMOVSD $(0), Xx to AXORPS Xx, Xx - case AMOVSD: - if p.From.Type == obj.TYPE_FCONST { - if p.From.U.Dval == 0 { - if p.To.Type == obj.TYPE_REG && REG_X0 <= p.To.Reg && p.To.Reg <= REG_X7 { - p.As = AXORPS - p.From = p.To - break - } - } - } - fallthrough - - // fallthrough - - case AFMOVD, - AFADDD, - AFSUBD, - AFSUBRD, - AFMULD, - AFDIVD, - AFDIVRD, - AFCOMD, - AFCOMDP, - AADDSD, - ASUBSD, - AMULSD, - ADIVSD, - ACOMISD, - AUCOMISD: - if p.From.Type == obj.TYPE_FCONST { - i64 := math.Float64bits(p.From.U.Dval) - literal := fmt.Sprintf("$f64.%016x", i64) - s := obj.Linklookup(ctxt, literal, 0) - if s.Type == 0 { - s.Type = obj.SRODATA - obj.Adduint64(ctxt, s, i64) - s.Reachable = 0 - } - - p.From.Type = obj.TYPE_MEM - p.From.Name = obj.NAME_EXTERN - p.From.Sym = s - p.From.Offset = 0 - } - } -} - -func preprocess(ctxt *obj.Link, cursym *obj.LSym) { - if ctxt.Symmorestack[0] == nil { - ctxt.Symmorestack[0] = obj.Linklookup(ctxt, "runtime.morestack", 0) - ctxt.Symmorestack[1] = obj.Linklookup(ctxt, "runtime.morestack_noctxt", 0) - } - - if ctxt.Headtype == obj.Hplan9 && ctxt.Plan9privates == nil { - ctxt.Plan9privates = obj.Linklookup(ctxt, "_privates", 0) - } - - ctxt.Cursym = cursym - - if cursym.Text == nil || cursym.Text.Link == nil { - return - } - - p := cursym.Text - autoffset := int32(p.To.Offset) - if autoffset < 0 { - autoffset = 0 - } - - cursym.Locals = autoffset - cursym.Args = p.To.U.Argsize - - if p.From3.Offset&obj.NOSPLIT == 0 || (p.From3.Offset&obj.WRAPPER != 0) { - p = obj.Appendp(ctxt, p) - p = load_g_cx(ctxt, p) // load g into CX - } - - var q *obj.Prog - if cursym.Text.From3.Offset&obj.NOSPLIT == 0 { - p = stacksplit(ctxt, p, autoffset, cursym.Text.From3.Offset&obj.NEEDCTXT == 0, &q) // emit split check - } - - if autoffset != 0 { - p = obj.Appendp(ctxt, p) - p.As = AADJSP - p.From.Type = obj.TYPE_CONST - p.From.Offset = int64(autoffset) - p.Spadj = autoffset - } else { - // zero-byte stack adjustment. - // Insert a fake non-zero adjustment so that stkcheck can - // recognize the end of the stack-splitting prolog. - p = obj.Appendp(ctxt, p) - - p.As = obj.ANOP - p.Spadj = int32(-ctxt.Arch.Ptrsize) - p = obj.Appendp(ctxt, p) - p.As = obj.ANOP - p.Spadj = int32(ctxt.Arch.Ptrsize) - } - - if q != nil { - q.Pcond = p - } - deltasp := autoffset - - if cursym.Text.From3.Offset&obj.WRAPPER != 0 { - // if(g->panic != nil && g->panic->argp == FP) g->panic->argp = bottom-of-frame - // - // MOVL g_panic(CX), BX - // TESTL BX, BX - // JEQ end - // LEAL (autoffset+4)(SP), DI - // CMPL panic_argp(BX), DI - // JNE end - // MOVL SP, panic_argp(BX) - // end: - // NOP - // - // The NOP is needed to give the jumps somewhere to land. - // It is a liblink NOP, not an x86 NOP: it encodes to 0 instruction bytes. - - p = obj.Appendp(ctxt, p) - - p.As = AMOVL - p.From.Type = obj.TYPE_MEM - p.From.Reg = REG_CX - p.From.Offset = 4 * int64(ctxt.Arch.Ptrsize) // G.panic - p.To.Type = obj.TYPE_REG - p.To.Reg = REG_BX - - p = obj.Appendp(ctxt, p) - p.As = ATESTL - p.From.Type = obj.TYPE_REG - p.From.Reg = REG_BX - p.To.Type = obj.TYPE_REG - p.To.Reg = REG_BX - - p = obj.Appendp(ctxt, p) - p.As = AJEQ - p.To.Type = obj.TYPE_BRANCH - p1 := p - - p = obj.Appendp(ctxt, p) - p.As = ALEAL - p.From.Type = obj.TYPE_MEM - p.From.Reg = REG_SP - p.From.Offset = int64(autoffset) + 4 - p.To.Type = obj.TYPE_REG - p.To.Reg = REG_DI - - p = obj.Appendp(ctxt, p) - p.As = ACMPL - p.From.Type = obj.TYPE_MEM - p.From.Reg = REG_BX - p.From.Offset = 0 // Panic.argp - p.To.Type = obj.TYPE_REG - p.To.Reg = REG_DI - - p = obj.Appendp(ctxt, p) - p.As = AJNE - p.To.Type = obj.TYPE_BRANCH - p2 := p - - p = obj.Appendp(ctxt, p) - p.As = AMOVL - p.From.Type = obj.TYPE_REG - p.From.Reg = REG_SP - p.To.Type = obj.TYPE_MEM - p.To.Reg = REG_BX - p.To.Offset = 0 // Panic.argp - - p = obj.Appendp(ctxt, p) - - p.As = obj.ANOP - p1.Pcond = p - p2.Pcond = p - } - - if ctxt.Debugzerostack != 0 && autoffset != 0 && cursym.Text.From3.Offset&obj.NOSPLIT == 0 { - // 8l -Z means zero the stack frame on entry. - // This slows down function calls but can help avoid - // false positives in garbage collection. - p = obj.Appendp(ctxt, p) - - p.As = AMOVL - p.From.Type = obj.TYPE_REG - p.From.Reg = REG_SP - p.To.Type = obj.TYPE_REG - p.To.Reg = REG_DI - - p = obj.Appendp(ctxt, p) - p.As = AMOVL - p.From.Type = obj.TYPE_CONST - p.From.Offset = int64(autoffset) / 4 - p.To.Type = obj.TYPE_REG - p.To.Reg = REG_CX - - p = obj.Appendp(ctxt, p) - p.As = AMOVL - p.From.Type = obj.TYPE_CONST - p.From.Offset = 0 - p.To.Type = obj.TYPE_REG - p.To.Reg = REG_AX - - p = obj.Appendp(ctxt, p) - p.As = AREP - - p = obj.Appendp(ctxt, p) - p.As = ASTOSL - } - - var a int - for ; p != nil; p = p.Link { - a = int(p.From.Name) - if a == obj.NAME_AUTO { - p.From.Offset += int64(deltasp) - } - if a == obj.NAME_PARAM { - p.From.Offset += int64(deltasp) + 4 - } - a = int(p.To.Name) - if a == obj.NAME_AUTO { - p.To.Offset += int64(deltasp) - } - if a == obj.NAME_PARAM { - p.To.Offset += int64(deltasp) + 4 - } - - switch p.As { - default: - continue - - case APUSHL, - APUSHFL: - deltasp += 4 - p.Spadj = 4 - continue - - case APUSHW, - APUSHFW: - deltasp += 2 - p.Spadj = 2 - continue - - case APOPL, - APOPFL: - deltasp -= 4 - p.Spadj = -4 - continue - - case APOPW, - APOPFW: - deltasp -= 2 - p.Spadj = -2 - continue - - case obj.ARET: - break - } - - if autoffset != deltasp { - ctxt.Diag("unbalanced PUSH/POP") - } - - if autoffset != 0 { - p.As = AADJSP - p.From.Type = obj.TYPE_CONST - p.From.Offset = int64(-autoffset) - p.Spadj = -autoffset - p = obj.Appendp(ctxt, p) - p.As = obj.ARET - - // If there are instructions following - // this ARET, they come from a branch - // with the same stackframe, so undo - // the cleanup. - p.Spadj = +autoffset - } - - if p.To.Sym != nil { // retjmp - p.As = obj.AJMP - } - } -} - -// Append code to p to load g into cx. -// Overwrites p with the first instruction (no first appendp). -// Overwriting p is unusual but it lets use this in both the -// prologue (caller must call appendp first) and in the epilogue. -// Returns last new instruction. -func load_g_cx(ctxt *obj.Link, p *obj.Prog) *obj.Prog { - p.As = AMOVL - p.From.Type = obj.TYPE_MEM - p.From.Reg = REG_TLS - p.From.Offset = 0 - p.To.Type = obj.TYPE_REG - p.To.Reg = REG_CX - - next := p.Link - progedit(ctxt, p) - for p.Link != next { - p = p.Link - } - - if p.From.Index == REG_TLS { - p.From.Scale = 2 - } - - return p -} - -// Append code to p to check for stack split. -// Appends to (does not overwrite) p. -// Assumes g is in CX. -// Returns last new instruction. -// On return, *jmpok is the instruction that should jump -// to the stack frame allocation if no split is needed. -func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32, noctxt bool, jmpok **obj.Prog) *obj.Prog { - if ctxt.Debugstack != 0 { - // 8l -K means check not only for stack - // overflow but stack underflow. - // On underflow, INT 3 (breakpoint). - // Underflow itself is rare but this also - // catches out-of-sync stack guard info. - p = obj.Appendp(ctxt, p) - - p.As = ACMPL - p.From.Type = obj.TYPE_MEM - p.From.Reg = REG_CX - p.From.Offset = 4 - p.To.Type = obj.TYPE_REG - p.To.Reg = REG_SP - - p = obj.Appendp(ctxt, p) - p.As = AJCC - p.To.Type = obj.TYPE_BRANCH - p.To.Offset = 4 - q1 := p - - p = obj.Appendp(ctxt, p) - p.As = AINT - p.From.Type = obj.TYPE_CONST - p.From.Offset = 3 - - p = obj.Appendp(ctxt, p) - p.As = obj.ANOP - q1.Pcond = p - } - - var q1 *obj.Prog - - if framesize <= obj.StackSmall { - // small stack: SP <= stackguard - // CMPL SP, stackguard - p = obj.Appendp(ctxt, p) - - p.As = ACMPL - p.From.Type = obj.TYPE_REG - p.From.Reg = REG_SP - p.To.Type = obj.TYPE_MEM - p.To.Reg = REG_CX - p.To.Offset = 2 * int64(ctxt.Arch.Ptrsize) // G.stackguard0 - if ctxt.Cursym.Cfunc != 0 { - p.To.Offset = 3 * int64(ctxt.Arch.Ptrsize) // G.stackguard1 - } - } else if framesize <= obj.StackBig { - // large stack: SP-framesize <= stackguard-StackSmall - // LEAL -(framesize-StackSmall)(SP), AX - // CMPL AX, stackguard - p = obj.Appendp(ctxt, p) - - p.As = ALEAL - p.From.Type = obj.TYPE_MEM - p.From.Reg = REG_SP - p.From.Offset = -(int64(framesize) - obj.StackSmall) - p.To.Type = obj.TYPE_REG - p.To.Reg = REG_AX - - p = obj.Appendp(ctxt, p) - p.As = ACMPL - p.From.Type = obj.TYPE_REG - p.From.Reg = REG_AX - p.To.Type = obj.TYPE_MEM - p.To.Reg = REG_CX - p.To.Offset = 2 * int64(ctxt.Arch.Ptrsize) // G.stackguard0 - if ctxt.Cursym.Cfunc != 0 { - p.To.Offset = 3 * int64(ctxt.Arch.Ptrsize) // G.stackguard1 - } - } else { - // Such a large stack we need to protect against wraparound - // if SP is close to zero. - // SP-stackguard+StackGuard <= framesize + (StackGuard-StackSmall) - // The +StackGuard on both sides is required to keep the left side positive: - // SP is allowed to be slightly below stackguard. See stack.h. - // - // Preemption sets stackguard to StackPreempt, a very large value. - // That breaks the math above, so we have to check for that explicitly. - // MOVL stackguard, CX - // CMPL CX, $StackPreempt - // JEQ label-of-call-to-morestack - // LEAL StackGuard(SP), AX - // SUBL stackguard, AX - // CMPL AX, $(framesize+(StackGuard-StackSmall)) - p = obj.Appendp(ctxt, p) - - p.As = AMOVL - p.From.Type = obj.TYPE_MEM - p.From.Reg = REG_CX - p.From.Offset = 0 - p.From.Offset = 2 * int64(ctxt.Arch.Ptrsize) // G.stackguard0 - if ctxt.Cursym.Cfunc != 0 { - p.From.Offset = 3 * int64(ctxt.Arch.Ptrsize) // G.stackguard1 - } - p.To.Type = obj.TYPE_REG - p.To.Reg = REG_SI - - p = obj.Appendp(ctxt, p) - p.As = ACMPL - p.From.Type = obj.TYPE_REG - p.From.Reg = REG_SI - p.To.Type = obj.TYPE_CONST - p.To.Offset = int64(uint32(obj.StackPreempt & (1<<32 - 1))) - - p = obj.Appendp(ctxt, p) - p.As = AJEQ - p.To.Type = obj.TYPE_BRANCH - q1 = p - - p = obj.Appendp(ctxt, p) - p.As = ALEAL - p.From.Type = obj.TYPE_MEM - p.From.Reg = REG_SP - p.From.Offset = obj.StackGuard - p.To.Type = obj.TYPE_REG - p.To.Reg = REG_AX - - p = obj.Appendp(ctxt, p) - p.As = ASUBL - p.From.Type = obj.TYPE_REG - p.From.Reg = REG_SI - p.From.Offset = 0 - p.To.Type = obj.TYPE_REG - p.To.Reg = REG_AX - - p = obj.Appendp(ctxt, p) - p.As = ACMPL - p.From.Type = obj.TYPE_REG - p.From.Reg = REG_AX - p.To.Type = obj.TYPE_CONST - p.To.Offset = int64(framesize) + (obj.StackGuard - obj.StackSmall) - } - - // common - p = obj.Appendp(ctxt, p) - - p.As = AJHI - p.To.Type = obj.TYPE_BRANCH - p.To.Offset = 4 - q := p - - p = obj.Appendp(ctxt, p) - p.As = obj.ACALL - p.To.Type = obj.TYPE_BRANCH - if ctxt.Cursym.Cfunc != 0 { - p.To.Sym = obj.Linklookup(ctxt, "runtime.morestackc", 0) - } else { - p.To.Sym = ctxt.Symmorestack[bool2int(noctxt)] - } - - p = obj.Appendp(ctxt, p) - p.As = obj.AJMP - p.To.Type = obj.TYPE_BRANCH - p.Pcond = ctxt.Cursym.Text.Link - - if q != nil { - q.Pcond = p.Link - } - if q1 != nil { - q1.Pcond = q.Link - } - - *jmpok = q - return p -} - -func follow(ctxt *obj.Link, s *obj.LSym) { - ctxt.Cursym = s - - firstp := ctxt.NewProg() - lastp := firstp - xfol(ctxt, s.Text, &lastp) - lastp.Link = nil - s.Text = firstp.Link -} - -func nofollow(a int) bool { - switch a { - case obj.AJMP, - obj.ARET, - AIRETL, - AIRETW, - obj.AUNDEF: - return true - } - - return false -} - -func pushpop(a int) bool { - switch a { - case APUSHL, - APUSHFL, - APUSHW, - APUSHFW, - APOPL, - APOPFL, - APOPW, - APOPFW: - return true - } - - return false -} - -func relinv(a int) int { - switch a { - case AJEQ: - return AJNE - case AJNE: - return AJEQ - case AJLE: - return AJGT - case AJLS: - return AJHI - case AJLT: - return AJGE - case AJMI: - return AJPL - case AJGE: - return AJLT - case AJPL: - return AJMI - case AJGT: - return AJLE - case AJHI: - return AJLS - case AJCS: - return AJCC - case AJCC: - return AJCS - case AJPS: - return AJPC - case AJPC: - return AJPS - case AJOS: - return AJOC - case AJOC: - return AJOS - } - - log.Fatalf("unknown relation: %s", Anames[a]) - return 0 -} - -func xfol(ctxt *obj.Link, p *obj.Prog, last **obj.Prog) { - var q *obj.Prog - var i int - var a int - -loop: - if p == nil { - return - } - if p.As == obj.AJMP { - q = p.Pcond - if q != nil && q.As != obj.ATEXT { - /* mark instruction as done and continue layout at target of jump */ - p.Mark = 1 - - p = q - if p.Mark == 0 { - goto loop - } - } - } - - if p.Mark != 0 { - /* - * p goes here, but already used it elsewhere. - * copy up to 4 instructions or else branch to other copy. - */ - i = 0 - q = p - for ; i < 4; (func() { i++; q = q.Link })() { - if q == nil { - break - } - if q == *last { - break - } - a = int(q.As) - if a == obj.ANOP { - i-- - continue - } - - if nofollow(a) || pushpop(a) { - break // NOTE(rsc): arm does goto copy - } - if q.Pcond == nil || q.Pcond.Mark != 0 { - continue - } - if a == obj.ACALL || a == ALOOP { - continue - } - for { - if p.As == obj.ANOP { - p = p.Link - continue - } - - q = obj.Copyp(ctxt, p) - p = p.Link - q.Mark = 1 - (*last).Link = q - *last = q - if int(q.As) != a || q.Pcond == nil || q.Pcond.Mark != 0 { - continue - } - - q.As = int16(relinv(int(q.As))) - p = q.Pcond - q.Pcond = q.Link - q.Link = p - xfol(ctxt, q.Link, last) - p = q.Link - if p.Mark != 0 { - return - } - goto loop - /* */ - } - } - q = ctxt.NewProg() - q.As = obj.AJMP - q.Lineno = p.Lineno - q.To.Type = obj.TYPE_BRANCH - q.To.Offset = p.Pc - q.Pcond = p - p = q - } - - /* emit p */ - p.Mark = 1 - - (*last).Link = p - *last = p - a = int(p.As) - - /* continue loop with what comes after p */ - if nofollow(a) { - return - } - if p.Pcond != nil && a != obj.ACALL { - /* - * some kind of conditional branch. - * recurse to follow one path. - * continue loop on the other. - */ - q = obj.Brchain(ctxt, p.Pcond) - if q != nil { - p.Pcond = q - } - q = obj.Brchain(ctxt, p.Link) - if q != nil { - p.Link = q - } - if p.From.Type == obj.TYPE_CONST { - if p.From.Offset == 1 { - /* - * expect conditional jump to be taken. - * rewrite so that's the fall-through case. - */ - p.As = int16(relinv(a)) - - q = p.Link - p.Link = p.Pcond - p.Pcond = q - } - } else { - q = p.Link - if q.Mark != 0 { - if a != ALOOP { - p.As = int16(relinv(a)) - p.Link = p.Pcond - p.Pcond = q - } - } - } - - xfol(ctxt, p.Link, last) - if p.Pcond.Mark != 0 { - return - } - p = p.Pcond - goto loop - } - - p = p.Link - goto loop -} - -var unaryDst = map[int]bool{ - ABSWAPL: true, - ACMPXCHG8B: true, - ADECB: true, - ADECL: true, - ADECW: true, - AINCB: true, - AINCL: true, - AINCW: true, - ANEGB: true, - ANEGL: true, - ANEGW: true, - ANOTB: true, - ANOTL: true, - ANOTW: true, - APOPL: true, - APOPW: true, - ASETCC: true, - ASETCS: true, - ASETEQ: true, - ASETGE: true, - ASETGT: true, - ASETHI: true, - ASETLE: true, - ASETLS: true, - ASETLT: true, - ASETMI: true, - ASETNE: true, - ASETOC: true, - ASETOS: true, - ASETPC: true, - ASETPL: true, - ASETPS: true, - AFFREE: true, - AFLDENV: true, - AFSAVE: true, - AFSTCW: true, - AFSTENV: true, - AFSTSW: true, -} - -var Link386 = obj.LinkArch{ - ByteOrder: binary.LittleEndian, - Pconv: Pconv, - Name: "386", - Thechar: '8', - Preprocess: preprocess, - Assemble: span8, - Follow: follow, - Progedit: progedit, - UnaryDst: unaryDst, - Minlc: 1, - Ptrsize: 4, - Regsize: 4, -} diff --git a/src/cmd/internal/obj/i386/util.go b/src/cmd/internal/obj/i386/util.go deleted file mode 100644 index b3e964361f1..00000000000 --- a/src/cmd/internal/obj/i386/util.go +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package i386 - -func bool2int(b bool) int { - if b { - return 1 - } - return 0 -}