Skip to content

Commit

Permalink
pass: ZeroExtend32BitOutputs
Browse files Browse the repository at this point in the history
Updates #121
  • Loading branch information
mmcloughlin committed Jan 21, 2020
1 parent 1447f7a commit 6a6a813
Show file tree
Hide file tree
Showing 4 changed files with 135 additions and 52 deletions.
19 changes: 18 additions & 1 deletion pass/pass.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,13 @@ var Compile = Concat(
FunctionPass(PruneDanglingLabels),
FunctionPass(LabelTarget),
FunctionPass(CFG),
InstructionPass(ZeroExtend32BitOutputs),
FunctionPass(Liveness),
FunctionPass(AllocateRegisters),
FunctionPass(BindRegisters),
FunctionPass(VerifyAllocation),
Func(IncludeTextFlagHeader),
// FunctionPass(PruneSelfMoves),
FunctionPass(PruneSelfMoves),
FunctionPass(RequiredISAExtensions),
)

Expand Down Expand Up @@ -51,6 +52,22 @@ func (p FunctionPass) Execute(f *ir.File) error {
return nil
}

// InstructionPass is a convenience for implementing a full file pass with a
// function that operates on each Instruction independently.
type InstructionPass func(*ir.Instruction) error

// Execute calls p on every instruction in the file. Exits on the first error.
func (p InstructionPass) Execute(f *ir.File) error {
for _, fn := range f.Functions() {
for _, i := range fn.Instructions() {
if err := p(i); err != nil {
return err
}
}
}
return nil
}

// Concat returns a pass that executes the given passes in order, stopping on the first error.
func Concat(passes ...Interface) Interface {
return Func(func(f *ir.File) error {
Expand Down
20 changes: 20 additions & 0 deletions pass/reg.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,32 @@ package pass

import (
"errors"
"log"

"github.com/mmcloughlin/avo/ir"
"github.com/mmcloughlin/avo/operand"
"github.com/mmcloughlin/avo/reg"
)

// ZeroExtend32BitOutputs applies the rule that "32-bit operands generate a
// 32-bit result, zero-extended to a 64-bit result in the destination
// general-purpose register" (Intel Software Developer’s Manual, Volume 1,
// 3.4.1.1).
func ZeroExtend32BitOutputs(i *ir.Instruction) error {
for j, op := range i.Outputs {
if !operand.IsR32(op) {
continue
}
r, ok := op.(reg.GP)
if !ok {
log.Printf("r32: %#v", op)
panic("r32 operand should satisfy reg.GP")
}
i.Outputs[j] = r.As64()
}
return nil
}

// Liveness computes register liveness.
func Liveness(fn *ir.Function) error {
// Note this implementation is initially naive so as to be "obviously correct".
Expand Down
18 changes: 9 additions & 9 deletions reg/x86.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,12 @@ type gpcasts struct {
Register
}

func (c gpcasts) As8() Register { return c.as(S8) }
func (c gpcasts) As8L() Register { return c.as(S8L) }
func (c gpcasts) As8H() Register { return c.as(S8H) }
func (c gpcasts) As16() Register { return c.as(S16) }
func (c gpcasts) As32() Register { return c.as(S32) }
func (c gpcasts) As64() Register { return c.as(S64) }
func (c gpcasts) As8() Register { return gpcasts{c.as(S8)} }
func (c gpcasts) As8L() Register { return gpcasts{c.as(S8L)} }
func (c gpcasts) As8H() Register { return gpcasts{c.as(S8H)} }
func (c gpcasts) As16() Register { return gpcasts{c.as(S16)} }
func (c gpcasts) As32() Register { return gpcasts{c.as(S32)} }
func (c gpcasts) As64() Register { return gpcasts{c.as(S64)} }

// GPPhysical is a general-purpose physical register.
type GPPhysical interface {
Expand Down Expand Up @@ -188,9 +188,9 @@ type veccasts struct {
Register
}

func (c veccasts) AsX() Register { return c.as(S128) }
func (c veccasts) AsY() Register { return c.as(S256) }
func (c veccasts) AsZ() Register { return c.as(S512) }
func (c veccasts) AsX() Register { return veccasts{c.as(S128)} }
func (c veccasts) AsY() Register { return veccasts{c.as(S256)} }
func (c veccasts) AsZ() Register { return veccasts{c.as(S512)} }

// VecPhysical is a physical vector register.
type VecPhysical interface {
Expand Down
130 changes: 88 additions & 42 deletions tests/alloc/upper32/upper32.s
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,65 @@ TEXT ·Upper32(SB), NOSPLIT, $0-8
// Initialize sum.
XORQ AX, AX

// Initialize registers.
MOVQ $0x9e77d78aacb8cbcc, CX
MOVQ $0x9e77d78aacb8cbcc, DX
MOVQ $0x9e77d78aacb8cbcc, BX
MOVQ $0x9e77d78aacb8cbcc, BP
MOVQ $0x9e77d78aacb8cbcc, SI
MOVQ $0x9e77d78aacb8cbcc, DI
MOVQ $0x9e77d78aacb8cbcc, R8
MOVQ $0x9e77d78aacb8cbcc, R9
MOVQ $0x9e77d78aacb8cbcc, R10
MOVQ $0x9e77d78aacb8cbcc, R11
MOVQ $0x9e77d78aacb8cbcc, R12
MOVQ $0x9e77d78aacb8cbcc, R13
MOVQ $0x9e77d78aacb8cbcc, R14
MOVQ $0x9e77d78aacb8cbcc, R15
MOVQ $0x9e77d78aacb8cbcc, CX
MOVQ $0x9e77d78aacb8cbcc, DX
MOVQ $0x9e77d78aacb8cbcc, BX
MOVQ $0x9e77d78aacb8cbcc, BP
MOVQ $0x9e77d78aacb8cbcc, SI
MOVQ $0x9e77d78aacb8cbcc, DI
MOVQ $0x9e77d78aacb8cbcc, R8
MOVQ $0x9e77d78aacb8cbcc, R9
MOVQ $0x9e77d78aacb8cbcc, R10
MOVQ $0x9e77d78aacb8cbcc, R11
MOVQ $0x9e77d78aacb8cbcc, R12
MOVQ $0x9e77d78aacb8cbcc, R13
MOVQ $0x9e77d78aacb8cbcc, R14
MOVQ $0x9e77d78aacb8cbcc, R15
MOVQ $0x9e77d78aacb8cbcc, CX
MOVQ $0x9e77d78aacb8cbcc, DX
MOVQ $0x9e77d78aacb8cbcc, BX
MOVQ $0x9e77d78aacb8cbcc, BP
MOVQ $0x9e77d78aacb8cbcc, SI
MOVQ $0x9e77d78aacb8cbcc, DI
MOVQ $0x9e77d78aacb8cbcc, R8
MOVQ $0x9e77d78aacb8cbcc, R9
MOVQ $0x9e77d78aacb8cbcc, R10
MOVQ $0x9e77d78aacb8cbcc, R11
MOVQ $0x9e77d78aacb8cbcc, R12
MOVQ $0x9e77d78aacb8cbcc, R13
MOVQ $0x9e77d78aacb8cbcc, R14
MOVQ $0x9e77d78aacb8cbcc, R15

// Iteration 1.
MOVQ $0x00000001, CX
MOVQ $0x00000002, DX
MOVQ $0x00000003, BX
MOVQ $0x00000004, BP
MOVQ $0x00000005, SI
MOVQ $0x00000006, DI
MOVQ $0x00000007, R8
MOVQ $0x00000008, R9
MOVQ $0x00000009, R10
MOVQ $0x0000000a, R11
MOVQ $0x0000000b, R12
MOVQ $0x0000000c, R13
MOVQ $0x0000000d, R14
MOVQ $0x0000000e, R15
MOVL $0x00000001, CX
MOVL $0x00000002, DX
MOVL $0x00000003, BX
MOVL $0x00000004, BP
MOVL $0x00000005, SI
MOVL $0x00000006, DI
MOVL $0x00000007, R8
MOVL $0x00000008, R9
MOVL $0x00000009, R10
MOVL $0x0000000a, R11
MOVL $0x0000000b, R12
MOVL $0x0000000c, R13
MOVL $0x0000000d, R14
MOVL $0x0000000e, R15
ADDQ CX, AX
ADDQ DX, AX
ADDQ BX, AX
Expand All @@ -38,20 +82,20 @@ TEXT ·Upper32(SB), NOSPLIT, $0-8
ADDQ R15, AX

// Iteration 2.
MOVQ $0x0000000f, CX
MOVQ $0x00000010, DX
MOVQ $0x00000011, BX
MOVQ $0x00000012, BP
MOVQ $0x00000013, SI
MOVQ $0x00000014, DI
MOVQ $0x00000015, R8
MOVQ $0x00000016, R9
MOVQ $0x00000017, R10
MOVQ $0x00000018, R11
MOVQ $0x00000019, R12
MOVQ $0x0000001a, R13
MOVQ $0x0000001b, R14
MOVQ $0x0000001c, R15
MOVL $0x0000000f, CX
MOVL $0x00000010, DX
MOVL $0x00000011, BX
MOVL $0x00000012, BP
MOVL $0x00000013, SI
MOVL $0x00000014, DI
MOVL $0x00000015, R8
MOVL $0x00000016, R9
MOVL $0x00000017, R10
MOVL $0x00000018, R11
MOVL $0x00000019, R12
MOVL $0x0000001a, R13
MOVL $0x0000001b, R14
MOVL $0x0000001c, R15
ADDQ CX, AX
ADDQ DX, AX
ADDQ BX, AX
Expand All @@ -68,20 +112,20 @@ TEXT ·Upper32(SB), NOSPLIT, $0-8
ADDQ R15, AX

// Iteration 3.
MOVQ $0x0000001d, CX
MOVQ $0x0000001e, DX
MOVQ $0x0000001f, BX
MOVQ $0x00000020, BP
MOVQ $0x00000021, SI
MOVQ $0x00000022, DI
MOVQ $0x00000023, R8
MOVQ $0x00000024, R9
MOVQ $0x00000025, R10
MOVQ $0x00000026, R11
MOVQ $0x00000027, R12
MOVQ $0x00000028, R13
MOVQ $0x00000029, R14
MOVQ $0x0000002a, R15
MOVL $0x0000001d, CX
MOVL $0x0000001e, DX
MOVL $0x0000001f, BX
MOVL $0x00000020, BP
MOVL $0x00000021, SI
MOVL $0x00000022, DI
MOVL $0x00000023, R8
MOVL $0x00000024, R9
MOVL $0x00000025, R10
MOVL $0x00000026, R11
MOVL $0x00000027, R12
MOVL $0x00000028, R13
MOVL $0x00000029, R14
MOVL $0x0000002a, R15
ADDQ CX, AX
ADDQ DX, AX
ADDQ BX, AX
Expand All @@ -96,5 +140,7 @@ TEXT ·Upper32(SB), NOSPLIT, $0-8
ADDQ R13, AX
ADDQ R14, AX
ADDQ R15, AX

// Store result and return.
MOVQ AX, ret+0(FP)
RET

0 comments on commit 6a6a813

Please sign in to comment.