Commit daddeb26 authored by Rob Pike's avatar Rob Pike

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/6220Reviewed-by: default avatarRuss Cox <rsc@golang.org>
parent 95bf77bc
This diff is collapsed.
......@@ -64,7 +64,7 @@ func gclean() {
for i := 0; i < len(reg); i++ {
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")
}
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]--
if reg[i] == 0 {
......
......@@ -521,7 +521,7 @@ omem:
$$.Type = obj.TYPE_MEM
$$.Offset = $1;
$$.Index = int16($3);
$$.Scale = int8($5);
$$.Scale = int16($5);
checkscale($$.Scale);
}
| con '(' LLREG ')' '(' LLREG '*' con ')'
......@@ -531,7 +531,7 @@ omem:
$$.Reg = int16($3)
$$.Offset = $1;
$$.Index = int16($6);
$$.Scale = int8($8);
$$.Scale = int16($8);
checkscale($$.Scale);
}
| con '(' LLREG ')' '(' LSREG '*' con ')'
......@@ -541,7 +541,7 @@ omem:
$$.Reg = int16($3)
$$.Offset = $1;
$$.Index = int16($6);
$$.Scale = int8($8);
$$.Scale = int16($8);
checkscale($$.Scale);
}
| '(' LLREG ')'
......@@ -561,7 +561,7 @@ omem:
$$ = nullgen;
$$.Type = obj.TYPE_MEM
$$.Index = int16($2);
$$.Scale = int8($4);
$$.Scale = int16($4);
checkscale($$.Scale);
}
| '(' LLREG ')' '(' LLREG '*' con ')'
......@@ -570,7 +570,7 @@ omem:
$$.Type = obj.TYPE_MEM
$$.Reg = int16($2)
$$.Index = int16($5);
$$.Scale = int8($7);
$$.Scale = int16($7);
checkscale($$.Scale);
}
......@@ -583,7 +583,7 @@ nmem:
{
$$ = $1;
$$.Index = int16($3);
$$.Scale = int8($5);
$$.Scale = int16($5);
checkscale($$.Scale);
}
......
......@@ -918,7 +918,7 @@ var lexinit = []asm.Lextab{
func cinit() {
}
func checkscale(scale int8) {
func checkscale(scale int16) {
switch scale {
case 1,
2,
......
This diff is collapsed.
......@@ -838,7 +838,7 @@ func agenr(n *gc.Node, a *gc.Node, res *gc.Node) {
if w == 1 || w == 2 || w == 4 || w == 8 {
p1 := gins(x86.ALEAQ, &n2, &n3)
p1.From.Type = obj.TYPE_MEM
p1.From.Scale = int8(w)
p1.From.Scale = int16(w)
p1.From.Index = p1.From.Reg
p1.From.Reg = p1.To.Reg
} else {
......
......@@ -89,12 +89,12 @@ func gclean() {
for i := x86.REG_AX; i <= x86.REG_R15; i++ {
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++ {
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))
}
}
}
......
......@@ -534,7 +534,7 @@ omem:
$$.Type = obj.TYPE_MEM
$$.Offset = $1;
$$.Index = int16($3);
$$.Scale = int8($5);
$$.Scale = int16($5);
checkscale($$.Scale);
}
| con '(' LLREG ')' '(' LLREG '*' con ')'
......@@ -544,7 +544,7 @@ omem:
$$.Reg = int16($3)
$$.Offset = $1;
$$.Index = int16($6);
$$.Scale = int8($8);
$$.Scale = int16($8);
checkscale($$.Scale);
}
| con '(' LLREG ')' '(' LSREG '*' con ')'
......@@ -554,7 +554,7 @@ omem:
$$.Reg = int16($3)
$$.Offset = $1;
$$.Index = int16($6);
$$.Scale = int8($8);
$$.Scale = int16($8);
checkscale($$.Scale);
}
| '(' LLREG ')'
......@@ -581,7 +581,7 @@ omem:
$$ = nullgen;
$$.Type = obj.TYPE_MEM
$$.Index = int16($2);
$$.Scale = int8($4);
$$.Scale = int16($4);
checkscale($$.Scale);
}
| '(' LLREG ')' '(' LLREG '*' con ')'
......@@ -590,7 +590,7 @@ omem:
$$.Type = obj.TYPE_MEM
$$.Reg = int16($2)
$$.Index = int16($5);
$$.Scale = int8($7);
$$.Scale = int16($7);
checkscale($$.Scale);
}
......@@ -603,7 +603,7 @@ nmem:
{
$$ = $1;
$$.Index = int16($3);
$$.Scale = int8($5);
$$.Scale = int16($5);
checkscale($$.Scale);
}
......
......@@ -706,7 +706,7 @@ func cinit() {
nullgen.Index = i386.REG_NONE
}
func checkscale(scale int8) {
func checkscale(scale int16) {
switch scale {
case 1,
2,
......
This diff is collapsed.
......@@ -774,7 +774,7 @@ func agen(n *gc.Node, res *gc.Node) {
// LEAL (n3)(n2*w), 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.Index = p1.From.Reg
p1.From.Reg = p1.To.Reg
......
......@@ -582,12 +582,12 @@ func gclean() {
for i := i386.REG_AX; i <= i386.REG_DI; i++ {
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++ {
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")
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")
goto err
......@@ -683,7 +683,7 @@ func regalloc(n *gc.Node, t *gc.Type, o *gc.Node) {
}
fmt.Printf("registers allocated at\n")
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")
}
......@@ -702,7 +702,7 @@ out:
regpc[i] = uint32(obj.Getcallerpc(&n))
if i == i386.REG_AX || i == i386.REG_CX || i == i386.REG_DX || i == i386.REG_SP {
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]--
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))
}
}
......
......@@ -927,7 +927,7 @@ regaddr:
$$ = nullgen;
$$.Type = obj.TYPE_MEM;
$$.Reg = int16($2);
$$.Scale = int8($4);
$$.Scale = int16($4);
$$.Offset = 0;
}
......
......@@ -1786,7 +1786,7 @@ yydefault:
yyVAL.addr = nullgen
yyVAL.addr.Type = obj.TYPE_MEM
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
}
case 157:
......
......@@ -747,15 +747,15 @@ func clearfat(nl *gc.Node) {
c := uint64(w % 8) // bytes
q := uint64(w / 8) // dwords
if reg[ppc64.REGRT1] > 0 {
gc.Fatal("R%d in use during clearfat", ppc64.REGRT1)
if reg[ppc64.REGRT1-ppc64.REG_R0] > 0 {
gc.Fatal("R%d in use during clearfat", ppc64.REGRT1-ppc64.REG_R0)
}
var r0 gc.Node
gc.Nodreg(&r0, gc.Types[gc.TUINT64], ppc64.REG_R0) // r0 is always zero
var dst gc.Node
gc.Nodreg(&dst, gc.Types[gc.Tptr], ppc64.REGRT1)
reg[ppc64.REGRT1]++
reg[ppc64.REGRT1-ppc64.REG_R0]++
agen(nl, &dst)
var boff uint64
......@@ -812,7 +812,7 @@ func clearfat(nl *gc.Node) {
p.To.Offset = int64(t + boff)
}
reg[ppc64.REGRT1]--
reg[ppc64.REGRT1-ppc64.REG_R0]--
}
// Called after regopt and peep have run.
......
......@@ -63,14 +63,14 @@ var resvd = []int{
}
func ginit() {
for i := int(0); i < len(reg); i++ {
for i := 0; i < len(reg); i++ {
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
}
for i := int(0); i < len(resvd); i++ {
for i := 0; i < len(resvd); i++ {
reg[resvd[i]-ppc64.REG_R0]++
}
}
......@@ -84,7 +84,7 @@ func gclean() {
for i := int(0); i < len(reg); i++ {
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])
}
}
}
......
......@@ -38,8 +38,6 @@ type Arch struct {
IsJump func(word string) bool
// Aconv pretty-prints an instruction opcode for this architecture.
Aconv func(int) string
// Rconv pretty-prints a register for this architecture.
Rconv func(int) string
}
// nilRegisterNumber is the register number function for architectures
......@@ -188,7 +186,6 @@ func arch386() *Arch {
UnaryDestination: unaryDestination,
IsJump: jump386,
Aconv: i386.Aconv,
Rconv: i386.Rconv,
}
}
......@@ -309,7 +306,6 @@ func archAmd64() *Arch {
UnaryDestination: unaryDestination,
IsJump: jump386,
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.
// TODO: Are there aliases we need to add?
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.
delete(register, "R10")
......@@ -362,7 +358,6 @@ func archArm() *Arch {
UnaryDestination: unaryDestination,
IsJump: jumpArm,
Aconv: arm.Aconv,
Rconv: arm.Rconv,
}
}
......@@ -372,17 +367,17 @@ func archPPC64() *Arch {
// TODO: Should this be done in obj for us?
// 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++ {
register[ppc64.Rconv(i)] = int16(i)
register[obj.Rconv(i)] = int16(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++ {
// TODO: Rconv prints these as C7 but the input syntax requires CR7.
register[fmt.Sprintf("CR%d", i-ppc64.REG_C0)] = int16(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["XER"] = ppc64.REG_XER
......@@ -422,6 +417,5 @@ func archPPC64() *Arch {
UnaryDestination: nil,
IsJump: jumpPPC64,
Aconv: ppc64.Aconv,
Rconv: ppc64.Rconv,
}
}
......@@ -73,7 +73,7 @@ func (p *Parser) evalInteger(pseudo string, operands []lex.Token) int64 {
// validateImmediate checks that addr represents an immediate constant.
func (p *Parser) validateImmediate(pseudo string, addr *obj.Addr) {
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.
// Bizarrely, to obj it's specified by setting index on the LHS.
// TODO: can we fix this?
if a[1].Class != 0 {
if a[0].Class != 0 {
if a[1].Reg2 != 0 {
if a[0].Reg2 != 0 {
p.errorf("register pair must be on LHS")
}
prog.From.Index = int16(a[1].Class)
prog.To.Class = 0
prog.From.Index = int16(a[1].Reg2)
prog.To.Reg2 = 0
}
case '9':
var reg0, reg1 int16
......@@ -642,7 +642,7 @@ var emptyProg obj.Prog
// getConstantPseudo checks that addr represents a plain constant and returns its value.
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 {
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
}
......@@ -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.
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, p.arch.Rconv, addr))
p.errorf("%s: expected integer constant; found %s", p.arch.Aconv(op), obj.Dconv(prog, addr))
}
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.
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, p.arch.Rconv, addr))
p.errorf("%s: expected immediate constant; found %s", p.arch.Aconv(op), obj.Dconv(prog, addr))
}
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.
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, p.arch.Rconv, addr))
p.errorf("%s: expected register; found %s", p.arch.Aconv(op), obj.Dconv(prog, addr))
}
return addr.Reg
}
......@@ -34,7 +34,7 @@ func testOperandParser(t *testing.T, parser *Parser, tests []operandTest) {
parser.start(lex.Tokenize(test.input))
addr := obj.Addr{}
parser.operand(&addr)
result := obj.Dconv(&emptyProg, parser.arch.Rconv, &addr)
result := obj.Dconv(&emptyProg, &addr)
if 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{}
parser.operand(&addr)
want := obj.Addr{
Type: obj.TYPE_REG,
Reg: parser.arch.Register["AX"],
Class: int8(parser.arch.Register["BX"]), // TODO: clean up how this is encoded in parse.go
Type: obj.TYPE_REG,
Reg: parser.arch.Register["AX"],
Reg2: parser.arch.Register["BX"], // TODO: clean up how this is encoded in parse.go
}
if 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,
Offset: 4,
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 {
t.Errorf("foo+4(SB):AX: expected %+v got %+v", want, addr)
......@@ -99,7 +99,7 @@ func TestPPC64OperandParser(t *testing.T) {
want := obj.Addr{
Type: obj.TYPE_MEM,
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 {
t.Errorf("(R1+R2): expected %+v got %+v", want, addr)
......
......@@ -255,7 +255,7 @@ func (p *Parser) operand(a *obj.Addr) bool {
if tok.ScanToken == scanner.Ident && !p.atStartOfRegister(name) {
// We have a symbol. Parse $sym±offset(symkind)
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 {
return true
}
......@@ -297,10 +297,10 @@ func (p *Parser) operand(a *obj.Addr) bool {
if r2 != 0 {
// Form is R1:R2. It is on RHS and the second register
// 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)
return true
}
......@@ -327,7 +327,7 @@ func (p *Parser) operand(a *obj.Addr) bool {
}
a.Type = obj.TYPE_FCONST
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)
return true
}
......@@ -341,7 +341,7 @@ func (p *Parser) operand(a *obj.Addr) bool {
}
a.Type = obj.TYPE_SCONST
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)
return true
}
......@@ -355,7 +355,7 @@ func (p *Parser) operand(a *obj.Addr) bool {
default:
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)
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.
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(':')
r2, ok := p.registerReference(p.next().String())
if !ok {
return false
}
a.Class = int8(r2) // TODO: See comment about Class above.
a.Reg2 = r2 // TODO: See comment about Reg3 above.
} else {
// Register indirection: (reg) or (index*scale). We are on the opening paren.
p.registerIndirect(a, prefix)
......@@ -646,7 +646,7 @@ func (p *Parser) registerIndirect(a *obj.Addr, prefix rune) {
}
// TODO: This is rewritten in asm. Clumsy.
a.Type = obj.TYPE_MEM
a.Scale = int8(r2)
a.Scale = r2
// Nothing may follow.
return
}
......@@ -672,13 +672,13 @@ func (p *Parser) registerIndirect(a *obj.Addr, prefix rune) {
p.errorf("unimplemented two-register form")
}
a.Index = r1
a.Scale = scale
a.Scale = int16(scale)
p.get(')')
} else if scale != 0 {
// First (R) was missing, all we have is (R*scale).
a.Reg = 0
a.Index = r1
a.Scale = scale
a.Scale = int16(scale)
}
}
......
......@@ -1257,7 +1257,7 @@ func exprfmt(n *Node, prec int) string {
case OREGISTER:
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
case OLITERAL: // this is a bit of a mess
......@@ -1787,7 +1787,7 @@ func nodedump(n *Node, flag int) string {
case OREGISTER,
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:
fp += fmt.Sprintf("%v-%v%v", Oconv(int(n.Op), 0), Vconv(&n.Val, 0), Jconv(n, 0))
......
......@@ -1283,7 +1283,7 @@ brk:
if rgp.regno != 0 {
if Debug['R'] != 0 && Debug['v'] != 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))
......
......@@ -47,7 +47,7 @@ const (
)
const (
REG_R0 = 32 + iota
REG_R0 = obj.RBaseARM + iota
REG_R1
REG_R2
REG_R3
......@@ -83,6 +83,7 @@ const (
REG_FPCR
REG_CPSR
REG_SPSR
MAXREG
REGRET = REG_R0
REGEXT = REG_R10
REGG = REGEXT - 0
......
......@@ -45,7 +45,7 @@ type Optab struct {
a3 uint8
type_ uint8
size int8
param int8
param int16
flag int8
pcrelsiz uint8
}
......
......@@ -86,26 +86,26 @@ func Pconv(p *obj.Prog) string {
if a == AMOVM {
if p.From.Type == obj.TYPE_CONST {
str = fmt.Sprintf("%.5d (%v)\t%v%s\t%v,%v",
p.Pc, p.Line(), Aconv(a), sc, RAconv(&p.From), 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 {
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 {
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 {
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 {
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 {
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 {
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
......@@ -160,42 +160,36 @@ func RAconv(a *obj.Addr) string {
return fp
}
func Rconv(r int) string {
var fp string
func init() {
obj.RegisterRegister(obj.RBaseARM, MAXREG, Rconv)
}
func Rconv(r int) string {
if r == 0 {
fp += "NONE"
return fp
return "NONE"
}
if REG_R0 <= r && r <= REG_R15 {
fp += fmt.Sprintf("R%d", r-REG_R0)
return fp
return fmt.Sprintf("R%d", r-REG_R0)
}
if REG_F0 <= r && r <= REG_F15 {
fp += fmt.Sprintf("F%d", r-REG_F0)
return fp
return fmt.Sprintf("F%d", r-REG_F0)
}
switch r {
case REG_FPSR:
fp += "FPSR"
return fp
return "FPSR"
case REG_FPCR:
fp += "FPCR"
return fp
return "FPCR"
case REG_CPSR:
fp += "CPSR"
return fp
return "CPSR"
case REG_SPSR:
fp += "SPSR"
return fp
return "SPSR"
}
fp += fmt.Sprintf("badreg(%d)", r)
return fp
return fmt.Sprintf("Rgok(%d)", r-obj.RBaseARM)
}
func DRconv(a int) string {
......
......@@ -535,15 +535,15 @@ const (
const (
REG_NONE = 0
REG_AL = 0 + 16 + iota - 1
REG_AL = obj.RBase386 + 0 + iota - 1
REG_CL
REG_DL
REG_BL
REG_AH = 4 + 16 + iota - 5
REG_AH = obj.RBase386 + 4 + iota - 5
REG_CH
REG_DH
REG_BH
REG_AX = 8 + 16 + iota - 9
REG_AX = obj.RBase386 + 8 + iota - 9
REG_CX
REG_DX
REG_BX
......@@ -551,9 +551,9 @@ const (
REG_BP
REG_SI
REG_DI
REG_F0 = 16 + 16
REG_F7 = REG_F0 + 7 + 16
REG_CS = 24 + 16 + iota - 19
REG_F0 = obj.RBase386 + 16
REG_F7 = obj.RBase386 + REG_F0 + 7
REG_CS = obj.RBase386 + 24 + iota - 19
REG_SS
REG_DS
REG_ES
......@@ -564,10 +564,10 @@ const (
REG_LDTR
REG_MSW
REG_TASK
REG_CR = 35 + 16
REG_DR = 43 + 16
REG_TR = 51 + 16
REG_X0 = 59 + 16 + iota - 33
REG_CR = obj.RBase386 + 35
REG_DR = obj.RBase386 + 43
REG_TR = obj.RBase386 + 51
REG_X0 = obj.RBase386 + 59 + iota - 33
REG_X1
REG_X2
REG_X3
......@@ -575,8 +575,8 @@ const (
REG_X5
REG_X6
REG_X7
REG_TLS = 67 + 16
MAXREG = 68 + 16
REG_TLS = obj.RBase386 + 67
MAXREG = obj.RBase386 + 68
T_TYPE = 1 << 0
T_INDEX = 1 << 1
T_OFFSET = 1 << 2
......
......@@ -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 {
ctxt.Diag("unexpected addr: %v", obj.Dconv(p, Rconv, a))
ctxt.Diag("unexpected addr: %v", obj.Dconv(p, a))
}
fallthrough
......@@ -1509,7 +1509,7 @@ func oclass(ctxt *obj.Link, p *obj.Prog, a *obj.Addr) int {
case obj.TYPE_CONST:
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)
......@@ -1529,7 +1529,7 @@ func oclass(ctxt *obj.Link, p *obj.Prog, a *obj.Addr) int {
}
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
}
......@@ -1772,7 +1772,7 @@ func vaddr(ctxt *obj.Link, p *obj.Prog, a *obj.Addr, r *obj.Reloc) int32 {
s = a.Sym
if s != 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")
}
......@@ -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 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")
}
......@@ -1972,7 +1972,7 @@ putrelv:
return
bad:
ctxt.Diag("asmand: bad address %v", obj.Dconv(p, Rconv, a))
ctxt.Diag("asmand: bad address %v", obj.Dconv(p, a))
return
}
......
......@@ -48,21 +48,21 @@ func Pconv(p *obj.Prog) string {
switch p.As {
case obj.ADATA:
str = fmt.Sprintf("%.5d (%v)\t%v\t%v/%d,%v",
p.Pc, p.Line(), Aconv(int(p.As)), obj.Dconv(p, 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:
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, 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
}
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:
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
// SHRQ $32(DX*0), AX
......@@ -155,20 +155,13 @@ var Register = []string{
"MAXREG", /* [MAXREG] */
}
func Rconv(r int) string {
var str string
var fp string
func init() {
obj.RegisterRegister(obj.RBase386, obj.RBase386+len(Register), Rconv)
}
if r == REG_NONE {
fp += "NONE"
return fp
}
func Rconv(r int) string {
if r >= REG_AL && r-REG_AL < len(Register) {
str = fmt.Sprintf("%s", Register[r-REG_AL])
} else {
str = fmt.Sprintf("gok(%d)", r)
return fmt.Sprintf("%s", Register[r-REG_AL])
}
fp += str
return fp
return fmt.Sprintf("Rgok(%d)", r-obj.RBase386)
}
......@@ -35,8 +35,9 @@ import "encoding/binary"
type Addr struct {
Type int16
Reg int16
Reg2 int16 // RHS of register pair. AX:DX (386)
Index int16
Scale int8
Scale int16 // Sometimes holds a register.
Name int8
Offset int64
Sym *LSym
......
......@@ -45,7 +45,7 @@ const (
// avoid conflict with ucontext.h. sigh.
const (
REG_R0 = 32 + iota
REG_R0 = obj.RBasePPC64 + iota
REG_R1
REG_R2
REG_R3
......@@ -77,7 +77,7 @@ const (
REG_R29
REG_R30
REG_R31
REG_F0 = 64 + iota - 32
REG_F0 = obj.RBasePPC64 + 32 + iota - 32
REG_F1
REG_F2
REG_F3
......@@ -109,8 +109,8 @@ const (
REG_F29
REG_F30
REG_F31
REG_SPECIAL = 96
REG_C0 = 96 + iota - 65
REG_SPECIAL = obj.RBasePPC64 + 64
REG_C0 = obj.RBasePPC64 + 64 + iota - 65
REG_C1
REG_C2
REG_C3
......@@ -118,11 +118,11 @@ const (
REG_C5
REG_C6
REG_C7
REG_MSR = 104 + iota - 73
REG_MSR = obj.RBasePPC64 + 72 + iota - 73
REG_FPSCR
REG_CR
REG_SPR0 = 1024
REG_DCR0 = 2048
REG_SPR0 = obj.RBasePPC64 + 1024
REG_DCR0 = obj.RBasePPC64 + 2048
REG_XER = REG_SPR0 + 1
REG_LR = REG_SPR0 + 8
REG_CTR = REG_SPR0 + 9
......
......@@ -54,7 +54,7 @@ type Optab struct {
a4 uint8
type_ int8
size int8
param int8
param int16
}
var optab = []Optab{
......
......@@ -64,14 +64,14 @@ func Pconv(p *obj.Prog) string {
str = ""
if a == obj.ADATA {
str = fmt.Sprintf("%.5d (%v)\t%v\t%v/%d,%v",
p.Pc, p.Line(), Aconv(a), obj.Dconv(p, 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 {
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, 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 {
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 p.Mark&NOSCHED != 0 {
......@@ -79,31 +79,31 @@ func Pconv(p *obj.Prog) string {
}
if p.Reg == 0 && p.From3.Type == obj.TYPE_NONE {
str += fmt.Sprintf("%.5d (%v)\t%v\t%v,%v",
p.Pc, p.Line(), Aconv(a), obj.Dconv(p, 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 {
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, 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 {
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, 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 {
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 {
str += fmt.Sprintf(",%v", Rconv(int(p.Reg)))
}
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 {
......@@ -128,63 +128,52 @@ func Aconv(a int) string {
return fp
}
func Rconv(r int) string {
var fp string
func init() {
obj.RegisterRegister(obj.RBasePPC64, REG_DCR0+1024, Rconv)
}
func Rconv(r int) string {
if r == 0 {
fp += "NONE"
return fp
return "NONE"
}
if REG_R0 <= r && r <= REG_R31 {
fp += fmt.Sprintf("R%d", r-REG_R0)
return fp
return fmt.Sprintf("R%d", r-REG_R0)
}
if REG_F0 <= r && r <= REG_F31 {
fp += fmt.Sprintf("F%d", r-REG_F0)
return fp
return fmt.Sprintf("F%d", r-REG_F0)
}
if REG_C0 <= r && r <= REG_C7 {
fp += fmt.Sprintf("C%d", r-REG_C0)
return fp
return fmt.Sprintf("C%d", r-REG_C0)
}
if r == REG_CR {
fp += "CR"
return fp
return "CR"
}
if REG_SPR0 <= r && r <= REG_SPR0+1023 {
switch r {
case REG_XER:
fp += "XER"
return fp
return "XER"
case REG_LR:
fp += "LR"
return fp
return "LR"
case REG_CTR:
fp += "CTR"
return fp
return "CTR"
}
fp += fmt.Sprintf("SPR(%d)", r-REG_SPR0)
return fp
return fmt.Sprintf("SPR(%d)", r-REG_SPR0)
}
if REG_DCR0 <= r && r <= REG_DCR0+1023 {
fp += fmt.Sprintf("DCR(%d)", r-REG_DCR0)
return fp
return fmt.Sprintf("DCR(%d)", r-REG_DCR0)
}
if r == REG_FPSCR {
fp += "FPSCR"
return fp
return "FPSCR"
}
if r == REG_MSR {
fp += "MSR"
return fp
return "MSR"
}
fp += fmt.Sprintf("badreg(%d)", r)
return fp
return fmt.Sprintf("Rgok(%d)", r-obj.RBasePPC64)
}
func DRconv(a int) string {
......
......@@ -261,19 +261,15 @@ func (ctxt *Link) Line(n int) string {
return Linklinefmt(ctxt, n, false, false)
}
func (ctxt *Link) Rconv(reg int) string {
return ctxt.Arch.Rconv(reg)
}
func Getcallerpc(interface{}) uintptr {
return 1
}
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
switch a.Type {
......@@ -283,7 +279,7 @@ func Dconv(p *Prog, Rconv func(int) string, a *Addr) string {
case TYPE_NONE:
str = ""
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:
......@@ -298,7 +294,7 @@ func Dconv(p *Prog, Rconv func(int) string, a *Addr) string {
str = fmt.Sprintf("%v", Rconv(int(a.Reg)))
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:
......@@ -313,19 +309,19 @@ func Dconv(p *Prog, Rconv func(int) string, a *Addr) string {
}
case TYPE_INDIR:
str = fmt.Sprintf("*%s", Mconv(Rconv, a))
str = fmt.Sprintf("*%s", Mconv(a))
case TYPE_MEM:
str = Mconv(Rconv, a)
str = Mconv(a)
if a.Index != REG_NONE {
str += fmt.Sprintf("(%v*%d)", Rconv(int(a.Index)), int(a.Scale))
}
case TYPE_CONST:
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 {
str = fmt.Sprintf("$%v", Mconv(Rconv, a))
str = fmt.Sprintf("$%v", Mconv(a))
}
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)
case TYPE_ADDR:
str = fmt.Sprintf("$%s", Mconv(Rconv, a))
str = fmt.Sprintf("$%s", Mconv(a))
case TYPE_SHIFT:
v := int(a.Offset)
......@@ -371,7 +367,7 @@ func Dconv(p *Prog, Rconv func(int) string, a *Addr) string {
return str
}
func Mconv(Rconv func(int) string, a *Addr) string {
func Mconv(a *Addr) string {
var str string
switch a.Name {
......@@ -417,3 +413,49 @@ func offConv(off int64) string {
}
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)
}
......@@ -714,7 +714,7 @@ const (
const (
REG_NONE = 0
REG_AL = 0 + 16 + iota - 1
REG_AL = obj.RBaseAMD64 + 0 + iota - 1
REG_CL
REG_DL
REG_BL
......@@ -730,7 +730,7 @@ const (
REG_R13B
REG_R14B
REG_R15B
REG_AX = 16 + 16 + iota - 17
REG_AX = obj.RBaseAMD64 + 16 + iota - 17
REG_CX
REG_DX
REG_BX
......@@ -746,13 +746,13 @@ const (
REG_R13
REG_R14
REG_R15
REG_AH = 32 + 16 + iota - 33
REG_AH = obj.RBaseAMD64 + 32 + iota - 33
REG_CH
REG_DH
REG_BH
REG_F0 = 36 + 16
REG_M0 = 44 + 16
REG_X0 = 52 + 16 + iota - 39
REG_F0 = obj.RBaseAMD64 + 36
REG_M0 = obj.RBaseAMD64 + 44
REG_X0 = obj.RBaseAMD64 + 52 + iota - 39
REG_X1
REG_X2
REG_X3
......@@ -768,7 +768,7 @@ const (
REG_X13
REG_X14
REG_X15
REG_CS = 68 + 16 + iota - 55
REG_CS = obj.RBaseAMD64 + 68 + iota - 55
REG_SS
REG_DS
REG_ES
......@@ -779,10 +779,10 @@ const (
REG_LDTR
REG_MSW
REG_TASK
REG_CR = 79 + 16
REG_DR = 95 + 16
REG_TR = 103 + 16
REG_TLS = 111 + 16 + iota - 69
REG_CR = obj.RBaseAMD64 + 79
REG_DR = obj.RBaseAMD64 + 95
REG_TR = obj.RBaseAMD64 + 103
REG_TLS = obj.RBaseAMD64 + 111 + iota - 69
MAXREG
REGARG = -1
REGRET = REG_AX
......
......@@ -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 {
ctxt.Diag("unexpected addr: %v", obj.Dconv(p, Rconv, a))
ctxt.Diag("unexpected addr: %v", obj.Dconv(p, a))
}
fallthrough
......@@ -1939,7 +1939,7 @@ func oclass(ctxt *obj.Link, p *obj.Prog, a *obj.Addr) int {
case obj.TYPE_CONST:
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
......@@ -1966,7 +1966,7 @@ func oclass(ctxt *obj.Link, p *obj.Prog, a *obj.Addr) int {
}
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
}
......@@ -2317,7 +2317,7 @@ func vaddr(ctxt *obj.Link, p *obj.Prog, a *obj.Addr, r *obj.Reloc) int64 {
obj.NAME_EXTERN:
s = a.Sym
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")
}
......@@ -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 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")
}
......@@ -2545,7 +2545,7 @@ putrelv:
return
bad:
ctxt.Diag("asmand: bad address %v", obj.Dconv(p, Rconv, a))
ctxt.Diag("asmand: bad address %v", obj.Dconv(p, a))
return
}
......
......@@ -60,21 +60,21 @@ func Pconv(p *obj.Prog) string {
switch p.As {
case obj.ADATA:
str = fmt.Sprintf("%.5d (%v)\t%v\t%v/%d,%v",
p.Pc, p.Line(), Aconv(int(p.As)), obj.Dconv(p, 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:
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, 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
}
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:
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
// SHRQ $32(DX*0), AX
......@@ -211,21 +211,13 @@ var Register = []string{
"MAXREG", /* [MAXREG] */
}
func Rconv(r int) string {
var str string
var fp string
if r == REG_NONE {
fp += "NONE"
return fp
}
func init() {
obj.RegisterRegister(REG_AL, REG_AL+len(Register), Rconv)
}
func Rconv(r int) string {
if REG_AL <= r && r-REG_AL < len(Register) {
str = fmt.Sprintf("%s", Register[r-REG_AL])
} else {
str = fmt.Sprintf("gok(%d)", r)
return fmt.Sprintf("%s", Register[r-REG_AL])
}
fp += str
return fp
return fmt.Sprintf("Rgok(%d)", r-obj.RBaseAMD64)
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment