x86: rel types and generated tests

This commit is contained in:
Michael McLoughlin
2018-11-27 22:08:11 -08:00
parent 3881907ec8
commit 4395adacc8
13 changed files with 18188 additions and 19 deletions

View File

@@ -207,12 +207,17 @@ func isvm(op avo.Operand, idx func(avo.Operand) bool) bool {
return ok && IsR64(m.Base) && idx(m.Index)
}
// IsRel8 returns true if op is an 8-bit offset relative to instruction pointer.
func IsRel8(op avo.Operand) bool {
// TODO(mbm): implement rel8 operand check
return false
r, ok := op.(Rel)
return ok && r == Rel(int8(r))
}
// IsRel32 returns true if op is an offset relative to instruction pointer, or a
// label reference.
func IsRel32(op avo.Operand) bool {
// TODO(mbm): implement rel32 operand check
return false
// TODO(mbm): should labels be considered separately?
_, rel := op.(Rel)
_, label := op.(LabelRef)
return rel || label
}

View File

@@ -1,6 +1,7 @@
package operand
import (
"math"
"reflect"
"runtime"
"testing"
@@ -129,6 +130,18 @@ func TestChecks(t *testing.T) {
{IsVm64y, Mem{Base: reg.R9, Index: reg.Y11}, true},
{IsVm64y, Mem{Base: reg.R11L, Index: reg.Y11}, false},
{IsVm64y, Mem{Base: reg.R8, Index: reg.Z11}, false},
// Relative operands
{IsRel8, Rel(math.MinInt8), true},
{IsRel8, Rel(math.MaxInt8), true},
{IsRel8, Rel(math.MinInt8 - 1), false},
{IsRel8, Rel(math.MaxInt8 + 1), false},
{IsRel8, reg.R9B, false},
{IsRel32, Rel(math.MinInt32), true},
{IsRel32, Rel(math.MaxInt32), true},
{IsRel32, LabelRef("label"), true},
{IsRel32, reg.R9L, false},
}
for _, c := range cases {

View File

@@ -30,5 +30,19 @@ func (m Mem) Asm() string {
type Imm uint64
func (i Imm) Asm() string {
return fmt.Sprintf("%#x", uint64(i))
return fmt.Sprintf("%#x", i)
}
// Rel is an offset relative to the instruction pointer.
type Rel int32
func (r Rel) Asm() string {
return fmt.Sprintf(".%+d", r)
}
// LabelRef is a reference to a label.
type LabelRef string
func (l LabelRef) Asm() string {
return string(l)
}