diff options
| author | Russ Cox <rsc@golang.org> | 2015-02-05 03:57:44 -0500 |
|---|---|---|
| committer | Russ Cox <rsc@golang.org> | 2015-02-05 19:13:12 +0000 |
| commit | 1fc330d8fe0ce6cbc6fd1f47c1cf035119566fc7 (patch) | |
| tree | 5436d1070b778506897f77f44706f1f30f1d0980 /src/cmd/internal/obj | |
| parent | 8db173b85e1a151b61b38a15c9a4c97beac74191 (diff) | |
| download | go-1fc330d8fe0ce6cbc6fd1f47c1cf035119566fc7.tar.xz | |
[dev.cc] cmd/internal/obj: reconvert from liblink
cmd/internal/obj reconverted using rsc.io/c2go rev 2a95256.
- Brings in new, more regular Prog, Addr definitions
- Add Prog* argument to oclass in liblink/asm[68].c, for c2go conversion.
- Update objwriter for change in TEXT size encoding.
- Merge 5a, 6a, 8a, 9a changes into new5a, new6a, new8a, new9a (by hand).
- Add +build ignore to cmd/asm/internal/{addr,arch,asm}, cmd/asm.
They need to be updated for the changes.
- Reenable verifyAsm in cmd/go.
- Reenable GOOBJ=2 mode by default in liblink.
All architectures build successfully again.
Change-Id: I2c845c5d365aa484b570476898171bee657b626d
Reviewed-on: https://go-review.googlesource.com/3963
Reviewed-by: Rob Pike <r@golang.org>
Diffstat (limited to 'src/cmd/internal/obj')
31 files changed, 3323 insertions, 3847 deletions
diff --git a/src/cmd/internal/obj/arm/5.out.go b/src/cmd/internal/obj/arm/5.out.go index a1edfffe03..d62b99e2eb 100644 --- a/src/cmd/internal/obj/arm/5.out.go +++ b/src/cmd/internal/obj/arm/5.out.go @@ -30,17 +30,7 @@ package arm -// list[5689].c - -// obj.c - -// objfile.c - -// pass.c - -// pcln.c - -// sym.c +import "cmd/internal/obj" // TODO(ality): remove this workaround. // It's here because Pconv in liblink/list?.c references %L. @@ -57,18 +47,54 @@ const ( ) const ( - REGRET = 0 - REGEXT = 10 + REG_R0 = 32 + iota + REG_R1 + REG_R2 + REG_R3 + REG_R4 + REG_R5 + REG_R6 + REG_R7 + REG_R8 + REG_R9 + REG_R10 + REG_R11 + REG_R12 + REG_R13 + REG_R14 + REG_R15 + REG_F0 + REG_F1 + REG_F2 + REG_F3 + REG_F4 + REG_F5 + REG_F6 + REG_F7 + REG_F8 + REG_F9 + REG_F10 + REG_F11 + REG_F12 + REG_F13 + REG_F14 + REG_F15 + REG_FPSR + REG_FPCR + REG_CPSR + REG_SPSR + REGRET = REG_R0 + REGEXT = REG_R10 REGG = REGEXT - 0 REGM = REGEXT - 1 - REGTMP = 11 - REGSP = 13 - REGLINK = 14 - REGPC = 15 + REGTMP = REG_R11 + REGSP = REG_R13 + REGLINK = REG_R14 + REGPC = REG_R15 NFREG = 16 - FREGRET = 0 - FREGEXT = 7 - FREGTMP = 15 + FREGRET = REG_F0 + FREGEXT = REG_F7 + FREGTMP = REG_F15 ) /* compiler allocates register variables F0 up */ @@ -110,13 +136,13 @@ const ( C_SP C_HREG C_ADDR + C_TEXTSIZE C_GOK C_NCLASS ) const ( - AXXX = iota - AAND + AAND = obj.A_ARCHSPECIFIC + iota AEOR ASUB ARSB @@ -131,8 +157,6 @@ const ( AORR ABIC AMVN - AB - ABL ABEQ ABNE ABCS @@ -190,23 +214,12 @@ const ( AMOVM ASWPBU ASWPW - ANOP ARFE ASWI AMULA - ADATA - AGLOBL - AGOK - AHISTORY - ANAME - ARET - ATEXT AWORD - ADYNT_ - AINIT_ ABCASE ACASE - AEND AMULL AMULAL AMULLU @@ -214,31 +227,22 @@ const ( ABX ABXRET ADWORD - ASIGNAME ALDREX ASTREX ALDREXD ASTREXD APLD - AUNDEF ACLZ AMULWT AMULWB AMULAWT AMULAWB - AUSEFIELD - ATYPE - AFUNCDATA - APCDATA - ACHECKNIL - AVARDEF - AVARKILL - ADUFFCOPY - ADUFFZERO ADATABUNDLE ADATABUNDLEEND AMRC ALAST + AB = obj.AJMP + ABL = obj.ACALL ) /* scond byte */ @@ -249,56 +253,29 @@ const ( C_WBIT = 1 << 6 C_FBIT = 1 << 7 C_UBIT = 1 << 7 - C_SCOND_EQ = 0 - C_SCOND_NE = 1 - C_SCOND_HS = 2 - C_SCOND_LO = 3 - C_SCOND_MI = 4 - C_SCOND_PL = 5 - C_SCOND_VS = 6 - C_SCOND_VC = 7 - C_SCOND_HI = 8 - C_SCOND_LS = 9 - C_SCOND_GE = 10 - C_SCOND_LT = 11 - C_SCOND_GT = 12 - C_SCOND_LE = 13 - C_SCOND_NONE = 14 - C_SCOND_NV = 15 + C_SCOND_XOR = 14 + C_SCOND_EQ = 0 ^ C_SCOND_XOR + C_SCOND_NE = 1 ^ C_SCOND_XOR + C_SCOND_HS = 2 ^ C_SCOND_XOR + C_SCOND_LO = 3 ^ C_SCOND_XOR + C_SCOND_MI = 4 ^ C_SCOND_XOR + C_SCOND_PL = 5 ^ C_SCOND_XOR + C_SCOND_VS = 6 ^ C_SCOND_XOR + C_SCOND_VC = 7 ^ C_SCOND_XOR + C_SCOND_HI = 8 ^ C_SCOND_XOR + C_SCOND_LS = 9 ^ C_SCOND_XOR + C_SCOND_GE = 10 ^ C_SCOND_XOR + C_SCOND_LT = 11 ^ C_SCOND_XOR + C_SCOND_GT = 12 ^ C_SCOND_XOR + C_SCOND_LE = 13 ^ C_SCOND_XOR + C_SCOND_NONE = 14 ^ C_SCOND_XOR + C_SCOND_NV = 15 ^ C_SCOND_XOR SHIFT_LL = 0 << 5 SHIFT_LR = 1 << 5 SHIFT_AR = 2 << 5 SHIFT_RR = 3 << 5 ) -const ( - D_GOK = 0 - D_NONE = 1 - D_BRANCH = D_NONE + 1 - D_OREG = D_NONE + 2 - D_CONST = D_NONE + 7 - D_FCONST = D_NONE + 8 - D_SCONST = D_NONE + 9 - D_PSR = D_NONE + 10 - D_REG = D_NONE + 12 - D_FREG = D_NONE + 13 - D_FILE = D_NONE + 16 - D_OCONST = D_NONE + 17 - D_FILE1 = D_NONE + 18 - D_SHIFT = D_NONE + 19 - D_FPCR = D_NONE + 20 - D_REGREG = D_NONE + 21 - D_ADDR = D_NONE + 22 - D_SBIG = D_NONE + 23 - D_CONST2 = D_NONE + 24 - D_REGREG2 = D_NONE + 25 - D_EXTERN = D_NONE + 3 - D_STATIC = D_NONE + 4 - D_AUTO = D_NONE + 5 - D_PARAM = D_NONE + 6 - D_LAST = D_NONE + 26 -) - /* * this is the ranlib header */ diff --git a/src/cmd/internal/obj/arm/anames5.go b/src/cmd/internal/obj/arm/anames5.go index dd7b12aa13..067bec72ab 100644 --- a/src/cmd/internal/obj/arm/anames5.go +++ b/src/cmd/internal/obj/arm/anames5.go @@ -1,8 +1,26 @@ package arm var Anames = []string{ - "XXX", - "AND", + "XXX ", + "CALL", + "CHECKNIL", + "DATA", + "DUFFCOPY", + "DUFFZERO", + "END", + "FUNCDATA", + "GLOBL", + "JMP", + "NOP", + "PCDATA", + "RET", + "TEXT", + "TYPE", + "UNDEF", + "USEFIELD", + "VARDEF", + "VARKILL", + "AND ", "EOR", "SUB", "RSB", @@ -17,8 +35,6 @@ var Anames = []string{ "ORR", "BIC", "MVN", - "B", - "BL", "BEQ", "BNE", "BCS", @@ -76,23 +92,12 @@ var Anames = []string{ "MOVM", "SWPBU", "SWPW", - "NOP", "RFE", "SWI", "MULA", - "DATA", - "GLOBL", - "GOK", - "HISTORY", - "NAME", - "RET", - "TEXT", "WORD", - "DYNT_", - "INIT_", "BCASE", "CASE", - "END", "MULL", "MULAL", "MULLU", @@ -100,27 +105,16 @@ var Anames = []string{ "BX", "BXRET", "DWORD", - "SIGNAME", "LDREX", "STREX", "LDREXD", "STREXD", "PLD", - "UNDEF", "CLZ", "MULWT", "MULWB", "MULAWT", "MULAWB", - "USEFIELD", - "TYPE", - "FUNCDATA", - "PCDATA", - "CHECKNIL", - "VARDEF", - "VARKILL", - "DUFFCOPY", - "DUFFZERO", "DATABUNDLE", "DATABUNDLEEND", "MRC", @@ -164,6 +158,7 @@ var cnames5 = []string{ "SP", "HREG", "ADDR", + "TEXTSIZE", "GOK", "NCLASS", "SCOND = (1<<4)-1", @@ -172,25 +167,21 @@ var cnames5 = []string{ "WBIT = 1<<6", "FBIT = 1<<7", "UBIT = 1<<7", - "SCOND_EQ = 0", - "SCOND_NE = 1", - "SCOND_HS = 2", - "SCOND_LO = 3", - "SCOND_MI = 4", - "SCOND_PL = 5", - "SCOND_VS = 6", - "SCOND_VC = 7", - "SCOND_HI = 8", - "SCOND_LS = 9", - "SCOND_GE = 10", - "SCOND_LT = 11", - "SCOND_GT = 12", - "SCOND_LE = 13", - "SCOND_NONE = 14", - "SCOND_NV = 15", -} - -var dnames5 = []string{ - D_GOK: "GOK", - D_NONE: "NONE", + "SCOND_XOR = 14", + "SCOND_EQ = 0 ^ C_SCOND_XOR", + "SCOND_NE = 1 ^ C_SCOND_XOR", + "SCOND_HS = 2 ^ C_SCOND_XOR", + "SCOND_LO = 3 ^ C_SCOND_XOR", + "SCOND_MI = 4 ^ C_SCOND_XOR", + "SCOND_PL = 5 ^ C_SCOND_XOR", + "SCOND_VS = 6 ^ C_SCOND_XOR", + "SCOND_VC = 7 ^ C_SCOND_XOR", + "SCOND_HI = 8 ^ C_SCOND_XOR", + "SCOND_LS = 9 ^ C_SCOND_XOR", + "SCOND_GE = 10 ^ C_SCOND_XOR", + "SCOND_LT = 11 ^ C_SCOND_XOR", + "SCOND_GT = 12 ^ C_SCOND_XOR", + "SCOND_LE = 13 ^ C_SCOND_XOR", + "SCOND_NONE = 14 ^ C_SCOND_XOR", + "SCOND_NV = 15 ^ C_SCOND_XOR", } diff --git a/src/cmd/internal/obj/arm/asm5.go b/src/cmd/internal/obj/arm/asm5.go index 54155c98f0..54c84174e2 100644 --- a/src/cmd/internal/obj/arm/asm5.go +++ b/src/cmd/internal/obj/arm/asm5.go @@ -67,8 +67,7 @@ const ( var optab = []Optab{ /* struct Optab: OPCODE, from, prog->reg, to, type,size,param,flag */ - Optab{ATEXT, C_ADDR, C_NONE, C_LCON, 0, 0, 0, 0, 0}, - Optab{ATEXT, C_ADDR, C_REG, C_LCON, 0, 0, 0, 0, 0}, + Optab{obj.ATEXT, C_ADDR, C_NONE, C_TEXTSIZE, 0, 0, 0, 0, 0}, Optab{AADD, C_REG, C_REG, C_REG, 1, 4, 0, 0, 0}, Optab{AADD, C_REG, C_NONE, C_REG, 1, 4, 0, 0, 0}, Optab{AMOVW, C_REG, C_NONE, C_REG, 1, 4, 0, 0, 0}, @@ -245,20 +244,20 @@ var optab = []Optab{ Optab{ALDREXD, C_SOREG, C_NONE, C_REG, 91, 4, 0, 0, 0}, Optab{ASTREXD, C_SOREG, C_REG, C_REG, 92, 4, 0, 0, 0}, Optab{APLD, C_SOREG, C_NONE, C_NONE, 95, 4, 0, 0, 0}, - Optab{AUNDEF, C_NONE, C_NONE, C_NONE, 96, 4, 0, 0, 0}, + Optab{obj.AUNDEF, C_NONE, C_NONE, C_NONE, 96, 4, 0, 0, 0}, Optab{ACLZ, C_REG, C_NONE, C_REG, 97, 4, 0, 0, 0}, Optab{AMULWT, C_REG, C_REG, C_REG, 98, 4, 0, 0, 0}, Optab{AMULAWT, C_REG, C_REG, C_REGREG2, 99, 4, 0, 0, 0}, - Optab{AUSEFIELD, C_ADDR, C_NONE, C_NONE, 0, 0, 0, 0, 0}, - Optab{APCDATA, C_LCON, C_NONE, C_LCON, 0, 0, 0, 0, 0}, - Optab{AFUNCDATA, C_LCON, C_NONE, C_ADDR, 0, 0, 0, 0, 0}, - Optab{ANOP, C_NONE, C_NONE, C_NONE, 0, 0, 0, 0, 0}, - Optab{ADUFFZERO, C_NONE, C_NONE, C_SBRA, 5, 4, 0, 0, 0}, // same as ABL - Optab{ADUFFCOPY, C_NONE, C_NONE, C_SBRA, 5, 4, 0, 0, 0}, // same as ABL + Optab{obj.AUSEFIELD, C_ADDR, C_NONE, C_NONE, 0, 0, 0, 0, 0}, + Optab{obj.APCDATA, C_LCON, C_NONE, C_LCON, 0, 0, 0, 0, 0}, + Optab{obj.AFUNCDATA, C_LCON, C_NONE, C_ADDR, 0, 0, 0, 0, 0}, + Optab{obj.ANOP, C_NONE, C_NONE, C_NONE, 0, 0, 0, 0, 0}, + Optab{obj.ADUFFZERO, C_NONE, C_NONE, C_SBRA, 5, 4, 0, 0, 0}, // same as ABL + Optab{obj.ADUFFCOPY, C_NONE, C_NONE, C_SBRA, 5, 4, 0, 0, 0}, // same as ABL Optab{ADATABUNDLE, C_NONE, C_NONE, C_NONE, 100, 4, 0, 0, 0}, Optab{ADATABUNDLEEND, C_NONE, C_NONE, C_NONE, 100, 0, 0, 0, 0}, - Optab{AXXX, C_NONE, C_NONE, C_NONE, 0, 4, 0, 0, 0}, + Optab{obj.AXXX, C_NONE, C_NONE, C_NONE, 0, 4, 0, 0, 0}, } var pool struct { @@ -271,22 +270,6 @@ var oprange [ALAST]Oprang var xcmp [C_GOK + 1][C_GOK + 1]uint8 -var zprg = obj.Prog{ - As: AGOK, - Scond: C_SCOND_NONE, - Reg: NREG, - From: obj.Addr{ - Name: D_NONE, - Type: D_NONE, - Reg: NREG, - }, - To: obj.Addr{ - Name: D_NONE, - Type: D_NONE, - Reg: NREG, - }, -} - var deferreturn *obj.LSym func nocache(p *obj.Prog) { @@ -297,7 +280,6 @@ func nocache(p *obj.Prog) { /* size of a case statement including jump table */ func casesz(ctxt *obj.Link, p *obj.Prog) int32 { - var jt int = 0 var n int32 = 0 var o *Optab @@ -315,13 +297,17 @@ func casesz(ctxt *obj.Link, p *obj.Prog) int32 { return n } +// Note about encoding: Prog.scond holds the condition encoding, +// but XOR'ed with C_SCOND_XOR, so that C_SCOND_NONE == 0. +// The code that shifts the value << 28 has the responsibility +// for XORing with C_SCOND_XOR too. + // asmoutnacl assembles the instruction p. It replaces asmout for NaCl. // It returns the total number of bytes put in out, and it can change // p->pc if extra padding is necessary. // In rare cases, asmoutnacl might split p into two instructions. // origPC is the PC for this Prog (no padding is taken into account). func asmoutnacl(ctxt *obj.Link, origPC int32, p *obj.Prog, o *Optab, out []uint32) int { - var size int var reg int var q *obj.Prog @@ -332,7 +318,6 @@ func asmoutnacl(ctxt *obj.Link, origPC int32, p *obj.Prog, o *Optab, out []uint3 // instruction specific switch p.As { - default: if out != nil { asmout(ctxt, p, o, out) @@ -346,12 +331,12 @@ func asmoutnacl(ctxt *obj.Link, origPC int32, p *obj.Prog, o *Optab, out []uint3 asmout(ctxt, p, o, out) } - case AUNDEF, + case obj.AUNDEF, APLD: size = 4 if out != nil { switch p.As { - case AUNDEF: + case obj.AUNDEF: out[0] = 0xe7fedef0 // NACL_INSTR_ARM_ABORT_NOW (UDF #0xEDE0) case APLD: @@ -362,24 +347,23 @@ func asmoutnacl(ctxt *obj.Link, origPC int32, p *obj.Prog, o *Optab, out []uint3 case AB, ABL: - if p.To.Type != D_OREG { + if p.To.Type != obj.TYPE_MEM { if out != nil { asmout(ctxt, p, o, out) } } else { - - if p.To.Offset != 0 || size != 4 || p.To.Reg >= 16 || p.To.Reg < 0 { + if p.To.Offset != 0 || size != 4 || p.To.Reg > REG_R15 || p.To.Reg < REG_R0 { ctxt.Diag("unsupported instruction: %v", p) } if p.Pc&15 == 12 { p.Pc += 4 } if out != nil { - out[0] = (uint32(p.Scond)&C_SCOND)<<28 | 0x03c0013f | uint32(p.To.Reg)<<12 | uint32(p.To.Reg)<<16 // BIC $0xc000000f, Rx + out[0] = ((uint32(p.Scond)&C_SCOND)^C_SCOND_XOR)<<28 | 0x03c0013f | (uint32(p.To.Reg)&15)<<12 | (uint32(p.To.Reg)&15)<<16 // BIC $0xc000000f, Rx if p.As == AB { - out[1] = (uint32(p.Scond)&C_SCOND)<<28 | 0x012fff10 | uint32(p.To.Reg) // BX Rx // ABL + out[1] = ((uint32(p.Scond)&C_SCOND)^C_SCOND_XOR)<<28 | 0x012fff10 | (uint32(p.To.Reg)&15)<<0 // BX Rx // ABL } else { - out[1] = (uint32(p.Scond)&C_SCOND)<<28 | 0x012fff30 | uint32(p.To.Reg) // BLX Rx + out[1] = ((uint32(p.Scond)&C_SCOND)^C_SCOND_XOR)<<28 | 0x012fff30 | (uint32(p.To.Reg)&15)<<0 // BLX Rx } } @@ -388,14 +372,12 @@ func asmoutnacl(ctxt *obj.Link, origPC int32, p *obj.Prog, o *Optab, out []uint3 // align the last instruction (the actual BL) to the last instruction in a bundle if p.As == ABL { - if deferreturn == nil { deferreturn = obj.Linklookup(ctxt, "runtime.deferreturn", 0) } if p.To.Sym == deferreturn { p.Pc = ((int64(origPC) + 15) &^ 15) + 16 - int64(size) } else { - p.Pc += (16 - ((p.Pc + int64(size)) & 15)) & 15 } } @@ -414,7 +396,7 @@ func asmoutnacl(ctxt *obj.Link, origPC int32, p *obj.Prog, o *Optab, out []uint3 AMOVW, ASTREX, ASTREXD: - if p.To.Type == D_REG && p.To.Reg == 15 && p.From.Reg == 13 { // MOVW.W x(R13), PC + if p.To.Type == obj.TYPE_REG && p.To.Reg == REG_R15 && p.From.Reg == REG_R13 { // MOVW.W x(R13), PC if out != nil { asmout(ctxt, p, o, out) } @@ -422,9 +404,9 @@ func asmoutnacl(ctxt *obj.Link, origPC int32, p *obj.Prog, o *Optab, out []uint3 if out != nil { // Note: 5c and 5g reg.c know that DIV/MOD smashes R12 // so that this return instruction expansion is valid. - out[0] = out[0] &^ 0x3000 // change PC to R12 - out[1] = (uint32(p.Scond)&C_SCOND)<<28 | 0x03ccc13f // BIC $0xc000000f, R12 - out[2] = (uint32(p.Scond)&C_SCOND)<<28 | 0x012fff1c // BX R12 + out[0] = out[0] &^ 0x3000 // change PC to R12 + out[1] = ((uint32(p.Scond)&C_SCOND)^C_SCOND_XOR)<<28 | 0x03ccc13f // BIC $0xc000000f, R12 + out[2] = ((uint32(p.Scond)&C_SCOND)^C_SCOND_XOR)<<28 | 0x012fff1c // BX R12 } size += 8 @@ -433,20 +415,17 @@ func asmoutnacl(ctxt *obj.Link, origPC int32, p *obj.Prog, o *Optab, out []uint3 } break } else { - // if the instruction used more than 4 bytes, then it must have used a very large // offset to update R13, so we need to additionally mask R13. if out != nil { - - out[size/4-1] &^= 0x3000 // change PC to R12 - out[size/4] = (uint32(p.Scond)&C_SCOND)<<28 | 0x03cdd103 // BIC $0xc0000000, R13 - out[size/4+1] = (uint32(p.Scond)&C_SCOND)<<28 | 0x03ccc13f // BIC $0xc000000f, R12 - out[size/4+2] = (uint32(p.Scond)&C_SCOND)<<28 | 0x012fff1c // BX R12 + out[size/4-1] &^= 0x3000 // change PC to R12 + out[size/4] = ((uint32(p.Scond)&C_SCOND)^C_SCOND_XOR)<<28 | 0x03cdd103 // BIC $0xc0000000, R13 + out[size/4+1] = ((uint32(p.Scond)&C_SCOND)^C_SCOND_XOR)<<28 | 0x03ccc13f // BIC $0xc000000f, R12 + out[size/4+2] = ((uint32(p.Scond)&C_SCOND)^C_SCOND_XOR)<<28 | 0x012fff1c // BX R12 } // p->pc+size is only ok at 4 or 12 mod 16. if (p.Pc+int64(size))%8 == 0 { - p.Pc += 4 } size += 12 @@ -454,24 +433,23 @@ func asmoutnacl(ctxt *obj.Link, origPC int32, p *obj.Prog, o *Optab, out []uint3 } } - if p.To.Type == D_REG && p.To.Reg == 15 { + if p.To.Type == obj.TYPE_REG && p.To.Reg == REG_R15 { ctxt.Diag("unsupported instruction (move to another register and use indirect jump instead): %v", p) } - if p.To.Type == D_OREG && p.To.Reg == 13 && (p.Scond&C_WBIT != 0) && size > 4 { + if p.To.Type == obj.TYPE_MEM && p.To.Reg == REG_R13 && (p.Scond&C_WBIT != 0) && size > 4 { // function prolog with very large frame size: MOVW.W R14,-100004(R13) // split it into two instructions: // ADD $-100004, R13 // MOVW R14, 0(R13) - q = ctxt.NewProg() + q = new(obj.Prog) p.Scond &^= C_WBIT *q = *p a = &p.To - if p.To.Type == D_OREG { + if p.To.Type == obj.TYPE_MEM { a2 = &q.To } else { - a2 = &q.From } nocache(q) @@ -487,43 +465,40 @@ func asmoutnacl(ctxt *obj.Link, origPC int32, p *obj.Prog, o *Optab, out []uint3 p.As = AADD p.From = *a - p.From.Reg = NREG - p.From.Type = D_CONST - p.To = zprg.To - p.To.Type = D_REG - p.To.Reg = 13 + p.From.Reg = 0 + p.From.Type = obj.TYPE_CONST + p.To = obj.Zprog.To + p.To.Type = obj.TYPE_REG + p.To.Reg = REG_R13 // make q into p but load/store from 0(R13) q.Spadj = 0 - *a2 = zprg.From - a2.Type = D_OREG - a2.Reg = 13 + *a2 = obj.Zprog.From + a2.Type = obj.TYPE_MEM + a2.Reg = REG_R13 a2.Sym = nil a2.Offset = 0 size = int(oplook(ctxt, p).size) break } - if (p.To.Type == D_OREG && p.To.Reg != 13 && p.To.Reg != 9) || (p.From.Type == D_OREG && p.From.Reg != 13 && p.From.Reg != 9) { // MOVW Rx, X(Ry), y != 13 && y != 9 // MOVW X(Rx), Ry, x != 13 && x != 9 - if p.To.Type == D_OREG { + if (p.To.Type == obj.TYPE_MEM && p.To.Reg != REG_R13 && p.To.Reg != REG_R9) || (p.From.Type == obj.TYPE_MEM && p.From.Reg != REG_R13 && p.From.Reg != REG_R9) { // MOVW Rx, X(Ry), y != 13 && y != 9 // MOVW X(Rx), Ry, x != 13 && x != 9 + if p.To.Type == obj.TYPE_MEM { a = &p.To } else { - a = &p.From } reg = int(a.Reg) if size == 4 { - // if addr.reg == NREG, then it is probably load from x(FP) with small x, no need to modify. - if reg == NREG { - + // if addr.reg == 0, then it is probably load from x(FP) with small x, no need to modify. + if reg == 0 { if out != nil { asmout(ctxt, p, o, out) } } else { - if out != nil { - out[0] = (uint32(p.Scond)&C_SCOND)<<28 | 0x03c00103 | uint32(reg)<<16 | uint32(reg)<<12 // BIC $0xc0000000, Rx + out[0] = ((uint32(p.Scond)&C_SCOND)^C_SCOND_XOR)<<28 | 0x03c00103 | (uint32(reg)&15)<<16 | (uint32(reg)&15)<<12 // BIC $0xc0000000, Rx } if p.Pc&15 == 12 { p.Pc += 4 @@ -536,22 +511,19 @@ func asmoutnacl(ctxt *obj.Link, origPC int32, p *obj.Prog, o *Optab, out []uint3 break } else { - // if a load/store instruction takes more than 1 word to implement, then // we need to seperate the instruction into two: // 1. explicitly load the address into R11. // 2. load/store from R11. // This won't handle .W/.P, so we should reject such code. if p.Scond&(C_PBIT|C_WBIT) != 0 { - ctxt.Diag("unsupported instruction (.P/.W): %v", p) } - q = ctxt.NewProg() + q = new(obj.Prog) *q = *p - if p.To.Type == D_OREG { + if p.To.Type == obj.TYPE_MEM { a2 = &q.To } else { - a2 = &q.From } nocache(q) @@ -567,16 +539,16 @@ func asmoutnacl(ctxt *obj.Link, origPC int32, p *obj.Prog, o *Optab, out []uint3 p.As = AMOVW p.From = *a - p.From.Type = D_CONST - p.To = zprg.To - p.To.Type = D_REG - p.To.Reg = 11 + p.From.Type = obj.TYPE_ADDR + p.To = obj.Zprog.To + p.To.Type = obj.TYPE_REG + p.To.Reg = REG_R11 // make q into p but load/store from 0(R11) - *a2 = zprg.From + *a2 = obj.Zprog.From - a2.Type = D_OREG - a2.Reg = 11 + a2.Type = obj.TYPE_MEM + a2.Reg = REG_R11 a2.Sym = nil a2.Offset = 0 size = int(oplook(ctxt, p).size) @@ -589,13 +561,12 @@ func asmoutnacl(ctxt *obj.Link, origPC int32, p *obj.Prog, o *Optab, out []uint3 } // destination register specific - if p.To.Type == D_REG { - + if p.To.Type == obj.TYPE_REG { switch p.To.Reg { - case 9: + case REG_R9: ctxt.Diag("invalid instruction, cannot write to R9: %v", p) - case 13: + case REG_R13: if out != nil { out[size/4] = 0xe3cdd103 // BIC $0xc0000000, R13 } @@ -659,7 +630,6 @@ func span5(ctxt *obj.Link, cursym *obj.LSym) { if ctxt.Headtype != obj.Hnacl { m = int(o.size) } else { - m = asmoutnacl(ctxt, c, p, o, nil) c = int32(p.Pc) // asmoutnacl might change pc for alignment o = oplook(ctxt, p) // asmoutnacl might change p in rare cases @@ -671,7 +641,6 @@ func span5(ctxt *obj.Link, cursym *obj.LSym) { // must check literal pool here in case p generates many instructions if ctxt.Blitrl != nil { - i = m if p.As == ACASE { i = int(casesz(ctxt, p)) @@ -682,7 +651,7 @@ func span5(ctxt *obj.Link, cursym *obj.LSym) { } } - if m == 0 && (p.As != AFUNCDATA && p.As != APCDATA && p.As != ADATABUNDLEEND && p.As != ANOP) { + if m == 0 && (p.As != obj.AFUNCDATA && p.As != obj.APCDATA && p.As != ADATABUNDLEEND && p.As != obj.ANOP) { ctxt.Diag("zero-width instruction\n%v", p) continue } @@ -701,7 +670,7 @@ func span5(ctxt *obj.Link, cursym *obj.LSym) { break } - if p.As == AMOVW && p.To.Type == D_REG && p.To.Reg == REGPC && p.Scond&C_SCOND == C_SCOND_NONE { + if p.As == AMOVW && p.To.Type == obj.TYPE_REG && p.To.Reg == REGPC && p.Scond&C_SCOND == C_SCOND_NONE { flushpool(ctxt, p, 0, 0) } c += int32(m) @@ -738,18 +707,18 @@ func span5(ctxt *obj.Link, cursym *obj.LSym) { if(otxt < 0) otxt = -otxt; if(otxt >= (1L<<17) - 10) { - q = ctxt->arch->prg(); + q = emallocz(sizeof(Prog)); q->link = p->link; p->link = q; q->as = AB; - q->to.type = D_BRANCH; + q->to.type = TYPE_BRANCH; q->pcond = p->pcond; p->pcond = q; - q = ctxt->arch->prg(); + q = emallocz(sizeof(Prog)); q->link = p->link; p->link = q; q->as = AB; - q->to.type = D_BRANCH; + q->to.type = TYPE_BRANCH; q->pcond = q->link->link; bflag = 1; } @@ -760,7 +729,6 @@ func span5(ctxt *obj.Link, cursym *obj.LSym) { if ctxt.Headtype != obj.Hnacl { m = int(o.size) } else { - m = asmoutnacl(ctxt, c, p, o, nil) } if p.Pc != int64(opc) { @@ -777,8 +745,8 @@ func span5(ctxt *obj.Link, cursym *obj.LSym) { if m/4 > len(out) { ctxt.Diag("instruction size too large: %d > %d", m/4, len(out)) } - if m == 0 && (p.As != AFUNCDATA && p.As != APCDATA && p.As != ADATABUNDLEEND && p.As != ANOP) { - if p.As == ATEXT { + if m == 0 && (p.As != obj.AFUNCDATA && p.As != obj.APCDATA && p.As != ADATABUNDLEEND && p.As != obj.ANOP) { + if p.As == obj.ATEXT { ctxt.Autosize = int32(p.To.Offset + 4) continue } @@ -807,7 +775,6 @@ func span5(ctxt *obj.Link, cursym *obj.LSym) { * perhaps we'd be able to parallelize the span loop above. */ if ctxt.Tlsg == nil { - ctxt.Tlsg = obj.Linklookup(ctxt, "runtime.tlsg", 0) } @@ -826,7 +793,6 @@ func span5(ctxt *obj.Link, cursym *obj.LSym) { asmout(ctxt, p, o, out[:]) m = int(o.size) } else { - m = asmoutnacl(ctxt, c, p, o, out[:]) if int64(opc) != p.Pc { ctxt.Diag("asmoutnacl broken: pc changed (%d->%d) in last stage: %v", opc, int32(p.Pc), p) @@ -877,7 +843,6 @@ func span5(ctxt *obj.Link, cursym *obj.LSym) { * this happens only in extended basic blocks that exceed 4k. */ func checkpool(ctxt *obj.Link, p *obj.Prog, sz int) int { - if pool.size >= 0xff0 || immaddr(int32((p.Pc+int64(sz)+4)+4+int64(12+pool.size)-int64(pool.start+8))) == 0 { return flushpool(ctxt, p, 1, 0) } else if p.Link == nil { @@ -894,9 +859,9 @@ func flushpool(ctxt *obj.Link, p *obj.Prog, skip int, force int) int { if false && skip == 1 { fmt.Printf("note: flush literal pool at %x: len=%d ref=%x\n", uint64(p.Pc+4), pool.size, pool.start) } - q = ctxt.NewProg() + q = new(obj.Prog) q.As = AB - q.To.Type = D_BRANCH + q.To.Type = obj.TYPE_BRANCH q.Pcond = p.Link q.Link = ctxt.Blitrl q.Lineno = p.Lineno @@ -906,7 +871,7 @@ func flushpool(ctxt *obj.Link, p *obj.Prog, skip int, force int) int { } if ctxt.Headtype == obj.Hnacl && pool.size%16 != 0 { // if pool is not multiple of 16 bytes, add an alignment marker - q = ctxt.NewProg() + q = new(obj.Prog) q.As = ADATABUNDLEEND ctxt.Elitrl.Link = q @@ -920,7 +885,6 @@ func flushpool(ctxt *obj.Link, p *obj.Prog, skip int, force int) int { // for now, we set line number to the last instruction preceding them at least // this won't bloat the .debug_line tables for ctxt.Blitrl != nil { - ctxt.Blitrl.Lineno = p.Lineno ctxt.Blitrl = ctxt.Blitrl.Link } @@ -943,7 +907,7 @@ func addpool(ctxt *obj.Link, p *obj.Prog, a *obj.Addr) { c = aclass(ctxt, a) - t = zprg + t = obj.Zprog t.As = AWORD switch c { @@ -967,7 +931,7 @@ func addpool(ctxt *obj.Link, p *obj.Prog, a *obj.Addr) { C_SAUTO, C_LAUTO, C_LACON: - t.To.Type = D_CONST + t.To.Type = obj.TYPE_CONST t.To.Offset = ctxt.Instoffset break } @@ -983,9 +947,9 @@ func addpool(ctxt *obj.Link, p *obj.Prog, a *obj.Addr) { if ctxt.Headtype == obj.Hnacl && pool.size%16 == 0 { // start a new data bundle - q = ctxt.NewProg() + q = new(obj.Prog) - *q = zprg + *q = obj.Zprog q.As = ADATABUNDLE q.Pc = int64(pool.size) pool.size += 4 @@ -993,14 +957,13 @@ func addpool(ctxt *obj.Link, p *obj.Prog, a *obj.Addr) { ctxt.Blitrl = q pool.start = uint32(p.Pc) } else { - ctxt.Elitrl.Link = q } ctxt.Elitrl = q } - q = ctxt.NewProg() + q = new(obj.Prog) *q = t q.Pc = int64(pool.size) @@ -1008,7 +971,6 @@ func addpool(ctxt *obj.Link, p *obj.Prog, a *obj.Addr) { ctxt.Blitrl = q pool.start = uint32(p.Pc) } else { - ctxt.Elitrl.Link = q } ctxt.Elitrl = q @@ -1065,31 +1027,37 @@ func aclass(ctxt *obj.Link, a *obj.Addr) int { var t int switch a.Type { - case D_NONE: + case obj.TYPE_NONE: return C_NONE - case D_REG: - return C_REG + case obj.TYPE_REG: + if REG_R0 <= a.Reg && a.Reg <= REG_R15 { + return C_REG + } + if REG_F0 <= a.Reg && a.Reg <= REG_F15 { + return C_FREG + } + if a.Reg == REG_FPSR || a.Reg == REG_FPCR { + return C_FCR + } + if a.Reg == REG_CPSR || a.Reg == REG_SPSR { + return C_PSR + } + return C_GOK - case D_REGREG: + case obj.TYPE_REGREG: return C_REGREG - case D_REGREG2: + case obj.TYPE_REGREG2: return C_REGREG2 - case D_SHIFT: + case obj.TYPE_SHIFT: return C_SHIFT - case D_FREG: - return C_FREG - - case D_FPCR: - return C_FCR - - case D_OREG: + case obj.TYPE_MEM: switch a.Name { - case D_EXTERN, - D_STATIC: + case obj.NAME_EXTERN, + obj.NAME_STATIC: if a.Sym == nil || a.Sym.Name == "" { fmt.Printf("null sym external\n") return C_GOK @@ -1098,7 +1066,7 @@ func aclass(ctxt *obj.Link, a *obj.Addr) int { ctxt.Instoffset = 0 // s.b. unused but just in case return C_ADDR - case D_AUTO: + case obj.NAME_AUTO: ctxt.Instoffset = int64(ctxt.Autosize) + a.Offset t = int(immaddr(int32(ctxt.Instoffset))) if t != 0 { @@ -1117,7 +1085,7 @@ func aclass(ctxt *obj.Link, a *obj.Addr) int { return C_LAUTO - case D_PARAM: + case obj.NAME_PARAM: ctxt.Instoffset = int64(ctxt.Autosize) + a.Offset + 4 t = int(immaddr(int32(ctxt.Instoffset))) if t != 0 { @@ -1136,7 +1104,7 @@ func aclass(ctxt *obj.Link, a *obj.Addr) int { return C_LAUTO - case D_NONE: + case obj.TYPE_NONE: ctxt.Instoffset = a.Offset t = int(immaddr(int32(ctxt.Instoffset))) if t != 0 { @@ -1169,20 +1137,7 @@ func aclass(ctxt *obj.Link, a *obj.Addr) int { return C_GOK - case D_PSR: - return C_PSR - - case D_OCONST: - switch a.Name { - case D_EXTERN, - D_STATIC: - ctxt.Instoffset = 0 // s.b. unused but just in case - return C_ADDR - } - - return C_GOK - - case D_FCONST: + case obj.TYPE_FCONST: if chipzero5(ctxt, a.U.Dval) >= 0 { return C_ZFCON } @@ -1191,12 +1146,15 @@ func aclass(ctxt *obj.Link, a *obj.Addr) int { } return C_LFCON - case D_CONST, - D_CONST2: + case obj.TYPE_TEXTSIZE: + return C_TEXTSIZE + + case obj.TYPE_CONST, + obj.TYPE_ADDR: switch a.Name { - case D_NONE: + case obj.TYPE_NONE: ctxt.Instoffset = a.Offset - if a.Reg != NREG { + if a.Reg != 0 { return aconsize(ctxt) } @@ -1204,14 +1162,14 @@ func aclass(ctxt *obj.Link, a *obj.Addr) int { if t != 0 { return C_RCON } - t = int(immrot(uint32(^ctxt.Instoffset))) + t = int(immrot(^uint32(ctxt.Instoffset))) if t != 0 { return C_NCON } return C_LCON - case D_EXTERN, - D_STATIC: + case obj.NAME_EXTERN, + obj.NAME_STATIC: s = a.Sym if s == nil { break @@ -1219,18 +1177,18 @@ func aclass(ctxt *obj.Link, a *obj.Addr) int { ctxt.Instoffset = 0 // s.b. unused but just in case return C_LCONADDR - case D_AUTO: + case obj.NAME_AUTO: ctxt.Instoffset = int64(ctxt.Autosize) + a.Offset return aconsize(ctxt) - case D_PARAM: + case obj.NAME_PARAM: ctxt.Instoffset = int64(ctxt.Autosize) + a.Offset + 4 return aconsize(ctxt) } return C_GOK - case D_BRANCH: + case obj.TYPE_BRANCH: return C_SBRA } @@ -1280,7 +1238,7 @@ func oplook(ctxt *obj.Link, p *obj.Prog) *Optab { a3-- a2 = C_NONE - if p.Reg != NREG { + if p.Reg != 0 { a2 = C_REG } r = int(p.As) @@ -1427,12 +1385,11 @@ func buildop(ctxt *obj.Link) { } } } - for n = 0; optab[n].as != AXXX; n++ { + for n = 0; optab[n].as != obj.AXXX; n++ { if optab[n].flag&LPCREL != 0 { if ctxt.Flag_shared != 0 { optab[n].size += int8(optab[n].pcrelsiz) } else { - optab[n].flag &^= LPCREL } } @@ -1516,17 +1473,17 @@ func buildop(ctxt *obj.Link) { ABL, ABX, ABXRET, - ADUFFZERO, - ADUFFCOPY, + obj.ADUFFZERO, + obj.ADUFFCOPY, ASWI, AWORD, AMOVM, ARFE, - ATEXT, - AUSEFIELD, + obj.ATEXT, + obj.AUSEFIELD, ACASE, ABCASE, - ATYPE: + obj.ATYPE: break case AADDF: @@ -1574,11 +1531,11 @@ func buildop(ctxt *obj.Link) { ASTREXD, ATST, APLD, - AUNDEF, + obj.AUNDEF, ACLZ, - AFUNCDATA, - APCDATA, - ANOP, + obj.AFUNCDATA, + obj.APCDATA, + obj.ANOP, ADATABUNDLE, ADATABUNDLEEND: break @@ -1627,15 +1584,15 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { rf = int(p.From.Reg) rt = int(p.To.Reg) r = int(p.Reg) - if p.To.Type == D_NONE { + if p.To.Type == obj.TYPE_NONE { rt = 0 } if p.As == AMOVB || p.As == AMOVH || p.As == AMOVW || p.As == AMVN { r = 0 - } else if r == NREG { + } else if r == 0 { r = rt } - o1 |= uint32(rf) | uint32(r)<<16 | uint32(rt)<<12 + o1 |= (uint32(rf)&15)<<0 | (uint32(r)&15)<<16 | (uint32(rt)&15)<<12 case 2: /* movbu $I,[R],R */ aclass(ctxt, &p.From) @@ -1644,15 +1601,15 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { o1 |= uint32(immrot(uint32(ctxt.Instoffset))) rt = int(p.To.Reg) r = int(p.Reg) - if p.To.Type == D_NONE { + if p.To.Type == obj.TYPE_NONE { rt = 0 } if p.As == AMOVW || p.As == AMVN { r = 0 - } else if r == NREG { + } else if r == 0 { r = rt } - o1 |= uint32(r)<<16 | uint32(rt)<<12 + o1 |= (uint32(r)&15)<<16 | (uint32(rt)&15)<<12 case 3: /* add R<<[IR],[R],R */ o1 = mov(ctxt, p) @@ -1663,11 +1620,11 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { o1 = oprrr(ctxt, AADD, int(p.Scond)) o1 |= uint32(immrot(uint32(ctxt.Instoffset))) r = int(p.From.Reg) - if r == NREG { + if r == 0 { r = int(o.param) } - o1 |= uint32(r) << 16 - o1 |= uint32(p.To.Reg) << 12 + o1 |= (uint32(r) & 15) << 16 + o1 |= (uint32(p.To.Reg) & 15) << 12 case 5: /* bra s */ o1 = opbra(ctxt, int(p.As), int(p.Scond)) @@ -1694,8 +1651,8 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { o1 = oprrr(ctxt, AADD, int(p.Scond)) o1 |= uint32(immrot(uint32(ctxt.Instoffset))) - o1 |= uint32(p.To.Reg) << 16 - o1 |= REGPC << 12 + o1 |= (uint32(p.To.Reg) & 15) << 16 + o1 |= (REGPC & 15) << 12 case 7: /* bl (R) -> blx R */ aclass(ctxt, &p.To) @@ -1704,7 +1661,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { ctxt.Diag("%v: doesn't support BL offset(REG) where offset != 0", p) } o1 = oprrr(ctxt, ABL, int(p.Scond)) - o1 |= uint32(p.To.Reg) + o1 |= (uint32(p.To.Reg) & 15) << 0 rel = obj.Addrel(ctxt.Cursym) rel.Off = int32(ctxt.Pc) rel.Siz = 0 @@ -1715,28 +1672,28 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { o1 = oprrr(ctxt, int(p.As), int(p.Scond)) r = int(p.Reg) - if r == NREG { + if r == 0 { r = int(p.To.Reg) } - o1 |= uint32(r) + o1 |= (uint32(r) & 15) << 0 o1 |= uint32((ctxt.Instoffset & 31) << 7) - o1 |= uint32(p.To.Reg) << 12 + o1 |= (uint32(p.To.Reg) & 15) << 12 case 9: /* sll R,[R],R -> mov (R<<R),R */ o1 = oprrr(ctxt, int(p.As), int(p.Scond)) r = int(p.Reg) - if r == NREG { + if r == 0 { r = int(p.To.Reg) } - o1 |= uint32(r) - o1 |= uint32(p.From.Reg)<<8 | 1<<4 - o1 |= uint32(p.To.Reg) << 12 + o1 |= (uint32(r) & 15) << 0 + o1 |= (uint32(p.From.Reg)&15)<<8 | 1<<4 + o1 |= (uint32(p.To.Reg) & 15) << 12 case 10: /* swi [$con] */ o1 = oprrr(ctxt, int(p.As), int(p.Scond)) - if p.To.Type != D_NONE { + if p.To.Type != obj.TYPE_NONE { aclass(ctxt, &p.To) o1 |= uint32(ctxt.Instoffset & 0xffffff) } @@ -1760,7 +1717,6 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { // to the thread-local g and m pointers. // Emit a TLS relocation instead of a standard one. if rel.Sym == ctxt.Tlsg { - rel.Type = obj.R_TLS if ctxt.Flag_shared != 0 { rel.Add += ctxt.Pc - p.Pcrel.Pc - 8 - int64(rel.Siz) @@ -1771,7 +1727,6 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { rel.Type = obj.R_PCREL rel.Add += ctxt.Pc - p.Pcrel.Pc - 8 } else { - rel.Type = obj.R_ADDR } o1 = 0 @@ -1781,7 +1736,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { o1 = omvl(ctxt, p, &p.From, int(p.To.Reg)) if o.flag&LPCREL != 0 { - o2 = oprrr(ctxt, AADD, int(p.Scond)) | uint32(p.To.Reg) | REGPC<<16 | uint32(p.To.Reg)<<12 + o2 = oprrr(ctxt, AADD, int(p.Scond)) | (uint32(p.To.Reg)&15)<<0 | (REGPC&15)<<16 | (uint32(p.To.Reg)&15)<<12 } case 13: /* op $lcon, [R], R */ @@ -1791,16 +1746,16 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { break } o2 = oprrr(ctxt, int(p.As), int(p.Scond)) - o2 |= REGTMP + o2 |= REGTMP & 15 r = int(p.Reg) if p.As == AMOVW || p.As == AMVN { r = 0 - } else if r == NREG { + } else if r == 0 { r = int(p.To.Reg) } - o2 |= uint32(r) << 16 - if p.To.Type != D_NONE { - o2 |= uint32(p.To.Reg) << 12 + o2 |= (uint32(r) & 15) << 16 + if p.To.Type != obj.TYPE_NONE { + o2 |= (uint32(p.To.Reg) & 15) << 12 } case 14: /* movb/movbu/movh/movhu R,R */ @@ -1809,18 +1764,16 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { if p.As == AMOVBU || p.As == AMOVHU { o2 = oprrr(ctxt, ASRL, int(p.Scond)) } else { - o2 = oprrr(ctxt, ASRA, int(p.Scond)) } r = int(p.To.Reg) - o1 |= uint32(p.From.Reg) | uint32(r)<<12 - o2 |= uint32(r) | uint32(r)<<12 + o1 |= (uint32(p.From.Reg)&15)<<0 | (uint32(r)&15)<<12 + o2 |= uint32(r)&15 | (uint32(r)&15)<<12 if p.As == AMOVB || p.As == AMOVBS || p.As == AMOVBU { o1 |= 24 << 7 o2 |= 24 << 7 } else { - o1 |= 16 << 7 o2 |= 16 << 7 } @@ -1831,7 +1784,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { rf = int(p.From.Reg) rt = int(p.To.Reg) r = int(p.Reg) - if r == NREG { + if r == 0 { r = rt } if rt == r { @@ -1840,13 +1793,13 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { } if false { - if rt == r || rf == REGPC || r == REGPC || rt == REGPC { + if rt == r || rf == REGPC&15 || r == REGPC&15 || rt == REGPC&15 { ctxt.Diag("bad registers in MUL") prasm(p) } } - o1 |= uint32(rf)<<8 | uint32(r) | uint32(rt)<<16 + o1 |= (uint32(rf)&15)<<8 | (uint32(r)&15)<<0 | (uint32(rt)&15)<<16 case 16: /* div r,[r,]r */ o1 = 0xf << 28 @@ -1859,13 +1812,13 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { rt = int(p.To.Reg) rt2 = int(p.To.Offset) r = int(p.Reg) - o1 |= uint32(rf)<<8 | uint32(r) | uint32(rt)<<16 | uint32(rt2)<<12 + o1 |= (uint32(rf)&15)<<8 | (uint32(r)&15)<<0 | (uint32(rt)&15)<<16 | (uint32(rt2)&15)<<12 case 20: /* mov/movb/movbu R,O(R) */ aclass(ctxt, &p.To) r = int(p.To.Reg) - if r == NREG { + if r == 0 { r = int(o.param) } o1 = osr(ctxt, int(p.As), int(p.From.Reg), int32(ctxt.Instoffset), r, int(p.Scond)) @@ -1874,7 +1827,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { aclass(ctxt, &p.From) r = int(p.From.Reg) - if r == NREG { + if r == 0 { r = int(o.param) } o1 = olr(ctxt, int32(ctxt.Instoffset), r, int(p.To.Reg), int(p.Scond)) @@ -1889,10 +1842,10 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { break } r = int(p.To.Reg) - if r == NREG { + if r == 0 { r = int(o.param) } - o2 = osrr(ctxt, int(p.From.Reg), REGTMP, r, int(p.Scond)) + o2 = osrr(ctxt, int(p.From.Reg), REGTMP&15, r, int(p.Scond)) if p.As != AMOVW { o2 |= 1 << 22 } @@ -1904,10 +1857,10 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { break } r = int(p.From.Reg) - if r == NREG { + if r == 0 { r = int(o.param) } - o2 = olrr(ctxt, REGTMP, r, int(p.To.Reg), int(p.Scond)) + o2 = olrr(ctxt, REGTMP&15, r, int(p.To.Reg), int(p.Scond)) if p.As == AMOVBU || p.As == AMOVBS || p.As == AMOVB { o2 |= 1 << 22 } @@ -1920,22 +1873,22 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { } o2 = oprrr(ctxt, AADD, int(p.Scond)) - o2 |= REGTMP + o2 |= REGTMP & 15 r = int(p.From.Reg) - if r == NREG { + if r == 0 { r = int(o.param) } - o2 |= uint32(r) << 16 - if p.To.Type != D_NONE { - o2 |= uint32(p.To.Reg) << 12 + o2 |= (uint32(r) & 15) << 16 + if p.To.Type != obj.TYPE_NONE { + o2 |= (uint32(p.To.Reg) & 15) << 12 } case 35: /* mov PSR,R */ o1 = 2<<23 | 0xf<<16 | 0<<0 - o1 |= (uint32(p.Scond) & C_SCOND) << 28 + o1 |= ((uint32(p.Scond) & C_SCOND) ^ C_SCOND_XOR) << 28 o1 |= (uint32(p.From.Reg) & 1) << 22 - o1 |= uint32(p.To.Reg) << 12 + o1 |= (uint32(p.To.Reg) & 15) << 12 case 36: /* mov R,PSR */ o1 = 2<<23 | 0x29f<<12 | 0<<4 @@ -1943,9 +1896,9 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { if p.Scond&C_FBIT != 0 { o1 ^= 0x010 << 12 } - o1 |= (uint32(p.Scond) & C_SCOND) << 28 + o1 |= ((uint32(p.Scond) & C_SCOND) ^ C_SCOND_XOR) << 28 o1 |= (uint32(p.To.Reg) & 1) << 22 - o1 |= uint32(p.From.Reg) << 0 + o1 |= (uint32(p.From.Reg) & 15) << 0 case 37: /* mov $con,PSR */ aclass(ctxt, &p.From) @@ -1954,10 +1907,10 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { if p.Scond&C_FBIT != 0 { o1 ^= 0x010 << 12 } - o1 |= (uint32(p.Scond) & C_SCOND) << 28 + o1 |= ((uint32(p.Scond) & C_SCOND) ^ C_SCOND_XOR) << 28 o1 |= uint32(immrot(uint32(ctxt.Instoffset))) o1 |= (uint32(p.To.Reg) & 1) << 22 - o1 |= uint32(p.From.Reg) << 0 + o1 |= (uint32(p.From.Reg) & 15) << 0 case 38, 39: @@ -1966,14 +1919,14 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { o1 = 0x4 << 25 o1 |= uint32(p.From.Offset & 0xffff) - o1 |= uint32(p.To.Reg) << 16 + o1 |= (uint32(p.To.Reg) & 15) << 16 aclass(ctxt, &p.To) case 39: /* movm oreg,$con -> ldm */ o1 = 0x4<<25 | 1<<20 o1 |= uint32(p.To.Offset & 0xffff) - o1 |= uint32(p.From.Reg) << 16 + o1 |= (uint32(p.From.Reg) & 15) << 16 aclass(ctxt, &p.From) break } @@ -1981,7 +1934,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { if ctxt.Instoffset != 0 { ctxt.Diag("offset must be zero in MOVM; %v", p) } - o1 |= (uint32(p.Scond) & C_SCOND) << 28 + o1 |= ((uint32(p.Scond) & C_SCOND) ^ C_SCOND_XOR) << 28 if p.Scond&C_PBIT != 0 { o1 |= 1 << 24 } @@ -2005,10 +1958,10 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { if p.As != ASWPW { o1 |= 1 << 22 } - o1 |= uint32(p.From.Reg) << 16 - o1 |= uint32(p.Reg) << 0 - o1 |= uint32(p.To.Reg) << 12 - o1 |= (uint32(p.Scond) & C_SCOND) << 28 + o1 |= (uint32(p.From.Reg) & 15) << 16 + o1 |= (uint32(p.Reg) & 15) << 0 + o1 |= (uint32(p.To.Reg) & 15) << 12 + o1 |= ((uint32(p.Scond) & C_SCOND) ^ C_SCOND_XOR) << 28 case 41: /* rfe -> movm.s.w.u 0(r13),[r15] */ o1 = 0xe8fd8000 @@ -2017,7 +1970,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { v = regoff(ctxt, &p.To) r = int(p.To.Reg) - if r == NREG { + if r == 0 { r = int(o.param) } o1 = ofsr(ctxt, int(p.As), int(p.From.Reg), v, r, int(p.Scond), p) @@ -2026,7 +1979,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { v = regoff(ctxt, &p.From) r = int(p.From.Reg) - if r == NREG { + if r == 0 { r = int(o.param) } o1 = ofsr(ctxt, int(p.As), int(p.To.Reg), v, r, int(p.Scond), p) | 1<<20 @@ -2038,10 +1991,10 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { break } r = int(p.To.Reg) - if r == NREG { + if r == 0 { r = int(o.param) } - o2 = oprrr(ctxt, AADD, int(p.Scond)) | REGTMP<<12 | REGTMP<<16 | uint32(r) + o2 = oprrr(ctxt, AADD, int(p.Scond)) | (REGTMP&15)<<12 | (REGTMP&15)<<16 | (uint32(r)&15)<<0 o3 = ofsr(ctxt, int(p.As), int(p.From.Reg), 0, REGTMP, int(p.Scond), p) case 53: /* floating point load, int32 offset UGLY */ @@ -2051,11 +2004,11 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { break } r = int(p.From.Reg) - if r == NREG { + if r == 0 { r = int(o.param) } - o2 = oprrr(ctxt, AADD, int(p.Scond)) | REGTMP<<12 | REGTMP<<16 | uint32(r) - o3 = ofsr(ctxt, int(p.As), int(p.To.Reg), 0, REGTMP, int(p.Scond), p) | 1<<20 + o2 = oprrr(ctxt, AADD, int(p.Scond)) | (REGTMP&15)<<12 | (REGTMP&15)<<16 | (uint32(r)&15)<<0 + o3 = ofsr(ctxt, int(p.As), int(p.To.Reg), 0, (REGTMP&15), int(p.Scond), p) | 1<<20 case 54: /* floating point arith */ o1 = oprrr(ctxt, int(p.As), int(p.Scond)) @@ -2063,24 +2016,24 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { rf = int(p.From.Reg) rt = int(p.To.Reg) r = int(p.Reg) - if r == NREG { + if r == 0 { r = rt if p.As == AMOVF || p.As == AMOVD || p.As == AMOVFD || p.As == AMOVDF || p.As == ASQRTF || p.As == ASQRTD || p.As == AABSF || p.As == AABSD { r = 0 } } - o1 |= uint32(rf) | uint32(r)<<16 | uint32(rt)<<12 + o1 |= (uint32(rf)&15)<<0 | (uint32(r)&15)<<16 | (uint32(rt)&15)<<12 case 56: /* move to FP[CS]R */ - o1 = (uint32(p.Scond)&C_SCOND)<<28 | 0xe<<24 | 1<<8 | 1<<4 + o1 = ((uint32(p.Scond)&C_SCOND)^C_SCOND_XOR)<<28 | 0xe<<24 | 1<<8 | 1<<4 - o1 |= (uint32(p.To.Reg)+1)<<21 | uint32(p.From.Reg)<<12 + o1 |= ((uint32(p.To.Reg)&1)+1)<<21 | (uint32(p.From.Reg)&15)<<12 case 57: /* move from FP[CS]R */ - o1 = (uint32(p.Scond)&C_SCOND)<<28 | 0xe<<24 | 1<<8 | 1<<4 + o1 = ((uint32(p.Scond)&C_SCOND)^C_SCOND_XOR)<<28 | 0xe<<24 | 1<<8 | 1<<4 - o1 |= (uint32(p.From.Reg)+1)<<21 | uint32(p.To.Reg)<<12 | 1<<20 + o1 |= ((uint32(p.From.Reg)&1)+1)<<21 | (uint32(p.To.Reg)&15)<<12 | 1<<20 case 58: /* movbu R,R */ o1 = oprrr(ctxt, AAND, int(p.Scond)) @@ -2088,17 +2041,16 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { o1 |= uint32(immrot(0xff)) rt = int(p.To.Reg) r = int(p.From.Reg) - if p.To.Type == D_NONE { + if p.To.Type == obj.TYPE_NONE { rt = 0 } - if r == NREG { + if r == 0 { r = rt } - o1 |= uint32(r)<<16 | uint32(rt)<<12 + o1 |= (uint32(r)&15)<<16 | (uint32(rt)&15)<<12 case 59: /* movw/bu R<<I(R),R -> ldr indexed */ - if p.From.Reg == NREG { - + if p.From.Reg == 0 { if p.As != AMOVW { ctxt.Diag("byte MOV from shifter operand") } @@ -2115,8 +2067,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { } case 60: /* movb R(R),R -> ldrsb indexed */ - if p.From.Reg == NREG { - + if p.From.Reg == 0 { ctxt.Diag("byte MOV from shifter operand") o1 = mov(ctxt, p) break @@ -2129,8 +2080,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { o1 ^= 1<<5 | 1<<6 case 61: /* movw/b/bu R,R<<[IR](R) -> str indexed */ - if p.To.Reg == NREG { - + if p.To.Reg == 0 { ctxt.Diag("MOV to shifter operand") } o1 = osrr(ctxt, int(p.From.Reg), int(p.To.Offset), int(p.To.Reg), int(p.Scond)) @@ -2140,20 +2090,17 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { case 62: /* case R -> movw R<<2(PC),PC */ if o.flag&LPCREL != 0 { - - o1 = oprrr(ctxt, AADD, int(p.Scond)) | uint32(immrot(1)) | uint32(p.From.Reg)<<16 | REGTMP<<12 - o2 = olrr(ctxt, REGTMP, REGPC, REGTMP, int(p.Scond)) + o1 = oprrr(ctxt, AADD, int(p.Scond)) | uint32(immrot(1)) | (uint32(p.From.Reg)&15)<<16 | (REGTMP&15)<<12 + o2 = olrr(ctxt, REGTMP&15, REGPC, REGTMP, int(p.Scond)) o2 |= 2 << 7 - o3 = oprrr(ctxt, AADD, int(p.Scond)) | REGTMP | REGPC<<16 | REGPC<<12 + o3 = oprrr(ctxt, AADD, int(p.Scond)) | REGTMP&15 | (REGPC&15)<<16 | (REGPC&15)<<12 } else { - - o1 = olrr(ctxt, int(p.From.Reg), REGPC, REGPC, int(p.Scond)) + o1 = olrr(ctxt, int(p.From.Reg)&15, REGPC, REGPC, int(p.Scond)) o1 |= 2 << 7 } case 63: /* bcase */ if p.Pcond != nil { - rel = obj.Addrel(ctxt.Cursym) rel.Off = int32(ctxt.Pc) rel.Siz = 4 @@ -2161,7 +2108,6 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { rel.Sym = p.To.Sym rel.Add = p.To.Offset } else { - rel.Sym = ctxt.Cursym rel.Add = p.Pcond.Pc } @@ -2170,7 +2116,6 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { rel.Type = obj.R_PCREL rel.Add += ctxt.Pc - p.Pcrel.Pc - 16 + int64(rel.Siz) } else { - rel.Type = obj.R_ADDR } o1 = 0 @@ -2186,7 +2131,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { o2 = osr(ctxt, int(p.As), int(p.From.Reg), 0, REGTMP, int(p.Scond)) if o.flag&LPCREL != 0 { o3 = o2 - o2 = oprrr(ctxt, AADD, int(p.Scond)) | REGTMP | REGPC<<16 | REGTMP<<12 + o2 = oprrr(ctxt, AADD, int(p.Scond)) | REGTMP&15 | (REGPC&15)<<16 | (REGTMP&15)<<12 } case 65: /* mov/movbu addr,R */ @@ -2201,7 +2146,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { } if o.flag&LPCREL != 0 { o3 = o2 - o2 = oprrr(ctxt, AADD, int(p.Scond)) | REGTMP | REGPC<<16 | REGTMP<<12 + o2 = oprrr(ctxt, AADD, int(p.Scond)) | REGTMP&15 | (REGPC&15)<<16 | (REGTMP&15)<<12 } case 68: /* floating point store -> ADDR */ @@ -2213,7 +2158,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { o2 = ofsr(ctxt, int(p.As), int(p.From.Reg), 0, REGTMP, int(p.Scond), p) if o.flag&LPCREL != 0 { o3 = o2 - o2 = oprrr(ctxt, AADD, int(p.Scond)) | REGTMP | REGPC<<16 | REGTMP<<12 + o2 = oprrr(ctxt, AADD, int(p.Scond)) | REGTMP&15 | (REGPC&15)<<16 | (REGTMP&15)<<12 } case 69: /* floating point load <- ADDR */ @@ -2222,10 +2167,10 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { if !(o1 != 0) { break } - o2 = ofsr(ctxt, int(p.As), int(p.To.Reg), 0, REGTMP, int(p.Scond), p) | 1<<20 + o2 = ofsr(ctxt, int(p.As), int(p.To.Reg), 0, (REGTMP&15), int(p.Scond), p) | 1<<20 if o.flag&LPCREL != 0 { o3 = o2 - o2 = oprrr(ctxt, AADD, int(p.Scond)) | REGTMP | REGPC<<16 | REGTMP<<12 + o2 = oprrr(ctxt, AADD, int(p.Scond)) | REGTMP&15 | (REGPC&15)<<16 | (REGTMP&15)<<12 } /* ArmV4 ops: */ @@ -2233,7 +2178,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { aclass(ctxt, &p.To) r = int(p.To.Reg) - if r == NREG { + if r == 0 { r = int(o.param) } o1 = oshr(ctxt, int(p.From.Reg), int32(ctxt.Instoffset), r, int(p.Scond)) @@ -2242,7 +2187,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { aclass(ctxt, &p.From) r = int(p.From.Reg) - if r == NREG { + if r == 0 { r = int(o.param) } o1 = olhr(ctxt, int32(ctxt.Instoffset), r, int(p.To.Reg), int(p.Scond)) @@ -2259,10 +2204,10 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { break } r = int(p.To.Reg) - if r == NREG { + if r == 0 { r = int(o.param) } - o2 = oshrr(ctxt, int(p.From.Reg), REGTMP, r, int(p.Scond)) + o2 = oshrr(ctxt, int(p.From.Reg), REGTMP&15, r, int(p.Scond)) case 73: /* movb/movh/movhu L(R),R -> ldrsb/ldrsh/ldrh */ o1 = omvl(ctxt, p, &p.From, REGTMP) @@ -2271,10 +2216,10 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { break } r = int(p.From.Reg) - if r == NREG { + if r == 0 { r = int(o.param) } - o2 = olhrr(ctxt, REGTMP, r, int(p.To.Reg), int(p.Scond)) + o2 = olhrr(ctxt, REGTMP&15, r, int(p.To.Reg), int(p.Scond)) if p.As == AMOVB || p.As == AMOVBS { o2 ^= 1<<5 | 1<<6 } else if p.As == AMOVH || p.As == AMOVHS { @@ -2292,17 +2237,17 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { } /* - o1 = oprrr(ctxt, AADD, p->scond) | immrot(0) | (REGPC<<16) | (REGLINK<<12); // mov PC, LR - o2 = ((p->scond&C_SCOND)<<28) | (0x12fff<<8) | (1<<4) | p->to.reg; // BX R + o1 = oprrr(ctxt, AADD, p->scond) | immrot(0) | ((REGPC&15)<<16) | ((REGLINK&15)<<12); // mov PC, LR + o2 = (((p->scond&C_SCOND) ^ C_SCOND_XOR)<<28) | (0x12fff<<8) | (1<<4) | ((p->to.reg&15) << 0); // BX R */ // p->to.reg may be REGLINK o1 = oprrr(ctxt, AADD, int(p.Scond)) o1 |= uint32(immrot(uint32(ctxt.Instoffset))) - o1 |= uint32(p.To.Reg) << 16 - o1 |= REGTMP << 12 - o2 = oprrr(ctxt, AADD, int(p.Scond)) | uint32(immrot(0)) | REGPC<<16 | REGLINK<<12 // mov PC, LR - o3 = (uint32(p.Scond)&C_SCOND)<<28 | 0x12fff<<8 | 1<<4 | REGTMP // BX Rtmp + o1 |= (uint32(p.To.Reg) & 15) << 16 + o1 |= (REGTMP & 15) << 12 + o2 = oprrr(ctxt, AADD, int(p.Scond)) | uint32(immrot(0)) | (REGPC&15)<<16 | (REGLINK&15)<<12 // mov PC, LR + o3 = ((uint32(p.Scond)&C_SCOND)^C_SCOND_XOR)<<28 | 0x12fff<<8 | 1<<4 | REGTMP&15 // BX Rtmp case 76: /* bx O(R) when returning from fn*/ ctxt.Diag("ABXRET") @@ -2314,9 +2259,9 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { ctxt.Diag("offset must be zero in LDREX") } o1 = 0x19<<20 | 0xf9f - o1 |= uint32(p.From.Reg) << 16 - o1 |= uint32(p.To.Reg) << 12 - o1 |= (uint32(p.Scond) & C_SCOND) << 28 + o1 |= (uint32(p.From.Reg) & 15) << 16 + o1 |= (uint32(p.To.Reg) & 15) << 12 + o1 |= ((uint32(p.Scond) & C_SCOND) ^ C_SCOND_XOR) << 28 case 78: /* strex reg,oreg,reg */ aclass(ctxt, &p.From) @@ -2325,42 +2270,40 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { ctxt.Diag("offset must be zero in STREX") } o1 = 0x18<<20 | 0xf90 - o1 |= uint32(p.From.Reg) << 16 - o1 |= uint32(p.Reg) << 0 - o1 |= uint32(p.To.Reg) << 12 - o1 |= (uint32(p.Scond) & C_SCOND) << 28 + o1 |= (uint32(p.From.Reg) & 15) << 16 + o1 |= (uint32(p.Reg) & 15) << 0 + o1 |= (uint32(p.To.Reg) & 15) << 12 + o1 |= ((uint32(p.Scond) & C_SCOND) ^ C_SCOND_XOR) << 28 case 80: /* fmov zfcon,freg */ if p.As == AMOVD { - o1 = 0xeeb00b00 // VMOV imm 64 o2 = oprrr(ctxt, ASUBD, int(p.Scond)) } else { - o1 = 0x0eb00a00 // VMOV imm 32 o2 = oprrr(ctxt, ASUBF, int(p.Scond)) } v = 0x70 // 1.0 - r = int(p.To.Reg) + r = (int(p.To.Reg) & 15) << 0 // movf $1.0, r - o1 |= (uint32(p.Scond) & C_SCOND) << 28 + o1 |= ((uint32(p.Scond) & C_SCOND) ^ C_SCOND_XOR) << 28 - o1 |= uint32(r) << 12 + o1 |= (uint32(r) & 15) << 12 o1 |= (uint32(v) & 0xf) << 0 o1 |= (uint32(v) & 0xf0) << 12 // subf r,r,r - o2 |= uint32(r) | uint32(r)<<16 | uint32(r)<<12 + o2 |= (uint32(r)&15)<<0 | (uint32(r)&15)<<16 | (uint32(r)&15)<<12 case 81: /* fmov sfcon,freg */ o1 = 0x0eb00a00 // VMOV imm 32 if p.As == AMOVD { o1 = 0xeeb00b00 // VMOV imm 64 } - o1 |= (uint32(p.Scond) & C_SCOND) << 28 - o1 |= uint32(p.To.Reg) << 12 + o1 |= ((uint32(p.Scond) & C_SCOND) ^ C_SCOND_XOR) << 28 + o1 |= (uint32(p.To.Reg) & 15) << 12 v = int32(chipfloat5(ctxt, p.From.U.Dval)) o1 |= (uint32(v) & 0xf) << 0 o1 |= (uint32(v) & 0xf0) << 12 @@ -2368,65 +2311,65 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { case 82: /* fcmp freg,freg, */ o1 = oprrr(ctxt, int(p.As), int(p.Scond)) - o1 |= uint32(p.Reg)<<12 | uint32(p.From.Reg)<<0 + o1 |= (uint32(p.Reg)&15)<<12 | (uint32(p.From.Reg)&15)<<0 o2 = 0x0ef1fa10 // VMRS R15 - o2 |= (uint32(p.Scond) & C_SCOND) << 28 + o2 |= ((uint32(p.Scond) & C_SCOND) ^ C_SCOND_XOR) << 28 case 83: /* fcmp freg,, */ o1 = oprrr(ctxt, int(p.As), int(p.Scond)) - o1 |= uint32(p.From.Reg)<<12 | 1<<16 + o1 |= (uint32(p.From.Reg)&15)<<12 | 1<<16 o2 = 0x0ef1fa10 // VMRS R15 - o2 |= (uint32(p.Scond) & C_SCOND) << 28 + o2 |= ((uint32(p.Scond) & C_SCOND) ^ C_SCOND_XOR) << 28 case 84: /* movfw freg,freg - truncate float-to-fix */ o1 = oprrr(ctxt, int(p.As), int(p.Scond)) - o1 |= uint32(p.From.Reg) << 0 - o1 |= uint32(p.To.Reg) << 12 + o1 |= (uint32(p.From.Reg) & 15) << 0 + o1 |= (uint32(p.To.Reg) & 15) << 12 case 85: /* movwf freg,freg - fix-to-float */ o1 = oprrr(ctxt, int(p.As), int(p.Scond)) - o1 |= uint32(p.From.Reg) << 0 - o1 |= uint32(p.To.Reg) << 12 + o1 |= (uint32(p.From.Reg) & 15) << 0 + o1 |= (uint32(p.To.Reg) & 15) << 12 // macro for movfw freg,FTMP; movw FTMP,reg case 86: /* movfw freg,reg - truncate float-to-fix */ o1 = oprrr(ctxt, int(p.As), int(p.Scond)) - o1 |= uint32(p.From.Reg) << 0 - o1 |= FREGTMP << 12 - o2 = oprrr(ctxt, AMOVFW+AEND, int(p.Scond)) - o2 |= FREGTMP << 16 - o2 |= uint32(p.To.Reg) << 12 + o1 |= (uint32(p.From.Reg) & 15) << 0 + o1 |= (FREGTMP & 15) << 12 + o2 = oprrr(ctxt, AMOVFW+ALAST, int(p.Scond)) + o2 |= (FREGTMP & 15) << 16 + o2 |= (uint32(p.To.Reg) & 15) << 12 // macro for movw reg,FTMP; movwf FTMP,freg case 87: /* movwf reg,freg - fix-to-float */ - o1 = oprrr(ctxt, AMOVWF+AEND, int(p.Scond)) + o1 = oprrr(ctxt, AMOVWF+ALAST, int(p.Scond)) - o1 |= uint32(p.From.Reg) << 12 - o1 |= FREGTMP << 16 + o1 |= (uint32(p.From.Reg) & 15) << 12 + o1 |= (FREGTMP & 15) << 16 o2 = oprrr(ctxt, int(p.As), int(p.Scond)) - o2 |= FREGTMP << 0 - o2 |= uint32(p.To.Reg) << 12 + o2 |= (FREGTMP & 15) << 0 + o2 |= (uint32(p.To.Reg) & 15) << 12 case 88: /* movw reg,freg */ - o1 = oprrr(ctxt, AMOVWF+AEND, int(p.Scond)) + o1 = oprrr(ctxt, AMOVWF+ALAST, int(p.Scond)) - o1 |= uint32(p.From.Reg) << 12 - o1 |= uint32(p.To.Reg) << 16 + o1 |= (uint32(p.From.Reg) & 15) << 12 + o1 |= (uint32(p.To.Reg) & 15) << 16 case 89: /* movw freg,reg */ - o1 = oprrr(ctxt, AMOVFW+AEND, int(p.Scond)) + o1 = oprrr(ctxt, AMOVFW+ALAST, int(p.Scond)) - o1 |= uint32(p.From.Reg) << 16 - o1 |= uint32(p.To.Reg) << 12 + o1 |= (uint32(p.From.Reg) & 15) << 16 + o1 |= (uint32(p.To.Reg) & 15) << 12 case 90: /* tst reg */ - o1 = oprrr(ctxt, ACMP+AEND, int(p.Scond)) + o1 = oprrr(ctxt, ACMP+ALAST, int(p.Scond)) - o1 |= uint32(p.From.Reg) << 16 + o1 |= (uint32(p.From.Reg) & 15) << 16 case 91: /* ldrexd oreg,reg */ aclass(ctxt, &p.From) @@ -2435,9 +2378,9 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { ctxt.Diag("offset must be zero in LDREX") } o1 = 0x1b<<20 | 0xf9f - o1 |= uint32(p.From.Reg) << 16 - o1 |= uint32(p.To.Reg) << 12 - o1 |= (uint32(p.Scond) & C_SCOND) << 28 + o1 |= (uint32(p.From.Reg) & 15) << 16 + o1 |= (uint32(p.To.Reg) & 15) << 12 + o1 |= ((uint32(p.Scond) & C_SCOND) ^ C_SCOND_XOR) << 28 case 92: /* strexd reg,oreg,reg */ aclass(ctxt, &p.From) @@ -2446,10 +2389,10 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { ctxt.Diag("offset must be zero in STREX") } o1 = 0x1a<<20 | 0xf90 - o1 |= uint32(p.From.Reg) << 16 - o1 |= uint32(p.Reg) << 0 - o1 |= uint32(p.To.Reg) << 12 - o1 |= (uint32(p.Scond) & C_SCOND) << 28 + o1 |= (uint32(p.From.Reg) & 15) << 16 + o1 |= (uint32(p.Reg) & 15) << 0 + o1 |= (uint32(p.To.Reg) & 15) << 12 + o1 |= ((uint32(p.Scond) & C_SCOND) ^ C_SCOND_XOR) << 28 case 93: /* movb/movh/movhu addr,R -> ldrsb/ldrsh/ldrh */ o1 = omvl(ctxt, p, &p.From, REGTMP) @@ -2465,7 +2408,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { } if o.flag&LPCREL != 0 { o3 = o2 - o2 = oprrr(ctxt, AADD, int(p.Scond)) | REGTMP | REGPC<<16 | REGTMP<<12 + o2 = oprrr(ctxt, AADD, int(p.Scond)) | REGTMP&15 | (REGPC&15)<<16 | (REGTMP&15)<<12 } case 94: /* movh/movhu R,addr -> strh */ @@ -2477,18 +2420,17 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { o2 = oshr(ctxt, int(p.From.Reg), 0, REGTMP, int(p.Scond)) if o.flag&LPCREL != 0 { o3 = o2 - o2 = oprrr(ctxt, AADD, int(p.Scond)) | REGTMP | REGPC<<16 | REGTMP<<12 + o2 = oprrr(ctxt, AADD, int(p.Scond)) | REGTMP&15 | (REGPC&15)<<16 | (REGTMP&15)<<12 } case 95: /* PLD off(reg) */ o1 = 0xf5d0f000 - o1 |= uint32(p.From.Reg) << 16 + o1 |= (uint32(p.From.Reg) & 15) << 16 if p.From.Offset < 0 { o1 &^= (1 << 23) o1 |= uint32((-p.From.Offset) & 0xfff) } else { - o1 |= uint32(p.From.Offset & 0xfff) } @@ -2503,29 +2445,28 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { case 97: /* CLZ Rm, Rd */ o1 = oprrr(ctxt, int(p.As), int(p.Scond)) - o1 |= uint32(p.To.Reg) << 12 - o1 |= uint32(p.From.Reg) + o1 |= (uint32(p.To.Reg) & 15) << 12 + o1 |= (uint32(p.From.Reg) & 15) << 0 case 98: /* MULW{T,B} Rs, Rm, Rd */ o1 = oprrr(ctxt, int(p.As), int(p.Scond)) - o1 |= uint32(p.To.Reg) << 16 - o1 |= uint32(p.From.Reg) << 8 - o1 |= uint32(p.Reg) + o1 |= (uint32(p.To.Reg) & 15) << 16 + o1 |= (uint32(p.From.Reg) & 15) << 8 + o1 |= (uint32(p.Reg) & 15) << 0 case 99: /* MULAW{T,B} Rs, Rm, Rn, Rd */ o1 = oprrr(ctxt, int(p.As), int(p.Scond)) - o1 |= uint32(p.To.Reg) << 12 - o1 |= uint32(p.From.Reg) << 8 - o1 |= uint32(p.Reg) - o1 |= uint32(p.To.Offset << 16) + o1 |= (uint32(p.To.Reg) & 15) << 12 + o1 |= (uint32(p.From.Reg) & 15) << 8 + o1 |= (uint32(p.Reg) & 15) << 0 + o1 |= uint32((p.To.Offset & 15) << 16) // DATABUNDLE: BKPT $0x5be0, signify the start of NaCl data bundle; // DATABUNDLEEND: zero width alignment marker case 100: if p.As == ADATABUNDLE { - o1 = 0xe125be70 } break @@ -2549,23 +2490,23 @@ func mov(ctxt *obj.Link, p *obj.Prog) uint32 { o1 = oprrr(ctxt, int(p.As), int(p.Scond)) o1 |= uint32(p.From.Offset) rt = int(p.To.Reg) - r = int(p.Reg) - if p.To.Type == D_NONE { + if p.To.Type == obj.TYPE_NONE { rt = 0 } + r = int(p.Reg) if p.As == AMOVW || p.As == AMVN { r = 0 - } else if r == NREG { + } else if r == 0 { r = rt } - o1 |= uint32(r)<<16 | uint32(rt)<<12 + o1 |= (uint32(r)&15)<<16 | (uint32(rt)&15)<<12 return o1 } func oprrr(ctxt *obj.Link, a int, sc int) uint32 { var o uint32 - o = (uint32(sc) & C_SCOND) << 28 + o = ((uint32(sc) & C_SCOND) ^ C_SCOND_XOR) << 28 if sc&C_SBIT != 0 { o |= 1 << 20 } @@ -2671,7 +2612,6 @@ func oprrr(ctxt *obj.Link, a int, sc int) uint32 { case AMOVWF: if sc&C_UBIT == 0 { - o |= 1 << 7 /* signed */ } return o | 0xe<<24 | 0xb<<20 | 8<<16 | 0xa<<8 | 4<<4 | 0<<18 | 0<<8 // toint, double @@ -2684,7 +2624,6 @@ func oprrr(ctxt *obj.Link, a int, sc int) uint32 { case AMOVFW: if sc&C_UBIT == 0 { - o |= 1 << 16 /* signed */ } return o | 0xe<<24 | 0xb<<20 | 8<<16 | 0xa<<8 | 4<<4 | 1<<18 | 0<<8 | 1<<7 // toint, double, trunc @@ -2695,13 +2634,13 @@ func oprrr(ctxt *obj.Link, a int, sc int) uint32 { } return o | 0xe<<24 | 0xb<<20 | 8<<16 | 0xa<<8 | 4<<4 | 1<<18 | 1<<8 | 1<<7 // toint, double, trunc - case AMOVWF + AEND: // copy WtoF + case AMOVWF + ALAST: // copy WtoF return o | 0xe<<24 | 0x0<<20 | 0xb<<8 | 1<<4 - case AMOVFW + AEND: // copy FtoW + case AMOVFW + ALAST: // copy FtoW return o | 0xe<<24 | 0x1<<20 | 0xb<<8 | 1<<4 - case ACMP + AEND: // cmp imm + case ACMP + ALAST: // cmp imm return o | 0x3<<24 | 0x5<<20 // CLZ doesn't support .nil @@ -2734,7 +2673,8 @@ func opbra(ctxt *obj.Link, a int, sc int) uint32 { ctxt.Diag(".nil/.nil/.W on bra instruction") } sc &= C_SCOND - if a == ABL || a == ADUFFZERO || a == ADUFFCOPY { + sc ^= C_SCOND_XOR + if a == ABL || a == obj.ADUFFZERO || a == obj.ADUFFCOPY { return uint32(sc)<<28 | 0x5<<25 | 0x1<<24 } if sc != 0xe { @@ -2788,7 +2728,7 @@ func olr(ctxt *obj.Link, v int32, b int, r int, sc int) uint32 { if sc&C_SBIT != 0 { ctxt.Diag(".nil on LDR/STR instruction") } - o = (uint32(sc) & C_SCOND) << 28 + o = ((uint32(sc) & C_SCOND) ^ C_SCOND_XOR) << 28 if !(sc&C_PBIT != 0) { o |= 1 << 24 } @@ -2811,8 +2751,8 @@ func olr(ctxt *obj.Link, v int32, b int, r int, sc int) uint32 { ctxt.Diag("literal span too large: %d (R%d)\n%v", v, b, ctxt.Printp) } o |= uint32(v) - o |= uint32(b) << 16 - o |= uint32(r) << 12 + o |= (uint32(b) & 15) << 16 + o |= (uint32(r) & 15) << 12 return o } @@ -2822,7 +2762,7 @@ func olhr(ctxt *obj.Link, v int32, b int, r int, sc int) uint32 { if sc&C_SBIT != 0 { ctxt.Diag(".nil on LDRH/STRH instruction") } - o = (uint32(sc) & C_SCOND) << 28 + o = ((uint32(sc) & C_SCOND) ^ C_SCOND_XOR) << 28 if !(sc&C_PBIT != 0) { o |= 1 << 24 } @@ -2839,8 +2779,8 @@ func olhr(ctxt *obj.Link, v int32, b int, r int, sc int) uint32 { ctxt.Diag("literal span too large: %d (R%d)\n%v", v, b, ctxt.Printp) } o |= uint32(v)&0xf | (uint32(v)>>4)<<8 | 1<<22 - o |= uint32(b) << 16 - o |= uint32(r) << 12 + o |= (uint32(b) & 15) << 16 + o |= (uint32(r) & 15) << 12 return o } @@ -2883,7 +2823,7 @@ func ofsr(ctxt *obj.Link, a int, r int, v int32, b int, sc int, p *obj.Prog) uin if sc&C_SBIT != 0 { ctxt.Diag(".nil on FLDR/FSTR instruction") } - o = (uint32(sc) & C_SCOND) << 28 + o = ((uint32(sc) & C_SCOND) ^ C_SCOND_XOR) << 28 if !(sc&C_PBIT != 0) { o |= 1 << 24 } @@ -2902,8 +2842,8 @@ func ofsr(ctxt *obj.Link, a int, r int, v int32, b int, sc int, p *obj.Prog) uin ctxt.Diag("literal span too large: %d\n%v", v, p) } o |= (uint32(v) >> 2) & 0xFF - o |= uint32(b) << 16 - o |= uint32(r) << 12 + o |= (uint32(b) & 15) << 16 + o |= (uint32(r) & 15) << 12 switch a { default: @@ -2926,7 +2866,7 @@ func omvl(ctxt *obj.Link, p *obj.Prog, a *obj.Addr, dr int) uint32 { var o1 uint32 if !(p.Pcond != nil) { aclass(ctxt, a) - v = immrot(uint32(^ctxt.Instoffset)) + v = immrot(^uint32(ctxt.Instoffset)) if v == 0 { ctxt.Diag("missing literal") prasm(p) @@ -2935,9 +2875,8 @@ func omvl(ctxt *obj.Link, p *obj.Prog, a *obj.Addr, dr int) uint32 { o1 = oprrr(ctxt, AMVN, int(p.Scond)&C_SCOND) o1 |= uint32(v) - o1 |= uint32(dr) << 12 + o1 |= (uint32(dr) & 15) << 12 } else { - v = int32(p.Pcond.Pc - p.Pc - 8) o1 = olr(ctxt, v, REGPC, dr, int(p.Scond)&C_SCOND) } @@ -2948,7 +2887,6 @@ func omvl(ctxt *obj.Link, p *obj.Prog, a *obj.Addr, dr int) uint32 { func chipzero5(ctxt *obj.Link, e float64) int { // We use GOARM=7 to gate the use of VFPv3 vmov (imm) instructions. if ctxt.Goarm < 7 || e != 0 { - return -1 } return 0 @@ -2963,7 +2901,6 @@ func chipfloat5(ctxt *obj.Link, e float64) int { // We use GOARM=7 to gate the use of VFPv3 vmov (imm) instructions. if ctxt.Goarm < 7 { - goto no } @@ -2982,13 +2919,11 @@ func chipfloat5(ctxt *obj.Link, e float64) int { // sign bit (a) if h&0x80000000 != 0 { - n |= 1 << 7 } // exp sign bit (b) if h1 == 0x3fc00000 { - n |= 1 << 6 } diff --git a/src/cmd/internal/obj/arm/list5.go b/src/cmd/internal/obj/arm/list5.go index ee9e53e904..c37a563621 100644 --- a/src/cmd/internal/obj/arm/list5.go +++ b/src/cmd/internal/obj/arm/list5.go @@ -70,7 +70,7 @@ func Pconv(p *obj.Prog) string { a = int(p.As) s = int(p.Scond) - sc = extra[s&C_SCOND] + sc = extra[(s&C_SCOND)^C_SCOND_XOR] if s&C_SBIT != 0 { sc += ".S" } @@ -84,25 +84,21 @@ func Pconv(p *obj.Prog) string { sc += ".U" } if a == AMOVM { - if p.From.Type == D_CONST { + if p.From.Type == obj.TYPE_CONST { str = fmt.Sprintf("%.5d (%v)\t%v%s\t%v,%v", p.Pc, p.Line(), Aconv(a), sc, RAconv(&p.From), Dconv(p, 0, &p.To)) - } else if p.To.Type == D_CONST { + } else if p.To.Type == obj.TYPE_CONST { str = fmt.Sprintf("%.5d (%v)\t%v%s\t%v,%v", p.Pc, p.Line(), Aconv(a), sc, Dconv(p, 0, &p.From), RAconv(&p.To)) } else { - str = fmt.Sprintf("%.5d (%v)\t%v%s\t%v,%v", p.Pc, p.Line(), Aconv(a), sc, Dconv(p, 0, &p.From), Dconv(p, 0, &p.To)) } - } else if a == ADATA { - str = fmt.Sprintf("%.5d (%v)\t%v\t%v/%d,%v", p.Pc, p.Line(), Aconv(a), Dconv(p, 0, &p.From), p.Reg, Dconv(p, 0, &p.To)) - } else if p.As == ATEXT { - str = fmt.Sprintf("%.5d (%v)\t%v\t%v,%d,%v", p.Pc, p.Line(), Aconv(a), Dconv(p, 0, &p.From), p.Reg, Dconv(p, 0, &p.To)) - } else if p.Reg == NREG { + } else if a == obj.ADATA { + str = fmt.Sprintf("%.5d (%v)\t%v\t%v/%d,%v", p.Pc, p.Line(), Aconv(a), Dconv(p, 0, &p.From), p.From3.Offset, Dconv(p, 0, &p.To)) + } else if p.As == obj.ATEXT { + str = fmt.Sprintf("%.5d (%v)\t%v\t%v,%d,%v", p.Pc, p.Line(), Aconv(a), Dconv(p, 0, &p.From), p.From3.Offset, Dconv(p, 0, &p.To)) + } else if p.Reg == 0 { str = fmt.Sprintf("%.5d (%v)\t%v%s\t%v,%v", p.Pc, p.Line(), Aconv(a), sc, Dconv(p, 0, &p.From), Dconv(p, 0, &p.To)) - } else if p.From.Type != D_FREG { - str = fmt.Sprintf("%.5d (%v)\t%v%s\t%v,R%d,%v", p.Pc, p.Line(), Aconv(a), sc, Dconv(p, 0, &p.From), p.Reg, Dconv(p, 0, &p.To)) } else { - - str = fmt.Sprintf("%.5d (%v)\t%v%s\t%v,F%d,%v", p.Pc, p.Line(), Aconv(a), sc, Dconv(p, 0, &p.From), p.Reg, Dconv(p, 0, &p.To)) + str = fmt.Sprintf("%.5d (%v)\t%v%s\t%v,%v,%v", p.Pc, p.Line(), Aconv(a), sc, Dconv(p, 0, &p.From), Rconv(int(p.Reg)), Dconv(p, 0, &p.To)) } fp += str @@ -114,7 +110,7 @@ func Aconv(a int) string { var fp string s = "???" - if a >= AXXX && a < ALAST { + if a >= obj.AXXX && a < ALAST { s = Anames[a] } fp += s @@ -132,63 +128,53 @@ func Dconv(p *obj.Prog, flag int, a *obj.Addr) string { default: str = fmt.Sprintf("GOK-type(%d)", a.Type) - case D_NONE: + case obj.TYPE_NONE: str = "" - if a.Name != D_NONE || a.Reg != NREG || a.Sym != nil { - str = fmt.Sprintf("%v(R%d)(NONE)", Mconv(a), a.Reg) + if a.Name != obj.TYPE_NONE || a.Reg != 0 || a.Sym != nil { + str = fmt.Sprintf("%v(%v)(NONE)", Mconv(a), Rconv(int(a.Reg))) } - case D_CONST: - if a.Reg != NREG { - str = fmt.Sprintf("$%v(R%d)", Mconv(a), a.Reg) + case obj.TYPE_CONST, + obj.TYPE_ADDR: + if a.Reg != 0 { + str = fmt.Sprintf("$%v(%v)", Mconv(a), Rconv(int(a.Reg))) } else { - str = fmt.Sprintf("$%v", Mconv(a)) } - case D_CONST2: - str = fmt.Sprintf("$%d-%d", a.Offset, a.Offset2) + case obj.TYPE_TEXTSIZE: + if a.U.Argsize == obj.ArgsSizeUnknown { + str = fmt.Sprintf("$%d", a.Offset) + } else { + str = fmt.Sprintf("$%d-%d", a.Offset, a.U.Argsize) + } - case D_SHIFT: + case obj.TYPE_SHIFT: v = int(a.Offset) op = string("<<>>->@>"[((v>>5)&3)<<1:]) if v&(1<<4) != 0 { str = fmt.Sprintf("R%d%c%cR%d", v&15, op[0], op[1], (v>>8)&15) } else { - str = fmt.Sprintf("R%d%c%c%d", v&15, op[0], op[1], (v>>7)&31) } - if a.Reg != NREG { - str += fmt.Sprintf("(R%d)", a.Reg) + if a.Reg != 0 { + str += fmt.Sprintf("(%v)", Rconv(int(a.Reg))) } - case D_OREG: - if a.Reg != NREG { - str = fmt.Sprintf("%v(R%d)", Mconv(a), a.Reg) + case obj.TYPE_MEM: + if a.Reg != 0 { + str = fmt.Sprintf("%v(%v)", Mconv(a), Rconv(int(a.Reg))) } else { - str = fmt.Sprintf("%v", Mconv(a)) } - case D_REG: - str = fmt.Sprintf("R%d", a.Reg) - if a.Name != D_NONE || a.Sym != nil { - str = fmt.Sprintf("%v(R%d)(REG)", Mconv(a), a.Reg) - } - - case D_FREG: - str = fmt.Sprintf("F%d", a.Reg) - if a.Name != D_NONE || a.Sym != nil { - str = fmt.Sprintf("%v(R%d)(REG)", Mconv(a), a.Reg) + case obj.TYPE_REG: + str = fmt.Sprintf("%v", Rconv(int(a.Reg))) + if a.Name != obj.TYPE_NONE || a.Sym != nil { + str = fmt.Sprintf("%v(%v)(REG)", Mconv(a), Rconv(int(a.Reg))) } - case D_PSR: - str = fmt.Sprintf("PSR") - if a.Name != D_NONE || a.Sym != nil { - str = fmt.Sprintf("%v(PSR)(REG)", Mconv(a)) - } - - case D_BRANCH: + case obj.TYPE_BRANCH: if a.Sym != nil { str = fmt.Sprintf("%s(SB)", a.Sym.Name) } else if p != nil && p.Pcond != nil { @@ -196,14 +182,13 @@ func Dconv(p *obj.Prog, flag int, a *obj.Addr) string { } else if a.U.Branch != nil { str = fmt.Sprintf("%d", a.U.Branch.Pc) } else { - str = fmt.Sprintf("%d(PC)", a.Offset) /*-pc*/ } - case D_FCONST: + case obj.TYPE_FCONST: str = fmt.Sprintf("$%.17g", a.U.Dval) - case D_SCONST: + case obj.TYPE_SCONST: str = fmt.Sprintf("$\"%q\"", a.U.Sval) break } @@ -221,9 +206,8 @@ func RAconv(a *obj.Addr) string { str = fmt.Sprintf("GOK-reglist") switch a.Type { - case D_CONST, - D_CONST2: - if a.Reg != NREG { + case obj.TYPE_CONST: + if a.Reg != 0 { break } if a.Sym != nil { @@ -233,10 +217,9 @@ func RAconv(a *obj.Addr) string { str = "" for i = 0; i < NREG; i++ { if v&(1<<uint(i)) != 0 { - if str[0] == 0 { + if str == "" { str += "[R" } else { - str += ",R" } str += fmt.Sprintf("%d", i) @@ -253,10 +236,38 @@ func RAconv(a *obj.Addr) string { func Rconv(r int) string { var fp string - var str string + if r == 0 { + fp += "NONE" + return fp + } + if REG_R0 <= r && r <= REG_R15 { + fp += fmt.Sprintf("R%d", r-REG_R0) + return fp + } + if REG_F0 <= r && r <= REG_F15 { + fp += fmt.Sprintf("F%d", r-REG_F0) + return fp + } - str = fmt.Sprintf("R%d", r) - fp += str + switch r { + case REG_FPSR: + fp += "FPSR" + return fp + + case REG_FPCR: + fp += "FPCR" + return fp + + case REG_CPSR: + fp += "CPSR" + return fp + + case REG_SPSR: + fp += "SPSR" + return fp + } + + fp += fmt.Sprintf("badreg(%d)", r) return fp } @@ -288,19 +299,19 @@ func Mconv(a *obj.Addr) string { default: str = fmt.Sprintf("GOK-name(%d)", a.Name) - case D_NONE: + case obj.NAME_NONE: str = fmt.Sprintf("%d", a.Offset) - case D_EXTERN: + case obj.NAME_EXTERN: str = fmt.Sprintf("%s+%d(SB)", s.Name, int(a.Offset)) - case D_STATIC: + case obj.NAME_STATIC: str = fmt.Sprintf("%s<>+%d(SB)", s.Name, int(a.Offset)) - case D_AUTO: + case obj.NAME_AUTO: str = fmt.Sprintf("%s-%d(SP)", s.Name, int(-a.Offset)) - case D_PARAM: + case obj.NAME_PARAM: str = fmt.Sprintf("%s+%d(FP)", s.Name, int(a.Offset)) break } diff --git a/src/cmd/internal/obj/arm/obj5.go b/src/cmd/internal/obj/arm/obj5.go index d59c9df0e4..cd359a55dd 100644 --- a/src/cmd/internal/obj/arm/obj5.go +++ b/src/cmd/internal/obj/arm/obj5.go @@ -38,46 +38,6 @@ import ( "math" ) -var zprg5 = obj.Prog{ - As: AGOK, - Scond: C_SCOND_NONE, - Reg: NREG, - From: obj.Addr{ - Name: D_NONE, - Type: D_NONE, - Reg: NREG, - }, - To: obj.Addr{ - Name: D_NONE, - Type: D_NONE, - Reg: NREG, - }, -} - -func symtype(a *obj.Addr) int { - return int(a.Name) -} - -func isdata(p *obj.Prog) bool { - return p.As == ADATA || p.As == AGLOBL -} - -func iscall(p *obj.Prog) bool { - return p.As == ABL -} - -func datasize(p *obj.Prog) int { - return int(p.Reg) -} - -func textflag(p *obj.Prog) int { - return int(p.Reg) -} - -func settextflag(p *obj.Prog, f int) { - p.Reg = uint8(f) -} - func progedit(ctxt *obj.Link, p *obj.Prog) { var literal string var s *obj.LSym @@ -86,53 +46,48 @@ func progedit(ctxt *obj.Link, p *obj.Prog) { p.From.Class = 0 p.To.Class = 0 - // Rewrite B/BL to symbol as D_BRANCH. + // Rewrite B/BL to symbol as TYPE_BRANCH. switch p.As { - case AB, ABL, - ADUFFZERO, - ADUFFCOPY: - if p.To.Type == D_OREG && (p.To.Name == D_EXTERN || p.To.Name == D_STATIC) && p.To.Sym != nil { - p.To.Type = D_BRANCH + obj.ADUFFZERO, + obj.ADUFFCOPY: + 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 } break } // Replace TLS register fetches on older ARM procesors. switch p.As { - // Treat MRC 15, 0, <reg>, C13, C0, 3 specially. case AMRC: if p.To.Offset&0xffff0fff == 0xee1d0f70 { - // Because the instruction might be rewriten to a BL which returns in R0 // the register must be zero. if p.To.Offset&0xf000 != 0 { - ctxt.Diag("%v: TLS MRC instruction must write to R0 as it might get translated into a BL instruction", p.Line()) } if ctxt.Goarm < 7 { // Replace it with BL runtime.read_tls_fallback(SB) for ARM CPUs that lack the tls extension. if tlsfallback == nil { - tlsfallback = obj.Linklookup(ctxt, "runtime.read_tls_fallback", 0) } // MOVW LR, R11 p.As = AMOVW - p.From.Type = D_REG + p.From.Type = obj.TYPE_REG p.From.Reg = REGLINK - p.To.Type = D_REG + p.To.Type = obj.TYPE_REG p.To.Reg = REGTMP // BL runtime.read_tls_fallback(SB) p = obj.Appendp(ctxt, p) p.As = ABL - p.To.Type = D_BRANCH + p.To.Type = obj.TYPE_BRANCH p.To.Sym = tlsfallback p.To.Offset = 0 @@ -140,9 +95,9 @@ func progedit(ctxt *obj.Link, p *obj.Prog) { p = obj.Appendp(ctxt, p) p.As = AMOVW - p.From.Type = D_REG + p.From.Type = obj.TYPE_REG p.From.Reg = REGTMP - p.To.Type = D_REG + p.To.Type = obj.TYPE_REG p.To.Reg = REGLINK break } @@ -156,9 +111,8 @@ func progedit(ctxt *obj.Link, p *obj.Prog) { // Rewrite float constants to values stored in memory. switch p.As { - case AMOVF: - if p.From.Type == D_FCONST && chipfloat5(ctxt, p.From.U.Dval) < 0 && (chipzero5(ctxt, p.From.U.Dval) < 0 || p.Scond&C_SCOND != C_SCOND_NONE) { + if p.From.Type == obj.TYPE_FCONST && chipfloat5(ctxt, p.From.U.Dval) < 0 && (chipzero5(ctxt, p.From.U.Dval) < 0 || p.Scond&C_SCOND != C_SCOND_NONE) { var i32 uint32 var f32 float32 f32 = float32(p.From.U.Dval) @@ -171,14 +125,14 @@ func progedit(ctxt *obj.Link, p *obj.Prog) { s.Reachable = 0 } - p.From.Type = D_OREG + p.From.Type = obj.TYPE_MEM p.From.Sym = s - p.From.Name = D_EXTERN + p.From.Name = obj.NAME_EXTERN p.From.Offset = 0 } case AMOVD: - if p.From.Type == D_FCONST && chipfloat5(ctxt, p.From.U.Dval) < 0 && (chipzero5(ctxt, p.From.U.Dval) < 0 || p.Scond&C_SCOND != C_SCOND_NONE) { + if p.From.Type == obj.TYPE_FCONST && chipfloat5(ctxt, p.From.U.Dval) < 0 && (chipzero5(ctxt, p.From.U.Dval) < 0 || p.Scond&C_SCOND != C_SCOND_NONE) { var i64 uint64 i64 = math.Float64bits(p.From.U.Dval) literal = fmt.Sprintf("$f64.%016x", i64) @@ -189,9 +143,9 @@ func progedit(ctxt *obj.Link, p *obj.Prog) { s.Reachable = 0 } - p.From.Type = D_OREG + p.From.Type = obj.TYPE_MEM p.From.Sym = s - p.From.Name = D_EXTERN + p.From.Name = obj.NAME_EXTERN p.From.Offset = 0 } @@ -205,24 +159,18 @@ func progedit(ctxt *obj.Link, p *obj.Prog) { // offset. Rewrite $runtime.tlsg(SB) to runtime.tlsg(SB) to // compensate. if ctxt.Tlsg == nil { - ctxt.Tlsg = obj.Linklookup(ctxt, "runtime.tlsg", 0) } - if p.From.Type == D_CONST && p.From.Name == D_EXTERN && p.From.Sym == ctxt.Tlsg { - p.From.Type = D_OREG + if p.From.Type == obj.TYPE_ADDR && p.From.Name == obj.NAME_EXTERN && p.From.Sym == ctxt.Tlsg { + p.From.Type = obj.TYPE_MEM } - if p.To.Type == D_CONST && p.To.Name == D_EXTERN && p.To.Sym == ctxt.Tlsg { - p.To.Type = D_OREG + if p.To.Type == obj.TYPE_ADDR && p.To.Name == obj.NAME_EXTERN && p.To.Sym == ctxt.Tlsg { + p.To.Type = obj.TYPE_MEM } } } -func prg() *obj.Prog { - p := zprg - return &p -} - // Prog.mark const ( FOLL = 1 << 0 @@ -249,7 +197,7 @@ func nocache5(p *obj.Prog) { p.To.Class = 0 } -func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) { +func preprocess(ctxt *obj.Link, cursym *obj.LSym) { var p *obj.Prog var pl *obj.Prog var p1 *obj.Prog @@ -284,38 +232,38 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) { autoffset = 0 } cursym.Locals = autoffset - cursym.Args = p.To.Offset2 + cursym.Args = p.To.U.Argsize if ctxt.Debugzerostack != 0 { - if autoffset != 0 && !(p.Reg&obj.NOSPLIT != 0) { + if autoffset != 0 && !(p.From3.Offset&obj.NOSPLIT != 0) { // MOVW $4(R13), R1 p = obj.Appendp(ctxt, p) p.As = AMOVW - p.From.Type = D_CONST - p.From.Reg = 13 + p.From.Type = obj.TYPE_ADDR + p.From.Reg = REG_R13 p.From.Offset = 4 - p.To.Type = D_REG - p.To.Reg = 1 + p.To.Type = obj.TYPE_REG + p.To.Reg = REG_R1 // MOVW $n(R13), R2 p = obj.Appendp(ctxt, p) p.As = AMOVW - p.From.Type = D_CONST - p.From.Reg = 13 + p.From.Type = obj.TYPE_ADDR + p.From.Reg = REG_R13 p.From.Offset = 4 + int64(autoffset) - p.To.Type = D_REG - p.To.Reg = 2 + p.To.Type = obj.TYPE_REG + p.To.Reg = REG_R2 // MOVW $0, R3 p = obj.Appendp(ctxt, p) p.As = AMOVW - p.From.Type = D_CONST + p.From.Type = obj.TYPE_CONST p.From.Offset = 0 - p.To.Type = D_REG - p.To.Reg = 3 + p.To.Type = obj.TYPE_REG + p.To.Reg = REG_R3 // L: // MOVW.nil R3, 0(R1) +4 @@ -325,22 +273,22 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) { p = pl p.As = AMOVW - p.From.Type = D_REG - p.From.Reg = 3 - p.To.Type = D_OREG - p.To.Reg = 1 + p.From.Type = obj.TYPE_REG + p.From.Reg = REG_R3 + p.To.Type = obj.TYPE_MEM + p.To.Reg = REG_R1 p.To.Offset = 4 p.Scond |= C_PBIT p = obj.Appendp(ctxt, p) p.As = ACMP - p.From.Type = D_REG - p.From.Reg = 1 - p.Reg = 2 + p.From.Type = obj.TYPE_REG + p.From.Reg = REG_R1 + p.Reg = REG_R2 p = obj.Appendp(ctxt, p) p.As = ABNE - p.To.Type = D_BRANCH + p.To.Type = obj.TYPE_BRANCH p.Pcond = pl } } @@ -352,17 +300,16 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) { * expand BECOME pseudo */ for p = cursym.Text; p != nil; p = p.Link { - switch p.As { case ACASE: if ctxt.Flag_shared != 0 { linkcase(p) } - case ATEXT: + case obj.ATEXT: p.Mark |= LEAF - case ARET: + case obj.ARET: break case ADIV, @@ -376,7 +323,7 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) { cursym.Text.Mark &^= LEAF continue - case ANOP: + case obj.ANOP: q1 = p.Link q.Link = q1 /* q is non-nop */ if q1 != nil { @@ -386,8 +333,8 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) { case ABL, ABX, - ADUFFZERO, - ADUFFCOPY: + obj.ADUFFZERO, + obj.ADUFFCOPY: cursym.Text.Mark &^= LEAF fallthrough @@ -411,7 +358,7 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) { ABLE: q1 = p.Pcond if q1 != nil { - for q1.As == ANOP { + for q1.As == obj.ANOP { q1 = q1.Link p.Pcond = q1 } @@ -426,7 +373,7 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) { for p = cursym.Text; p != nil; p = p.Link { o = int(p.As) switch o { - case ATEXT: + case obj.ATEXT: autosize = int32(p.To.Offset + 4) if autosize <= 4 { if cursym.Text.Mark&LEAF != 0 { @@ -451,8 +398,8 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) { } } - if !(p.Reg&obj.NOSPLIT != 0) { - p = stacksplit(ctxt, p, autosize, bool2int(!(cursym.Text.Reg&obj.NEEDCTXT != 0))) // emit split check + if !(p.From3.Offset&obj.NOSPLIT != 0) { + p = stacksplit(ctxt, p, autosize, bool2int(!(cursym.Text.From3.Offset&obj.NEEDCTXT != 0))) // emit split check } // MOVW.W R14,$-autosize(SP) @@ -460,14 +407,14 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) { p.As = AMOVW p.Scond |= C_WBIT - p.From.Type = D_REG + p.From.Type = obj.TYPE_REG p.From.Reg = REGLINK - p.To.Type = D_OREG + p.To.Type = obj.TYPE_MEM p.To.Offset = int64(-autosize) p.To.Reg = REGSP p.Spadj = autosize - if cursym.Text.Reg&obj.WRAPPER != 0 { + if cursym.Text.From3.Offset&obj.WRAPPER != 0 { // if(g->panic != nil && g->panic->argp == FP) g->panic->argp = bottom-of-frame // // MOVW g_panic(g), R1 @@ -488,84 +435,83 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) { p = obj.Appendp(ctxt, p) p.As = AMOVW - p.From.Type = D_OREG + p.From.Type = obj.TYPE_MEM p.From.Reg = REGG p.From.Offset = 4 * int64(ctxt.Arch.Ptrsize) // G.panic - p.To.Type = D_REG - p.To.Reg = 1 + p.To.Type = obj.TYPE_REG + p.To.Reg = REG_R1 p = obj.Appendp(ctxt, p) p.As = ACMP - p.From.Type = D_CONST + p.From.Type = obj.TYPE_CONST p.From.Offset = 0 - p.Reg = 1 + p.Reg = REG_R1 p = obj.Appendp(ctxt, p) p.As = ABEQ - p.To.Type = D_BRANCH + p.To.Type = obj.TYPE_BRANCH p1 = p p = obj.Appendp(ctxt, p) p.As = AMOVW - p.From.Type = D_OREG - p.From.Reg = 1 + p.From.Type = obj.TYPE_MEM + p.From.Reg = REG_R1 p.From.Offset = 0 // Panic.argp - p.To.Type = D_REG - p.To.Reg = 2 + p.To.Type = obj.TYPE_REG + p.To.Reg = REG_R2 p = obj.Appendp(ctxt, p) p.As = AADD - p.From.Type = D_CONST + p.From.Type = obj.TYPE_CONST p.From.Offset = int64(autosize) + 4 - p.Reg = 13 - p.To.Type = D_REG - p.To.Reg = 3 + p.Reg = REG_R13 + p.To.Type = obj.TYPE_REG + p.To.Reg = REG_R3 p = obj.Appendp(ctxt, p) p.As = ACMP - p.From.Type = D_REG - p.From.Reg = 2 - p.Reg = 3 + p.From.Type = obj.TYPE_REG + p.From.Reg = REG_R2 + p.Reg = REG_R3 p = obj.Appendp(ctxt, p) p.As = ABNE - p.To.Type = D_BRANCH + p.To.Type = obj.TYPE_BRANCH p2 = p p = obj.Appendp(ctxt, p) p.As = AADD - p.From.Type = D_CONST + p.From.Type = obj.TYPE_CONST p.From.Offset = 4 - p.Reg = 13 - p.To.Type = D_REG - p.To.Reg = 4 + p.Reg = REG_R13 + p.To.Type = obj.TYPE_REG + p.To.Reg = REG_R4 p = obj.Appendp(ctxt, p) p.As = AMOVW - p.From.Type = D_REG - p.From.Reg = 4 - p.To.Type = D_OREG - p.To.Reg = 1 + p.From.Type = obj.TYPE_REG + p.From.Reg = REG_R4 + p.To.Type = obj.TYPE_MEM + p.To.Reg = REG_R1 p.To.Offset = 0 // Panic.argp p = obj.Appendp(ctxt, p) - p.As = ANOP + p.As = obj.ANOP p1.Pcond = p p2.Pcond = p } - case ARET: + case obj.ARET: nocache5(p) if cursym.Text.Mark&LEAF != 0 { if !(autosize != 0) { p.As = AB - p.From = zprg5.From + p.From = obj.Zprog.From if p.To.Sym != nil { // retjmp - p.To.Type = D_BRANCH + p.To.Type = obj.TYPE_BRANCH } else { - - p.To.Type = D_OREG + p.To.Type = obj.TYPE_MEM p.To.Offset = 0 p.To.Reg = REGLINK } @@ -576,10 +522,10 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) { p.As = AMOVW p.Scond |= C_PBIT - p.From.Type = D_OREG + p.From.Type = obj.TYPE_MEM p.From.Offset = int64(autosize) p.From.Reg = REGSP - p.To.Type = D_REG + p.To.Type = obj.TYPE_REG p.To.Reg = REGPC // If there are instructions following @@ -589,19 +535,19 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) { p.To.Reg = REGLINK q2 = obj.Appendp(ctxt, p) q2.As = AB - q2.To.Type = D_BRANCH + q2.To.Type = obj.TYPE_BRANCH q2.To.Sym = p.To.Sym p.To.Sym = nil p = q2 } case AADD: - if p.From.Type == D_CONST && p.From.Reg == NREG && p.To.Type == D_REG && p.To.Reg == REGSP { + if p.From.Type == obj.TYPE_CONST && p.From.Reg == 0 && p.To.Type == obj.TYPE_REG && p.To.Reg == REGSP { p.Spadj = int32(-p.From.Offset) } case ASUB: - if p.From.Type == D_CONST && p.From.Reg == NREG && p.To.Type == D_REG && p.To.Reg == REGSP { + if p.From.Type == obj.TYPE_CONST && p.From.Reg == 0 && p.To.Type == obj.TYPE_REG && p.To.Reg == REGSP { p.Spadj = int32(p.From.Offset) } @@ -612,10 +558,10 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) { if ctxt.Debugdivmod != 0 { break } - if p.From.Type != D_REG { + if p.From.Type != obj.TYPE_REG { break } - if p.To.Type != D_REG { + if p.To.Type != obj.TYPE_REG { break } q1 = p @@ -625,9 +571,9 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) { p.As = AMOVW p.Lineno = q1.Lineno - p.From.Type = D_REG + p.From.Type = obj.TYPE_REG p.From.Reg = q1.From.Reg - p.To.Type = D_OREG + p.To.Type = obj.TYPE_MEM p.To.Reg = REGSP p.To.Offset = 4 @@ -636,12 +582,12 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) { p.As = AMOVW p.Lineno = q1.Lineno - p.From.Type = D_REG - p.From.Reg = int8(q1.Reg) - if q1.Reg == NREG { + p.From.Type = obj.TYPE_REG + p.From.Reg = q1.Reg + if q1.Reg == 0 { p.From.Reg = q1.To.Reg } - p.To.Type = D_REG + p.To.Type = obj.TYPE_REG p.To.Reg = REGTMP p.To.Offset = 0 @@ -650,7 +596,7 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) { p.As = ABL p.Lineno = q1.Lineno - p.To.Type = D_BRANCH + p.To.Type = obj.TYPE_BRANCH switch o { case ADIV: p.To.Sym = ctxt.Sym_div @@ -671,10 +617,10 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) { p.As = AMOVW p.Lineno = q1.Lineno - p.From.Type = D_REG + p.From.Type = obj.TYPE_REG p.From.Reg = REGTMP p.From.Offset = 0 - p.To.Type = D_REG + p.To.Type = obj.TYPE_REG p.To.Reg = q1.To.Reg /* ADD $8,SP */ @@ -682,11 +628,11 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) { p.As = AADD p.Lineno = q1.Lineno - p.From.Type = D_CONST - p.From.Reg = NREG + p.From.Type = obj.TYPE_CONST + p.From.Reg = 0 p.From.Offset = 8 - p.Reg = NREG - p.To.Type = D_REG + p.Reg = 0 + p.To.Type = obj.TYPE_REG p.To.Reg = REGSP p.Spadj = -8 @@ -695,34 +641,34 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) { /* TODO: Remove SP adjustments; see issue 6699. */ q1.As = AMOVW - q1.From.Type = D_OREG + q1.From.Type = obj.TYPE_MEM q1.From.Reg = REGSP q1.From.Offset = 0 - q1.Reg = NREG - q1.To.Type = D_REG + q1.Reg = 0 + q1.To.Type = obj.TYPE_REG q1.To.Reg = REGTMP /* SUB $8,SP */ q1 = obj.Appendp(ctxt, q1) q1.As = AMOVW - q1.From.Type = D_REG + q1.From.Type = obj.TYPE_REG q1.From.Reg = REGTMP - q1.Reg = NREG - q1.To.Type = D_OREG + q1.Reg = 0 + q1.To.Type = obj.TYPE_MEM q1.To.Reg = REGSP q1.To.Offset = -8 q1.Scond |= C_WBIT q1.Spadj = 8 case AMOVW: - if (p.Scond&C_WBIT != 0) && p.To.Type == D_OREG && p.To.Reg == REGSP { + if (p.Scond&C_WBIT != 0) && p.To.Type == obj.TYPE_MEM && p.To.Reg == REGSP { p.Spadj = int32(-p.To.Offset) } - if (p.Scond&C_PBIT != 0) && p.From.Type == D_OREG && p.From.Reg == REGSP && p.To.Reg != REGPC { + if (p.Scond&C_PBIT != 0) && p.From.Type == obj.TYPE_MEM && p.From.Reg == REGSP && p.To.Reg != REGPC { p.Spadj = int32(-p.From.Offset) } - if p.From.Type == D_CONST && p.From.Reg == REGSP && p.To.Type == D_REG && p.To.Reg == REGSP { + if p.From.Type == obj.TYPE_ADDR && p.From.Reg == REGSP && p.To.Type == obj.TYPE_REG && p.To.Reg == REGSP { p.Spadj = int32(-p.From.Offset) } break @@ -730,6 +676,10 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) { } } +func isfloatreg(a *obj.Addr) int { + return bool2int(a.Type == obj.TYPE_REG && REG_F0 <= a.Reg && a.Reg <= REG_F15) +} + func softfloat(ctxt *obj.Link, cursym *obj.LSym) { var p *obj.Prog var next *obj.Prog @@ -751,7 +701,7 @@ func softfloat(ctxt *obj.Link, cursym *obj.LSym) { for p = cursym.Text; p != nil; p = p.Link { switch p.As { case AMOVW: - if p.To.Type == D_FREG || p.From.Type == D_FREG { + if isfloatreg(&p.To) != 0 || isfloatreg(&p.From) != 0 { goto soft } goto notsoft @@ -786,15 +736,15 @@ func softfloat(ctxt *obj.Link, cursym *obj.LSym) { soft: if !(wasfloat != 0) || (p.Mark&LABEL != 0) { - next = ctxt.NewProg() + next = new(obj.Prog) *next = *p // BL _sfloat(SB) - *p = zprg5 + *p = obj.Zprog p.Link = next p.As = ABL - p.To.Type = D_BRANCH + p.To.Type = obj.TYPE_BRANCH p.To.Sym = symsfloat p.Lineno = next.Lineno @@ -814,14 +764,14 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32, noctxt int) *obj.P p = obj.Appendp(ctxt, p) p.As = AMOVW - p.From.Type = D_OREG + p.From.Type = obj.TYPE_MEM p.From.Reg = REGG 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 = D_REG - p.To.Reg = 1 + p.To.Type = obj.TYPE_REG + p.To.Reg = REG_R1 if framesize <= obj.StackSmall { // small stack: SP < stackguard @@ -829,8 +779,8 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32, noctxt int) *obj.P p = obj.Appendp(ctxt, p) p.As = ACMP - p.From.Type = D_REG - p.From.Reg = 1 + p.From.Type = obj.TYPE_REG + p.From.Reg = REG_R1 p.Reg = REGSP } else if framesize <= obj.StackBig { // large stack: SP-framesize < stackguard-StackSmall @@ -839,19 +789,18 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32, noctxt int) *obj.P p = obj.Appendp(ctxt, p) p.As = AMOVW - p.From.Type = D_CONST + p.From.Type = obj.TYPE_ADDR p.From.Reg = REGSP p.From.Offset = int64(-framesize) - p.To.Type = D_REG - p.To.Reg = 2 + p.To.Type = obj.TYPE_REG + p.To.Reg = REG_R2 p = obj.Appendp(ctxt, p) p.As = ACMP - p.From.Type = D_REG - p.From.Reg = 1 - p.Reg = 2 + p.From.Type = obj.TYPE_REG + p.From.Reg = REG_R1 + p.Reg = REG_R2 } else { - // Such a large stack we need to protect against wraparound // if SP is close to zero. // SP-stackguard+StackGuard < framesize + (StackGuard-StackSmall) @@ -865,40 +814,40 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32, noctxt int) *obj.P p = obj.Appendp(ctxt, p) p.As = ACMP - p.From.Type = D_CONST + p.From.Type = obj.TYPE_CONST p.From.Offset = int64(uint32(obj.StackPreempt & (1<<32 - 1))) - p.Reg = 1 + p.Reg = REG_R1 p = obj.Appendp(ctxt, p) p.As = AMOVW - p.From.Type = D_CONST + p.From.Type = obj.TYPE_ADDR p.From.Reg = REGSP p.From.Offset = obj.StackGuard - p.To.Type = D_REG - p.To.Reg = 2 + p.To.Type = obj.TYPE_REG + p.To.Reg = REG_R2 p.Scond = C_SCOND_NE p = obj.Appendp(ctxt, p) p.As = ASUB - p.From.Type = D_REG - p.From.Reg = 1 - p.To.Type = D_REG - p.To.Reg = 2 + p.From.Type = obj.TYPE_REG + p.From.Reg = REG_R1 + p.To.Type = obj.TYPE_REG + p.To.Reg = REG_R2 p.Scond = C_SCOND_NE p = obj.Appendp(ctxt, p) p.As = AMOVW - p.From.Type = D_CONST + p.From.Type = obj.TYPE_ADDR p.From.Offset = int64(framesize) + (obj.StackGuard - obj.StackSmall) - p.To.Type = D_REG - p.To.Reg = 3 + p.To.Type = obj.TYPE_REG + p.To.Reg = REG_R3 p.Scond = C_SCOND_NE p = obj.Appendp(ctxt, p) p.As = ACMP - p.From.Type = D_REG - p.From.Reg = 3 - p.Reg = 2 + p.From.Type = obj.TYPE_REG + p.From.Reg = REG_R3 + p.Reg = REG_R2 p.Scond = C_SCOND_NE } @@ -907,21 +856,20 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32, noctxt int) *obj.P p.As = AMOVW p.Scond = C_SCOND_LS - p.From.Type = D_REG + p.From.Type = obj.TYPE_REG p.From.Reg = REGLINK - p.To.Type = D_REG - p.To.Reg = 3 + p.To.Type = obj.TYPE_REG + p.To.Reg = REG_R3 // BL.LS runtime.morestack(SB) // modifies LR, returns with LO still asserted p = obj.Appendp(ctxt, p) p.As = ABL p.Scond = C_SCOND_LS - p.To.Type = D_BRANCH + 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[noctxt] } @@ -929,7 +877,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32, noctxt int) *obj.P p = obj.Appendp(ctxt, p) p.As = ABLS - p.To.Type = D_BRANCH + p.To.Type = obj.TYPE_BRANCH p.Pcond = ctxt.Cursym.Text.Link return p @@ -951,7 +899,7 @@ func follow(ctxt *obj.Link, s *obj.LSym) { ctxt.Cursym = s - firstp = ctxt.NewProg() + firstp = new(obj.Prog) lastp = firstp xfol(ctxt, s.Text, &lastp) lastp.Link = nil @@ -1011,7 +959,7 @@ loop: a = int(p.As) if a == AB { q = p.Pcond - if q != nil && q.As != ATEXT { + if q != nil && q.As != obj.ATEXT { p.Mark |= FOLL p = q if !(p.Mark&FOLL != 0) { @@ -1028,12 +976,12 @@ loop: break } a = int(q.As) - if a == ANOP { + if a == obj.ANOP { i-- continue } - if a == AB || (a == ARET && q.Scond == C_SCOND_NONE) || a == ARFE || a == AUNDEF { + if a == AB || (a == obj.ARET && q.Scond == C_SCOND_NONE) || a == ARFE || a == obj.AUNDEF { goto copy } if q.Pcond == nil || (q.Pcond.Mark&FOLL != 0) { @@ -1045,7 +993,7 @@ loop: copy: for { - r = ctxt.NewProg() + r = new(obj.Prog) *r = *p if !(r.Mark&FOLL != 0) { fmt.Printf("can't happen 1\n") @@ -1060,7 +1008,7 @@ loop: (*last).Link = r *last = r - if a == AB || (a == ARET && q.Scond == C_SCOND_NONE) || a == ARFE || a == AUNDEF { + if a == AB || (a == obj.ARET && q.Scond == C_SCOND_NONE) || a == ARFE || a == obj.AUNDEF { return } r.As = ABNE @@ -1080,10 +1028,10 @@ loop: } a = AB - q = ctxt.NewProg() + q = new(obj.Prog) q.As = int16(a) q.Lineno = p.Lineno - q.To.Type = D_BRANCH + q.To.Type = obj.TYPE_BRANCH q.To.Offset = p.Pc q.Pcond = p p = q @@ -1092,14 +1040,14 @@ loop: p.Mark |= FOLL (*last).Link = p *last = p - if a == AB || (a == ARET && p.Scond == C_SCOND_NONE) || a == ARFE || a == AUNDEF { + if a == AB || (a == obj.ARET && p.Scond == C_SCOND_NONE) || a == ARFE || a == obj.AUNDEF { return } if p.Pcond != nil { if a != ABL && a != ABX && p.Link != nil { q = obj.Brchain(ctxt, p.Link) - if a != ATEXT && a != ABCASE { + if a != obj.ATEXT && a != ABCASE { if q != nil && (q.Mark&FOLL != 0) { p.As = int16(relinv(a)) p.Link = p.Pcond @@ -1127,46 +1075,16 @@ loop: } var Linkarm = obj.LinkArch{ - ByteOrder: binary.LittleEndian, - Pconv: Pconv, - Name: "arm", - Thechar: '5', - Endian: obj.LittleEndian, - Addstacksplit: addstacksplit, - Assemble: span5, - Datasize: datasize, - Follow: follow, - Iscall: iscall, - Isdata: isdata, - Prg: prg, - Progedit: progedit, - Settextflag: settextflag, - Symtype: symtype, - Textflag: textflag, - Minlc: 4, - Ptrsize: 4, - Regsize: 4, - D_ADDR: D_ADDR, - D_AUTO: D_AUTO, - D_BRANCH: D_BRANCH, - D_CONST: D_CONST, - D_EXTERN: D_EXTERN, - D_FCONST: D_FCONST, - D_NONE: D_NONE, - D_PARAM: D_PARAM, - D_SCONST: D_SCONST, - D_STATIC: D_STATIC, - D_OREG: D_OREG, - ACALL: ABL, - ADATA: ADATA, - AEND: AEND, - AFUNCDATA: AFUNCDATA, - AGLOBL: AGLOBL, - AJMP: AB, - ANOP: ANOP, - APCDATA: APCDATA, - ARET: ARET, - ATEXT: ATEXT, - ATYPE: ATYPE, - AUSEFIELD: AUSEFIELD, + ByteOrder: binary.LittleEndian, + Pconv: Pconv, + Name: "arm", + Thechar: '5', + Endian: obj.LittleEndian, + Preprocess: preprocess, + Assemble: span5, + Follow: follow, + Progedit: progedit, + Minlc: 4, + Ptrsize: 4, + Regsize: 4, } diff --git a/src/cmd/internal/obj/data.go b/src/cmd/internal/obj/data.go index 35d5182db8..66995a3cd7 100644 --- a/src/cmd/internal/obj/data.go +++ b/src/cmd/internal/obj/data.go @@ -37,7 +37,6 @@ import ( ) func mangle(file string) { - log.Fatalf("%s: mangled input file", file) } @@ -58,7 +57,7 @@ func Symgrow(ctxt *Link, s *LSym, lsiz int64) { func savedata(ctxt *Link, s *LSym, p *Prog, pn string) { off := int32(p.From.Offset) - siz := int32(ctxt.Arch.Datasize(p)) + siz := int32(p.From3.Offset) if off < 0 || siz < 0 || off >= 1<<30 || siz >= 100 { mangle(pn) } @@ -71,7 +70,7 @@ func savedata(ctxt *Link, s *LSym, p *Prog, pn string) { default: ctxt.Diag("bad data: %P", p) - case ctxt.Arch.D_FCONST: + case TYPE_FCONST: switch siz { default: ctxt.Diag("unexpected %d-byte floating point constant", siz) @@ -85,11 +84,11 @@ func savedata(ctxt *Link, s *LSym, p *Prog, pn string) { ctxt.Arch.ByteOrder.PutUint64(s.P[off:], flt) } - case ctxt.Arch.D_SCONST: + case TYPE_SCONST: copy(s.P[off:off+siz], p.To.U.Sval) - case ctxt.Arch.D_CONST, ctxt.Arch.D_ADDR: - if p.To.Sym != nil || int(p.To.Type) == ctxt.Arch.D_ADDR { + case TYPE_CONST, TYPE_ADDR: + if p.To.Sym != nil || int(p.To.Type) == TYPE_ADDR { r := Addrel(s) r.Off = off r.Siz = uint8(siz) @@ -119,7 +118,7 @@ func Addrel(s *LSym) *Reloc { return &s.R[len(s.R)-1] } -func setuintxx(ctxt *Link, s *LSym, off int64, v uint64, wid int64) int64 { +func Setuintxx(ctxt *Link, s *LSym, off int64, v uint64, wid int64) int64 { if s.Type == 0 { s.Type = SDATA } @@ -147,7 +146,7 @@ func adduintxx(ctxt *Link, s *LSym, v uint64, wid int) int64 { var off int64 off = s.Size - setuintxx(ctxt, s, off, v, int64(wid)) + Setuintxx(ctxt, s, off, v, int64(wid)) return off } @@ -168,19 +167,19 @@ func Adduint64(ctxt *Link, s *LSym, v uint64) int64 { } func setuint8(ctxt *Link, s *LSym, r int64, v uint8) int64 { - return setuintxx(ctxt, s, r, uint64(v), 1) + return Setuintxx(ctxt, s, r, uint64(v), 1) } func setuint16(ctxt *Link, s *LSym, r int64, v uint16) int64 { - return setuintxx(ctxt, s, r, uint64(v), 2) + return Setuintxx(ctxt, s, r, uint64(v), 2) } func setuint32(ctxt *Link, s *LSym, r int64, v uint32) int64 { - return setuintxx(ctxt, s, r, uint64(v), 4) + return Setuintxx(ctxt, s, r, uint64(v), 4) } func setuint64(ctxt *Link, s *LSym, r int64, v uint64) int64 { - return setuintxx(ctxt, s, r, v, 8) + return Setuintxx(ctxt, s, r, v, 8) } func addaddrplus(ctxt *Link, s *LSym, t *LSym, add int64) int64 { diff --git a/src/cmd/internal/obj/funcdata.go b/src/cmd/internal/obj/funcdata.go index 1d10b22ac8..44cba7aae8 100644 --- a/src/cmd/internal/obj/funcdata.go +++ b/src/cmd/internal/obj/funcdata.go @@ -1,12 +1,13 @@ -// cmd/9l/noop.c, cmd/9l/pass.c, cmd/9l/span.c from Vita Nuova. +// Inferno utils/5c/list.c +// http://code.google.com/p/inferno-os/source/browse/utils/5c/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-2008 Vita Nuova Holdings Limited (www.vitanuova.com) +// 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-2008 Lucent Technologies Inc. and others +// 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 @@ -74,5 +75,5 @@ const ( FUNCDATA_ArgsPointerMaps = 0 FUNCDATA_LocalsPointerMaps = 1 FUNCDATA_DeadValueMaps = 2 - ArgsSizeUnknown = 0x80000000 + ArgsSizeUnknown = -0x80000000 ) diff --git a/src/cmd/internal/obj/go.go b/src/cmd/internal/obj/go.go index b0b21835f5..005730d9a3 100644 --- a/src/cmd/internal/obj/go.go +++ b/src/cmd/internal/obj/go.go @@ -5,12 +5,75 @@ package obj import ( + "fmt" "math" + "os" "strings" ) // go-specific code shared across loaders (5l, 6l, 8l). +var Framepointer_enabled int + +var fieldtrack_enabled int + +var Zprog Prog + +// Toolchain experiments. +// These are controlled by the GOEXPERIMENT environment +// variable recorded when the toolchain is built. +// This list is also known to cmd/gc. +var exper = []struct { + name string + val *int +}{ + struct { + name string + val *int + }{"fieldtrack", &fieldtrack_enabled}, + struct { + name string + val *int + }{"framepointer", &Framepointer_enabled}, +} + +func addexp(s string) { + var i int + + for i = 0; i < len(exper); i++ { + if exper[i].name == s { + if exper[i].val != nil { + *exper[i].val = 1 + } + return + } + } + + fmt.Printf("unknown experiment %s\n", s) + os.Exit(2) +} + +func linksetexp() { + for _, f := range strings.Split(goexperiment, ",") { + if f != "" { + addexp(f) + } + } +} + +func expstring() string { + buf := "X" + for i := range exper { + if *exper[i].val != 0 { + buf += "," + exper[i].name + } + } + if buf == "X" { + buf += ",none" + } + return "X:" + buf[2:] +} + // replace all "". with pkg. func expandpkg(t0 string, pkg string) string { return strings.Replace(t0, `"".`, pkg+".", -1) diff --git a/src/cmd/internal/obj/i386/8.out.go b/src/cmd/internal/obj/i386/8.out.go index f0e3b332d2..72463471bb 100644 --- a/src/cmd/internal/obj/i386/8.out.go +++ b/src/cmd/internal/obj/i386/8.out.go @@ -30,9 +30,10 @@ package i386 +import "cmd/internal/obj" + const ( - AXXX = iota - AAAA + AAAA = obj.A_ARCHSPECIFIC + iota AAAD AAAM AAAS @@ -62,7 +63,6 @@ const ( ABTSL ABTSW ABYTE - ACALL ACLC ACLD ACLI @@ -76,7 +76,6 @@ const ( ACMPSW ADAA ADAS - ADATA ADECB ADECL ADECW @@ -84,9 +83,6 @@ const ( ADIVL ADIVW AENTER - AGLOBL - AGOK - AHISTORY AHLT AIDIVB AIDIVL @@ -119,7 +115,6 @@ const ( AJLS AJLT AJMI - AJMP AJNE AJOC AJOS @@ -159,11 +154,9 @@ const ( AMULB AMULL AMULW - ANAME ANEGB ANEGL ANEGW - ANOP ANOTB ANOTL ANOTW @@ -197,7 +190,6 @@ const ( ARCRW AREP AREPN - ARET AROLB AROLL AROLW @@ -254,7 +246,6 @@ const ( ATESTB ATESTL ATESTW - ATEXT AVERR AVERW AWAIT @@ -367,10 +358,6 @@ const ( AFXTRACT AFYL2X AFYL2XP1 - AEND - ADYNT_ - AINIT_ - ASIGNAME ACMPXCHGB ACMPXCHGL ACMPXCHGW @@ -429,7 +416,6 @@ const ( APREFETCHT2 APREFETCHNTA ABSWAPL - AUNDEF AADDPD AADDPS AADDSD @@ -544,73 +530,53 @@ const ( AAESENC APINSRD APSHUFB - AUSEFIELD - ATYPE - AFUNCDATA - APCDATA - ACHECKNIL - AVARDEF - AVARKILL - ADUFFCOPY - ADUFFZERO ALAST ) const ( - D_AL = 0 + iota - D_CL - D_DL - D_BL - D_AH = 4 + iota - 4 - D_CH - D_DH - D_BH - D_AX = 8 + iota - 8 - D_CX - D_DX - D_BX - D_SP - D_BP - D_SI - D_DI - D_F0 = 16 - D_F7 = D_F0 + 7 - D_CS = 24 + iota - 18 - D_SS - D_DS - D_ES - D_FS - D_GS - D_GDTR - D_IDTR - D_LDTR - D_MSW - D_TASK - D_CR = 35 - D_DR = 43 - D_TR = 51 - D_X0 = 59 + iota - 32 - D_X1 - D_X2 - D_X3 - D_X4 - D_X5 - D_X6 - D_X7 - D_TLS = 67 - D_NONE = 68 - D_BRANCH = 69 - D_EXTERN = 70 - D_STATIC = 71 - D_AUTO = 72 - D_PARAM = 73 - D_CONST = 74 - D_FCONST = 75 - D_SCONST = 76 - D_ADDR = 77 + iota - 50 - D_INDIR - D_CONST2 = D_INDIR + D_INDIR + iota - 52 - D_LAST + REG_NONE = 0 + REG_AL = 0 + 16 + iota - 1 + REG_CL + REG_DL + REG_BL + REG_AH = 4 + 16 + iota - 5 + REG_CH + REG_DH + REG_BH + REG_AX = 8 + 16 + iota - 9 + REG_CX + REG_DX + REG_BX + REG_SP + REG_BP + REG_SI + REG_DI + REG_F0 = 16 + 16 + REG_F7 = REG_F0 + 7 + 16 + REG_CS = 24 + 16 + iota - 19 + REG_SS + REG_DS + REG_ES + REG_FS + REG_GS + REG_GDTR + REG_IDTR + REG_LDTR + REG_MSW + REG_TASK + REG_CR = 35 + 16 + REG_DR = 43 + 16 + REG_TR = 51 + 16 + REG_X0 = 59 + 16 + iota - 33 + REG_X1 + REG_X2 + REG_X3 + REG_X4 + REG_X5 + REG_X6 + REG_X7 + REG_TLS = 67 + 16 + MAXREG = 68 + 16 T_TYPE = 1 << 0 T_INDEX = 1 << 1 T_OFFSET = 1 << 2 @@ -620,8 +586,8 @@ const ( T_OFFSET2 = 1 << 6 T_GOTYPE = 1 << 7 REGARG = -1 - REGRET = D_AX - FREGRET = D_F0 - REGSP = D_SP - REGTMP = D_DI + REGRET = REG_AX + FREGRET = REG_F0 + REGSP = REG_SP + REGTMP = REG_DI ) diff --git a/src/cmd/internal/obj/i386/anames8.go b/src/cmd/internal/obj/i386/anames8.go index dd6103641f..c0f6263ff7 100644 --- a/src/cmd/internal/obj/i386/anames8.go +++ b/src/cmd/internal/obj/i386/anames8.go @@ -4,8 +4,26 @@ package i386 * this is the ranlib header */ var Anames = []string{ - "XXX", - "AAA", + "XXX ", + "CALL", + "CHECKNIL", + "DATA", + "DUFFCOPY", + "DUFFZERO", + "END", + "FUNCDATA", + "GLOBL", + "JMP", + "NOP", + "PCDATA", + "RET", + "TEXT", + "TYPE", + "UNDEF", + "USEFIELD", + "VARDEF", + "VARKILL", + "AAA ", "AAD", "AAM", "AAS", @@ -35,7 +53,6 @@ var Anames = []string{ "BTSL", "BTSW", "BYTE", - "CALL", "CLC", "CLD", "CLI", @@ -49,7 +66,6 @@ var Anames = []string{ "CMPSW", "DAA", "DAS", - "DATA", "DECB", "DECL", "DECW", @@ -57,9 +73,6 @@ var Anames = []string{ "DIVL", "DIVW", "ENTER", - "GLOBL", - "GOK", - "HISTORY", "HLT", "IDIVB", "IDIVL", @@ -92,7 +105,6 @@ var Anames = []string{ "JLS", "JLT", "JMI", - "JMP", "JNE", "JOC", "JOS", @@ -132,11 +144,9 @@ var Anames = []string{ "MULB", "MULL", "MULW", - "NAME", "NEGB", "NEGL", "NEGW", - "NOP", "NOTB", "NOTL", "NOTW", @@ -170,7 +180,6 @@ var Anames = []string{ "RCRW", "REP", "REPN", - "RET", "ROLB", "ROLL", "ROLW", @@ -227,7 +236,6 @@ var Anames = []string{ "TESTB", "TESTL", "TESTW", - "TEXT", "VERR", "VERW", "WAIT", @@ -340,10 +348,6 @@ var Anames = []string{ "FXTRACT", "FYL2X", "FYL2XP1", - "END", - "DYNT_", - "INIT_", - "SIGNAME", "CMPXCHGB", "CMPXCHGL", "CMPXCHGW", @@ -402,7 +406,6 @@ var Anames = []string{ "PREFETCHT2", "PREFETCHNTA", "BSWAPL", - "UNDEF", "ADDPD", "ADDPS", "ADDSD", @@ -517,68 +520,5 @@ var Anames = []string{ "AESENC", "PINSRD", "PSHUFB", - "USEFIELD", - "TYPE", - "FUNCDATA", - "PCDATA", - "CHECKNIL", - "VARDEF", - "VARKILL", - "DUFFCOPY", - "DUFFZERO", "LAST", } - -var dnames8 = []string{ - D_AL: "AL", - D_CL: "CL", - D_DL: "DL", - D_BL: "BL", - D_AH: "AH", - D_CH: "CH", - D_DH: "DH", - D_BH: "BH", - D_AX: "AX", - D_CX: "CX", - D_DX: "DX", - D_BX: "BX", - D_SP: "SP", - D_BP: "BP", - D_SI: "SI", - D_DI: "DI", - D_F0: "F0", - D_CS: "CS", - D_SS: "SS", - D_DS: "DS", - D_ES: "ES", - D_FS: "FS", - D_GS: "GS", - D_GDTR: "GDTR", - D_IDTR: "IDTR", - D_LDTR: "LDTR", - D_MSW: "MSW", - D_TASK: "TASK", - D_CR: "CR", - D_DR: "DR", - D_TR: "TR", - D_X0: "X0", - D_X1: "X1", - D_X2: "X2", - D_X3: "X3", - D_X4: "X4", - D_X5: "X5", - D_X6: "X6", - D_X7: "X7", - D_TLS: "TLS", - D_NONE: "NONE", - D_BRANCH: "BRANCH", - D_EXTERN: "EXTERN", - D_STATIC: "STATIC", - D_AUTO: "AUTO", - D_PARAM: "PARAM", - D_CONST: "CONST", - D_FCONST: "FCONST", - D_SCONST: "SCONST", - D_ADDR: "ADDR", - D_INDIR: "INDIR", -} diff --git a/src/cmd/internal/obj/i386/asm8.go b/src/cmd/internal/obj/i386/asm8.go index 2c3c637e5f..6ef1c3a43b 100644 --- a/src/cmd/internal/obj/i386/asm8.go +++ b/src/cmd/internal/obj/i386/asm8.go @@ -34,6 +34,7 @@ import ( "cmd/internal/obj" "fmt" "log" + "strings" ) // Instruction layout. @@ -50,6 +51,8 @@ type Optab struct { op [13]uint8 } +var opindex [ALAST + 1]*Optab + const ( Yxxx = 0 + iota Ynone @@ -72,6 +75,7 @@ const ( Ym Ybr Ycol + Ytextsize Ytls Ycs Yss @@ -113,7 +117,7 @@ const ( Yxr Yxm Ymax - Zxxx = 0 + iota - 62 + Zxxx = 0 + iota - 63 Zlit Zlitm_r Z_rp @@ -165,7 +169,7 @@ const ( var ycover [Ymax * Ymax]uint8 -var reg [D_NONE]int +var reg [MAXREG]int var ynone = []uint8{ Ynone, @@ -177,7 +181,7 @@ var ynone = []uint8{ var ytext = []uint8{ Ymb, - Yi32, + Ytextsize, Zpseudo, 1, 0, @@ -1123,7 +1127,7 @@ var yxshuf = []uint8{ var optab = /* as, ytab, andproto, opcode */ []Optab{ - Optab{AXXX, nil, 0, [13]uint8{}}, + 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}}, @@ -1154,7 +1158,7 @@ var optab = /* as, ytab, andproto, opcode */ Optab{ABTSL, yml_rl, Pm, [13]uint8{0xab}}, Optab{ABTSW, yml_rl, Pq, [13]uint8{0xab}}, Optab{ABYTE, ybyte, Px, [13]uint8{1}}, - Optab{ACALL, ycall, Px, [13]uint8{0xff, 02, 0xff, 0x15, 0xe8}}, + 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}}, @@ -1168,7 +1172,7 @@ var optab = /* as, ytab, andproto, opcode */ Optab{ACMPSW, ynone, Pe, [13]uint8{0xa7}}, Optab{ADAA, ynone, Px, [13]uint8{0x27}}, Optab{ADAS, ynone, Px, [13]uint8{0x2f}}, - Optab{ADATA, nil, 0, [13]uint8{}}, + 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}}, @@ -1176,9 +1180,7 @@ var optab = /* as, ytab, andproto, opcode */ Optab{ADIVL, ydivl, Px, [13]uint8{0xf7, 06}}, Optab{ADIVW, ydivl, Pe, [13]uint8{0xf7, 06}}, Optab{AENTER, nil, 0, [13]uint8{}}, /* botch */ - Optab{AGLOBL, nil, 0, [13]uint8{}}, - Optab{AGOK, nil, 0, [13]uint8{}}, - Optab{AHISTORY, nil, 0, [13]uint8{}}, + 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}}, @@ -1211,7 +1213,7 @@ var optab = /* as, ytab, andproto, opcode */ 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{AJMP, yjmp, Px, [13]uint8{0xff, 04, 0xeb, 0xe9}}, + 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}}, @@ -1251,14 +1253,13 @@ var optab = /* as, ytab, andproto, opcode */ 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{ANAME, nil, 0, [13]uint8{}}, Optab{ANEGB, yscond, Px, [13]uint8{0xf6, 03}}, - Optab{ANEGL, yscond, Px, [13]uint8{0xf7, 03}}, - Optab{ANEGW, yscond, Pe, [13]uint8{0xf7, 03}}, - Optab{ANOP, ynop, Px, [13]uint8{0, 0}}, + 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}}, - Optab{ANOTW, yscond, Pe, [13]uint8{0xf7, 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}}, @@ -1289,7 +1290,7 @@ var optab = /* as, ytab, andproto, opcode */ 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{ARET, ynone, Px, [13]uint8{0xc3}}, + 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}}, @@ -1346,7 +1347,7 @@ var optab = /* as, ytab, andproto, opcode */ 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{ATEXT, ytext, Px, [13]uint8{}}, + 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}}, @@ -1459,14 +1460,12 @@ var optab = /* as, ytab, andproto, opcode */ 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{AEND, nil, 0, [13]uint8{}}, - Optab{ADYNT_, nil, 0, [13]uint8{}}, - Optab{AINIT_, nil, 0, [13]uint8{}}, - Optab{ASIGNAME, nil, 0, [13]uint8{}}, + 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}}, + 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}}, @@ -1521,7 +1520,7 @@ var optab = /* as, ytab, andproto, opcode */ Optab{APREFETCHT2, yprefetch, Pm, [13]uint8{0x18, 03}}, Optab{APREFETCHNTA, yprefetch, Pm, [13]uint8{0x18, 00}}, Optab{ABSWAPL, ybswap, Pm, [13]uint8{0xc8}}, - Optab{AUNDEF, ynone, Px, [13]uint8{0x0f, 0x0b}}, + 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}}, @@ -1636,15 +1635,15 @@ var optab = /* as, ytab, andproto, opcode */ 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{AUSEFIELD, ynop, Px, [13]uint8{0, 0}}, - Optab{ATYPE, nil, 0, [13]uint8{}}, - Optab{AFUNCDATA, yfuncdata, Px, [13]uint8{0, 0}}, - Optab{APCDATA, ypcdata, Px, [13]uint8{0, 0}}, - Optab{ACHECKNIL, nil, 0, [13]uint8{}}, - Optab{AVARDEF, nil, 0, [13]uint8{}}, - Optab{AVARKILL, nil, 0, [13]uint8{}}, - Optab{ADUFFCOPY, yduff, Px, [13]uint8{0xe8}}, - Optab{ADUFFZERO, yduff, Px, [13]uint8{0xe8}}, + 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{}}, } @@ -1666,7 +1665,6 @@ var nop = [][16]uint8{ // 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 { @@ -1708,21 +1706,14 @@ func span8(ctxt *obj.Link, s *obj.LSym) { } for p = s.Text; p != nil; p = p.Link { - n = 0 - if p.To.Type == D_BRANCH { + if p.To.Type == obj.TYPE_BRANCH { if p.Pcond == nil { p.Pcond = p } } - q = p.Pcond - if q != nil { - if q.Back != 2 { - n = 1 - } - } - p.Back = uint8(n) if p.As == AADJSP { - p.To.Type = D_SP + p.To.Type = obj.TYPE_REG + p.To.Reg = REG_SP v = int32(-p.From.Offset) p.From.Offset = int64(v) p.As = AADDL @@ -1733,7 +1724,7 @@ func span8(ctxt *obj.Link, s *obj.LSym) { } if v == 0 { - p.As = ANOP + p.As = obj.ANOP } } } @@ -1746,8 +1737,8 @@ func span8(ctxt *obj.Link, s *obj.LSym) { } if p.As == AADJSP { - - p.To.Type = D_SP + p.To.Type = obj.TYPE_REG + p.To.Reg = REG_SP v = int32(-p.From.Offset) p.From.Offset = int64(v) p.As = AADDL @@ -1758,7 +1749,7 @@ func span8(ctxt *obj.Link, s *obj.LSym) { } if v == 0 { - p.As = ANOP + p.As = obj.ANOP } } } @@ -1782,21 +1773,18 @@ func span8(ctxt *obj.Link, s *obj.LSym) { // 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 == ACALL && p.To.Sym == deferreturn { - + 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 == ACALL { - + if p.As == obj.ACALL { c = naclpad(ctxt, s, c, -(c+int32(p.Isize))&31) } @@ -1805,7 +1793,6 @@ func span8(ctxt *obj.Link, s *obj.LSym) { // 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) } @@ -1813,7 +1800,6 @@ func span8(ctxt *obj.Link, s *obj.LSym) { // 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) } } @@ -1822,7 +1808,6 @@ func span8(ctxt *obj.Link, s *obj.LSym) { // 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 { @@ -1833,11 +1818,9 @@ func span8(ctxt *obj.Link, s *obj.LSym) { 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:] @@ -1905,11 +1888,14 @@ func span8(ctxt *obj.Link, s *obj.LSym) { func instinit() { var i int + var c int for i = 1; optab[i].as != 0; i++ { - if i != int(optab[i].as) { - log.Fatalf("phase error in optab: at %v found %v", Aconv(i), Aconv(int(optab[i].as))) + c = int(optab[i].as) + if opindex[c] != nil { + log.Fatalf("phase error in optab: %d (%v)", i, Aconv(c)) } + opindex[c] = &optab[i] } for i = 0; i < Ymax; i++ { @@ -1962,248 +1948,271 @@ func instinit() { ycover[Ym*Ymax+Yxm] = 1 ycover[Yxr*Ymax+Yxm] = 1 - for i = 0; i < D_NONE; i++ { + for i = 0; i < MAXREG; i++ { reg[i] = -1 - if i >= D_AL && i <= D_BH { - reg[i] = (i - D_AL) & 7 + if i >= REG_AL && i <= REG_BH { + reg[i] = (i - REG_AL) & 7 } - if i >= D_AX && i <= D_DI { - reg[i] = (i - D_AX) & 7 + if i >= REG_AX && i <= REG_DI { + reg[i] = (i - REG_AX) & 7 } - if i >= D_F0 && i <= D_F0+7 { - reg[i] = (i - D_F0) & 7 + if i >= REG_F0 && i <= REG_F0+7 { + reg[i] = (i - REG_F0) & 7 } - if i >= D_X0 && i <= D_X0+7 { - reg[i] = (i - D_X0) & 7 + if i >= REG_X0 && i <= REG_X0+7 { + reg[i] = (i - REG_X0) & 7 } } } func prefixof(ctxt *obj.Link, a *obj.Addr) int { - switch a.Type { - case D_INDIR + D_CS: - return 0x2e + if a.Type == obj.TYPE_MEM && a.Name == obj.NAME_NONE { + switch a.Reg { + case REG_CS: + return 0x2e - case D_INDIR + D_DS: - return 0x3e + case REG_DS: + return 0x3e - case D_INDIR + D_ES: - return 0x26 + case REG_ES: + return 0x26 - case D_INDIR + D_FS: - return 0x64 + case REG_FS: + return 0x64 - case D_INDIR + D_GS: - return 0x65 + 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 D_INDIR + D_TLS: - switch ctxt.Headtype { - - default: - log.Fatalf("unknown TLS base register for %s", obj.Headstr(ctxt.Headtype)) + // 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 + case obj.Hdarwin, + obj.Hdragonfly, + obj.Hfreebsd, + obj.Hnetbsd, + obj.Hopenbsd: + return 0x65 // GS + } } } return 0 } -func oclass(a *obj.Addr) int { +func oclass(ctxt *obj.Link, p *obj.Prog, a *obj.Addr) int { var v int32 - if (a.Type >= D_INDIR && a.Type < 2*D_INDIR) || a.Index != D_NONE { - if a.Index != D_NONE && a.Scale == 0 { - if a.Type == D_ADDR { - switch a.Index { - case D_EXTERN, - D_STATIC: - return Yi32 + // 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 + } - case D_AUTO, - D_PARAM: - return Yiauto - } + switch a.Type { + case obj.TYPE_NONE: + return Ynone - return Yxxx - } + case obj.TYPE_BRANCH: + return Ybr - //if(a->type == D_INDIR+D_ADDR) - // print("*Ycol\n"); + // 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", Dconv(p, 0, a)) + } + fallthrough + + // fall through + + case obj.TYPE_CONST: + if a.Sym != nil { + ctxt.Diag("TYPE_CONST with symbol: %v", Dconv(p, 0, 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 } - switch a.Type { - case D_AL: + if a.Type != obj.TYPE_REG { + ctxt.Diag("unexpected addr1: type=%d %v", a.Type, Dconv(p, 0, a)) + return Yxxx + } + + switch a.Reg { + case REG_AL: return Yal - case D_AX: + case REG_AX: return Yax - case D_CL, - D_DL, - D_BL, - D_AH, - D_CH, - D_DH, - D_BH: + case REG_CL, + REG_DL, + REG_BL, + REG_AH, + REG_CH, + REG_DH, + REG_BH: return Yrb - case D_CX: + case REG_CX: return Ycx - case D_DX, - D_BX: + case REG_DX, + REG_BX: return Yrx - case D_SP, - D_BP, - D_SI, - D_DI: + case REG_SP, + REG_BP, + REG_SI, + REG_DI: return Yrl - case D_F0 + 0: + case REG_F0 + 0: return Yf0 - case D_F0 + 1, - D_F0 + 2, - D_F0 + 3, - D_F0 + 4, - D_F0 + 5, - D_F0 + 6, - D_F0 + 7: + 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 D_X0 + 0, - D_X0 + 1, - D_X0 + 2, - D_X0 + 3, - D_X0 + 4, - D_X0 + 5, - D_X0 + 6, - D_X0 + 7: + 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 D_NONE: - return Ynone - - case D_CS: + case REG_CS: return Ycs - case D_SS: + case REG_SS: return Yss - case D_DS: + case REG_DS: return Yds - case D_ES: + case REG_ES: return Yes - case D_FS: + case REG_FS: return Yfs - case D_GS: + case REG_GS: return Ygs - case D_TLS: + case REG_TLS: return Ytls - case D_GDTR: + case REG_GDTR: return Ygdtr - case D_IDTR: + case REG_IDTR: return Yidtr - case D_LDTR: + case REG_LDTR: return Yldtr - case D_MSW: + case REG_MSW: return Ymsw - case D_TASK: + case REG_TASK: return Ytask - case D_CR + 0: + case REG_CR + 0: return Ycr0 - case D_CR + 1: + case REG_CR + 1: return Ycr1 - case D_CR + 2: + case REG_CR + 2: return Ycr2 - case D_CR + 3: + case REG_CR + 3: return Ycr3 - case D_CR + 4: + case REG_CR + 4: return Ycr4 - case D_CR + 5: + case REG_CR + 5: return Ycr5 - case D_CR + 6: + case REG_CR + 6: return Ycr6 - case D_CR + 7: + case REG_CR + 7: return Ycr7 - case D_DR + 0: + case REG_DR + 0: return Ydr0 - case D_DR + 1: + case REG_DR + 1: return Ydr1 - case D_DR + 2: + case REG_DR + 2: return Ydr2 - case D_DR + 3: + case REG_DR + 3: return Ydr3 - case D_DR + 4: + case REG_DR + 4: return Ydr4 - case D_DR + 5: + case REG_DR + 5: return Ydr5 - case D_DR + 6: + case REG_DR + 6: return Ydr6 - case D_DR + 7: + case REG_DR + 7: return Ydr7 - case D_TR + 0: + case REG_TR + 0: return Ytr0 - case D_TR + 1: + case REG_TR + 1: return Ytr1 - case D_TR + 2: + case REG_TR + 2: return Ytr2 - case D_TR + 3: + case REG_TR + 3: return Ytr3 - case D_TR + 4: + case REG_TR + 4: return Ytr4 - case D_TR + 5: + case REG_TR + 5: return Ytr5 - case D_TR + 6: + case REG_TR + 6: return Ytr6 - case D_TR + 7: + case REG_TR + 7: return Ytr7 - - case D_EXTERN, - D_STATIC, - D_AUTO, - D_PARAM: - return Ym - - case D_CONST, - D_CONST2, - D_ADDR: - if a.Sym == nil { - v = int32(a.Offset) - if v == 0 { - return Yi0 - } - if v == 1 { - return Yi1 - } - if v >= -128 && v <= 127 { - return Yi8 - } - } - - return Yi32 - - case D_BRANCH: - return Ybr } return Yxxx @@ -2216,17 +2225,17 @@ func asmidx(ctxt *obj.Link, scale int, index int, base int) { default: goto bad - case D_NONE: + case obj.TYPE_NONE: i = 4 << 3 goto bas - case D_AX, - D_CX, - D_DX, - D_BX, - D_BP, - D_SI, - D_DI: + case REG_AX, + REG_CX, + REG_DX, + REG_BX, + REG_BP, + REG_SI, + REG_DI: i = reg[index] << 3 break } @@ -2254,17 +2263,17 @@ bas: default: goto bad - case D_NONE: /* must be mod=00 */ + case REG_NONE: /* must be mod=00 */ i |= 5 - case D_AX, - D_CX, - D_DX, - D_BX, - D_SP, - D_BP, - D_SI, - D_DI: + case REG_AX, + REG_CX, + REG_DX, + REG_BX, + REG_SP, + REG_BP, + REG_SI, + REG_DI: i |= reg[base] break } @@ -2307,22 +2316,15 @@ func relput4(ctxt *obj.Link, p *obj.Prog, a *obj.Addr) { } func vaddr(ctxt *obj.Link, p *obj.Prog, a *obj.Addr, r *obj.Reloc) int32 { - var t int - var v int32 var s *obj.LSym if r != nil { *r = obj.Reloc{} } - t = int(a.Type) - v = int32(a.Offset) - if t == D_ADDR { - t = int(a.Index) - } - switch t { - case D_STATIC, - D_EXTERN: + switch a.Name { + case obj.NAME_STATIC, + obj.NAME_EXTERN: s = a.Sym if s != nil { if r == nil { @@ -2334,11 +2336,14 @@ func vaddr(ctxt *obj.Link, p *obj.Prog, a *obj.Addr, r *obj.Reloc) int32 { r.Siz = 4 r.Off = -1 r.Sym = s - r.Add = int64(v) - v = 0 + r.Add = a.Offset + return 0 } - case D_INDIR + D_TLS: + 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", Dconv(p, 0, a)) log.Fatalf("bad code") @@ -2347,62 +2352,79 @@ func vaddr(ctxt *obj.Link, p *obj.Prog, a *obj.Addr, r *obj.Reloc) int32 { r.Type = obj.R_TLS_LE r.Siz = 4 r.Off = -1 // caller must fill in - r.Add = int64(v) - v = 0 - break + r.Add = a.Offset + return 0 } - return v + return int32(a.Offset) } func asmand(ctxt *obj.Link, p *obj.Prog, a *obj.Addr, r int) { var v int32 - var t int - var scale int + var base int var rel obj.Reloc v = int32(a.Offset) - t = int(a.Type) rel.Siz = 0 - if a.Index != D_NONE && a.Index != D_TLS { - if t < D_INDIR || t >= 2*D_INDIR { - switch t { - default: - goto bad - case D_STATIC, - D_EXTERN: - t = D_NONE - v = vaddr(ctxt, p, a, &rel) + 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 D_AUTO, - D_PARAM: - t = D_SP - break - } - } else { + 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) - t -= D_INDIR + case obj.NAME_AUTO, + obj.NAME_PARAM: + base = REG_SP + break } - if t == D_NONE { + 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), t) + asmidx(ctxt, int(a.Scale), int(a.Index), base) goto putrelv } - if v == 0 && rel.Siz == 0 && t != D_BP { + 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), t) + 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), t) + asmidx(ctxt, int(a.Scale), int(a.Index), base) ctxt.Andptr[0] = byte(v) ctxt.Andptr = ctxt.Andptr[1:] return @@ -2410,63 +2432,45 @@ func asmand(ctxt *obj.Link, p *obj.Prog, a *obj.Addr, r int) { ctxt.Andptr[0] = byte(2<<6 | 4<<0 | r<<3) ctxt.Andptr = ctxt.Andptr[1:] - asmidx(ctxt, int(a.Scale), int(a.Index), t) + asmidx(ctxt, int(a.Scale), int(a.Index), base) goto putrelv } - if t >= D_AL && t <= D_F7 || t >= D_X0 && t <= D_X7 { - if v != 0 { - goto bad - } - ctxt.Andptr[0] = byte(3<<6 | reg[t]<<0 | r<<3) - ctxt.Andptr = ctxt.Andptr[1:] - return - } - - scale = int(a.Scale) - if t < D_INDIR || t >= 2*D_INDIR { - switch a.Type { - default: - goto bad - - case D_STATIC, - D_EXTERN: - t = D_NONE - v = vaddr(ctxt, p, a, &rel) - - case D_AUTO, - D_PARAM: - t = D_SP - break - } - - scale = 1 - } else { + base = int(a.Reg) + switch a.Name { + case obj.NAME_STATIC, + obj.NAME_EXTERN: + base = REG_NONE + v = vaddr(ctxt, p, a, &rel) - t -= D_INDIR + case obj.NAME_AUTO, + obj.NAME_PARAM: + base = REG_SP + break } - if t == D_TLS { + + if base == REG_TLS { v = vaddr(ctxt, p, a, &rel) } - if t == D_NONE || (D_CS <= t && t <= D_GS) || t == D_TLS { + 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 t == D_SP { + 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, scale, D_NONE, t) + 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, scale, D_NONE, t) + asmidx(ctxt, int(a.Scale), REG_NONE, base) ctxt.Andptr[0] = byte(v) ctxt.Andptr = ctxt.Andptr[1:] return @@ -2474,12 +2478,12 @@ func asmand(ctxt *obj.Link, p *obj.Prog, a *obj.Addr, r int) { ctxt.Andptr[0] = byte(2<<6 | 4<<0 | r<<3) ctxt.Andptr = ctxt.Andptr[1:] - asmidx(ctxt, scale, D_NONE, t) + asmidx(ctxt, int(a.Scale), REG_NONE, base) goto putrelv } - if t >= D_AX && t <= D_DI { - if a.Index == D_TLS { + if REG_AX <= base && base <= REG_DI { + if a.Index == REG_TLS { rel = obj.Reloc{} rel.Type = obj.R_TLS_IE rel.Siz = 4 @@ -2488,20 +2492,20 @@ func asmand(ctxt *obj.Link, p *obj.Prog, a *obj.Addr, r int) { v = 0 } - if v == 0 && rel.Siz == 0 && t != D_BP { - ctxt.Andptr[0] = byte(0<<6 | reg[t]<<0 | r<<3) + 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[t]<<0 | r<<3) + 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[t]<<0 | r<<3) + ctxt.Andptr[0] = byte(2<<6 | reg[base]<<0 | r<<3) ctxt.Andptr = ctxt.Andptr[1:] goto putrelv } @@ -3118,11 +3122,10 @@ var ymovtab = []uint8{ } // byteswapreg returns a byte-addressable register (AX, BX, CX, DX) -// which is not referenced in a->type. +// 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 { - var cana int var canb int var canc int @@ -3133,63 +3136,68 @@ func byteswapreg(ctxt *obj.Link, a *obj.Addr) int { canb = canc cana = canb - switch a.Type { - case D_NONE: + if a.Type == obj.TYPE_NONE { cand = 0 cana = cand + } - case D_AX, - D_AL, - D_AH, - D_INDIR + D_AX: - cana = 0 + 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 D_BX, - D_BL, - D_BH, - D_INDIR + D_BX: - canb = 0 + case REG_AX, + REG_AL, + REG_AH: + cana = 0 - case D_CX, - D_CL, - D_CH, - D_INDIR + D_CX: - canc = 0 + case REG_BX, + REG_BL, + REG_BH: + canb = 0 - case D_DX, - D_DL, - D_DH, - D_INDIR + D_DX: - cand = 0 - break + case REG_CX, + REG_CL, + REG_CH: + canc = 0 + + case REG_DX, + REG_DL, + REG_DH: + cand = 0 + break + } } - switch a.Index { - case D_AX: - cana = 0 + if a.Type == obj.TYPE_MEM || a.Type == obj.TYPE_ADDR { + switch a.Index { + case REG_AX: + cana = 0 - case D_BX: - canb = 0 + case REG_BX: + canb = 0 - case D_CX: - canc = 0 + case REG_CX: + canc = 0 - case D_DX: - cand = 0 - break + case REG_DX: + cand = 0 + break + } } if cana != 0 { - return D_AX + return REG_AX } if canb != 0 { - return D_BX + return REG_BX } if canc != 0 { - return D_CX + return REG_CX } if cand != 0 { - return D_DX + return REG_DX } ctxt.Diag("impossible byte register") @@ -3202,34 +3210,23 @@ func subreg(p *obj.Prog, from int, to int) { fmt.Printf("\n%v\ts/%v/%v/\n", p, Rconv(from), Rconv(to)) } - if int(p.From.Type) == from { - p.From.Type = int16(to) + if int(p.From.Reg) == from { + p.From.Reg = int16(to) p.Ft = 0 } - if int(p.To.Type) == from { - p.To.Type = int16(to) + if int(p.To.Reg) == from { + p.To.Reg = int16(to) p.Tt = 0 } if int(p.From.Index) == from { - p.From.Index = uint8(to) + p.From.Index = int16(to) p.Ft = 0 } if int(p.To.Index) == from { - p.To.Index = uint8(to) - p.Tt = 0 - } - - from += D_INDIR - if int(p.From.Type) == from { - p.From.Type = int16(to + D_INDIR) - p.Ft = 0 - } - - if int(p.To.Type) == from { - p.To.Type = int16(to + D_INDIR) + p.To.Index = int16(to) p.Tt = 0 } @@ -3301,15 +3298,15 @@ func doasm(ctxt *obj.Link, p *obj.Prog) { } if p.Ft == 0 { - p.Ft = uint8(oclass(&p.From)) + p.Ft = uint8(oclass(ctxt, p, &p.From)) } if p.Tt == 0 { - p.Tt = uint8(oclass(&p.To)) + p.Tt = uint8(oclass(ctxt, p, &p.To)) } ft = int(p.Ft) * Ymax tt = int(p.Tt) * Ymax - o = &optab[p.As] + o = opindex[p.As] t = o.ytab if t == nil { ctxt.Diag("asmins: noproto %v", p) @@ -3382,27 +3379,27 @@ found: ctxt.Andptr[0] = byte(op) ctxt.Andptr = ctxt.Andptr[1:] } - asmand(ctxt, p, &p.From, reg[p.To.Type]) + 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.Type]) + 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.Type]) + asmand(ctxt, p, &p.From, reg[p.To.Reg]) case Zm_r_xm: mediaop(ctxt, o, op, int(t[3]), z) - asmand(ctxt, p, &p.From, reg[p.To.Type]) + asmand(ctxt, p, &p.From, reg[p.To.Reg]) case Zm_r_i_xm: mediaop(ctxt, o, op, int(t[3]), z) - asmand(ctxt, p, &p.From, reg[p.To.Type]) + asmand(ctxt, p, &p.From, reg[p.To.Reg]) ctxt.Andptr[0] = byte(p.To.Offset) ctxt.Andptr = ctxt.Andptr[1:] @@ -3417,22 +3414,20 @@ found: ctxt.Andptr[0] = byte(op) ctxt.Andptr = ctxt.Andptr[1:] } - asmand(ctxt, p, &p.From, reg[p.To.Type]) + 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 != D_ADDR { + if p.From.Type != obj.TYPE_ADDR { ctxt.Diag("asmins: Zaut sb type ADDR") } - p.From.Type = int16(p.From.Index) - p.From.Index = D_NONE + p.From.Type = obj.TYPE_MEM p.Ft = 0 - asmand(ctxt, p, &p.From, reg[p.To.Type]) - p.From.Index = uint8(p.From.Type) - p.From.Type = D_ADDR + asmand(ctxt, p, &p.From, reg[p.To.Reg]) + p.From.Type = obj.TYPE_ADDR p.Ft = 0 case Zm_o: @@ -3443,15 +3438,15 @@ found: case Zr_m: ctxt.Andptr[0] = byte(op) ctxt.Andptr = ctxt.Andptr[1:] - asmand(ctxt, p, &p.To, reg[p.From.Type]) + asmand(ctxt, p, &p.To, reg[p.From.Reg]) case Zr_m_xm: mediaop(ctxt, o, op, int(t[3]), z) - asmand(ctxt, p, &p.To, reg[p.From.Type]) + asmand(ctxt, p, &p.To, reg[p.From.Reg]) case Zr_m_i_xm: mediaop(ctxt, o, op, int(t[3]), z) - asmand(ctxt, p, &p.To, reg[p.From.Type]) + asmand(ctxt, p, &p.To, reg[p.From.Reg]) ctxt.Andptr[0] = byte(p.From.Offset) ctxt.Andptr = ctxt.Andptr[1:] @@ -3488,7 +3483,6 @@ found: if t[2] == Zib_ { a = &p.From } else { - a = &p.To } v = vaddr(ctxt, p, a, nil) @@ -3498,13 +3492,13 @@ found: ctxt.Andptr = ctxt.Andptr[1:] case Zib_rp: - ctxt.Andptr[0] = byte(op + reg[p.To.Type]) + 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.Type]) + 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) @@ -3513,14 +3507,13 @@ found: 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.Type]) + asmand(ctxt, p, &p.To, reg[p.To.Reg]) ctxt.Andptr[0] = byte(vaddr(ctxt, p, &p.From, nil)) ctxt.Andptr = ctxt.Andptr[1:] @@ -3529,7 +3522,6 @@ found: if t[2] == Zil_ { a = &p.From } else { - a = &p.To } ctxt.Andptr[0] = byte(op) @@ -3541,7 +3533,6 @@ found: ctxt.Andptr[0] = byte(v >> 8) ctxt.Andptr = ctxt.Andptr[1:] } else { - relput4(ctxt, p, a) } @@ -3553,7 +3544,6 @@ found: 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])) } @@ -3565,14 +3555,13 @@ found: 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.Type]) + 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) @@ -3580,22 +3569,21 @@ found: 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.Type]) + ctxt.Andptr[0] = byte(op + reg[p.To.Reg]) ctxt.Andptr = ctxt.Andptr[1:] case Zrp_: - ctxt.Andptr[0] = byte(op + reg[p.From.Type]) + 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.Type]) + asmand(ctxt, p, &p.To, reg[p.To.Reg]) case Zcall: if p.To.Sym == nil { @@ -3656,7 +3644,6 @@ found: } else if t[2] == Zloop { ctxt.Diag("loop too far: %v", p) } else { - v -= 5 - 2 if t[2] == Zbr { ctxt.Andptr[0] = 0x0f @@ -3695,7 +3682,6 @@ found: } else if t[2] == Zloop { ctxt.Diag("loop too far: %v", p) } else { - if t[2] == Zbr { ctxt.Andptr[0] = 0x0f ctxt.Andptr = ctxt.Andptr[1:] @@ -3718,7 +3704,6 @@ found: ctxt.Andptr[0] = byte(op) ctxt.Andptr = ctxt.Andptr[1:] } else { - ctxt.Andptr[0] = byte(o.op[z+1]) ctxt.Andptr = ctxt.Andptr[1:] } @@ -3791,10 +3776,10 @@ domov: bad: pp = *p - z = int(p.From.Type) - if z >= D_BP && z <= D_DI { + 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 != D_AX { + if breg != REG_AX { ctxt.Andptr[0] = 0x87 ctxt.Andptr = ctxt.Andptr[1:] /* xchg lhs,bx */ asmand(ctxt, p, &p.From, reg[breg]) @@ -3804,10 +3789,9 @@ bad: 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, D_AX) + subreg(&pp, z, REG_AX) doasm(ctxt, &pp) ctxt.Andptr[0] = byte(0x90 + reg[z]) ctxt.Andptr = ctxt.Andptr[1:] /* xchg lsh,ax */ @@ -3816,10 +3800,10 @@ bad: return } - z = int(p.To.Type) - if z >= D_BP && z <= D_DI { + 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 != D_AX { + if breg != REG_AX { ctxt.Andptr[0] = 0x87 ctxt.Andptr = ctxt.Andptr[1:] /* xchg rhs,bx */ asmand(ctxt, p, &p.To, reg[breg]) @@ -3829,10 +3813,9 @@ bad: 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, D_AX) + subreg(&pp, z, REG_AX) doasm(ctxt, &pp) ctxt.Andptr[0] = byte(0x90 + reg[z]) ctxt.Andptr = ctxt.Andptr[1:] /* xchg rsh,ax */ @@ -3841,7 +3824,7 @@ bad: return } - ctxt.Diag("doasm: notfound t2=%x from=%x to=%x %v", t[2], uint16(p.From.Type), uint16(p.To.Type), p) + ctxt.Diag("doasm: notfound t2=%d from=%d to=%d %v", t[2], p.Ft, p.Tt, p) return mfound: @@ -3851,7 +3834,6 @@ mfound: case 0: /* lit */ for z = 4; t[z] != E; z++ { - ctxt.Andptr[0] = t[z] ctxt.Andptr = ctxt.Andptr[1:] } @@ -3886,7 +3868,6 @@ mfound: case 5: /* load full pointer, trash heap */ if t[4] != 0 { - ctxt.Andptr[0] = t[4] ctxt.Andptr = ctxt.Andptr[1:] } @@ -3894,27 +3875,27 @@ mfound: default: goto bad - case D_DS: + case REG_DS: ctxt.Andptr[0] = 0xc5 ctxt.Andptr = ctxt.Andptr[1:] - case D_SS: + case REG_SS: ctxt.Andptr[0] = 0x0f ctxt.Andptr = ctxt.Andptr[1:] ctxt.Andptr[0] = 0xb2 ctxt.Andptr = ctxt.Andptr[1:] - case D_ES: + case REG_ES: ctxt.Andptr[0] = 0xc4 ctxt.Andptr = ctxt.Andptr[1:] - case D_FS: + case REG_FS: ctxt.Andptr[0] = 0x0f ctxt.Andptr = ctxt.Andptr[1:] ctxt.Andptr[0] = 0xb4 ctxt.Andptr = ctxt.Andptr[1:] - case D_GS: + case REG_GS: ctxt.Andptr[0] = 0x0f ctxt.Andptr = ctxt.Andptr[1:] ctxt.Andptr[0] = 0xb5 @@ -3922,16 +3903,14 @@ mfound: break } - asmand(ctxt, p, &p.From, reg[p.To.Type]) + asmand(ctxt, p, &p.From, reg[p.To.Reg]) case 6: /* double shift */ - z = int(p.From.Type) - - switch z { + switch p.From.Type { default: goto bad - case D_CONST: + case obj.TYPE_CONST: ctxt.Andptr[0] = 0x0f ctxt.Andptr = ctxt.Andptr[1:] ctxt.Andptr[0] = t[4] @@ -3940,31 +3919,37 @@ mfound: ctxt.Andptr[0] = byte(p.From.Offset) ctxt.Andptr = ctxt.Andptr[1:] - case D_CL, - D_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 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]) + break + } + break } 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.Type]) + 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 @@ -3972,7 +3957,6 @@ mfound: // 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)) @@ -3981,42 +3965,45 @@ mfound: obj.Hnacl: pp.From = p.From - pp.From.Type = D_INDIR + D_GS + pp.From.Type = obj.TYPE_MEM + pp.From.Reg = REG_GS pp.From.Offset = 0 - pp.From.Index = D_NONE + 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.Type]) + 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 = D_EXTERN + pp.From.Type = obj.TYPE_MEM + pp.From.Name = obj.NAME_EXTERN pp.From.Sym = ctxt.Plan9privates pp.From.Offset = 0 - pp.From.Index = D_NONE + pp.From.Index = REG_NONE ctxt.Andptr[0] = 0x8B ctxt.Andptr = ctxt.Andptr[1:] - asmand(ctxt, p, &pp.From, reg[p.To.Type]) + 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 = D_INDIR + D_FS + pp.From.Type = obj.TYPE_MEM + pp.From.Reg = REG_FS pp.From.Offset = 0x14 - pp.From.Index = D_NONE + 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.Type]) + asmand(ctxt, p, &pp.From, reg[p.To.Reg]) break } @@ -4039,7 +4026,7 @@ func asmins(ctxt *obj.Link, p *obj.Prog) { ctxt.Andptr = ctxt.And[:] - if p.As == AUSEFIELD { + if p.As == obj.AUSEFIELD { r = obj.Addrel(ctxt.Cursym) r.Off = 0 r.Sym = p.From.Sym @@ -4050,17 +4037,17 @@ func asmins(ctxt *obj.Link, p *obj.Prog) { if ctxt.Headtype == obj.Hnacl { switch p.As { - case ARET: + case obj.ARET: copy(ctxt.Andptr, naclret) ctxt.Andptr = ctxt.Andptr[len(naclret):] return - case ACALL, - AJMP: - if D_AX <= p.To.Type && p.To.Type <= D_DI { + 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.Type - D_AX)) + ctxt.Andptr[0] = byte(0xe0 | (p.To.Reg - REG_AX)) ctxt.Andptr = ctxt.Andptr[1:] ctxt.Andptr[0] = 0xe0 ctxt.Andptr = ctxt.Andptr[1:] diff --git a/src/cmd/internal/obj/i386/list8.go b/src/cmd/internal/obj/i386/list8.go index 5a55890582..087da7e4d0 100644 --- a/src/cmd/internal/obj/i386/list8.go +++ b/src/cmd/internal/obj/i386/list8.go @@ -46,16 +46,16 @@ func Pconv(p *obj.Prog) string { var fp string switch p.As { - case ADATA: - str = fmt.Sprintf("%.5d (%v)\t%v\t%v/%d,%v", p.Pc, p.Line(), Aconv(int(p.As)), Dconv(p, 0, &p.From), p.From.Scale, Dconv(p, 0, &p.To)) + case obj.ADATA: + str = fmt.Sprintf("%.5d (%v)\t%v\t%v/%d,%v", p.Pc, p.Line(), Aconv(int(p.As)), Dconv(p, 0, &p.From), p.From3.Offset, Dconv(p, 0, &p.To)) - case ATEXT: - if p.From.Scale != 0 { - str = fmt.Sprintf("%.5d (%v)\t%v\t%v,%d,%v", p.Pc, p.Line(), Aconv(int(p.As)), Dconv(p, 0, &p.From), p.From.Scale, Dconv(p, fmtLong, &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(), Aconv(int(p.As)), Dconv(p, 0, &p.From), p.From3.Offset, Dconv(p, 0, &p.To)) break } - str = fmt.Sprintf("%.5d (%v)\t%v\t%v,%v", p.Pc, p.Line(), Aconv(int(p.As)), Dconv(p, 0, &p.From), Dconv(p, fmtLong, &p.To)) + str = fmt.Sprintf("%.5d (%v)\t%v\t%v,%v", p.Pc, p.Line(), Aconv(int(p.As)), Dconv(p, 0, &p.From), Dconv(p, 0, &p.To)) default: str = fmt.Sprintf("%.5d (%v)\t%v\t%v,%v", p.Pc, p.Line(), Aconv(int(p.As)), Dconv(p, 0, &p.From), Dconv(p, 0, &p.To)) @@ -78,45 +78,34 @@ func Dconv(p *obj.Prog, flag int, a *obj.Addr) string { var s string var fp string - var i int - - i = int(a.Type) - - if flag&fmtLong != 0 /*untyped*/ { - if i == D_CONST2 { - str = fmt.Sprintf("$%d-%d", a.Offset, a.Offset2) - } else { - - // ATEXT dst is not constant - str = fmt.Sprintf("!!%v", Dconv(p, 0, a)) - } + switch a.Type { + default: + str = fmt.Sprintf("type=%d", a.Type) - goto brk - } + case obj.TYPE_NONE: + str = "" - if i >= D_INDIR { + // TODO(rsc): This special case is for instructions like + // PINSRQ CX,$1,X6 + // where the $1 is included in the p->to Addr. + // Move into a new field. + case obj.TYPE_REG: if a.Offset != 0 { - str = fmt.Sprintf("%d(%v)", a.Offset, Rconv(i-D_INDIR)) - } else { - - str = fmt.Sprintf("(%v)", Rconv(i-D_INDIR)) + str = fmt.Sprintf("$%d,%v", a.Offset, Rconv(int(a.Reg))) + break } - goto brk - } - switch i { - default: - if a.Offset != 0 { - str = fmt.Sprintf("$%d,%v", a.Offset, Rconv(i)) - } else { + str = fmt.Sprintf("%v", Rconv(int(a.Reg))) - str = fmt.Sprintf("%v", Rconv(i)) + // TODO(rsc): This special case is for SHRQ $32, AX:DX, which encodes as + // SHRQ $32(DX*0), AX + // Remove. + if a.Index != REG_NONE { + s = fmt.Sprintf("(%v*%d)", Rconv(int(a.Index)), int(a.Scale)) + str += s } - case D_NONE: - str = "" - - case D_BRANCH: + case obj.TYPE_BRANCH: if a.Sym != nil { str = fmt.Sprintf("%s(SB)", a.Sym.Name) } else if p != nil && p.Pcond != nil { @@ -124,69 +113,85 @@ func Dconv(p *obj.Prog, flag int, a *obj.Addr) string { } else if a.U.Branch != nil { str = fmt.Sprintf("%d", a.U.Branch.Pc) } else { - str = fmt.Sprintf("%d(PC)", a.Offset) } - case D_EXTERN: - str = fmt.Sprintf("%s+%d(SB)", a.Sym.Name, a.Offset) + case obj.TYPE_MEM: + switch a.Name { + default: + str = fmt.Sprintf("name=%d", a.Name) - case D_STATIC: - str = fmt.Sprintf("%s<>+%d(SB)", a.Sym.Name, a.Offset) + case obj.NAME_NONE: + if a.Offset != 0 { + str = fmt.Sprintf("%d(%v)", a.Offset, Rconv(int(a.Reg))) + } else { + str = fmt.Sprintf("(%v)", Rconv(int(a.Reg))) + } - case D_AUTO: - if a.Sym != nil { - str = fmt.Sprintf("%s+%d(SP)", a.Sym.Name, a.Offset) - } else { + case obj.NAME_EXTERN: + str = fmt.Sprintf("%s+%d(SB)", a.Sym.Name, a.Offset) - str = fmt.Sprintf("%d(SP)", a.Offset) - } + case obj.NAME_STATIC: + str = fmt.Sprintf("%s<>+%d(SB)", a.Sym.Name, a.Offset) - case D_PARAM: - if a.Sym != nil { - str = fmt.Sprintf("%s+%d(FP)", a.Sym.Name, a.Offset) - } else { + case obj.NAME_AUTO: + if a.Sym != nil { + str = fmt.Sprintf("%s+%d(SP)", a.Sym.Name, a.Offset) + } else { + str = fmt.Sprintf("%d(SP)", a.Offset) + } + + case obj.NAME_PARAM: + if a.Sym != nil { + str = fmt.Sprintf("%s+%d(FP)", a.Sym.Name, a.Offset) + } else { + str = fmt.Sprintf("%d(FP)", a.Offset) + } + break + } - str = fmt.Sprintf("%d(FP)", a.Offset) + if a.Index != REG_NONE { + s = fmt.Sprintf("(%v*%d)", Rconv(int(a.Index)), int(a.Scale)) + str += s } - case D_CONST: + case obj.TYPE_CONST: str = fmt.Sprintf("$%d", a.Offset) - case D_CONST2: - if !(flag&fmtLong != 0 /*untyped*/) { - // D_CONST2 outside of ATEXT should not happen - str = fmt.Sprintf("!!$%d-%d", a.Offset, a.Offset2) + // TODO(rsc): This special case is for SHRQ $32, AX:DX, which encodes as + // SHRQ $32(DX*0), AX + // Remove. + if a.Index != REG_NONE { + s = fmt.Sprintf("(%v*%d)", Rconv(int(a.Index)), int(a.Scale)) + str += s } - case D_FCONST: + case obj.TYPE_TEXTSIZE: + if a.U.Argsize == obj.ArgsSizeUnknown { + str = fmt.Sprintf("$%d", a.Offset) + } else { + str = fmt.Sprintf("$%d-%d", a.Offset, a.U.Argsize) + } + + case obj.TYPE_FCONST: str = fmt.Sprintf("$(%.17g)", a.U.Dval) - case D_SCONST: + case obj.TYPE_SCONST: str = fmt.Sprintf("$\"%q\"", a.U.Sval) - case D_ADDR: - a.Type = int16(a.Index) - a.Index = D_NONE + case obj.TYPE_ADDR: + a.Type = obj.TYPE_MEM str = fmt.Sprintf("$%v", Dconv(p, 0, a)) - a.Index = uint8(a.Type) - a.Type = D_ADDR - goto conv - } - -brk: - if a.Index != D_NONE { - s = fmt.Sprintf("(%v*%d)", Rconv(int(a.Index)), int(a.Scale)) - str += s + a.Type = obj.TYPE_ADDR + break } -conv: fp += str return fp } var Register = []string{ - "AL", /* [D_AL] */ + "AL", /* [REG_AL] */ "CL", "DL", "BL", @@ -194,7 +199,7 @@ var Register = []string{ "CH", "DH", "BH", - "AX", /* [D_AX] */ + "AX", /* [REG_AX] */ "CX", "DX", "BX", @@ -202,7 +207,7 @@ var Register = []string{ "BP", "SI", "DI", - "F0", /* [D_F0] */ + "F0", /* [REG_F0] */ "F1", "F2", "F3", @@ -210,18 +215,18 @@ var Register = []string{ "F5", "F6", "F7", - "CS", /* [D_CS] */ + "CS", /* [REG_CS] */ "SS", "DS", "ES", "FS", "GS", - "GDTR", /* [D_GDTR] */ - "IDTR", /* [D_IDTR] */ - "LDTR", /* [D_LDTR] */ - "MSW", /* [D_MSW] */ - "TASK", /* [D_TASK] */ - "CR0", /* [D_CR] */ + "GDTR", /* [REG_GDTR] */ + "IDTR", /* [REG_IDTR] */ + "LDTR", /* [REG_LDTR] */ + "MSW", /* [REG_MSW] */ + "TASK", /* [REG_TASK] */ + "CR0", /* [REG_CR] */ "CR1", "CR2", "CR3", @@ -229,7 +234,7 @@ var Register = []string{ "CR5", "CR6", "CR7", - "DR0", /* [D_DR] */ + "DR0", /* [REG_DR] */ "DR1", "DR2", "DR3", @@ -237,7 +242,7 @@ var Register = []string{ "DR5", "DR6", "DR7", - "TR0", /* [D_TR] */ + "TR0", /* [REG_TR] */ "TR1", "TR2", "TR3", @@ -245,7 +250,7 @@ var Register = []string{ "TR5", "TR6", "TR7", - "X0", /* [D_X0] */ + "X0", /* [REG_X0] */ "X1", "X2", "X3", @@ -253,18 +258,21 @@ var Register = []string{ "X5", "X6", "X7", - "TLS", /* [D_TLS] */ - "NONE", /* [D_NONE] */ + "TLS", /* [REG_TLS] */ + "MAXREG", /* [MAXREG] */ } func Rconv(r int) string { var str string var fp string - if r >= D_AL && r <= D_NONE { - str = fmt.Sprintf("%s", Register[r-D_AL]) + if r == REG_NONE { + fp += "NONE" + return fp + } + if r >= REG_AL && r-REG_AL < len(Register) { + str = fmt.Sprintf("%s", Register[r-REG_AL]) } else { - str = fmt.Sprintf("gok(%d)", r) } diff --git a/src/cmd/internal/obj/i386/obj8.go b/src/cmd/internal/obj/i386/obj8.go index 909e8f53c6..69385a1ef4 100644 --- a/src/cmd/internal/obj/i386/obj8.go +++ b/src/cmd/internal/obj/i386/obj8.go @@ -38,51 +38,6 @@ import ( "math" ) -var zprg = obj.Prog{ - Back: 2, - As: AGOK, - From: obj.Addr{ - Type: D_NONE, - Index: D_NONE, - Scale: 1, - }, - To: obj.Addr{ - Type: D_NONE, - Index: D_NONE, - Scale: 1, - }, -} - -func symtype(a *obj.Addr) int { - var t int - - t = int(a.Type) - if t == D_ADDR { - t = int(a.Index) - } - return t -} - -func isdata(p *obj.Prog) bool { - return p.As == ADATA || p.As == AGLOBL -} - -func iscall(p *obj.Prog) bool { - return p.As == ACALL -} - -func datasize(p *obj.Prog) int { - return int(p.From.Scale) -} - -func textflag(p *obj.Prog) int { - return int(p.From.Scale) -} - -func settextflag(p *obj.Prog, f int) { - p.From.Scale = int8(f) -} - func canuselocaltls(ctxt *obj.Link) int { switch ctxt.Headtype { case obj.Hlinux, @@ -102,7 +57,6 @@ func progedit(ctxt *obj.Link, p *obj.Prog) { // See obj6.c for discussion of TLS. if canuselocaltls(ctxt) != 0 { - // Reduce TLS initial exec model to TLS local exec model. // Sequences like // MOVL TLS, BX @@ -110,26 +64,26 @@ func progedit(ctxt *obj.Link, p *obj.Prog) { // become // NOP // ... off(TLS) ... - if p.As == AMOVL && p.From.Type == D_TLS && D_AX <= p.To.Type && p.To.Type <= D_DI { - - p.As = ANOP - p.From.Type = D_NONE - p.To.Type = D_NONE + 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.Index == D_TLS && D_INDIR+D_AX <= p.From.Type && p.From.Type <= D_INDIR+D_DI { - p.From.Type = D_INDIR + D_TLS + 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 = D_NONE + p.From.Index = REG_NONE } - if p.To.Index == D_TLS && D_INDIR+D_AX <= p.To.Type && p.To.Type <= D_INDIR+D_DI { - p.To.Type = D_INDIR + D_TLS + 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 = D_NONE + 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 @@ -137,59 +91,52 @@ func progedit(ctxt *obj.Link, p *obj.Prog) { // 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 == D_INDIR+D_TLS && D_AX <= p.To.Type && p.To.Type <= D_DI { - + 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 = p.From - q.From.Type = D_INDIR + p.To.Type - q.From.Index = D_TLS + 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 = D_TLS - p.From.Index = D_NONE + 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 == D_TLS { + if p.From.Scale == 1 && p.From.Index == REG_TLS { p.From.Scale = 2 } - if p.To.Scale == 1 && p.To.Index == D_TLS { + if p.To.Scale == 1 && p.To.Index == REG_TLS { p.To.Scale = 2 } } - // Rewrite CALL/JMP/RET to symbol as D_BRANCH. + // Rewrite CALL/JMP/RET to symbol as TYPE_BRANCH. switch p.As { - - case ACALL, - AJMP, - ARET: - if (p.To.Type == D_EXTERN || p.To.Type == D_STATIC) && p.To.Sym != nil { - p.To.Type = D_BRANCH + 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 } break } // 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 == D_FCONST { - + if p.From.Type == obj.TYPE_FCONST { if p.From.U.Dval == 0 { - if p.To.Type >= D_X0 { - if p.To.Type <= D_X7 { - p.As = AXORPS - p.From.Type = p.To.Type - p.From.Index = p.To.Index - break - } + 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 } } } @@ -212,8 +159,7 @@ func progedit(ctxt *obj.Link, p *obj.Prog) { ADIVSS, ACOMISS, AUCOMISS: - if p.From.Type == D_FCONST { - + if p.From.Type == obj.TYPE_FCONST { var i32 uint32 var f32 float32 f32 = float32(p.From.U.Dval) @@ -226,23 +172,20 @@ func progedit(ctxt *obj.Link, p *obj.Prog) { s.Reachable = 0 } - p.From.Type = D_EXTERN + 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 == D_FCONST { - + if p.From.Type == obj.TYPE_FCONST { if p.From.U.Dval == 0 { - if p.To.Type >= D_X0 { - if p.To.Type <= D_X7 { - p.As = AXORPS - p.From.Type = p.To.Type - p.From.Index = p.To.Index - break - } + 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 } } } @@ -265,8 +208,7 @@ func progedit(ctxt *obj.Link, p *obj.Prog) { ADIVSD, ACOMISD, AUCOMISD: - if p.From.Type == D_FCONST { - + if p.From.Type == obj.TYPE_FCONST { var i64 uint64 i64 = math.Float64bits(p.From.U.Dval) literal = fmt.Sprintf("$f64.%016x", i64) @@ -277,7 +219,8 @@ func progedit(ctxt *obj.Link, p *obj.Prog) { s.Reachable = 0 } - p.From.Type = D_EXTERN + p.From.Type = obj.TYPE_MEM + p.From.Name = obj.NAME_EXTERN p.From.Sym = s p.From.Offset = 0 } @@ -286,12 +229,7 @@ func progedit(ctxt *obj.Link, p *obj.Prog) { } } -func prg() *obj.Prog { - p := zprg - return &p -} - -func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) { +func preprocess(ctxt *obj.Link, cursym *obj.LSym) { var p *obj.Prog var q *obj.Prog var p1 *obj.Prog @@ -322,37 +260,35 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) { } cursym.Locals = autoffset - cursym.Args = p.To.Offset2 + cursym.Args = p.To.U.Argsize q = nil - if !(p.From.Scale&obj.NOSPLIT != 0) || (p.From.Scale&obj.WRAPPER != 0) { + 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 } - if !(cursym.Text.From.Scale&obj.NOSPLIT != 0) { - p = stacksplit(ctxt, p, autoffset, bool2int(!(cursym.Text.From.Scale&obj.NEEDCTXT != 0)), &q) // emit split check + if !(cursym.Text.From3.Offset&obj.NOSPLIT != 0) { + p = stacksplit(ctxt, p, autoffset, bool2int(!(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 = D_CONST + 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 = ANOP + p.As = obj.ANOP p.Spadj = int32(-ctxt.Arch.Ptrsize) p = obj.Appendp(ctxt, p) - p.As = ANOP + p.As = obj.ANOP p.Spadj = int32(ctxt.Arch.Ptrsize) } @@ -361,7 +297,7 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) { } deltasp = autoffset - if cursym.Text.From.Scale&obj.WRAPPER != 0 { + 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 @@ -380,71 +316,85 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) { p = obj.Appendp(ctxt, p) p.As = AMOVL - p.From.Type = D_INDIR + D_CX + p.From.Type = obj.TYPE_MEM + p.From.Reg = REG_CX p.From.Offset = 4 * int64(ctxt.Arch.Ptrsize) // G.panic - p.To.Type = D_BX + p.To.Type = obj.TYPE_REG + p.To.Reg = REG_BX p = obj.Appendp(ctxt, p) p.As = ATESTL - p.From.Type = D_BX - p.To.Type = D_BX + 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 = D_BRANCH + p.To.Type = obj.TYPE_BRANCH p1 = p p = obj.Appendp(ctxt, p) p.As = ALEAL - p.From.Type = D_INDIR + D_SP + p.From.Type = obj.TYPE_MEM + p.From.Reg = REG_SP p.From.Offset = int64(autoffset) + 4 - p.To.Type = D_DI + p.To.Type = obj.TYPE_REG + p.To.Reg = REG_DI p = obj.Appendp(ctxt, p) p.As = ACMPL - p.From.Type = D_INDIR + D_BX + p.From.Type = obj.TYPE_MEM + p.From.Reg = REG_BX p.From.Offset = 0 // Panic.argp - p.To.Type = D_DI + p.To.Type = obj.TYPE_REG + p.To.Reg = REG_DI p = obj.Appendp(ctxt, p) p.As = AJNE - p.To.Type = D_BRANCH + p.To.Type = obj.TYPE_BRANCH p2 = p p = obj.Appendp(ctxt, p) p.As = AMOVL - p.From.Type = D_SP - p.To.Type = D_INDIR + D_BX + 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 = ANOP + p.As = obj.ANOP p1.Pcond = p p2.Pcond = p } - if ctxt.Debugzerostack != 0 && autoffset != 0 && !(cursym.Text.From.Scale&obj.NOSPLIT != 0) { + 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 = D_SP - p.To.Type = D_DI + 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 = D_CONST + p.From.Type = obj.TYPE_CONST p.From.Offset = int64(autoffset) / 4 - p.To.Type = D_CX + p.To.Type = obj.TYPE_REG + p.To.Reg = REG_CX p = obj.Appendp(ctxt, p) p.As = AMOVL - p.From.Type = D_CONST + p.From.Type = obj.TYPE_CONST p.From.Offset = 0 - p.To.Type = D_AX + p.To.Type = obj.TYPE_REG + p.To.Reg = REG_AX p = obj.Appendp(ctxt, p) p.As = AREP @@ -454,18 +404,18 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) { } for ; p != nil; p = p.Link { - a = int(p.From.Type) - if a == D_AUTO { + a = int(p.From.Name) + if a == obj.NAME_AUTO { p.From.Offset += int64(deltasp) } - if a == D_PARAM { + if a == obj.NAME_PARAM { p.From.Offset += int64(deltasp) + 4 } - a = int(p.To.Type) - if a == D_AUTO { + a = int(p.To.Name) + if a == obj.NAME_AUTO { p.To.Offset += int64(deltasp) } - if a == D_PARAM { + if a == obj.NAME_PARAM { p.To.Offset += int64(deltasp) + 4 } @@ -497,7 +447,7 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) { p.Spadj = -2 continue - case ARET: + case obj.ARET: break } @@ -507,11 +457,11 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) { if autoffset != 0 { p.As = AADJSP - p.From.Type = D_CONST + p.From.Type = obj.TYPE_CONST p.From.Offset = int64(-autoffset) p.Spadj = -autoffset p = obj.Appendp(ctxt, p) - p.As = ARET + p.As = obj.ARET // If there are instructions following // this ARET, they come from a branch @@ -521,7 +471,7 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) { } if p.To.Sym != nil { // retjmp - p.As = AJMP + p.As = obj.AJMP } } } @@ -532,13 +482,14 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) { // 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 { - var next *obj.Prog p.As = AMOVL - p.From.Type = D_INDIR + D_TLS + p.From.Type = obj.TYPE_MEM + p.From.Reg = REG_TLS p.From.Offset = 0 - p.To.Type = D_CX + p.To.Type = obj.TYPE_REG + p.To.Reg = REG_CX next = p.Link progedit(ctxt, p) @@ -546,7 +497,7 @@ func load_g_cx(ctxt *obj.Link, p *obj.Prog) *obj.Prog { p = p.Link } - if p.From.Index == D_TLS { + if p.From.Index == REG_TLS { p.From.Scale = 2 } @@ -560,7 +511,6 @@ func load_g_cx(ctxt *obj.Link, p *obj.Prog) *obj.Prog { // 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 int, jmpok **obj.Prog) *obj.Prog { - var q *obj.Prog var q1 *obj.Prog @@ -573,23 +523,25 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32, noctxt int, jmpok p = obj.Appendp(ctxt, p) p.As = ACMPL - p.From.Type = D_INDIR + D_CX + p.From.Type = obj.TYPE_MEM + p.From.Reg = REG_CX p.From.Offset = 4 - p.To.Type = D_SP + p.To.Type = obj.TYPE_REG + p.To.Reg = REG_SP p = obj.Appendp(ctxt, p) p.As = AJCC - p.To.Type = D_BRANCH + p.To.Type = obj.TYPE_BRANCH p.To.Offset = 4 q1 = p p = obj.Appendp(ctxt, p) p.As = AINT - p.From.Type = D_CONST + p.From.Type = obj.TYPE_CONST p.From.Offset = 3 p = obj.Appendp(ctxt, p) - p.As = ANOP + p.As = obj.ANOP q1.Pcond = p } @@ -601,8 +553,10 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32, noctxt int, jmpok p = obj.Appendp(ctxt, p) p.As = ACMPL - p.From.Type = D_SP - p.To.Type = D_INDIR + D_CX + 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 @@ -614,20 +568,23 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32, noctxt int, jmpok p = obj.Appendp(ctxt, p) p.As = ALEAL - p.From.Type = D_INDIR + D_SP + p.From.Type = obj.TYPE_MEM + p.From.Reg = REG_SP p.From.Offset = -(int64(framesize) - obj.StackSmall) - p.To.Type = D_AX + p.To.Type = obj.TYPE_REG + p.To.Reg = REG_AX p = obj.Appendp(ctxt, p) p.As = ACMPL - p.From.Type = D_AX - p.To.Type = D_INDIR + D_CX + 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) @@ -645,41 +602,49 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32, noctxt int, jmpok p = obj.Appendp(ctxt, p) p.As = AMOVL - p.From.Type = D_INDIR + D_CX + 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 = D_SI + p.To.Type = obj.TYPE_REG + p.To.Reg = REG_SI p = obj.Appendp(ctxt, p) p.As = ACMPL - p.From.Type = D_SI - p.To.Type = D_CONST + 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 = D_BRANCH + p.To.Type = obj.TYPE_BRANCH q1 = p p = obj.Appendp(ctxt, p) p.As = ALEAL - p.From.Type = D_INDIR + D_SP + p.From.Type = obj.TYPE_MEM + p.From.Reg = REG_SP p.From.Offset = obj.StackGuard - p.To.Type = D_AX + p.To.Type = obj.TYPE_REG + p.To.Reg = REG_AX p = obj.Appendp(ctxt, p) p.As = ASUBL - p.From.Type = D_SI + p.From.Type = obj.TYPE_REG + p.From.Reg = REG_SI p.From.Offset = 0 - p.To.Type = D_AX + p.To.Type = obj.TYPE_REG + p.To.Reg = REG_AX p = obj.Appendp(ctxt, p) p.As = ACMPL - p.From.Type = D_AX - p.To.Type = D_CONST + 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) } @@ -687,23 +652,22 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32, noctxt int, jmpok p = obj.Appendp(ctxt, p) p.As = AJHI - p.To.Type = D_BRANCH + p.To.Type = obj.TYPE_BRANCH p.To.Offset = 4 q = p p = obj.Appendp(ctxt, p) - p.As = ACALL - p.To.Type = D_BRANCH + 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[noctxt] } p = obj.Appendp(ctxt, p) - p.As = AJMP - p.To.Type = D_BRANCH + p.As = obj.AJMP + p.To.Type = obj.TYPE_BRANCH p.Pcond = ctxt.Cursym.Text.Link if q != nil { @@ -723,7 +687,7 @@ func follow(ctxt *obj.Link, s *obj.LSym) { ctxt.Cursym = s - firstp = ctxt.NewProg() + firstp = new(obj.Prog) lastp = firstp xfol(ctxt, s.Text, &lastp) lastp.Link = nil @@ -732,11 +696,11 @@ func follow(ctxt *obj.Link, s *obj.LSym) { func nofollow(a int) int { switch a { - case AJMP, - ARET, + case obj.AJMP, + obj.ARET, AIRETL, AIRETW, - AUNDEF: + obj.AUNDEF: return 1 } @@ -808,9 +772,9 @@ loop: if p == nil { return } - if p.As == AJMP { + if p.As == obj.AJMP { q = p.Pcond - if q != nil && q.As != ATEXT { + if q != nil && q.As != obj.ATEXT { /* mark instruction as done and continue layout at target of jump */ p.Mark = 1 @@ -829,7 +793,6 @@ loop: i = 0 q = p for ; i < 4; (func() { i++; q = q.Link })() { - if q == nil { break } @@ -837,7 +800,7 @@ loop: break } a = int(q.As) - if a == ANOP { + if a == obj.ANOP { i-- continue } @@ -848,11 +811,11 @@ loop: if q.Pcond == nil || q.Pcond.Mark != 0 { continue } - if a == ACALL || a == ALOOP { + if a == obj.ACALL || a == ALOOP { continue } for { - if p.As == ANOP { + if p.As == obj.ANOP { p = p.Link continue } @@ -879,10 +842,10 @@ loop: /* */ } } - q = ctxt.NewProg() - q.As = AJMP + q = new(obj.Prog) + q.As = obj.AJMP q.Lineno = p.Lineno - q.To.Type = D_BRANCH + q.To.Type = obj.TYPE_BRANCH q.To.Offset = p.Pc q.Pcond = p p = q @@ -897,10 +860,9 @@ loop: /* continue loop with what comes after p */ if nofollow(a) != 0 { - return } - if p.Pcond != nil && a != ACALL { + if p.Pcond != nil && a != obj.ACALL { /* * some kind of conditional branch. * recurse to follow one path. @@ -908,14 +870,13 @@ loop: */ 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 == D_CONST { + if p.From.Type == obj.TYPE_CONST { if p.From.Offset == 1 { /* * expect conditional jump to be taken. @@ -928,7 +889,6 @@ loop: p.Pcond = q } } else { - q = p.Link if q.Mark != 0 { if a != ALOOP { @@ -952,45 +912,16 @@ loop: } var Link386 = obj.LinkArch{ - ByteOrder: binary.LittleEndian, - Pconv: Pconv, - Name: "386", - Thechar: '8', - Endian: obj.LittleEndian, - Addstacksplit: addstacksplit, - Assemble: span8, - Datasize: datasize, - Follow: follow, - Iscall: iscall, - Isdata: isdata, - Prg: prg, - Progedit: progedit, - Settextflag: settextflag, - Symtype: symtype, - Textflag: textflag, - Minlc: 1, - Ptrsize: 4, - Regsize: 4, - D_ADDR: D_ADDR, - D_AUTO: D_AUTO, - D_BRANCH: D_BRANCH, - D_CONST: D_CONST, - D_EXTERN: D_EXTERN, - D_FCONST: D_FCONST, - D_NONE: D_NONE, - D_PARAM: D_PARAM, - D_SCONST: D_SCONST, - D_STATIC: D_STATIC, - ACALL: ACALL, - ADATA: ADATA, - AEND: AEND, - AFUNCDATA: AFUNCDATA, - AGLOBL: AGLOBL, - AJMP: AJMP, - ANOP: ANOP, - APCDATA: APCDATA, - ARET: ARET, - ATEXT: ATEXT, - ATYPE: ATYPE, - AUSEFIELD: AUSEFIELD, + ByteOrder: binary.LittleEndian, + Pconv: Pconv, + Name: "386", + Thechar: '8', + Endian: obj.LittleEndian, + Preprocess: preprocess, + Assemble: span8, + Follow: follow, + Progedit: progedit, + Minlc: 1, + Ptrsize: 4, + Regsize: 4, } diff --git a/src/cmd/internal/obj/ld.go b/src/cmd/internal/obj/ld.go index 06dee836a1..f28f6877bf 100644 --- a/src/cmd/internal/obj/ld.go +++ b/src/cmd/internal/obj/ld.go @@ -116,7 +116,6 @@ func mkfwd(sym *LSym) { if i == 0 { cnt[i] = 1 } else { - cnt[i] = LOG * cnt[i-1] } dwn[i] = 1 diff --git a/src/cmd/internal/obj/link.go b/src/cmd/internal/obj/link.go index f2311f9234..308b6b63d5 100644 --- a/src/cmd/internal/obj/link.go +++ b/src/cmd/internal/obj/link.go @@ -33,24 +33,25 @@ package obj import "encoding/binary" type Addr struct { + Type int16 + Reg int16 + Index int16 + Scale int8 + Name int8 Offset int64 + Sym *LSym U struct { - Sval string - Dval float64 - Branch *Prog + Sval string + Dval float64 + Branch *Prog + Argsize int32 + Bits uint64 } - Sym *LSym - Gotype *LSym - Type int16 - Index uint8 - Scale int8 - Reg int8 - Name int8 - Class int8 - Etype uint8 - Offset2 int32 - Node interface{} - Width int64 + Gotype *LSym + Class int8 + Etype uint8 + Node interface{} + Width int64 } type Prog struct { @@ -61,7 +62,7 @@ type Prog struct { As int16 Scond uint8 From Addr - Reg uint8 + Reg int16 From3 Addr To Addr Opt interface{} @@ -79,7 +80,6 @@ type Prog struct { Printed uint8 Width int8 Mode int8 - TEXTFLAG uint8 } type LSym struct { @@ -149,7 +149,7 @@ type Auto struct { Asym *LSym Link *Auto Aoffset int32 - Type int16 + Name int16 Gotype *LSym } @@ -240,48 +240,18 @@ type Plist struct { } type LinkArch struct { - Pconv func(*Prog) string - Name string - Thechar int - Endian int32 - ByteOrder binary.ByteOrder - Addstacksplit func(*Link, *LSym) - Assemble func(*Link, *LSym) - Datasize func(*Prog) int - Follow func(*Link, *LSym) - Iscall func(*Prog) bool - Isdata func(*Prog) bool - Prg func() *Prog - Progedit func(*Link, *Prog) - Settextflag func(*Prog, int) - Symtype func(*Addr) int - Textflag func(*Prog) int - Minlc int - Ptrsize int - Regsize int - D_ADDR int - D_AUTO int - D_BRANCH int - D_CONST int - D_EXTERN int - D_FCONST int - D_NONE int - D_PARAM int - D_SCONST int - D_STATIC int - D_OREG int - ACALL int - ADATA int - AEND int - AFUNCDATA int - AGLOBL int - AJMP int - ANOP int - APCDATA int - ARET int - ATEXT int - ATYPE int - AUSEFIELD int + Pconv func(*Prog) string + ByteOrder binary.ByteOrder + Name string + Thechar int + Endian int32 + Preprocess func(*Link, *LSym) + Assemble func(*Link, *LSym) + Follow func(*Link, *LSym) + Progedit func(*Link, *Prog) + Minlc int + Ptrsize int + Regsize int } type Library struct { @@ -318,7 +288,156 @@ type Pciter struct { done int } -// prevent incompatible type signatures between liblink and 8l on Plan 9 +// An Addr is an argument to an instruction. +// The general forms and their encodings are: +// +// sym±offset(symkind)(reg)(index*scale) +// Memory reference at address &sym(symkind) + offset + reg + index*scale. +// Any of sym(symkind), ±offset, (reg), (index*scale), and *scale can be omitted. +// If (reg) and *scale are both omitted, the resulting expression (index) is parsed as (reg). +// To force a parsing as index*scale, write (index*1). +// Encoding: +// type = TYPE_MEM +// name = symkind (NAME_AUTO, ...) or 0 (NAME_NONE) +// sym = sym +// offset = ±offset +// reg = reg (REG_*) +// index = index (REG_*) +// scale = scale (1, 2, 4, 8) +// +// $<mem> +// Effective address of memory reference <mem>, defined above. +// Encoding: same as memory reference, but type = TYPE_ADDR. +// +// $<±integer value> +// This is a special case of $<mem>, in which only ±offset is present. +// It has a separate type for easy recognition. +// Encoding: +// type = TYPE_CONST +// offset = ±integer value +// +// *<mem> +// Indirect reference through memory reference <mem>, defined above. +// Only used on x86 for CALL/JMP *sym(SB), which calls/jumps to a function +// pointer stored in the data word sym(SB), not a function named sym(SB). +// Encoding: same as above, but type = TYPE_INDIR. +// +// $*$<mem> +// No longer used. +// On machines with actual SB registers, $*$<mem> forced the +// instruction encoding to use a full 32-bit constant, never a +// reference relative to SB. +// +// $<floating point literal> +// Floating point constant value. +// Encoding: +// type = TYPE_FCONST +// u.dval = floating point value +// +// $<string literal, up to 8 chars> +// String literal value (raw bytes used for DATA instruction). +// Encoding: +// type = TYPE_SCONST +// u.sval = string +// +// <register name> +// Any register: integer, floating point, control, segment, and so on. +// If looking for specific register kind, must check type and reg value range. +// Encoding: +// type = TYPE_REG +// reg = reg (REG_*) +// +// x(PC) +// Encoding: +// type = TYPE_BRANCH +// u.branch = Prog* reference OR ELSE offset = target pc (branch takes priority) +// +// $±x-±y +// Final argument to TEXT, specifying local frame size x and argument size y. +// In this form, x and y are integer literals only, not arbitrary expressions. +// This avoids parsing ambiguities due to the use of - as a separator. +// The ± are optional. +// If the final argument to TEXT omits the -±y, the encoding should still +// use TYPE_TEXTSIZE (not TYPE_CONST), with u.argsize = ArgsSizeUnknown. +// Encoding: +// type = TYPE_TEXTSIZE +// offset = x +// u.argsize = y +// +// reg<<shift, reg>>shift, reg->shift, reg@>shift +// Shifted register value, for ARM. +// In this form, reg must be a register and shift can be a register or an integer constant. +// Encoding: +// type = TYPE_SHIFT +// offset = (reg&15) | shifttype<<5 | count +// shifttype = 0, 1, 2, 3 for <<, >>, ->, @> +// count = (reg&15)<<8 | 1<<4 for a register shift count, (n&31)<<7 for an integer constant. +// +// (reg, reg) +// A destination register pair. When used as the last argument of an instruction, +// this form makes clear that both registers are destinations. +// Encoding: +// type = TYPE_REGREG +// reg = first register +// offset = second register +// +// reg, reg +// TYPE_REGREG2, to be removed. +// + +const ( + NAME_NONE = 0 + iota + NAME_EXTERN + NAME_STATIC + NAME_AUTO + NAME_PARAM +) + +const ( + TYPE_NONE = 0 + TYPE_BRANCH = 5 + iota - 1 + TYPE_TEXTSIZE + TYPE_MEM + TYPE_CONST + TYPE_FCONST + TYPE_SCONST + TYPE_REG + TYPE_ADDR + TYPE_SHIFT + TYPE_REGREG + TYPE_REGREG2 + TYPE_INDIR +) + +// TODO(rsc): Describe prog. +// TODO(rsc): Describe TEXT/GLOBL flag in from3, DATA width in from3. + +// Prog.as opcodes. +// These are the portable opcodes, common to all architectures. +// Each architecture defines many more arch-specific opcodes, +// with values starting at A_ARCHSPECIFIC. +const ( + AXXX = 0 + iota + ACALL + ACHECKNIL + ADATA + ADUFFCOPY + ADUFFZERO + AEND + AFUNCDATA + AGLOBL + AJMP + ANOP + APCDATA + ARET + ATEXT + ATYPE + AUNDEF + AUSEFIELD + AVARDEF + AVARKILL + A_ARCHSPECIFIC +) // prevent incompatible type signatures between liblink and 8l on Plan 9 @@ -397,7 +516,7 @@ const ( RV_TYPE_MASK = RV_CHECK_OVERFLOW - 1 ) -// Auto.type +// Auto.name const ( A_AUTO = 1 + iota A_PARAM @@ -461,3 +580,17 @@ const ( // go.c // ld.c + +// list[5689].c + +// obj.c + +// objfile.c + +// pass.c + +// pcln.c + +// sym.c + +var linkbasepointer int diff --git a/src/cmd/internal/obj/obj.go b/src/cmd/internal/obj/obj.go index 4d8d13c8ec..214d9cae8b 100644 --- a/src/cmd/internal/obj/obj.go +++ b/src/cmd/internal/obj/obj.go @@ -15,7 +15,7 @@ const ( NSYM = 50 ) -func linklinefmt(ctxt *Link, lno0 int, showAll, showFullPath bool) string { +func Linklinefmt(ctxt *Link, lno0 int, showAll, showFullPath bool) string { var a [HISTSZ]struct { incl *Hist idel int32 @@ -222,11 +222,9 @@ func Linklinehist(ctxt *Link, lineno int, f string, offset int) { if offset != 0 { fmt.Printf("%4d: %s (#line %d)\n", lineno, f, offset) } else { - fmt.Printf("%4d: %s\n", lineno, f) } } else { - fmt.Printf("%4d: <pop>\n", lineno) } } @@ -297,7 +295,6 @@ func Linkprfile(ctxt *Link, line int) { * start a new Prog list. */ func Linknewplist(ctxt *Link) *Plist { - var pl *Plist pl = new(Plist) @@ -305,7 +302,6 @@ func Linknewplist(ctxt *Link) *Plist { if ctxt.Plist == nil { ctxt.Plist = pl } else { - ctxt.Plast.Link = pl } ctxt.Plast = pl diff --git a/src/cmd/internal/obj/objfile.go b/src/cmd/internal/obj/objfile.go index f1e1701f0f..7e4482ccf6 100644 --- a/src/cmd/internal/obj/objfile.go +++ b/src/cmd/internal/obj/objfile.go @@ -17,7 +17,6 @@ var outfile string // out a Go object file. The linker does not call this; the linker // does not write out object files. func Writeobjdirect(ctxt *Link, b *Biobuf) { - var flag int var found int var h *Hist @@ -44,16 +43,16 @@ func Writeobjdirect(ctxt *Link, b *Biobuf) { for pl = ctxt.Plist; pl != nil; pl = pl.Link { for p = pl.Firstpc; p != nil; p = plink { if ctxt.Debugasm != 0 && ctxt.Debugvlog != 0 { - fmt.Printf("obj: %p %v\n", p, p) + fmt.Printf("obj: %v\n", p) } plink = p.Link p.Link = nil - if int(p.As) == ctxt.Arch.AEND { + if p.As == AEND { continue } - if int(p.As) == ctxt.Arch.ATYPE { + if p.As == ATYPE { // Assume each TYPE instruction describes // a different local variable or parameter, // so no dedup. @@ -66,20 +65,19 @@ func Writeobjdirect(ctxt *Link, b *Biobuf) { // If something else could use them, we could arrange to // preserve them. if curtext == nil { - continue } a = new(Auto) a.Asym = p.From.Sym a.Aoffset = int32(p.From.Offset) - a.Type = int16(ctxt.Arch.Symtype(&p.From)) + a.Name = int16(p.From.Name) a.Gotype = p.From.Gotype a.Link = curtext.Autom curtext.Autom = a continue } - if int(p.As) == ctxt.Arch.AGLOBL { + if p.As == AGLOBL { s = p.From.Sym tmp6 := s.Seenglobl s.Seenglobl++ @@ -93,7 +91,6 @@ func Writeobjdirect(ctxt *Link, b *Biobuf) { if data == nil { data = s } else { - edata.Next = s } s.Next = nil @@ -101,7 +98,7 @@ func Writeobjdirect(ctxt *Link, b *Biobuf) { if s.Type == 0 || s.Type == SXREF { s.Type = SBSS } - flag = ctxt.Arch.Textflag(p) + flag = int(p.From3.Offset) if flag&DUPOK != 0 { s.Dupok = 1 } @@ -114,12 +111,12 @@ func Writeobjdirect(ctxt *Link, b *Biobuf) { continue } - if int(p.As) == ctxt.Arch.ADATA { + if p.As == ADATA { savedata(ctxt, p.From.Sym, p, "<input>") continue } - if int(p.As) == ctxt.Arch.ATEXT { + if p.As == ATEXT { s = p.From.Sym if s == nil { // func _() { } @@ -138,11 +135,10 @@ func Writeobjdirect(ctxt *Link, b *Biobuf) { if text == nil { text = s } else { - etext.Next = s } etext = s - flag = ctxt.Arch.Textflag(p) + flag = int(p.From3.Offset) if flag&DUPOK != 0 { s.Dupok = 1 } @@ -157,16 +153,16 @@ func Writeobjdirect(ctxt *Link, b *Biobuf) { continue } - if int(p.As) == ctxt.Arch.AFUNCDATA { + if p.As == AFUNCDATA { // Rewrite reference to go_args_stackmap(SB) to the Go-provided declaration information. if curtext == nil { // func _() {} continue } if p.To.Sym.Name == "go_args_stackmap" { - if int(p.From.Type) != ctxt.Arch.D_CONST || p.From.Offset != FUNCDATA_ArgsPointerMaps { + if p.From.Type != TYPE_CONST || p.From.Offset != FUNCDATA_ArgsPointerMaps { ctxt.Diag("FUNCDATA use of go_args_stackmap(SB) without FUNCDATA_ArgsPointerMaps") } - p.To.Sym = Linklookup(ctxt, string(fmt.Sprintf("%s.args_stackmap", curtext.Name)), int(curtext.Version)) + p.To.Sym = Linklookup(ctxt, fmt.Sprintf("%s.args_stackmap", curtext.Name), int(curtext.Version)) } } @@ -181,13 +177,12 @@ func Writeobjdirect(ctxt *Link, b *Biobuf) { // Add reference to Go arguments for C or assembly functions without them. for s = text; s != nil; s = s.Next { - if !strings.HasPrefix(s.Name, "\"\".") { continue } found = 0 for p = s.Text; p != nil; p = p.Link { - if int(p.As) == ctxt.Arch.AFUNCDATA && int(p.From.Type) == ctxt.Arch.D_CONST && p.From.Offset == FUNCDATA_ArgsPointerMaps { + if p.As == AFUNCDATA && p.From.Type == TYPE_CONST && p.From.Offset == FUNCDATA_ArgsPointerMaps { found = 1 break } @@ -195,28 +190,21 @@ func Writeobjdirect(ctxt *Link, b *Biobuf) { if !(found != 0) { p = Appendp(ctxt, s.Text) - p.As = int16(ctxt.Arch.AFUNCDATA) - p.From.Type = int16(ctxt.Arch.D_CONST) + p.As = AFUNCDATA + p.From.Type = TYPE_CONST p.From.Offset = FUNCDATA_ArgsPointerMaps - if ctxt.Arch.Thechar == '6' || ctxt.Arch.Thechar == '8' { - p.To.Type = int16(ctxt.Arch.D_EXTERN) - } else { - - p.To.Type = int16(ctxt.Arch.D_OREG) - p.To.Name = int8(ctxt.Arch.D_EXTERN) - } - - p.To.Sym = Linklookup(ctxt, string(fmt.Sprintf("%s.args_stackmap", s.Name)), int(s.Version)) + p.To.Type = TYPE_MEM + p.To.Name = NAME_EXTERN + p.To.Sym = Linklookup(ctxt, fmt.Sprintf("%s.args_stackmap", s.Name), int(s.Version)) } } // Turn functions into machine code images. for s = text; s != nil; s = s.Next { - mkfwd(s) linkpatch(ctxt, s) ctxt.Arch.Follow(ctxt, s) - ctxt.Arch.Addstacksplit(ctxt, s) + ctxt.Arch.Preprocess(ctxt, s) ctxt.Arch.Assemble(ctxt, s) linkpcln(ctxt, s) } @@ -230,7 +218,6 @@ func Writeobjdirect(ctxt *Link, b *Biobuf) { // Emit autolib. for h = ctxt.Hist; h != nil; h = h.Link { - if h.Offset < 0 { wrstring(b, h.Name) } @@ -239,7 +226,6 @@ func Writeobjdirect(ctxt *Link, b *Biobuf) { // Emit symbols. for s = text; s != nil; s = s.Next { - writesym(ctxt, b, s) } for s = data; s != nil; s = s.Next { @@ -307,7 +293,6 @@ func writesym(ctxt *Link, b *Biobuf, s *LSym) { if ' ' <= c && c <= 0x7e { fmt.Fprintf(ctxt.Bso, "%c", c) } else { - fmt.Fprintf(ctxt.Bso, ".") } } @@ -325,7 +310,6 @@ func writesym(ctxt *Link, b *Biobuf, s *LSym) { if ctxt.Arch.Thechar == '5' || ctxt.Arch.Thechar == '9' { fmt.Fprintf(ctxt.Bso, "\trel %d+%d t=%d %s+%x\n", int(r.Off), r.Siz, r.Type, name, uint64(int64(r.Add))) } else { - fmt.Fprintf(ctxt.Bso, "\trel %d+%d t=%d %s+%d\n", int(r.Off), r.Siz, r.Type, name, int64(r.Add)) } } @@ -365,13 +349,12 @@ func writesym(ctxt *Link, b *Biobuf, s *LSym) { for a = s.Autom; a != nil; a = a.Link { wrsym(b, a.Asym) wrint(b, int64(a.Aoffset)) - if int(a.Type) == ctxt.Arch.D_AUTO { + if a.Name == NAME_AUTO { wrint(b, A_AUTO) - } else if int(a.Type) == ctxt.Arch.D_PARAM { + } else if a.Name == NAME_PARAM { wrint(b, A_PARAM) } else { - - log.Fatalf("%s: invalid local variable type %d", s.Name, a.Type) + log.Fatalf("%s: invalid local variable type %d", s.Name, a.Name) } wrsym(b, a.Gotype) } diff --git a/src/cmd/internal/obj/pass.go b/src/cmd/internal/obj/pass.go index a8c1c77d83..812e00b557 100644 --- a/src/cmd/internal/obj/pass.go +++ b/src/cmd/internal/obj/pass.go @@ -33,11 +33,10 @@ package obj // Code and data passes. func Brchain(ctxt *Link, p *Prog) *Prog { - var i int for i = 0; i < 20; i++ { - if p == nil || int(p.As) != ctxt.Arch.AJMP || p.Pcond == nil { + if p == nil || p.As != AJMP || p.Pcond == nil { return p } p = p.Pcond @@ -52,7 +51,7 @@ func brloop(ctxt *Link, p *Prog) *Prog { c = 0 for q = p; q != nil; q = q.Pcond { - if int(q.As) != ctxt.Arch.AJMP || q.Pcond == nil { + if q.As != AJMP || q.Pcond == nil { break } c++ @@ -64,6 +63,92 @@ func brloop(ctxt *Link, p *Prog) *Prog { return q } +func checkaddr(ctxt *Link, p *Prog, a *Addr) { + // Check expected encoding, especially TYPE_CONST vs TYPE_ADDR. + switch a.Type { + case TYPE_NONE: + return + + case TYPE_BRANCH: + if a.Reg != 0 || a.Index != 0 || a.Scale != 0 || a.Name != 0 { + break + } + return + + case TYPE_TEXTSIZE: + if a.Reg != 0 || a.Index != 0 || a.Scale != 0 || a.Name != 0 { + break + } + return + + //if(a->u.bits != 0) + // break; + case TYPE_MEM: + return + + // TODO(rsc): After fixing SHRQ, check a->index != 0 too. + case TYPE_CONST: + if a.Name != 0 || a.Sym != nil || a.Reg != 0 { + ctxt.Diag("argument is TYPE_CONST, should be TYPE_ADDR, in %v", p) + return + } + + if a.Reg != 0 || a.Scale != 0 || a.Name != 0 || a.Sym != nil || a.U.Bits != 0 { + break + } + return + + case TYPE_FCONST, + TYPE_SCONST: + if a.Reg != 0 || a.Index != 0 || a.Scale != 0 || a.Name != 0 || a.Offset != 0 || a.Sym != nil { + break + } + return + + // TODO(rsc): After fixing PINSRQ, check a->offset != 0 too. + // TODO(rsc): After fixing SHRQ, check a->index != 0 too. + case TYPE_REG: + if a.Scale != 0 || a.Name != 0 || a.Sym != nil { + break + } + return + + case TYPE_ADDR: + if a.U.Bits != 0 { + break + } + if a.Reg == 0 && a.Index == 0 && a.Scale == 0 && a.Name == 0 && a.Sym == nil { + ctxt.Diag("argument is TYPE_ADDR, should be TYPE_CONST, in %v", p) + } + return + + case TYPE_SHIFT: + if a.Index != 0 || a.Scale != 0 || a.Name != 0 || a.Sym != nil || a.U.Bits != 0 { + break + } + return + + case TYPE_REGREG: + if a.Index != 0 || a.Scale != 0 || a.Name != 0 || a.Sym != nil || a.U.Bits != 0 { + break + } + return + + case TYPE_REGREG2: + return + + // Expect sym and name to be set, nothing else. + // Technically more is allowed, but this is only used for *name(SB). + case TYPE_INDIR: + if a.Reg != 0 || a.Index != 0 || a.Scale != 0 || a.Name == 0 || a.Offset != 0 || a.Sym == nil || a.U.Bits != 0 { + break + } + return + } + + ctxt.Diag("invalid encoding for argument %v", p) +} + func linkpatch(ctxt *Link, sym *LSym) { var c int32 var name string @@ -73,10 +158,14 @@ func linkpatch(ctxt *Link, sym *LSym) { ctxt.Cursym = sym for p = sym.Text; p != nil; p = p.Link { + checkaddr(ctxt, p, &p.From) + checkaddr(ctxt, p, &p.From3) + checkaddr(ctxt, p, &p.To) + if ctxt.Arch.Progedit != nil { ctxt.Arch.Progedit(ctxt, p) } - if int(p.To.Type) != ctxt.Arch.D_BRANCH { + if p.To.Type != TYPE_BRANCH { continue } if p.To.U.Branch != nil { @@ -97,7 +186,6 @@ func linkpatch(ctxt *Link, sym *LSym) { if q.Forwd != nil && int64(c) >= q.Forwd.Pc { q = q.Forwd } else { - q = q.Link } } @@ -108,7 +196,7 @@ func linkpatch(ctxt *Link, sym *LSym) { name = p.To.Sym.Name } ctxt.Diag("branch out of range (%#x)\n%v [%s]", uint32(c), p, name) - p.To.Type = int16(ctxt.Arch.D_NONE) + p.To.Type = TYPE_NONE } p.To.U.Branch = q @@ -120,7 +208,7 @@ func linkpatch(ctxt *Link, sym *LSym) { if p.Pcond != nil { p.Pcond = brloop(ctxt, p.Pcond) if p.Pcond != nil { - if int(p.To.Type) == ctxt.Arch.D_BRANCH { + if p.To.Type == TYPE_BRANCH { p.To.Offset = p.Pcond.Pc } } diff --git a/src/cmd/internal/obj/pcln.go b/src/cmd/internal/obj/pcln.go index 32d9498fef..d31ec2cf86 100644 --- a/src/cmd/internal/obj/pcln.go +++ b/src/cmd/internal/obj/pcln.go @@ -28,7 +28,6 @@ func addvarint(ctxt *Link, d *Pcdata, val uint32) { // where func is the function, val is the current value, p is the instruction being // considered, and arg can be used to further parameterize valfunc. func funcpctab(ctxt *Link, dst *Pcdata, func_ *LSym, desc string, valfunc func(*Link, *LSym, int32, *Prog, int32, interface{}) int32, arg interface{}) { - var dbg int var i int var oldval int32 @@ -83,7 +82,6 @@ func funcpctab(ctxt *Link, dst *Pcdata, func_ *LSym, desc string, valfunc func(* // instruction. Keep going, so that we only emit a delta // for a true instruction boundary in the program. if p.Link != nil && p.Link.Pc == p.Pc { - val = valfunc(ctxt, func_, val, p, 1, arg) if ctxt.Debugpcln != 0 { fmt.Fprintf(ctxt.Bso, "%6x %6s %v\n", uint64(int64(p.Pc)), "", p) @@ -106,7 +104,6 @@ func funcpctab(ctxt *Link, dst *Pcdata, func_ *LSym, desc string, valfunc func(* // where the 0x80 bit indicates that the integer continues. if ctxt.Debugpcln != 0 { - fmt.Fprintf(ctxt.Bso, "%6x %6d %v\n", uint64(int64(p.Pc)), val, p) } @@ -119,7 +116,6 @@ func funcpctab(ctxt *Link, dst *Pcdata, func_ *LSym, desc string, valfunc func(* if delta>>31 != 0 { delta = 1 | ^(delta << 1) } else { - delta <<= 1 } addvarint(ctxt, dst, delta) @@ -152,13 +148,12 @@ func funcpctab(ctxt *Link, dst *Pcdata, func_ *LSym, desc string, valfunc func(* // Because p->lineno applies to p, phase == 0 (before p) // takes care of the update. func pctofileline(ctxt *Link, sym *LSym, oldval int32, p *Prog, phase int32, arg interface{}) int32 { - var i int32 var l int32 var f *LSym var pcln *Pcln - if int(p.As) == ctxt.Arch.ATEXT || int(p.As) == ctxt.Arch.ANOP || int(p.As) == ctxt.Arch.AUSEFIELD || p.Lineno == 0 || phase == 1 { + if p.As == ATEXT || p.As == ANOP || p.As == AUSEFIELD || p.Lineno == 0 || phase == 1 { return oldval } linkgetline(ctxt, p.Lineno, &f, &l) @@ -195,7 +190,6 @@ func pctofileline(ctxt *Link, sym *LSym, oldval int32, p *Prog, phase int32, arg // The adjustment by p takes effect only after p, so we // apply the change during phase == 1. func pctospadj(ctxt *Link, sym *LSym, oldval int32, p *Prog, phase int32, arg interface{}) int32 { - if oldval == -1 { // starting oldval = 0 } @@ -216,8 +210,7 @@ func pctospadj(ctxt *Link, sym *LSym, oldval int32, p *Prog, phase int32, arg in // Since PCDATA instructions have no width in the final code, // it does not matter which phase we use for the update. func pctopcdata(ctxt *Link, sym *LSym, oldval int32, p *Prog, phase int32, arg interface{}) int32 { - - if phase == 0 || int(p.As) != ctxt.Arch.APCDATA || p.From.Offset != int64(arg.(uint32)) { + if phase == 0 || p.As != APCDATA || p.From.Offset != int64(arg.(uint32)) { return oldval } if int64(int32(p.To.Offset)) != p.To.Offset { @@ -243,10 +236,10 @@ func linkpcln(ctxt *Link, cursym *LSym) { npcdata = 0 nfuncdata = 0 for p = cursym.Text; p != nil; p = p.Link { - if int(p.As) == ctxt.Arch.APCDATA && p.From.Offset >= int64(npcdata) { + if p.As == APCDATA && p.From.Offset >= int64(npcdata) { npcdata = int(p.From.Offset + 1) } - if int(p.As) == ctxt.Arch.AFUNCDATA && p.From.Offset >= int64(nfuncdata) { + if p.As == AFUNCDATA && p.From.Offset >= int64(nfuncdata) { nfuncdata = int(p.From.Offset + 1) } } @@ -265,21 +258,20 @@ func linkpcln(ctxt *Link, cursym *LSym) { havepc := make([]uint32, (npcdata+31)/32) havefunc := make([]uint32, (nfuncdata+31)/32) for p = cursym.Text; p != nil; p = p.Link { - if int(p.As) == ctxt.Arch.AFUNCDATA { + if p.As == AFUNCDATA { if (havefunc[p.From.Offset/32]>>uint64(p.From.Offset%32))&1 != 0 { ctxt.Diag("multiple definitions for FUNCDATA $%d", p.From.Offset) } havefunc[p.From.Offset/32] |= 1 << uint64(p.From.Offset%32) } - if int(p.As) == ctxt.Arch.APCDATA { + if p.As == APCDATA { havepc[p.From.Offset/32] |= 1 << uint64(p.From.Offset%32) } } // pcdata. for i = 0; i < npcdata; i++ { - if (havepc[i/32]>>uint(i%32))&1 == 0 { continue } @@ -288,12 +280,11 @@ func linkpcln(ctxt *Link, cursym *LSym) { // funcdata if nfuncdata > 0 { - for p = cursym.Text; p != nil; p = p.Link { - if int(p.As) == ctxt.Arch.AFUNCDATA { + if p.As == AFUNCDATA { i = int(p.From.Offset) pcln.Funcdataoff[i] = p.To.Offset - if int(p.To.Type) != ctxt.Arch.D_CONST { + if p.To.Type != TYPE_CONST { // TODO: Dedup. //funcdata_bytes += p->to.sym->size; pcln.Funcdata[i] = p.To.Sym @@ -306,7 +297,6 @@ func linkpcln(ctxt *Link, cursym *LSym) { // iteration over encoded pcdata tables. func getvarint(pp *[]byte) uint32 { - var p []byte var shift int var v uint32 diff --git a/src/cmd/internal/obj/ppc64/9.out.go b/src/cmd/internal/obj/ppc64/9.out.go index 3c20b93f55..2eb4b0c89c 100644 --- a/src/cmd/internal/obj/ppc64/9.out.go +++ b/src/cmd/internal/obj/ppc64/9.out.go @@ -29,6 +29,8 @@ package ppc64 +import "cmd/internal/obj" + // auto generated by go tool dist /* @@ -41,30 +43,112 @@ const ( NFREG = 32 ) +// avoid conflict with ucontext.h. sigh. const ( - REGZERO = 0 - REGSP = 1 - REGSB = 2 - REGRET = 3 + REG_R0 = 32 + iota + REG_R1 + REG_R2 + REG_R3 + REG_R4 + REG_R5 + REG_R6 + REG_R7 + REG_R8 + REG_R9 + REG_R10 + REG_R11 + REG_R12 + REG_R13 + REG_R14 + REG_R15 + REG_R16 + REG_R17 + REG_R18 + REG_R19 + REG_R20 + REG_R21 + REG_R22 + REG_R23 + REG_R24 + REG_R25 + REG_R26 + REG_R27 + REG_R28 + REG_R29 + REG_R30 + REG_R31 + REG_F0 = 64 + iota - 32 + REG_F1 + REG_F2 + REG_F3 + REG_F4 + REG_F5 + REG_F6 + REG_F7 + REG_F8 + REG_F9 + REG_F10 + REG_F11 + REG_F12 + REG_F13 + REG_F14 + REG_F15 + REG_F16 + REG_F17 + REG_F18 + REG_F19 + REG_F20 + REG_F21 + REG_F22 + REG_F23 + REG_F24 + REG_F25 + REG_F26 + REG_F27 + REG_F28 + REG_F29 + REG_F30 + REG_F31 + REG_SPECIAL = 96 + REG_C0 = 96 + iota - 65 + REG_C1 + REG_C2 + REG_C3 + REG_C4 + REG_C5 + REG_C6 + REG_C7 + REG_MSR = 104 + iota - 73 + REG_FPSCR + REG_CR + REG_SPR0 = 1024 + REG_DCR0 = 2048 + REG_XER = REG_SPR0 + 1 + REG_LR = REG_SPR0 + 8 + REG_CTR = REG_SPR0 + 9 + REGZERO = REG_R0 + REGSP = REG_R1 + REGSB = REG_R2 + REGRET = REG_R3 REGARG = -1 - REGRT1 = 3 - REGRT2 = 4 - REGMIN = 7 - REGENV = 11 - REGTLS = 13 - REGMAX = 27 - REGEXT = 30 - REGG = 30 - REGTMP = 31 - FREGRET = 0 - FREGMIN = 17 - FREGMAX = 26 - FREGEXT = 26 - FREGCVI = 27 - FREGZERO = 28 - FREGHALF = 29 - FREGONE = 30 - FREGTWO = 31 + REGRT1 = REG_R3 + REGRT2 = REG_R4 + REGMIN = REG_R7 + REGENV = REG_R11 + REGTLS = REG_R13 + REGMAX = REG_R27 + REGEXT = REG_R30 + REGG = REG_R30 + REGTMP = REG_R31 + FREGRET = REG_F0 + FREGMIN = REG_F17 + FREGMAX = REG_F26 + FREGEXT = REG_F26 + FREGCVI = REG_F27 + FREGZERO = REG_F28 + FREGHALF = REG_F29 + FREGONE = REG_F30 + FREGTWO = REG_F31 ) /* @@ -129,12 +213,12 @@ const ( C_ANY C_GOK C_ADDR + C_TEXTSIZE C_NCLASS ) const ( - AXXX = iota - AADD + AADD = obj.A_ARCHSPECIFIC + iota AADDCC AADDV AADDVCC @@ -163,11 +247,9 @@ const ( ABEQ ABGE ABGT - ABL ABLE ABLT ABNE - ABR ABVC ABVS ACMP @@ -349,19 +431,7 @@ const ( ATLBSYNC ATW ASYSCALL - ADATA - AGLOBL - AGOK - AHISTORY - ANAME - ANOP - ARETURN - ATEXT AWORD - AEND - ADYNT - AINIT - ASIGNAME ARFCI AFRES AFRESCC @@ -438,48 +508,8 @@ const ( AREMDUV AREMDUVCC AHRFID - AUNDEF - AUSEFIELD - ATYPE - AFUNCDATA - APCDATA - ACHECKNIL - AVARDEF - AVARKILL - ADUFFCOPY - ADUFFZERO ALAST -) - -/* type/name */ -const ( - D_GOK = 0 + iota - D_NONE - D_EXTERN - D_STATIC - D_AUTO - D_PARAM - D_BRANCH - D_OREG - D_CONST - D_FCONST - D_SCONST - D_REG - D_FPSCR - D_MSR - D_FREG - D_CREG - D_SPR - D_OPT - D_FILE - D_FILE1 - D_DCR - D_DCONST - D_ADDR - D_LAST - D_R0 = 0 - D_F0 = D_R0 + NREG - D_XER = 1 - D_LR = 8 - D_CTR = 9 + ABR = obj.AJMP + ABL = obj.ACALL + ARETURN = obj.ARET ) diff --git a/src/cmd/internal/obj/ppc64/anames9.go b/src/cmd/internal/obj/ppc64/anames9.go index 431c3fa31e..a49e14a9ee 100644 --- a/src/cmd/internal/obj/ppc64/anames9.go +++ b/src/cmd/internal/obj/ppc64/anames9.go @@ -1,13 +1,29 @@ package ppc64 -/* and many supervisor level registers */ - /* * this is the ranlib header */ var Anames = []string{ - "XXX", - "ADD", + "XXX ", + "CALL", + "CHECKNIL", + "DATA", + "DUFFCOPY", + "DUFFZERO", + "END", + "FUNCDATA", + "GLOBL", + "JMP", + "NOP", + "PCDATA", + "RET", + "TEXT", + "TYPE", + "UNDEF", + "USEFIELD", + "VARDEF", + "VARKILL", + "ADD ", "ADDCC", "ADDV", "ADDVCC", @@ -36,11 +52,9 @@ var Anames = []string{ "BEQ", "BGE", "BGT", - "BL", "BLE", "BLT", "BNE", - "BR", "BVC", "BVS", "CMP", @@ -222,19 +236,7 @@ var Anames = []string{ "TLBSYNC", "TW", "SYSCALL", - "DATA", - "GLOBL", - "GOK", - "HISTORY", - "NAME", - "NOP", - "RETURN", - "TEXT", "WORD", - "END", - "DYNT", - "INIT", - "SIGNAME", "RFCI", "FRES", "FRESCC", @@ -311,16 +313,6 @@ var Anames = []string{ "REMDUV", "REMDUVCC", "HRFID", - "UNDEF", - "USEFIELD", - "TYPE", - "FUNCDATA", - "PCDATA", - "CHECKNIL", - "VARDEF", - "VARKILL", - "DUFFCOPY", - "DUFFZERO", "LAST", } @@ -359,31 +351,6 @@ var cnames9 = []string{ "ANY", "GOK", "ADDR", + "TEXTSIZE", "NCLASS", } - -var dnames9 = []string{ - D_GOK: "GOK/R0", - D_NONE: "NONE/XER", - D_EXTERN: "EXTERN", - D_STATIC: "STATIC", - D_AUTO: "AUTO", - D_PARAM: "PARAM", - D_BRANCH: "BRANCH", - D_OREG: "OREG", - D_CONST: "CONST/LR", - D_FCONST: "FCONST/CTR", - D_SCONST: "SCONST", - D_REG: "REG", - D_FPSCR: "FPSCR", - D_MSR: "MSR", - D_FREG: "FREG", - D_CREG: "CREG", - D_SPR: "SPR", - D_OPT: "OPT", - D_FILE: "FILE", - D_FILE1: "FILE1", - D_DCR: "DCR", - D_DCONST: "DCONST", - D_ADDR: "ADDR", -} diff --git a/src/cmd/internal/obj/ppc64/asm9.go b/src/cmd/internal/obj/ppc64/asm9.go index fe3e626b03..9f6b7f3924 100644 --- a/src/cmd/internal/obj/ppc64/asm9.go +++ b/src/cmd/internal/obj/ppc64/asm9.go @@ -58,14 +58,10 @@ type Optab struct { } var optab = []Optab{ - Optab{ATEXT, C_LEXT, C_NONE, C_NONE, C_LCON, 0, 0, 0}, - Optab{ATEXT, C_LEXT, C_REG, C_NONE, C_LCON, 0, 0, 0}, - Optab{ATEXT, C_LEXT, C_NONE, C_LCON, C_LCON, 0, 0, 0}, - Optab{ATEXT, C_LEXT, C_REG, C_LCON, C_LCON, 0, 0, 0}, - Optab{ATEXT, C_ADDR, C_NONE, C_NONE, C_LCON, 0, 0, 0}, - Optab{ATEXT, C_ADDR, C_REG, C_NONE, C_LCON, 0, 0, 0}, - Optab{ATEXT, C_ADDR, C_NONE, C_LCON, C_LCON, 0, 0, 0}, - Optab{ATEXT, C_ADDR, C_REG, C_LCON, C_LCON, 0, 0, 0}, + Optab{obj.ATEXT, C_LEXT, C_NONE, C_NONE, C_TEXTSIZE, 0, 0, 0}, + Optab{obj.ATEXT, C_LEXT, C_NONE, C_LCON, C_TEXTSIZE, 0, 0, 0}, + Optab{obj.ATEXT, C_ADDR, C_NONE, C_NONE, C_TEXTSIZE, 0, 0, 0}, + Optab{obj.ATEXT, C_ADDR, C_NONE, C_LCON, C_TEXTSIZE, 0, 0, 0}, /* move register */ Optab{AMOVD, C_REG, C_NONE, C_NONE, C_REG, 1, 4, 0}, Optab{AMOVB, C_REG, C_NONE, C_NONE, C_REG, 12, 4, 0}, @@ -389,15 +385,15 @@ var optab = []Optab{ Optab{ASTSW, C_REG, C_NONE, C_LCON, C_ZOREG, 41, 4, 0}, Optab{ALSW, C_ZOREG, C_NONE, C_NONE, C_REG, 45, 4, 0}, Optab{ALSW, C_ZOREG, C_NONE, C_LCON, C_REG, 42, 4, 0}, - Optab{AUNDEF, C_NONE, C_NONE, C_NONE, C_NONE, 78, 4, 0}, - Optab{AUSEFIELD, C_ADDR, C_NONE, C_NONE, C_NONE, 0, 0, 0}, - Optab{APCDATA, C_LCON, C_NONE, C_NONE, C_LCON, 0, 0, 0}, - Optab{AFUNCDATA, C_SCON, C_NONE, C_NONE, C_ADDR, 0, 0, 0}, - Optab{ANOP, C_NONE, C_NONE, C_NONE, C_NONE, 0, 0, 0}, - Optab{ADUFFZERO, C_NONE, C_NONE, C_NONE, C_LBRA, 11, 4, 0}, // same as ABR/ABL - Optab{ADUFFCOPY, C_NONE, C_NONE, C_NONE, C_LBRA, 11, 4, 0}, // same as ABR/ABL + Optab{obj.AUNDEF, C_NONE, C_NONE, C_NONE, C_NONE, 78, 4, 0}, + Optab{obj.AUSEFIELD, C_ADDR, C_NONE, C_NONE, C_NONE, 0, 0, 0}, + Optab{obj.APCDATA, C_LCON, C_NONE, C_NONE, C_LCON, 0, 0, 0}, + Optab{obj.AFUNCDATA, C_SCON, C_NONE, C_NONE, C_ADDR, 0, 0, 0}, + Optab{obj.ANOP, C_NONE, C_NONE, C_NONE, C_NONE, 0, 0, 0}, + Optab{obj.ADUFFZERO, C_NONE, C_NONE, C_NONE, C_LBRA, 11, 4, 0}, // same as ABR/ABL + Optab{obj.ADUFFCOPY, C_NONE, C_NONE, C_NONE, C_LBRA, 11, 4, 0}, // same as ABR/ABL - Optab{AXXX, C_NONE, C_NONE, C_NONE, C_NONE, 0, 4, 0}, + Optab{obj.AXXX, C_NONE, C_NONE, C_NONE, C_NONE, 0, 4, 0}, } type Oprang struct { @@ -426,7 +422,7 @@ func span9(ctxt *obj.Link, cursym *obj.LSym) { return } ctxt.Cursym = cursym - ctxt.Autosize = int32(p.To.Offset&0xffffffff) + 8 + ctxt.Autosize = int32(p.To.Offset + 8) if oprange[AANDN].start == nil { buildop(ctxt) @@ -441,7 +437,7 @@ func span9(ctxt *obj.Link, cursym *obj.LSym) { o = oplook(ctxt, p) m = int(o.size) if m == 0 { - if p.As != ANOP && p.As != AFUNCDATA && p.As != APCDATA { + if p.As != obj.ANOP && p.As != obj.AFUNCDATA && p.As != obj.APCDATA { ctxt.Diag("zero-width instruction\n%v", p) } continue @@ -472,21 +468,20 @@ func span9(ctxt *obj.Link, cursym *obj.LSym) { // very large conditional branches if (o.type_ == 16 || o.type_ == 17) && p.Pcond != nil { - otxt = p.Pcond.Pc - c if otxt < -(1<<15)+10 || otxt >= (1<<15)-10 { - q = ctxt.NewProg() + q = new(obj.Prog) q.Link = p.Link p.Link = q q.As = ABR - q.To.Type = D_BRANCH + q.To.Type = obj.TYPE_BRANCH q.Pcond = p.Pcond p.Pcond = q - q = ctxt.NewProg() + q = new(obj.Prog) q.Link = p.Link p.Link = q q.As = ABR - q.To.Type = D_BRANCH + q.To.Type = obj.TYPE_BRANCH q.Pcond = q.Link.Link //addnop(p->link); @@ -497,7 +492,7 @@ func span9(ctxt *obj.Link, cursym *obj.LSym) { m = int(o.size) if m == 0 { - if p.As != ANOP && p.As != AFUNCDATA && p.As != APCDATA { + if p.As != obj.ANOP && p.As != obj.AFUNCDATA && p.As != obj.APCDATA { ctxt.Diag("zero-width instruction\n%v", p) } continue @@ -516,7 +511,6 @@ func span9(ctxt *obj.Link, cursym *obj.LSym) { * lay out the code, emitting code and data relocations. */ if ctxt.Tlsg == nil { - ctxt.Tlsg = obj.Linklookup(ctxt, "runtime.tlsg", 0) } @@ -550,43 +544,49 @@ func aclass(ctxt *obj.Link, a *obj.Addr) int { var s *obj.LSym switch a.Type { - case D_NONE: + case obj.TYPE_NONE: return C_NONE - case D_REG: - return C_REG - - case D_FREG: - return C_FREG - - case D_CREG: - return C_CREG - - case D_SPR: - if a.Offset == D_LR { - return C_LR + case obj.TYPE_REG: + if REG_R0 <= a.Reg && a.Reg <= REG_R31 { + return C_REG } - if a.Offset == D_XER { - return C_XER + if REG_F0 <= a.Reg && a.Reg <= REG_F31 { + return C_FREG } - if a.Offset == D_CTR { - return C_CTR + if REG_C0 <= a.Reg && a.Reg <= REG_C7 || a.Reg == REG_CR { + return C_CREG } - return C_SPR + if REG_SPR0 <= a.Reg && a.Reg <= REG_SPR0+1023 { + switch a.Reg { + case REG_LR: + return C_LR - case D_DCR: - return C_SPR + case REG_XER: + return C_XER - case D_FPSCR: - return C_FPSCR + case REG_CTR: + return C_CTR + } + + return C_SPR + } - case D_MSR: - return C_MSR + if REG_DCR0 <= a.Reg && a.Reg <= REG_DCR0+1023 { + return C_SPR + } + if a.Reg == REG_FPSCR { + return C_FPSCR + } + if a.Reg == REG_MSR { + return C_MSR + } + return C_GOK - case D_OREG: + case obj.TYPE_MEM: switch a.Name { - case D_EXTERN, - D_STATIC: + case obj.NAME_EXTERN, + obj.NAME_STATIC: if a.Sym == nil { break } @@ -596,21 +596,21 @@ func aclass(ctxt *obj.Link, a *obj.Addr) int { } return C_LEXT - case D_AUTO: + case obj.NAME_AUTO: ctxt.Instoffset = int64(ctxt.Autosize) + a.Offset if ctxt.Instoffset >= -BIG && ctxt.Instoffset < BIG { return C_SAUTO } return C_LAUTO - case D_PARAM: + case obj.NAME_PARAM: ctxt.Instoffset = int64(ctxt.Autosize) + a.Offset + 8 if ctxt.Instoffset >= -BIG && ctxt.Instoffset < BIG { return C_SAUTO } return C_LAUTO - case D_NONE: + case obj.TYPE_NONE: ctxt.Instoffset = a.Offset if ctxt.Instoffset == 0 { return C_ZOREG @@ -623,18 +623,15 @@ func aclass(ctxt *obj.Link, a *obj.Addr) int { return C_GOK - case D_OPT: - ctxt.Instoffset = a.Offset & 31 - if a.Name == D_NONE { - return C_SCON - } - return C_GOK + case obj.TYPE_TEXTSIZE: + return C_TEXTSIZE - case D_CONST: + case obj.TYPE_CONST, + obj.TYPE_ADDR: switch a.Name { - case D_NONE: + case obj.TYPE_NONE: ctxt.Instoffset = a.Offset - if a.Reg != NREG { + if a.Reg != 0 { if -BIG <= ctxt.Instoffset && ctxt.Instoffset <= BIG { return C_SACON } @@ -646,8 +643,8 @@ func aclass(ctxt *obj.Link, a *obj.Addr) int { goto consize - case D_EXTERN, - D_STATIC: + case obj.NAME_EXTERN, + obj.NAME_STATIC: s = a.Sym if s == nil { break @@ -662,14 +659,14 @@ func aclass(ctxt *obj.Link, a *obj.Addr) int { /* not sure why this barfs */ return C_LCON - case D_AUTO: + case obj.NAME_AUTO: ctxt.Instoffset = int64(ctxt.Autosize) + a.Offset if ctxt.Instoffset >= -BIG && ctxt.Instoffset < BIG { return C_SACON } return C_LACON - case D_PARAM: + case obj.NAME_PARAM: ctxt.Instoffset = int64(ctxt.Autosize) + a.Offset + 8 if ctxt.Instoffset >= -BIG && ctxt.Instoffset < BIG { return C_SACON @@ -710,7 +707,7 @@ func aclass(ctxt *obj.Link, a *obj.Addr) int { } return C_DCON - case D_BRANCH: + case obj.TYPE_BRANCH: return C_SBRA } @@ -759,7 +756,7 @@ func oplook(ctxt *obj.Link, p *obj.Prog) *Optab { a4-- a2 = C_NONE - if p.Reg != NREG { + if p.Reg != 0 { a2 = C_REG } @@ -924,8 +921,7 @@ func buildop(ctxt *obj.Link) { } } } - for n = 0; optab[n].as != AXXX; n++ { - + for n = 0; optab[n].as != obj.AXXX; n++ { } sort.Sort(ocmp(optab[:n])) for i = 0; i < n; i++ { @@ -1295,14 +1291,14 @@ func buildop(ctxt *obj.Link) { ASLBMTE, AWORD, ADWORD, - ANOP, - ATEXT, - AUNDEF, - AUSEFIELD, - AFUNCDATA, - APCDATA, - ADUFFZERO, - ADUFFCOPY: + obj.ANOP, + obj.ATEXT, + obj.AUNDEF, + obj.AUSEFIELD, + obj.AFUNCDATA, + obj.APCDATA, + obj.ADUFFZERO, + obj.ADUFFCOPY: break } } @@ -1322,7 +1318,6 @@ func OP(o uint32, xo uint32) uint32 { /* the order is dest, a/s, b/imm for both arithmetic and logical operations */ func AOP_RRR(op uint32, d uint32, a uint32, b uint32) uint32 { - return op | (d&31)<<21 | (a&31)<<16 | (b&31)<<11 } @@ -1397,7 +1392,6 @@ func oclass(a *obj.Addr) int { // add R_ADDRPOWER relocation to symbol s for the two instructions o1 and o2. func addaddrreloc(ctxt *obj.Link, s *obj.LSym, o1 *uint32, o2 *uint32) { - var rel *obj.Reloc rel = obj.Addrel(ctxt.Cursym) @@ -1412,7 +1406,6 @@ func addaddrreloc(ctxt *obj.Link, s *obj.LSym, o1 *uint32, o2 *uint32) { * 32-bit masks */ func getmask(m []byte, v uint32) int { - var i int m[1] = 0 @@ -1461,7 +1454,6 @@ func maskgen(ctxt *obj.Link, p *obj.Prog, m []byte, v uint32) { * 64-bit masks (rldic etc) */ func getmask64(m []byte, v uint64) int { - var i int m[1] = 0 @@ -1534,7 +1526,6 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { //print("%P => case %d\n", p, o->type); switch o.type_ { - default: ctxt.Diag("unknown type %d", o.type_) prasm(p) @@ -1543,8 +1534,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { break case 1: /* mov r1,r2 ==> OR Rs,Rs,Ra */ - if p.To.Reg == REGZERO && p.From.Type == D_CONST { - + if p.To.Reg == REGZERO && p.From.Type == obj.TYPE_CONST { v = regoff(ctxt, &p.From) if r0iszero != 0 /*TypeKind(100016)*/ && v != 0 { //nerrors--; @@ -1560,7 +1550,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { case 2: /* int/cr/fp op Rb,[Ra],Rd */ r = int(p.Reg) - if r == NREG { + if r == 0 { r = int(p.To.Reg) } o1 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), uint32(p.To.Reg), uint32(r), uint32(p.From.Reg)) @@ -1570,7 +1560,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { v = int32(d) r = int(p.From.Reg) - if r == NREG { + if r == 0 { r = int(o.param) } if r0iszero != 0 /*TypeKind(100016)*/ && p.To.Reg == 0 && (r != 0 || v != 0) { @@ -1589,7 +1579,6 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { a = OP_ADDIS } else { - if int64(int16(d)) != d { log.Fatalf("invalid handling of %v", p) } @@ -1601,7 +1590,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { v = regoff(ctxt, &p.From) r = int(p.Reg) - if r == NREG { + if r == 0 { r = int(p.To.Reg) } if r0iszero != 0 /*TypeKind(100016)*/ && p.To.Reg == 0 { @@ -1618,7 +1607,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { case 6: /* logical op Rb,[Rs,]Ra; no literal */ r = int(p.Reg) - if r == NREG { + if r == 0 { r = int(p.To.Reg) } o1 = LOP_RRR(uint32(oprrr(ctxt, int(p.As))), uint32(p.To.Reg), uint32(r), uint32(p.From.Reg)) @@ -1626,17 +1615,16 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { case 7: /* mov r, soreg ==> stw o(r) */ r = int(p.To.Reg) - if r == NREG { + if r == 0 { r = int(o.param) } v = regoff(ctxt, &p.To) - if p.To.Type == D_OREG && p.Reg != NREG { + if p.To.Type == obj.TYPE_MEM && p.Reg != 0 { if v != 0 { ctxt.Diag("illegal indexed instruction\n%v", p) } o1 = AOP_RRR(uint32(opstorex(ctxt, int(p.As))), uint32(p.From.Reg), uint32(p.Reg), uint32(r)) } else { - if int32(int16(v)) != v { log.Fatalf("mishandled instruction %v", p) } @@ -1646,17 +1634,16 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { case 8: /* mov soreg, r ==> lbz/lhz/lwz o(r) */ r = int(p.From.Reg) - if r == NREG { + if r == 0 { r = int(o.param) } v = regoff(ctxt, &p.From) - if p.From.Type == D_OREG && p.Reg != NREG { + if p.From.Type == obj.TYPE_MEM && p.Reg != 0 { if v != 0 { ctxt.Diag("illegal indexed instruction\n%v", p) } o1 = AOP_RRR(uint32(oploadx(ctxt, int(p.As))), uint32(p.To.Reg), uint32(p.Reg), uint32(r)) } else { - if int32(int16(v)) != v { log.Fatalf("mishandled instruction %v", p) } @@ -1666,17 +1653,16 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { case 9: /* movb soreg, r ==> lbz o(r),r2; extsb r2,r2 */ r = int(p.From.Reg) - if r == NREG { + if r == 0 { r = int(o.param) } v = regoff(ctxt, &p.From) - if p.From.Type == D_OREG && p.Reg != NREG { + if p.From.Type == obj.TYPE_MEM && p.Reg != 0 { if v != 0 { ctxt.Diag("illegal indexed instruction\n%v", p) } o1 = AOP_RRR(uint32(oploadx(ctxt, int(p.As))), uint32(p.To.Reg), uint32(p.Reg), uint32(r)) } else { - o1 = AOP_IRR(uint32(opload(ctxt, int(p.As))), uint32(p.To.Reg), uint32(r), uint32(v)) } o2 = LOP_RRR(OP_EXTSB, uint32(p.To.Reg), uint32(p.To.Reg), 0) @@ -1684,7 +1670,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { case 10: /* sub Ra,[Rb],Rd => subf Rd,Ra,Rb */ r = int(p.Reg) - if r == NREG { + if r == 0 { r = int(p.To.Reg) } o1 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), uint32(p.To.Reg), uint32(p.From.Reg), uint32(r)) @@ -1721,8 +1707,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { } case 12: /* movb r,r (extsb); movw r,r (extsw) */ - if p.To.Reg == REGZERO && p.From.Type == D_CONST { - + if p.To.Reg == REGZERO && p.From.Type == obj.TYPE_CONST { v = regoff(ctxt, &p.From) if r0iszero != 0 /*TypeKind(100016)*/ && v != 0 { ctxt.Diag("literal operation on R0\n%v", p) @@ -1735,13 +1720,11 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { if p.As == AMOVW { o1 = LOP_RRR(OP_EXTSW, uint32(p.To.Reg), uint32(p.From.Reg), 0) } else { - o1 = LOP_RRR(OP_EXTSB, uint32(p.To.Reg), uint32(p.From.Reg), 0) } case 13: /* mov[bhw]z r,r; uses rlwinm not andi. to avoid changing CC */ if p.As == AMOVBZ { - o1 = OP_RLW(OP_RLWINM, uint32(p.To.Reg), uint32(p.From.Reg), 0, 24, 31) } else if p.As == AMOVH { o1 = LOP_RRR(OP_EXTSH, uint32(p.To.Reg), uint32(p.From.Reg), 0) @@ -1750,14 +1733,13 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { } else if p.As == AMOVWZ { o1 = OP_RLW(OP_RLDIC, uint32(p.To.Reg), uint32(p.From.Reg), 0, 0, 0) | 1<<5 /* MB=32 */ } else { - ctxt.Diag("internal: bad mov[bhw]z\n%v", p) } case 14: /* rldc[lr] Rb,Rs,$mask,Ra -- left, right give different masks */ r = int(p.Reg) - if r == NREG { + if r == 0 { r = int(p.To.Reg) } d = vregoff(ctxt, &p.From3) @@ -1792,11 +1774,11 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { 16: /* bc bo,bi,sbra */ a = 0 - if p.From.Type == D_CONST { + if p.From.Type == obj.TYPE_CONST { a = int(regoff(ctxt, &p.From)) } r = int(p.Reg) - if r == NREG { + if r == 0 { r = 0 } v = 0 @@ -1815,17 +1797,15 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { case 15: /* br/bl (r) => mov r,lr; br/bl (lr) */ if p.As == ABC || p.As == ABCL { - v = regoff(ctxt, &p.To) & 31 } else { - v = 20 /* unconditional */ } r = int(p.Reg) - if r == NREG { + if r == 0 { r = 0 } - o1 = AOP_RRR(OP_MTSPR, uint32(p.To.Reg), 0, 0) | (D_LR&0x1f)<<16 | ((D_LR>>5)&0x1f)<<11 + o1 = AOP_RRR(OP_MTSPR, uint32(p.To.Reg), 0, 0) | (REG_LR&0x1f)<<16 | ((REG_LR>>5)&0x1f)<<11 o2 = OPVCC(19, 16, 0, 0) if p.As == ABL || p.As == ABCL { o2 |= 1 @@ -1834,14 +1814,12 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { case 18: /* br/bl (lr/ctr); bc/bcl bo,bi,(lr/ctr) */ if p.As == ABC || p.As == ABCL { - v = regoff(ctxt, &p.From) & 31 } else { - v = 20 /* unconditional */ } r = int(p.Reg) - if r == NREG { + if r == 0 { r = 0 } switch oclass(&p.To) { @@ -1868,7 +1846,6 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { o1 = loadu32(int(p.To.Reg), d) o2 = LOP_IRR(OP_ORI, uint32(p.To.Reg), uint32(p.To.Reg), uint32(int32(d))) } else { - o1 = AOP_IRR(OP_ADDIS, REGTMP, REGZERO, uint32(high16adjusted(int32(d)))) o2 = AOP_IRR(OP_ADDI, uint32(p.To.Reg), REGTMP, uint32(d)) addaddrreloc(ctxt, p.From.Sym, &o1, &o2) @@ -1880,24 +1857,23 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { v = regoff(ctxt, &p.From) r = int(p.Reg) - if r == NREG { + if r == 0 { r = int(p.To.Reg) } if p.As == AADD && (!(r0iszero != 0 /*TypeKind(100016)*/) && p.Reg == 0 || r0iszero != 0 /*TypeKind(100016)*/ && p.To.Reg == 0) { ctxt.Diag("literal operation on R0\n%v", p) } - o1 = AOP_IRR(uint32(opirr(ctxt, int(p.As)+AEND)), uint32(p.To.Reg), uint32(r), uint32(v)>>16) + o1 = AOP_IRR(uint32(opirr(ctxt, int(p.As)+ALAST)), uint32(p.To.Reg), uint32(r), uint32(v)>>16) case 22: /* add $lcon,r1,r2 ==> cau+or+add */ /* could do add/sub more efficiently */ if p.To.Reg == REGTMP || p.Reg == REGTMP { - ctxt.Diag("cant synthesize large constant\n%v", p) } d = vregoff(ctxt, &p.From) o1 = loadu32(REGTMP, d) o2 = LOP_IRR(OP_ORI, REGTMP, REGTMP, uint32(int32(d))) r = int(p.Reg) - if r == NREG { + if r == 0 { r = int(p.To.Reg) } o3 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), uint32(p.To.Reg), REGTMP, uint32(r)) @@ -1909,14 +1885,13 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { case 23: /* and $lcon,r1,r2 ==> cau+or+and */ /* masks could be done using rlnm etc. */ if p.To.Reg == REGTMP || p.Reg == REGTMP { - ctxt.Diag("cant synthesize large constant\n%v", p) } d = vregoff(ctxt, &p.From) o1 = loadu32(REGTMP, d) o2 = LOP_IRR(OP_ORI, REGTMP, REGTMP, uint32(int32(d))) r = int(p.Reg) - if r == NREG { + if r == 0 { r = int(p.To.Reg) } o3 = LOP_RRR(uint32(oprrr(ctxt, int(p.As))), uint32(p.To.Reg), REGTMP, uint32(r)) @@ -1937,7 +1912,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { v = 63 } r = int(p.Reg) - if r == NREG { + if r == 0 { r = int(p.To.Reg) } switch p.As { @@ -1972,12 +1947,11 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { case 26: /* mov $lsext/auto/oreg,,r2 ==> addis+addi */ if p.To.Reg == REGTMP { - ctxt.Diag("can't synthesize large constant\n%v", p) } v = regoff(ctxt, &p.From) r = int(p.From.Reg) - if r == NREG { + if r == 0 { r = int(o.param) } o1 = AOP_IRR(OP_ADDIS, REGTMP, uint32(r), uint32(high16adjusted(v))) @@ -1991,7 +1965,6 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { case 28: /* subc r1,$lcon,r2 ==> cau+or+subfc */ if p.To.Reg == REGTMP || p.From.Reg == REGTMP { - ctxt.Diag("can't synthesize large constant\n%v", p) } v = regoff(ctxt, &p.From3) @@ -2069,7 +2042,6 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { o1 = uint32(d >> 32) o2 = uint32(d) } else { - o1 = uint32(d) o2 = uint32(d >> 32) } @@ -2088,7 +2060,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { case 32: /* fmul frc,fra,frd */ r = int(p.Reg) - if r == NREG { + if r == 0 { r = int(p.To.Reg) } o1 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), uint32(p.To.Reg), uint32(r), 0) | (uint32(p.From.Reg)&31)<<6 @@ -2108,7 +2080,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { v = regoff(ctxt, &p.To) r = int(p.To.Reg) - if r == NREG { + if r == 0 { r = int(o.param) } o1 = AOP_IRR(OP_ADDIS, REGTMP, uint32(r), uint32(high16adjusted(v))) @@ -2118,7 +2090,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { v = regoff(ctxt, &p.From) r = int(p.From.Reg) - if r == NREG { + if r == 0 { r = int(o.param) } o1 = AOP_IRR(OP_ADDIS, REGTMP, uint32(r), uint32(high16adjusted(v))) @@ -2128,7 +2100,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { v = regoff(ctxt, &p.From) r = int(p.From.Reg) - if r == NREG { + if r == 0 { r = int(o.param) } o1 = AOP_IRR(OP_ADDIS, REGTMP, uint32(r), uint32(high16adjusted(v))) @@ -2147,7 +2119,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { case 43: /* unary indexed source: dcbf (b); dcbf (a+b) */ r = int(p.Reg) - if r == NREG { + if r == 0 { r = 0 } o1 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), 0, uint32(r), uint32(p.From.Reg)) @@ -2155,7 +2127,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { case 44: /* indexed store */ r = int(p.Reg) - if r == NREG { + if r == 0 { r = 0 } o1 = AOP_RRR(uint32(opstorex(ctxt, int(p.As))), uint32(p.From.Reg), uint32(r), uint32(p.To.Reg)) @@ -2163,7 +2135,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { case 45: /* indexed load */ r = int(p.Reg) - if r == NREG { + if r == 0 { r = 0 } o1 = AOP_RRR(uint32(oploadx(ctxt, int(p.As))), uint32(p.To.Reg), uint32(r), uint32(p.From.Reg)) @@ -2174,7 +2146,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { case 47: /* op Ra, Rd; also op [Ra,] Rd */ r = int(p.From.Reg) - if r == NREG { + if r == 0 { r = int(p.To.Reg) } o1 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), uint32(p.To.Reg), uint32(r), 0) @@ -2182,24 +2154,23 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { case 48: /* op Rs, Ra */ r = int(p.From.Reg) - if r == NREG { + if r == 0 { r = int(p.To.Reg) } o1 = LOP_RRR(uint32(oprrr(ctxt, int(p.As))), uint32(p.To.Reg), uint32(r), 0) case 49: /* op Rb; op $n, Rb */ - if p.From.Type != D_REG { /* tlbie $L, rB */ + if p.From.Type != obj.TYPE_REG { /* tlbie $L, rB */ v = regoff(ctxt, &p.From) & 1 o1 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), 0, 0, uint32(p.To.Reg)) | uint32(v)<<21 } else { - o1 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), 0, 0, uint32(p.From.Reg)) } case 50: /* rem[u] r1[,r2],r3 */ r = int(p.Reg) - if r == NREG { + if r == 0 { r = int(p.To.Reg) } v = oprrr(ctxt, int(p.As)) @@ -2217,7 +2188,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { case 51: /* remd[u] r1[,r2],r3 */ r = int(p.Reg) - if r == NREG { + if r == 0 { r = int(p.To.Reg) } v = oprrr(ctxt, int(p.As)) @@ -2236,15 +2207,12 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { case 54: /* mov msr,r1; mov r1, msr*/ if oclass(&p.From) == C_REG { - if p.As == AMOVD { o1 = AOP_RRR(OP_MTMSRD, uint32(p.From.Reg), 0, 0) } else { - o1 = AOP_RRR(OP_MTMSR, uint32(p.From.Reg), 0, 0) } } else { - o1 = AOP_RRR(OP_MFMSR, uint32(p.To.Reg), 0, 0) } @@ -2255,7 +2223,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { v = regoff(ctxt, &p.From) r = int(p.Reg) - if r == NREG { + if r == 0 { r = int(p.To.Reg) } o1 = AOP_RRR(uint32(opirr(ctxt, int(p.As))), uint32(r), uint32(p.To.Reg), uint32(v)&31) @@ -2267,7 +2235,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { v = regoff(ctxt, &p.From) r = int(p.Reg) - if r == NREG { + if r == 0 { r = int(p.To.Reg) } @@ -2279,7 +2247,6 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { ctxt->diag("illegal shift %ld\n%P", v, p); */ if v < 0 { - v = 0 } else if v > 32 { v = 32 @@ -2289,7 +2256,6 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { mask[1] = 31 v = 32 - v } else { - mask[0] = 0 mask[1] = uint8(31 - v) } @@ -2303,7 +2269,7 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { v = regoff(ctxt, &p.From) r = int(p.Reg) - if r == NREG { + if r == 0 { r = int(p.To.Reg) } o1 = LOP_IRR(uint32(opirr(ctxt, int(p.As))), uint32(p.To.Reg), uint32(r), uint32(v)) @@ -2312,10 +2278,10 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { v = regoff(ctxt, &p.From) r = int(p.Reg) - if r == NREG { + if r == 0 { r = int(p.To.Reg) } - o1 = LOP_IRR(uint32(opirr(ctxt, int(p.As)+AEND)), uint32(p.To.Reg), uint32(r), uint32(v)>>16) /* oris, xoris, andis */ + o1 = LOP_IRR(uint32(opirr(ctxt, int(p.As)+ALAST)), uint32(p.To.Reg), uint32(r), uint32(v)>>16) /* oris, xoris, andis */ case 60: /* tw to,a,b */ r = int(regoff(ctxt, &p.From) & 31) @@ -2342,41 +2308,34 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { o1 |= (uint32(mask[0])&31)<<6 | (uint32(mask[1])&31)<<1 case 64: /* mtfsf fr[, $m] {,fpcsr} */ - if p.From3.Type != D_NONE { - + if p.From3.Type != obj.TYPE_NONE { v = regoff(ctxt, &p.From3) & 255 } else { - v = 255 } o1 = OP_MTFSF | uint32(v)<<17 | uint32(p.From.Reg)<<11 case 65: /* MOVFL $imm,FPSCR(n) => mtfsfi crfd,imm */ - if p.To.Reg == NREG { - + if p.To.Reg == 0 { ctxt.Diag("must specify FPSCR(n)\n%v", p) } o1 = OP_MTFSFI | (uint32(p.To.Reg)&15)<<23 | (uint32(regoff(ctxt, &p.From))&31)<<12 case 66: /* mov spr,r1; mov r1,spr, also dcr */ - if p.From.Type == D_REG { - + if REG_R0 <= p.From.Reg && p.From.Reg <= REG_R31 { r = int(p.From.Reg) - v = int32(p.To.Offset) - if p.To.Type == D_DCR { + v = int32(p.To.Reg) + if REG_DCR0 <= v && v <= REG_DCR0+1023 { o1 = OPVCC(31, 451, 0, 0) /* mtdcr */ } else { - o1 = OPVCC(31, 467, 0, 0) /* mtspr */ } } else { - r = int(p.To.Reg) - v = int32(p.From.Offset) - if p.From.Type == D_DCR { + v = int32(p.From.Reg) + if REG_DCR0 <= v && v <= REG_DCR0+1023 { o1 = OPVCC(31, 323, 0, 0) /* mfdcr */ } else { - o1 = OPVCC(31, 339, 0, 0) /* mfspr */ } } @@ -2384,35 +2343,29 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { o1 = AOP_RRR(o1, uint32(r), 0, 0) | (uint32(v)&0x1f)<<16 | ((uint32(v)>>5)&0x1f)<<11 case 67: /* mcrf crfD,crfS */ - if p.From.Type != D_CREG || p.From.Reg == NREG || p.To.Type != D_CREG || p.To.Reg == NREG { - + if p.From.Type != obj.TYPE_REG || p.From.Reg < REG_C0 || REG_C7 < p.From.Reg || p.To.Type != obj.TYPE_REG || p.To.Reg < REG_C0 || REG_C7 < p.To.Reg { ctxt.Diag("illegal CR field number\n%v", p) } o1 = AOP_RRR(OP_MCRF, ((uint32(p.To.Reg) & 7) << 2), ((uint32(p.From.Reg) & 7) << 2), 0) case 68: /* mfcr rD; mfocrf CRM,rD */ - if p.From.Type == D_CREG && p.From.Reg != NREG { - + if p.From.Type == obj.TYPE_REG && REG_C0 <= p.From.Reg && p.From.Reg <= REG_C7 { v = 1 << uint(7-(p.To.Reg&7)) /* CR(n) */ o1 = AOP_RRR(OP_MFCR, uint32(p.To.Reg), 0, 0) | 1<<20 | uint32(v)<<12 /* new form, mfocrf */ } else { - o1 = AOP_RRR(OP_MFCR, uint32(p.To.Reg), 0, 0) /* old form, whole register */ } case 69: /* mtcrf CRM,rS */ - if p.From3.Type != D_NONE { - - if p.To.Reg != NREG { + if p.From3.Type != obj.TYPE_NONE { + if p.To.Reg != 0 { ctxt.Diag("can't use both mask and CR(n)\n%v", p) } v = regoff(ctxt, &p.From3) & 0xff } else { - - if p.To.Reg == NREG { + if p.To.Reg == 0 { v = 0xff /* CR */ } else { - v = 1 << uint(7-(p.To.Reg&7)) /* CR(n) */ } } @@ -2420,21 +2373,17 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { o1 = AOP_RRR(OP_MTCRF, uint32(p.From.Reg), 0, 0) | uint32(v)<<12 case 70: /* [f]cmp r,r,cr*/ - if p.Reg == NREG { - + if p.Reg == 0 { r = 0 } else { - r = (int(p.Reg) & 7) << 2 } o1 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), uint32(r), uint32(p.From.Reg), uint32(p.To.Reg)) case 71: /* cmp[l] r,i,cr*/ - if p.Reg == NREG { - + if p.Reg == 0 { r = 0 } else { - r = (int(p.Reg) & 7) << 2 } o1 = AOP_RRR(uint32(opirr(ctxt, int(p.As))), uint32(r), uint32(p.From.Reg), 0) | uint32(regoff(ctxt, &p.To))&0xffff @@ -2443,23 +2392,20 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { o1 = AOP_RRR(uint32(oprrr(ctxt, int(p.As))), uint32(p.From.Reg), 0, uint32(p.To.Reg)) case 73: /* mcrfs crfD,crfS */ - if p.From.Type != D_FPSCR || p.From.Reg == NREG || p.To.Type != D_CREG || p.To.Reg == NREG { - + if p.From.Type != obj.TYPE_REG || p.From.Reg != REG_FPSCR || p.To.Type != obj.TYPE_REG || p.To.Reg < REG_C0 || REG_C7 < p.To.Reg { ctxt.Diag("illegal FPSCR/CR field number\n%v", p) } - o1 = AOP_RRR(OP_MCRFS, ((uint32(p.To.Reg) & 7) << 2), ((uint32(p.From.Reg) & 7) << 2), 0) + o1 = AOP_RRR(OP_MCRFS, ((uint32(p.To.Reg) & 7) << 2), ((0 & 7) << 2), 0) case 77: /* syscall $scon, syscall Rx */ - if p.From.Type == D_CONST { - + if p.From.Type == obj.TYPE_CONST { if p.From.Offset > BIG || p.From.Offset < -BIG { ctxt.Diag("illegal syscall, sysnum too large: %v", p) } o1 = AOP_IRR(OP_ADDI, REGZERO, REGZERO, uint32(p.From.Offset)) - } else if p.From.Type == D_REG { + } else if p.From.Type == obj.TYPE_REG { o1 = LOP_RRR(OP_OR, REGZERO, uint32(p.From.Reg), uint32(p.From.Reg)) } else { - ctxt.Diag("illegal syscall: %v", p) o1 = 0x7fe00008 // trap always } @@ -3046,21 +2992,21 @@ func opirr(ctxt *obj.Link, a int) int32 { return int32(OPVCC(12, 0, 0, 0)) case AADDCCC: return int32(OPVCC(13, 0, 0, 0)) - case AADD + AEND: + case AADD + ALAST: return int32(OPVCC(15, 0, 0, 0)) /* ADDIS/CAU */ case AANDCC: return int32(OPVCC(28, 0, 0, 0)) - case AANDCC + AEND: + case AANDCC + ALAST: return int32(OPVCC(29, 0, 0, 0)) /* ANDIS./ANDIU. */ case ABR: return int32(OPVCC(18, 0, 0, 0)) case ABL: return int32(OPVCC(18, 0, 0, 0) | 1) - case ADUFFZERO: + case obj.ADUFFZERO: return int32(OPVCC(18, 0, 0, 0) | 1) - case ADUFFCOPY: + case obj.ADUFFCOPY: return int32(OPVCC(18, 0, 0, 0) | 1) case ABC: return int32(OPVCC(16, 0, 0, 0)) @@ -3100,7 +3046,7 @@ func opirr(ctxt *obj.Link, a int) int32 { case AOR: return int32(OPVCC(24, 0, 0, 0)) - case AOR + AEND: + case AOR + ALAST: return int32(OPVCC(25, 0, 0, 0)) /* ORIS/ORIU */ case ARLWMI: @@ -3152,7 +3098,7 @@ func opirr(ctxt *obj.Link, a int) int32 { case AXOR: return int32(OPVCC(26, 0, 0, 0)) /* XORIL */ - case AXOR + AEND: + case AXOR + ALAST: return int32(OPVCC(27, 0, 0, 0)) /* XORIU */ } @@ -3164,7 +3110,6 @@ func opirr(ctxt *obj.Link, a int) int32 { * load o(a),d */ func opload(ctxt *obj.Link, a int) int32 { - switch a { case AMOVD: return int32(OPVCC(58, 0, 0, 0)) /* ld */ @@ -3214,7 +3159,6 @@ func opload(ctxt *obj.Link, a int) int32 { * indexed load a(b),d */ func oploadx(ctxt *obj.Link, a int) int32 { - switch a { case AMOVWZ: return int32(OPVCC(31, 23, 0, 0)) /* lwzx */ @@ -3274,7 +3218,6 @@ func oploadx(ctxt *obj.Link, a int) int32 { * store s,o(d) */ func opstore(ctxt *obj.Link, a int) int32 { - switch a { case AMOVB, AMOVBZ: @@ -3325,7 +3268,6 @@ func opstore(ctxt *obj.Link, a int) int32 { * indexed store s,a(b) */ func opstorex(ctxt *obj.Link, a int) int32 { - switch a { case AMOVB, AMOVBZ: diff --git a/src/cmd/internal/obj/ppc64/list9.go b/src/cmd/internal/obj/ppc64/list9.go index 1722231a58..c7d892b345 100644 --- a/src/cmd/internal/obj/ppc64/list9.go +++ b/src/cmd/internal/obj/ppc64/list9.go @@ -43,7 +43,6 @@ const ( // %A int Opcodes (instruction mnemonics) // // %D Addr* Addresses (instruction operands) -// Flags: "%lD": seperate the high and low words of a constant by "-" // // %P Prog* Instructions // @@ -59,49 +58,34 @@ func Pconv(p *obj.Prog) string { var fp string var a int - var ch int a = int(p.As) - if a == ADATA || a == AINIT || a == ADYNT { - str = fmt.Sprintf("%.5d (%v)\t%v\t%v/%d,%v", p.Pc, p.Line(), Aconv(a), Dconv(p, 0, &p.From), p.Reg, Dconv(p, 0, &p.To)) - } else if a == ATEXT { - if p.Reg != 0 { - str = fmt.Sprintf("%.5d (%v) %v %v,%d,%v", p.Pc, p.Line(), Aconv(a), Dconv(p, 0, &p.From), p.Reg, Dconv(p, fmtLong, &p.To)) + str = "" + if a == obj.ADATA { + str = fmt.Sprintf("%.5d (%v)\t%v\t%v/%d,%v", p.Pc, p.Line(), Aconv(a), Dconv(p, 0, &p.From), p.From3.Offset, Dconv(p, 0, &p.To)) + } else if a == obj.ATEXT || a == obj.AGLOBL { + if p.From3.Offset != 0 { + str = fmt.Sprintf("%.5d (%v)\t%v\t%v,%d,%v", p.Pc, p.Line(), Aconv(a), Dconv(p, 0, &p.From), p.From3.Offset, Dconv(p, 0, &p.To)) } else { - - str = fmt.Sprintf("%.5d (%v) %v %v,%v", p.Pc, p.Line(), Aconv(a), Dconv(p, 0, &p.From), Dconv(p, fmtLong, &p.To)) - } - } else if a == AGLOBL { - if p.Reg != 0 { - str = fmt.Sprintf("%.5d (%v) %v %v,%d,%v", p.Pc, p.Line(), Aconv(a), Dconv(p, 0, &p.From), p.Reg, Dconv(p, 0, &p.To)) - } else { - - str = fmt.Sprintf("%.5d (%v) %v %v,%v", p.Pc, p.Line(), Aconv(a), Dconv(p, 0, &p.From), Dconv(p, 0, &p.To)) + str = fmt.Sprintf("%.5d (%v)\t%v\t%v,%v", p.Pc, p.Line(), Aconv(a), Dconv(p, 0, &p.From), Dconv(p, 0, &p.To)) } } else { - if p.Mark&NOSCHED != 0 { str += fmt.Sprintf("*") } - if p.Reg == NREG && p.From3.Type == D_NONE { + if p.Reg == 0 && p.From3.Type == obj.TYPE_NONE { str += fmt.Sprintf("%.5d (%v)\t%v\t%v,%v", p.Pc, p.Line(), Aconv(a), Dconv(p, 0, &p.From), Dconv(p, 0, &p.To)) - } else if a != ATEXT && p.From.Type == D_OREG { - str += fmt.Sprintf("%.5d (%v)\t%v\t%d(R%d+R%d),%v", p.Pc, p.Line(), Aconv(a), p.From.Offset, p.From.Reg, p.Reg, Dconv(p, 0, &p.To)) - } else if p.To.Type == D_OREG { - str += fmt.Sprintf("%.5d (%v)\t%v\t%v,%d(R%d+R%d)", p.Pc, p.Line(), Aconv(a), Dconv(p, 0, &p.From), p.To.Offset, p.To.Reg, p.Reg) + } else if a != obj.ATEXT && p.From.Type == obj.TYPE_MEM { + str += fmt.Sprintf("%.5d (%v)\t%v\t%d(%v+%v),%v", p.Pc, p.Line(), Aconv(a), p.From.Offset, Rconv(int(p.From.Reg)), Rconv(int(p.Reg)), Dconv(p, 0, &p.To)) + } else if p.To.Type == obj.TYPE_MEM { + str += fmt.Sprintf("%.5d (%v)\t%v\t%v,%d(%v+%v)", p.Pc, p.Line(), Aconv(a), Dconv(p, 0, &p.From), p.To.Offset, Rconv(int(p.To.Reg)), Rconv(int(p.Reg))) } else { - str += fmt.Sprintf("%.5d (%v)\t%v\t%v", p.Pc, p.Line(), Aconv(a), Dconv(p, 0, &p.From)) - if p.Reg != NREG { - ch = 'R' - if p.From.Type == D_FREG { - ch = 'F' - } - str += fmt.Sprintf(",%c%d", ch, p.Reg) + if p.Reg != 0 { + str += fmt.Sprintf(",%v", Rconv(int(p.Reg))) } - - if p.From3.Type != D_NONE { + if p.From3.Type != obj.TYPE_NONE { str += fmt.Sprintf(",%v", Dconv(p, 0, &p.From3)) } str += fmt.Sprintf(",%v", Dconv(p, 0, &p.To)) @@ -122,7 +106,7 @@ func Aconv(a int) string { var fp string s = "???" - if a >= AXXX && a < ALAST { + if a >= obj.AXXX && a < ALAST { s = Anames[a] } fp += s @@ -135,126 +119,53 @@ func Dconv(p *obj.Prog, flag int, a *obj.Addr) string { var v int32 - if flag&fmtLong != 0 /*untyped*/ { - if a.Type == D_CONST { - str = fmt.Sprintf("$%d-%d", int32(a.Offset), int32(a.Offset>>32)) - } else { - - // ATEXT dst is not constant - str = fmt.Sprintf("!!%v", Dconv(p, 0, a)) - } - - goto ret - } - switch a.Type { default: str = fmt.Sprintf("GOK-type(%d)", a.Type) - case D_NONE: + case obj.TYPE_NONE: str = "" - if a.Name != D_NONE || a.Reg != NREG || a.Sym != nil { - str = fmt.Sprintf("%v(R%d)(NONE)", Mconv(a), a.Reg) + if a.Name != obj.TYPE_NONE || a.Reg != 0 || a.Sym != nil { + str = fmt.Sprintf("%v(%v)(NONE)", Mconv(a), Rconv(int(a.Reg))) } - case D_CONST, - D_DCONST: - if a.Reg != NREG { - str = fmt.Sprintf("$%v(R%d)", Mconv(a), a.Reg) + case obj.TYPE_CONST, + obj.TYPE_ADDR: + if a.Reg != 0 { + str = fmt.Sprintf("$%v(%v)", Mconv(a), Rconv(int(a.Reg))) } else { - str = fmt.Sprintf("$%v", Mconv(a)) } - case D_OREG: - if a.Reg != NREG { - str = fmt.Sprintf("%v(R%d)", Mconv(a), a.Reg) + case obj.TYPE_TEXTSIZE: + if a.U.Argsize == obj.ArgsSizeUnknown { + str = fmt.Sprintf("$%d", a.Offset) } else { - - str = fmt.Sprintf("%v", Mconv(a)) + str = fmt.Sprintf("$%d-%d", a.Offset, a.U.Argsize) } - case D_REG: - str = fmt.Sprintf("R%d", a.Reg) - if a.Name != D_NONE || a.Sym != nil { - str = fmt.Sprintf("%v(R%d)(REG)", Mconv(a), a.Reg) - } - - case D_FREG: - str = fmt.Sprintf("F%d", a.Reg) - if a.Name != D_NONE || a.Sym != nil { - str = fmt.Sprintf("%v(F%d)(REG)", Mconv(a), a.Reg) - } - - case D_CREG: - if a.Reg == NREG { - str = "CR" + case obj.TYPE_MEM: + if a.Reg != 0 { + str = fmt.Sprintf("%v(%v)", Mconv(a), Rconv(int(a.Reg))) } else { - - str = fmt.Sprintf("CR%d", a.Reg) - } - if a.Name != D_NONE || a.Sym != nil { - str = fmt.Sprintf("%v(C%d)(REG)", Mconv(a), a.Reg) - } - - case D_SPR: - if a.Name == D_NONE && a.Sym == nil { - switch uint32(a.Offset) { - case D_XER: - str = fmt.Sprintf("XER") - case D_LR: - str = fmt.Sprintf("LR") - case D_CTR: - str = fmt.Sprintf("CTR") - default: - str = fmt.Sprintf("SPR(%d)", a.Offset) - break - } - - break - } - - str = fmt.Sprintf("SPR-GOK(%d)", a.Reg) - if a.Name != D_NONE || a.Sym != nil { - str = fmt.Sprintf("%v(SPR-GOK%d)(REG)", Mconv(a), a.Reg) - } - - case D_DCR: - if a.Name == D_NONE && a.Sym == nil { - str = fmt.Sprintf("DCR(%d)", a.Offset) - break - } - - str = fmt.Sprintf("DCR-GOK(%d)", a.Reg) - if a.Name != D_NONE || a.Sym != nil { - str = fmt.Sprintf("%v(DCR-GOK%d)(REG)", Mconv(a), a.Reg) + str = fmt.Sprintf("%v", Mconv(a)) } - case D_OPT: - str = fmt.Sprintf("OPT(%d)", a.Reg) - - case D_FPSCR: - if a.Reg == NREG { - str = "FPSCR" - } else { - - str = fmt.Sprintf("FPSCR(%d)", a.Reg) + case obj.TYPE_REG: + str = fmt.Sprintf("%v", Rconv(int(a.Reg))) + if a.Name != obj.TYPE_NONE || a.Sym != nil { + str = fmt.Sprintf("%v(%v)(REG)", Mconv(a), Rconv(int(a.Reg))) } - case D_MSR: - str = fmt.Sprintf("MSR") - - case D_BRANCH: + case obj.TYPE_BRANCH: if p.Pcond != nil { v = int32(p.Pcond.Pc) //if(v >= INITTEXT) // v -= INITTEXT-HEADR; if a.Sym != nil { - str = fmt.Sprintf("%s+%.5x(BRANCH)", a.Sym.Name, uint32(v)) } else { - str = fmt.Sprintf("%.5x(BRANCH)", uint32(v)) } } else if a.U.Branch != nil { @@ -262,20 +173,18 @@ func Dconv(p *obj.Prog, flag int, a *obj.Addr) string { } else if a.Sym != nil { str = fmt.Sprintf("%s+%d(APC)", a.Sym.Name, a.Offset) } else { - str = fmt.Sprintf("%d(APC)", a.Offset) } //sprint(str, "$%lux-%lux", a->ieee.h, a->ieee.l); - case D_FCONST: + case obj.TYPE_FCONST: str = fmt.Sprintf("$%.17g", a.U.Dval) - case D_SCONST: + case obj.TYPE_SCONST: str = fmt.Sprintf("$\"%q\"", a.U.Sval) break } -ret: fp += str return fp } @@ -298,43 +207,38 @@ func Mconv(a *obj.Addr) string { // goto out; //} switch a.Name { - default: str = fmt.Sprintf("GOK-name(%d)", a.Name) - case D_NONE: + case obj.TYPE_NONE: l = int32(a.Offset) if int64(l) != a.Offset { str = fmt.Sprintf("0x%x", uint64(a.Offset)) } else { - str = fmt.Sprintf("%d", a.Offset) } - case D_EXTERN: + case obj.NAME_EXTERN: if a.Offset != 0 { str = fmt.Sprintf("%s+%d(SB)", s.Name, a.Offset) } else { - str = fmt.Sprintf("%s(SB)", s.Name) } - case D_STATIC: + case obj.NAME_STATIC: str = fmt.Sprintf("%s<>+%d(SB)", s.Name, a.Offset) - case D_AUTO: + case obj.NAME_AUTO: if s == nil { str = fmt.Sprintf("%d(SP)", -a.Offset) } else { - str = fmt.Sprintf("%s-%d(SP)", s.Name, -a.Offset) } - case D_PARAM: + case obj.NAME_PARAM: if s == nil { str = fmt.Sprintf("%d(FP)", a.Offset) } else { - str = fmt.Sprintf("%s+%d(FP)", s.Name, a.Offset) } break @@ -346,16 +250,61 @@ func Mconv(a *obj.Addr) string { } func Rconv(r int) string { - var str string var fp string - if r < NREG { - str = fmt.Sprintf("r%d", r) - } else { + if r == 0 { + fp += "NONE" + return fp + } + if REG_R0 <= r && r <= REG_R31 { + fp += fmt.Sprintf("R%d", r-REG_R0) + return fp + } + if REG_F0 <= r && r <= REG_F31 { + fp += fmt.Sprintf("F%d", r-REG_F0) + return fp + } + if REG_C0 <= r && r <= REG_C7 { + fp += fmt.Sprintf("C%d", r-REG_C0) + return fp + } + if r == REG_CR { + fp += "CR" + return fp + } + if REG_SPR0 <= r && r <= REG_SPR0+1023 { + switch r { + case REG_XER: + fp += "XER" + return fp + + case REG_LR: + fp += "LR" + return fp + + case REG_CTR: + fp += "CTR" + return fp + } - str = fmt.Sprintf("f%d", r-NREG) + fp += fmt.Sprintf("SPR(%d)", r-REG_SPR0) + return fp } - fp += str + + if REG_DCR0 <= r && r <= REG_DCR0+1023 { + fp += fmt.Sprintf("DCR(%d)", r-REG_DCR0) + return fp + } + if r == REG_FPSCR { + fp += "FPSCR" + return fp + } + if r == REG_MSR { + fp += "MSR" + return fp + } + + fp += fmt.Sprintf("badreg(%d)", r) return fp } diff --git a/src/cmd/internal/obj/ppc64/obj9.go b/src/cmd/internal/obj/ppc64/obj9.go index 3a25a125c2..2040089705 100644 --- a/src/cmd/internal/obj/ppc64/obj9.go +++ b/src/cmd/internal/obj/ppc64/obj9.go @@ -36,50 +36,6 @@ import ( "math" ) -var zprg = obj.Prog{ - As: AGOK, - Reg: NREG, - From: obj.Addr{ - Name: D_NONE, - Type: D_NONE, - Reg: NREG, - }, - From3: obj.Addr{ - Name: D_NONE, - Type: D_NONE, - Reg: NREG, - }, - To: obj.Addr{ - Name: D_NONE, - Type: D_NONE, - Reg: NREG, - }, -} - -func symtype(a *obj.Addr) int { - return int(a.Name) -} - -func isdata(p *obj.Prog) bool { - return p.As == ADATA || p.As == AGLOBL -} - -func iscall(p *obj.Prog) bool { - return p.As == ABL -} - -func datasize(p *obj.Prog) int { - return int(p.Reg) -} - -func textflag(p *obj.Prog) int { - return int(p.Reg) -} - -func settextflag(p *obj.Prog, f int) { - p.Reg = uint8(f) -} - func progedit(ctxt *obj.Link, p *obj.Prog) { var literal string var s *obj.LSym @@ -87,25 +43,23 @@ func progedit(ctxt *obj.Link, p *obj.Prog) { p.From.Class = 0 p.To.Class = 0 - // Rewrite BR/BL to symbol as D_BRANCH. + // Rewrite BR/BL to symbol as TYPE_BRANCH. switch p.As { - case ABR, ABL, ARETURN, - ADUFFZERO, - ADUFFCOPY: + obj.ADUFFZERO, + obj.ADUFFCOPY: if p.To.Sym != nil { - p.To.Type = D_BRANCH + p.To.Type = obj.TYPE_BRANCH } break } // Rewrite float constants to values stored in memory. switch p.As { - case AFMOVS: - if p.From.Type == D_FCONST { + if p.From.Type == obj.TYPE_FCONST { var i32 uint32 var f32 float32 f32 = float32(p.From.U.Dval) @@ -113,56 +67,54 @@ func progedit(ctxt *obj.Link, p *obj.Prog) { literal = fmt.Sprintf("$f32.%08x", i32) s = obj.Linklookup(ctxt, literal, 0) s.Size = 4 - p.From.Type = D_OREG + p.From.Type = obj.TYPE_MEM p.From.Sym = s - p.From.Name = D_EXTERN + p.From.Name = obj.NAME_EXTERN p.From.Offset = 0 } case AFMOVD: - if p.From.Type == D_FCONST { + if p.From.Type == obj.TYPE_FCONST { var i64 uint64 i64 = math.Float64bits(p.From.U.Dval) literal = fmt.Sprintf("$f64.%016x", i64) s = obj.Linklookup(ctxt, literal, 0) s.Size = 8 - p.From.Type = D_OREG + p.From.Type = obj.TYPE_MEM p.From.Sym = s - p.From.Name = D_EXTERN + p.From.Name = obj.NAME_EXTERN p.From.Offset = 0 } // Put >32-bit constants in memory and load them case AMOVD: - if p.From.Type == D_CONST && p.From.Name == D_NONE && p.From.Reg == NREG && int64(int32(p.From.Offset)) != p.From.Offset { - + if p.From.Type == obj.TYPE_CONST && p.From.Name == obj.NAME_NONE && p.From.Reg == 0 && int64(int32(p.From.Offset)) != p.From.Offset { literal = fmt.Sprintf("$i64.%016x", uint64(p.From.Offset)) s = obj.Linklookup(ctxt, literal, 0) s.Size = 8 - p.From.Type = D_OREG + p.From.Type = obj.TYPE_MEM p.From.Sym = s - p.From.Name = D_EXTERN + p.From.Name = obj.NAME_EXTERN p.From.Offset = 0 } } // Rewrite SUB constants into ADD. switch p.As { - case ASUBC: - if p.From.Type == D_CONST { + if p.From.Type == obj.TYPE_CONST { p.From.Offset = -p.From.Offset p.As = AADDC } case ASUBCCC: - if p.From.Type == D_CONST { + if p.From.Type == obj.TYPE_CONST { p.From.Offset = -p.From.Offset p.As = AADDCCC } case ASUB: - if p.From.Type == D_CONST { + if p.From.Type == obj.TYPE_CONST { p.From.Offset = -p.From.Offset p.As = AADD } @@ -171,20 +123,7 @@ func progedit(ctxt *obj.Link, p *obj.Prog) { } } -func parsetextconst(arg int64, textstksiz *int64, textarg *int64) { - *textstksiz = arg & 0xffffffff - if *textstksiz&0x80000000 != 0 { - *textstksiz = -(-*textstksiz & 0xffffffff) - } - - *textarg = (arg >> 32) & 0xffffffff - if *textarg&0x80000000 != 0 { - *textarg = 0 - } - *textarg = (*textarg + 7) &^ 7 -} - -func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) { +func preprocess(ctxt *obj.Link, cursym *obj.LSym) { var p *obj.Prog var q *obj.Prog var p1 *obj.Prog @@ -194,7 +133,6 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) { var mov int var aoffset int var textstksiz int64 - var textarg int64 var autosize int32 if ctxt.Symmorestack[0] == nil { @@ -210,9 +148,9 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) { } p = cursym.Text - parsetextconst(p.To.Offset, &textstksiz, &textarg) + textstksiz = p.To.Offset - cursym.Args = int32(p.To.Offset >> 32) + cursym.Args = p.To.U.Argsize cursym.Locals = int32(textstksiz) /* @@ -222,7 +160,6 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) { * expand BECOME pseudo */ if ctxt.Debugvlog != 0 { - fmt.Fprintf(ctxt.Bso, "%5.2f noops\n", obj.Cputime()) } obj.Bflush(ctxt.Bso) @@ -231,7 +168,7 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) { for p = cursym.Text; p != nil; p = p.Link { switch p.As { /* too hard, just leave alone */ - case ATEXT: + case obj.ATEXT: q = p p.Mark |= LABEL | LEAF | SYNC @@ -241,7 +178,7 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) { case ANOR: q = p - if p.To.Type == D_REG { + if p.To.Type == obj.TYPE_REG { if p.To.Reg == REGZERO { p.Mark |= LABEL | SYNC } @@ -284,24 +221,9 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) { AMOVWZ, AMOVD: q = p - switch p.From.Type { - case D_MSR, - D_SPR, - D_FPSCR, - D_CREG, - D_DCR: - p.Mark |= LABEL | SYNC - } - - switch p.To.Type { - case D_MSR, - D_SPR, - D_FPSCR, - D_CREG, - D_DCR: + if p.From.Reg >= REG_SPECIAL || p.To.Reg >= REG_SPECIAL { p.Mark |= LABEL | SYNC } - continue case AFABS, @@ -346,8 +268,8 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) { case ABL, ABCL, - ADUFFZERO, - ADUFFCOPY: + obj.ADUFFZERO, + obj.ADUFFCOPY: cursym.Text.Mark &^= LEAF fallthrough @@ -365,7 +287,7 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) { q = p q1 = p.Pcond if q1 != nil { - for q1.As == ANOP { + for q1.As == obj.ANOP { q1 = q1.Link p.Pcond = q1 } @@ -374,7 +296,6 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) { q1.Mark |= LABEL } } else { - p.Mark |= LABEL } q1 = p.Link @@ -396,7 +317,7 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) { } continue - case ANOP: + case obj.ANOP: q1 = p.Link q.Link = q1 /* q is non-nop */ q1.Mark |= p.Mark @@ -412,7 +333,7 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) { for p = cursym.Text; p != nil; p = p.Link { o = int(p.As) switch o { - case ATEXT: + case obj.ATEXT: mov = AMOVD aoffset = 0 autosize = int32(textstksiz + 8) @@ -421,10 +342,10 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) { } else if autosize&4 != 0 { autosize += 4 } - p.To.Offset = int64(uint64(p.To.Offset)&(0xffffffff<<32) | uint64(uint32(autosize-8))) + p.To.Offset = int64(autosize) - 8 - if !(p.Reg&obj.NOSPLIT != 0) { - p = stacksplit(ctxt, p, autosize, bool2int(!(cursym.Text.Reg&obj.NEEDCTXT != 0))) // emit split check + if !(p.From3.Offset&obj.NOSPLIT != 0) { + p = stacksplit(ctxt, p, autosize, bool2int(!(cursym.Text.From3.Offset&obj.NEEDCTXT != 0))) // emit split check } q = p @@ -432,17 +353,15 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) { if autosize != 0 { /* use MOVDU to adjust R1 when saving R31, if autosize is small */ if !(cursym.Text.Mark&LEAF != 0) && autosize >= -BIG && autosize <= BIG { - mov = AMOVDU aoffset = int(-autosize) } else { - q = obj.Appendp(ctxt, p) q.As = AADD q.Lineno = p.Lineno - q.From.Type = D_CONST + q.From.Type = obj.TYPE_CONST q.From.Offset = int64(-autosize) - q.To.Type = D_REG + q.To.Type = obj.TYPE_REG q.To.Reg = REGSP q.Spadj = +autosize } @@ -463,24 +382,24 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) { q = obj.Appendp(ctxt, q) q.As = AMOVD q.Lineno = p.Lineno - q.From.Type = D_SPR - q.From.Offset = D_LR - q.To.Type = D_REG + q.From.Type = obj.TYPE_REG + q.From.Reg = REG_LR + q.To.Type = obj.TYPE_REG q.To.Reg = REGTMP q = obj.Appendp(ctxt, q) q.As = int16(mov) q.Lineno = p.Lineno - q.From.Type = D_REG + q.From.Type = obj.TYPE_REG q.From.Reg = REGTMP - q.To.Type = D_OREG + q.To.Type = obj.TYPE_MEM q.To.Offset = int64(aoffset) q.To.Reg = REGSP if q.As == AMOVDU { q.Spadj = int32(-aoffset) } - if cursym.Text.Reg&obj.WRAPPER != 0 { + if cursym.Text.From3.Offset&obj.WRAPPER != 0 { // if(g->panic != nil && g->panic->argp == FP) g->panic->argp = bottom-of-frame // // MOVD g_panic(g), R3 @@ -501,109 +420,109 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) { q = obj.Appendp(ctxt, q) q.As = AMOVD - q.From.Type = D_OREG + q.From.Type = obj.TYPE_MEM q.From.Reg = REGG q.From.Offset = 4 * int64(ctxt.Arch.Ptrsize) // G.panic - q.To.Type = D_REG - q.To.Reg = 3 + q.To.Type = obj.TYPE_REG + q.To.Reg = REG_R3 q = obj.Appendp(ctxt, q) q.As = ACMP - q.From.Type = D_REG - q.From.Reg = 0 - q.To.Type = D_REG - q.To.Reg = 3 + q.From.Type = obj.TYPE_REG + q.From.Reg = REG_R0 + q.To.Type = obj.TYPE_REG + q.To.Reg = REG_R3 q = obj.Appendp(ctxt, q) q.As = ABEQ - q.To.Type = D_BRANCH + q.To.Type = obj.TYPE_BRANCH p1 = q q = obj.Appendp(ctxt, q) q.As = AMOVD - q.From.Type = D_OREG - q.From.Reg = 3 + q.From.Type = obj.TYPE_MEM + q.From.Reg = REG_R3 q.From.Offset = 0 // Panic.argp - q.To.Type = D_REG - q.To.Reg = 4 + q.To.Type = obj.TYPE_REG + q.To.Reg = REG_R4 q = obj.Appendp(ctxt, q) q.As = AADD - q.From.Type = D_CONST + q.From.Type = obj.TYPE_CONST q.From.Offset = int64(autosize) + 8 q.Reg = REGSP - q.To.Type = D_REG - q.To.Reg = 5 + q.To.Type = obj.TYPE_REG + q.To.Reg = REG_R5 q = obj.Appendp(ctxt, q) q.As = ACMP - q.From.Type = D_REG - q.From.Reg = 4 - q.To.Type = D_REG - q.To.Reg = 5 + q.From.Type = obj.TYPE_REG + q.From.Reg = REG_R4 + q.To.Type = obj.TYPE_REG + q.To.Reg = REG_R5 q = obj.Appendp(ctxt, q) q.As = ABNE - q.To.Type = D_BRANCH + q.To.Type = obj.TYPE_BRANCH p2 = q q = obj.Appendp(ctxt, q) q.As = AADD - q.From.Type = D_CONST + q.From.Type = obj.TYPE_CONST q.From.Offset = 8 q.Reg = REGSP - q.To.Type = D_REG - q.To.Reg = 6 + q.To.Type = obj.TYPE_REG + q.To.Reg = REG_R6 q = obj.Appendp(ctxt, q) q.As = AMOVD - q.From.Type = D_REG - q.From.Reg = 6 - q.To.Type = D_OREG - q.To.Reg = 3 + q.From.Type = obj.TYPE_REG + q.From.Reg = REG_R6 + q.To.Type = obj.TYPE_MEM + q.To.Reg = REG_R3 q.To.Offset = 0 // Panic.argp q = obj.Appendp(ctxt, q) - q.As = ANOP + q.As = obj.ANOP p1.Pcond = q p2.Pcond = q } case ARETURN: - if p.From.Type == D_CONST { + if p.From.Type == obj.TYPE_CONST { ctxt.Diag("using BECOME (%v) is not supported!", p) break } if p.To.Sym != nil { // retjmp p.As = ABR - p.To.Type = D_BRANCH + p.To.Type = obj.TYPE_BRANCH break } if cursym.Text.Mark&LEAF != 0 { if !(autosize != 0) { p.As = ABR - p.From = zprg.From - p.To.Type = D_SPR - p.To.Offset = D_LR + p.From = obj.Zprog.From + p.To.Type = obj.TYPE_REG + p.To.Reg = REG_LR p.Mark |= BRANCH break } p.As = AADD - p.From.Type = D_CONST + p.From.Type = obj.TYPE_CONST p.From.Offset = int64(autosize) - p.To.Type = D_REG + p.To.Type = obj.TYPE_REG p.To.Reg = REGSP p.Spadj = -autosize - q = ctxt.NewProg() + q = new(obj.Prog) q.As = ABR q.Lineno = p.Lineno - q.To.Type = D_SPR - q.To.Offset = D_LR + q.To.Type = obj.TYPE_REG + q.To.Reg = REG_LR q.Mark |= BRANCH q.Spadj = +autosize @@ -613,19 +532,19 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) { } p.As = AMOVD - p.From.Type = D_OREG + p.From.Type = obj.TYPE_MEM p.From.Offset = 0 p.From.Reg = REGSP - p.To.Type = D_REG + p.To.Type = obj.TYPE_REG p.To.Reg = REGTMP - q = ctxt.NewProg() + q = new(obj.Prog) q.As = AMOVD q.Lineno = p.Lineno - q.From.Type = D_REG + q.From.Type = obj.TYPE_REG q.From.Reg = REGTMP - q.To.Type = D_SPR - q.To.Offset = D_LR + q.To.Type = obj.TYPE_REG + q.To.Reg = REG_LR q.Link = p.Link p.Link = q @@ -633,14 +552,14 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) { if false { // Debug bad returns - q = ctxt.NewProg() + q = new(obj.Prog) q.As = AMOVD q.Lineno = p.Lineno - q.From.Type = D_OREG + q.From.Type = obj.TYPE_MEM q.From.Offset = 0 q.From.Reg = REGTMP - q.To.Type = D_REG + q.To.Type = obj.TYPE_REG q.To.Reg = REGTMP q.Link = p.Link @@ -649,12 +568,12 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) { } if autosize != 0 { - q = ctxt.NewProg() + q = new(obj.Prog) q.As = AADD q.Lineno = p.Lineno - q.From.Type = D_CONST + q.From.Type = obj.TYPE_CONST q.From.Offset = int64(autosize) - q.To.Type = D_REG + q.To.Type = obj.TYPE_REG q.To.Reg = REGSP q.Spadj = -autosize @@ -662,11 +581,11 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) { p.Link = q } - q1 = ctxt.NewProg() + q1 = new(obj.Prog) q1.As = ABR q1.Lineno = p.Lineno - q1.To.Type = D_SPR - q1.To.Offset = D_LR + q1.To.Type = obj.TYPE_REG + q1.To.Reg = REG_LR q1.Mark |= BRANCH q1.Spadj = +autosize @@ -674,7 +593,7 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) { q.Link = q1 case AADD: - if p.To.Type == D_REG && p.To.Reg == REGSP && p.From.Type == D_CONST { + if p.To.Type == obj.TYPE_REG && p.To.Reg == REGSP && p.From.Type == obj.TYPE_CONST { p.Spadj = int32(-p.From.Offset) } break @@ -728,7 +647,6 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) { } */ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32, noctxt int) *obj.Prog { - var q *obj.Prog var q1 *obj.Prog @@ -736,14 +654,14 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32, noctxt int) *obj.P p = obj.Appendp(ctxt, p) p.As = AMOVD - p.From.Type = D_OREG + p.From.Type = obj.TYPE_MEM p.From.Reg = REGG 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 = D_REG - p.To.Reg = 3 + p.To.Type = obj.TYPE_REG + p.To.Reg = REG_R3 q = nil if framesize <= obj.StackSmall { @@ -752,9 +670,9 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32, noctxt int) *obj.P p = obj.Appendp(ctxt, p) p.As = ACMPU - p.From.Type = D_REG - p.From.Reg = 3 - p.To.Type = D_REG + p.From.Type = obj.TYPE_REG + p.From.Reg = REG_R3 + p.To.Type = obj.TYPE_REG p.To.Reg = REGSP } else if framesize <= obj.StackBig { // large stack: SP-framesize < stackguard-StackSmall @@ -763,20 +681,19 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32, noctxt int) *obj.P p = obj.Appendp(ctxt, p) p.As = AADD - p.From.Type = D_CONST + p.From.Type = obj.TYPE_CONST p.From.Offset = int64(-framesize) p.Reg = REGSP - p.To.Type = D_REG - p.To.Reg = 4 + p.To.Type = obj.TYPE_REG + p.To.Reg = REG_R4 p = obj.Appendp(ctxt, p) p.As = ACMPU - p.From.Type = D_REG - p.From.Reg = 3 - p.To.Type = D_REG - p.To.Reg = 4 + p.From.Type = obj.TYPE_REG + p.From.Reg = REG_R3 + p.To.Type = obj.TYPE_REG + p.To.Reg = REG_R4 } else { - // Such a large stack we need to protect against wraparound. // If SP is close to zero: // SP-stackguard+StackGuard <= framesize + (StackGuard-StackSmall) @@ -795,44 +712,44 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32, noctxt int) *obj.P p = obj.Appendp(ctxt, p) p.As = ACMP - p.From.Type = D_REG - p.From.Reg = 3 - p.To.Type = D_CONST + p.From.Type = obj.TYPE_REG + p.From.Reg = REG_R3 + p.To.Type = obj.TYPE_CONST p.To.Offset = obj.StackPreempt p = obj.Appendp(ctxt, p) q = p p.As = ABEQ - p.To.Type = D_BRANCH + p.To.Type = obj.TYPE_BRANCH p = obj.Appendp(ctxt, p) p.As = AADD - p.From.Type = D_CONST + p.From.Type = obj.TYPE_CONST p.From.Offset = obj.StackGuard p.Reg = REGSP - p.To.Type = D_REG - p.To.Reg = 4 + p.To.Type = obj.TYPE_REG + p.To.Reg = REG_R4 p = obj.Appendp(ctxt, p) p.As = ASUB - p.From.Type = D_REG - p.From.Reg = 3 - p.To.Type = D_REG - p.To.Reg = 4 + p.From.Type = obj.TYPE_REG + p.From.Reg = REG_R3 + p.To.Type = obj.TYPE_REG + p.To.Reg = REG_R4 p = obj.Appendp(ctxt, p) p.As = AMOVD - p.From.Type = D_CONST + p.From.Type = obj.TYPE_CONST p.From.Offset = int64(framesize) + obj.StackGuard - obj.StackSmall - p.To.Type = D_REG + p.To.Type = obj.TYPE_REG p.To.Reg = REGTMP p = obj.Appendp(ctxt, p) p.As = ACMPU - p.From.Type = D_REG + p.From.Type = obj.TYPE_REG p.From.Reg = REGTMP - p.To.Type = D_REG - p.To.Reg = 4 + p.To.Type = obj.TYPE_REG + p.To.Reg = REG_R4 } // q1: BLT done @@ -840,16 +757,16 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32, noctxt int) *obj.P q1 = p p.As = ABLT - p.To.Type = D_BRANCH + p.To.Type = obj.TYPE_BRANCH // MOVD LR, R5 p = obj.Appendp(ctxt, p) p.As = AMOVD - p.From.Type = D_SPR - p.From.Offset = D_LR - p.To.Type = D_REG - p.To.Reg = 5 + p.From.Type = obj.TYPE_REG + p.From.Reg = REG_LR + p.To.Type = obj.TYPE_REG + p.To.Reg = REG_R5 if q != nil { q.Pcond = p } @@ -858,11 +775,10 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32, noctxt int) *obj.P p = obj.Appendp(ctxt, p) p.As = ABL - p.To.Type = D_BRANCH + 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[noctxt] } @@ -870,13 +786,13 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32, noctxt int) *obj.P p = obj.Appendp(ctxt, p) p.As = ABR - p.To.Type = D_BRANCH + p.To.Type = obj.TYPE_BRANCH p.Pcond = ctxt.Cursym.Text.Link // placeholder for q1's jump target p = obj.Appendp(ctxt, p) - p.As = ANOP // zero-width place holder + p.As = obj.ANOP // zero-width place holder q1.Pcond = p return p @@ -888,7 +804,7 @@ func follow(ctxt *obj.Link, s *obj.LSym) { ctxt.Cursym = s - firstp = ctxt.NewProg() + firstp = new(obj.Prog) lastp = firstp xfol(ctxt, s.Text, &lastp) lastp.Link = nil @@ -966,7 +882,7 @@ loop: } b = 0 /* set */ a = int(q.As) - if a == ANOP { + if a == obj.ANOP { i-- continue } @@ -984,7 +900,7 @@ loop: copy: for { - r = ctxt.NewProg() + r = new(obj.Prog) *r = *p if !(r.Mark&FOLL != 0) { fmt.Printf("cant happen 1\n") @@ -1016,10 +932,10 @@ loop: } a = ABR - q = ctxt.NewProg() + q = new(obj.Prog) q.As = int16(a) q.Lineno = p.Lineno - q.To.Type = D_BRANCH + q.To.Type = obj.TYPE_BRANCH q.To.Offset = p.Pc q.Pcond = p p = q @@ -1052,97 +968,32 @@ loop: goto loop } -func prg() *obj.Prog { - p := zprg - return &p -} - var Linkppc64 = obj.LinkArch{ - ByteOrder: binary.BigEndian, - Pconv: Pconv, - Name: "ppc64", - Thechar: '9', - Endian: obj.BigEndian, - Addstacksplit: addstacksplit, - Assemble: span9, - Datasize: datasize, - Follow: follow, - Iscall: iscall, - Isdata: isdata, - Prg: prg, - Progedit: progedit, - Settextflag: settextflag, - Symtype: symtype, - Textflag: textflag, - Minlc: 4, - Ptrsize: 8, - Regsize: 8, - D_ADDR: D_ADDR, - D_AUTO: D_AUTO, - D_BRANCH: D_BRANCH, - D_CONST: D_CONST, - D_EXTERN: D_EXTERN, - D_FCONST: D_FCONST, - D_NONE: D_NONE, - D_PARAM: D_PARAM, - D_SCONST: D_SCONST, - D_STATIC: D_STATIC, - D_OREG: D_OREG, - ACALL: ABL, - ADATA: ADATA, - AEND: AEND, - AFUNCDATA: AFUNCDATA, - AGLOBL: AGLOBL, - AJMP: ABR, - ANOP: ANOP, - APCDATA: APCDATA, - ARET: ARETURN, - ATEXT: ATEXT, - ATYPE: ATYPE, - AUSEFIELD: AUSEFIELD, + ByteOrder: binary.BigEndian, + Pconv: Pconv, + Name: "ppc64", + Thechar: '9', + Endian: obj.BigEndian, + Preprocess: preprocess, + Assemble: span9, + Follow: follow, + Progedit: progedit, + Minlc: 4, + Ptrsize: 8, + Regsize: 8, } var Linkppc64le = obj.LinkArch{ - ByteOrder: binary.LittleEndian, - Pconv: Pconv, - Name: "ppc64le", - Thechar: '9', - Endian: obj.LittleEndian, - Addstacksplit: addstacksplit, - Assemble: span9, - Datasize: datasize, - Follow: follow, - Iscall: iscall, - Isdata: isdata, - Prg: prg, - Progedit: progedit, - Settextflag: settextflag, - Symtype: symtype, - Textflag: textflag, - Minlc: 4, - Ptrsize: 8, - Regsize: 8, - D_ADDR: D_ADDR, - D_AUTO: D_AUTO, - D_BRANCH: D_BRANCH, - D_CONST: D_CONST, - D_EXTERN: D_EXTERN, - D_FCONST: D_FCONST, - D_NONE: D_NONE, - D_PARAM: D_PARAM, - D_SCONST: D_SCONST, - D_STATIC: D_STATIC, - D_OREG: D_OREG, - ACALL: ABL, - ADATA: ADATA, - AEND: AEND, - AFUNCDATA: AFUNCDATA, - AGLOBL: AGLOBL, - AJMP: ABR, - ANOP: ANOP, - APCDATA: APCDATA, - ARET: ARETURN, - ATEXT: ATEXT, - ATYPE: ATYPE, - AUSEFIELD: AUSEFIELD, + ByteOrder: binary.LittleEndian, + Pconv: Pconv, + Name: "ppc64le", + Thechar: '9', + Endian: obj.LittleEndian, + Preprocess: preprocess, + Assemble: span9, + Follow: follow, + Progedit: progedit, + Minlc: 4, + Ptrsize: 8, + Regsize: 8, } diff --git a/src/cmd/internal/obj/sym.go b/src/cmd/internal/obj/sym.go index 855aeea8ec..583b3256f6 100644 --- a/src/cmd/internal/obj/sym.go +++ b/src/cmd/internal/obj/sym.go @@ -49,10 +49,6 @@ var headers = []struct { struct { name string val int - }{"android", Hlinux}, - struct { - name string - val int }{"darwin", Hdarwin}, struct { name string @@ -73,6 +69,10 @@ var headers = []struct { struct { name string val int + }{"android", Hlinux}, // must be after "linux" entry or else headstr(Hlinux) == "android" + struct { + name string + val int }{"nacl", Hnacl}, struct { name string @@ -129,6 +129,8 @@ func Linknew(arch *LinkArch) *Link { var p string var buf string + linksetexp() + ctxt = new(Link) ctxt.Arch = arch ctxt.Version = HistVersion @@ -151,7 +153,6 @@ func Linknew(arch *LinkArch) *Link { // Record thread-local storage offset. // TODO(rsc): Move tlsoffset back into the linker. switch ctxt.Headtype { - default: log.Fatalf("unknown thread-local storage offset for %s", Headstr(ctxt.Headtype)) @@ -194,7 +195,6 @@ func Linknew(arch *LinkArch) *Link { */ case Hdarwin: switch ctxt.Arch.Thechar { - default: log.Fatalf("unknown thread-local storage offset for darwin/%s", ctxt.Arch.Name) @@ -211,12 +211,10 @@ func Linknew(arch *LinkArch) *Link { // On arm, record goarm. if ctxt.Arch.Thechar == '5' { - p = Getgoarm() if p != "" { ctxt.Goarm = int32(Atoi(p)) } else { - ctxt.Goarm = 6 } } @@ -281,6 +279,5 @@ func Linklookup(ctxt *Link, name string, v int) *LSym { // read-only lookup func linkrlookup(ctxt *Link, name string, v int) *LSym { - return _lookup(ctxt, name, v, 0) } diff --git a/src/cmd/internal/obj/util.go b/src/cmd/internal/obj/util.go index 14f2271cb2..de7197e0ba 100644 --- a/src/cmd/internal/obj/util.go +++ b/src/cmd/internal/obj/util.go @@ -25,10 +25,19 @@ func Cputime() float64 { type Biobuf struct { unget int haveUnget bool + f *os.File r *bufio.Reader w *bufio.Writer } +func Bopenw(name string) (*Biobuf, error) { + f, err := os.Open(name) + if err != nil { + return nil, err + } + return &Biobuf{f: f, w: bufio.NewWriter(f)}, nil +} + func Binitw(w io.Writer) *Biobuf { return &Biobuf{w: bufio.NewWriter(w)} } @@ -75,6 +84,15 @@ func Bflush(b *Biobuf) error { return b.w.Flush() } +func Bterm(b *Biobuf) error { + err := b.w.Flush() + err1 := b.f.Close() + if err == nil { + err = err1 + } + return err +} + func envOr(key, value string) string { if x := os.Getenv(key); x != "" { return x @@ -108,7 +126,7 @@ func Atoi(s string) int { } func (p *Prog) Line() string { - return linklinefmt(p.Ctxt, int(p.Lineno), false, false) + return Linklinefmt(p.Ctxt, int(p.Lineno), false, false) } func (p *Prog) String() string { @@ -119,7 +137,11 @@ func (p *Prog) String() string { } func (ctxt *Link) NewProg() *Prog { - p := ctxt.Arch.Prg() // should be the only call to this; all others should use ctxt.NewProg + p := new(Prog) // should be the only call to this; all others should use ctxt.NewProg p.Ctxt = ctxt return p } + +func (ctxt *Link) Line(n int) string { + return Linklinefmt(ctxt, n, false, false) +} diff --git a/src/cmd/internal/obj/x86/6.out.go b/src/cmd/internal/obj/x86/6.out.go index f19c0cd654..f96597b066 100644 --- a/src/cmd/internal/obj/x86/6.out.go +++ b/src/cmd/internal/obj/x86/6.out.go @@ -30,12 +30,13 @@ package x86 +import "cmd/internal/obj" + /* * amd64 */ const ( - AXXX = iota - AAAA + AAAA = obj.A_ARCHSPECIFIC + iota AAAD AAAM AAAS @@ -65,7 +66,6 @@ const ( ABTSL ABTSW ABYTE - ACALL ACLC ACLD ACLI @@ -79,7 +79,6 @@ const ( ACMPSW ADAA ADAS - ADATA ADECB ADECL ADECQ @@ -88,9 +87,6 @@ const ( ADIVL ADIVW AENTER - AGLOBL - AGOK - AHISTORY AHLT AIDIVB AIDIVL @@ -123,7 +119,6 @@ const ( AJLS AJLT AJMI - AJMP AJNE AJOC AJOS @@ -166,11 +161,9 @@ const ( AMULB AMULL AMULW - ANAME ANEGB ANEGL ANEGW - ANOP ANOTB ANOTL ANOTW @@ -204,7 +197,6 @@ const ( ARCRW AREP AREPN - ARET AROLB AROLL AROLW @@ -261,7 +253,6 @@ const ( ATESTB ATESTL ATESTW - ATEXT AVERR AVERW AWAIT @@ -370,10 +361,6 @@ const ( AFXTRACT AFYL2X AFYL2XP1 - AEND - ADYNT_ - AINIT_ - ASIGNAME ACMPXCHGB ACMPXCHGL ACMPXCHGW @@ -714,7 +701,6 @@ const ( AMOVQL ABSWAPL ABSWAPQ - AUNDEF AAESENC AAESENCLAST AAESDEC @@ -723,100 +709,89 @@ const ( AAESKEYGENASSIST APSHUFD APCLMULQDQ - AUSEFIELD - ATYPE - AFUNCDATA - APCDATA - ACHECKNIL - AVARDEF - AVARKILL - ADUFFCOPY - ADUFFZERO ALAST ) const ( - D_AL = 0 + iota - D_CL - D_DL - D_BL - D_SPB - D_BPB - D_SIB - D_DIB - D_R8B - D_R9B - D_R10B - D_R11B - D_R12B - D_R13B - D_R14B - D_R15B - D_AX = 16 + iota - 16 - D_CX - D_DX - D_BX - D_SP - D_BP - D_SI - D_DI - D_R8 - D_R9 - D_R10 - D_R11 - D_R12 - D_R13 - D_R14 - D_R15 - D_AH = 32 + iota - 32 - D_CH - D_DH - D_BH - D_F0 = 36 - D_M0 = 44 - D_X0 = 52 + iota - 38 - D_X1 - D_X2 - D_X3 - D_X4 - D_X5 - D_X6 - D_X7 - D_X8 - D_X9 - D_X10 - D_X11 - D_X12 - D_X13 - D_X14 - D_X15 - D_CS = 68 + iota - 54 - D_SS - D_DS - D_ES - D_FS - D_GS - D_GDTR - D_IDTR - D_LDTR - D_MSW - D_TASK - D_CR = 79 - D_DR = 95 - D_TR = 103 - D_TLS = 111 - D_NONE = 112 - D_BRANCH = 113 - D_EXTERN = 114 - D_STATIC = 115 - D_AUTO = 116 - D_PARAM = 117 - D_CONST = 118 - D_FCONST = 119 - D_SCONST = 120 - D_ADDR = 121 + iota - 78 - D_INDIR - D_LAST + REG_NONE = 0 + REG_AL = 0 + 16 + iota - 1 + REG_CL + REG_DL + REG_BL + REG_SPB + REG_BPB + REG_SIB + REG_DIB + REG_R8B + REG_R9B + REG_R10B + REG_R11B + REG_R12B + REG_R13B + REG_R14B + REG_R15B + REG_AX = 16 + 16 + iota - 17 + REG_CX + REG_DX + REG_BX + REG_SP + REG_BP + REG_SI + REG_DI + REG_R8 + REG_R9 + REG_R10 + REG_R11 + REG_R12 + REG_R13 + REG_R14 + REG_R15 + REG_AH = 32 + 16 + iota - 33 + REG_CH + REG_DH + REG_BH + REG_F0 = 36 + 16 + REG_M0 = 44 + 16 + REG_X0 = 52 + 16 + iota - 39 + REG_X1 + REG_X2 + REG_X3 + REG_X4 + REG_X5 + REG_X6 + REG_X7 + REG_X8 + REG_X9 + REG_X10 + REG_X11 + REG_X12 + REG_X13 + REG_X14 + REG_X15 + REG_CS = 68 + 16 + iota - 55 + REG_SS + REG_DS + REG_ES + REG_FS + REG_GS + REG_GDTR + REG_IDTR + REG_LDTR + REG_MSW + REG_TASK + REG_CR = 79 + 16 + REG_DR = 95 + 16 + REG_TR = 103 + 16 + REG_TLS = 111 + 16 + iota - 69 + MAXREG + REGARG = -1 + REGRET = REG_AX + FREGRET = REG_X0 + REGSP = REG_SP + REGTMP = REG_DI + REGEXT = REG_R15 + FREGMIN = REG_X0 + 5 + FREGEXT = REG_X0 + 15 T_TYPE = 1 << 0 T_INDEX = 1 << 1 T_OFFSET = 1 << 2 @@ -825,12 +800,4 @@ const ( T_SCONST = 1 << 5 T_64 = 1 << 6 T_GOTYPE = 1 << 7 - REGARG = -1 - REGRET = D_AX - FREGRET = D_X0 - REGSP = D_SP - REGTMP = D_DI - REGEXT = D_R15 - FREGMIN = D_X0 + 5 - FREGEXT = D_X0 + 15 ) diff --git a/src/cmd/internal/obj/x86/anames6.go b/src/cmd/internal/obj/x86/anames6.go index 4d8a0b0346..c7cc409e5f 100644 --- a/src/cmd/internal/obj/x86/anames6.go +++ b/src/cmd/internal/obj/x86/anames6.go @@ -4,8 +4,26 @@ package x86 * this is the ranlib header */ var Anames = []string{ - "XXX", - "AAA", + "XXX ", + "CALL", + "CHECKNIL", + "DATA", + "DUFFCOPY", + "DUFFZERO", + "END", + "FUNCDATA", + "GLOBL", + "JMP", + "NOP", + "PCDATA", + "RET", + "TEXT", + "TYPE", + "UNDEF", + "USEFIELD", + "VARDEF", + "VARKILL", + "AAA ", "AAD", "AAM", "AAS", @@ -35,7 +53,6 @@ var Anames = []string{ "BTSL", "BTSW", "BYTE", - "CALL", "CLC", "CLD", "CLI", @@ -49,7 +66,6 @@ var Anames = []string{ "CMPSW", "DAA", "DAS", - "DATA", "DECB", "DECL", "DECQ", @@ -58,9 +74,6 @@ var Anames = []string{ "DIVL", "DIVW", "ENTER", - "GLOBL", - "GOK", - "HISTORY", "HLT", "IDIVB", "IDIVL", @@ -93,7 +106,6 @@ var Anames = []string{ "JLS", "JLT", "JMI", - "JMP", "JNE", "JOC", "JOS", @@ -136,11 +148,9 @@ var Anames = []string{ "MULB", "MULL", "MULW", - "NAME", "NEGB", "NEGL", "NEGW", - "NOP", "NOTB", "NOTL", "NOTW", @@ -174,7 +184,6 @@ var Anames = []string{ "RCRW", "REP", "REPN", - "RET", "ROLB", "ROLL", "ROLW", @@ -231,7 +240,6 @@ var Anames = []string{ "TESTB", "TESTL", "TESTW", - "TEXT", "VERR", "VERW", "WAIT", @@ -340,10 +348,6 @@ var Anames = []string{ "FXTRACT", "FYL2X", "FYL2XP1", - "END", - "DYNT_", - "INIT_", - "SIGNAME", "CMPXCHGB", "CMPXCHGL", "CMPXCHGW", @@ -684,7 +688,6 @@ var Anames = []string{ "MOVQL", "BSWAPL", "BSWAPQ", - "UNDEF", "AESENC", "AESENCLAST", "AESDEC", @@ -693,97 +696,5 @@ var Anames = []string{ "AESKEYGENASSIST", "PSHUFD", "PCLMULQDQ", - "USEFIELD", - "TYPE", - "FUNCDATA", - "PCDATA", - "CHECKNIL", - "VARDEF", - "VARKILL", - "DUFFCOPY", - "DUFFZERO", "LAST", } - -var dnames6 = []string{ - D_AL: "AL", - D_CL: "CL", - D_DL: "DL", - D_BL: "BL", - D_SPB: "SPB", - D_BPB: "BPB", - D_SIB: "SIB", - D_DIB: "DIB", - D_R8B: "R8B", - D_R9B: "R9B", - D_R10B: "R10B", - D_R11B: "R11B", - D_R12B: "R12B", - D_R13B: "R13B", - D_R14B: "R14B", - D_R15B: "R15B", - D_AX: "AX", - D_CX: "CX", - D_DX: "DX", - D_BX: "BX", - D_SP: "SP", - D_BP: "BP", - D_SI: "SI", - D_DI: "DI", - D_R8: "R8", - D_R9: "R9", - D_R10: "R10", - D_R11: "R11", - D_R12: "R12", - D_R13: "R13", - D_R14: "R14", - D_R15: "R15", - D_AH: "AH", - D_CH: "CH", - D_DH: "DH", - D_BH: "BH", - D_F0: "F0", - D_M0: "M0", - D_X0: "X0", - D_X1: "X1", - D_X2: "X2", - D_X3: "X3", - D_X4: "X4", - D_X5: "X5", - D_X6: "X6", - D_X7: "X7", - D_X8: "X8", - D_X9: "X9", - D_X10: "X10", - D_X11: "X11", - D_X12: "X12", - D_X13: "X13", - D_X14: "X14", - D_X15: "X15", - D_CS: "CS", - D_SS: "SS", - D_DS: "DS", - D_ES: "ES", - D_FS: "FS", - D_GS: "GS", - D_GDTR: "GDTR", - D_IDTR: "IDTR", - D_LDTR: "LDTR", - D_MSW: "MSW", - D_TASK: "TASK", - D_CR: "CR", - D_DR: "DR", - D_TR: "TR", - D_TLS: "TLS", - D_NONE: "NONE", - D_BRANCH: "BRANCH", - D_EXTERN: "EXTERN", - D_STATIC: "STATIC", - D_AUTO: "AUTO", - D_PARAM: "PARAM", - D_CONST: "CONST", - D_FCONST: "FCONST", - D_SCONST: "SCONST", - D_ADDR: "ADDR", - D_INDIR: "INDIR", -} diff --git a/src/cmd/internal/obj/x86/asm6.go b/src/cmd/internal/obj/x86/asm6.go index 0665a08754..689e6414c2 100644 --- a/src/cmd/internal/obj/x86/asm6.go +++ b/src/cmd/internal/obj/x86/asm6.go @@ -128,8 +128,9 @@ const ( Yxr Yxm Ytls + Ytextsize Ymax - Zxxx = 0 + iota - 67 + Zxxx = 0 + iota - 68 Zlit Zlitm_r Z_rp @@ -197,9 +198,9 @@ const ( var ycover [Ymax * Ymax]uint8 -var reg [D_NONE]int +var reg [MAXREG]int -var regrex [D_NONE + 1]int +var regrex [MAXREG + 1]int var ynone = []uint8{ Ynone, @@ -211,7 +212,7 @@ var ynone = []uint8{ var ytext = []uint8{ Ymb, - Yi64, + Ytextsize, Zpseudo, 1, 0, @@ -1423,7 +1424,7 @@ var yaes2 = []uint8{ var optab = /* as, ytab, andproto, opcode */ []Optab{ - Optab{AXXX, nil, 0, [23]uint8{}}, + Optab{obj.AXXX, nil, 0, [23]uint8{}}, Optab{AAAA, ynone, P32, [23]uint8{0x37}}, Optab{AAAD, ynone, P32, [23]uint8{0xd5, 0x0a}}, Optab{AAAM, ynone, P32, [23]uint8{0xd4, 0x0a}}, @@ -1473,7 +1474,7 @@ var optab = Optab{ABTSW, ybtl, Pq, [23]uint8{0xba, 05, 0xab}}, Optab{ABTW, ybtl, Pq, [23]uint8{0xba, 04, 0xa3}}, Optab{ABYTE, ybyte, Px, [23]uint8{1}}, - Optab{ACALL, ycall, Px, [23]uint8{0xff, 02, 0xe8}}, + Optab{obj.ACALL, ycall, Px, [23]uint8{0xff, 02, 0xe8}}, Optab{ACDQ, ynone, Px, [23]uint8{0x99}}, Optab{ACLC, ynone, Px, [23]uint8{0xf8}}, Optab{ACLD, ynone, Px, [23]uint8{0xfc}}, @@ -1570,7 +1571,7 @@ var optab = Optab{ACQO, ynone, Pw, [23]uint8{0x99}}, Optab{ADAA, ynone, P32, [23]uint8{0x27}}, Optab{ADAS, ynone, P32, [23]uint8{0x2f}}, - Optab{ADATA, nil, 0, [23]uint8{}}, + Optab{obj.ADATA, nil, 0, [23]uint8{}}, Optab{ADECB, yincb, Pb, [23]uint8{0xfe, 01}}, Optab{ADECL, yincl, Px, [23]uint8{0xff, 01}}, Optab{ADECQ, yincl, Pw, [23]uint8{0xff, 01}}, @@ -1589,9 +1590,7 @@ var optab = Optab{AFXSAVE, ysvrs, Pm, [23]uint8{0xae, 00, 0xae, 00}}, Optab{AFXRSTOR64, ysvrs, Pw, [23]uint8{0x0f, 0xae, 01, 0x0f, 0xae, 01}}, Optab{AFXSAVE64, ysvrs, Pw, [23]uint8{0x0f, 0xae, 00, 0x0f, 0xae, 00}}, - Optab{AGLOBL, nil, 0, [23]uint8{}}, - Optab{AGOK, nil, 0, [23]uint8{}}, - Optab{AHISTORY, nil, 0, [23]uint8{}}, + Optab{obj.AGLOBL, nil, 0, [23]uint8{}}, Optab{AHLT, ynone, Px, [23]uint8{0xf4}}, Optab{AIDIVB, ydivb, Pb, [23]uint8{0xf6, 07}}, Optab{AIDIVL, ydivl, Px, [23]uint8{0xf7, 07}}, @@ -1629,7 +1628,7 @@ var optab = Optab{AJLS, yjcond, Px, [23]uint8{0x76, 0x86}}, Optab{AJLT, yjcond, Px, [23]uint8{0x7c, 0x8c}}, Optab{AJMI, yjcond, Px, [23]uint8{0x78, 0x88}}, - Optab{AJMP, yjmp, Px, [23]uint8{0xff, 04, 0xeb, 0xe9}}, + Optab{obj.AJMP, yjmp, Px, [23]uint8{0xff, 04, 0xeb, 0xe9}}, Optab{AJNE, yjcond, Px, [23]uint8{0x75, 0x85}}, Optab{AJOC, yjcond, Px, [23]uint8{0x71, 0x81, 00}}, Optab{AJOS, yjcond, Px, [23]uint8{0x70, 0x80, 00}}, @@ -1716,12 +1715,11 @@ var optab = Optab{AMULSD, yxm, Pf2, [23]uint8{0x59}}, Optab{AMULSS, yxm, Pf3, [23]uint8{0x59}}, Optab{AMULW, ydivl, Pe, [23]uint8{0xf7, 04}}, - Optab{ANAME, nil, 0, [23]uint8{}}, Optab{ANEGB, yscond, Pb, [23]uint8{0xf6, 03}}, Optab{ANEGL, yscond, Px, [23]uint8{0xf7, 03}}, Optab{ANEGQ, yscond, Pw, [23]uint8{0xf7, 03}}, Optab{ANEGW, yscond, Pe, [23]uint8{0xf7, 03}}, - Optab{ANOP, ynop, Px, [23]uint8{0, 0}}, + Optab{obj.ANOP, ynop, Px, [23]uint8{0, 0}}, Optab{ANOTB, yscond, Pb, [23]uint8{0xf6, 02}}, Optab{ANOTL, yscond, Px, [23]uint8{0xf7, 02}}, Optab{ANOTQ, yscond, Pw, [23]uint8{0xf7, 02}}, @@ -1859,7 +1857,7 @@ var optab = Optab{ARCRW, yshl, Pe, [23]uint8{0xd1, 03, 0xc1, 03, 0xd3, 03, 0xd3, 03}}, Optab{AREP, ynone, Px, [23]uint8{0xf3}}, Optab{AREPN, ynone, Px, [23]uint8{0xf2}}, - Optab{ARET, ynone, Px, [23]uint8{0xc3}}, + Optab{obj.ARET, ynone, Px, [23]uint8{0xc3}}, Optab{ARETFW, yret, Pe, [23]uint8{0xcb, 0xca}}, Optab{ARETFL, yret, Px, [23]uint8{0xcb, 0xca}}, Optab{ARETFQ, yret, Pw, [23]uint8{0xcb, 0xca}}, @@ -1942,7 +1940,7 @@ var optab = Optab{ATESTL, ytestl, Px, [23]uint8{0xa9, 0xf7, 00, 0x85, 0x85}}, Optab{ATESTQ, ytestl, Pw, [23]uint8{0xa9, 0xf7, 00, 0x85, 0x85}}, Optab{ATESTW, ytestl, Pe, [23]uint8{0xa9, 0xf7, 00, 0x85, 0x85}}, - Optab{ATEXT, ytext, Px, [23]uint8{}}, + Optab{obj.ATEXT, ytext, Px, [23]uint8{}}, Optab{AUCOMISD, yxcmp, Pe, [23]uint8{0x2e}}, Optab{AUCOMISS, yxcmp, Pm, [23]uint8{0x2e}}, Optab{AUNPCKHPD, yxm, Pe, [23]uint8{0x15}}, @@ -2091,7 +2089,7 @@ var optab = Optab{APREFETCHT2, yprefetch, Pm, [23]uint8{0x18, 03}}, Optab{APREFETCHNTA, yprefetch, Pm, [23]uint8{0x18, 00}}, Optab{AMOVQL, yrl_ml, Px, [23]uint8{0x89}}, - Optab{AUNDEF, ynone, Px, [23]uint8{0x0f, 0x0b}}, + Optab{obj.AUNDEF, ynone, Px, [23]uint8{0x0f, 0x0b}}, Optab{AAESENC, yaes, Pq, [23]uint8{0x38, 0xdc, 0}}, Optab{AAESENCLAST, yaes, Pq, [23]uint8{0x38, 0xdd, 0}}, Optab{AAESDEC, yaes, Pq, [23]uint8{0x38, 0xde, 0}}, @@ -2100,16 +2098,16 @@ var optab = Optab{AAESKEYGENASSIST, yaes2, Pq, [23]uint8{0x3a, 0xdf, 0}}, Optab{APSHUFD, yaes2, Pq, [23]uint8{0x70, 0}}, Optab{APCLMULQDQ, yxshuf, Pq, [23]uint8{0x3a, 0x44, 0}}, - Optab{AUSEFIELD, ynop, Px, [23]uint8{0, 0}}, - Optab{ATYPE, nil, 0, [23]uint8{}}, - Optab{AFUNCDATA, yfuncdata, Px, [23]uint8{0, 0}}, - Optab{APCDATA, ypcdata, Px, [23]uint8{0, 0}}, - Optab{ACHECKNIL, nil, 0, [23]uint8{}}, - Optab{AVARDEF, nil, 0, [23]uint8{}}, - Optab{AVARKILL, nil, 0, [23]uint8{}}, - Optab{ADUFFCOPY, yduff, Px, [23]uint8{0xe8}}, - Optab{ADUFFZERO, yduff, Px, [23]uint8{0xe8}}, - Optab{AEND, nil, 0, [23]uint8{}}, + Optab{obj.AUSEFIELD, ynop, Px, [23]uint8{0, 0}}, + Optab{obj.ATYPE, nil, 0, [23]uint8{}}, + Optab{obj.AFUNCDATA, yfuncdata, Px, [23]uint8{0, 0}}, + Optab{obj.APCDATA, ypcdata, Px, [23]uint8{0, 0}}, + Optab{obj.ACHECKNIL, nil, 0, [23]uint8{}}, + Optab{obj.AVARDEF, nil, 0, [23]uint8{}}, + Optab{obj.AVARKILL, nil, 0, [23]uint8{}}, + Optab{obj.ADUFFCOPY, yduff, Px, [23]uint8{0xe8}}, + Optab{obj.ADUFFZERO, yduff, Px, [23]uint8{0xe8}}, + Optab{obj.AEND, nil, 0, [23]uint8{}}, Optab{0, nil, 0, [23]uint8{}}, } @@ -2121,7 +2119,6 @@ var opindex [ALAST + 1]*Optab // around a Solaris-specific bug that should be fixed differently, but we don't know // what that bug is. And this does fix it. func isextern(s *obj.LSym) int { - // All the Solaris dynamic imports from libc.so begin with "libc_". return bool2int(strings.HasPrefix(s.Name, "libc_")) } @@ -2144,7 +2141,6 @@ var nop = [][16]uint8{ // 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 { @@ -2193,21 +2189,14 @@ func span6(ctxt *obj.Link, s *obj.LSym) { } for p = ctxt.Cursym.Text; p != nil; p = p.Link { - n = 0 - if p.To.Type == D_BRANCH { + if p.To.Type == obj.TYPE_BRANCH { if p.Pcond == nil { p.Pcond = p } } - q = p.Pcond - if q != nil { - if q.Back != 2 { - n = 1 - } - } - p.Back = uint8(n) if p.As == AADJSP { - p.To.Type = D_SP + p.To.Type = obj.TYPE_REG + p.To.Reg = REG_SP v = int32(-p.From.Offset) p.From.Offset = int64(v) p.As = int16(spadjop(ctxt, p, AADDL, AADDQ)) @@ -2218,7 +2207,7 @@ func span6(ctxt *obj.Link, s *obj.LSym) { } if v == 0 { - p.As = ANOP + p.As = obj.ANOP } } } @@ -2232,7 +2221,8 @@ func span6(ctxt *obj.Link, s *obj.LSym) { } if p.As == AADJSP { - p.To.Type = D_SP + p.To.Type = obj.TYPE_REG + p.To.Reg = REG_SP v = int32(-p.From.Offset) p.From.Offset = int64(v) p.As = int16(spadjop(ctxt, p, AADDL, AADDQ)) @@ -2243,7 +2233,7 @@ func span6(ctxt *obj.Link, s *obj.LSym) { } if v == 0 { - p.As = ANOP + p.As = obj.ANOP } } } @@ -2267,21 +2257,18 @@ func span6(ctxt *obj.Link, s *obj.LSym) { // 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 == ACALL && p.To.Sym == deferreturn { - + 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 == ACALL { - + if p.As == obj.ACALL { c = naclpad(ctxt, s, c, -(c+int32(p.Isize))&31) } @@ -2290,7 +2277,6 @@ func span6(ctxt *obj.Link, s *obj.LSym) { // make sure REP has room for 2 more bytes, so that // padding will not be inserted before the next instruction. if (p.As == AREP || p.As == AREPN) && c>>5 != (c+3-1)>>5 { - c = naclpad(ctxt, s, c, -c&31) } @@ -2298,7 +2284,6 @@ func span6(ctxt *obj.Link, s *obj.LSym) { // 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) } } @@ -2318,7 +2303,6 @@ func span6(ctxt *obj.Link, s *obj.LSym) { // 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 { @@ -2329,11 +2313,9 @@ func span6(ctxt *obj.Link, s *obj.LSym) { if q.As == AJCXZL { 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:] @@ -2477,358 +2459,374 @@ func instinit() { ycover[Ym*Ymax+Yxm] = 1 ycover[Yxr*Ymax+Yxm] = 1 - for i = 0; i < D_NONE; i++ { + for i = 0; i < MAXREG; i++ { reg[i] = -1 - if i >= D_AL && i <= D_R15B { - reg[i] = (i - D_AL) & 7 - if i >= D_SPB && i <= D_DIB { + if i >= REG_AL && i <= REG_R15B { + reg[i] = (i - REG_AL) & 7 + if i >= REG_SPB && i <= REG_DIB { regrex[i] = 0x40 } - if i >= D_R8B && i <= D_R15B { + if i >= REG_R8B && i <= REG_R15B { regrex[i] = Rxr | Rxx | Rxb } } - if i >= D_AH && i <= D_BH { - reg[i] = 4 + ((i - D_AH) & 7) + if i >= REG_AH && i <= REG_BH { + reg[i] = 4 + ((i - REG_AH) & 7) } - if i >= D_AX && i <= D_R15 { - reg[i] = (i - D_AX) & 7 - if i >= D_R8 { + if i >= REG_AX && i <= REG_R15 { + reg[i] = (i - REG_AX) & 7 + if i >= REG_R8 { regrex[i] = Rxr | Rxx | Rxb } } - if i >= D_F0 && i <= D_F0+7 { - reg[i] = (i - D_F0) & 7 + if i >= REG_F0 && i <= REG_F0+7 { + reg[i] = (i - REG_F0) & 7 } - if i >= D_M0 && i <= D_M0+7 { - reg[i] = (i - D_M0) & 7 + if i >= REG_M0 && i <= REG_M0+7 { + reg[i] = (i - REG_M0) & 7 } - if i >= D_X0 && i <= D_X0+15 { - reg[i] = (i - D_X0) & 7 - if i >= D_X0+8 { + if i >= REG_X0 && i <= REG_X0+15 { + reg[i] = (i - REG_X0) & 7 + if i >= REG_X0+8 { regrex[i] = Rxr | Rxx | Rxb } } - if i >= D_CR+8 && i <= D_CR+15 { + if i >= REG_CR+8 && i <= REG_CR+15 { regrex[i] = Rxr } } } func prefixof(ctxt *obj.Link, a *obj.Addr) int { - switch a.Type { - case D_INDIR + D_CS: - return 0x2e + if a.Type == obj.TYPE_MEM && a.Name == obj.NAME_NONE { + switch a.Reg { + case REG_CS: + return 0x2e - case D_INDIR + D_DS: - return 0x3e + case REG_DS: + return 0x3e - case D_INDIR + D_ES: - return 0x26 + case REG_ES: + return 0x26 - case D_INDIR + D_FS: - return 0x64 + case REG_FS: + return 0x64 - case D_INDIR + D_GS: - return 0x65 + 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 D_INDIR + D_TLS: - switch ctxt.Headtype { - - default: - log.Fatalf("unknown TLS base register for %s", obj.Headstr(ctxt.Headtype)) + // 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.Hdragonfly, - obj.Hfreebsd, - obj.Hlinux, - obj.Hnetbsd, - obj.Hopenbsd, - obj.Hsolaris: - return 0x64 // FS + case obj.Hdragonfly, + obj.Hfreebsd, + obj.Hlinux, + obj.Hnetbsd, + obj.Hopenbsd, + obj.Hsolaris: + return 0x64 // FS - case obj.Hdarwin: - return 0x65 // GS + case obj.Hdarwin: + return 0x65 // GS + } } } switch a.Index { - case D_CS: + case REG_CS: return 0x2e - case D_DS: + case REG_DS: return 0x3e - case D_ES: + case REG_ES: return 0x26 - case D_FS: + case REG_FS: return 0x64 - case D_GS: + case REG_GS: return 0x65 } return 0 } -func oclass(ctxt *obj.Link, a *obj.Addr) int { +func oclass(ctxt *obj.Link, p *obj.Prog, a *obj.Addr) int { var v int64 var l int32 - if a.Type >= D_INDIR || a.Index != D_NONE { - if a.Index != D_NONE && a.Scale == 0 { - if a.Type == D_ADDR { - switch a.Index { - case D_EXTERN, - D_STATIC: - if a.Sym != nil && isextern(a.Sym) != 0 { - return Yi32 - } - return Yiauto // use pc-relative addressing + // 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 + } - case D_AUTO, - D_PARAM: - return Yiauto - } + switch a.Type { + case obj.TYPE_NONE: + return Ynone + + case obj.TYPE_BRANCH: + return Ybr + + case obj.TYPE_MEM: + return Ym - return Yxxx + case obj.TYPE_ADDR: + switch a.Name { + case obj.NAME_EXTERN, + obj.NAME_STATIC: + if a.Sym != nil && isextern(a.Sym) != 0 { + return Yi32 } + return Yiauto // use pc-relative addressing - return Ycol + case obj.NAME_AUTO, + obj.NAME_PARAM: + return Yiauto } - return Ym + // TODO(rsc): 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", Dconv(p, 0, a)) + } + fallthrough + + // fall through + + case obj.TYPE_CONST: + if a.Sym != nil { + ctxt.Diag("TYPE_CONST with symbol: %v", Dconv(p, 0, a)) + } + + v = a.Offset + if v == 0 { + return Yi0 + } + if v == 1 { + return Yi1 + } + if v >= -128 && v <= 127 { + return Yi8 + } + l = int32(v) + if int64(l) == v { + return Ys32 /* can sign extend */ + } + if v>>32 == 0 { + return Yi32 /* unsigned */ + } + return Yi64 + + case obj.TYPE_TEXTSIZE: + return Ytextsize } - switch a.Type { - case D_AL: + if a.Type != obj.TYPE_REG { + ctxt.Diag("unexpected addr1: type=%d %v", a.Type, Dconv(p, 0, a)) + return Yxxx + } + + switch a.Reg { + case REG_AL: return Yal - case D_AX: + case REG_AX: return Yax /* - case D_SPB: + case REG_SPB: */ - case D_BPB, - D_SIB, - D_DIB, - D_R8B, - D_R9B, - D_R10B, - D_R11B, - D_R12B, - D_R13B, - D_R14B, - D_R15B: + case REG_BPB, + REG_SIB, + REG_DIB, + REG_R8B, + REG_R9B, + REG_R10B, + REG_R11B, + REG_R12B, + REG_R13B, + REG_R14B, + REG_R15B: if ctxt.Asmode != 64 { - return Yxxx } fallthrough - case D_DL, - D_BL, - D_AH, - D_CH, - D_DH, - D_BH: + case REG_DL, + REG_BL, + REG_AH, + REG_CH, + REG_DH, + REG_BH: return Yrb - case D_CL: + case REG_CL: return Ycl - case D_CX: + case REG_CX: return Ycx - case D_DX, - D_BX: + case REG_DX, + REG_BX: return Yrx - case D_R8, /* not really Yrl */ - D_R9, - D_R10, - D_R11, - D_R12, - D_R13, - D_R14, - D_R15: + case REG_R8, /* not really Yrl */ + REG_R9, + REG_R10, + REG_R11, + REG_R12, + REG_R13, + REG_R14, + REG_R15: if ctxt.Asmode != 64 { - return Yxxx } fallthrough - case D_SP, - D_BP, - D_SI, - D_DI: + case REG_SP, + REG_BP, + REG_SI, + REG_DI: return Yrl - case D_F0 + 0: + case REG_F0 + 0: return Yf0 - case D_F0 + 1, - D_F0 + 2, - D_F0 + 3, - D_F0 + 4, - D_F0 + 5, - D_F0 + 6, - D_F0 + 7: + 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 D_M0 + 0, - D_M0 + 1, - D_M0 + 2, - D_M0 + 3, - D_M0 + 4, - D_M0 + 5, - D_M0 + 6, - D_M0 + 7: + case REG_M0 + 0, + REG_M0 + 1, + REG_M0 + 2, + REG_M0 + 3, + REG_M0 + 4, + REG_M0 + 5, + REG_M0 + 6, + REG_M0 + 7: return Ymr - case D_X0 + 0, - D_X0 + 1, - D_X0 + 2, - D_X0 + 3, - D_X0 + 4, - D_X0 + 5, - D_X0 + 6, - D_X0 + 7, - D_X0 + 8, - D_X0 + 9, - D_X0 + 10, - D_X0 + 11, - D_X0 + 12, - D_X0 + 13, - D_X0 + 14, - D_X0 + 15: + 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, + REG_X0 + 8, + REG_X0 + 9, + REG_X0 + 10, + REG_X0 + 11, + REG_X0 + 12, + REG_X0 + 13, + REG_X0 + 14, + REG_X0 + 15: return Yxr - case D_NONE: - return Ynone - - case D_CS: + case REG_CS: return Ycs - case D_SS: + case REG_SS: return Yss - case D_DS: + case REG_DS: return Yds - case D_ES: + case REG_ES: return Yes - case D_FS: + case REG_FS: return Yfs - case D_GS: + case REG_GS: return Ygs - case D_TLS: + case REG_TLS: return Ytls - case D_GDTR: + case REG_GDTR: return Ygdtr - case D_IDTR: + case REG_IDTR: return Yidtr - case D_LDTR: + case REG_LDTR: return Yldtr - case D_MSW: + case REG_MSW: return Ymsw - case D_TASK: + case REG_TASK: return Ytask - case D_CR + 0: + case REG_CR + 0: return Ycr0 - case D_CR + 1: + case REG_CR + 1: return Ycr1 - case D_CR + 2: + case REG_CR + 2: return Ycr2 - case D_CR + 3: + case REG_CR + 3: return Ycr3 - case D_CR + 4: + case REG_CR + 4: return Ycr4 - case D_CR + 5: + case REG_CR + 5: return Ycr5 - case D_CR + 6: + case REG_CR + 6: return Ycr6 - case D_CR + 7: + case REG_CR + 7: return Ycr7 - case D_CR + 8: + case REG_CR + 8: return Ycr8 - case D_DR + 0: + case REG_DR + 0: return Ydr0 - case D_DR + 1: + case REG_DR + 1: return Ydr1 - case D_DR + 2: + case REG_DR + 2: return Ydr2 - case D_DR + 3: + case REG_DR + 3: return Ydr3 - case D_DR + 4: + case REG_DR + 4: return Ydr4 - case D_DR + 5: + case REG_DR + 5: return Ydr5 - case D_DR + 6: + case REG_DR + 6: return Ydr6 - case D_DR + 7: + case REG_DR + 7: return Ydr7 - case D_TR + 0: + case REG_TR + 0: return Ytr0 - case D_TR + 1: + case REG_TR + 1: return Ytr1 - case D_TR + 2: + case REG_TR + 2: return Ytr2 - case D_TR + 3: + case REG_TR + 3: return Ytr3 - case D_TR + 4: + case REG_TR + 4: return Ytr4 - case D_TR + 5: + case REG_TR + 5: return Ytr5 - case D_TR + 6: + case REG_TR + 6: return Ytr6 - case D_TR + 7: + case REG_TR + 7: return Ytr7 - - case D_EXTERN, - D_STATIC, - D_AUTO, - D_PARAM: - return Ym - - case D_CONST, - D_ADDR: - if a.Sym == nil { - v = a.Offset - if v == 0 { - return Yi0 - } - if v == 1 { - return Yi1 - } - if v >= -128 && v <= 127 { - return Yi8 - } - l = int32(v) - if int64(l) == v { - return Ys32 /* can sign extend */ - } - if v>>32 == 0 { - return Yi32 /* unsigned */ - } - return Yi64 - } - - return Yi32 - - case D_BRANCH: - return Ybr } return Yxxx @@ -2841,30 +2839,30 @@ func asmidx(ctxt *obj.Link, scale int, index int, base int) { default: goto bad - case D_NONE: + case REG_NONE: i = 4 << 3 goto bas - case D_R8, - D_R9, - D_R10, - D_R11, - D_R12, - D_R13, - D_R14, - D_R15: + case REG_R8, + REG_R9, + REG_R10, + REG_R11, + REG_R12, + REG_R13, + REG_R14, + REG_R15: if ctxt.Asmode != 64 { goto bad } fallthrough - case D_AX, - D_CX, - D_DX, - D_BX, - D_BP, - D_SI, - D_DI: + case REG_AX, + REG_CX, + REG_DX, + REG_BX, + REG_BP, + REG_SI, + REG_DI: i = reg[index] << 3 break } @@ -2892,30 +2890,30 @@ bas: default: goto bad - case D_NONE: /* must be mod=00 */ + case REG_NONE: /* must be mod=00 */ i |= 5 - case D_R8, - D_R9, - D_R10, - D_R11, - D_R12, - D_R13, - D_R14, - D_R15: + case REG_R8, + REG_R9, + REG_R10, + REG_R11, + REG_R12, + REG_R13, + REG_R14, + REG_R15: if ctxt.Asmode != 64 { goto bad } fallthrough - case D_AX, - D_CX, - D_DX, - D_BX, - D_SP, - D_BP, - D_SI, - D_DI: + case REG_AX, + REG_CX, + REG_DX, + REG_BX, + REG_SP, + REG_BP, + REG_SI, + REG_DI: i |= reg[base] break } @@ -2987,23 +2985,15 @@ relput8(Prog *p, Addr *a) } */ func vaddr(ctxt *obj.Link, p *obj.Prog, a *obj.Addr, r *obj.Reloc) int64 { - - var t int - var v int64 var s *obj.LSym if r != nil { *r = obj.Reloc{} } - t = int(a.Type) - v = a.Offset - if t == D_ADDR { - t = int(a.Index) - } - switch t { - case D_STATIC, - D_EXTERN: + switch a.Name { + case obj.NAME_STATIC, + obj.NAME_EXTERN: s = a.Sym if r == nil { ctxt.Diag("need reloc for %v", Dconv(p, 0, a)) @@ -3014,22 +3004,23 @@ func vaddr(ctxt *obj.Link, p *obj.Prog, a *obj.Addr, r *obj.Reloc) int64 { r.Siz = 4 r.Type = obj.R_ADDR } else { - r.Siz = 4 r.Type = obj.R_PCREL } r.Off = -1 // caller must fill in r.Sym = s - r.Add = v - v = 0 + r.Add = a.Offset if s.Type == obj.STLSBSS { r.Xadd = r.Add - int64(r.Siz) r.Type = obj.R_TLS r.Xsym = s } - case D_INDIR + D_TLS: + return 0 + } + + if (a.Type == obj.TYPE_MEM || a.Type == obj.TYPE_ADDR) && a.Reg == REG_TLS { if r == nil { ctxt.Diag("need reloc for %v", Dconv(p, 0, a)) log.Fatalf("reloc") @@ -3038,66 +3029,85 @@ func vaddr(ctxt *obj.Link, p *obj.Prog, a *obj.Addr, r *obj.Reloc) int64 { r.Type = obj.R_TLS_LE r.Siz = 4 r.Off = -1 // caller must fill in - r.Add = v - v = 0 - break + r.Add = a.Offset + return 0 } - return v + return a.Offset } func asmandsz(ctxt *obj.Link, p *obj.Prog, a *obj.Addr, r int, rex int, m64 int) { var v int32 - var t int - var scale int + var base int var rel obj.Reloc rex &= 0x40 | Rxr v = int32(a.Offset) - t = int(a.Type) rel.Siz = 0 - if a.Index != D_NONE && a.Index != D_TLS { - if t < D_INDIR { - switch t { - default: - goto bad - case D_EXTERN, - D_STATIC: - if !(isextern(a.Sym) != 0) { - goto bad - } - t = D_NONE - v = int32(vaddr(ctxt, p, a, &rel)) + 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 D_AUTO, - D_PARAM: - t = D_SP - break + case obj.TYPE_REG: + if a.Reg < REG_AL || REG_X0+15 < 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:] + ctxt.Rexflag |= regrex[a.Reg]&(0x40|Rxb) | rex + 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: + if !(isextern(a.Sym) != 0) { + goto bad } - } else { + base = REG_NONE + v = int32(vaddr(ctxt, p, a, &rel)) - t -= D_INDIR + case obj.NAME_AUTO, + obj.NAME_PARAM: + base = REG_SP + break } - ctxt.Rexflag |= regrex[int(a.Index)]&Rxx | regrex[t]&Rxb | rex - if t == D_NONE { + + ctxt.Rexflag |= regrex[int(a.Index)]&Rxx | regrex[base]&Rxb | rex + 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), t) + asmidx(ctxt, int(a.Scale), int(a.Index), base) goto putrelv } - if v == 0 && rel.Siz == 0 && t != D_BP && t != D_R13 { + if v == 0 && rel.Siz == 0 && base != REG_BP && base != REG_R13 { ctxt.Andptr[0] = byte(0<<6 | 4<<0 | r<<3) ctxt.Andptr = ctxt.Andptr[1:] - asmidx(ctxt, int(a.Scale), int(a.Index), t) + 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), t) + asmidx(ctxt, int(a.Scale), int(a.Index), base) ctxt.Andptr[0] = byte(v) ctxt.Andptr = ctxt.Andptr[1:] return @@ -3105,49 +3115,33 @@ func asmandsz(ctxt *obj.Link, p *obj.Prog, a *obj.Addr, r int, rex int, m64 int) ctxt.Andptr[0] = byte(2<<6 | 4<<0 | r<<3) ctxt.Andptr = ctxt.Andptr[1:] - asmidx(ctxt, int(a.Scale), int(a.Index), t) + asmidx(ctxt, int(a.Scale), int(a.Index), base) goto putrelv } - if t >= D_AL && t <= D_X0+15 { - if v != 0 { - goto bad - } - ctxt.Andptr[0] = byte(3<<6 | reg[t]<<0 | r<<3) - ctxt.Andptr = ctxt.Andptr[1:] - ctxt.Rexflag |= regrex[t]&(0x40|Rxb) | rex - return - } - - scale = int(a.Scale) - if t < D_INDIR { - switch a.Type { - default: - goto bad - - case D_STATIC, - D_EXTERN: - t = D_NONE - v = int32(vaddr(ctxt, p, a, &rel)) - - case D_AUTO, - D_PARAM: - t = D_SP - break + base = int(a.Reg) + switch a.Name { + case obj.NAME_STATIC, + obj.NAME_EXTERN: + if a.Sym == nil { + ctxt.Diag("bad addr: %v", p) } + base = REG_NONE + v = int32(vaddr(ctxt, p, a, &rel)) - scale = 1 - } else { - - t -= D_INDIR + case obj.NAME_AUTO, + obj.NAME_PARAM: + base = REG_SP + break } - if t == D_TLS { + + if base == REG_TLS { v = int32(vaddr(ctxt, p, a, &rel)) } - ctxt.Rexflag |= regrex[t]&Rxb | rex - if t == D_NONE || (D_CS <= t && t <= D_GS) || t == D_TLS { - if (a.Sym == nil || !(isextern(a.Sym) != 0)) && t == D_NONE && (a.Type == D_STATIC || a.Type == D_EXTERN) || ctxt.Asmode != 64 { + ctxt.Rexflag |= regrex[base]&Rxb | rex + if base == REG_NONE || (REG_CS <= base && base <= REG_GS) || base == REG_TLS { + if (a.Sym == nil || !(isextern(a.Sym) != 0)) && base == REG_NONE && (a.Name == obj.NAME_STATIC || a.Name == obj.NAME_EXTERN) || ctxt.Asmode != 64 { ctxt.Andptr[0] = byte(0<<6 | 5<<0 | r<<3) ctxt.Andptr = ctxt.Andptr[1:] goto putrelv @@ -3161,31 +3155,31 @@ func asmandsz(ctxt *obj.Link, p *obj.Prog, a *obj.Addr, r int, rex int, m64 int) goto putrelv } - if t == D_SP || t == D_R12 { + if base == REG_SP || base == REG_R12 { if v == 0 { - ctxt.Andptr[0] = byte(0<<6 | reg[t]<<0 | r<<3) + ctxt.Andptr[0] = byte(0<<6 | reg[base]<<0 | r<<3) ctxt.Andptr = ctxt.Andptr[1:] - asmidx(ctxt, scale, D_NONE, t) + asmidx(ctxt, int(a.Scale), REG_NONE, base) return } if v >= -128 && v < 128 { - ctxt.Andptr[0] = byte(1<<6 | reg[t]<<0 | r<<3) + ctxt.Andptr[0] = byte(1<<6 | reg[base]<<0 | r<<3) ctxt.Andptr = ctxt.Andptr[1:] - asmidx(ctxt, scale, D_NONE, t) + 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 | reg[t]<<0 | r<<3) + ctxt.Andptr[0] = byte(2<<6 | reg[base]<<0 | r<<3) ctxt.Andptr = ctxt.Andptr[1:] - asmidx(ctxt, scale, D_NONE, t) + asmidx(ctxt, int(a.Scale), REG_NONE, base) goto putrelv } - if t >= D_AX && t <= D_R15 { - if a.Index == D_TLS { + if REG_AX <= base && base <= REG_R15 { + if a.Index == REG_TLS { rel = obj.Reloc{} rel.Type = obj.R_TLS_IE rel.Siz = 4 @@ -3194,20 +3188,20 @@ func asmandsz(ctxt *obj.Link, p *obj.Prog, a *obj.Addr, r int, rex int, m64 int) v = 0 } - if v == 0 && rel.Siz == 0 && t != D_BP && t != D_R13 { - ctxt.Andptr[0] = byte(0<<6 | reg[t]<<0 | r<<3) + if v == 0 && rel.Siz == 0 && base != REG_BP && base != REG_R13 { + 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[t]<<0 | r<<3) + 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[t]<<0 | r<<3) + ctxt.Andptr[0] = byte(2<<6 | reg[base]<<0 | r<<3) ctxt.Andptr = ctxt.Andptr[1:] goto putrelv } @@ -3237,7 +3231,7 @@ bad: } func asmand(ctxt *obj.Link, p *obj.Prog, a *obj.Addr, ra *obj.Addr) { - asmandsz(ctxt, p, a, reg[ra.Type], regrex[ra.Type], 0) + asmandsz(ctxt, p, a, reg[ra.Reg], regrex[ra.Reg], 0) } func asmando(ctxt *obj.Link, p *obj.Prog, a *obj.Addr, o int) { @@ -3245,8 +3239,8 @@ func asmando(ctxt *obj.Link, p *obj.Prog, a *obj.Addr, o int) { } func bytereg(a *obj.Addr, t *uint8) { - if a.Index == D_NONE && (a.Type >= D_AX && a.Type <= D_R15) { - a.Type = D_AL + (a.Type - D_AX) + if a.Type == obj.TYPE_REG && a.Index == REG_NONE && (REG_AX <= a.Reg && a.Reg <= REG_R15) { + a.Reg += REG_AL - REG_AX *t = 0 } } @@ -3382,48 +3376,45 @@ var ymovtab = []Movtab{ } func isax(a *obj.Addr) int { - switch a.Type { - case D_AX, - D_AL, - D_AH, - D_INDIR + D_AX: + switch a.Reg { + case REG_AX, + REG_AL, + REG_AH: return 1 } - if a.Index == D_AX { + if a.Index == REG_AX { return 1 } return 0 } func subreg(p *obj.Prog, from int, to int) { - if false { /*debug['Q']*/ + if false { /* debug['Q'] */ fmt.Printf("\n%v\ts/%v/%v/\n", p, Rconv(from), Rconv(to)) } - if int(p.From.Type) == from { - p.From.Type = int16(to) + if int(p.From.Reg) == from { + p.From.Reg = int16(to) + p.Ft = 0 } - if int(p.To.Type) == from { - p.To.Type = int16(to) + + if int(p.To.Reg) == from { + p.To.Reg = int16(to) + p.Tt = 0 } if int(p.From.Index) == from { - p.From.Index = uint8(to) - } - if int(p.To.Index) == from { - p.To.Index = uint8(to) + p.From.Index = int16(to) + p.Ft = 0 } - from += D_INDIR - if int(p.From.Type) == from { - p.From.Type = int16(to + D_INDIR) - } - if int(p.To.Type) == from { - p.To.Type = int16(to + D_INDIR) + if int(p.To.Index) == from { + p.To.Index = int16(to) + p.Tt = 0 } - if false { /*debug['Q']*/ + if false { /* debug['Q'] */ fmt.Printf("%v\n", p) } } @@ -3499,10 +3490,10 @@ func doasm(ctxt *obj.Link, p *obj.Prog) { } if p.Ft == 0 { - p.Ft = uint8(oclass(ctxt, &p.From)) + p.Ft = uint8(oclass(ctxt, p, &p.From)) } if p.Tt == 0 { - p.Tt = uint8(oclass(ctxt, &p.To)) + p.Tt = uint8(oclass(ctxt, p, &p.To)) } ft = int(p.Ft) * Ymax @@ -3560,7 +3551,6 @@ found: case Pw: /* 64-bit escape */ if p.Mode != 64 { - ctxt.Diag("asmins: illegal 64: %v", p) } ctxt.Rexflag |= Pw @@ -3572,13 +3562,11 @@ found: case P32: /* 32 bit but illegal if 64-bit mode */ if p.Mode == 64 { - ctxt.Diag("asmins: illegal in 64-bit mode: %v", p) } case Py: /* 64-bit only, no prefix */ if p.Mode != 64 { - ctxt.Diag("asmins: illegal in %d-bit mode: %v", p.Mode, p) } break @@ -3684,14 +3672,12 @@ found: case Zaut_r: ctxt.Andptr[0] = 0x8d ctxt.Andptr = ctxt.Andptr[1:] /* leal */ - if p.From.Type != D_ADDR { + if p.From.Type != obj.TYPE_ADDR { ctxt.Diag("asmins: Zaut sb type ADDR") } - p.From.Type = int16(p.From.Index) - p.From.Index = D_NONE + p.From.Type = obj.TYPE_MEM asmand(ctxt, p, &p.From, &p.To) - p.From.Index = uint8(p.From.Type) - p.From.Type = D_ADDR + p.From.Type = obj.TYPE_ADDR case Zm_o: ctxt.Andptr[0] = byte(op) @@ -3762,7 +3748,6 @@ found: if t[2] == Zib_ { a = &p.From } else { - a = &p.To } ctxt.Andptr[0] = byte(op) @@ -3771,15 +3756,15 @@ found: ctxt.Andptr = ctxt.Andptr[1:] case Zib_rp: - ctxt.Rexflag |= regrex[p.To.Type] & (Rxb | 0x40) - ctxt.Andptr[0] = byte(op + reg[p.To.Type]) + ctxt.Rexflag |= regrex[p.To.Reg] & (Rxb | 0x40) + 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.Rexflag |= regrex[p.To.Type] & Rxb - ctxt.Andptr[0] = byte(op + reg[p.To.Type]) + ctxt.Rexflag |= regrex[p.To.Reg] & Rxb + 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) @@ -3788,14 +3773,13 @@ found: ctxt.Andptr[0] = byte(v >> 8) ctxt.Andptr = ctxt.Andptr[1:] } else { - relput4(ctxt, p, &p.From) } case Zo_iw: ctxt.Andptr[0] = byte(op) ctxt.Andptr = ctxt.Andptr[1:] - if p.From.Type != D_NONE { + if p.From.Type != obj.TYPE_NONE { v = vaddr(ctxt, p, &p.From, nil) ctxt.Andptr[0] = byte(v) ctxt.Andptr = ctxt.Andptr[1:] @@ -3811,8 +3795,8 @@ found: //print("zero: %llux %P\n", v, p); ctxt.Rexflag &^= (0x40 | Rxw) - ctxt.Rexflag |= regrex[p.To.Type] & Rxb - ctxt.Andptr[0] = byte(0xb8 + reg[p.To.Type]) + ctxt.Rexflag |= regrex[p.To.Reg] & Rxb + ctxt.Andptr[0] = byte(0xb8 + reg[p.To.Reg]) ctxt.Andptr = ctxt.Andptr[1:] if rel.Type != 0 { r = obj.Addrel(ctxt.Cursym) @@ -3831,11 +3815,10 @@ found: asmando(ctxt, p, &p.To, 0) put4(ctxt, int32(v)) /* need all 8 */ } else { - //print("all: %llux %P\n", v, p); - ctxt.Rexflag |= regrex[p.To.Type] & Rxb + ctxt.Rexflag |= regrex[p.To.Reg] & Rxb - ctxt.Andptr[0] = byte(op + reg[p.To.Type]) + ctxt.Andptr[0] = byte(op + reg[p.To.Reg]) ctxt.Andptr = ctxt.Andptr[1:] if rel.Type != 0 { r = obj.Addrel(ctxt.Cursym) @@ -3858,7 +3841,6 @@ found: if t[2] == Zil_ { a = &p.From } else { - a = &p.To } ctxt.Andptr[0] = byte(op) @@ -3870,7 +3852,6 @@ found: ctxt.Andptr[0] = byte(v >> 8) ctxt.Andptr = ctxt.Andptr[1:] } else { - relput4(ctxt, p, a) } @@ -3882,7 +3863,6 @@ found: a = &p.From asmando(ctxt, p, &p.To, int(o.op[z+1])) } else { - a = &p.To asmando(ctxt, p, &p.From, int(o.op[z+1])) } @@ -3894,7 +3874,6 @@ found: ctxt.Andptr[0] = byte(v >> 8) ctxt.Andptr = ctxt.Andptr[1:] } else { - relput4(ctxt, p, a) } @@ -3909,18 +3888,17 @@ found: ctxt.Andptr[0] = byte(v >> 8) ctxt.Andptr = ctxt.Andptr[1:] } else { - relput4(ctxt, p, &p.From) } case Z_rp: - ctxt.Rexflag |= regrex[p.To.Type] & (Rxb | 0x40) - ctxt.Andptr[0] = byte(op + reg[p.To.Type]) + ctxt.Rexflag |= regrex[p.To.Reg] & (Rxb | 0x40) + ctxt.Andptr[0] = byte(op + reg[p.To.Reg]) ctxt.Andptr = ctxt.Andptr[1:] case Zrp_: - ctxt.Rexflag |= regrex[p.From.Type] & (Rxb | 0x40) - ctxt.Andptr[0] = byte(op + reg[p.From.Type]) + ctxt.Rexflag |= regrex[p.From.Reg] & (Rxb | 0x40) + ctxt.Andptr[0] = byte(op + reg[p.From.Reg]) ctxt.Andptr = ctxt.Andptr[1:] case Zclr: @@ -3950,7 +3928,6 @@ found: Zjmp, Zloop: if p.To.Sym != nil { - if t[2] != Zjmp { ctxt.Diag("branch to ATEXT") log.Fatalf("bad code") @@ -3992,7 +3969,6 @@ found: } else if t[2] == Zloop { ctxt.Diag("loop too far: %v", p) } else { - v -= 5 - 2 if t[2] == Zbr { ctxt.Andptr[0] = 0x0f @@ -4031,7 +4007,6 @@ found: } else if t[2] == Zloop { ctxt.Diag("loop too far: %v", p) } else { - if t[2] == Zbr { ctxt.Andptr[0] = 0x0f ctxt.Andptr = ctxt.Andptr[1:] @@ -4129,24 +4104,23 @@ bad: */ pp = *p - z = int(p.From.Type) - if z >= D_BP && z <= D_DI { - if isax(&p.To) != 0 || p.To.Type == D_NONE { + z = int(p.From.Reg) + if p.From.Type == obj.TYPE_REG && z >= REG_BP && z <= REG_DI { + if isax(&p.To) != 0 || p.To.Type == obj.TYPE_NONE { // We certainly don't want to exchange // with AX if the op is MUL or DIV. ctxt.Andptr[0] = 0x87 ctxt.Andptr = ctxt.Andptr[1:] /* xchg lhs,bx */ - asmando(ctxt, p, &p.From, reg[D_BX]) - subreg(&pp, z, D_BX) + asmando(ctxt, p, &p.From, reg[REG_BX]) + subreg(&pp, z, REG_BX) doasm(ctxt, &pp) ctxt.Andptr[0] = 0x87 ctxt.Andptr = ctxt.Andptr[1:] /* xchg lhs,bx */ - asmando(ctxt, p, &p.From, reg[D_BX]) + asmando(ctxt, p, &p.From, reg[REG_BX]) } else { - ctxt.Andptr[0] = byte(0x90 + reg[z]) ctxt.Andptr = ctxt.Andptr[1:] /* xchg lsh,ax */ - subreg(&pp, z, D_AX) + subreg(&pp, z, REG_AX) doasm(ctxt, &pp) ctxt.Andptr[0] = byte(0x90 + reg[z]) ctxt.Andptr = ctxt.Andptr[1:] /* xchg lsh,ax */ @@ -4155,22 +4129,21 @@ bad: return } - z = int(p.To.Type) - if z >= D_BP && z <= D_DI { + z = int(p.To.Reg) + if p.To.Type == obj.TYPE_REG && z >= REG_BP && z <= REG_DI { if isax(&p.From) != 0 { ctxt.Andptr[0] = 0x87 ctxt.Andptr = ctxt.Andptr[1:] /* xchg rhs,bx */ - asmando(ctxt, p, &p.To, reg[D_BX]) - subreg(&pp, z, D_BX) + asmando(ctxt, p, &p.To, reg[REG_BX]) + subreg(&pp, z, REG_BX) doasm(ctxt, &pp) ctxt.Andptr[0] = 0x87 ctxt.Andptr = ctxt.Andptr[1:] /* xchg rhs,bx */ - asmando(ctxt, p, &p.To, reg[D_BX]) + asmando(ctxt, p, &p.To, reg[REG_BX]) } else { - ctxt.Andptr[0] = byte(0x90 + reg[z]) ctxt.Andptr = ctxt.Andptr[1:] /* xchg rsh,ax */ - subreg(&pp, z, D_AX) + subreg(&pp, z, REG_AX) doasm(ctxt, &pp) ctxt.Andptr[0] = byte(0x90 + reg[z]) ctxt.Andptr = ctxt.Andptr[1:] /* xchg rsh,ax */ @@ -4180,7 +4153,7 @@ bad: } } - ctxt.Diag("doasm: notfound from=%x to=%x %v", uint16(p.From.Type), uint16(p.To.Type), p) + ctxt.Diag("doasm: notfound ft=%d tt=%d %v %d %d", p.Ft, p.Tt, p, oclass(ctxt, p, &p.From), oclass(ctxt, p, &p.To)) return mfound: @@ -4190,7 +4163,6 @@ mfound: case 0: /* lit */ for z = 0; t[z] != E; z++ { - ctxt.Andptr[0] = t[z] ctxt.Andptr = ctxt.Andptr[1:] } @@ -4214,7 +4186,7 @@ mfound: ctxt.Andptr[0] = t[1] ctxt.Andptr = ctxt.Andptr[1:] asmando(ctxt, p, &p.To, int(t[2])) - ctxt.Rexflag |= regrex[p.From.Type] & (Rxr | 0x40) + ctxt.Rexflag |= regrex[p.From.Reg] & (Rxr | 0x40) case 4: /* m,r - 2op */ ctxt.Andptr[0] = t[0] @@ -4223,11 +4195,10 @@ mfound: ctxt.Andptr[0] = t[1] ctxt.Andptr = ctxt.Andptr[1:] asmando(ctxt, p, &p.From, int(t[2])) - ctxt.Rexflag |= regrex[p.To.Type] & (Rxr | 0x40) + ctxt.Rexflag |= regrex[p.To.Reg] & (Rxr | 0x40) case 5: /* load full pointer, trash heap */ if t[0] != 0 { - ctxt.Andptr[0] = t[0] ctxt.Andptr = ctxt.Andptr[1:] } @@ -4235,27 +4206,27 @@ mfound: default: goto bad - case D_DS: + case REG_DS: ctxt.Andptr[0] = 0xc5 ctxt.Andptr = ctxt.Andptr[1:] - case D_SS: + case REG_SS: ctxt.Andptr[0] = 0x0f ctxt.Andptr = ctxt.Andptr[1:] ctxt.Andptr[0] = 0xb2 ctxt.Andptr = ctxt.Andptr[1:] - case D_ES: + case REG_ES: ctxt.Andptr[0] = 0xc4 ctxt.Andptr = ctxt.Andptr[1:] - case D_FS: + case REG_FS: ctxt.Andptr[0] = 0x0f ctxt.Andptr = ctxt.Andptr[1:] ctxt.Andptr[0] = 0xb4 ctxt.Andptr = ctxt.Andptr[1:] - case D_GS: + case REG_GS: ctxt.Andptr[0] = 0x0f ctxt.Andptr = ctxt.Andptr[1:] ctxt.Andptr[0] = 0xb5 @@ -4267,7 +4238,6 @@ mfound: case 6: /* double shift */ if t[0] == Pw { - if p.Mode != 64 { ctxt.Diag("asmins: illegal 64: %v", p) } @@ -4279,12 +4249,11 @@ mfound: t = t[1:] } - z = int(p.From.Type) - switch z { + switch p.From.Type { default: goto bad - case D_CONST: + case obj.TYPE_CONST: ctxt.Andptr[0] = 0x0f ctxt.Andptr = ctxt.Andptr[1:] ctxt.Andptr[0] = t[0] @@ -4293,14 +4262,20 @@ mfound: ctxt.Andptr[0] = byte(p.From.Offset) ctxt.Andptr = ctxt.Andptr[1:] - case D_CL, - D_CX: - ctxt.Andptr[0] = 0x0f - ctxt.Andptr = ctxt.Andptr[1:] - ctxt.Andptr[0] = t[1] - ctxt.Andptr = ctxt.Andptr[1:] - asmandsz(ctxt, p, &p.To, reg[int(p.From.Index)], regrex[int(p.From.Index)], 0) - break + 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[1] + ctxt.Andptr = ctxt.Andptr[1:] + asmandsz(ctxt, p, &p.To, reg[int(p.From.Index)], regrex[int(p.From.Index)], 0) + break + } } // NOTE: The systems listed here are the ones that use the "TLS initial exec" model, @@ -4309,7 +4284,6 @@ mfound: // are handled in prefixof above and should not be listed here. case 7: /* mov tls, r */ switch ctxt.Headtype { - default: log.Fatalf("unknown TLS base location for %s", obj.Headstr(ctxt.Headtype)) @@ -4318,10 +4292,11 @@ mfound: ctxt.Plan9privates = obj.Linklookup(ctxt, "_privates", 0) } pp.From = obj.Addr{} - pp.From.Type = D_EXTERN + pp.From.Type = obj.TYPE_MEM + pp.From.Name = obj.NAME_EXTERN pp.From.Sym = ctxt.Plan9privates pp.From.Offset = 0 - pp.From.Index = D_NONE + pp.From.Index = REG_NONE ctxt.Rexflag |= Pw ctxt.Andptr[0] = 0x8B ctxt.Andptr = ctxt.Andptr[1:] @@ -4331,9 +4306,11 @@ mfound: case obj.Hsolaris: // TODO(rsc): Delete Hsolaris from list. Should not use this code. See progedit in obj6.c. pp.From = p.From - pp.From.Type = D_INDIR + D_NONE + pp.From.Type = obj.TYPE_MEM + pp.From.Name = obj.NAME_NONE + pp.From.Reg = REG_NONE pp.From.Offset = 0 - pp.From.Index = D_NONE + pp.From.Index = REG_NONE pp.From.Scale = 0 ctxt.Rexflag |= Pw ctxt.Andptr[0] = 0x64 @@ -4346,9 +4323,11 @@ mfound: case obj.Hwindows: pp.From = p.From - pp.From.Type = D_INDIR + D_GS + pp.From.Type = obj.TYPE_MEM + pp.From.Name = obj.NAME_NONE + pp.From.Reg = REG_GS pp.From.Offset = 0x28 - pp.From.Index = D_NONE + pp.From.Index = REG_NONE pp.From.Scale = 0 ctxt.Rexflag |= Pw ctxt.Andptr[0] = 0x65 @@ -4405,11 +4384,11 @@ var naclstos = []uint8{ } func nacltrunc(ctxt *obj.Link, reg int) { - if reg >= D_R8 { + if reg >= REG_R8 { ctxt.Andptr[0] = 0x45 ctxt.Andptr = ctxt.Andptr[1:] } - reg = (reg - D_AX) & 7 + reg = (reg - REG_AX) & 7 ctxt.Andptr[0] = 0x89 ctxt.Andptr = ctxt.Andptr[1:] ctxt.Andptr[0] = byte(3<<6 | reg<<3 | reg) @@ -4427,7 +4406,7 @@ func asmins(ctxt *obj.Link, p *obj.Prog) { ctxt.Andptr = ctxt.And[:] ctxt.Asmode = int(p.Mode) - if p.As == AUSEFIELD { + if p.As == obj.AUSEFIELD { r = obj.Addrel(ctxt.Cursym) r.Off = 0 r.Siz = 0 @@ -4453,28 +4432,28 @@ func asmins(ctxt *obj.Link, p *obj.Prog) { } if p.As != ALEAQ && p.As != ALEAL { - if p.From.Index != D_NONE && p.From.Scale > 0 { + if p.From.Index != obj.TYPE_NONE && p.From.Scale > 0 { nacltrunc(ctxt, int(p.From.Index)) } - if p.To.Index != D_NONE && p.To.Scale > 0 { + if p.To.Index != obj.TYPE_NONE && p.To.Scale > 0 { nacltrunc(ctxt, int(p.To.Index)) } } switch p.As { - case ARET: + case obj.ARET: copy(ctxt.Andptr, naclret) ctxt.Andptr = ctxt.Andptr[len(naclret):] return - case ACALL, - AJMP: - if D_AX <= p.To.Type && p.To.Type <= D_DI { + case obj.ACALL, + obj.AJMP: + if p.To.Type == obj.TYPE_REG && REG_AX <= p.To.Reg && p.To.Reg <= REG_DI { // ANDL $~31, reg ctxt.Andptr[0] = 0x83 ctxt.Andptr = ctxt.Andptr[1:] - ctxt.Andptr[0] = byte(0xe0 | (p.To.Type - D_AX)) + ctxt.Andptr[0] = byte(0xe0 | (p.To.Reg - REG_AX)) ctxt.Andptr = ctxt.Andptr[1:] ctxt.Andptr[0] = 0xe0 ctxt.Andptr = ctxt.Andptr[1:] @@ -4485,18 +4464,18 @@ func asmins(ctxt *obj.Link, p *obj.Prog) { ctxt.Andptr[0] = 0x01 ctxt.Andptr = ctxt.Andptr[1:] - ctxt.Andptr[0] = byte(0xf8 | (p.To.Type - D_AX)) + ctxt.Andptr[0] = byte(0xf8 | (p.To.Reg - REG_AX)) ctxt.Andptr = ctxt.Andptr[1:] } - if D_R8 <= p.To.Type && p.To.Type <= D_R15 { + if p.To.Type == obj.TYPE_REG && REG_R8 <= p.To.Reg && p.To.Reg <= REG_R15 { // ANDL $~31, reg ctxt.Andptr[0] = 0x41 ctxt.Andptr = ctxt.Andptr[1:] ctxt.Andptr[0] = 0x83 ctxt.Andptr = ctxt.Andptr[1:] - ctxt.Andptr[0] = byte(0xe0 | (p.To.Type - D_R8)) + ctxt.Andptr[0] = byte(0xe0 | (p.To.Reg - REG_R8)) ctxt.Andptr = ctxt.Andptr[1:] ctxt.Andptr[0] = 0xe0 ctxt.Andptr = ctxt.Andptr[1:] @@ -4507,7 +4486,7 @@ func asmins(ctxt *obj.Link, p *obj.Prog) { ctxt.Andptr[0] = 0x01 ctxt.Andptr = ctxt.Andptr[1:] - ctxt.Andptr[0] = byte(0xf8 | (p.To.Type - D_R8)) + ctxt.Andptr[0] = byte(0xf8 | (p.To.Reg - REG_R8)) ctxt.Andptr = ctxt.Andptr[1:] } @@ -4568,7 +4547,6 @@ func asmins(ctxt *obj.Link, p *obj.Prog) { * note that the handbook often misleadingly shows 66/f2/f3 in `opcode'. */ if p.Mode != 64 { - ctxt.Diag("asmins: illegal in mode %d: %v", p.Mode, p) } n = -cap(ctxt.Andptr) + cap(and0) @@ -4598,13 +4576,13 @@ func asmins(ctxt *obj.Link, p *obj.Prog) { } } - if ctxt.Headtype == obj.Hnacl && p.As != ACMPL && p.As != ACMPQ { - switch p.To.Type { - case D_SP: + if ctxt.Headtype == obj.Hnacl && p.As != ACMPL && p.As != ACMPQ && p.To.Type == obj.TYPE_REG { + switch p.To.Reg { + case REG_SP: copy(ctxt.Andptr, naclspfix) ctxt.Andptr = ctxt.Andptr[len(naclspfix):] - case D_BP: + case REG_BP: copy(ctxt.Andptr, naclbpfix) ctxt.Andptr = ctxt.Andptr[len(naclbpfix):] break diff --git a/src/cmd/internal/obj/x86/list6.go b/src/cmd/internal/obj/x86/list6.go index df061c75e2..c782f6387a 100644 --- a/src/cmd/internal/obj/x86/list6.go +++ b/src/cmd/internal/obj/x86/list6.go @@ -40,7 +40,6 @@ import ( // %A int Opcodes (instruction mnemonics) // // %D Addr* Addresses (instruction operands) -// Flags: "%lD": seperate the high and low words of a constant by "-" // // %P Prog* Instructions // @@ -59,16 +58,16 @@ func Pconv(p *obj.Prog) string { var fp string switch p.As { - case ADATA: - str = fmt.Sprintf("%.5d (%v)\t%v\t%v/%d,%v", p.Pc, p.Line(), Aconv(int(p.As)), Dconv(p, 0, &p.From), p.From.Scale, Dconv(p, 0, &p.To)) + case obj.ADATA: + str = fmt.Sprintf("%.5d (%v)\t%v\t%v/%d,%v", p.Pc, p.Line(), Aconv(int(p.As)), Dconv(p, 0, &p.From), p.From3.Offset, Dconv(p, 0, &p.To)) - case ATEXT: - if p.From.Scale != 0 { - str = fmt.Sprintf("%.5d (%v)\t%v\t%v,%d,%v", p.Pc, p.Line(), Aconv(int(p.As)), Dconv(p, 0, &p.From), p.From.Scale, Dconv(p, fmtLong, &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(), Aconv(int(p.As)), Dconv(p, 0, &p.From), p.From3.Offset, Dconv(p, 0, &p.To)) break } - str = fmt.Sprintf("%.5d (%v)\t%v\t%v,%v", p.Pc, p.Line(), Aconv(int(p.As)), Dconv(p, 0, &p.From), Dconv(p, fmtLong, &p.To)) + str = fmt.Sprintf("%.5d (%v)\t%v\t%v,%v", p.Pc, p.Line(), Aconv(int(p.As)), Dconv(p, 0, &p.From), Dconv(p, 0, &p.To)) default: str = fmt.Sprintf("%.5d (%v)\t%v\t%v,%v", p.Pc, p.Line(), Aconv(int(p.As)), Dconv(p, 0, &p.From), Dconv(p, 0, &p.To)) @@ -91,45 +90,26 @@ func Dconv(p *obj.Prog, flag int, a *obj.Addr) string { var s string var fp string - var i int - - i = int(a.Type) - - if flag&fmtLong != 0 /*untyped*/ { - if i == D_CONST { - str = fmt.Sprintf("$%d-%d", a.Offset&0xffffffff, a.Offset>>32) - } else { - - // ATEXT dst is not constant - str = fmt.Sprintf("!!%v", Dconv(p, 0, a)) - } - - goto brk - } - - if i >= D_INDIR { - if a.Offset != 0 { - str = fmt.Sprintf("%d(%v)", a.Offset, Rconv(i-D_INDIR)) - } else { + switch a.Type { + default: + str = fmt.Sprintf("type=%d", a.Type) - str = fmt.Sprintf("(%v)", Rconv(i-D_INDIR)) - } - goto brk - } + case obj.TYPE_NONE: + str = "" - switch i { - default: + // TODO(rsc): This special case is for instructions like + // PINSRQ CX,$1,X6 + // where the $1 is included in the p->to Addr. + // Move into a new field. + case obj.TYPE_REG: if a.Offset != 0 { - str = fmt.Sprintf("$%d,%v", a.Offset, Rconv(i)) - } else { - - str = fmt.Sprintf("%v", Rconv(i)) + str = fmt.Sprintf("$%d,%v", a.Offset, Rconv(int(a.Reg))) + break } - case D_NONE: - str = "" + str = fmt.Sprintf("%v", Rconv(int(a.Reg))) - case D_BRANCH: + case obj.TYPE_BRANCH: if a.Sym != nil { str = fmt.Sprintf("%s(SB)", a.Sym.Name) } else if p != nil && p.Pcond != nil { @@ -137,57 +117,79 @@ func Dconv(p *obj.Prog, flag int, a *obj.Addr) string { } else if a.U.Branch != nil { str = fmt.Sprintf("%d", a.U.Branch.Pc) } else { - str = fmt.Sprintf("%d(PC)", a.Offset) } - case D_EXTERN: - str = fmt.Sprintf("%s+%d(SB)", a.Sym.Name, a.Offset) + case obj.TYPE_MEM: + switch a.Name { + default: + str = fmt.Sprintf("name=%d", a.Name) - case D_STATIC: - str = fmt.Sprintf("%s<>+%d(SB)", a.Sym.Name, a.Offset) + case obj.NAME_NONE: + if a.Offset != 0 { + str = fmt.Sprintf("%d(%v)", a.Offset, Rconv(int(a.Reg))) + } else { + str = fmt.Sprintf("(%v)", Rconv(int(a.Reg))) + } - case D_AUTO: - if a.Sym != nil { - str = fmt.Sprintf("%s+%d(SP)", a.Sym.Name, a.Offset) - } else { + case obj.NAME_EXTERN: + str = fmt.Sprintf("%s+%d(SB)", a.Sym.Name, a.Offset) - str = fmt.Sprintf("%d(SP)", a.Offset) - } + case obj.NAME_STATIC: + str = fmt.Sprintf("%s<>+%d(SB)", a.Sym.Name, a.Offset) - case D_PARAM: - if a.Sym != nil { - str = fmt.Sprintf("%s+%d(FP)", a.Sym.Name, a.Offset) - } else { + case obj.NAME_AUTO: + if a.Sym != nil { + str = fmt.Sprintf("%s+%d(SP)", a.Sym.Name, a.Offset) + } else { + str = fmt.Sprintf("%d(SP)", a.Offset) + } - str = fmt.Sprintf("%d(FP)", a.Offset) + case obj.NAME_PARAM: + if a.Sym != nil { + str = fmt.Sprintf("%s+%d(FP)", a.Sym.Name, a.Offset) + } else { + str = fmt.Sprintf("%d(FP)", a.Offset) + } + break } - case D_CONST: + if a.Index != REG_NONE { + s = fmt.Sprintf("(%v*%d)", Rconv(int(a.Index)), int(a.Scale)) + str += s + } + + case obj.TYPE_CONST: str = fmt.Sprintf("$%d", a.Offset) - case D_FCONST: + // TODO(rsc): This special case is for SHRQ $32, AX:DX, which encodes as + // SHRQ $32(DX*0), AX + // Remove. + if a.Index != REG_NONE { + s = fmt.Sprintf("(%v*%d)", Rconv(int(a.Index)), int(a.Scale)) + str += s + } + + case obj.TYPE_TEXTSIZE: + if a.U.Argsize == obj.ArgsSizeUnknown { + str = fmt.Sprintf("$%d", a.Offset) + } else { + str = fmt.Sprintf("$%d-%d", a.Offset, a.U.Argsize) + } + + case obj.TYPE_FCONST: str = fmt.Sprintf("$(%.17g)", a.U.Dval) - case D_SCONST: + case obj.TYPE_SCONST: str = fmt.Sprintf("$\"%q\"", a.U.Sval) - case D_ADDR: - a.Type = int16(a.Index) - a.Index = D_NONE + case obj.TYPE_ADDR: + a.Type = obj.TYPE_MEM str = fmt.Sprintf("$%v", Dconv(p, 0, a)) - a.Index = uint8(a.Type) - a.Type = D_ADDR - goto conv - } - -brk: - if a.Index != D_NONE { - s = fmt.Sprintf("(%v*%d)", Rconv(int(a.Index)), int(a.Scale)) - str += s + a.Type = obj.TYPE_ADDR + break } -conv: fp += str return fp } @@ -304,18 +306,22 @@ var Register = []string{ "TR5", "TR6", "TR7", - "TLS", /* [D_TLS] */ - "NONE", /* [D_NONE] */ + "TLS", /* [D_TLS] */ + "MAXREG", /* [MAXREG] */ } func Rconv(r int) string { var str string var fp string - if r >= D_AL && r <= D_NONE { - str = fmt.Sprintf("%s", Register[r-D_AL]) - } else { + if r == REG_NONE { + fp += "NONE" + return fp + } + if REG_AL <= r && r-REG_AL < len(Register) { + str = fmt.Sprintf("%s", Register[r-REG_AL]) + } else { str = fmt.Sprintf("gok(%d)", r) } diff --git a/src/cmd/internal/obj/x86/obj6.go b/src/cmd/internal/obj/x86/obj6.go index 1b7c119c3e..b3991e4a27 100644 --- a/src/cmd/internal/obj/x86/obj6.go +++ b/src/cmd/internal/obj/x86/obj6.go @@ -38,53 +38,14 @@ import ( "math" ) -var zprg = obj.Prog{ - Back: 2, - As: AGOK, - From: obj.Addr{ - Type: D_NONE, - Index: D_NONE, - }, - To: obj.Addr{ - Type: D_NONE, - Index: D_NONE, - }, -} - func nopout(p *obj.Prog) { - p.As = ANOP - p.From.Type = D_NONE - p.To.Type = D_NONE -} - -func symtype(a *obj.Addr) int { - var t int - - t = int(a.Type) - if t == D_ADDR { - t = int(a.Index) - } - return t -} - -func isdata(p *obj.Prog) bool { - return p.As == ADATA || p.As == AGLOBL -} - -func iscall(p *obj.Prog) bool { - return p.As == ACALL -} - -func datasize(p *obj.Prog) int { - return int(p.From.Scale) -} - -func textflag(p *obj.Prog) int { - return int(p.From.Scale) -} - -func settextflag(p *obj.Prog, f int) { - p.From.Scale = int8(f) + p.As = obj.ANOP + p.From.Type = obj.TYPE_NONE + p.From.Reg = 0 + p.From.Name = 0 + p.To.Type = obj.TYPE_NONE + p.To.Reg = 0 + p.To.Name = 0 } func canuselocaltls(ctxt *obj.Link) int { @@ -136,7 +97,6 @@ func progedit(ctxt *obj.Link, p *obj.Prog) { // liblink and then finally using relocations in the linker. if canuselocaltls(ctxt) != 0 { - // Reduce TLS initial exec model to TLS local exec model. // Sequences like // MOVQ TLS, BX @@ -148,23 +108,21 @@ func progedit(ctxt *obj.Link, p *obj.Prog) { // TODO(rsc): Remove the Hsolaris special case. It exists only to // guarantee we are producing byte-identical binaries as before this code. // But it should be unnecessary. - if (p.As == AMOVQ || p.As == AMOVL) && p.From.Type == D_TLS && D_AX <= p.To.Type && p.To.Type <= D_R15 && ctxt.Headtype != obj.Hsolaris { - + if (p.As == AMOVQ || 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_R15 && ctxt.Headtype != obj.Hsolaris { nopout(p) } - if p.From.Index == D_TLS && D_INDIR+D_AX <= p.From.Type && p.From.Type <= D_INDIR+D_R15 { - p.From.Type = D_INDIR + D_TLS + if p.From.Type == obj.TYPE_MEM && p.From.Index == REG_TLS && REG_AX <= p.From.Reg && p.From.Reg <= REG_R15 { + p.From.Reg = REG_TLS p.From.Scale = 0 - p.From.Index = D_NONE + p.From.Index = REG_NONE } - if p.To.Index == D_TLS && D_INDIR+D_AX <= p.To.Type && p.To.Type <= D_INDIR+D_R15 { - p.To.Type = D_INDIR + D_TLS + if p.To.Type == obj.TYPE_MEM && p.To.Index == REG_TLS && REG_AX <= p.To.Reg && p.To.Reg <= REG_R15 { + p.To.Reg = REG_TLS p.To.Scale = 0 - p.To.Index = D_NONE + 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 // MOVQ off(TLS), BX @@ -172,28 +130,28 @@ func progedit(ctxt *obj.Link, p *obj.Prog) { // MOVQ TLS, BX // MOVQ 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 == AMOVQ || p.As == AMOVL) && p.From.Type == D_INDIR+D_TLS && D_AX <= p.To.Type && p.To.Type <= D_R15 { - + if (p.As == AMOVQ || 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_R15 { q = obj.Appendp(ctxt, p) q.As = p.As q.From = p.From - q.From.Type = D_INDIR + p.To.Type - q.From.Index = D_TLS + 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 = D_TLS - p.From.Index = D_NONE + 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.Hwindows || ctxt.Headtype == obj.Hplan9 { - - if p.From.Scale == 1 && p.From.Index == D_TLS { + if p.From.Scale == 1 && p.From.Index == REG_TLS { p.From.Scale = 2 } - if p.To.Scale == 1 && p.To.Index == D_TLS { + if p.To.Scale == 1 && p.To.Index == REG_TLS { p.To.Scale = 2 } } @@ -205,14 +163,13 @@ func progedit(ctxt *obj.Link, p *obj.Prog) { // Maintain information about code generation mode. if ctxt.Mode == 0 { - ctxt.Mode = 64 } p.Mode = int8(ctxt.Mode) switch p.As { case AMODE: - if p.From.Type == D_CONST || p.From.Type == D_INDIR+D_NONE { + if p.From.Type == obj.TYPE_CONST || (p.From.Type == obj.TYPE_MEM && p.From.Reg == REG_NONE) { switch int(p.From.Offset) { case 16, 32, @@ -226,33 +183,27 @@ func progedit(ctxt *obj.Link, p *obj.Prog) { break } - // Rewrite CALL/JMP/RET to symbol as D_BRANCH. + // Rewrite CALL/JMP/RET to symbol as TYPE_BRANCH. switch p.As { - - case ACALL, - AJMP, - ARET: - if (p.To.Type == D_EXTERN || p.To.Type == D_STATIC) && p.To.Sym != nil { - p.To.Type = D_BRANCH + 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 } break } // 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 == D_FCONST { - + if p.From.Type == obj.TYPE_FCONST { if p.From.U.Dval == 0 { - if p.To.Type >= D_X0 { - if p.To.Type <= D_X15 { - p.As = AXORPS - p.From.Type = p.To.Type - p.From.Index = p.To.Index - break - } + if p.To.Type == obj.TYPE_REG && REG_X0 <= p.To.Reg && p.To.Reg <= REG_X15 { + p.As = AXORPS + p.From = p.To + break } } } @@ -275,8 +226,7 @@ func progedit(ctxt *obj.Link, p *obj.Prog) { ADIVSS, ACOMISS, AUCOMISS: - if p.From.Type == D_FCONST { - + if p.From.Type == obj.TYPE_FCONST { var i32 uint32 var f32 float32 f32 = float32(p.From.U.Dval) @@ -289,23 +239,20 @@ func progedit(ctxt *obj.Link, p *obj.Prog) { s.Reachable = 0 } - p.From.Type = D_EXTERN + 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 == D_FCONST { - + if p.From.Type == obj.TYPE_FCONST { if p.From.U.Dval == 0 { - if p.To.Type >= D_X0 { - if p.To.Type <= D_X15 { - p.As = AXORPS - p.From.Type = p.To.Type - p.From.Index = p.To.Index - break - } + if p.To.Type == obj.TYPE_REG && REG_X0 <= p.To.Reg && p.To.Reg <= REG_X15 { + p.As = AXORPS + p.From = p.To + break } } } @@ -327,8 +274,7 @@ func progedit(ctxt *obj.Link, p *obj.Prog) { ADIVSD, ACOMISD, AUCOMISD: - if p.From.Type == D_FCONST { - + if p.From.Type == obj.TYPE_FCONST { var i64 uint64 i64 = math.Float64bits(p.From.U.Dval) literal = fmt.Sprintf("$f64.%016x", i64) @@ -339,7 +285,8 @@ func progedit(ctxt *obj.Link, p *obj.Prog) { s.Reachable = 0 } - p.From.Type = D_EXTERN + p.From.Type = obj.TYPE_MEM + p.From.Name = obj.NAME_EXTERN p.From.Sym = s p.From.Offset = 0 } @@ -353,52 +300,37 @@ func nacladdr(ctxt *obj.Link, p *obj.Prog, a *obj.Addr) { return } - if a.Type == D_BP || a.Type == D_INDIR+D_BP { + if a.Reg == REG_BP { ctxt.Diag("invalid address: %v", p) return } - if a.Type == D_INDIR+D_TLS { - a.Type = D_INDIR + D_BP - } else if a.Type == D_TLS { - a.Type = D_BP + if a.Reg == REG_TLS { + a.Reg = REG_BP } - if D_INDIR <= a.Type && a.Type <= D_INDIR+D_INDIR { - switch a.Type { + if a.Type == obj.TYPE_MEM && a.Name == obj.NAME_NONE { + switch a.Reg { // all ok - case D_INDIR + D_BP, - D_INDIR + D_SP, - D_INDIR + D_R15: + case REG_BP, + REG_SP, + REG_R15: break default: - if a.Index != D_NONE { + if a.Index != REG_NONE { ctxt.Diag("invalid address %v", p) } - a.Index = uint8(a.Type - D_INDIR) - if a.Index != D_NONE { + a.Index = a.Reg + if a.Index != REG_NONE { a.Scale = 1 } - a.Type = D_INDIR + D_R15 + a.Reg = REG_R15 break } } } -func parsetextconst(arg int64, textstksiz *int64, textarg *int64) { - *textstksiz = arg & 0xffffffff - if *textstksiz&0x80000000 != 0 { - *textstksiz = -(-*textstksiz & 0xffffffff) - } - - *textarg = (arg >> 32) & 0xffffffff - if *textarg&0x80000000 != 0 { - *textarg = 0 - } - *textarg = (*textarg + 7) &^ 7 -} - -func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) { +func preprocess(ctxt *obj.Link, cursym *obj.LSym) { var p *obj.Prog var q *obj.Prog var p1 *obj.Prog @@ -407,7 +339,7 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) { var deltasp int32 var a int var pcsize int - var textstksiz int64 + var bpsize int var textarg int64 if ctxt.Tlsg == nil { @@ -429,60 +361,70 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) { } p = cursym.Text - parsetextconst(p.To.Offset, &textstksiz, &textarg) - autoffset = int32(textstksiz) + autoffset = int32(p.To.Offset) if autoffset < 0 { autoffset = 0 } - cursym.Args = int32(p.To.Offset >> 32) - cursym.Locals = int32(textstksiz) + if obj.Framepointer_enabled != 0 && autoffset > 0 { + // Make room for to save a base pointer. If autoffset == 0, + // this might do something special like a tail jump to + // another function, so in that case we omit this. + bpsize = ctxt.Arch.Ptrsize + + autoffset += int32(bpsize) + p.To.Offset += int64(bpsize) + } else { + bpsize = 0 + } + + textarg = int64(p.To.U.Argsize) + cursym.Args = int32(textarg) + cursym.Locals = int32(p.To.Offset) - if autoffset < obj.StackSmall && !(p.From.Scale&obj.NOSPLIT != 0) { + if autoffset < obj.StackSmall && !(p.From3.Offset&obj.NOSPLIT != 0) { for q = p; q != nil; q = q.Link { - if q.As == ACALL { + if q.As == obj.ACALL { goto noleaf } - if (q.As == ADUFFCOPY || q.As == ADUFFZERO) && autoffset >= obj.StackSmall-8 { + if (q.As == obj.ADUFFCOPY || q.As == obj.ADUFFZERO) && autoffset >= obj.StackSmall-8 { goto noleaf } } - p.From.Scale |= obj.NOSPLIT + p.From3.Offset |= obj.NOSPLIT noleaf: } q = nil - if !(p.From.Scale&obj.NOSPLIT != 0) || (p.From.Scale&obj.WRAPPER != 0) { + 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 } - if !(cursym.Text.From.Scale&obj.NOSPLIT != 0) { - p = stacksplit(ctxt, p, autoffset, int32(textarg), bool2int(!(cursym.Text.From.Scale&obj.NEEDCTXT != 0)), &q) // emit split check + if !(cursym.Text.From3.Offset&obj.NOSPLIT != 0) { + p = stacksplit(ctxt, p, autoffset, int32(textarg), bool2int(!(cursym.Text.From3.Offset&obj.NEEDCTXT != 0)), &q) // emit split check } if autoffset != 0 { - if autoffset%int32(ctxt.Arch.Regsize) != 0 { ctxt.Diag("unaligned stack size %d", autoffset) } p = obj.Appendp(ctxt, p) p.As = AADJSP - p.From.Type = D_CONST + 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 = ANOP + p.As = obj.ANOP p.Spadj = int32(-ctxt.Arch.Ptrsize) p = obj.Appendp(ctxt, p) - p.As = ANOP + p.As = obj.ANOP p.Spadj = int32(ctxt.Arch.Ptrsize) } @@ -491,7 +433,31 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) { } deltasp = autoffset - if cursym.Text.From.Scale&obj.WRAPPER != 0 { + if bpsize > 0 { + // Save caller's BP + p = obj.Appendp(ctxt, p) + + p.As = AMOVQ + p.From.Type = obj.TYPE_REG + p.From.Reg = REG_BP + p.To.Type = obj.TYPE_MEM + p.To.Reg = REG_SP + p.To.Scale = 1 + p.To.Offset = int64(autoffset) - int64(bpsize) + + // Move current frame to BP + p = obj.Appendp(ctxt, p) + + p.As = ALEAQ + p.From.Type = obj.TYPE_MEM + p.From.Reg = REG_SP + p.From.Scale = 1 + p.From.Offset = int64(autoffset) - int64(bpsize) + p.To.Type = obj.TYPE_REG + p.To.Reg = REG_BP + } + + if cursym.Text.From3.Offset&obj.WRAPPER != 0 { // if(g->panic != nil && g->panic->argp == FP) g->panic->argp = bottom-of-frame // // MOVQ g_panic(CX), BX @@ -510,94 +476,111 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) { p = obj.Appendp(ctxt, p) p.As = AMOVQ - p.From.Type = D_INDIR + D_CX + p.From.Type = obj.TYPE_MEM + p.From.Reg = REG_CX p.From.Offset = 4 * int64(ctxt.Arch.Ptrsize) // G.panic - p.To.Type = D_BX + p.To.Type = obj.TYPE_REG + p.To.Reg = REG_BX if ctxt.Headtype == obj.Hnacl { p.As = AMOVL - p.From.Type = D_INDIR + D_R15 + p.From.Type = obj.TYPE_MEM + p.From.Reg = REG_R15 p.From.Scale = 1 - p.From.Index = D_CX + p.From.Index = REG_CX } p = obj.Appendp(ctxt, p) p.As = ATESTQ - p.From.Type = D_BX - p.To.Type = D_BX + p.From.Type = obj.TYPE_REG + p.From.Reg = REG_BX + p.To.Type = obj.TYPE_REG + p.To.Reg = REG_BX if ctxt.Headtype == obj.Hnacl { p.As = ATESTL } p = obj.Appendp(ctxt, p) p.As = AJEQ - p.To.Type = D_BRANCH + p.To.Type = obj.TYPE_BRANCH p1 = p p = obj.Appendp(ctxt, p) p.As = ALEAQ - p.From.Type = D_INDIR + D_SP + p.From.Type = obj.TYPE_MEM + p.From.Reg = REG_SP p.From.Offset = int64(autoffset) + 8 - p.To.Type = D_DI + p.To.Type = obj.TYPE_REG + p.To.Reg = REG_DI if ctxt.Headtype == obj.Hnacl { p.As = ALEAL } p = obj.Appendp(ctxt, p) p.As = ACMPQ - p.From.Type = D_INDIR + D_BX + p.From.Type = obj.TYPE_MEM + p.From.Reg = REG_BX p.From.Offset = 0 // Panic.argp - p.To.Type = D_DI + p.To.Type = obj.TYPE_REG + p.To.Reg = REG_DI if ctxt.Headtype == obj.Hnacl { p.As = ACMPL - p.From.Type = D_INDIR + D_R15 + p.From.Type = obj.TYPE_MEM + p.From.Reg = REG_R15 p.From.Scale = 1 - p.From.Index = D_BX + p.From.Index = REG_BX } p = obj.Appendp(ctxt, p) p.As = AJNE - p.To.Type = D_BRANCH + p.To.Type = obj.TYPE_BRANCH p2 = p p = obj.Appendp(ctxt, p) p.As = AMOVQ - p.From.Type = D_SP - p.To.Type = D_INDIR + D_BX + 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 if ctxt.Headtype == obj.Hnacl { p.As = AMOVL - p.To.Type = D_INDIR + D_R15 + p.To.Type = obj.TYPE_MEM + p.To.Reg = REG_R15 p.To.Scale = 1 - p.To.Index = D_BX + p.To.Index = REG_BX } p = obj.Appendp(ctxt, p) - p.As = ANOP + p.As = obj.ANOP p1.Pcond = p p2.Pcond = p } - if ctxt.Debugzerostack != 0 && autoffset != 0 && !(cursym.Text.From.Scale&obj.NOSPLIT != 0) { + if ctxt.Debugzerostack != 0 && autoffset != 0 && !(cursym.Text.From3.Offset&obj.NOSPLIT != 0) { // 6l -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 = AMOVQ - p.From.Type = D_SP - p.To.Type = D_DI + 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 = AMOVQ - p.From.Type = D_CONST + p.From.Type = obj.TYPE_CONST p.From.Offset = int64(autoffset) / 8 - p.To.Type = D_CX + p.To.Type = obj.TYPE_REG + p.To.Reg = REG_CX p = obj.Appendp(ctxt, p) p.As = AMOVQ - p.From.Type = D_CONST + p.From.Type = obj.TYPE_CONST p.From.Offset = 0 - p.To.Type = D_AX + p.To.Type = obj.TYPE_REG + p.To.Reg = REG_AX p = obj.Appendp(ctxt, p) p.As = AREP @@ -608,18 +591,18 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) { for ; p != nil; p = p.Link { pcsize = int(p.Mode) / 8 - a = int(p.From.Type) - if a == D_AUTO { - p.From.Offset += int64(deltasp) + a = int(p.From.Name) + if a == obj.NAME_AUTO { + p.From.Offset += int64(deltasp) - int64(bpsize) } - if a == D_PARAM { + if a == obj.NAME_PARAM { p.From.Offset += int64(deltasp) + int64(pcsize) } - a = int(p.To.Type) - if a == D_AUTO { - p.To.Offset += int64(deltasp) + a = int(p.To.Name) + if a == obj.NAME_AUTO { + p.To.Offset += int64(deltasp) - int64(bpsize) } - if a == D_PARAM { + if a == obj.NAME_PARAM { p.To.Offset += int64(deltasp) + int64(pcsize) } @@ -663,7 +646,7 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) { p.Spadj = -2 continue - case ARET: + case obj.ARET: break } @@ -672,12 +655,25 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) { } if autoffset != 0 { + if bpsize > 0 { + // Restore caller's BP + p.As = AMOVQ + + p.From.Type = obj.TYPE_MEM + p.From.Reg = REG_SP + p.From.Scale = 1 + p.From.Offset = int64(autoffset) - int64(bpsize) + p.To.Type = obj.TYPE_REG + p.To.Reg = REG_BP + p = obj.Appendp(ctxt, p) + } + p.As = AADJSP - p.From.Type = D_CONST + p.From.Type = obj.TYPE_CONST p.From.Offset = int64(-autoffset) p.Spadj = -autoffset p = obj.Appendp(ctxt, p) - p.As = ARET + p.As = obj.ARET // If there are instructions following // this ARET, they come from a branch @@ -687,20 +683,22 @@ func addstacksplit(ctxt *obj.Link, cursym *obj.LSym) { } if p.To.Sym != nil { // retjmp - p.As = AJMP + p.As = obj.AJMP } } } func indir_cx(ctxt *obj.Link, a *obj.Addr) { if ctxt.Headtype == obj.Hnacl { - a.Type = D_INDIR + D_R15 - a.Index = D_CX + a.Type = obj.TYPE_MEM + a.Reg = REG_R15 + a.Index = REG_CX a.Scale = 1 return } - a.Type = D_INDIR + D_CX + a.Type = obj.TYPE_MEM + a.Reg = REG_CX } // Append code to p to load g into cx. @@ -709,16 +707,17 @@ func indir_cx(ctxt *obj.Link, a *obj.Addr) { // 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 { - var next *obj.Prog p.As = AMOVQ if ctxt.Arch.Ptrsize == 4 { p.As = AMOVL } - p.From.Type = D_INDIR + D_TLS + p.From.Type = obj.TYPE_MEM + p.From.Reg = REG_TLS p.From.Offset = 0 - p.To.Type = D_CX + p.To.Type = obj.TYPE_REG + p.To.Reg = REG_CX next = p.Link progedit(ctxt, p) @@ -726,7 +725,7 @@ func load_g_cx(ctxt *obj.Link, p *obj.Prog) *obj.Prog { p = p.Link } - if p.From.Index == D_TLS { + if p.From.Index == REG_TLS { p.From.Scale = 2 } @@ -740,7 +739,6 @@ func load_g_cx(ctxt *obj.Link, p *obj.Prog) *obj.Prog { // 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, textarg int32, noctxt int, jmpok **obj.Prog) *obj.Prog { - var q *obj.Prog var q1 *obj.Prog var cmp int @@ -767,7 +765,8 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32, textarg int32, noc p = obj.Appendp(ctxt, p) p.As = int16(cmp) - p.From.Type = D_SP + p.From.Type = obj.TYPE_REG + p.From.Reg = REG_SP indir_cx(ctxt, &p.To) p.To.Offset = 2 * int64(ctxt.Arch.Ptrsize) // G.stackguard0 if ctxt.Cursym.Cfunc != 0 { @@ -780,20 +779,22 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32, textarg int32, noc p = obj.Appendp(ctxt, p) p.As = int16(lea) - p.From.Type = D_INDIR + D_SP + p.From.Type = obj.TYPE_MEM + p.From.Reg = REG_SP p.From.Offset = -(int64(framesize) - obj.StackSmall) - p.To.Type = D_AX + p.To.Type = obj.TYPE_REG + p.To.Reg = REG_AX p = obj.Appendp(ctxt, p) p.As = int16(cmp) - p.From.Type = D_AX + p.From.Type = obj.TYPE_REG + p.From.Reg = REG_AX indir_cx(ctxt, &p.To) 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) @@ -817,34 +818,41 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32, textarg int32, noc if ctxt.Cursym.Cfunc != 0 { p.From.Offset = 3 * int64(ctxt.Arch.Ptrsize) // G.stackguard1 } - p.To.Type = D_SI + p.To.Type = obj.TYPE_REG + p.To.Reg = REG_SI p = obj.Appendp(ctxt, p) p.As = int16(cmp) - p.From.Type = D_SI - p.To.Type = D_CONST + p.From.Type = obj.TYPE_REG + p.From.Reg = REG_SI + p.To.Type = obj.TYPE_CONST p.To.Offset = obj.StackPreempt p = obj.Appendp(ctxt, p) p.As = AJEQ - p.To.Type = D_BRANCH + p.To.Type = obj.TYPE_BRANCH q1 = p p = obj.Appendp(ctxt, p) p.As = int16(lea) - p.From.Type = D_INDIR + D_SP + p.From.Type = obj.TYPE_MEM + p.From.Reg = REG_SP p.From.Offset = obj.StackGuard - p.To.Type = D_AX + p.To.Type = obj.TYPE_REG + p.To.Reg = REG_AX p = obj.Appendp(ctxt, p) p.As = int16(sub) - p.From.Type = D_SI - p.To.Type = D_AX + p.From.Type = obj.TYPE_REG + p.From.Reg = REG_SI + p.To.Type = obj.TYPE_REG + p.To.Reg = REG_AX p = obj.Appendp(ctxt, p) p.As = int16(cmp) - p.From.Type = D_AX - p.To.Type = D_CONST + 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) } @@ -852,22 +860,21 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32, textarg int32, noc p = obj.Appendp(ctxt, p) p.As = AJHI - p.To.Type = D_BRANCH + p.To.Type = obj.TYPE_BRANCH q = p p = obj.Appendp(ctxt, p) - p.As = ACALL - p.To.Type = D_BRANCH + 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[noctxt] } p = obj.Appendp(ctxt, p) - p.As = AJMP - p.To.Type = D_BRANCH + p.As = obj.AJMP + p.To.Type = obj.TYPE_BRANCH p.Pcond = ctxt.Cursym.Text.Link if q != nil { @@ -887,7 +894,7 @@ func follow(ctxt *obj.Link, s *obj.LSym) { ctxt.Cursym = s - firstp = ctxt.NewProg() + firstp = new(obj.Prog) lastp = firstp xfol(ctxt, s.Text, &lastp) lastp.Link = nil @@ -896,15 +903,15 @@ func follow(ctxt *obj.Link, s *obj.LSym) { func nofollow(a int) int { switch a { - case AJMP, - ARET, + case obj.AJMP, + obj.ARET, AIRETL, AIRETQ, AIRETW, ARETFL, ARETFQ, ARETFW, - AUNDEF: + obj.AUNDEF: return 1 } @@ -980,9 +987,9 @@ loop: if p == nil { return } - if p.As == AJMP { + if p.As == obj.AJMP { q = p.Pcond - if q != nil && q.As != ATEXT { + if q != nil && q.As != obj.ATEXT { /* mark instruction as done and continue layout at target of jump */ p.Mark = 1 @@ -1001,7 +1008,6 @@ loop: i = 0 q = p for ; i < 4; (func() { i++; q = q.Link })() { - if q == nil { break } @@ -1009,7 +1015,7 @@ loop: break } a = int(q.As) - if a == ANOP { + if a == obj.ANOP { i-- continue } @@ -1020,11 +1026,11 @@ loop: if q.Pcond == nil || q.Pcond.Mark != 0 { continue } - if a == ACALL || a == ALOOP { + if a == obj.ACALL || a == ALOOP { continue } for { - if p.As == ANOP { + if p.As == obj.ANOP { p = p.Link continue } @@ -1051,10 +1057,10 @@ loop: /* */ } } - q = ctxt.NewProg() - q.As = AJMP + q = new(obj.Prog) + q.As = obj.AJMP q.Lineno = p.Lineno - q.To.Type = D_BRANCH + q.To.Type = obj.TYPE_BRANCH q.To.Offset = p.Pc q.Pcond = p p = q @@ -1069,10 +1075,9 @@ loop: /* continue loop with what comes after p */ if nofollow(a) != 0 { - return } - if p.Pcond != nil && a != ACALL { + if p.Pcond != nil && a != obj.ACALL { /* * some kind of conditional branch. * recurse to follow one path. @@ -1080,14 +1085,13 @@ loop: */ 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 == D_CONST { + if p.From.Type == obj.TYPE_CONST { if p.From.Offset == 1 { /* * expect conditional jump to be taken. @@ -1100,7 +1104,6 @@ loop: p.Pcond = q } } else { - q = p.Link if q.Mark != 0 { if a != ALOOP { @@ -1123,95 +1126,32 @@ loop: goto loop } -func prg() *obj.Prog { - p := zprg - return &p -} - var Linkamd64 = obj.LinkArch{ - ByteOrder: binary.LittleEndian, - Pconv: Pconv, - Name: "amd64", - Thechar: '6', - Endian: obj.LittleEndian, - Addstacksplit: addstacksplit, - Assemble: span6, - Datasize: datasize, - Follow: follow, - Iscall: iscall, - Isdata: isdata, - Prg: prg, - Progedit: progedit, - Settextflag: settextflag, - Symtype: symtype, - Textflag: textflag, - Minlc: 1, - Ptrsize: 8, - Regsize: 8, - D_ADDR: D_ADDR, - D_AUTO: D_AUTO, - D_BRANCH: D_BRANCH, - D_CONST: D_CONST, - D_EXTERN: D_EXTERN, - D_FCONST: D_FCONST, - D_NONE: D_NONE, - D_PARAM: D_PARAM, - D_SCONST: D_SCONST, - D_STATIC: D_STATIC, - ACALL: ACALL, - ADATA: ADATA, - AEND: AEND, - AFUNCDATA: AFUNCDATA, - AGLOBL: AGLOBL, - AJMP: AJMP, - ANOP: ANOP, - APCDATA: APCDATA, - ARET: ARET, - ATEXT: ATEXT, - ATYPE: ATYPE, - AUSEFIELD: AUSEFIELD, + ByteOrder: binary.LittleEndian, + Pconv: Pconv, + Name: "amd64", + Thechar: '6', + Endian: obj.LittleEndian, + Preprocess: preprocess, + Assemble: span6, + Follow: follow, + Progedit: progedit, + Minlc: 1, + Ptrsize: 8, + Regsize: 8, } var Linkamd64p32 = obj.LinkArch{ - ByteOrder: binary.LittleEndian, - Pconv: Pconv, - Name: "amd64p32", - Thechar: '6', - Endian: obj.LittleEndian, - Addstacksplit: addstacksplit, - Assemble: span6, - Datasize: datasize, - Follow: follow, - Iscall: iscall, - Isdata: isdata, - Prg: prg, - Progedit: progedit, - Settextflag: settextflag, - Symtype: symtype, - Textflag: textflag, - Minlc: 1, - Ptrsize: 4, - Regsize: 8, - D_ADDR: D_ADDR, - D_AUTO: D_AUTO, - D_BRANCH: D_BRANCH, - D_CONST: D_CONST, - D_EXTERN: D_EXTERN, - D_FCONST: D_FCONST, - D_NONE: D_NONE, - D_PARAM: D_PARAM, - D_SCONST: D_SCONST, - D_STATIC: D_STATIC, - ACALL: ACALL, - ADATA: ADATA, - AEND: AEND, - AFUNCDATA: AFUNCDATA, - AGLOBL: AGLOBL, - AJMP: AJMP, - ANOP: ANOP, - APCDATA: APCDATA, - ARET: ARET, - ATEXT: ATEXT, - ATYPE: ATYPE, - AUSEFIELD: AUSEFIELD, + ByteOrder: binary.LittleEndian, + Pconv: Pconv, + Name: "amd64p32", + Thechar: '6', + Endian: obj.LittleEndian, + Preprocess: preprocess, + Assemble: span6, + Follow: follow, + Progedit: progedit, + Minlc: 1, + Ptrsize: 4, + Regsize: 8, } |
