cmd/internal/obj: make Rconv a global function

Clean up the obj API by making Rconv (register pretty printer) a top-level
function. This means that Dconv (operand pretty printer) doesn't need
an Rconv argument.

To do this, we make the register numbers, which are arbitrary inside an
operand (obj.Addr), disjoint sets for each architecture. Each architecture
registers (ha) a piece of the space and then the global Rconv knows which
architecture-specific printer to use.

Clean up all the code that uses Dconv.

Now register numbers are large, so a couple of fields in Addr need to go
from int8 to int16 because they sometimes hold register numbers. Clean
up their uses, which meant regenerating the yacc grammars for the
assemblers. There are changes in this CL triggered by earlier changes
to yacc, which had not been run in this directory.

There is still cleanup to do in Addr, but we're getting closer to that being
easy to do.

Change-Id: I9290ebee013b62f7d24e886743ea5a6b232990ab
Reviewed-on: https://go-review.googlesource.com/6220
Reviewed-by: Russ Cox <rsc@golang.org>
This commit is contained in:
Rob Pike 2015-02-26 17:09:16 -08:00
parent 95bf77bc68
commit daddeb2686
36 changed files with 1177 additions and 756 deletions

File diff suppressed because it is too large Load diff

View file

@ -64,7 +64,7 @@ func gclean() {
for i := 0; i < len(reg); i++ { for i := 0; i < len(reg); i++ {
if reg[i] != 0 { if reg[i] != 0 {
gc.Yyerror("reg %v left allocated\n", gc.Ctxt.Rconv(i)) gc.Yyerror("reg %v left allocated\n", obj.Rconv(i))
} }
} }
} }
@ -216,7 +216,7 @@ func regfree(n *gc.Node) {
gc.Fatal("regfree: reg out of range") gc.Fatal("regfree: reg out of range")
} }
if reg[i] <= 0 { if reg[i] <= 0 {
gc.Fatal("regfree: reg %v not allocated", gc.Ctxt.Rconv(i)) gc.Fatal("regfree: reg %v not allocated", obj.Rconv(i))
} }
reg[i]-- reg[i]--
if reg[i] == 0 { if reg[i] == 0 {

View file

@ -521,7 +521,7 @@ omem:
$$.Type = obj.TYPE_MEM $$.Type = obj.TYPE_MEM
$$.Offset = $1; $$.Offset = $1;
$$.Index = int16($3); $$.Index = int16($3);
$$.Scale = int8($5); $$.Scale = int16($5);
checkscale($$.Scale); checkscale($$.Scale);
} }
| con '(' LLREG ')' '(' LLREG '*' con ')' | con '(' LLREG ')' '(' LLREG '*' con ')'
@ -531,7 +531,7 @@ omem:
$$.Reg = int16($3) $$.Reg = int16($3)
$$.Offset = $1; $$.Offset = $1;
$$.Index = int16($6); $$.Index = int16($6);
$$.Scale = int8($8); $$.Scale = int16($8);
checkscale($$.Scale); checkscale($$.Scale);
} }
| con '(' LLREG ')' '(' LSREG '*' con ')' | con '(' LLREG ')' '(' LSREG '*' con ')'
@ -541,7 +541,7 @@ omem:
$$.Reg = int16($3) $$.Reg = int16($3)
$$.Offset = $1; $$.Offset = $1;
$$.Index = int16($6); $$.Index = int16($6);
$$.Scale = int8($8); $$.Scale = int16($8);
checkscale($$.Scale); checkscale($$.Scale);
} }
| '(' LLREG ')' | '(' LLREG ')'
@ -561,7 +561,7 @@ omem:
$$ = nullgen; $$ = nullgen;
$$.Type = obj.TYPE_MEM $$.Type = obj.TYPE_MEM
$$.Index = int16($2); $$.Index = int16($2);
$$.Scale = int8($4); $$.Scale = int16($4);
checkscale($$.Scale); checkscale($$.Scale);
} }
| '(' LLREG ')' '(' LLREG '*' con ')' | '(' LLREG ')' '(' LLREG '*' con ')'
@ -570,7 +570,7 @@ omem:
$$.Type = obj.TYPE_MEM $$.Type = obj.TYPE_MEM
$$.Reg = int16($2) $$.Reg = int16($2)
$$.Index = int16($5); $$.Index = int16($5);
$$.Scale = int8($7); $$.Scale = int16($7);
checkscale($$.Scale); checkscale($$.Scale);
} }
@ -583,7 +583,7 @@ nmem:
{ {
$$ = $1; $$ = $1;
$$.Index = int16($3); $$.Index = int16($3);
$$.Scale = int8($5); $$.Scale = int16($5);
checkscale($$.Scale); checkscale($$.Scale);
} }

View file

@ -918,7 +918,7 @@ var lexinit = []asm.Lextab{
func cinit() { func cinit() {
} }
func checkscale(scale int8) { func checkscale(scale int16) {
switch scale { switch scale {
case 1, case 1,
2, 2,

File diff suppressed because it is too large Load diff

View file

@ -838,7 +838,7 @@ func agenr(n *gc.Node, a *gc.Node, res *gc.Node) {
if w == 1 || w == 2 || w == 4 || w == 8 { if w == 1 || w == 2 || w == 4 || w == 8 {
p1 := gins(x86.ALEAQ, &n2, &n3) p1 := gins(x86.ALEAQ, &n2, &n3)
p1.From.Type = obj.TYPE_MEM p1.From.Type = obj.TYPE_MEM
p1.From.Scale = int8(w) p1.From.Scale = int16(w)
p1.From.Index = p1.From.Reg p1.From.Index = p1.From.Reg
p1.From.Reg = p1.To.Reg p1.From.Reg = p1.To.Reg
} else { } else {

View file

@ -89,12 +89,12 @@ func gclean() {
for i := x86.REG_AX; i <= x86.REG_R15; i++ { for i := x86.REG_AX; i <= x86.REG_R15; i++ {
if reg[i] != 0 { if reg[i] != 0 {
gc.Yyerror("reg %v left allocated\n", gc.Ctxt.Rconv(i)) gc.Yyerror("reg %v left allocated\n", obj.Rconv(i))
} }
} }
for i := x86.REG_X0; i <= x86.REG_X15; i++ { for i := x86.REG_X0; i <= x86.REG_X15; i++ {
if reg[i] != 0 { if reg[i] != 0 {
gc.Yyerror("reg %v left allocated\n", gc.Ctxt.Rconv(i)) gc.Yyerror("reg %v left allocated\n", obj.Rconv(i))
} }
} }
} }

View file

@ -534,7 +534,7 @@ omem:
$$.Type = obj.TYPE_MEM $$.Type = obj.TYPE_MEM
$$.Offset = $1; $$.Offset = $1;
$$.Index = int16($3); $$.Index = int16($3);
$$.Scale = int8($5); $$.Scale = int16($5);
checkscale($$.Scale); checkscale($$.Scale);
} }
| con '(' LLREG ')' '(' LLREG '*' con ')' | con '(' LLREG ')' '(' LLREG '*' con ')'
@ -544,7 +544,7 @@ omem:
$$.Reg = int16($3) $$.Reg = int16($3)
$$.Offset = $1; $$.Offset = $1;
$$.Index = int16($6); $$.Index = int16($6);
$$.Scale = int8($8); $$.Scale = int16($8);
checkscale($$.Scale); checkscale($$.Scale);
} }
| con '(' LLREG ')' '(' LSREG '*' con ')' | con '(' LLREG ')' '(' LSREG '*' con ')'
@ -554,7 +554,7 @@ omem:
$$.Reg = int16($3) $$.Reg = int16($3)
$$.Offset = $1; $$.Offset = $1;
$$.Index = int16($6); $$.Index = int16($6);
$$.Scale = int8($8); $$.Scale = int16($8);
checkscale($$.Scale); checkscale($$.Scale);
} }
| '(' LLREG ')' | '(' LLREG ')'
@ -581,7 +581,7 @@ omem:
$$ = nullgen; $$ = nullgen;
$$.Type = obj.TYPE_MEM $$.Type = obj.TYPE_MEM
$$.Index = int16($2); $$.Index = int16($2);
$$.Scale = int8($4); $$.Scale = int16($4);
checkscale($$.Scale); checkscale($$.Scale);
} }
| '(' LLREG ')' '(' LLREG '*' con ')' | '(' LLREG ')' '(' LLREG '*' con ')'
@ -590,7 +590,7 @@ omem:
$$.Type = obj.TYPE_MEM $$.Type = obj.TYPE_MEM
$$.Reg = int16($2) $$.Reg = int16($2)
$$.Index = int16($5); $$.Index = int16($5);
$$.Scale = int8($7); $$.Scale = int16($7);
checkscale($$.Scale); checkscale($$.Scale);
} }
@ -603,7 +603,7 @@ nmem:
{ {
$$ = $1; $$ = $1;
$$.Index = int16($3); $$.Index = int16($3);
$$.Scale = int8($5); $$.Scale = int16($5);
checkscale($$.Scale); checkscale($$.Scale);
} }

View file

@ -706,7 +706,7 @@ func cinit() {
nullgen.Index = i386.REG_NONE nullgen.Index = i386.REG_NONE
} }
func checkscale(scale int8) { func checkscale(scale int16) {
switch scale { switch scale {
case 1, case 1,
2, 2,

File diff suppressed because it is too large Load diff

View file

@ -774,7 +774,7 @@ func agen(n *gc.Node, res *gc.Node) {
// LEAL (n3)(n2*w), n3 // LEAL (n3)(n2*w), n3
p1 := gins(i386.ALEAL, &n2, &n3) p1 := gins(i386.ALEAL, &n2, &n3)
p1.From.Scale = int8(w) p1.From.Scale = int16(w)
p1.From.Type = obj.TYPE_MEM p1.From.Type = obj.TYPE_MEM
p1.From.Index = p1.From.Reg p1.From.Index = p1.From.Reg
p1.From.Reg = p1.To.Reg p1.From.Reg = p1.To.Reg

View file

@ -582,12 +582,12 @@ func gclean() {
for i := i386.REG_AX; i <= i386.REG_DI; i++ { for i := i386.REG_AX; i <= i386.REG_DI; i++ {
if reg[i] != 0 { if reg[i] != 0 {
gc.Yyerror("reg %v left allocated at %x", gc.Ctxt.Rconv(i), regpc[i]) gc.Yyerror("reg %v left allocated at %x", obj.Rconv(i), regpc[i])
} }
} }
for i := i386.REG_X0; i <= i386.REG_X7; i++ { for i := i386.REG_X0; i <= i386.REG_X7; i++ {
if reg[i] != 0 { if reg[i] != 0 {
gc.Yyerror("reg %v left allocated\n", gc.Ctxt.Rconv(i)) gc.Yyerror("reg %v left allocated\n", obj.Rconv(i))
} }
} }
} }
@ -657,7 +657,7 @@ func regalloc(n *gc.Node, t *gc.Type, o *gc.Node) {
fmt.Printf("registers allocated at\n") fmt.Printf("registers allocated at\n")
for i := i386.REG_AX; i <= i386.REG_DI; i++ { for i := i386.REG_AX; i <= i386.REG_DI; i++ {
fmt.Printf("\t%v\t%#x\n", gc.Ctxt.Rconv(i), regpc[i]) fmt.Printf("\t%v\t%#x\n", obj.Rconv(i), regpc[i])
} }
gc.Fatal("out of fixed registers") gc.Fatal("out of fixed registers")
goto err goto err
@ -683,7 +683,7 @@ func regalloc(n *gc.Node, t *gc.Type, o *gc.Node) {
} }
fmt.Printf("registers allocated at\n") fmt.Printf("registers allocated at\n")
for i := i386.REG_X0; i <= i386.REG_X7; i++ { for i := i386.REG_X0; i <= i386.REG_X7; i++ {
fmt.Printf("\t%v\t%#x\n", gc.Ctxt.Rconv(i), regpc[i]) fmt.Printf("\t%v\t%#x\n", obj.Rconv(i), regpc[i])
} }
gc.Fatal("out of floating registers") gc.Fatal("out of floating registers")
} }
@ -702,7 +702,7 @@ out:
regpc[i] = uint32(obj.Getcallerpc(&n)) regpc[i] = uint32(obj.Getcallerpc(&n))
if i == i386.REG_AX || i == i386.REG_CX || i == i386.REG_DX || i == i386.REG_SP { if i == i386.REG_AX || i == i386.REG_CX || i == i386.REG_DX || i == i386.REG_SP {
gc.Dump("regalloc-o", o) gc.Dump("regalloc-o", o)
gc.Fatal("regalloc %v", gc.Ctxt.Rconv(i)) gc.Fatal("regalloc %v", obj.Rconv(i))
} }
} }
@ -729,7 +729,7 @@ func regfree(n *gc.Node) {
} }
reg[i]-- reg[i]--
if reg[i] == 0 && (i == i386.REG_AX || i == i386.REG_CX || i == i386.REG_DX || i == i386.REG_SP) { if reg[i] == 0 && (i == i386.REG_AX || i == i386.REG_CX || i == i386.REG_DX || i == i386.REG_SP) {
gc.Fatal("regfree %v", gc.Ctxt.Rconv(i)) gc.Fatal("regfree %v", obj.Rconv(i))
} }
} }

View file

@ -927,7 +927,7 @@ regaddr:
$$ = nullgen; $$ = nullgen;
$$.Type = obj.TYPE_MEM; $$.Type = obj.TYPE_MEM;
$$.Reg = int16($2); $$.Reg = int16($2);
$$.Scale = int8($4); $$.Scale = int16($4);
$$.Offset = 0; $$.Offset = 0;
} }

View file

@ -1786,7 +1786,7 @@ yydefault:
yyVAL.addr = nullgen yyVAL.addr = nullgen
yyVAL.addr.Type = obj.TYPE_MEM yyVAL.addr.Type = obj.TYPE_MEM
yyVAL.addr.Reg = int16(yyDollar[2].lval) yyVAL.addr.Reg = int16(yyDollar[2].lval)
yyVAL.addr.Scale = int8(yyDollar[4].lval) yyVAL.addr.Scale = int16(yyDollar[4].lval)
yyVAL.addr.Offset = 0 yyVAL.addr.Offset = 0
} }
case 157: case 157:

View file

@ -747,15 +747,15 @@ func clearfat(nl *gc.Node) {
c := uint64(w % 8) // bytes c := uint64(w % 8) // bytes
q := uint64(w / 8) // dwords q := uint64(w / 8) // dwords
if reg[ppc64.REGRT1] > 0 { if reg[ppc64.REGRT1-ppc64.REG_R0] > 0 {
gc.Fatal("R%d in use during clearfat", ppc64.REGRT1) gc.Fatal("R%d in use during clearfat", ppc64.REGRT1-ppc64.REG_R0)
} }
var r0 gc.Node var r0 gc.Node
gc.Nodreg(&r0, gc.Types[gc.TUINT64], ppc64.REG_R0) // r0 is always zero gc.Nodreg(&r0, gc.Types[gc.TUINT64], ppc64.REG_R0) // r0 is always zero
var dst gc.Node var dst gc.Node
gc.Nodreg(&dst, gc.Types[gc.Tptr], ppc64.REGRT1) gc.Nodreg(&dst, gc.Types[gc.Tptr], ppc64.REGRT1)
reg[ppc64.REGRT1]++ reg[ppc64.REGRT1-ppc64.REG_R0]++
agen(nl, &dst) agen(nl, &dst)
var boff uint64 var boff uint64
@ -812,7 +812,7 @@ func clearfat(nl *gc.Node) {
p.To.Offset = int64(t + boff) p.To.Offset = int64(t + boff)
} }
reg[ppc64.REGRT1]-- reg[ppc64.REGRT1-ppc64.REG_R0]--
} }
// Called after regopt and peep have run. // Called after regopt and peep have run.

View file

@ -63,14 +63,14 @@ var resvd = []int{
} }
func ginit() { func ginit() {
for i := int(0); i < len(reg); i++ { for i := 0; i < len(reg); i++ {
reg[i] = 1 reg[i] = 1
} }
for i := int(0); i < ppc64.NREG+ppc64.NFREG; i++ { for i := 0; i < ppc64.NREG+ppc64.NFREG; i++ {
reg[i] = 0 reg[i] = 0
} }
for i := int(0); i < len(resvd); i++ { for i := 0; i < len(resvd); i++ {
reg[resvd[i]-ppc64.REG_R0]++ reg[resvd[i]-ppc64.REG_R0]++
} }
} }
@ -84,7 +84,7 @@ func gclean() {
for i := int(0); i < len(reg); i++ { for i := int(0); i < len(reg); i++ {
if reg[i] != 0 { if reg[i] != 0 {
gc.Yyerror("reg %v left allocated, %p\n", gc.Ctxt.Rconv(i+ppc64.REG_R0), regpc[i]) gc.Yyerror("reg %v left allocated, %p\n", obj.Rconv(i+ppc64.REG_R0), regpc[i])
} }
} }
} }

View file

@ -38,8 +38,6 @@ type Arch struct {
IsJump func(word string) bool IsJump func(word string) bool
// Aconv pretty-prints an instruction opcode for this architecture. // Aconv pretty-prints an instruction opcode for this architecture.
Aconv func(int) string Aconv func(int) string
// Rconv pretty-prints a register for this architecture.
Rconv func(int) string
} }
// nilRegisterNumber is the register number function for architectures // nilRegisterNumber is the register number function for architectures
@ -188,7 +186,6 @@ func arch386() *Arch {
UnaryDestination: unaryDestination, UnaryDestination: unaryDestination,
IsJump: jump386, IsJump: jump386,
Aconv: i386.Aconv, Aconv: i386.Aconv,
Rconv: i386.Rconv,
} }
} }
@ -309,7 +306,6 @@ func archAmd64() *Arch {
UnaryDestination: unaryDestination, UnaryDestination: unaryDestination,
IsJump: jump386, IsJump: jump386,
Aconv: x86.Aconv, Aconv: x86.Aconv,
Rconv: x86.Rconv,
} }
} }
@ -320,7 +316,7 @@ func archArm() *Arch {
// Note that there is no list of names as there is for 386 and amd64. // Note that there is no list of names as there is for 386 and amd64.
// TODO: Are there aliases we need to add? // TODO: Are there aliases we need to add?
for i := arm.REG_R0; i < arm.REG_SPSR; i++ { for i := arm.REG_R0; i < arm.REG_SPSR; i++ {
register[arm.Rconv(i)] = int16(i) register[obj.Rconv(i)] = int16(i)
} }
// Avoid unintentionally clobbering g using R10. // Avoid unintentionally clobbering g using R10.
delete(register, "R10") delete(register, "R10")
@ -362,7 +358,6 @@ func archArm() *Arch {
UnaryDestination: unaryDestination, UnaryDestination: unaryDestination,
IsJump: jumpArm, IsJump: jumpArm,
Aconv: arm.Aconv, Aconv: arm.Aconv,
Rconv: arm.Rconv,
} }
} }
@ -372,17 +367,17 @@ func archPPC64() *Arch {
// TODO: Should this be done in obj for us? // TODO: Should this be done in obj for us?
// Note that there is no list of names as there is for 386 and amd64. // Note that there is no list of names as there is for 386 and amd64.
for i := ppc64.REG_R0; i <= ppc64.REG_R31; i++ { for i := ppc64.REG_R0; i <= ppc64.REG_R31; i++ {
register[ppc64.Rconv(i)] = int16(i) register[obj.Rconv(i)] = int16(i)
} }
for i := ppc64.REG_F0; i <= ppc64.REG_F31; i++ { for i := ppc64.REG_F0; i <= ppc64.REG_F31; i++ {
register[ppc64.Rconv(i)] = int16(i) register[obj.Rconv(i)] = int16(i)
} }
for i := ppc64.REG_C0; i <= ppc64.REG_C7; i++ { for i := ppc64.REG_C0; i <= ppc64.REG_C7; i++ {
// TODO: Rconv prints these as C7 but the input syntax requires CR7. // TODO: Rconv prints these as C7 but the input syntax requires CR7.
register[fmt.Sprintf("CR%d", i-ppc64.REG_C0)] = int16(i) register[fmt.Sprintf("CR%d", i-ppc64.REG_C0)] = int16(i)
} }
for i := ppc64.REG_MSR; i <= ppc64.REG_CR; i++ { for i := ppc64.REG_MSR; i <= ppc64.REG_CR; i++ {
register[ppc64.Rconv(i)] = int16(i) register[obj.Rconv(i)] = int16(i)
} }
register["CR"] = ppc64.REG_CR register["CR"] = ppc64.REG_CR
register["XER"] = ppc64.REG_XER register["XER"] = ppc64.REG_XER
@ -422,6 +417,5 @@ func archPPC64() *Arch {
UnaryDestination: nil, UnaryDestination: nil,
IsJump: jumpPPC64, IsJump: jumpPPC64,
Aconv: ppc64.Aconv, Aconv: ppc64.Aconv,
Rconv: ppc64.Rconv,
} }
} }

View file

@ -73,7 +73,7 @@ func (p *Parser) evalInteger(pseudo string, operands []lex.Token) int64 {
// validateImmediate checks that addr represents an immediate constant. // validateImmediate checks that addr represents an immediate constant.
func (p *Parser) validateImmediate(pseudo string, addr *obj.Addr) { func (p *Parser) validateImmediate(pseudo string, addr *obj.Addr) {
if addr.Type != obj.TYPE_CONST || addr.Name != 0 || addr.Reg != 0 || addr.Index != 0 { if addr.Type != obj.TYPE_CONST || addr.Name != 0 || addr.Reg != 0 || addr.Index != 0 {
p.errorf("%s: expected immediate constant; found %s", pseudo, obj.Dconv(&emptyProg, p.arch.Rconv, addr)) p.errorf("%s: expected immediate constant; found %s", pseudo, obj.Dconv(&emptyProg, addr))
} }
} }
@ -461,12 +461,12 @@ func (p *Parser) asmInstruction(op int, cond string, a []obj.Addr) {
// DX:AX as a register pair can only appear on the RHS. // DX:AX as a register pair can only appear on the RHS.
// Bizarrely, to obj it's specified by setting index on the LHS. // Bizarrely, to obj it's specified by setting index on the LHS.
// TODO: can we fix this? // TODO: can we fix this?
if a[1].Class != 0 { if a[1].Reg2 != 0 {
if a[0].Class != 0 { if a[0].Reg2 != 0 {
p.errorf("register pair must be on LHS") p.errorf("register pair must be on LHS")
} }
prog.From.Index = int16(a[1].Class) prog.From.Index = int16(a[1].Reg2)
prog.To.Class = 0 prog.To.Reg2 = 0
} }
case '9': case '9':
var reg0, reg1 int16 var reg0, reg1 int16
@ -642,7 +642,7 @@ var emptyProg obj.Prog
// getConstantPseudo checks that addr represents a plain constant and returns its value. // getConstantPseudo checks that addr represents a plain constant and returns its value.
func (p *Parser) getConstantPseudo(pseudo string, addr *obj.Addr) int64 { func (p *Parser) getConstantPseudo(pseudo string, addr *obj.Addr) int64 {
if addr.Type != obj.TYPE_MEM || addr.Name != 0 || addr.Reg != 0 || addr.Index != 0 { if addr.Type != obj.TYPE_MEM || addr.Name != 0 || addr.Reg != 0 || addr.Index != 0 {
p.errorf("%s: expected integer constant; found %s", pseudo, obj.Dconv(&emptyProg, p.arch.Rconv, addr)) p.errorf("%s: expected integer constant; found %s", pseudo, obj.Dconv(&emptyProg, addr))
} }
return addr.Offset return addr.Offset
} }
@ -650,7 +650,7 @@ func (p *Parser) getConstantPseudo(pseudo string, addr *obj.Addr) int64 {
// getConstant checks that addr represents a plain constant and returns its value. // 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 { 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 { 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, p.arch.Rconv, addr)) p.errorf("%s: expected integer constant; found %s", p.arch.Aconv(op), obj.Dconv(prog, addr))
} }
return addr.Offset return addr.Offset
} }
@ -658,7 +658,7 @@ func (p *Parser) getConstant(prog *obj.Prog, op int, addr *obj.Addr) int64 {
// getImmediate checks that addr represents an immediate constant and returns its value. // 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 { 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 { 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, p.arch.Rconv, addr)) p.errorf("%s: expected immediate constant; found %s", p.arch.Aconv(op), obj.Dconv(prog, addr))
} }
return addr.Offset return addr.Offset
} }
@ -666,7 +666,7 @@ func (p *Parser) getImmediate(prog *obj.Prog, op int, addr *obj.Addr) int64 {
// getRegister checks that addr represents a register and returns its value. // getRegister checks that addr represents a register and returns its value.
func (p *Parser) getRegister(prog *obj.Prog, op int, addr *obj.Addr) int16 { 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 { 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, p.arch.Rconv, addr)) p.errorf("%s: expected register; found %s", p.arch.Aconv(op), obj.Dconv(prog, addr))
} }
return addr.Reg return addr.Reg
} }

View file

@ -34,7 +34,7 @@ func testOperandParser(t *testing.T, parser *Parser, tests []operandTest) {
parser.start(lex.Tokenize(test.input)) parser.start(lex.Tokenize(test.input))
addr := obj.Addr{} addr := obj.Addr{}
parser.operand(&addr) parser.operand(&addr)
result := obj.Dconv(&emptyProg, parser.arch.Rconv, &addr) result := obj.Dconv(&emptyProg, &addr)
if result != test.output { if result != test.output {
t.Errorf("fail at %s: got %s; expected %s\n", test.input, result, test.output) t.Errorf("fail at %s: got %s; expected %s\n", test.input, result, test.output)
} }
@ -48,9 +48,9 @@ func testX86RegisterPair(t *testing.T, parser *Parser) {
addr := obj.Addr{} addr := obj.Addr{}
parser.operand(&addr) parser.operand(&addr)
want := obj.Addr{ want := obj.Addr{
Type: obj.TYPE_REG, Type: obj.TYPE_REG,
Reg: parser.arch.Register["AX"], Reg: parser.arch.Register["AX"],
Class: int8(parser.arch.Register["BX"]), // TODO: clean up how this is encoded in parse.go Reg2: parser.arch.Register["BX"], // TODO: clean up how this is encoded in parse.go
} }
if want != addr { if want != addr {
t.Errorf("AX:DX: expected %+v got %+v", want, addr) t.Errorf("AX:DX: expected %+v got %+v", want, addr)
@ -65,7 +65,7 @@ func testX86RegisterPair(t *testing.T, parser *Parser) {
Name: obj.NAME_EXTERN, Name: obj.NAME_EXTERN,
Offset: 4, Offset: 4,
Sym: obj.Linklookup(parser.ctxt, "foo", 0), Sym: obj.Linklookup(parser.ctxt, "foo", 0),
Class: int8(parser.arch.Register["AX"]), // TODO: clean up how this is encoded in parse.go Reg2: parser.arch.Register["AX"], // TODO: clean up how this is encoded in parse.go
} }
if want != addr { if want != addr {
t.Errorf("foo+4(SB):AX: expected %+v got %+v", want, addr) t.Errorf("foo+4(SB):AX: expected %+v got %+v", want, addr)
@ -99,7 +99,7 @@ func TestPPC64OperandParser(t *testing.T) {
want := obj.Addr{ want := obj.Addr{
Type: obj.TYPE_MEM, Type: obj.TYPE_MEM,
Reg: parser.arch.Register["R1"], Reg: parser.arch.Register["R1"],
Scale: int8(parser.arch.Register["R2"]), // TODO: clean up how this is encoded in parse.go Scale: parser.arch.Register["R2"], // TODO: clean up how this is encoded in parse.go
} }
if want != addr { if want != addr {
t.Errorf("(R1+R2): expected %+v got %+v", want, addr) t.Errorf("(R1+R2): expected %+v got %+v", want, addr)

View file

@ -255,7 +255,7 @@ func (p *Parser) operand(a *obj.Addr) bool {
if tok.ScanToken == scanner.Ident && !p.atStartOfRegister(name) { if tok.ScanToken == scanner.Ident && !p.atStartOfRegister(name) {
// We have a symbol. Parse $sym±offset(symkind) // We have a symbol. Parse $sym±offset(symkind)
p.symbolReference(a, name, prefix) p.symbolReference(a, name, prefix)
// fmt.Printf("SYM %s\n", obj.Dconv(&emptyProg, 0, p.arch.Rconv, a)) // fmt.Printf("SYM %s\n", obj.Dconv(&emptyProg, 0, a))
if p.peek() == scanner.EOF { if p.peek() == scanner.EOF {
return true return true
} }
@ -297,10 +297,10 @@ func (p *Parser) operand(a *obj.Addr) bool {
if r2 != 0 { if r2 != 0 {
// Form is R1:R2. It is on RHS and the second register // Form is R1:R2. It is on RHS and the second register
// needs to go into the LHS. This is a horrible hack. TODO. // needs to go into the LHS. This is a horrible hack. TODO.
a.Class = int8(r2) a.Reg2 = r2
} }
} }
// fmt.Printf("REG %s\n", obj.Dconv(&emptyProg, 0, p.arch.Rconv, a)) // fmt.Printf("REG %s\n", obj.Dconv(&emptyProg, 0, a))
p.expect(scanner.EOF) p.expect(scanner.EOF)
return true return true
} }
@ -327,7 +327,7 @@ func (p *Parser) operand(a *obj.Addr) bool {
} }
a.Type = obj.TYPE_FCONST a.Type = obj.TYPE_FCONST
a.U.Dval = p.floatExpr() a.U.Dval = p.floatExpr()
// fmt.Printf("FCONST %s\n", obj.Dconv(&emptyProg, 0, p.arch.Rconv, a)) // fmt.Printf("FCONST %s\n", obj.Dconv(&emptyProg, 0, a))
p.expect(scanner.EOF) p.expect(scanner.EOF)
return true return true
} }
@ -341,7 +341,7 @@ func (p *Parser) operand(a *obj.Addr) bool {
} }
a.Type = obj.TYPE_SCONST a.Type = obj.TYPE_SCONST
a.U.Sval = str a.U.Sval = str
// fmt.Printf("SCONST %s\n", obj.Dconv(&emptyProg, 0, p.arch.Rconv, a)) // fmt.Printf("SCONST %s\n", obj.Dconv(&emptyProg, 0, a))
p.expect(scanner.EOF) p.expect(scanner.EOF)
return true return true
} }
@ -355,7 +355,7 @@ func (p *Parser) operand(a *obj.Addr) bool {
default: default:
a.Type = obj.TYPE_MEM a.Type = obj.TYPE_MEM
} }
// fmt.Printf("CONST %d %s\n", a.Offset, obj.Dconv(&emptyProg, 0, p.arch.Rconv, a)) // fmt.Printf("CONST %d %s\n", a.Offset, obj.Dconv(&emptyProg, 0, a))
p.expect(scanner.EOF) p.expect(scanner.EOF)
return true return true
} }
@ -363,13 +363,13 @@ func (p *Parser) operand(a *obj.Addr) bool {
} }
// Odd x86 case: sym+4(SB):AX. Have name, colon, register. // Odd x86 case: sym+4(SB):AX. Have name, colon, register.
if p.peek() == ':' && a.Name != obj.NAME_NONE && a.Class == 0 && (p.arch.Thechar == '6' || p.arch.Thechar == '8') { if p.peek() == ':' && a.Name != obj.NAME_NONE && a.Reg2 == 0 && (p.arch.Thechar == '6' || p.arch.Thechar == '8') {
p.get(':') p.get(':')
r2, ok := p.registerReference(p.next().String()) r2, ok := p.registerReference(p.next().String())
if !ok { if !ok {
return false return false
} }
a.Class = int8(r2) // TODO: See comment about Class above. a.Reg2 = r2 // TODO: See comment about Reg3 above.
} else { } else {
// Register indirection: (reg) or (index*scale). We are on the opening paren. // Register indirection: (reg) or (index*scale). We are on the opening paren.
p.registerIndirect(a, prefix) p.registerIndirect(a, prefix)
@ -646,7 +646,7 @@ func (p *Parser) registerIndirect(a *obj.Addr, prefix rune) {
} }
// TODO: This is rewritten in asm. Clumsy. // TODO: This is rewritten in asm. Clumsy.
a.Type = obj.TYPE_MEM a.Type = obj.TYPE_MEM
a.Scale = int8(r2) a.Scale = r2
// Nothing may follow. // Nothing may follow.
return return
} }
@ -672,13 +672,13 @@ func (p *Parser) registerIndirect(a *obj.Addr, prefix rune) {
p.errorf("unimplemented two-register form") p.errorf("unimplemented two-register form")
} }
a.Index = r1 a.Index = r1
a.Scale = scale a.Scale = int16(scale)
p.get(')') p.get(')')
} else if scale != 0 { } else if scale != 0 {
// First (R) was missing, all we have is (R*scale). // First (R) was missing, all we have is (R*scale).
a.Reg = 0 a.Reg = 0
a.Index = r1 a.Index = r1
a.Scale = scale a.Scale = int16(scale)
} }
} }

View file

@ -1257,7 +1257,7 @@ func exprfmt(n *Node, prec int) string {
case OREGISTER: case OREGISTER:
var f string var f string
f += fmt.Sprintf("%v", Ctxt.Rconv(int(n.Val.U.Reg))) f += fmt.Sprintf("%v", obj.Rconv(int(n.Val.U.Reg)))
return f return f
case OLITERAL: // this is a bit of a mess case OLITERAL: // this is a bit of a mess
@ -1787,7 +1787,7 @@ func nodedump(n *Node, flag int) string {
case OREGISTER, case OREGISTER,
OINDREG: OINDREG:
fp += fmt.Sprintf("%v-%v%v", Oconv(int(n.Op), 0), Ctxt.Rconv(int(n.Val.U.Reg)), Jconv(n, 0)) fp += fmt.Sprintf("%v-%v%v", Oconv(int(n.Op), 0), obj.Rconv(int(n.Val.U.Reg)), Jconv(n, 0))
case OLITERAL: case OLITERAL:
fp += fmt.Sprintf("%v-%v%v", Oconv(int(n.Op), 0), Vconv(&n.Val, 0), Jconv(n, 0)) fp += fmt.Sprintf("%v-%v%v", Oconv(int(n.Op), 0), Vconv(&n.Val, 0), Jconv(n, 0))

View file

@ -1283,7 +1283,7 @@ brk:
if rgp.regno != 0 { if rgp.regno != 0 {
if Debug['R'] != 0 && Debug['v'] != 0 { if Debug['R'] != 0 && Debug['v'] != 0 {
v := &var_[rgp.varno:][0] v := &var_[rgp.varno:][0]
fmt.Printf("registerize %v+%d (bit=%2d et=%v) in %v usedreg=%#x vreg=%#x\n", Nconv(v.node, 0), v.offset, rgp.varno, Econv(int(v.etype), 0), Ctxt.Rconv(int(rgp.regno)), usedreg, vreg) fmt.Printf("registerize %v+%d (bit=%2d et=%v) in %v usedreg=%#x vreg=%#x\n", Nconv(v.node, 0), v.offset, rgp.varno, Econv(int(v.etype), 0), obj.Rconv(int(rgp.regno)), usedreg, vreg)
} }
paint3(rgp.enter, int(rgp.varno), vreg, int(rgp.regno)) paint3(rgp.enter, int(rgp.varno), vreg, int(rgp.regno))

View file

@ -47,7 +47,7 @@ const (
) )
const ( const (
REG_R0 = 32 + iota REG_R0 = obj.RBaseARM + iota
REG_R1 REG_R1
REG_R2 REG_R2
REG_R3 REG_R3
@ -83,6 +83,7 @@ const (
REG_FPCR REG_FPCR
REG_CPSR REG_CPSR
REG_SPSR REG_SPSR
MAXREG
REGRET = REG_R0 REGRET = REG_R0
REGEXT = REG_R10 REGEXT = REG_R10
REGG = REGEXT - 0 REGG = REGEXT - 0

View file

@ -45,7 +45,7 @@ type Optab struct {
a3 uint8 a3 uint8
type_ uint8 type_ uint8
size int8 size int8
param int8 param int16
flag int8 flag int8
pcrelsiz uint8 pcrelsiz uint8
} }

View file

@ -86,26 +86,26 @@ func Pconv(p *obj.Prog) string {
if a == AMOVM { if a == AMOVM {
if p.From.Type == obj.TYPE_CONST { if p.From.Type == obj.TYPE_CONST {
str = fmt.Sprintf("%.5d (%v)\t%v%s\t%v,%v", str = fmt.Sprintf("%.5d (%v)\t%v%s\t%v,%v",
p.Pc, p.Line(), Aconv(a), sc, RAconv(&p.From), obj.Dconv(p, Rconv, &p.To)) p.Pc, p.Line(), Aconv(a), sc, RAconv(&p.From), obj.Dconv(p, &p.To))
} else if p.To.Type == obj.TYPE_CONST { } else if p.To.Type == obj.TYPE_CONST {
str = fmt.Sprintf("%.5d (%v)\t%v%s\t%v,%v", str = fmt.Sprintf("%.5d (%v)\t%v%s\t%v,%v",
p.Pc, p.Line(), Aconv(a), sc, obj.Dconv(p, Rconv, &p.From), RAconv(&p.To)) p.Pc, p.Line(), Aconv(a), sc, obj.Dconv(p, &p.From), RAconv(&p.To))
} else { } else {
str = fmt.Sprintf("%.5d (%v)\t%v%s\t%v,%v", str = fmt.Sprintf("%.5d (%v)\t%v%s\t%v,%v",
p.Pc, p.Line(), Aconv(a), sc, obj.Dconv(p, Rconv, &p.From), obj.Dconv(p, Rconv, &p.To)) p.Pc, p.Line(), Aconv(a), sc, obj.Dconv(p, &p.From), obj.Dconv(p, &p.To))
} }
} else if a == obj.ADATA { } else if a == obj.ADATA {
str = fmt.Sprintf("%.5d (%v)\t%v\t%v/%d,%v", str = fmt.Sprintf("%.5d (%v)\t%v\t%v/%d,%v",
p.Pc, p.Line(), Aconv(a), obj.Dconv(p, Rconv, &p.From), p.From3.Offset, obj.Dconv(p, Rconv, &p.To)) p.Pc, p.Line(), Aconv(a), obj.Dconv(p, &p.From), p.From3.Offset, obj.Dconv(p, &p.To))
} else if p.As == obj.ATEXT { } else if p.As == obj.ATEXT {
str = fmt.Sprintf("%.5d (%v)\t%v\t%v,%d,%v", str = fmt.Sprintf("%.5d (%v)\t%v\t%v,%d,%v",
p.Pc, p.Line(), Aconv(a), obj.Dconv(p, Rconv, &p.From), p.From3.Offset, obj.Dconv(p, Rconv, &p.To)) p.Pc, p.Line(), Aconv(a), obj.Dconv(p, &p.From), p.From3.Offset, obj.Dconv(p, &p.To))
} else if p.Reg == 0 { } else if p.Reg == 0 {
str = fmt.Sprintf("%.5d (%v)\t%v%s\t%v,%v", str = fmt.Sprintf("%.5d (%v)\t%v%s\t%v,%v",
p.Pc, p.Line(), Aconv(a), sc, obj.Dconv(p, Rconv, &p.From), obj.Dconv(p, Rconv, &p.To)) p.Pc, p.Line(), Aconv(a), sc, obj.Dconv(p, &p.From), obj.Dconv(p, &p.To))
} else { } else {
str = fmt.Sprintf("%.5d (%v)\t%v%s\t%v,%v,%v", str = fmt.Sprintf("%.5d (%v)\t%v%s\t%v,%v,%v",
p.Pc, p.Line(), Aconv(a), sc, obj.Dconv(p, Rconv, &p.From), Rconv(int(p.Reg)), obj.Dconv(p, Rconv, &p.To)) p.Pc, p.Line(), Aconv(a), sc, obj.Dconv(p, &p.From), Rconv(int(p.Reg)), obj.Dconv(p, &p.To))
} }
fp += str fp += str
@ -160,42 +160,36 @@ func RAconv(a *obj.Addr) string {
return fp return fp
} }
func Rconv(r int) string { func init() {
var fp string obj.RegisterRegister(obj.RBaseARM, MAXREG, Rconv)
}
func Rconv(r int) string {
if r == 0 { if r == 0 {
fp += "NONE" return "NONE"
return fp
} }
if REG_R0 <= r && r <= REG_R15 { if REG_R0 <= r && r <= REG_R15 {
fp += fmt.Sprintf("R%d", r-REG_R0) return fmt.Sprintf("R%d", r-REG_R0)
return fp
} }
if REG_F0 <= r && r <= REG_F15 { if REG_F0 <= r && r <= REG_F15 {
fp += fmt.Sprintf("F%d", r-REG_F0) return fmt.Sprintf("F%d", r-REG_F0)
return fp
} }
switch r { switch r {
case REG_FPSR: case REG_FPSR:
fp += "FPSR" return "FPSR"
return fp
case REG_FPCR: case REG_FPCR:
fp += "FPCR" return "FPCR"
return fp
case REG_CPSR: case REG_CPSR:
fp += "CPSR" return "CPSR"
return fp
case REG_SPSR: case REG_SPSR:
fp += "SPSR" return "SPSR"
return fp
} }
fp += fmt.Sprintf("badreg(%d)", r) return fmt.Sprintf("Rgok(%d)", r-obj.RBaseARM)
return fp
} }
func DRconv(a int) string { func DRconv(a int) string {

View file

@ -535,15 +535,15 @@ const (
const ( const (
REG_NONE = 0 REG_NONE = 0
REG_AL = 0 + 16 + iota - 1 REG_AL = obj.RBase386 + 0 + iota - 1
REG_CL REG_CL
REG_DL REG_DL
REG_BL REG_BL
REG_AH = 4 + 16 + iota - 5 REG_AH = obj.RBase386 + 4 + iota - 5
REG_CH REG_CH
REG_DH REG_DH
REG_BH REG_BH
REG_AX = 8 + 16 + iota - 9 REG_AX = obj.RBase386 + 8 + iota - 9
REG_CX REG_CX
REG_DX REG_DX
REG_BX REG_BX
@ -551,9 +551,9 @@ const (
REG_BP REG_BP
REG_SI REG_SI
REG_DI REG_DI
REG_F0 = 16 + 16 REG_F0 = obj.RBase386 + 16
REG_F7 = REG_F0 + 7 + 16 REG_F7 = obj.RBase386 + REG_F0 + 7
REG_CS = 24 + 16 + iota - 19 REG_CS = obj.RBase386 + 24 + iota - 19
REG_SS REG_SS
REG_DS REG_DS
REG_ES REG_ES
@ -564,10 +564,10 @@ const (
REG_LDTR REG_LDTR
REG_MSW REG_MSW
REG_TASK REG_TASK
REG_CR = 35 + 16 REG_CR = obj.RBase386 + 35
REG_DR = 43 + 16 REG_DR = obj.RBase386 + 43
REG_TR = 51 + 16 REG_TR = obj.RBase386 + 51
REG_X0 = 59 + 16 + iota - 33 REG_X0 = obj.RBase386 + 59 + iota - 33
REG_X1 REG_X1
REG_X2 REG_X2
REG_X3 REG_X3
@ -575,8 +575,8 @@ const (
REG_X5 REG_X5
REG_X6 REG_X6
REG_X7 REG_X7
REG_TLS = 67 + 16 REG_TLS = obj.RBase386 + 67
MAXREG = 68 + 16 MAXREG = obj.RBase386 + 68
T_TYPE = 1 << 0 T_TYPE = 1 << 0
T_INDEX = 1 << 1 T_INDEX = 1 << 1
T_OFFSET = 1 << 2 T_OFFSET = 1 << 2

View file

@ -1501,7 +1501,7 @@ func oclass(ctxt *obj.Link, p *obj.Prog, a *obj.Addr) int {
} }
if a.Sym != nil || a.Name != obj.NAME_NONE { if a.Sym != nil || a.Name != obj.NAME_NONE {
ctxt.Diag("unexpected addr: %v", obj.Dconv(p, Rconv, a)) ctxt.Diag("unexpected addr: %v", obj.Dconv(p, a))
} }
fallthrough fallthrough
@ -1509,7 +1509,7 @@ func oclass(ctxt *obj.Link, p *obj.Prog, a *obj.Addr) int {
case obj.TYPE_CONST: case obj.TYPE_CONST:
if a.Sym != nil { if a.Sym != nil {
ctxt.Diag("TYPE_CONST with symbol: %v", obj.Dconv(p, Rconv, a)) ctxt.Diag("TYPE_CONST with symbol: %v", obj.Dconv(p, a))
} }
v = int32(a.Offset) v = int32(a.Offset)
@ -1529,7 +1529,7 @@ func oclass(ctxt *obj.Link, p *obj.Prog, a *obj.Addr) int {
} }
if a.Type != obj.TYPE_REG { if a.Type != obj.TYPE_REG {
ctxt.Diag("unexpected addr1: type=%d %v", a.Type, obj.Dconv(p, Rconv, a)) ctxt.Diag("unexpected addr1: type=%d %v", a.Type, obj.Dconv(p, a))
return Yxxx return Yxxx
} }
@ -1772,7 +1772,7 @@ func vaddr(ctxt *obj.Link, p *obj.Prog, a *obj.Addr, r *obj.Reloc) int32 {
s = a.Sym s = a.Sym
if s != nil { if s != nil {
if r == nil { if r == nil {
ctxt.Diag("need reloc for %v", obj.Dconv(p, Rconv, a)) ctxt.Diag("need reloc for %v", obj.Dconv(p, a))
log.Fatalf("bad code") log.Fatalf("bad code")
} }
@ -1789,7 +1789,7 @@ func vaddr(ctxt *obj.Link, p *obj.Prog, a *obj.Addr, r *obj.Reloc) int32 {
if (a.Type == obj.TYPE_MEM || a.Type == obj.TYPE_ADDR) && a.Reg == REG_TLS { if (a.Type == obj.TYPE_MEM || a.Type == obj.TYPE_ADDR) && a.Reg == REG_TLS {
if r == nil { if r == nil {
ctxt.Diag("need reloc for %v", obj.Dconv(p, Rconv, a)) ctxt.Diag("need reloc for %v", obj.Dconv(p, a))
log.Fatalf("bad code") log.Fatalf("bad code")
} }
@ -1972,7 +1972,7 @@ putrelv:
return return
bad: bad:
ctxt.Diag("asmand: bad address %v", obj.Dconv(p, Rconv, a)) ctxt.Diag("asmand: bad address %v", obj.Dconv(p, a))
return return
} }

View file

@ -48,21 +48,21 @@ func Pconv(p *obj.Prog) string {
switch p.As { switch p.As {
case obj.ADATA: case obj.ADATA:
str = fmt.Sprintf("%.5d (%v)\t%v\t%v/%d,%v", str = fmt.Sprintf("%.5d (%v)\t%v\t%v/%d,%v",
p.Pc, p.Line(), Aconv(int(p.As)), obj.Dconv(p, Rconv, &p.From), p.From3.Offset, obj.Dconv(p, Rconv, &p.To)) p.Pc, p.Line(), Aconv(int(p.As)), obj.Dconv(p, &p.From), p.From3.Offset, obj.Dconv(p, &p.To))
case obj.ATEXT: case obj.ATEXT:
if p.From3.Offset != 0 { if p.From3.Offset != 0 {
str = fmt.Sprintf("%.5d (%v)\t%v\t%v,%d,%v", str = fmt.Sprintf("%.5d (%v)\t%v\t%v,%d,%v",
p.Pc, p.Line(), Aconv(int(p.As)), obj.Dconv(p, Rconv, &p.From), p.From3.Offset, obj.Dconv(p, Rconv, &p.To)) p.Pc, p.Line(), Aconv(int(p.As)), obj.Dconv(p, &p.From), p.From3.Offset, obj.Dconv(p, &p.To))
break break
} }
str = fmt.Sprintf("%.5d (%v)\t%v\t%v,%v", str = fmt.Sprintf("%.5d (%v)\t%v\t%v,%v",
p.Pc, p.Line(), Aconv(int(p.As)), obj.Dconv(p, Rconv, &p.From), obj.Dconv(p, Rconv, &p.To)) p.Pc, p.Line(), Aconv(int(p.As)), obj.Dconv(p, &p.From), obj.Dconv(p, &p.To))
default: default:
str = fmt.Sprintf("%.5d (%v)\t%v\t%v,%v", str = fmt.Sprintf("%.5d (%v)\t%v\t%v,%v",
p.Pc, p.Line(), Aconv(int(p.As)), obj.Dconv(p, Rconv, &p.From), obj.Dconv(p, Rconv, &p.To)) p.Pc, p.Line(), 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 // TODO(rsc): This special case is for SHRQ $32, AX:DX, which encodes as
// SHRQ $32(DX*0), AX // SHRQ $32(DX*0), AX
@ -155,20 +155,13 @@ var Register = []string{
"MAXREG", /* [MAXREG] */ "MAXREG", /* [MAXREG] */
} }
func Rconv(r int) string { func init() {
var str string obj.RegisterRegister(obj.RBase386, obj.RBase386+len(Register), Rconv)
var fp string }
if r == REG_NONE { func Rconv(r int) string {
fp += "NONE" if r >= REG_AL && r-REG_AL < len(Register) {
return fp return fmt.Sprintf("%s", Register[r-REG_AL])
} }
if r >= REG_AL && r-REG_AL < len(Register) { return fmt.Sprintf("Rgok(%d)", r-obj.RBase386)
str = fmt.Sprintf("%s", Register[r-REG_AL])
} else {
str = fmt.Sprintf("gok(%d)", r)
}
fp += str
return fp
} }

View file

@ -35,8 +35,9 @@ import "encoding/binary"
type Addr struct { type Addr struct {
Type int16 Type int16
Reg int16 Reg int16
Reg2 int16 // RHS of register pair. AX:DX (386)
Index int16 Index int16
Scale int8 Scale int16 // Sometimes holds a register.
Name int8 Name int8
Offset int64 Offset int64
Sym *LSym Sym *LSym

View file

@ -45,7 +45,7 @@ const (
// avoid conflict with ucontext.h. sigh. // avoid conflict with ucontext.h. sigh.
const ( const (
REG_R0 = 32 + iota REG_R0 = obj.RBasePPC64 + iota
REG_R1 REG_R1
REG_R2 REG_R2
REG_R3 REG_R3
@ -77,7 +77,7 @@ const (
REG_R29 REG_R29
REG_R30 REG_R30
REG_R31 REG_R31
REG_F0 = 64 + iota - 32 REG_F0 = obj.RBasePPC64 + 32 + iota - 32
REG_F1 REG_F1
REG_F2 REG_F2
REG_F3 REG_F3
@ -109,8 +109,8 @@ const (
REG_F29 REG_F29
REG_F30 REG_F30
REG_F31 REG_F31
REG_SPECIAL = 96 REG_SPECIAL = obj.RBasePPC64 + 64
REG_C0 = 96 + iota - 65 REG_C0 = obj.RBasePPC64 + 64 + iota - 65
REG_C1 REG_C1
REG_C2 REG_C2
REG_C3 REG_C3
@ -118,11 +118,11 @@ const (
REG_C5 REG_C5
REG_C6 REG_C6
REG_C7 REG_C7
REG_MSR = 104 + iota - 73 REG_MSR = obj.RBasePPC64 + 72 + iota - 73
REG_FPSCR REG_FPSCR
REG_CR REG_CR
REG_SPR0 = 1024 REG_SPR0 = obj.RBasePPC64 + 1024
REG_DCR0 = 2048 REG_DCR0 = obj.RBasePPC64 + 2048
REG_XER = REG_SPR0 + 1 REG_XER = REG_SPR0 + 1
REG_LR = REG_SPR0 + 8 REG_LR = REG_SPR0 + 8
REG_CTR = REG_SPR0 + 9 REG_CTR = REG_SPR0 + 9

View file

@ -54,7 +54,7 @@ type Optab struct {
a4 uint8 a4 uint8
type_ int8 type_ int8
size int8 size int8
param int8 param int16
} }
var optab = []Optab{ var optab = []Optab{

View file

@ -64,14 +64,14 @@ func Pconv(p *obj.Prog) string {
str = "" str = ""
if a == obj.ADATA { if a == obj.ADATA {
str = fmt.Sprintf("%.5d (%v)\t%v\t%v/%d,%v", str = fmt.Sprintf("%.5d (%v)\t%v\t%v/%d,%v",
p.Pc, p.Line(), Aconv(a), obj.Dconv(p, Rconv, &p.From), p.From3.Offset, obj.Dconv(p, Rconv, &p.To)) p.Pc, p.Line(), Aconv(a), obj.Dconv(p, &p.From), p.From3.Offset, obj.Dconv(p, &p.To))
} else if a == obj.ATEXT || a == obj.AGLOBL { } else if a == obj.ATEXT || a == obj.AGLOBL {
if p.From3.Offset != 0 { if p.From3.Offset != 0 {
str = fmt.Sprintf("%.5d (%v)\t%v\t%v,%d,%v", str = fmt.Sprintf("%.5d (%v)\t%v\t%v,%d,%v",
p.Pc, p.Line(), Aconv(a), obj.Dconv(p, Rconv, &p.From), p.From3.Offset, obj.Dconv(p, Rconv, &p.To)) p.Pc, p.Line(), Aconv(a), obj.Dconv(p, &p.From), p.From3.Offset, obj.Dconv(p, &p.To))
} else { } else {
str = fmt.Sprintf("%.5d (%v)\t%v\t%v,%v", str = fmt.Sprintf("%.5d (%v)\t%v\t%v,%v",
p.Pc, p.Line(), Aconv(a), obj.Dconv(p, Rconv, &p.From), obj.Dconv(p, Rconv, &p.To)) p.Pc, p.Line(), Aconv(a), obj.Dconv(p, &p.From), obj.Dconv(p, &p.To))
} }
} else { } else {
if p.Mark&NOSCHED != 0 { if p.Mark&NOSCHED != 0 {
@ -79,31 +79,31 @@ func Pconv(p *obj.Prog) string {
} }
if p.Reg == 0 && p.From3.Type == obj.TYPE_NONE { if p.Reg == 0 && p.From3.Type == obj.TYPE_NONE {
str += fmt.Sprintf("%.5d (%v)\t%v\t%v,%v", str += fmt.Sprintf("%.5d (%v)\t%v\t%v,%v",
p.Pc, p.Line(), Aconv(a), obj.Dconv(p, Rconv, &p.From), obj.Dconv(p, Rconv, &p.To)) p.Pc, p.Line(), Aconv(a), obj.Dconv(p, &p.From), obj.Dconv(p, &p.To))
} else if a != obj.ATEXT && p.From.Type == obj.TYPE_MEM { } else if a != obj.ATEXT && p.From.Type == obj.TYPE_MEM {
off := "" off := ""
if p.From.Offset != 0 { if p.From.Offset != 0 {
off = fmt.Sprintf("%d", p.From.Offset) off = fmt.Sprintf("%d", p.From.Offset)
} }
str += fmt.Sprintf("%.5d (%v)\t%v\t%s(%v+%v),%v", 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, Rconv, &p.To)) p.Pc, p.Line(), 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 { } else if p.To.Type == obj.TYPE_MEM {
off := "" off := ""
if p.From.Offset != 0 { if p.From.Offset != 0 {
off = fmt.Sprintf("%d", p.From.Offset) off = fmt.Sprintf("%d", p.From.Offset)
} }
str += fmt.Sprintf("%.5d (%v)\t%v\t%v,%s(%v+%v)", str += fmt.Sprintf("%.5d (%v)\t%v\t%v,%s(%v+%v)",
p.Pc, p.Line(), Aconv(a), obj.Dconv(p, Rconv, &p.From), off, Rconv(int(p.To.Reg)), Rconv(int(p.Reg))) p.Pc, p.Line(), Aconv(a), obj.Dconv(p, &p.From), off, Rconv(int(p.To.Reg)), Rconv(int(p.Reg)))
} else { } else {
str += fmt.Sprintf("%.5d (%v)\t%v\t%v", str += fmt.Sprintf("%.5d (%v)\t%v\t%v",
p.Pc, p.Line(), Aconv(a), obj.Dconv(p, Rconv, &p.From)) p.Pc, p.Line(), Aconv(a), obj.Dconv(p, &p.From))
if p.Reg != 0 { if p.Reg != 0 {
str += fmt.Sprintf(",%v", Rconv(int(p.Reg))) str += fmt.Sprintf(",%v", Rconv(int(p.Reg)))
} }
if p.From3.Type != obj.TYPE_NONE { if p.From3.Type != obj.TYPE_NONE {
str += fmt.Sprintf(",%v", obj.Dconv(p, Rconv, &p.From3)) str += fmt.Sprintf(",%v", obj.Dconv(p, &p.From3))
} }
str += fmt.Sprintf(",%v", obj.Dconv(p, Rconv, &p.To)) str += fmt.Sprintf(",%v", obj.Dconv(p, &p.To))
} }
if p.Spadj != 0 { if p.Spadj != 0 {
@ -128,63 +128,52 @@ func Aconv(a int) string {
return fp return fp
} }
func Rconv(r int) string { func init() {
var fp string obj.RegisterRegister(obj.RBasePPC64, REG_DCR0+1024, Rconv)
}
func Rconv(r int) string {
if r == 0 { if r == 0 {
fp += "NONE" return "NONE"
return fp
} }
if REG_R0 <= r && r <= REG_R31 { if REG_R0 <= r && r <= REG_R31 {
fp += fmt.Sprintf("R%d", r-REG_R0) return fmt.Sprintf("R%d", r-REG_R0)
return fp
} }
if REG_F0 <= r && r <= REG_F31 { if REG_F0 <= r && r <= REG_F31 {
fp += fmt.Sprintf("F%d", r-REG_F0) return fmt.Sprintf("F%d", r-REG_F0)
return fp
} }
if REG_C0 <= r && r <= REG_C7 { if REG_C0 <= r && r <= REG_C7 {
fp += fmt.Sprintf("C%d", r-REG_C0) return fmt.Sprintf("C%d", r-REG_C0)
return fp
} }
if r == REG_CR { if r == REG_CR {
fp += "CR" return "CR"
return fp
} }
if REG_SPR0 <= r && r <= REG_SPR0+1023 { if REG_SPR0 <= r && r <= REG_SPR0+1023 {
switch r { switch r {
case REG_XER: case REG_XER:
fp += "XER" return "XER"
return fp
case REG_LR: case REG_LR:
fp += "LR" return "LR"
return fp
case REG_CTR: case REG_CTR:
fp += "CTR" return "CTR"
return fp
} }
fp += fmt.Sprintf("SPR(%d)", r-REG_SPR0) return fmt.Sprintf("SPR(%d)", r-REG_SPR0)
return fp
} }
if REG_DCR0 <= r && r <= REG_DCR0+1023 { if REG_DCR0 <= r && r <= REG_DCR0+1023 {
fp += fmt.Sprintf("DCR(%d)", r-REG_DCR0) return fmt.Sprintf("DCR(%d)", r-REG_DCR0)
return fp
} }
if r == REG_FPSCR { if r == REG_FPSCR {
fp += "FPSCR" return "FPSCR"
return fp
} }
if r == REG_MSR { if r == REG_MSR {
fp += "MSR" return "MSR"
return fp
} }
fp += fmt.Sprintf("badreg(%d)", r) return fmt.Sprintf("Rgok(%d)", r-obj.RBasePPC64)
return fp
} }
func DRconv(a int) string { func DRconv(a int) string {

View file

@ -261,19 +261,15 @@ func (ctxt *Link) Line(n int) string {
return Linklinefmt(ctxt, n, false, false) return Linklinefmt(ctxt, n, false, false)
} }
func (ctxt *Link) Rconv(reg int) string {
return ctxt.Arch.Rconv(reg)
}
func Getcallerpc(interface{}) uintptr { func Getcallerpc(interface{}) uintptr {
return 1 return 1
} }
func (ctxt *Link) Dconv(a *Addr) string { func (ctxt *Link) Dconv(a *Addr) string {
return Dconv(nil, ctxt.Rconv, a) return Dconv(nil, a)
} }
func Dconv(p *Prog, Rconv func(int) string, a *Addr) string { func Dconv(p *Prog, a *Addr) string {
var str string var str string
switch a.Type { switch a.Type {
@ -283,7 +279,7 @@ func Dconv(p *Prog, Rconv func(int) string, a *Addr) string {
case TYPE_NONE: case TYPE_NONE:
str = "" str = ""
if a.Name != NAME_NONE || a.Reg != 0 || a.Sym != nil { if a.Name != NAME_NONE || a.Reg != 0 || a.Sym != nil {
str = fmt.Sprintf("%v(%v)(NONE)", Mconv(Rconv, a), Rconv(int(a.Reg))) str = fmt.Sprintf("%v(%v)(NONE)", Mconv(a), Rconv(int(a.Reg)))
} }
case TYPE_REG: case TYPE_REG:
@ -298,7 +294,7 @@ func Dconv(p *Prog, Rconv func(int) string, a *Addr) string {
str = fmt.Sprintf("%v", Rconv(int(a.Reg))) str = fmt.Sprintf("%v", Rconv(int(a.Reg)))
if a.Name != TYPE_NONE || a.Sym != nil { if a.Name != TYPE_NONE || a.Sym != nil {
str = fmt.Sprintf("%v(%v)(REG)", Mconv(Rconv, a), Rconv(int(a.Reg))) str = fmt.Sprintf("%v(%v)(REG)", Mconv(a), Rconv(int(a.Reg)))
} }
case TYPE_BRANCH: case TYPE_BRANCH:
@ -313,19 +309,19 @@ func Dconv(p *Prog, Rconv func(int) string, a *Addr) string {
} }
case TYPE_INDIR: case TYPE_INDIR:
str = fmt.Sprintf("*%s", Mconv(Rconv, a)) str = fmt.Sprintf("*%s", Mconv(a))
case TYPE_MEM: case TYPE_MEM:
str = Mconv(Rconv, a) str = Mconv(a)
if a.Index != REG_NONE { if a.Index != REG_NONE {
str += fmt.Sprintf("(%v*%d)", Rconv(int(a.Index)), int(a.Scale)) str += fmt.Sprintf("(%v*%d)", Rconv(int(a.Index)), int(a.Scale))
} }
case TYPE_CONST: case TYPE_CONST:
if a.Reg != 0 { if a.Reg != 0 {
str = fmt.Sprintf("$%v(%v)", Mconv(Rconv, a), Rconv(int(a.Reg))) str = fmt.Sprintf("$%v(%v)", Mconv(a), Rconv(int(a.Reg)))
} else { } else {
str = fmt.Sprintf("$%v", Mconv(Rconv, a)) str = fmt.Sprintf("$%v", Mconv(a))
} }
case TYPE_TEXTSIZE: case TYPE_TEXTSIZE:
@ -347,7 +343,7 @@ func Dconv(p *Prog, Rconv func(int) string, a *Addr) string {
str = fmt.Sprintf("$%q", a.U.Sval) str = fmt.Sprintf("$%q", a.U.Sval)
case TYPE_ADDR: case TYPE_ADDR:
str = fmt.Sprintf("$%s", Mconv(Rconv, a)) str = fmt.Sprintf("$%s", Mconv(a))
case TYPE_SHIFT: case TYPE_SHIFT:
v := int(a.Offset) v := int(a.Offset)
@ -371,7 +367,7 @@ func Dconv(p *Prog, Rconv func(int) string, a *Addr) string {
return str return str
} }
func Mconv(Rconv func(int) string, a *Addr) string { func Mconv(a *Addr) string {
var str string var str string
switch a.Name { switch a.Name {
@ -417,3 +413,49 @@ func offConv(off int64) string {
} }
return fmt.Sprintf("%+d", off) return fmt.Sprintf("%+d", off)
} }
type regSet struct {
lo int
hi int
Rconv func(int) string
}
// Few enough architectures that a linear scan is fastest.
// Not even worth sorting.
var regSpace []regSet
/*
Each architecture defines a register space as a unique
integer range.
Here is the list of architectures and the base of their register spaces.
*/
const (
// Because of masking operations in the encodings, each register
// space should start at 0 modulo some power of 2.
RBase386 = 1 * 1024
RBaseAMD64 = 2 * 1024
RBaseARM = 3 * 1024
RBasePPC64 = 4 * 1024
// The next free base is 8*1024 (PPC64 has many registers).
)
// RegisterRegister binds a pretty-printer (Rconv) for register
// numbers to a given register number range. Lo is inclusive,
// hi exclusive (valid registers are lo through hi-1).
func RegisterRegister(lo, hi int, Rconv func(int) string) {
regSpace = append(regSpace, regSet{lo, hi, Rconv})
}
func Rconv(reg int) string {
if reg == REG_NONE {
return "NONE"
}
for i := range regSpace {
rs := &regSpace[i]
if rs.lo <= reg && reg < rs.hi {
return rs.Rconv(reg)
}
}
return fmt.Sprintf("R???%d", reg)
}

View file

@ -714,7 +714,7 @@ const (
const ( const (
REG_NONE = 0 REG_NONE = 0
REG_AL = 0 + 16 + iota - 1 REG_AL = obj.RBaseAMD64 + 0 + iota - 1
REG_CL REG_CL
REG_DL REG_DL
REG_BL REG_BL
@ -730,7 +730,7 @@ const (
REG_R13B REG_R13B
REG_R14B REG_R14B
REG_R15B REG_R15B
REG_AX = 16 + 16 + iota - 17 REG_AX = obj.RBaseAMD64 + 16 + iota - 17
REG_CX REG_CX
REG_DX REG_DX
REG_BX REG_BX
@ -746,13 +746,13 @@ const (
REG_R13 REG_R13
REG_R14 REG_R14
REG_R15 REG_R15
REG_AH = 32 + 16 + iota - 33 REG_AH = obj.RBaseAMD64 + 32 + iota - 33
REG_CH REG_CH
REG_DH REG_DH
REG_BH REG_BH
REG_F0 = 36 + 16 REG_F0 = obj.RBaseAMD64 + 36
REG_M0 = 44 + 16 REG_M0 = obj.RBaseAMD64 + 44
REG_X0 = 52 + 16 + iota - 39 REG_X0 = obj.RBaseAMD64 + 52 + iota - 39
REG_X1 REG_X1
REG_X2 REG_X2
REG_X3 REG_X3
@ -768,7 +768,7 @@ const (
REG_X13 REG_X13
REG_X14 REG_X14
REG_X15 REG_X15
REG_CS = 68 + 16 + iota - 55 REG_CS = obj.RBaseAMD64 + 68 + iota - 55
REG_SS REG_SS
REG_DS REG_DS
REG_ES REG_ES
@ -779,10 +779,10 @@ const (
REG_LDTR REG_LDTR
REG_MSW REG_MSW
REG_TASK REG_TASK
REG_CR = 79 + 16 REG_CR = obj.RBaseAMD64 + 79
REG_DR = 95 + 16 REG_DR = obj.RBaseAMD64 + 95
REG_TR = 103 + 16 REG_TR = obj.RBaseAMD64 + 103
REG_TLS = 111 + 16 + iota - 69 REG_TLS = obj.RBaseAMD64 + 111 + iota - 69
MAXREG MAXREG
REGARG = -1 REGARG = -1
REGRET = REG_AX REGRET = REG_AX

View file

@ -1931,7 +1931,7 @@ func oclass(ctxt *obj.Link, p *obj.Prog, a *obj.Addr) int {
} }
if a.Sym != nil || a.Name != obj.NAME_NONE { if a.Sym != nil || a.Name != obj.NAME_NONE {
ctxt.Diag("unexpected addr: %v", obj.Dconv(p, Rconv, a)) ctxt.Diag("unexpected addr: %v", obj.Dconv(p, a))
} }
fallthrough fallthrough
@ -1939,7 +1939,7 @@ func oclass(ctxt *obj.Link, p *obj.Prog, a *obj.Addr) int {
case obj.TYPE_CONST: case obj.TYPE_CONST:
if a.Sym != nil { if a.Sym != nil {
ctxt.Diag("TYPE_CONST with symbol: %v", obj.Dconv(p, Rconv, a)) ctxt.Diag("TYPE_CONST with symbol: %v", obj.Dconv(p, a))
} }
v = a.Offset v = a.Offset
@ -1966,7 +1966,7 @@ func oclass(ctxt *obj.Link, p *obj.Prog, a *obj.Addr) int {
} }
if a.Type != obj.TYPE_REG { if a.Type != obj.TYPE_REG {
ctxt.Diag("unexpected addr1: type=%d %v", a.Type, obj.Dconv(p, Rconv, a)) ctxt.Diag("unexpected addr1: type=%d %v", a.Type, obj.Dconv(p, a))
return Yxxx return Yxxx
} }
@ -2317,7 +2317,7 @@ func vaddr(ctxt *obj.Link, p *obj.Prog, a *obj.Addr, r *obj.Reloc) int64 {
obj.NAME_EXTERN: obj.NAME_EXTERN:
s = a.Sym s = a.Sym
if r == nil { if r == nil {
ctxt.Diag("need reloc for %v", obj.Dconv(p, Rconv, a)) ctxt.Diag("need reloc for %v", obj.Dconv(p, a))
log.Fatalf("reloc") log.Fatalf("reloc")
} }
@ -2343,7 +2343,7 @@ func vaddr(ctxt *obj.Link, p *obj.Prog, a *obj.Addr, r *obj.Reloc) int64 {
if (a.Type == obj.TYPE_MEM || a.Type == obj.TYPE_ADDR) && a.Reg == REG_TLS { if (a.Type == obj.TYPE_MEM || a.Type == obj.TYPE_ADDR) && a.Reg == REG_TLS {
if r == nil { if r == nil {
ctxt.Diag("need reloc for %v", obj.Dconv(p, Rconv, a)) ctxt.Diag("need reloc for %v", obj.Dconv(p, a))
log.Fatalf("reloc") log.Fatalf("reloc")
} }
@ -2545,7 +2545,7 @@ putrelv:
return return
bad: bad:
ctxt.Diag("asmand: bad address %v", obj.Dconv(p, Rconv, a)) ctxt.Diag("asmand: bad address %v", obj.Dconv(p, a))
return return
} }

View file

@ -60,21 +60,21 @@ func Pconv(p *obj.Prog) string {
switch p.As { switch p.As {
case obj.ADATA: case obj.ADATA:
str = fmt.Sprintf("%.5d (%v)\t%v\t%v/%d,%v", str = fmt.Sprintf("%.5d (%v)\t%v\t%v/%d,%v",
p.Pc, p.Line(), Aconv(int(p.As)), obj.Dconv(p, Rconv, &p.From), p.From3.Offset, obj.Dconv(p, Rconv, &p.To)) p.Pc, p.Line(), Aconv(int(p.As)), obj.Dconv(p, &p.From), p.From3.Offset, obj.Dconv(p, &p.To))
case obj.ATEXT: case obj.ATEXT:
if p.From3.Offset != 0 { if p.From3.Offset != 0 {
str = fmt.Sprintf("%.5d (%v)\t%v\t%v,%d,%v", str = fmt.Sprintf("%.5d (%v)\t%v\t%v,%d,%v",
p.Pc, p.Line(), Aconv(int(p.As)), obj.Dconv(p, Rconv, &p.From), p.From3.Offset, obj.Dconv(p, Rconv, &p.To)) p.Pc, p.Line(), Aconv(int(p.As)), obj.Dconv(p, &p.From), p.From3.Offset, obj.Dconv(p, &p.To))
break break
} }
str = fmt.Sprintf("%.5d (%v)\t%v\t%v,%v", str = fmt.Sprintf("%.5d (%v)\t%v\t%v,%v",
p.Pc, p.Line(), Aconv(int(p.As)), obj.Dconv(p, Rconv, &p.From), obj.Dconv(p, Rconv, &p.To)) p.Pc, p.Line(), Aconv(int(p.As)), obj.Dconv(p, &p.From), obj.Dconv(p, &p.To))
default: default:
str = fmt.Sprintf("%.5d (%v)\t%v\t%v,%v", str = fmt.Sprintf("%.5d (%v)\t%v\t%v,%v",
p.Pc, p.Line(), Aconv(int(p.As)), obj.Dconv(p, Rconv, &p.From), obj.Dconv(p, Rconv, &p.To)) p.Pc, p.Line(), 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 // TODO(rsc): This special case is for SHRQ $32, AX:DX, which encodes as
// SHRQ $32(DX*0), AX // SHRQ $32(DX*0), AX
@ -211,21 +211,13 @@ var Register = []string{
"MAXREG", /* [MAXREG] */ "MAXREG", /* [MAXREG] */
} }
func Rconv(r int) string { func init() {
var str string obj.RegisterRegister(REG_AL, REG_AL+len(Register), Rconv)
var fp string }
if r == REG_NONE { func Rconv(r int) string {
fp += "NONE" if REG_AL <= r && r-REG_AL < len(Register) {
return fp return fmt.Sprintf("%s", Register[r-REG_AL])
} }
return fmt.Sprintf("Rgok(%d)", r-obj.RBaseAMD64)
if REG_AL <= r && r-REG_AL < len(Register) {
str = fmt.Sprintf("%s", Register[r-REG_AL])
} else {
str = fmt.Sprintf("gok(%d)", r)
}
fp += str
return fp
} }