github.com/tetratelabs/wazero@v1.7.1/internal/engine/wazevo/backend/isa/amd64/lower_constant.go (about)

     1  package amd64
     2  
     3  import (
     4  	"github.com/tetratelabs/wazero/internal/engine/wazevo/backend/regalloc"
     5  	"github.com/tetratelabs/wazero/internal/engine/wazevo/ssa"
     6  )
     7  
     8  // lowerConstant allocates a new VReg and inserts the instruction to load the constant value.
     9  func (m *machine) lowerConstant(instr *ssa.Instruction) (vr regalloc.VReg) {
    10  	val := instr.Return()
    11  	valType := val.Type()
    12  
    13  	vr = m.c.AllocateVReg(valType)
    14  	m.insertLoadConstant(instr, vr)
    15  	return
    16  }
    17  
    18  // InsertLoadConstantBlockArg implements backend.Machine.
    19  func (m *machine) InsertLoadConstantBlockArg(instr *ssa.Instruction, vr regalloc.VReg) {
    20  	m.insertLoadConstant(instr, vr)
    21  }
    22  
    23  func (m *machine) insertLoadConstant(instr *ssa.Instruction, vr regalloc.VReg) {
    24  	val := instr.Return()
    25  	valType := val.Type()
    26  	v := instr.ConstantVal()
    27  
    28  	bits := valType.Bits()
    29  	if bits < 64 { // Clear the redundant bits just in case it's unexpectedly sign-extended, etc.
    30  		v = v & ((1 << valType.Bits()) - 1)
    31  	}
    32  
    33  	switch valType {
    34  	case ssa.TypeF32, ssa.TypeF64:
    35  		m.lowerFconst(vr, v, bits == 64)
    36  	case ssa.TypeI32, ssa.TypeI64:
    37  		m.lowerIconst(vr, v, bits == 64)
    38  	default:
    39  		panic("BUG")
    40  	}
    41  }
    42  
    43  func (m *machine) lowerFconst(dst regalloc.VReg, c uint64, _64 bool) {
    44  	if c == 0 {
    45  		xor := m.allocateInstr().asZeros(dst)
    46  		m.insert(xor)
    47  	} else {
    48  		var tmpType ssa.Type
    49  		if _64 {
    50  			tmpType = ssa.TypeI64
    51  		} else {
    52  			tmpType = ssa.TypeI32
    53  		}
    54  		tmpInt := m.c.AllocateVReg(tmpType)
    55  		loadToGP := m.allocateInstr().asImm(tmpInt, c, _64)
    56  		m.insert(loadToGP)
    57  
    58  		movToXmm := m.allocateInstr().asGprToXmm(sseOpcodeMovq, newOperandReg(tmpInt), dst, _64)
    59  		m.insert(movToXmm)
    60  	}
    61  }
    62  
    63  func (m *machine) lowerIconst(dst regalloc.VReg, c uint64, _64 bool) {
    64  	i := m.allocateInstr()
    65  	if c == 0 {
    66  		i.asZeros(dst)
    67  	} else {
    68  		i.asImm(dst, c, _64)
    69  	}
    70  	m.insert(i)
    71  }