diff options
| author | Rob Pike <r@golang.org> | 2015-03-02 20:17:20 -0800 |
|---|---|---|
| committer | Rob Pike <r@golang.org> | 2015-03-03 17:06:27 +0000 |
| commit | 74e88dfdeebef392d52d3f792e2071b058c1e231 (patch) | |
| tree | e066ac4bde456ffd50b2ecaf402020056f97653c /src/cmd/internal | |
| parent | 91e7ca588d07b8e04e9608c4436d2d701f6c59d0 (diff) | |
| download | go-74e88dfdeebef392d52d3f792e2071b058c1e231.tar.xz | |
cmd/internal/obj: switch to one global Aconv
Aconv is the pretty-printer for instruction opcodes like AMOVQ.
There was one for each architecture.
Make the space of A names have a different region for each architecture,
much as we did for the registers, so a single global Aconv function can
do the work. Each architecture registers its region as a slice of names
at a given offset.
The global names like CALL and JMP are now defined only once.
The A values are used for indexing tables, so make it easy to do the
indexing by making the offset maskable.
Remove a bunch of now-duplicated architecture-specific code.
Change-Id: Ib15647b7145a1c089e21e36543691a19e146b60e
Reviewed-on: https://go-review.googlesource.com/6620
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Rob Pike <r@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Diffstat (limited to 'src/cmd/internal')
| -rw-r--r-- | src/cmd/internal/obj/arm/5.out.go | 2 | ||||
| -rw-r--r-- | src/cmd/internal/obj/arm/anames5.go | 23 | ||||
| -rw-r--r-- | src/cmd/internal/obj/arm/asm5.go | 141 | ||||
| -rw-r--r-- | src/cmd/internal/obj/arm/list5.go | 50 | ||||
| -rw-r--r-- | src/cmd/internal/obj/i386/8.out.go | 2 | ||||
| -rw-r--r-- | src/cmd/internal/obj/i386/anames8.go | 23 | ||||
| -rw-r--r-- | src/cmd/internal/obj/i386/asm8.go | 149 | ||||
| -rw-r--r-- | src/cmd/internal/obj/i386/list8.go | 13 | ||||
| -rw-r--r-- | src/cmd/internal/obj/link.go | 30 | ||||
| -rw-r--r-- | src/cmd/internal/obj/ppc64/9.out.go | 2 | ||||
| -rw-r--r-- | src/cmd/internal/obj/ppc64/anames9.go | 26 | ||||
| -rw-r--r-- | src/cmd/internal/obj/ppc64/asm9.go | 512 | ||||
| -rw-r--r-- | src/cmd/internal/obj/ppc64/list9.go | 25 | ||||
| -rw-r--r-- | src/cmd/internal/obj/util.go | 65 | ||||
| -rw-r--r-- | src/cmd/internal/obj/x86/6.out.go | 2 | ||||
| -rw-r--r-- | src/cmd/internal/obj/x86/anames6.go | 23 | ||||
| -rw-r--r-- | src/cmd/internal/obj/x86/asm6.go | 10 | ||||
| -rw-r--r-- | src/cmd/internal/obj/x86/list6.go | 13 | ||||
| -rw-r--r-- | src/cmd/internal/obj/x86/obj6.go | 10 |
19 files changed, 521 insertions, 600 deletions
diff --git a/src/cmd/internal/obj/arm/5.out.go b/src/cmd/internal/obj/arm/5.out.go index d4b0170e58..91e96874f0 100644 --- a/src/cmd/internal/obj/arm/5.out.go +++ b/src/cmd/internal/obj/arm/5.out.go @@ -145,7 +145,7 @@ const ( ) const ( - AAND = obj.A_ARCHSPECIFIC + iota + AAND = obj.ABaseARM + obj.A_ARCHSPECIFIC + iota AEOR ASUB ARSB diff --git a/src/cmd/internal/obj/arm/anames5.go b/src/cmd/internal/obj/arm/anames5.go index f00cf17760..9f50df3239 100644 --- a/src/cmd/internal/obj/arm/anames5.go +++ b/src/cmd/internal/obj/arm/anames5.go @@ -1,26 +1,9 @@ package arm +import "cmd/internal/obj" + var Anames = []string{ - "XXX", - "CALL", - "CHECKNIL", - "DATA", - "DUFFCOPY", - "DUFFZERO", - "END", - "FUNCDATA", - "GLOBL", - "JMP", - "NOP", - "PCDATA", - "RET", - "TEXT", - "TYPE", - "UNDEF", - "USEFIELD", - "VARDEF", - "VARKILL", - "AND", + obj.A_ARCHSPECIFIC: "AND", "EOR", "SUB", "RSB", diff --git a/src/cmd/internal/obj/arm/asm5.go b/src/cmd/internal/obj/arm/asm5.go index 064cbe26f1..10cca25172 100644 --- a/src/cmd/internal/obj/arm/asm5.go +++ b/src/cmd/internal/obj/arm/asm5.go @@ -39,7 +39,7 @@ import ( ) type Optab struct { - as uint8 + as uint16 a1 uint8 a2 int8 a3 uint8 @@ -268,7 +268,7 @@ var pool struct { extra uint32 } -var oprange [ALAST]Oprang +var oprange [ALAST & obj.AMask]Oprang var xcmp [C_GOK + 1][C_GOK + 1]uint8 @@ -580,7 +580,7 @@ func span5(ctxt *obj.Link, cursym *obj.LSym) { return } - if oprange[AAND].start == nil { + if oprange[AAND&obj.AMask].start == nil { buildop(ctxt) } @@ -1207,14 +1207,14 @@ func oplook(ctxt *obj.Link, p *obj.Prog) *Optab { if p.Reg != 0 { a2 = C_REG } - r := int(p.As) + r := p.As & obj.AMask o := oprange[r].start if o == nil { o = oprange[r].stop /* just generate an error */ } if false { /*debug['O']*/ - fmt.Printf("oplook %v %v %v %v\n", Aconv(int(p.As)), DRconv(a1), DRconv(a2), DRconv(a3)) + fmt.Printf("oplook %v %v %v %v\n", obj.Aconv(int(p.As)), DRconv(a1), DRconv(a2), DRconv(a3)) fmt.Printf("\t\t%d %d\n", p.From.Type, p.To.Type) } @@ -1335,6 +1335,10 @@ func (x ocmp) Less(i, j int) bool { return false } +func opset(a, b0 uint16) { + oprange[a&obj.AMask] = oprange[b0] +} + func buildop(ctxt *obj.Link) { var n int @@ -1356,67 +1360,66 @@ func buildop(ctxt *obj.Link) { } sort.Sort(ocmp(optab[:n])) - var r int for i := 0; i < n; i++ { - r = int(optab[i].as) - oprange[r].start = optab[i:] - for int(optab[i].as) == r { + r0 := optab[i].as & obj.AMask + oprange[r0].start = optab[i:] + for optab[i].as&obj.AMask == r0 { i++ } - oprange[r].stop = optab[i:] + oprange[r0].stop = optab[i:] i-- - switch r { + switch r0 { default: - ctxt.Diag("unknown op in build: %v", Aconv(r)) + ctxt.Diag("unknown op in build: %v", obj.Aconv(int(optab[i].as))) log.Fatalf("bad code") case AADD: - oprange[AAND] = oprange[r] - oprange[AEOR] = oprange[r] - oprange[ASUB] = oprange[r] - oprange[ARSB] = oprange[r] - oprange[AADC] = oprange[r] - oprange[ASBC] = oprange[r] - oprange[ARSC] = oprange[r] - oprange[AORR] = oprange[r] - oprange[ABIC] = oprange[r] + opset(AAND, r0) + opset(AEOR, r0) + opset(ASUB, r0) + opset(ARSB, r0) + opset(AADC, r0) + opset(ASBC, r0) + opset(ARSC, r0) + opset(AORR, r0) + opset(ABIC, r0) case ACMP: - oprange[ATEQ] = oprange[r] - oprange[ACMN] = oprange[r] + opset(ATEQ, r0) + opset(ACMN, r0) case AMVN: break case ABEQ: - oprange[ABNE] = oprange[r] - oprange[ABCS] = oprange[r] - oprange[ABHS] = oprange[r] - oprange[ABCC] = oprange[r] - oprange[ABLO] = oprange[r] - oprange[ABMI] = oprange[r] - oprange[ABPL] = oprange[r] - oprange[ABVS] = oprange[r] - oprange[ABVC] = oprange[r] - oprange[ABHI] = oprange[r] - oprange[ABLS] = oprange[r] - oprange[ABGE] = oprange[r] - oprange[ABLT] = oprange[r] - oprange[ABGT] = oprange[r] - oprange[ABLE] = oprange[r] + opset(ABNE, r0) + opset(ABCS, r0) + opset(ABHS, r0) + opset(ABCC, r0) + opset(ABLO, r0) + opset(ABMI, r0) + opset(ABPL, r0) + opset(ABVS, r0) + opset(ABVC, r0) + opset(ABHI, r0) + opset(ABLS, r0) + opset(ABGE, r0) + opset(ABLT, r0) + opset(ABGT, r0) + opset(ABLE, r0) case ASLL: - oprange[ASRL] = oprange[r] - oprange[ASRA] = oprange[r] + opset(ASRL, r0) + opset(ASRA, r0) case AMUL: - oprange[AMULU] = oprange[r] + opset(AMULU, r0) case ADIV: - oprange[AMOD] = oprange[r] - oprange[AMODU] = oprange[r] - oprange[ADIVU] = oprange[r] + opset(AMOD, r0) + opset(AMODU, r0) + opset(ADIVU, r0) case AMOVW, AMOVB, @@ -1428,7 +1431,7 @@ func buildop(ctxt *obj.Link) { break case ASWPW: - oprange[ASWPBU] = oprange[r] + opset(ASWPBU, r0) case AB, ABL, @@ -1448,42 +1451,42 @@ func buildop(ctxt *obj.Link) { break case AADDF: - oprange[AADDD] = oprange[r] - oprange[ASUBF] = oprange[r] - oprange[ASUBD] = oprange[r] - oprange[AMULF] = oprange[r] - oprange[AMULD] = oprange[r] - oprange[ADIVF] = oprange[r] - oprange[ADIVD] = oprange[r] - oprange[ASQRTF] = oprange[r] - oprange[ASQRTD] = oprange[r] - oprange[AMOVFD] = oprange[r] - oprange[AMOVDF] = oprange[r] - oprange[AABSF] = oprange[r] - oprange[AABSD] = oprange[r] + opset(AADDD, r0) + opset(ASUBF, r0) + opset(ASUBD, r0) + opset(AMULF, r0) + opset(AMULD, r0) + opset(ADIVF, r0) + opset(ADIVD, r0) + opset(ASQRTF, r0) + opset(ASQRTD, r0) + opset(AMOVFD, r0) + opset(AMOVDF, r0) + opset(AABSF, r0) + opset(AABSD, r0) case ACMPF: - oprange[ACMPD] = oprange[r] + opset(ACMPD, r0) case AMOVF: - oprange[AMOVD] = oprange[r] + opset(AMOVD, r0) case AMOVFW: - oprange[AMOVDW] = oprange[r] + opset(AMOVDW, r0) case AMOVWF: - oprange[AMOVWD] = oprange[r] + opset(AMOVWD, r0) case AMULL: - oprange[AMULAL] = oprange[r] - oprange[AMULLU] = oprange[r] - oprange[AMULALU] = oprange[r] + opset(AMULAL, r0) + opset(AMULLU, r0) + opset(AMULALU, r0) case AMULWT: - oprange[AMULWB] = oprange[r] + opset(AMULWB, r0) case AMULAWT: - oprange[AMULAWB] = oprange[r] + opset(AMULAWB, r0) case AMULA, ALDREX, @@ -2660,7 +2663,7 @@ func opbra(ctxt *obj.Link, a int, sc int) uint32 { return 0xe<<28 | 0x5<<25 } - ctxt.Diag("bad bra %v", Aconv(a)) + ctxt.Diag("bad bra %v", obj.Aconv(a)) prasm(ctxt.Curp) return 0 } @@ -2780,7 +2783,7 @@ func ofsr(ctxt *obj.Link, a int, r int, v int32, b int, sc int, p *obj.Prog) uin switch a { default: - ctxt.Diag("bad fst %v", Aconv(a)) + ctxt.Diag("bad fst %v", obj.Aconv(a)) fallthrough case AMOVD: diff --git a/src/cmd/internal/obj/arm/list5.go b/src/cmd/internal/obj/arm/list5.go index 60caedebc1..0625cffcf9 100644 --- a/src/cmd/internal/obj/arm/list5.go +++ b/src/cmd/internal/obj/arm/list5.go @@ -79,57 +79,16 @@ func Pconv(p *obj.Prog) string { var str string if a == obj.ADATA { str = fmt.Sprintf("%.5d (%v)\t%v\t%v/%d,%v", - p.Pc, p.Line(), Aconv(a), obj.Dconv(p, &p.From), p.From3.Offset, obj.Dconv(p, &p.To)) + p.Pc, p.Line(), obj.Aconv(a), obj.Dconv(p, &p.From), p.From3.Offset, obj.Dconv(p, &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), obj.Dconv(p, &p.From), p.From3.Offset, obj.Dconv(p, &p.To)) + p.Pc, p.Line(), obj.Aconv(a), obj.Dconv(p, &p.From), p.From3.Offset, obj.Dconv(p, &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, obj.Dconv(p, &p.From), obj.Dconv(p, &p.To)) + p.Pc, p.Line(), obj.Aconv(a), sc, obj.Dconv(p, &p.From), obj.Dconv(p, &p.To)) } else { str = fmt.Sprintf("%.5d (%v)\t%v%s\t%v,%v,%v", - p.Pc, p.Line(), Aconv(a), sc, obj.Dconv(p, &p.From), Rconv(int(p.Reg)), obj.Dconv(p, &p.To)) - } - - var fp string - fp += str - return fp -} - -func Aconv(a int) string { - s := "???" - if a >= obj.AXXX && a < ALAST { - s = Anames[a] - } - var fp string - fp += s - return fp -} - -func RAconv(a *obj.Addr) string { - str := fmt.Sprintf("GOK-reglist") - switch a.Type { - case obj.TYPE_CONST: - if a.Reg != 0 { - break - } - if a.Sym != nil { - break - } - v := int(a.Offset) - str = "" - for i := 0; i < NREG; i++ { - if v&(1<<uint(i)) != 0 { - if str == "" { - str += "[R" - } else { - str += ",R" - } - str += fmt.Sprintf("%d", i) - } - } - - str += "]" + p.Pc, p.Line(), obj.Aconv(a), sc, obj.Dconv(p, &p.From), Rconv(int(p.Reg)), obj.Dconv(p, &p.To)) } var fp string @@ -139,6 +98,7 @@ func RAconv(a *obj.Addr) string { func init() { obj.RegisterRegister(obj.RBaseARM, MAXREG, Rconv) + obj.RegisterOpcode(obj.ABaseARM, Anames) } func Rconv(r int) string { diff --git a/src/cmd/internal/obj/i386/8.out.go b/src/cmd/internal/obj/i386/8.out.go index ab58cc1f0c..6e4fca186a 100644 --- a/src/cmd/internal/obj/i386/8.out.go +++ b/src/cmd/internal/obj/i386/8.out.go @@ -33,7 +33,7 @@ package i386 import "cmd/internal/obj" const ( - AAAA = obj.A_ARCHSPECIFIC + iota + AAAA = obj.ABase386 + obj.A_ARCHSPECIFIC + iota AAAD AAAM AAAS diff --git a/src/cmd/internal/obj/i386/anames8.go b/src/cmd/internal/obj/i386/anames8.go index ebf2e5e65a..60245634ca 100644 --- a/src/cmd/internal/obj/i386/anames8.go +++ b/src/cmd/internal/obj/i386/anames8.go @@ -1,29 +1,12 @@ package i386 +import "cmd/internal/obj" + /* * this is the ranlib header */ var Anames = []string{ - "XXX", - "CALL", - "CHECKNIL", - "DATA", - "DUFFCOPY", - "DUFFZERO", - "END", - "FUNCDATA", - "GLOBL", - "JMP", - "NOP", - "PCDATA", - "RET", - "TEXT", - "TYPE", - "UNDEF", - "USEFIELD", - "VARDEF", - "VARKILL", - "AAA", + obj.A_ARCHSPECIFIC: "AAA", "AAD", "AAM", "AAS", diff --git a/src/cmd/internal/obj/i386/asm8.go b/src/cmd/internal/obj/i386/asm8.go index 112e839c16..8ad2304f27 100644 --- a/src/cmd/internal/obj/i386/asm8.go +++ b/src/cmd/internal/obj/i386/asm8.go @@ -58,7 +58,7 @@ type ytab struct { zoffset uint8 } -var opindex [ALAST + 1]*Optab +var opindex [(ALAST + 1) & obj.AMask]*Optab const ( Yxxx = 0 + iota @@ -1331,12 +1331,11 @@ func span8(ctxt *obj.Link, s *obj.LSym) { } func instinit() { - var c int for i := 1; optab[i].as != 0; i++ { - c = int(optab[i].as) + c := optab[i].as & obj.AMask if opindex[c] != nil { - log.Fatalf("phase error in optab: %d (%v)", i, Aconv(c)) + log.Fatalf("phase error in optab: %d (%v)", i, obj.Aconv(int(optab[i].as))) } opindex[c] = &optab[i] } @@ -1969,7 +1968,7 @@ const ( var ymovtab = []uint8{ /* push */ - APUSHL, + APUSHL & obj.AMask, Ycs, Ynone, 0, @@ -1977,7 +1976,7 @@ var ymovtab = []uint8{ E, 0, 0, - APUSHL, + APUSHL & obj.AMask, Yss, Ynone, 0, @@ -1985,7 +1984,7 @@ var ymovtab = []uint8{ E, 0, 0, - APUSHL, + APUSHL & obj.AMask, Yds, Ynone, 0, @@ -1993,7 +1992,7 @@ var ymovtab = []uint8{ E, 0, 0, - APUSHL, + APUSHL & obj.AMask, Yes, Ynone, 0, @@ -2001,7 +2000,7 @@ var ymovtab = []uint8{ E, 0, 0, - APUSHL, + APUSHL & obj.AMask, Yfs, Ynone, 0, @@ -2009,7 +2008,7 @@ var ymovtab = []uint8{ 0xa0, E, 0, - APUSHL, + APUSHL & obj.AMask, Ygs, Ynone, 0, @@ -2017,7 +2016,7 @@ var ymovtab = []uint8{ 0xa8, E, 0, - APUSHW, + APUSHW & obj.AMask, Ycs, Ynone, 0, @@ -2025,7 +2024,7 @@ var ymovtab = []uint8{ 0x0e, E, 0, - APUSHW, + APUSHW & obj.AMask, Yss, Ynone, 0, @@ -2033,7 +2032,7 @@ var ymovtab = []uint8{ 0x16, E, 0, - APUSHW, + APUSHW & obj.AMask, Yds, Ynone, 0, @@ -2041,7 +2040,7 @@ var ymovtab = []uint8{ 0x1e, E, 0, - APUSHW, + APUSHW & obj.AMask, Yes, Ynone, 0, @@ -2049,7 +2048,7 @@ var ymovtab = []uint8{ 0x06, E, 0, - APUSHW, + APUSHW & obj.AMask, Yfs, Ynone, 0, @@ -2057,7 +2056,7 @@ var ymovtab = []uint8{ 0x0f, 0xa0, E, - APUSHW, + APUSHW & obj.AMask, Ygs, Ynone, 0, @@ -2067,7 +2066,7 @@ var ymovtab = []uint8{ E, /* pop */ - APOPL, + APOPL & obj.AMask, Ynone, Yds, 0, @@ -2075,7 +2074,7 @@ var ymovtab = []uint8{ E, 0, 0, - APOPL, + APOPL & obj.AMask, Ynone, Yes, 0, @@ -2083,7 +2082,7 @@ var ymovtab = []uint8{ E, 0, 0, - APOPL, + APOPL & obj.AMask, Ynone, Yss, 0, @@ -2091,7 +2090,7 @@ var ymovtab = []uint8{ E, 0, 0, - APOPL, + APOPL & obj.AMask, Ynone, Yfs, 0, @@ -2099,7 +2098,7 @@ var ymovtab = []uint8{ 0xa1, E, 0, - APOPL, + APOPL & obj.AMask, Ynone, Ygs, 0, @@ -2107,7 +2106,7 @@ var ymovtab = []uint8{ 0xa9, E, 0, - APOPW, + APOPW & obj.AMask, Ynone, Yds, 0, @@ -2115,7 +2114,7 @@ var ymovtab = []uint8{ 0x1f, E, 0, - APOPW, + APOPW & obj.AMask, Ynone, Yes, 0, @@ -2123,7 +2122,7 @@ var ymovtab = []uint8{ 0x07, E, 0, - APOPW, + APOPW & obj.AMask, Ynone, Yss, 0, @@ -2131,7 +2130,7 @@ var ymovtab = []uint8{ 0x17, E, 0, - APOPW, + APOPW & obj.AMask, Ynone, Yfs, 0, @@ -2139,7 +2138,7 @@ var ymovtab = []uint8{ 0x0f, 0xa1, E, - APOPW, + APOPW & obj.AMask, Ynone, Ygs, 0, @@ -2149,7 +2148,7 @@ var ymovtab = []uint8{ E, /* mov seg */ - AMOVW, + AMOVW & obj.AMask, Yes, Yml, 1, @@ -2157,7 +2156,7 @@ var ymovtab = []uint8{ 0, 0, 0, - AMOVW, + AMOVW & obj.AMask, Ycs, Yml, 1, @@ -2165,7 +2164,7 @@ var ymovtab = []uint8{ 1, 0, 0, - AMOVW, + AMOVW & obj.AMask, Yss, Yml, 1, @@ -2173,7 +2172,7 @@ var ymovtab = []uint8{ 2, 0, 0, - AMOVW, + AMOVW & obj.AMask, Yds, Yml, 1, @@ -2181,7 +2180,7 @@ var ymovtab = []uint8{ 3, 0, 0, - AMOVW, + AMOVW & obj.AMask, Yfs, Yml, 1, @@ -2189,7 +2188,7 @@ var ymovtab = []uint8{ 4, 0, 0, - AMOVW, + AMOVW & obj.AMask, Ygs, Yml, 1, @@ -2197,7 +2196,7 @@ var ymovtab = []uint8{ 5, 0, 0, - AMOVW, + AMOVW & obj.AMask, Yml, Yes, 2, @@ -2205,7 +2204,7 @@ var ymovtab = []uint8{ 0, 0, 0, - AMOVW, + AMOVW & obj.AMask, Yml, Ycs, 2, @@ -2213,7 +2212,7 @@ var ymovtab = []uint8{ 1, 0, 0, - AMOVW, + AMOVW & obj.AMask, Yml, Yss, 2, @@ -2221,7 +2220,7 @@ var ymovtab = []uint8{ 2, 0, 0, - AMOVW, + AMOVW & obj.AMask, Yml, Yds, 2, @@ -2229,7 +2228,7 @@ var ymovtab = []uint8{ 3, 0, 0, - AMOVW, + AMOVW & obj.AMask, Yml, Yfs, 2, @@ -2237,7 +2236,7 @@ var ymovtab = []uint8{ 4, 0, 0, - AMOVW, + AMOVW & obj.AMask, Yml, Ygs, 2, @@ -2247,7 +2246,7 @@ var ymovtab = []uint8{ 0, /* mov cr */ - AMOVL, + AMOVL & obj.AMask, Ycr0, Yml, 3, @@ -2255,7 +2254,7 @@ var ymovtab = []uint8{ 0x20, 0, 0, - AMOVL, + AMOVL & obj.AMask, Ycr2, Yml, 3, @@ -2263,7 +2262,7 @@ var ymovtab = []uint8{ 0x20, 2, 0, - AMOVL, + AMOVL & obj.AMask, Ycr3, Yml, 3, @@ -2271,7 +2270,7 @@ var ymovtab = []uint8{ 0x20, 3, 0, - AMOVL, + AMOVL & obj.AMask, Ycr4, Yml, 3, @@ -2279,7 +2278,7 @@ var ymovtab = []uint8{ 0x20, 4, 0, - AMOVL, + AMOVL & obj.AMask, Yml, Ycr0, 4, @@ -2287,7 +2286,7 @@ var ymovtab = []uint8{ 0x22, 0, 0, - AMOVL, + AMOVL & obj.AMask, Yml, Ycr2, 4, @@ -2295,7 +2294,7 @@ var ymovtab = []uint8{ 0x22, 2, 0, - AMOVL, + AMOVL & obj.AMask, Yml, Ycr3, 4, @@ -2303,7 +2302,7 @@ var ymovtab = []uint8{ 0x22, 3, 0, - AMOVL, + AMOVL & obj.AMask, Yml, Ycr4, 4, @@ -2313,7 +2312,7 @@ var ymovtab = []uint8{ 0, /* mov dr */ - AMOVL, + AMOVL & obj.AMask, Ydr0, Yml, 3, @@ -2321,7 +2320,7 @@ var ymovtab = []uint8{ 0x21, 0, 0, - AMOVL, + AMOVL & obj.AMask, Ydr6, Yml, 3, @@ -2329,7 +2328,7 @@ var ymovtab = []uint8{ 0x21, 6, 0, - AMOVL, + AMOVL & obj.AMask, Ydr7, Yml, 3, @@ -2337,7 +2336,7 @@ var ymovtab = []uint8{ 0x21, 7, 0, - AMOVL, + AMOVL & obj.AMask, Yml, Ydr0, 4, @@ -2345,7 +2344,7 @@ var ymovtab = []uint8{ 0x23, 0, 0, - AMOVL, + AMOVL & obj.AMask, Yml, Ydr6, 4, @@ -2353,7 +2352,7 @@ var ymovtab = []uint8{ 0x23, 6, 0, - AMOVL, + AMOVL & obj.AMask, Yml, Ydr7, 4, @@ -2363,7 +2362,7 @@ var ymovtab = []uint8{ 0, /* mov tr */ - AMOVL, + AMOVL & obj.AMask, Ytr6, Yml, 3, @@ -2371,7 +2370,7 @@ var ymovtab = []uint8{ 0x24, 6, 0, - AMOVL, + AMOVL & obj.AMask, Ytr7, Yml, 3, @@ -2379,7 +2378,7 @@ var ymovtab = []uint8{ 0x24, 7, 0, - AMOVL, + AMOVL & obj.AMask, Yml, Ytr6, 4, @@ -2387,7 +2386,7 @@ var ymovtab = []uint8{ 0x26, 6, E, - AMOVL, + AMOVL & obj.AMask, Yml, Ytr7, 4, @@ -2397,7 +2396,7 @@ var ymovtab = []uint8{ E, /* lgdt, sgdt, lidt, sidt */ - AMOVL, + AMOVL & obj.AMask, Ym, Ygdtr, 4, @@ -2405,7 +2404,7 @@ var ymovtab = []uint8{ 0x01, 2, 0, - AMOVL, + AMOVL & obj.AMask, Ygdtr, Ym, 3, @@ -2413,7 +2412,7 @@ var ymovtab = []uint8{ 0x01, 0, 0, - AMOVL, + AMOVL & obj.AMask, Ym, Yidtr, 4, @@ -2421,7 +2420,7 @@ var ymovtab = []uint8{ 0x01, 3, 0, - AMOVL, + AMOVL & obj.AMask, Yidtr, Ym, 3, @@ -2431,7 +2430,7 @@ var ymovtab = []uint8{ 0, /* lldt, sldt */ - AMOVW, + AMOVW & obj.AMask, Yml, Yldtr, 4, @@ -2439,7 +2438,7 @@ var ymovtab = []uint8{ 0x00, 2, 0, - AMOVW, + AMOVW & obj.AMask, Yldtr, Yml, 3, @@ -2449,7 +2448,7 @@ var ymovtab = []uint8{ 0, /* lmsw, smsw */ - AMOVW, + AMOVW & obj.AMask, Yml, Ymsw, 4, @@ -2457,7 +2456,7 @@ var ymovtab = []uint8{ 0x01, 6, 0, - AMOVW, + AMOVW & obj.AMask, Ymsw, Yml, 3, @@ -2467,7 +2466,7 @@ var ymovtab = []uint8{ 0, /* ltr, str */ - AMOVW, + AMOVW & obj.AMask, Yml, Ytask, 4, @@ -2475,7 +2474,7 @@ var ymovtab = []uint8{ 0x00, 3, 0, - AMOVW, + AMOVW & obj.AMask, Ytask, Yml, 3, @@ -2485,7 +2484,7 @@ var ymovtab = []uint8{ 0, /* load full pointer */ - AMOVL, + AMOVL & obj.AMask, Yml, Ycol, 5, @@ -2493,7 +2492,7 @@ var ymovtab = []uint8{ 0, 0, 0, - AMOVW, + AMOVW & obj.AMask, Yml, Ycol, 5, @@ -2503,7 +2502,7 @@ var ymovtab = []uint8{ 0, /* double shift */ - ASHLL, + ASHLL & obj.AMask, Ycol, Yml, 6, @@ -2511,7 +2510,7 @@ var ymovtab = []uint8{ 0xa5, 0, 0, - ASHRL, + ASHRL & obj.AMask, Ycol, Yml, 6, @@ -2521,7 +2520,7 @@ var ymovtab = []uint8{ 0, /* extra imul */ - AIMULW, + AIMULW & obj.AMask, Yml, Yrl, 7, @@ -2529,7 +2528,7 @@ var ymovtab = []uint8{ 0xaf, 0, 0, - AIMULL, + AIMULL & obj.AMask, Yml, Yrl, 7, @@ -2539,7 +2538,7 @@ var ymovtab = []uint8{ 0, /* load TLS base pointer */ - AMOVL, + AMOVL & obj.AMask, Ytls, Yrl, 8, @@ -2712,7 +2711,7 @@ func doasm(ctxt *obj.Link, p *obj.Prog) { ft := int(p.Ft) * Ymax tt := int(p.Tt) * Ymax - o := opindex[p.As] + o := opindex[p.As&obj.AMask] z := 0 var a *obj.Addr @@ -3163,7 +3162,7 @@ func doasm(ctxt *obj.Link, p *obj.Prog) { domov: var pp obj.Prog for t := []byte(ymovtab); t[0] != 0; t = t[8:] { - if p.As == int16(t[0]) { + if p.As&obj.AMask == int16(t[0]) { if ycover[ft+int(t[1])] != 0 { if ycover[tt+int(t[2])] != 0 { switch t[3] { diff --git a/src/cmd/internal/obj/i386/list8.go b/src/cmd/internal/obj/i386/list8.go index f843006bdb..f62253976b 100644 --- a/src/cmd/internal/obj/i386/list8.go +++ b/src/cmd/internal/obj/i386/list8.go @@ -47,21 +47,21 @@ func Pconv(p *obj.Prog) string { switch p.As { case obj.ADATA: str = fmt.Sprintf("%.5d (%v)\t%v\t%v/%d,%v", - p.Pc, p.Line(), Aconv(int(p.As)), obj.Dconv(p, &p.From), p.From3.Offset, obj.Dconv(p, &p.To)) + p.Pc, p.Line(), obj.Aconv(int(p.As)), obj.Dconv(p, &p.From), p.From3.Offset, obj.Dconv(p, &p.To)) case obj.ATEXT: if p.From3.Offset != 0 { str = fmt.Sprintf("%.5d (%v)\t%v\t%v,%d,%v", - p.Pc, p.Line(), Aconv(int(p.As)), obj.Dconv(p, &p.From), p.From3.Offset, obj.Dconv(p, &p.To)) + p.Pc, p.Line(), obj.Aconv(int(p.As)), obj.Dconv(p, &p.From), p.From3.Offset, obj.Dconv(p, &p.To)) break } str = fmt.Sprintf("%.5d (%v)\t%v\t%v,%v", - p.Pc, p.Line(), Aconv(int(p.As)), obj.Dconv(p, &p.From), obj.Dconv(p, &p.To)) + p.Pc, p.Line(), obj.Aconv(int(p.As)), obj.Dconv(p, &p.From), obj.Dconv(p, &p.To)) default: str = fmt.Sprintf("%.5d (%v)\t%v\t%v,%v", - p.Pc, p.Line(), Aconv(int(p.As)), obj.Dconv(p, &p.From), obj.Dconv(p, &p.To)) + p.Pc, p.Line(), obj.Aconv(int(p.As)), obj.Dconv(p, &p.From), obj.Dconv(p, &p.To)) // TODO(rsc): This special case is for SHRQ $32, AX:DX, which encodes as // SHRQ $32(DX*0), AX @@ -76,10 +76,6 @@ func Pconv(p *obj.Prog) string { return fp } -func Aconv(i int) string { - return Anames[i] -} - var Register = []string{ "AL", /* [REG_AL] */ "CL", @@ -154,6 +150,7 @@ var Register = []string{ func init() { obj.RegisterRegister(obj.RBase386, obj.RBase386+len(Register), Rconv) + obj.RegisterOpcode(obj.ABase386, Anames) } func Rconv(r int) string { diff --git a/src/cmd/internal/obj/link.go b/src/cmd/internal/obj/link.go index 4bac11e3fe..95c9886ab2 100644 --- a/src/cmd/internal/obj/link.go +++ b/src/cmd/internal/obj/link.go @@ -424,6 +424,10 @@ const ( // These are the portable opcodes, common to all architectures. // Each architecture defines many more arch-specific opcodes, // with values starting at A_ARCHSPECIFIC. +// Each architecture adds an offset to this so each machine has +// distinct space for its instructions. The offset is a power of +// two so it can be masked to return to origin zero. +// See the definitions of ABase386 etc. const ( AXXX = 0 + iota ACALL @@ -570,30 +574,4 @@ const ( LinkExternal ) -// asm5.c - -// asm6.c - -// asm8.c - -// asm9.c - -// data.c - -// 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/ppc64/9.out.go b/src/cmd/internal/obj/ppc64/9.out.go index 3030455bbd..d3d54fda79 100644 --- a/src/cmd/internal/obj/ppc64/9.out.go +++ b/src/cmd/internal/obj/ppc64/9.out.go @@ -218,7 +218,7 @@ const ( ) const ( - AADD = obj.A_ARCHSPECIFIC + iota + AADD = obj.ABasePPC64 + obj.A_ARCHSPECIFIC + iota AADDCC AADDV AADDVCC diff --git a/src/cmd/internal/obj/ppc64/anames9.go b/src/cmd/internal/obj/ppc64/anames9.go index 9d755dedbc..057256a430 100644 --- a/src/cmd/internal/obj/ppc64/anames9.go +++ b/src/cmd/internal/obj/ppc64/anames9.go @@ -1,29 +1,9 @@ package ppc64 -/* - * this is the ranlib header - */ +import "cmd/internal/obj" + var Anames = []string{ - "XXX", - "CALL", - "CHECKNIL", - "DATA", - "DUFFCOPY", - "DUFFZERO", - "END", - "FUNCDATA", - "GLOBL", - "JMP", - "NOP", - "PCDATA", - "RET", - "TEXT", - "TYPE", - "UNDEF", - "USEFIELD", - "VARDEF", - "VARKILL", - "ADD", + obj.A_ARCHSPECIFIC: "ADD", "ADDCC", "ADDV", "ADDVCC", diff --git a/src/cmd/internal/obj/ppc64/asm9.go b/src/cmd/internal/obj/ppc64/asm9.go index 16d1626727..30d7d835f1 100644 --- a/src/cmd/internal/obj/ppc64/asm9.go +++ b/src/cmd/internal/obj/ppc64/asm9.go @@ -402,7 +402,7 @@ type Oprang struct { stop []Optab } -var oprange [ALAST]Oprang +var oprange [ALAST & obj.AMask]Oprang var xcmp [C_NCLASS][C_NCLASS]uint8 @@ -414,7 +414,7 @@ func span9(ctxt *obj.Link, cursym *obj.LSym) { ctxt.Cursym = cursym ctxt.Autosize = int32(p.To.Offset + 8) - if oprange[AANDN].start == nil { + if oprange[AANDN&obj.AMask].start == nil { buildop(ctxt) } @@ -744,13 +744,13 @@ func oplook(ctxt *obj.Link, p *obj.Prog) *Optab { } //print("oplook %P %d %d %d %d\n", p, a1, a2, a3, a4); - r := int(p.As) + r0 := p.As & obj.AMask - o := oprange[r].start + o := oprange[r0].start if o == nil { - o = oprange[r].stop /* just generate an error */ + o = oprange[r0].stop /* just generate an error */ } - e := oprange[r].stop + e := oprange[r0].stop c1 := xcmp[a1][:] c3 := xcmp[a3][:] c4 := xcmp[a4][:] @@ -767,7 +767,7 @@ func oplook(ctxt *obj.Link, p *obj.Prog) *Optab { } } - ctxt.Diag("illegal combination %v %v %v %v %v", Aconv(int(p.As)), DRconv(a1), DRconv(a2), DRconv(a3), DRconv(a4)) + ctxt.Diag("illegal combination %v %v %v %v %v", obj.Aconv(int(p.As)), DRconv(a1), DRconv(a2), DRconv(a3), DRconv(a4)) prasm(p) if o == nil { o = optab @@ -887,6 +887,9 @@ func (x ocmp) Less(i, j int) bool { } return false } +func opset(a, b0 int16) { + oprange[a&obj.AMask] = oprange[b0] +} func buildop(ctxt *obj.Link) { var n int @@ -901,356 +904,355 @@ func buildop(ctxt *obj.Link) { for n = 0; optab[n].as != obj.AXXX; n++ { } sort.Sort(ocmp(optab[:n])) - var r int for i := 0; i < n; i++ { - r = int(optab[i].as) - oprange[r].start = optab[i:] - for int(optab[i].as) == r { + r0 := optab[i].as & obj.AMask + oprange[r0].start = optab[i:] + for optab[i].as&obj.AMask == r0 { i++ } - oprange[r].stop = optab[i:] + oprange[r0].stop = optab[i:] i-- - switch r { + switch r0 { default: - ctxt.Diag("unknown op in build: %v", Aconv(r)) + ctxt.Diag("unknown op in build: %v", obj.Aconv(int(optab[i].as))) log.Fatalf("bad code") case ADCBF: /* unary indexed: op (b+a); op (b) */ - oprange[ADCBI] = oprange[r] + opset(ADCBI, r0) - oprange[ADCBST] = oprange[r] - oprange[ADCBT] = oprange[r] - oprange[ADCBTST] = oprange[r] - oprange[ADCBZ] = oprange[r] - oprange[AICBI] = oprange[r] + opset(ADCBST, r0) + opset(ADCBT, r0) + opset(ADCBTST, r0) + opset(ADCBZ, r0) + opset(AICBI, r0) case AECOWX: /* indexed store: op s,(b+a); op s,(b) */ - oprange[ASTWCCC] = oprange[r] + opset(ASTWCCC, r0) - oprange[ASTDCCC] = oprange[r] + opset(ASTDCCC, r0) case AREM: /* macro */ - oprange[AREMCC] = oprange[r] + opset(AREMCC, r0) - oprange[AREMV] = oprange[r] - oprange[AREMVCC] = oprange[r] + opset(AREMV, r0) + opset(AREMVCC, r0) case AREMU: - oprange[AREMU] = oprange[r] - oprange[AREMUCC] = oprange[r] - oprange[AREMUV] = oprange[r] - oprange[AREMUVCC] = oprange[r] + opset(AREMU, r0) + opset(AREMUCC, r0) + opset(AREMUV, r0) + opset(AREMUVCC, r0) case AREMD: - oprange[AREMDCC] = oprange[r] - oprange[AREMDV] = oprange[r] - oprange[AREMDVCC] = oprange[r] + opset(AREMDCC, r0) + opset(AREMDV, r0) + opset(AREMDVCC, r0) case AREMDU: - oprange[AREMDU] = oprange[r] - oprange[AREMDUCC] = oprange[r] - oprange[AREMDUV] = oprange[r] - oprange[AREMDUVCC] = oprange[r] + opset(AREMDU, r0) + opset(AREMDUCC, r0) + opset(AREMDUV, r0) + opset(AREMDUVCC, r0) case ADIVW: /* op Rb[,Ra],Rd */ - oprange[AMULHW] = oprange[r] + opset(AMULHW, r0) - oprange[AMULHWCC] = oprange[r] - oprange[AMULHWU] = oprange[r] - oprange[AMULHWUCC] = oprange[r] - oprange[AMULLWCC] = oprange[r] - oprange[AMULLWVCC] = oprange[r] - oprange[AMULLWV] = oprange[r] - oprange[ADIVWCC] = oprange[r] - oprange[ADIVWV] = oprange[r] - oprange[ADIVWVCC] = oprange[r] - oprange[ADIVWU] = oprange[r] - oprange[ADIVWUCC] = oprange[r] - oprange[ADIVWUV] = oprange[r] - oprange[ADIVWUVCC] = oprange[r] - oprange[AADDCC] = oprange[r] - oprange[AADDCV] = oprange[r] - oprange[AADDCVCC] = oprange[r] - oprange[AADDV] = oprange[r] - oprange[AADDVCC] = oprange[r] - oprange[AADDE] = oprange[r] - oprange[AADDECC] = oprange[r] - oprange[AADDEV] = oprange[r] - oprange[AADDEVCC] = oprange[r] - oprange[ACRAND] = oprange[r] - oprange[ACRANDN] = oprange[r] - oprange[ACREQV] = oprange[r] - oprange[ACRNAND] = oprange[r] - oprange[ACRNOR] = oprange[r] - oprange[ACROR] = oprange[r] - oprange[ACRORN] = oprange[r] - oprange[ACRXOR] = oprange[r] - oprange[AMULHD] = oprange[r] - oprange[AMULHDCC] = oprange[r] - oprange[AMULHDU] = oprange[r] - oprange[AMULHDUCC] = oprange[r] - oprange[AMULLD] = oprange[r] - oprange[AMULLDCC] = oprange[r] - oprange[AMULLDVCC] = oprange[r] - oprange[AMULLDV] = oprange[r] - oprange[ADIVD] = oprange[r] - oprange[ADIVDCC] = oprange[r] - oprange[ADIVDVCC] = oprange[r] - oprange[ADIVDV] = oprange[r] - oprange[ADIVDU] = oprange[r] - oprange[ADIVDUCC] = oprange[r] - oprange[ADIVDUVCC] = oprange[r] - oprange[ADIVDUCC] = oprange[r] + opset(AMULHWCC, r0) + opset(AMULHWU, r0) + opset(AMULHWUCC, r0) + opset(AMULLWCC, r0) + opset(AMULLWVCC, r0) + opset(AMULLWV, r0) + opset(ADIVWCC, r0) + opset(ADIVWV, r0) + opset(ADIVWVCC, r0) + opset(ADIVWU, r0) + opset(ADIVWUCC, r0) + opset(ADIVWUV, r0) + opset(ADIVWUVCC, r0) + opset(AADDCC, r0) + opset(AADDCV, r0) + opset(AADDCVCC, r0) + opset(AADDV, r0) + opset(AADDVCC, r0) + opset(AADDE, r0) + opset(AADDECC, r0) + opset(AADDEV, r0) + opset(AADDEVCC, r0) + opset(ACRAND, r0) + opset(ACRANDN, r0) + opset(ACREQV, r0) + opset(ACRNAND, r0) + opset(ACRNOR, r0) + opset(ACROR, r0) + opset(ACRORN, r0) + opset(ACRXOR, r0) + opset(AMULHD, r0) + opset(AMULHDCC, r0) + opset(AMULHDU, r0) + opset(AMULHDUCC, r0) + opset(AMULLD, r0) + opset(AMULLDCC, r0) + opset(AMULLDVCC, r0) + opset(AMULLDV, r0) + opset(ADIVD, r0) + opset(ADIVDCC, r0) + opset(ADIVDVCC, r0) + opset(ADIVDV, r0) + opset(ADIVDU, r0) + opset(ADIVDUCC, r0) + opset(ADIVDUVCC, r0) + opset(ADIVDUCC, r0) case AMOVBZ: /* lbz, stz, rlwm(r/r), lhz, lha, stz, and x variants */ - oprange[AMOVH] = oprange[r] + opset(AMOVH, r0) - oprange[AMOVHZ] = oprange[r] + opset(AMOVHZ, r0) case AMOVBZU: /* lbz[x]u, stb[x]u, lhz[x]u, lha[x]u, sth[u]x, ld[x]u, std[u]x */ - oprange[AMOVHU] = oprange[r] + opset(AMOVHU, r0) - oprange[AMOVHZU] = oprange[r] - oprange[AMOVWU] = oprange[r] - oprange[AMOVWZU] = oprange[r] - oprange[AMOVDU] = oprange[r] - oprange[AMOVMW] = oprange[r] + opset(AMOVHZU, r0) + opset(AMOVWU, r0) + opset(AMOVWZU, r0) + opset(AMOVDU, r0) + opset(AMOVMW, r0) case AAND: /* logical op Rb,Rs,Ra; no literal */ - oprange[AANDN] = oprange[r] + opset(AANDN, r0) - oprange[AANDNCC] = oprange[r] - oprange[AEQV] = oprange[r] - oprange[AEQVCC] = oprange[r] - oprange[ANAND] = oprange[r] - oprange[ANANDCC] = oprange[r] - oprange[ANOR] = oprange[r] - oprange[ANORCC] = oprange[r] - oprange[AORCC] = oprange[r] - oprange[AORN] = oprange[r] - oprange[AORNCC] = oprange[r] - oprange[AXORCC] = oprange[r] + opset(AANDNCC, r0) + opset(AEQV, r0) + opset(AEQVCC, r0) + opset(ANAND, r0) + opset(ANANDCC, r0) + opset(ANOR, r0) + opset(ANORCC, r0) + opset(AORCC, r0) + opset(AORN, r0) + opset(AORNCC, r0) + opset(AXORCC, r0) case AADDME: /* op Ra, Rd */ - oprange[AADDMECC] = oprange[r] + opset(AADDMECC, r0) - oprange[AADDMEV] = oprange[r] - oprange[AADDMEVCC] = oprange[r] - oprange[AADDZE] = oprange[r] - oprange[AADDZECC] = oprange[r] - oprange[AADDZEV] = oprange[r] - oprange[AADDZEVCC] = oprange[r] - oprange[ASUBME] = oprange[r] - oprange[ASUBMECC] = oprange[r] - oprange[ASUBMEV] = oprange[r] - oprange[ASUBMEVCC] = oprange[r] - oprange[ASUBZE] = oprange[r] - oprange[ASUBZECC] = oprange[r] - oprange[ASUBZEV] = oprange[r] - oprange[ASUBZEVCC] = oprange[r] + opset(AADDMEV, r0) + opset(AADDMEVCC, r0) + opset(AADDZE, r0) + opset(AADDZECC, r0) + opset(AADDZEV, r0) + opset(AADDZEVCC, r0) + opset(ASUBME, r0) + opset(ASUBMECC, r0) + opset(ASUBMEV, r0) + opset(ASUBMEVCC, r0) + opset(ASUBZE, r0) + opset(ASUBZECC, r0) + opset(ASUBZEV, r0) + opset(ASUBZEVCC, r0) case AADDC: - oprange[AADDCCC] = oprange[r] + opset(AADDCCC, r0) case ABEQ: - oprange[ABGE] = oprange[r] - oprange[ABGT] = oprange[r] - oprange[ABLE] = oprange[r] - oprange[ABLT] = oprange[r] - oprange[ABNE] = oprange[r] - oprange[ABVC] = oprange[r] - oprange[ABVS] = oprange[r] + opset(ABGE, r0) + opset(ABGT, r0) + opset(ABLE, r0) + opset(ABLT, r0) + opset(ABNE, r0) + opset(ABVC, r0) + opset(ABVS, r0) case ABR: - oprange[ABL] = oprange[r] + opset(ABL, r0) case ABC: - oprange[ABCL] = oprange[r] + opset(ABCL, r0) case AEXTSB: /* op Rs, Ra */ - oprange[AEXTSBCC] = oprange[r] + opset(AEXTSBCC, r0) - oprange[AEXTSH] = oprange[r] - oprange[AEXTSHCC] = oprange[r] - oprange[ACNTLZW] = oprange[r] - oprange[ACNTLZWCC] = oprange[r] - oprange[ACNTLZD] = oprange[r] - oprange[AEXTSW] = oprange[r] - oprange[AEXTSWCC] = oprange[r] - oprange[ACNTLZDCC] = oprange[r] + opset(AEXTSH, r0) + opset(AEXTSHCC, r0) + opset(ACNTLZW, r0) + opset(ACNTLZWCC, r0) + opset(ACNTLZD, r0) + opset(AEXTSW, r0) + opset(AEXTSWCC, r0) + opset(ACNTLZDCC, r0) case AFABS: /* fop [s,]d */ - oprange[AFABSCC] = oprange[r] + opset(AFABSCC, r0) - oprange[AFNABS] = oprange[r] - oprange[AFNABSCC] = oprange[r] - oprange[AFNEG] = oprange[r] - oprange[AFNEGCC] = oprange[r] - oprange[AFRSP] = oprange[r] - oprange[AFRSPCC] = oprange[r] - oprange[AFCTIW] = oprange[r] - oprange[AFCTIWCC] = oprange[r] - oprange[AFCTIWZ] = oprange[r] - oprange[AFCTIWZCC] = oprange[r] - oprange[AFCTID] = oprange[r] - oprange[AFCTIDCC] = oprange[r] - oprange[AFCTIDZ] = oprange[r] - oprange[AFCTIDZCC] = oprange[r] - oprange[AFCFID] = oprange[r] - oprange[AFCFIDCC] = oprange[r] - oprange[AFRES] = oprange[r] - oprange[AFRESCC] = oprange[r] - oprange[AFRSQRTE] = oprange[r] - oprange[AFRSQRTECC] = oprange[r] - oprange[AFSQRT] = oprange[r] - oprange[AFSQRTCC] = oprange[r] - oprange[AFSQRTS] = oprange[r] - oprange[AFSQRTSCC] = oprange[r] + opset(AFNABS, r0) + opset(AFNABSCC, r0) + opset(AFNEG, r0) + opset(AFNEGCC, r0) + opset(AFRSP, r0) + opset(AFRSPCC, r0) + opset(AFCTIW, r0) + opset(AFCTIWCC, r0) + opset(AFCTIWZ, r0) + opset(AFCTIWZCC, r0) + opset(AFCTID, r0) + opset(AFCTIDCC, r0) + opset(AFCTIDZ, r0) + opset(AFCTIDZCC, r0) + opset(AFCFID, r0) + opset(AFCFIDCC, r0) + opset(AFRES, r0) + opset(AFRESCC, r0) + opset(AFRSQRTE, r0) + opset(AFRSQRTECC, r0) + opset(AFSQRT, r0) + opset(AFSQRTCC, r0) + opset(AFSQRTS, r0) + opset(AFSQRTSCC, r0) case AFADD: - oprange[AFADDS] = oprange[r] - oprange[AFADDCC] = oprange[r] - oprange[AFADDSCC] = oprange[r] - oprange[AFDIV] = oprange[r] - oprange[AFDIVS] = oprange[r] - oprange[AFDIVCC] = oprange[r] - oprange[AFDIVSCC] = oprange[r] - oprange[AFSUB] = oprange[r] - oprange[AFSUBS] = oprange[r] - oprange[AFSUBCC] = oprange[r] - oprange[AFSUBSCC] = oprange[r] + opset(AFADDS, r0) + opset(AFADDCC, r0) + opset(AFADDSCC, r0) + opset(AFDIV, r0) + opset(AFDIVS, r0) + opset(AFDIVCC, r0) + opset(AFDIVSCC, r0) + opset(AFSUB, r0) + opset(AFSUBS, r0) + opset(AFSUBCC, r0) + opset(AFSUBSCC, r0) case AFMADD: - oprange[AFMADDCC] = oprange[r] - oprange[AFMADDS] = oprange[r] - oprange[AFMADDSCC] = oprange[r] - oprange[AFMSUB] = oprange[r] - oprange[AFMSUBCC] = oprange[r] - oprange[AFMSUBS] = oprange[r] - oprange[AFMSUBSCC] = oprange[r] - oprange[AFNMADD] = oprange[r] - oprange[AFNMADDCC] = oprange[r] - oprange[AFNMADDS] = oprange[r] - oprange[AFNMADDSCC] = oprange[r] - oprange[AFNMSUB] = oprange[r] - oprange[AFNMSUBCC] = oprange[r] - oprange[AFNMSUBS] = oprange[r] - oprange[AFNMSUBSCC] = oprange[r] - oprange[AFSEL] = oprange[r] - oprange[AFSELCC] = oprange[r] + opset(AFMADDCC, r0) + opset(AFMADDS, r0) + opset(AFMADDSCC, r0) + opset(AFMSUB, r0) + opset(AFMSUBCC, r0) + opset(AFMSUBS, r0) + opset(AFMSUBSCC, r0) + opset(AFNMADD, r0) + opset(AFNMADDCC, r0) + opset(AFNMADDS, r0) + opset(AFNMADDSCC, r0) + opset(AFNMSUB, r0) + opset(AFNMSUBCC, r0) + opset(AFNMSUBS, r0) + opset(AFNMSUBSCC, r0) + opset(AFSEL, r0) + opset(AFSELCC, r0) case AFMUL: - oprange[AFMULS] = oprange[r] - oprange[AFMULCC] = oprange[r] - oprange[AFMULSCC] = oprange[r] + opset(AFMULS, r0) + opset(AFMULCC, r0) + opset(AFMULSCC, r0) case AFCMPO: - oprange[AFCMPU] = oprange[r] + opset(AFCMPU, r0) case AMTFSB0: - oprange[AMTFSB0CC] = oprange[r] - oprange[AMTFSB1] = oprange[r] - oprange[AMTFSB1CC] = oprange[r] + opset(AMTFSB0CC, r0) + opset(AMTFSB1, r0) + opset(AMTFSB1CC, r0) case ANEG: /* op [Ra,] Rd */ - oprange[ANEGCC] = oprange[r] + opset(ANEGCC, r0) - oprange[ANEGV] = oprange[r] - oprange[ANEGVCC] = oprange[r] + opset(ANEGV, r0) + opset(ANEGVCC, r0) case AOR: /* or/xor Rb,Rs,Ra; ori/xori $uimm,Rs,Ra; oris/xoris $uimm,Rs,Ra */ - oprange[AXOR] = oprange[r] + opset(AXOR, r0) case ASLW: - oprange[ASLWCC] = oprange[r] - oprange[ASRW] = oprange[r] - oprange[ASRWCC] = oprange[r] + opset(ASLWCC, r0) + opset(ASRW, r0) + opset(ASRWCC, r0) case ASLD: - oprange[ASLDCC] = oprange[r] - oprange[ASRD] = oprange[r] - oprange[ASRDCC] = oprange[r] + opset(ASLDCC, r0) + opset(ASRD, r0) + opset(ASRDCC, r0) case ASRAW: /* sraw Rb,Rs,Ra; srawi sh,Rs,Ra */ - oprange[ASRAWCC] = oprange[r] + opset(ASRAWCC, r0) case ASRAD: /* sraw Rb,Rs,Ra; srawi sh,Rs,Ra */ - oprange[ASRADCC] = oprange[r] + opset(ASRADCC, r0) case ASUB: /* SUB Ra,Rb,Rd => subf Rd,ra,rb */ - oprange[ASUB] = oprange[r] + opset(ASUB, r0) - oprange[ASUBCC] = oprange[r] - oprange[ASUBV] = oprange[r] - oprange[ASUBVCC] = oprange[r] - oprange[ASUBCCC] = oprange[r] - oprange[ASUBCV] = oprange[r] - oprange[ASUBCVCC] = oprange[r] - oprange[ASUBE] = oprange[r] - oprange[ASUBECC] = oprange[r] - oprange[ASUBEV] = oprange[r] - oprange[ASUBEVCC] = oprange[r] + opset(ASUBCC, r0) + opset(ASUBV, r0) + opset(ASUBVCC, r0) + opset(ASUBCCC, r0) + opset(ASUBCV, r0) + opset(ASUBCVCC, r0) + opset(ASUBE, r0) + opset(ASUBECC, r0) + opset(ASUBEV, r0) + opset(ASUBEVCC, r0) case ASYNC: - oprange[AISYNC] = oprange[r] - oprange[APTESYNC] = oprange[r] - oprange[ATLBSYNC] = oprange[r] + opset(AISYNC, r0) + opset(APTESYNC, r0) + opset(ATLBSYNC, r0) case ARLWMI: - oprange[ARLWMICC] = oprange[r] - oprange[ARLWNM] = oprange[r] - oprange[ARLWNMCC] = oprange[r] + opset(ARLWMICC, r0) + opset(ARLWNM, r0) + opset(ARLWNMCC, r0) case ARLDMI: - oprange[ARLDMICC] = oprange[r] + opset(ARLDMICC, r0) case ARLDC: - oprange[ARLDCCC] = oprange[r] + opset(ARLDCCC, r0) case ARLDCL: - oprange[ARLDCR] = oprange[r] - oprange[ARLDCLCC] = oprange[r] - oprange[ARLDCRCC] = oprange[r] + opset(ARLDCR, r0) + opset(ARLDCLCC, r0) + opset(ARLDCRCC, r0) case AFMOVD: - oprange[AFMOVDCC] = oprange[r] - oprange[AFMOVDU] = oprange[r] - oprange[AFMOVS] = oprange[r] - oprange[AFMOVSU] = oprange[r] + opset(AFMOVDCC, r0) + opset(AFMOVDU, r0) + opset(AFMOVS, r0) + opset(AFMOVSU, r0) case AECIWX: - oprange[ALWAR] = oprange[r] - oprange[ALDAR] = oprange[r] + opset(ALWAR, r0) + opset(ALDAR, r0) case ASYSCALL: /* just the op; flow of control */ - oprange[ARFI] = oprange[r] + opset(ARFI, r0) - oprange[ARFCI] = oprange[r] - oprange[ARFID] = oprange[r] - oprange[AHRFID] = oprange[r] + opset(ARFCI, r0) + opset(ARFID, r0) + opset(AHRFID, r0) case AMOVHBR: - oprange[AMOVWBR] = oprange[r] + opset(AMOVWBR, r0) case ASLBMFEE: - oprange[ASLBMFEV] = oprange[r] + opset(ASLBMFEV, r0) case ATW: - oprange[ATD] = oprange[r] + opset(ATD, r0) case ATLBIE: - oprange[ASLBIE] = oprange[r] - oprange[ATLBIEL] = oprange[r] + opset(ASLBIE, r0) + opset(ATLBIEL, r0) case AEIEIO: - oprange[ASLBIA] = oprange[r] + opset(ASLBIA, r0) case ACMP: - oprange[ACMPW] = oprange[r] + opset(ACMPW, r0) case ACMPU: - oprange[ACMPWU] = oprange[r] + opset(ACMPWU, r0) case AADD, AANDCC, /* and. Rb,Rs,Ra; andi. $uimm,Rs,Ra; andis. $uimm,Rs,Ra */ @@ -2954,7 +2956,7 @@ func oprrr(ctxt *obj.Link, a int) int32 { return int32(OPVCC(31, 316, 0, 1)) } - ctxt.Diag("bad r/r opcode %v", Aconv(a)) + ctxt.Diag("bad r/r opcode %v", obj.Aconv(a)) return 0 } @@ -3076,7 +3078,7 @@ func opirr(ctxt *obj.Link, a int) int32 { return int32(OPVCC(27, 0, 0, 0)) /* XORIU */ } - ctxt.Diag("bad opcode i/r %v", Aconv(a)) + ctxt.Diag("bad opcode i/r %v", obj.Aconv(a)) return 0 } @@ -3125,7 +3127,7 @@ func opload(ctxt *obj.Link, a int) int32 { return int32(OPVCC(46, 0, 0, 0)) /* lmw */ } - ctxt.Diag("bad load opcode %v", Aconv(a)) + ctxt.Diag("bad load opcode %v", obj.Aconv(a)) return 0 } @@ -3184,7 +3186,7 @@ func oploadx(ctxt *obj.Link, a int) int32 { return int32(OPVCC(31, 53, 0, 0)) /* ldux */ } - ctxt.Diag("bad loadx opcode %v", Aconv(a)) + ctxt.Diag("bad loadx opcode %v", obj.Aconv(a)) return 0 } @@ -3234,7 +3236,7 @@ func opstore(ctxt *obj.Link, a int) int32 { return int32(OPVCC(62, 0, 0, 1)) /* stdu */ } - ctxt.Diag("unknown store opcode %v", Aconv(a)) + ctxt.Diag("unknown store opcode %v", obj.Aconv(a)) return 0 } @@ -3292,6 +3294,6 @@ func opstorex(ctxt *obj.Link, a int) int32 { return int32(OPVCC(31, 181, 0, 0)) /* stdux */ } - ctxt.Diag("unknown storex opcode %v", Aconv(a)) + ctxt.Diag("unknown storex opcode %v", obj.Aconv(a)) return 0 } diff --git a/src/cmd/internal/obj/ppc64/list9.go b/src/cmd/internal/obj/ppc64/list9.go index 6c62fad7a3..f9de6f34a6 100644 --- a/src/cmd/internal/obj/ppc64/list9.go +++ b/src/cmd/internal/obj/ppc64/list9.go @@ -59,14 +59,14 @@ func Pconv(p *obj.Prog) string { str := "" if a == obj.ADATA { str = fmt.Sprintf("%.5d (%v)\t%v\t%v/%d,%v", - p.Pc, p.Line(), Aconv(a), obj.Dconv(p, &p.From), p.From3.Offset, obj.Dconv(p, &p.To)) + p.Pc, p.Line(), obj.Aconv(a), obj.Dconv(p, &p.From), p.From3.Offset, obj.Dconv(p, &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), obj.Dconv(p, &p.From), p.From3.Offset, obj.Dconv(p, &p.To)) + p.Pc, p.Line(), obj.Aconv(a), obj.Dconv(p, &p.From), p.From3.Offset, obj.Dconv(p, &p.To)) } else { str = fmt.Sprintf("%.5d (%v)\t%v\t%v,%v", - p.Pc, p.Line(), Aconv(a), obj.Dconv(p, &p.From), obj.Dconv(p, &p.To)) + p.Pc, p.Line(), obj.Aconv(a), obj.Dconv(p, &p.From), obj.Dconv(p, &p.To)) } } else { if p.Mark&NOSCHED != 0 { @@ -74,24 +74,24 @@ func Pconv(p *obj.Prog) string { } 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), obj.Dconv(p, &p.From), obj.Dconv(p, &p.To)) + p.Pc, p.Line(), obj.Aconv(a), obj.Dconv(p, &p.From), obj.Dconv(p, &p.To)) } else if a != obj.ATEXT && p.From.Type == obj.TYPE_MEM { off := "" if p.From.Offset != 0 { off = fmt.Sprintf("%d", p.From.Offset) } str += fmt.Sprintf("%.5d (%v)\t%v\t%s(%v+%v),%v", - p.Pc, p.Line(), Aconv(a), off, Rconv(int(p.From.Reg)), Rconv(int(p.Reg)), obj.Dconv(p, &p.To)) + p.Pc, p.Line(), obj.Aconv(a), off, Rconv(int(p.From.Reg)), Rconv(int(p.Reg)), obj.Dconv(p, &p.To)) } else if p.To.Type == obj.TYPE_MEM { off := "" if p.From.Offset != 0 { off = fmt.Sprintf("%d", p.From.Offset) } str += fmt.Sprintf("%.5d (%v)\t%v\t%v,%s(%v+%v)", - p.Pc, p.Line(), Aconv(a), obj.Dconv(p, &p.From), off, Rconv(int(p.To.Reg)), Rconv(int(p.Reg))) + p.Pc, p.Line(), obj.Aconv(a), obj.Dconv(p, &p.From), off, 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), obj.Dconv(p, &p.From)) + p.Pc, p.Line(), obj.Aconv(a), obj.Dconv(p, &p.From)) if p.Reg != 0 { str += fmt.Sprintf(",%v", Rconv(int(p.Reg))) } @@ -113,18 +113,9 @@ func Pconv(p *obj.Prog) string { return fp } -func Aconv(a int) string { - s := "???" - if a >= obj.AXXX && a < ALAST { - s = Anames[a] - } - var fp string - fp += s - return fp -} - func init() { obj.RegisterRegister(obj.RBasePPC64, REG_DCR0+1024, Rconv) + obj.RegisterOpcode(obj.ABasePPC64, Anames) } func Rconv(r int) string { diff --git a/src/cmd/internal/obj/util.go b/src/cmd/internal/obj/util.go index a3c88a2b8a..d626793475 100644 --- a/src/cmd/internal/obj/util.go +++ b/src/cmd/internal/obj/util.go @@ -491,3 +491,68 @@ func regListConv(list int) string { str += "]" return str } + +/* + Each architecture defines an instruction (A*) space as a unique + integer range. + Global opcodes like CALL start at 0; the architecture-specific ones + start at a distinct, big-maskable offsets. + Here is the list of architectures and the base of their opcode spaces. +*/ + +const ( + ABase386 = (1 + iota) << 12 + ABaseARM + ABaseAMD64 + ABasePPC64 + AMask = 1<<12 - 1 // AND with this to use the opcode as an array index. +) + +type opSet struct { + lo int + names []string +} + +// Not even worth sorting +var aSpace []opSet + +// RegisterOpcode binds a list of instruction names +// to a given instruction number range. +func RegisterOpcode(lo int, Anames []string) { + aSpace = append(aSpace, opSet{lo, Anames}) +} + +func Aconv(a int) string { + if a < A_ARCHSPECIFIC { + return Anames[a] + } + for i := range aSpace { + as := &aSpace[i] + if as.lo <= a && a < as.lo+len(as.names) { + return as.names[a-as.lo] + } + } + return fmt.Sprintf("A???%d", a) +} + +var Anames = []string{ + "XXX", + "CALL", + "CHECKNIL", + "DATA", + "DUFFCOPY", + "DUFFZERO", + "END", + "FUNCDATA", + "GLOBL", + "JMP", + "NOP", + "PCDATA", + "RET", + "TEXT", + "TYPE", + "UNDEF", + "USEFIELD", + "VARDEF", + "VARKILL", +} diff --git a/src/cmd/internal/obj/x86/6.out.go b/src/cmd/internal/obj/x86/6.out.go index 82f9291d61..45af1d65cc 100644 --- a/src/cmd/internal/obj/x86/6.out.go +++ b/src/cmd/internal/obj/x86/6.out.go @@ -36,7 +36,7 @@ import "cmd/internal/obj" * amd64 */ const ( - AAAA = obj.A_ARCHSPECIFIC + iota + AAAA = obj.ABaseAMD64 + obj.A_ARCHSPECIFIC + iota AAAD AAAM AAAS diff --git a/src/cmd/internal/obj/x86/anames6.go b/src/cmd/internal/obj/x86/anames6.go index fca730bf9d..5839b23112 100644 --- a/src/cmd/internal/obj/x86/anames6.go +++ b/src/cmd/internal/obj/x86/anames6.go @@ -1,29 +1,12 @@ package x86 +import "cmd/internal/obj" + /* * this is the ranlib header */ var Anames = []string{ - "XXX", - "CALL", - "CHECKNIL", - "DATA", - "DUFFCOPY", - "DUFFZERO", - "END", - "FUNCDATA", - "GLOBL", - "JMP", - "NOP", - "PCDATA", - "RET", - "TEXT", - "TYPE", - "UNDEF", - "USEFIELD", - "VARDEF", - "VARKILL", - "AAA", + obj.A_ARCHSPECIFIC: "AAA", "AAD", "AAM", "AAS", diff --git a/src/cmd/internal/obj/x86/asm6.go b/src/cmd/internal/obj/x86/asm6.go index cb7d524c63..07ae72f3f0 100644 --- a/src/cmd/internal/obj/x86/asm6.go +++ b/src/cmd/internal/obj/x86/asm6.go @@ -1435,7 +1435,7 @@ var optab = Optab{0, nil, 0, [23]uint8{}}, } -var opindex [ALAST + 1]*Optab +var opindex [(ALAST + 1) & obj.AMask]*Optab // isextern reports whether s describes an external symbol that must avoid pc-relative addressing. // This happens on systems like Solaris that call .so functions instead of system calls. @@ -1708,10 +1708,10 @@ func instinit() { for i := 1; optab[i].as != 0; i++ { c = int(optab[i].as) - if opindex[c] != nil { - log.Fatalf("phase error in optab: %d (%v)", i, Aconv(c)) + if opindex[c&obj.AMask] != nil { + log.Fatalf("phase error in optab: %d (%v)", i, obj.Aconv(c)) } - opindex[c] = &optab[i] + opindex[c&obj.AMask] = &optab[i] } for i := 0; i < Ymax; i++ { @@ -2758,7 +2758,7 @@ func mediaop(ctxt *obj.Link, o *Optab, op int, osize int, z int) int { func doasm(ctxt *obj.Link, p *obj.Prog) { ctxt.Curp = p // TODO - o := opindex[p.As] + o := opindex[p.As&obj.AMask] if o == nil { ctxt.Diag("asmins: missing op %v", p) diff --git a/src/cmd/internal/obj/x86/list6.go b/src/cmd/internal/obj/x86/list6.go index b2a7a7a24a..6b7d65cbae 100644 --- a/src/cmd/internal/obj/x86/list6.go +++ b/src/cmd/internal/obj/x86/list6.go @@ -59,21 +59,21 @@ func Pconv(p *obj.Prog) string { switch p.As { case obj.ADATA: str = fmt.Sprintf("%.5d (%v)\t%v\t%v/%d,%v", - p.Pc, p.Line(), Aconv(int(p.As)), obj.Dconv(p, &p.From), p.From3.Offset, obj.Dconv(p, &p.To)) + p.Pc, p.Line(), obj.Aconv(int(p.As)), obj.Dconv(p, &p.From), p.From3.Offset, obj.Dconv(p, &p.To)) case obj.ATEXT: if p.From3.Offset != 0 { str = fmt.Sprintf("%.5d (%v)\t%v\t%v,%d,%v", - p.Pc, p.Line(), Aconv(int(p.As)), obj.Dconv(p, &p.From), p.From3.Offset, obj.Dconv(p, &p.To)) + p.Pc, p.Line(), obj.Aconv(int(p.As)), obj.Dconv(p, &p.From), p.From3.Offset, obj.Dconv(p, &p.To)) break } str = fmt.Sprintf("%.5d (%v)\t%v\t%v,%v", - p.Pc, p.Line(), Aconv(int(p.As)), obj.Dconv(p, &p.From), obj.Dconv(p, &p.To)) + p.Pc, p.Line(), obj.Aconv(int(p.As)), obj.Dconv(p, &p.From), obj.Dconv(p, &p.To)) default: str = fmt.Sprintf("%.5d (%v)\t%v\t%v,%v", - p.Pc, p.Line(), Aconv(int(p.As)), obj.Dconv(p, &p.From), obj.Dconv(p, &p.To)) + p.Pc, p.Line(), obj.Aconv(int(p.As)), obj.Dconv(p, &p.From), obj.Dconv(p, &p.To)) // TODO(rsc): This special case is for SHRQ $32, AX:DX, which encodes as // SHRQ $32(DX*0), AX @@ -88,10 +88,6 @@ func Pconv(p *obj.Prog) string { return fp } -func Aconv(i int) string { - return Anames[i] -} - var Register = []string{ "AL", /* [D_AL] */ "CL", @@ -210,6 +206,7 @@ var Register = []string{ func init() { obj.RegisterRegister(REG_AL, REG_AL+len(Register), Rconv) + obj.RegisterOpcode(obj.ABaseAMD64, Anames) } func Rconv(r int) string { diff --git a/src/cmd/internal/obj/x86/obj6.go b/src/cmd/internal/obj/x86/obj6.go index 434a120bd6..2b1c3a2cc1 100644 --- a/src/cmd/internal/obj/x86/obj6.go +++ b/src/cmd/internal/obj/x86/obj6.go @@ -895,7 +895,7 @@ func pushpop(a int) bool { return false } -func relinv(a int) int { +func relinv(a int16) int16 { switch a { case AJEQ: return AJNE @@ -931,7 +931,7 @@ func relinv(a int) int { return AJOS } - log.Fatalf("unknown relation: %s", Anames[a]) + log.Fatalf("unknown relation: %s", obj.Aconv(int(a))) return 0 } @@ -1001,7 +1001,7 @@ loop: continue } - q.As = int16(relinv(int(q.As))) + q.As = relinv(q.As) p = q.Pcond q.Pcond = q.Link q.Link = p @@ -1054,7 +1054,7 @@ loop: * expect conditional jump to be taken. * rewrite so that's the fall-through case. */ - p.As = int16(relinv(a)) + p.As = relinv(int16(a)) q = p.Link p.Link = p.Pcond @@ -1064,7 +1064,7 @@ loop: q = p.Link if q.Mark != 0 { if a != ALOOP { - p.As = int16(relinv(a)) + p.As = relinv(int16(a)) p.Link = p.Pcond p.Pcond = q } |
