add Symbol type to operand

This commit is contained in:
Michael McLoughlin
2018-12-06 17:26:33 -08:00
parent e42eb1fb8c
commit 676ec39c51
5 changed files with 61 additions and 7 deletions

View File

@@ -10,7 +10,21 @@ type Op interface {
Asm() string Asm() string
} }
type Symbol struct {
Name string
Static bool
}
func (s Symbol) String() string {
n := s.Name
if s.Static {
n += "<>"
}
return n
}
type Mem struct { type Mem struct {
Symbol Symbol
Disp int Disp int
Base reg.Register Base reg.Register
Index reg.Register Index reg.Register
@@ -18,9 +32,13 @@ type Mem struct {
} }
func (m Mem) Asm() string { func (m Mem) Asm() string {
a := "" a := m.Symbol.String()
if m.Disp != 0 { if m.Disp != 0 {
if a == "" {
a += fmt.Sprintf("%d", m.Disp) a += fmt.Sprintf("%d", m.Disp)
} else {
a += fmt.Sprintf("%+d", m.Disp)
}
} }
if m.Base != nil { if m.Base != nil {
a += fmt.Sprintf("(%s)", m.Base.Asm()) a += fmt.Sprintf("(%s)", m.Base.Asm())

View File

@@ -7,6 +7,23 @@ import (
"github.com/mmcloughlin/avo/reg" "github.com/mmcloughlin/avo/reg"
) )
func TestSymbolString(t *testing.T) {
cases := []struct {
Symbol Symbol
Expect string
}{
{Symbol{}, ""},
{Symbol{Name: "name"}, "name"},
{Symbol{Name: "static", Static: true}, "static<>"},
}
for _, c := range cases {
got := c.Symbol.String()
if got != c.Expect {
t.Errorf("%#v.String() = %s expected %s", c.Symbol, got, c.Expect)
}
}
}
func TestMemAsm(t *testing.T) { func TestMemAsm(t *testing.T) {
cases := []struct { cases := []struct {
Mem Mem Mem Mem
@@ -14,11 +31,16 @@ func TestMemAsm(t *testing.T) {
}{ }{
{Mem{Base: reg.EAX}, "(AX)"}, {Mem{Base: reg.EAX}, "(AX)"},
{Mem{Disp: 16, Base: reg.RAX}, "16(AX)"}, {Mem{Disp: 16, Base: reg.RAX}, "16(AX)"},
{Mem{Disp: -7, Base: reg.RAX}, "-7(AX)"},
{Mem{Base: reg.R11, Index: reg.RAX, Scale: 4}, "(R11)(AX*4)"}, {Mem{Base: reg.R11, Index: reg.RAX, Scale: 4}, "(R11)(AX*4)"},
{Mem{Base: reg.R11, Index: reg.RAX, Scale: 1}, "(R11)(AX*1)"}, {Mem{Base: reg.R11, Index: reg.RAX, Scale: 1}, "(R11)(AX*1)"},
{Mem{Base: reg.R11, Index: reg.RAX}, "(R11)"}, {Mem{Base: reg.R11, Index: reg.RAX}, "(R11)"},
{Mem{Base: reg.R11, Scale: 8}, "(R11)"}, {Mem{Base: reg.R11, Scale: 8}, "(R11)"},
{Mem{Disp: 2048, Base: reg.R11, Index: reg.RAX, Scale: 8}, "2048(R11)(AX*8)"}, {Mem{Disp: 2048, Base: reg.R11, Index: reg.RAX, Scale: 8}, "2048(R11)(AX*8)"},
{Mem{Symbol: Symbol{Name: "foo"}, Base: reg.StaticBase}, "foo(SB)"},
{Mem{Symbol: Symbol{Name: "foo"}, Base: reg.StaticBase, Disp: 4}, "foo+4(SB)"},
{Mem{Symbol: Symbol{Name: "foo"}, Base: reg.StaticBase, Disp: -7}, "foo-7(SB)"},
{Mem{Symbol: Symbol{Name: "bar", Static: true}, Base: reg.StaticBase, Disp: 4, Index: reg.R11, Scale: 4}, "bar<>+4(SB)(R11*4)"},
} }
for _, c := range cases { for _, c := range cases {
got := c.Mem.Asm() got := c.Mem.Asm()

View File

@@ -7,6 +7,7 @@ func TestSpecBytes(t *testing.T) {
Spec Spec Spec Spec
Bytes uint Bytes uint
}{ }{
{S0, 0},
{S8L, 1}, {S8L, 1},
{S8H, 1}, {S8H, 1},
{S16, 2}, {S16, 2},

View File

@@ -140,6 +140,7 @@ func (r register) register() {}
type Spec uint16 type Spec uint16
const ( const (
S0 Spec = 0x0 // zero value reserved for pseudo registers
S8L Spec = 0x1 S8L Spec = 0x1
S8H Spec = 0x2 S8H Spec = 0x2
S8 = S8L S8 = S8L

View File

@@ -2,13 +2,15 @@ package reg
// Register families. // Register families.
const ( const (
GP Kind = iota Internal Kind = iota
GP
MMX MMX
SSEAVX SSEAVX
Mask Mask
) )
var Families = []*Family{ var Families = []*Family{
Pseudo,
GeneralPurpose, GeneralPurpose,
SIMD, SIMD,
} }
@@ -25,6 +27,16 @@ func FamilyOfKind(k Kind) *Family {
return familiesByKind[k] return familiesByKind[k]
} }
// Pseudo registers.
var (
Pseudo = &Family{Kind: Internal}
FramePointer = Pseudo.define(S0, 0, "FP")
ProgramCounter = Pseudo.define(S0, 0, "PC")
StaticBase = Pseudo.define(S0, 0, "SB")
StackPointer = Pseudo.define(S0, 0, "SP")
)
// General purpose registers. // General purpose registers.
var ( var (
GeneralPurpose = &Family{Kind: GP} GeneralPurpose = &Family{Kind: GP}