mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
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:
parent
95bf77bc68
commit
daddeb2686
36 changed files with 1177 additions and 756 deletions
462
src/cmd/5a/y.go
462
src/cmd/5a/y.go
File diff suppressed because it is too large
Load diff
|
|
@ -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 {
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
499
src/cmd/6a/y.go
499
src/cmd/6a/y.go
File diff suppressed because it is too large
Load diff
|
|
@ -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 {
|
||||||
|
|
|
||||||
|
|
@ -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))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
490
src/cmd/8a/y.go
490
src/cmd/8a/y.go
File diff suppressed because it is too large
Load diff
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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:
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
|
|
|
||||||
|
|
@ -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])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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))
|
||||||
|
|
|
||||||
|
|
@ -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))
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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{
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
|
|
@ -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 := ®Space[i]
|
||||||
|
if rs.lo <= reg && reg < rs.hi {
|
||||||
|
return rs.Rconv(reg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("R???%d", reg)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue