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

View File

@@ -7,6 +7,23 @@ import (
"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) {
cases := []struct {
Mem Mem
@@ -14,11 +31,16 @@ func TestMemAsm(t *testing.T) {
}{
{Mem{Base: reg.EAX}, "(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: 1}, "(R11)(AX*1)"},
{Mem{Base: reg.R11, Index: reg.RAX}, "(R11)"},
{Mem{Base: reg.R11, Scale: 8}, "(R11)"},
{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 {
got := c.Mem.Asm()

View File

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

View File

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

View File

@@ -2,13 +2,15 @@ package reg
// Register families.
const (
GP Kind = iota
Internal Kind = iota
GP
MMX
SSEAVX
Mask
)
var Families = []*Family{
Pseudo,
GeneralPurpose,
SIMD,
}
@@ -25,6 +27,16 @@ func FamilyOfKind(k Kind) *Family {
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.
var (
GeneralPurpose = &Family{Kind: GP}