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>
}
if gc.Debug['P'] != 0 {
- fmt.Printf(" => %v\n", arm.Aconv(int(p.As)))
+ fmt.Printf(" => %v\n", obj.Aconv(int(p.As)))
}
return true
}
func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int {
switch p.As {
default:
- fmt.Printf("copyu: can't find %v\n", arm.Aconv(int(p.As)))
+ fmt.Printf("copyu: can't find %v\n", obj.Aconv(int(p.As)))
return 2
case arm.AMOVM:
switch p.As {
default:
- fmt.Printf("copyu: can't find %v\n", ppc64.Aconv(int(p.As)))
+ fmt.Printf("copyu: can't find %v\n", obj.Aconv(int(p.As)))
return 2
case obj.ANOP, /* read p->from, write p->to */
return i
}
}
- gc.Fatal("as2variant: instruction %v is not a variant of itself", ppc64.Aconv(as))
+ gc.Fatal("as2variant: instruction %v is not a variant of itself", obj.Aconv(as))
return 0
}
RegisterNumber func(string, int16) (int16, bool)
// Instruction is a jump.
IsJump func(word string) bool
- // Aconv pretty-prints an instruction opcode for this architecture.
- Aconv func(int) string
}
// nilRegisterNumber is the register number function for architectures
// Prefixes not used on this architecture.
instructions := make(map[string]int)
- for i, s := range i386.Anames {
+ for i, s := range obj.Anames {
instructions[s] = i
}
+ for i, s := range i386.Anames {
+ if i >= obj.A_ARCHSPECIFIC {
+ instructions[s] = i + obj.ABase386
+ }
+ }
// Annoying aliases.
instructions["JA"] = i386.AJHI
instructions["JAE"] = i386.AJCC
RegisterPrefix: nil,
RegisterNumber: nilRegisterNumber,
IsJump: jump386,
- Aconv: i386.Aconv,
}
}
// Register prefix not used on this architecture.
instructions := make(map[string]int)
- for i, s := range x86.Anames {
+ for i, s := range obj.Anames {
instructions[s] = i
}
+ for i, s := range x86.Anames {
+ if i >= obj.A_ARCHSPECIFIC {
+ instructions[s] = i + obj.ABaseAMD64
+ }
+ }
// Annoying aliases.
instructions["JA"] = x86.AJHI
instructions["JAE"] = x86.AJCC
RegisterPrefix: nil,
RegisterNumber: nilRegisterNumber,
IsJump: jump386,
- Aconv: x86.Aconv,
}
}
}
instructions := make(map[string]int)
- for i, s := range arm.Anames {
+ for i, s := range obj.Anames {
instructions[s] = i
}
+ for i, s := range arm.Anames {
+ if i >= obj.A_ARCHSPECIFIC {
+ instructions[s] = i + obj.ABaseARM
+ }
+ }
// Annoying aliases.
instructions["B"] = obj.AJMP
instructions["BL"] = obj.ACALL
RegisterPrefix: registerPrefix,
RegisterNumber: armRegisterNumber,
IsJump: jumpArm,
- Aconv: arm.Aconv,
}
}
}
instructions := make(map[string]int)
- for i, s := range ppc64.Anames {
+ for i, s := range obj.Anames {
instructions[s] = i
}
+ for i, s := range ppc64.Anames {
+ if i >= obj.A_ARCHSPECIFIC {
+ instructions[s] = i + obj.ABasePPC64
+ }
+ }
// Annoying aliases.
instructions["BR"] = ppc64.ABR
instructions["BL"] = ppc64.ABL
RegisterPrefix: registerPrefix,
RegisterNumber: ppc64RegisterNumber,
IsJump: jumpPPC64,
- Aconv: ppc64.Aconv,
}
}
prog.From = a[0]
break
}
- p.errorf("wrong number of arguments to %s instruction", p.arch.Aconv(op))
+ p.errorf("wrong number of arguments to %s instruction", obj.Aconv(op))
return
case 3:
if p.arch.Thechar == '9' {
}
fallthrough
default:
- p.errorf("wrong number of arguments to %s instruction", p.arch.Aconv(op))
+ p.errorf("wrong number of arguments to %s instruction", obj.Aconv(op))
return
}
switch {
// asmInstruction assembles an instruction.
// MOVW R9, (R10)
func (p *Parser) asmInstruction(op int, cond string, a []obj.Addr) {
- // fmt.Printf("%s %+v\n", p.arch.Aconv(op), a)
+ // fmt.Printf("%s %+v\n", obj.Aconv(op), a)
prog := &obj.Prog{
Ctxt: p.ctxt,
Lineno: p.histLineNum,
prog.To = a[1]
break
}
- p.errorf("unrecognized addressing for %s", p.arch.Aconv(op))
+ p.errorf("unrecognized addressing for %s", obj.Aconv(op))
}
}
prog.From = a[0]
prog.From3 = a[1]
prog.To = a[2]
default:
- p.errorf("invalid addressing modes for %s instruction", p.arch.Aconv(op))
+ p.errorf("invalid addressing modes for %s instruction", obj.Aconv(op))
}
default:
p.errorf("TODO: implement three-operand instructions for this architecture")
prog.To = a[3]
break
}
- p.errorf("can't handle %s instruction with 4 operands", p.arch.Aconv(op))
+ p.errorf("can't handle %s instruction with 4 operands", obj.Aconv(op))
case 5:
if p.arch.Thechar == '9' && arch.IsPPC64RLD(op) {
// Always reg, reg, con, con, reg. (con, con is a 'mask').
prog.To = a[4]
break
}
- p.errorf("can't handle %s instruction with 5 operands", p.arch.Aconv(op))
+ p.errorf("can't handle %s instruction with 5 operands", obj.Aconv(op))
case 6:
// MCR and MRC on ARM
if p.arch.Thechar == '5' && arch.IsARMMRC(op) {
}
fallthrough
default:
- p.errorf("can't handle %s instruction with %d operands", p.arch.Aconv(op), len(a))
+ p.errorf("can't handle %s instruction with %d operands", obj.Aconv(op), len(a))
}
p.append(prog, cond, true)
// getConstant checks that addr represents a plain constant and returns its value.
func (p *Parser) getConstant(prog *obj.Prog, op int, addr *obj.Addr) int64 {
if addr.Type != obj.TYPE_MEM || addr.Name != 0 || addr.Reg != 0 || addr.Index != 0 {
- p.errorf("%s: expected integer constant; found %s", p.arch.Aconv(op), obj.Dconv(prog, addr))
+ p.errorf("%s: expected integer constant; found %s", obj.Aconv(op), obj.Dconv(prog, addr))
}
return addr.Offset
}
// getImmediate checks that addr represents an immediate constant and returns its value.
func (p *Parser) getImmediate(prog *obj.Prog, op int, addr *obj.Addr) int64 {
if addr.Type != obj.TYPE_CONST || addr.Name != 0 || addr.Reg != 0 || addr.Index != 0 {
- p.errorf("%s: expected immediate constant; found %s", p.arch.Aconv(op), obj.Dconv(prog, addr))
+ p.errorf("%s: expected immediate constant; found %s", obj.Aconv(op), obj.Dconv(prog, addr))
}
return addr.Offset
}
// getRegister checks that addr represents a register and returns its value.
func (p *Parser) getRegister(prog *obj.Prog, op int, addr *obj.Addr) int16 {
if addr.Type != obj.TYPE_REG || addr.Offset != 0 || addr.Name != 0 || addr.Index != 0 {
- p.errorf("%s: expected register; found %s", p.arch.Aconv(op), obj.Dconv(prog, addr))
+ p.errorf("%s: expected register; found %s", obj.Aconv(op), obj.Dconv(prog, addr))
}
return addr.Reg
}
)
const (
- AAND = obj.A_ARCHSPECIFIC + iota
+ AAND = obj.ABaseARM + obj.A_ARCHSPECIFIC + iota
AEOR
ASUB
ARSB
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",
)
type Optab struct {
- as uint8
+ as uint16
a1 uint8
a2 int8
a3 uint8
extra uint32
}
-var oprange [ALAST]Oprang
+var oprange [ALAST & obj.AMask]Oprang
var xcmp [C_GOK + 1][C_GOK + 1]uint8
return
}
- if oprange[AAND].start == nil {
+ if oprange[AAND&obj.AMask].start == nil {
buildop(ctxt)
}
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)
}
return false
}
+func opset(a, b0 uint16) {
+ oprange[a&obj.AMask] = oprange[b0]
+}
+
func buildop(ctxt *obj.Link) {
var n int
}
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,
break
case ASWPW:
- oprange[ASWPBU] = oprange[r]
+ opset(ASWPBU, r0)
case AB,
ABL,
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,
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
}
switch a {
default:
- ctxt.Diag("bad fst %v", Aconv(a))
+ ctxt.Diag("bad fst %v", obj.Aconv(a))
fallthrough
case AMOVD:
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
func init() {
obj.RegisterRegister(obj.RBaseARM, MAXREG, Rconv)
+ obj.RegisterOpcode(obj.ABaseARM, Anames)
}
func Rconv(r int) string {
import "cmd/internal/obj"
const (
- AAAA = obj.A_ARCHSPECIFIC + iota
+ AAAA = obj.ABase386 + obj.A_ARCHSPECIFIC + iota
AAAD
AAAM
AAAS
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",
zoffset uint8
}
-var opindex [ALAST + 1]*Optab
+var opindex [(ALAST + 1) & obj.AMask]*Optab
const (
Yxxx = 0 + iota
}
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]
}
var ymovtab = []uint8{
/* push */
- APUSHL,
+ APUSHL & obj.AMask,
Ycs,
Ynone,
0,
E,
0,
0,
- APUSHL,
+ APUSHL & obj.AMask,
Yss,
Ynone,
0,
E,
0,
0,
- APUSHL,
+ APUSHL & obj.AMask,
Yds,
Ynone,
0,
E,
0,
0,
- APUSHL,
+ APUSHL & obj.AMask,
Yes,
Ynone,
0,
E,
0,
0,
- APUSHL,
+ APUSHL & obj.AMask,
Yfs,
Ynone,
0,
0xa0,
E,
0,
- APUSHL,
+ APUSHL & obj.AMask,
Ygs,
Ynone,
0,
0xa8,
E,
0,
- APUSHW,
+ APUSHW & obj.AMask,
Ycs,
Ynone,
0,
0x0e,
E,
0,
- APUSHW,
+ APUSHW & obj.AMask,
Yss,
Ynone,
0,
0x16,
E,
0,
- APUSHW,
+ APUSHW & obj.AMask,
Yds,
Ynone,
0,
0x1e,
E,
0,
- APUSHW,
+ APUSHW & obj.AMask,
Yes,
Ynone,
0,
0x06,
E,
0,
- APUSHW,
+ APUSHW & obj.AMask,
Yfs,
Ynone,
0,
0x0f,
0xa0,
E,
- APUSHW,
+ APUSHW & obj.AMask,
Ygs,
Ynone,
0,
E,
/* pop */
- APOPL,
+ APOPL & obj.AMask,
Ynone,
Yds,
0,
E,
0,
0,
- APOPL,
+ APOPL & obj.AMask,
Ynone,
Yes,
0,
E,
0,
0,
- APOPL,
+ APOPL & obj.AMask,
Ynone,
Yss,
0,
E,
0,
0,
- APOPL,
+ APOPL & obj.AMask,
Ynone,
Yfs,
0,
0xa1,
E,
0,
- APOPL,
+ APOPL & obj.AMask,
Ynone,
Ygs,
0,
0xa9,
E,
0,
- APOPW,
+ APOPW & obj.AMask,
Ynone,
Yds,
0,
0x1f,
E,
0,
- APOPW,
+ APOPW & obj.AMask,
Ynone,
Yes,
0,
0x07,
E,
0,
- APOPW,
+ APOPW & obj.AMask,
Ynone,
Yss,
0,
0x17,
E,
0,
- APOPW,
+ APOPW & obj.AMask,
Ynone,
Yfs,
0,
0x0f,
0xa1,
E,
- APOPW,
+ APOPW & obj.AMask,
Ynone,
Ygs,
0,
E,
/* mov seg */
- AMOVW,
+ AMOVW & obj.AMask,
Yes,
Yml,
1,
0,
0,
0,
- AMOVW,
+ AMOVW & obj.AMask,
Ycs,
Yml,
1,
1,
0,
0,
- AMOVW,
+ AMOVW & obj.AMask,
Yss,
Yml,
1,
2,
0,
0,
- AMOVW,
+ AMOVW & obj.AMask,
Yds,
Yml,
1,
3,
0,
0,
- AMOVW,
+ AMOVW & obj.AMask,
Yfs,
Yml,
1,
4,
0,
0,
- AMOVW,
+ AMOVW & obj.AMask,
Ygs,
Yml,
1,
5,
0,
0,
- AMOVW,
+ AMOVW & obj.AMask,
Yml,
Yes,
2,
0,
0,
0,
- AMOVW,
+ AMOVW & obj.AMask,
Yml,
Ycs,
2,
1,
0,
0,
- AMOVW,
+ AMOVW & obj.AMask,
Yml,
Yss,
2,
2,
0,
0,
- AMOVW,
+ AMOVW & obj.AMask,
Yml,
Yds,
2,
3,
0,
0,
- AMOVW,
+ AMOVW & obj.AMask,
Yml,
Yfs,
2,
4,
0,
0,
- AMOVW,
+ AMOVW & obj.AMask,
Yml,
Ygs,
2,
0,
/* mov cr */
- AMOVL,
+ AMOVL & obj.AMask,
Ycr0,
Yml,
3,
0x20,
0,
0,
- AMOVL,
+ AMOVL & obj.AMask,
Ycr2,
Yml,
3,
0x20,
2,
0,
- AMOVL,
+ AMOVL & obj.AMask,
Ycr3,
Yml,
3,
0x20,
3,
0,
- AMOVL,
+ AMOVL & obj.AMask,
Ycr4,
Yml,
3,
0x20,
4,
0,
- AMOVL,
+ AMOVL & obj.AMask,
Yml,
Ycr0,
4,
0x22,
0,
0,
- AMOVL,
+ AMOVL & obj.AMask,
Yml,
Ycr2,
4,
0x22,
2,
0,
- AMOVL,
+ AMOVL & obj.AMask,
Yml,
Ycr3,
4,
0x22,
3,
0,
- AMOVL,
+ AMOVL & obj.AMask,
Yml,
Ycr4,
4,
0,
/* mov dr */
- AMOVL,
+ AMOVL & obj.AMask,
Ydr0,
Yml,
3,
0x21,
0,
0,
- AMOVL,
+ AMOVL & obj.AMask,
Ydr6,
Yml,
3,
0x21,
6,
0,
- AMOVL,
+ AMOVL & obj.AMask,
Ydr7,
Yml,
3,
0x21,
7,
0,
- AMOVL,
+ AMOVL & obj.AMask,
Yml,
Ydr0,
4,
0x23,
0,
0,
- AMOVL,
+ AMOVL & obj.AMask,
Yml,
Ydr6,
4,
0x23,
6,
0,
- AMOVL,
+ AMOVL & obj.AMask,
Yml,
Ydr7,
4,
0,
/* mov tr */
- AMOVL,
+ AMOVL & obj.AMask,
Ytr6,
Yml,
3,
0x24,
6,
0,
- AMOVL,
+ AMOVL & obj.AMask,
Ytr7,
Yml,
3,
0x24,
7,
0,
- AMOVL,
+ AMOVL & obj.AMask,
Yml,
Ytr6,
4,
0x26,
6,
E,
- AMOVL,
+ AMOVL & obj.AMask,
Yml,
Ytr7,
4,
E,
/* lgdt, sgdt, lidt, sidt */
- AMOVL,
+ AMOVL & obj.AMask,
Ym,
Ygdtr,
4,
0x01,
2,
0,
- AMOVL,
+ AMOVL & obj.AMask,
Ygdtr,
Ym,
3,
0x01,
0,
0,
- AMOVL,
+ AMOVL & obj.AMask,
Ym,
Yidtr,
4,
0x01,
3,
0,
- AMOVL,
+ AMOVL & obj.AMask,
Yidtr,
Ym,
3,
0,
/* lldt, sldt */
- AMOVW,
+ AMOVW & obj.AMask,
Yml,
Yldtr,
4,
0x00,
2,
0,
- AMOVW,
+ AMOVW & obj.AMask,
Yldtr,
Yml,
3,
0,
/* lmsw, smsw */
- AMOVW,
+ AMOVW & obj.AMask,
Yml,
Ymsw,
4,
0x01,
6,
0,
- AMOVW,
+ AMOVW & obj.AMask,
Ymsw,
Yml,
3,
0,
/* ltr, str */
- AMOVW,
+ AMOVW & obj.AMask,
Yml,
Ytask,
4,
0x00,
3,
0,
- AMOVW,
+ AMOVW & obj.AMask,
Ytask,
Yml,
3,
0,
/* load full pointer */
- AMOVL,
+ AMOVL & obj.AMask,
Yml,
Ycol,
5,
0,
0,
0,
- AMOVW,
+ AMOVW & obj.AMask,
Yml,
Ycol,
5,
0,
/* double shift */
- ASHLL,
+ ASHLL & obj.AMask,
Ycol,
Yml,
6,
0xa5,
0,
0,
- ASHRL,
+ ASHRL & obj.AMask,
Ycol,
Yml,
6,
0,
/* extra imul */
- AIMULW,
+ AIMULW & obj.AMask,
Yml,
Yrl,
7,
0xaf,
0,
0,
- AIMULL,
+ AIMULL & obj.AMask,
Yml,
Yrl,
7,
0,
/* load TLS base pointer */
- AMOVL,
+ AMOVL & obj.AMask,
Ytls,
Yrl,
8,
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
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] {
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
return fp
}
-func Aconv(i int) string {
- return Anames[i]
-}
-
var Register = []string{
"AL", /* [REG_AL] */
"CL",
func init() {
obj.RegisterRegister(obj.RBase386, obj.RBase386+len(Register), Rconv)
+ obj.RegisterOpcode(obj.ABase386, Anames)
}
func Rconv(r int) string {
// 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
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
)
const (
- AADD = obj.A_ARCHSPECIFIC + iota
+ AADD = obj.ABasePPC64 + obj.A_ARCHSPECIFIC + iota
AADDCC
AADDV
AADDVCC
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",
stop []Optab
}
-var oprange [ALAST]Oprang
+var oprange [ALAST & obj.AMask]Oprang
var xcmp [C_NCLASS][C_NCLASS]uint8
ctxt.Cursym = cursym
ctxt.Autosize = int32(p.To.Offset + 8)
- if oprange[AANDN].start == nil {
+ if oprange[AANDN&obj.AMask].start == nil {
buildop(ctxt)
}
}
//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][:]
}
}
- 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
}
return false
}
+func opset(a, b0 int16) {
+ oprange[a&obj.AMask] = oprange[b0]
+}
func buildop(ctxt *obj.Link) {
var n int
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]
-
- 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(AMULHW, r0)
+
+ 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]
-
- 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(AANDN, r0)
+
+ 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]
-
- 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(AADDMECC, r0)
+
+ 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]
-
- 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(AFABSCC, r0)
+
+ 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]
-
- 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(ASUB, r0)
+
+ 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 */
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
}
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
}
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
}
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
}
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
}
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
}
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 {
}
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)))
}
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 {
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",
+}
* amd64
*/
const (
- AAAA = obj.A_ARCHSPECIFIC + iota
+ AAAA = obj.ABaseAMD64 + obj.A_ARCHSPECIFIC + iota
AAAD
AAAM
AAAS
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",
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.
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++ {
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)
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
return fp
}
-func Aconv(i int) string {
- return Anames[i]
-}
-
var Register = []string{
"AL", /* [D_AL] */
"CL",
func init() {
obj.RegisterRegister(REG_AL, REG_AL+len(Register), Rconv)
+ obj.RegisterOpcode(obj.ABaseAMD64, Anames)
}
func Rconv(r int) string {
return false
}
-func relinv(a int) int {
+func relinv(a int16) int16 {
switch a {
case AJEQ:
return AJNE
return AJOS
}
- log.Fatalf("unknown relation: %s", Anames[a])
+ log.Fatalf("unknown relation: %s", obj.Aconv(int(a)))
return 0
}
continue
}
- q.As = int16(relinv(int(q.As)))
+ q.As = relinv(q.As)
p = q.Pcond
q.Pcond = q.Link
q.Link = p
* 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
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
}