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 }